vendor/vich/uploader-bundle/src/Mapping/PropertyMapping.php line 302

Open in your IDE?
  1. <?php
  2. namespace Vich\UploaderBundle\Mapping;
  3. use Symfony\Component\HttpFoundation\File\File;
  4. use Symfony\Component\PropertyAccess\PropertyAccess;
  5. use Symfony\Component\PropertyAccess\PropertyAccessor;
  6. use Vich\UploaderBundle\Naming\DirectoryNamerInterface;
  7. use Vich\UploaderBundle\Naming\NamerInterface;
  8. /**
  9.  * PropertyMapping.
  10.  *
  11.  * @author Dustin Dobervich <ddobervich@gmail.com>
  12.  * @final
  13.  */
  14. class PropertyMapping
  15. {
  16.     /**
  17.      * @var NamerInterface|null
  18.      */
  19.     protected $namer;
  20.     /**
  21.      * @var DirectoryNamerInterface
  22.      */
  23.     protected $directoryNamer;
  24.     /**
  25.      * @var array
  26.      */
  27.     protected $mapping;
  28.     /**
  29.      * @var string
  30.      */
  31.     protected $mappingName;
  32.     /**
  33.      * @var array<string, string|null>
  34.      */
  35.     protected $propertyPaths = [
  36.         'file' => null,
  37.         'name' => null,
  38.         'size' => null,
  39.         'mimeType' => null,
  40.         'originalName' => null,
  41.         'dimensions' => null,
  42.     ];
  43.     /**
  44.      * @var PropertyAccessor
  45.      */
  46.     protected $accessor;
  47.     /**
  48.      * @param string         $filePropertyPath     The path to the "file" property
  49.      * @param string         $fileNamePropertyPath The path to the "filename" property
  50.      * @param array|string[] $propertyPaths        The paths to other properties
  51.      */
  52.     public function __construct(string $filePropertyPathstring $fileNamePropertyPath, array $propertyPaths = [])
  53.     {
  54.         $this->propertyPaths = \array_merge(
  55.             $this->propertyPaths,
  56.             ['file' => $filePropertyPath'name' => $fileNamePropertyPath],
  57.             $propertyPaths
  58.         );
  59.     }
  60.     /**
  61.      * Gets the file property value for the given object.
  62.      *
  63.      * @param object $obj The object
  64.      *
  65.      * @return \Symfony\Component\HttpFoundation\File\UploadedFile|\Vich\UploaderBundle\FileAbstraction\ReplacingFile|null The file
  66.      *
  67.      * @throws \InvalidArgumentException
  68.      */
  69.     public function getFile($obj): ?File
  70.     {
  71.         return $this->readProperty($obj'file');
  72.     }
  73.     /**
  74.      * Modifies the file property value for the given object.
  75.      *
  76.      * @param object $obj  The object
  77.      * @param File   $file The new file
  78.      *
  79.      * @throws \InvalidArgumentException
  80.      * @throws \TypeError
  81.      */
  82.     public function setFile($objFile $file): void
  83.     {
  84.         $this->writeProperty($obj'file'$file);
  85.     }
  86.     /**
  87.      * Gets the fileName property of the given object.
  88.      *
  89.      * @param object $obj The object
  90.      *
  91.      * @return string The filename
  92.      *
  93.      * @throws \InvalidArgumentException
  94.      */
  95.     public function getFileName($obj): ?string
  96.     {
  97.         return $this->readProperty($obj'name');
  98.     }
  99.     /**
  100.      * Modifies the fileName property of the given object.
  101.      *
  102.      * @param object $obj The object
  103.      *
  104.      * @throws \InvalidArgumentException
  105.      * @throws \TypeError
  106.      */
  107.     public function setFileName($objstring $value): void
  108.     {
  109.         $this->writeProperty($obj'name'$value);
  110.     }
  111.     /**
  112.      * Removes value for each file-related property of the given object.
  113.      *
  114.      * @param object $obj The object
  115.      *
  116.      * @throws \InvalidArgumentException
  117.      * @throws \TypeError
  118.      */
  119.     public function erase($obj): void
  120.     {
  121.         foreach (['name''size''mimeType''originalName''dimensions'] as $property) {
  122.             $this->writeProperty($obj$propertynull);
  123.         }
  124.     }
  125.     /**
  126.      * Reads property of the given object.
  127.      *
  128.      * @internal
  129.      *
  130.      * @param object $obj      The object from which read
  131.      * @param string $property The property to read
  132.      *
  133.      * @return mixed
  134.      *
  135.      * @throws \InvalidArgumentException
  136.      */
  137.     public function readProperty($obj$property)
  138.     {
  139.         if (!\array_key_exists($property$this->propertyPaths)) {
  140.             throw new \InvalidArgumentException(\sprintf('Unknown property %s'$property));
  141.         }
  142.         if (!$this->propertyPaths[$property]) {
  143.             // not configured
  144.             return null;
  145.         }
  146.         $propertyPath $this->fixPropertyPath($obj$this->propertyPaths[$property]);
  147.         return $this->getAccessor()->getValue($obj$propertyPath);
  148.     }
  149.     /**
  150.      * Modifies property of the given object.
  151.      *
  152.      * @internal
  153.      *
  154.      * @param object $obj      The object to which write
  155.      * @param string $property The property to write
  156.      * @param mixed  $value    The value which should be written
  157.      *
  158.      * @throws \InvalidArgumentException
  159.      * @throws \TypeError
  160.      */
  161.     public function writeProperty($objstring $property$value): void
  162.     {
  163.         if (!\array_key_exists($property$this->propertyPaths)) {
  164.             throw new \InvalidArgumentException(\sprintf('Unknown property %s'$property));
  165.         }
  166.         if (!$this->propertyPaths[$property]) {
  167.             // not configured
  168.             return;
  169.         }
  170.         $propertyPath $this->fixPropertyPath($obj$this->propertyPaths[$property]);
  171.         $this->getAccessor()->setValue($obj$propertyPath$value);
  172.     }
  173.     /**
  174.      * Gets the configured file property name.
  175.      *
  176.      * @return string The name
  177.      */
  178.     public function getFilePropertyName(): string
  179.     {
  180.         return $this->propertyPaths['file'];
  181.     }
  182.     /**
  183.      * Gets the configured filename property name.
  184.      *
  185.      * @return string The name
  186.      */
  187.     public function getFileNamePropertyName(): string
  188.     {
  189.         return $this->propertyPaths['name'];
  190.     }
  191.     /**
  192.      * Gets the configured namer.
  193.      */
  194.     public function getNamer(): ?NamerInterface
  195.     {
  196.         return $this->namer;
  197.     }
  198.     /**
  199.      * Sets the namer.
  200.      */
  201.     public function setNamer(NamerInterface $namer): void
  202.     {
  203.         $this->namer $namer;
  204.     }
  205.     /**
  206.      * Determines if the mapping has a custom namer configured.
  207.      */
  208.     public function hasNamer(): bool
  209.     {
  210.         return null !== $this->namer;
  211.     }
  212.     /**
  213.      * Gets the configured directory namer.
  214.      */
  215.     public function getDirectoryNamer(): ?DirectoryNamerInterface
  216.     {
  217.         return $this->directoryNamer;
  218.     }
  219.     /**
  220.      * Sets the directory namer.
  221.      */
  222.     public function setDirectoryNamer(DirectoryNamerInterface $directoryNamer): void
  223.     {
  224.         $this->directoryNamer $directoryNamer;
  225.     }
  226.     /**
  227.      * Determines if the mapping has a custom directory namer configured.
  228.      */
  229.     public function hasDirectoryNamer(): bool
  230.     {
  231.         return null !== $this->directoryNamer;
  232.     }
  233.     /**
  234.      * Sets the configured configuration mapping.
  235.      *
  236.      * @param array $mapping The mapping;
  237.      */
  238.     public function setMapping(array $mapping): void
  239.     {
  240.         $this->mapping $mapping;
  241.     }
  242.     /**
  243.      * Gets the configured configuration mapping name.
  244.      */
  245.     public function getMappingName(): string
  246.     {
  247.         return $this->mappingName;
  248.     }
  249.     /**
  250.      * Sets the configured configuration mapping name.
  251.      *
  252.      * @param string $mappingName
  253.      */
  254.     public function setMappingName($mappingName): void
  255.     {
  256.         $this->mappingName $mappingName;
  257.     }
  258.     /**
  259.      * Gets the upload name for a given file (uses The file namers).
  260.      *
  261.      * @param object $obj
  262.      *
  263.      * @return string The upload name
  264.      */
  265.     public function getUploadName($obj): string
  266.     {
  267.         if (!$this->hasNamer()) {
  268.             $msg 'Not using a namer is deprecated and will be removed in version 2.';
  269.             @\trigger_error($msg, \E_USER_DEPRECATED);
  270.             return $this->getFile($obj)->getClientOriginalName();
  271.         }
  272.         return $this->getNamer()->name($obj$this);
  273.     }
  274.     /**
  275.      * Gets the upload directory for a given file (uses the directory namers).
  276.      *
  277.      * @param object $obj
  278.      *
  279.      * @return string|null The upload directory
  280.      */
  281.     public function getUploadDir($obj): ?string
  282.     {
  283.         if (!$this->hasDirectoryNamer()) {
  284.             return '';
  285.         }
  286.         $dir $this->getDirectoryNamer()->directoryName($obj$this);
  287.         // strip the trailing directory separator if needed
  288.         $dir $dir ? \rtrim($dir'/\\') : $dir;
  289.         return $dir;
  290.     }
  291.     /**
  292.      * Gets the base upload directory.
  293.      *
  294.      * @return string The configured upload directory
  295.      */
  296.     public function getUploadDestination(): string
  297.     {
  298.         return $this->mapping['upload_destination'];
  299.     }
  300.     /**
  301.      * Get uri prefix.
  302.      */
  303.     public function getUriPrefix(): string
  304.     {
  305.         return $this->mapping['uri_prefix'];
  306.     }
  307.     /**
  308.      * Fixes a given propertyPath to make it usable both with arrays and
  309.      * objects.
  310.      * Ie: if the given object is in fact an array, the property path must
  311.      * look like [myPath].
  312.      *
  313.      * @param object|array $object       The object to inspect
  314.      * @param string       $propertyPath The property path to fix
  315.      *
  316.      * @return string The fixed property path
  317.      */
  318.     protected function fixPropertyPath($objectstring $propertyPath): string
  319.     {
  320.         if (!\is_array($object)) {
  321.             return $propertyPath;
  322.         }
  323.         return '[' === $propertyPath[0] ? $propertyPath : \sprintf('[%s]'$propertyPath);
  324.     }
  325.     protected function getAccessor(): PropertyAccessor
  326.     {
  327.         // TODO: reuse original property accessor from forms
  328.         if (null !== $this->accessor) {
  329.             return $this->accessor;
  330.         }
  331.         return $this->accessor PropertyAccess::createPropertyAccessor();
  332.     }
  333. }