This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
<?php
namespace Gedmo\Uploadable\Mapping\Driver;
use Gedmo\Mapping\Driver\AbstractAnnotationDriver;
use Gedmo\Uploadable\Mapping\Validator;
/**
* This is an annotation mapping driver for Uploadable
* behavioral extension. Used for extraction of extended
* metadata from Annotations specifically for Uploadable
* extension.
*
* @author Gustavo Falco <comfortablynumb84@gmail.com>
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class Annotation extends AbstractAnnotationDriver
{
/**
* Annotation to define that this object is loggable
*/
const UPLOADABLE = 'Gedmo\\Mapping\\Annotation\\Uploadable';
const UPLOADABLE_FILE_MIME_TYPE = 'Gedmo\\Mapping\\Annotation\\UploadableFileMimeType';
const UPLOADABLE_FILE_NAME = 'Gedmo\\Mapping\\Annotation\\UploadableFileName';
const UPLOADABLE_FILE_PATH = 'Gedmo\\Mapping\\Annotation\\UploadableFilePath';
const UPLOADABLE_FILE_SIZE = 'Gedmo\\Mapping\\Annotation\\UploadableFileSize';
/**
* {@inheritDoc}
*/
public function readExtendedMetadata($meta, array &$config)
{
$class = $this->getMetaReflectionClass($meta);
// class annotations
if ($annot = $this->reader->getClassAnnotation($class, self::UPLOADABLE)) {
$config['uploadable'] = true;
$config['allowOverwrite'] = $annot->allowOverwrite;
$config['appendNumber'] = $annot->appendNumber;
$config['path'] = $annot->path;
$config['pathMethod'] = $annot->pathMethod;
$config['fileMimeTypeField'] = false;
$config['fileNameField'] = false;
$config['filePathField'] = false;
$config['fileSizeField'] = false;
$config['callback'] = $annot->callback;
$config['filenameGenerator'] = $annot->filenameGenerator;
$config['maxSize'] = (double) $annot->maxSize;
$config['allowedTypes'] = $annot->allowedTypes;
$config['disallowedTypes'] = $annot->disallowedTypes;
foreach ($class->getProperties() as $prop) {
if ($this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_MIME_TYPE)) {
$config['fileMimeTypeField'] = $prop->getName();
}
if ($this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_NAME)) {
$config['fileNameField'] = $prop->getName();
}
if ($this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_PATH)) {
$config['filePathField'] = $prop->getName();
}
if ($this->reader->getPropertyAnnotation($prop, self::UPLOADABLE_FILE_SIZE)) {
$config['fileSizeField'] = $prop->getName();
}
}
Validator::validateConfiguration($meta, $config);
}
/*
// Code in case we need to identify entities which are not Uploadables, but have associations
// with other Uploadable entities
} else {
// We need to check if this class has a relation with Uploadable entities
$associations = $meta->getAssociationMappings();
foreach ($associations as $field => $association) {
$refl = new \ReflectionClass($association['targetEntity']);
if ($annot = $this->reader->getClassAnnotation($refl, self::UPLOADABLE)) {
$config['hasUploadables'] = true;
if (!isset($config['uploadables'])) {
$config['uploadables'] = array();
}
$config['uploadables'][] = array(
'class' => $association['targetEntity'],
'property' => $association['fieldName']
);
}
}
}*/
$this->validateFullMetadata($meta, $config);
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace Gedmo\Uploadable\Mapping\Driver;
use Gedmo\Mapping\Driver\Xml as BaseXml;
use Gedmo\Uploadable\Mapping\Validator;
/**
* This is a xml mapping driver for Uploadable
* behavioral extension. Used for extraction of extended
* metadata from xml specifically for Uploadable
* extension.
*
* @author Gustavo Falco <comfortablynumb84@gmail.com>
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @author Miha Vrhovnik <miha.vrhovnik@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class Xml extends BaseXml
{
/**
* {@inheritDoc}
*/
public function readExtendedMetadata($meta, array &$config)
{
/**
* @var \SimpleXmlElement $xml
*/
$xml = $this->_getMapping($meta->name);
$xmlDoctrine = $xml;
$xml = $xml->children(self::GEDMO_NAMESPACE_URI);
if ($xmlDoctrine->getName() == 'entity' || $xmlDoctrine->getName() == 'mapped-superclass') {
if (isset($xml->uploadable)) {
$xmlUploadable = $xml->uploadable;
$config['uploadable'] = true;
$config['allowOverwrite'] = $this->_isAttributeSet($xmlUploadable, 'allow-overwrite') ?
(bool) $this->_getAttribute($xmlUploadable, 'allow-overwrite') : false;
$config['appendNumber'] = $this->_isAttributeSet($xmlUploadable, 'append-number') ?
(bool) $this->_getAttribute($xmlUploadable, 'append-number') : false;
$config['path'] = $this->_isAttributeSet($xmlUploadable, 'path') ?
$this->_getAttribute($xml->{'uploadable'}, 'path') : '';
$config['pathMethod'] = $this->_isAttributeSet($xmlUploadable, 'path-method') ?
$this->_getAttribute($xml->{'uploadable'}, 'path-method') : '';
$config['callback'] = $this->_isAttributeSet($xmlUploadable, 'callback') ?
$this->_getAttribute($xml->{'uploadable'}, 'callback') : '';
$config['fileMimeTypeField'] = false;
$config['fileNameField'] = false;
$config['filePathField'] = false;
$config['fileSizeField'] = false;
$config['filenameGenerator'] = $this->_isAttributeSet($xmlUploadable, 'filename-generator') ?
$this->_getAttribute($xml->{'uploadable'}, 'filename-generator') :
Validator::FILENAME_GENERATOR_NONE;
$config['maxSize'] = $this->_isAttributeSet($xmlUploadable, 'max-size') ?
(double) $this->_getAttribute($xml->{'uploadable'}, 'max-size') :
(double) 0;
$config['allowedTypes'] = $this->_isAttributeSet($xmlUploadable, 'allowed-types') ?
$this->_getAttribute($xml->{'uploadable'}, 'allowed-types') :
'';
$config['disallowedTypes'] = $this->_isAttributeSet($xmlUploadable, 'disallowed-types') ?
$this->_getAttribute($xml->{'uploadable'}, 'disallowed-types') :
'';
if (isset($xmlDoctrine->field)) {
foreach ($xmlDoctrine->field as $mapping) {
$mappingDoctrine = $mapping;
$mapping = $mapping->children(self::GEDMO_NAMESPACE_URI);
$field = $this->_getAttribute($mappingDoctrine, 'name');
if (isset($mapping->{'uploadable-file-mime-type'})) {
$config['fileMimeTypeField'] = $field;
} elseif (isset($mapping->{'uploadable-file-size'})) {
$config['fileSizeField'] = $field;
} elseif (isset($mapping->{'uploadable-file-name'})) {
$config['fileNameField'] = $field;
} elseif (isset($mapping->{'uploadable-file-path'})) {
$config['filePathField'] = $field;
}
}
}
Validator::validateConfiguration($meta, $config);
}
}
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace Gedmo\Uploadable\Mapping\Driver;
use Gedmo\Mapping\Driver\File;
use Gedmo\Mapping\Driver;
use Gedmo\Uploadable\Mapping\Validator;
/**
* This is a yaml mapping driver for Uploadable
* behavioral extension. Used for extraction of extended
* metadata from yaml specifically for Uploadable
* extension.
*
* @author Gustavo Falco <comfortablynumb84@gmail.com>
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class Yaml extends File implements Driver
{
/**
* File extension
* @var string
*/
protected $_extension = '.dcm.yml';
/**
* {@inheritDoc}
*/
public function readExtendedMetadata($meta, array &$config)
{
$mapping = $this->_getMapping($meta->name);
if (isset($mapping['gedmo'])) {
$classMapping = $mapping['gedmo'];
if (isset($classMapping['uploadable'])) {
$uploadable = $classMapping['uploadable'];
$config['uploadable'] = true;
$config['allowOverwrite'] = isset($uploadable['allowOverwrite']) ?
(bool) $uploadable['allowOverwrite'] : false;
$config['appendNumber'] = isset($uploadable['appendNumber']) ?
(bool) $uploadable['appendNumber'] : false;
$config['path'] = isset($uploadable['path']) ? $uploadable['path'] : '';
$config['pathMethod'] = isset($uploadable['pathMethod']) ? $uploadable['pathMethod'] : '';
$config['callback'] = isset($uploadable['callback']) ? $uploadable['callback'] : '';
$config['fileMimeTypeField'] = false;
$config['fileNameField'] = false;
$config['filePathField'] = false;
$config['fileSizeField'] = false;
$config['filenameGenerator'] = isset($uploadable['filenameGenerator']) ?
$uploadable['filenameGenerator'] :
Validator::FILENAME_GENERATOR_NONE;
$config['maxSize'] = isset($uploadable['maxSize']) ?
(double) $uploadable['maxSize'] :
(double) 0;
$config['allowedTypes'] = isset($uploadable['allowedTypes']) ?
$uploadable['allowedTypes'] :
'';
$config['disallowedTypes'] = isset($uploadable['disallowedTypes']) ?
$uploadable['disallowedTypes'] :
'';
if (isset($mapping['fields'])) {
foreach ($mapping['fields'] as $field => $info) {
if (isset($info['gedmo']) && array_key_exists(0, $info['gedmo'])) {
if ($info['gedmo'][0] === 'uploadableFileMimeType') {
$config['fileMimeTypeField'] = $field;
} elseif ($info['gedmo'][0] === 'uploadableFileSize') {
$config['fileSizeField'] = $field;
} elseif ($info['gedmo'][0] === 'uploadableFileName') {
$config['fileNameField'] = $field;
} elseif ($info['gedmo'][0] === 'uploadableFilePath') {
$config['filePathField'] = $field;
}
}
}
}
Validator::validateConfiguration($meta, $config);
}
}
}
/**
* {@inheritDoc}
*/
protected function _loadMappingFile($file)
{
return \Symfony\Component\Yaml\Yaml::parse(file_get_contents($file));
}
}

View File

@@ -0,0 +1,242 @@
<?php
namespace Gedmo\Uploadable\Mapping;
use Gedmo\Exception\InvalidMappingException;
use Gedmo\Exception\UploadableCantWriteException;
use Gedmo\Exception\UploadableInvalidPathException;
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
/**
* This class is used to validate mapping information
*
* @author Gustavo Falco <comfortablynumb84@gmail.com>
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class Validator
{
const UPLOADABLE_FILE_MIME_TYPE = 'UploadableFileMimeType';
const UPLOADABLE_FILE_NAME = 'UploadableFileName';
const UPLOADABLE_FILE_PATH = 'UploadableFilePath';
const UPLOADABLE_FILE_SIZE = 'UploadableFileSize';
const FILENAME_GENERATOR_SHA1 = 'SHA1';
const FILENAME_GENERATOR_ALPHANUMERIC = 'ALPHANUMERIC';
const FILENAME_GENERATOR_NONE = 'NONE';
/**
* Determines if we should throw an exception in the case the "allowedTypes" and
* "disallowedTypes" options are BOTH set. Useful for testing purposes
*
* @var bool
*/
public static $enableMimeTypesConfigException = true;
/**
* List of types which are valid for UploadableFileMimeType field
*
* @var array
*/
public static $validFileMimeTypeTypes = array(
'string',
);
/**
* List of types which are valid for UploadableFileName field
*
* @var array
*/
public static $validFileNameTypes = array(
'string',
);
/**
* List of types which are valid for UploadableFilePath field
*
* @var array
*/
public static $validFilePathTypes = array(
'string',
);
/**
* List of types which are valid for UploadableFileSize field for ORM
*
* @var array
*/
public static $validFileSizeTypes = array(
'decimal',
);
/**
* List of types which are valid for UploadableFileSize field for ODM
*
* @var array
*/
public static $validFileSizeTypesODM = array(
'float',
);
/**
* Whether to validate if the directory of the file exists and is writable, useful to disable it when using
* stream wrappers which don't support is_dir (like Gaufrette)
*
* @var bool
*/
public static $validateWritableDirectory = true;
public static function validateFileNameField(ClassMetadata $meta, $field)
{
self::validateField($meta, $field, self::UPLOADABLE_FILE_NAME, self::$validFileNameTypes);
}
public static function validateFileMimeTypeField(ClassMetadata $meta, $field)
{
self::validateField($meta, $field, self::UPLOADABLE_FILE_MIME_TYPE, self::$validFileMimeTypeTypes);
}
public static function validateFilePathField(ClassMetadata $meta, $field)
{
self::validateField($meta, $field, self::UPLOADABLE_FILE_PATH, self::$validFilePathTypes);
}
public static function validateFileSizeField(ClassMetadata $meta, $field)
{
if ($meta instanceof \Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo) {
self::validateField($meta, $field, self::UPLOADABLE_FILE_SIZE, self::$validFileSizeTypesODM);
} else {
self::validateField($meta, $field, self::UPLOADABLE_FILE_SIZE, self::$validFileSizeTypes);
}
}
public static function validateField($meta, $field, $uploadableField, $validFieldTypes)
{
if ($meta->isMappedSuperclass) {
return;
}
$fieldMapping = $meta->getFieldMapping($field);
if (!in_array($fieldMapping['type'], $validFieldTypes)) {
$msg = 'Field "%s" to work as an "%s" field must be of one of the following types: "%s".';
throw new InvalidMappingException(sprintf($msg,
$field,
$uploadableField,
implode(', ', $validFieldTypes)
));
}
}
public static function validatePath($path)
{
if (!is_string($path) || $path === '') {
throw new UploadableInvalidPathException('Path must be a string containing the path to a valid directory.');
}
if (!self::$validateWritableDirectory) {
return;
}
if (!is_dir($path) && !@mkdir($path, 0777, true)) {
throw new UploadableInvalidPathException(sprintf('Unable to create "%s" directory.',
$path
));
}
if (!is_writable($path)) {
throw new UploadableCantWriteException(sprintf('Directory "%s" does is not writable.',
$path
));
}
}
public static function validateConfiguration(ClassMetadata $meta, array &$config)
{
if (!$config['filePathField'] && !$config['fileNameField']) {
throw new InvalidMappingException(sprintf('Class "%s" must have an UploadableFilePath or UploadableFileName field.',
$meta->name
));
}
$refl = $meta->getReflectionClass();
if ($config['pathMethod'] !== '' && !$refl->hasMethod($config['pathMethod'])) {
throw new InvalidMappingException(sprintf('Class "%s" doesn\'t have method "%s"!',
$meta->name,
$config['pathMethod']
));
}
if ($config['callback'] !== '' && !$refl->hasMethod($config['callback'])) {
throw new InvalidMappingException(sprintf('Class "%s" doesn\'t have method "%s"!',
$meta->name,
$config['callback']
));
}
$config['maxSize'] = (double) $config['maxSize'];
if ($config['maxSize'] < 0) {
throw new InvalidMappingException(sprintf('Option "maxSize" must be a number >= 0 for class "%s".',
$meta->name
));
}
if (self::$enableMimeTypesConfigException && ($config['allowedTypes'] !== '' && $config['disallowedTypes'] !== '')) {
$msg = 'You\'ve set "allowedTypes" and "disallowedTypes" options. You must set only one in class "%s".';
throw new InvalidMappingException(sprintf($msg,
$meta->name
));
}
$config['allowedTypes'] = $config['allowedTypes'] ? (strpos($config['allowedTypes'], ',') !== false ?
explode(',', $config['allowedTypes']) : array($config['allowedTypes'])) : false;
$config['disallowedTypes'] = $config['disallowedTypes'] ? (strpos($config['disallowedTypes'], ',') !== false ?
explode(',', $config['disallowedTypes']) : array($config['disallowedTypes'])) : false;
if ($config['fileNameField']) {
self::validateFileNameField($meta, $config['fileNameField']);
}
if ($config['filePathField']) {
self::validateFilePathField($meta, $config['filePathField']);
}
if ($config['fileMimeTypeField']) {
self::validateFileMimeTypeField($meta, $config['fileMimeTypeField']);
}
if ($config['fileSizeField']) {
self::validateFileSizeField($meta, $config['fileSizeField']);
}
switch ((string) $config['filenameGenerator']) {
case self::FILENAME_GENERATOR_ALPHANUMERIC:
case self::FILENAME_GENERATOR_SHA1:
case self::FILENAME_GENERATOR_NONE:
break;
default:
$ok = false;
if (class_exists($config['filenameGenerator'])) {
$refl = new \ReflectionClass($config['filenameGenerator']);
if ($refl->implementsInterface('Gedmo\Uploadable\FilenameGenerator\FilenameGeneratorInterface')) {
$ok = true;
}
}
if (!$ok) {
$msg = 'Class "%s" needs a valid value for filenameGenerator. It can be: SHA1, ALPHANUMERIC, NONE or ';
$msg .= 'a class implementing FileGeneratorInterface.';
throw new InvalidMappingException(sprintf($msg,
$meta->name
));
}
}
}
}