|
4 | 4 |
|
5 | 5 | namespace Tmi\TranslationBundle\Utils; |
6 | 6 |
|
7 | | -use Doctrine\ORM\Mapping\Column; |
8 | | -use Doctrine\ORM\Mapping\Embedded; |
9 | | -use Doctrine\ORM\Mapping\Id; |
10 | | -use Doctrine\ORM\Mapping\ManyToMany; |
11 | | -use Doctrine\ORM\Mapping\ManyToOne; |
12 | | -use Doctrine\ORM\Mapping\OneToMany; |
13 | | -use Doctrine\ORM\Mapping\OneToOne; |
14 | | -use Tmi\TranslationBundle\Doctrine\Attribute\EmptyOnTranslate; |
15 | | -use Tmi\TranslationBundle\Doctrine\Attribute\SharedAmongstTranslations; |
| 7 | +use Doctrine\ORM\Mapping as ORM; |
| 8 | +use Tmi\TranslationBundle\Doctrine\Attribute as TranslationAttribute; |
16 | 9 |
|
17 | 10 | class AttributeHelper |
18 | 11 | { |
| 12 | + private const array DOCTRINE_ATTRIBUTES = [ |
| 13 | + 'isEmbedded' => ORM\Embedded::class, |
| 14 | + 'isOneToOne' => ORM\OneToOne::class, |
| 15 | + 'isId' => ORM\Id::class, |
| 16 | + 'isManyToOne' => ORM\ManyToOne::class, |
| 17 | + 'isOneToMany' => ORM\OneToMany::class, |
| 18 | + 'isManyToMany' => ORM\ManyToMany::class, |
| 19 | + ]; |
| 20 | + |
| 21 | + private const array TRANSLATION_ATTRIBUTES = [ |
| 22 | + 'isSharedAmongstTranslations' => TranslationAttribute\SharedAmongstTranslations::class, |
| 23 | + 'isEmptyOnTranslate' => TranslationAttribute\EmptyOnTranslate::class, |
| 24 | + ]; |
| 25 | + |
19 | 26 | /** |
20 | 27 | * Defines if the property is embedded. |
21 | 28 | */ |
22 | 29 | public function isEmbedded(\ReflectionProperty $property): bool |
23 | 30 | { |
24 | | - return [] !== $property->getAttributes(Embedded::class, \ReflectionAttribute::IS_INSTANCEOF); |
| 31 | + return $this->hasAttribute($property, self::DOCTRINE_ATTRIBUTES[__FUNCTION__]); |
25 | 32 | } |
26 | 33 |
|
27 | 34 | /** |
28 | 35 | * Defines if the property is to be shared amongst parents' translations. |
29 | 36 | */ |
30 | 37 | public function isSharedAmongstTranslations(\ReflectionProperty $property): bool |
31 | 38 | { |
32 | | - return [] !== $property->getAttributes(SharedAmongstTranslations::class, \ReflectionAttribute::IS_INSTANCEOF); |
| 39 | + return $this->hasAttribute($property, self::TRANSLATION_ATTRIBUTES[__FUNCTION__]); |
33 | 40 | } |
34 | 41 |
|
35 | 42 | /** |
36 | 43 | * Defines if the property should be emptied on translate. |
37 | 44 | */ |
38 | 45 | public function isEmptyOnTranslate(\ReflectionProperty $property): bool |
39 | 46 | { |
40 | | - return [] !== $property->getAttributes(EmptyOnTranslate::class, \ReflectionAttribute::IS_INSTANCEOF); |
| 47 | + return $this->hasAttribute($property, self::TRANSLATION_ATTRIBUTES[__FUNCTION__]); |
41 | 48 | } |
42 | 49 |
|
43 | 50 | /** |
44 | 51 | * Defines if the property is a OneToOne relation. |
45 | 52 | */ |
46 | 53 | public function isOneToOne(\ReflectionProperty $property): bool |
47 | 54 | { |
48 | | - return [] !== $property->getAttributes(OneToOne::class, \ReflectionAttribute::IS_INSTANCEOF); |
| 55 | + return $this->hasAttribute($property, self::DOCTRINE_ATTRIBUTES[__FUNCTION__]); |
49 | 56 | } |
50 | 57 |
|
51 | 58 | /** |
52 | 59 | * Defines if the property is an ID. |
53 | 60 | */ |
54 | 61 | public function isId(\ReflectionProperty $property): bool |
55 | 62 | { |
56 | | - return [] !== $property->getAttributes(Id::class, \ReflectionAttribute::IS_INSTANCEOF); |
| 63 | + return $this->hasAttribute($property, self::DOCTRINE_ATTRIBUTES[__FUNCTION__]); |
57 | 64 | } |
58 | 65 |
|
59 | 66 | /** |
60 | 67 | * Defines if the property is a ManyToOne relation. |
61 | 68 | */ |
62 | 69 | public function isManyToOne(\ReflectionProperty $property): bool |
63 | 70 | { |
64 | | - return [] !== $property->getAttributes(ManyToOne::class, \ReflectionAttribute::IS_INSTANCEOF); |
| 71 | + return $this->hasAttribute($property, self::DOCTRINE_ATTRIBUTES[__FUNCTION__]); |
65 | 72 | } |
66 | 73 |
|
67 | 74 | /** |
68 | | - * Defines if the property is a ManyToOne relation. |
| 75 | + * Defines if the property is a OneToMany relation. |
69 | 76 | */ |
70 | 77 | public function isOneToMany(\ReflectionProperty $property): bool |
71 | 78 | { |
72 | | - return [] !== $property->getAttributes(OneToMany::class, \ReflectionAttribute::IS_INSTANCEOF); |
| 79 | + return $this->hasAttribute($property, self::DOCTRINE_ATTRIBUTES[__FUNCTION__]); |
73 | 80 | } |
74 | 81 |
|
75 | 82 | /** |
76 | 83 | * Defines if the property is a ManyToMany relation. |
77 | 84 | */ |
78 | 85 | public function isManyToMany(\ReflectionProperty $property): bool |
79 | 86 | { |
80 | | - return [] !== $property->getAttributes(ManyToMany::class, \ReflectionAttribute::IS_INSTANCEOF); |
| 87 | + return $this->hasAttribute($property, self::DOCTRINE_ATTRIBUTES[__FUNCTION__]); |
81 | 88 | } |
82 | 89 |
|
83 | 90 | /** |
84 | 91 | * Defines if the property can be null. |
85 | 92 | */ |
86 | 93 | public function isNullable(\ReflectionProperty $property): bool |
87 | 94 | { |
88 | | - $ra = $property->getAttributes(Column::class, \ReflectionAttribute::IS_INSTANCEOF); |
89 | | - |
90 | | - if (0 < count($ra)) { |
91 | | - $ra = reset($ra); |
92 | | - $args = $ra->getArguments(); |
| 95 | + $type = $property->getType(); |
93 | 96 |
|
94 | | - return array_key_exists('nullable', $args) && true === $args['nullable']; |
95 | | - } |
| 97 | + return $type && $type->allowsNull(); |
| 98 | + } |
96 | 99 |
|
97 | | - return true; |
| 100 | + /** |
| 101 | + * Generic attribute check with consistent configuration. |
| 102 | + */ |
| 103 | + private function hasAttribute(\ReflectionProperty $property, string $attributeClass): bool |
| 104 | + { |
| 105 | + return [] !== $property->getAttributes($attributeClass, \ReflectionAttribute::IS_INSTANCEOF); |
98 | 106 | } |
99 | 107 | } |
0 commit comments