vendor/vich/uploader-bundle/src/Metadata/Driver/AttributeDriver.php line 101

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