vendor/vich/uploader-bundle/src/Metadata/Driver/AnnotationDriver.php line 80

  1. <?php
  2. namespace Vich\UploaderBundle\Metadata\Driver;
  3. use Doctrine\Common\Annotations\Reader as AnnotationReader;
  4. use Metadata\ClassMetadata as JMSClassMetadata;
  5. use Metadata\Driver\AdvancedDriverInterface;
  6. use Vich\UploaderBundle\Mapping\Annotation\Uploadable;
  7. use Vich\UploaderBundle\Mapping\Annotation\UploadableField;
  8. use Vich\UploaderBundle\Metadata\ClassMetadata;
  9. /**
  10.  * @author Kévin Gomez <contact@kevingomez.fr>
  11.  * @author Konstantin Myakshin <koc-dp@yandex.ru>
  12.  */
  13. class AnnotationDriver implements AdvancedDriverInterface
  14. {
  15.     /**
  16.      * @param \Doctrine\Persistence\ManagerRegistry[] $managerRegistryList
  17.      */
  18.     public function __construct(
  19.         protected readonly AnnotationReader|AttributeReader $reader,
  20.         private readonly array $managerRegistryList
  21.     ) {
  22.     }
  23.     public function loadMetadataForClass(\ReflectionClass $class): ?JMSClassMetadata
  24.     {
  25.         if (!$this->isUploadable($class)) {
  26.             return null;
  27.         }
  28.         $classMetadata = new ClassMetadata($class->name);
  29.         $classMetadata->fileResources[] = $class->getFileName();
  30.         $classes = [];
  31.         do {
  32.             $classes[] = $class;
  33.             $class $class->getParentClass();
  34.         } while (false !== $class);
  35.         $classes \array_reverse($classes);
  36.         $properties = [];
  37.         foreach ($classes as $cls) {
  38.             $properties = [...$properties, ...$cls->getProperties()];
  39.         }
  40.         foreach ($properties as $property) {
  41.             $uploadableField $this->reader->getPropertyAnnotation($propertyUploadableField::class);
  42.             if (null === $uploadableField) {
  43.                 continue;
  44.             }
  45.             /* @var $uploadableField UploadableField */
  46.             // TODO: try automatically determinate target fields if embeddable used
  47.             $fieldMetadata = [
  48.                 'mapping' => $uploadableField->getMapping(),
  49.                 'propertyName' => $property->getName(),
  50.                 'fileNameProperty' => $uploadableField->getFileNameProperty(),
  51.                 'size' => $uploadableField->getSize(),
  52.                 'mimeType' => $uploadableField->getMimeType(),
  53.                 'originalName' => $uploadableField->getOriginalName(),
  54.                 'dimensions' => $uploadableField->getDimensions(),
  55.             ];
  56.             // TODO: store UploadableField object instead of array
  57.             $classMetadata->fields[$property->getName()] = $fieldMetadata;
  58.         }
  59.         return $classMetadata;
  60.     }
  61.     public function getAllClassNames(): array
  62.     {
  63.         $classes = [];
  64.         $metadata = [];
  65.         foreach ($this->managerRegistryList as $managerRegisty) {
  66.             $managers $managerRegisty->getManagers();
  67.             foreach ($managers as $manager) {
  68.                 $metadata[] = $manager->getMetadataFactory()->getAllMetadata();
  69.             }
  70.         }
  71.         $metadata \array_merge(...$metadata);
  72.         /** @var \Doctrine\Persistence\Mapping\ClassMetadata $classMeta */
  73.         foreach ($metadata as $classMeta) {
  74.             if ($this->isUploadable(new \ReflectionClass($classMeta->getName()))) {
  75.                 $classes[] = $classMeta->getName();
  76.             }
  77.         }
  78.         return $classes;
  79.     }
  80.     protected function isUploadable(\ReflectionClass $class): bool
  81.     {
  82.         return null !== $this->reader->getClassAnnotation($classUploadable::class);
  83.     }
  84. }