AnnotationDriver.php
9 months ago
AttributeDriver.php
9 months ago
AttributeReader.php
9 months ago
CompatibilityAnnotationDriver.php
9 months ago
DriverChain.php
9 months ago
PHPDriver.php
9 months ago
ReflectionBasedDriver.php
9 months ago
RepeatableAttributeCollection.php
9 months ago
StaticPHPDriver.php
9 months ago
index.php
9 months ago
AttributeReader.php
80 lines
| 1 | <?php |
| 2 | declare (strict_types=1); |
| 3 | namespace MailPoetVendor\Doctrine\ORM\Mapping\Driver; |
| 4 | if (!defined('ABSPATH')) exit; |
| 5 | use Attribute; |
| 6 | use MailPoetVendor\Doctrine\ORM\Mapping\Annotation; |
| 7 | use LogicException; |
| 8 | use ReflectionAttribute; |
| 9 | use ReflectionClass; |
| 10 | use ReflectionMethod; |
| 11 | use ReflectionProperty; |
| 12 | use function assert; |
| 13 | use function is_string; |
| 14 | use function is_subclass_of; |
| 15 | use function sprintf; |
| 16 | final class AttributeReader |
| 17 | { |
| 18 | private array $isRepeatableAttribute = []; |
| 19 | public function getClassAttributes(ReflectionClass $class) : array |
| 20 | { |
| 21 | return $this->convertToAttributeInstances($class->getAttributes()); |
| 22 | } |
| 23 | public function getMethodAttributes(ReflectionMethod $method) : array |
| 24 | { |
| 25 | return $this->convertToAttributeInstances($method->getAttributes()); |
| 26 | } |
| 27 | public function getPropertyAttributes(ReflectionProperty $property) : array |
| 28 | { |
| 29 | return $this->convertToAttributeInstances($property->getAttributes()); |
| 30 | } |
| 31 | public function getPropertyAttribute(ReflectionProperty $property, $attributeName) |
| 32 | { |
| 33 | if ($this->isRepeatable($attributeName)) { |
| 34 | throw new LogicException(sprintf('The attribute "%s" is repeatable. Call getPropertyAttributeCollection() instead.', $attributeName)); |
| 35 | } |
| 36 | return $this->getPropertyAttributes($property)[$attributeName] ?? null; |
| 37 | } |
| 38 | public function getPropertyAttributeCollection(ReflectionProperty $property, string $attributeName) : RepeatableAttributeCollection |
| 39 | { |
| 40 | if (!$this->isRepeatable($attributeName)) { |
| 41 | throw new LogicException(sprintf('The attribute "%s" is not repeatable. Call getPropertyAttribute() instead.', $attributeName)); |
| 42 | } |
| 43 | return $this->getPropertyAttributes($property)[$attributeName] ?? new RepeatableAttributeCollection(); |
| 44 | } |
| 45 | private function convertToAttributeInstances(array $attributes) : array |
| 46 | { |
| 47 | $instances = []; |
| 48 | foreach ($attributes as $attribute) { |
| 49 | $attributeName = $attribute->getName(); |
| 50 | assert(is_string($attributeName)); |
| 51 | // Make sure we only get Doctrine Attributes |
| 52 | if (!is_subclass_of($attributeName, Annotation::class)) { |
| 53 | continue; |
| 54 | } |
| 55 | $instance = $attribute->newInstance(); |
| 56 | assert($instance instanceof Annotation); |
| 57 | if ($this->isRepeatable($attributeName)) { |
| 58 | if (!isset($instances[$attributeName])) { |
| 59 | $instances[$attributeName] = new RepeatableAttributeCollection(); |
| 60 | } |
| 61 | $collection = $instances[$attributeName]; |
| 62 | assert($collection instanceof RepeatableAttributeCollection); |
| 63 | $collection[] = $instance; |
| 64 | } else { |
| 65 | $instances[$attributeName] = $instance; |
| 66 | } |
| 67 | } |
| 68 | return $instances; |
| 69 | } |
| 70 | private function isRepeatable(string $attributeClassName) : bool |
| 71 | { |
| 72 | if (isset($this->isRepeatableAttribute[$attributeClassName])) { |
| 73 | return $this->isRepeatableAttribute[$attributeClassName]; |
| 74 | } |
| 75 | $reflectionClass = new ReflectionClass($attributeClassName); |
| 76 | $attribute = $reflectionClass->getAttributes()[0]->newInstance(); |
| 77 | return $this->isRepeatableAttribute[$attributeClassName] = ($attribute->flags & Attribute::IS_REPEATABLE) > 0; |
| 78 | } |
| 79 | } |
| 80 |