Skip to content

Commit 1267d98

Browse files
authored
Merge pull request #51 from rebuy-de/attribute-support
Add attribute support, remove deprecations, unify `JMSParser`
2 parents cda5b7d + 9c1ea16 commit 1267d98

File tree

12 files changed

+175
-296
lines changed

12 files changed

+175
-296
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
* `JMSTypeParser::getTraversableClass` returns `Traversable::class` instead of `Doctrine\Common\Collections\Collection` for general traversable properties.
1111
* Dropped support for PHP 7
1212
* Adjusted code to not trigger warnings with PHP 8.4
13+
* Removed deprecated `getDeserializeFormat` method from date time
14+
* Add attribute support for the `@Preferred` annotation
1315

1416
# Version 1.x
1517

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"require": {
1717
"php": "^8.0",
1818
"ext-json": "*",
19-
"doctrine/annotations": "^1.13 || ^2.0.1",
19+
"doctrine/annotations": "^2.0.1",
2020
"psr/log": "^1|^2|^3"
2121
},
2222
"require-dev": {

src/Annotation/Preferred.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* @Annotation
1414
* @Target({"METHOD", "PROPERTY"})
1515
*/
16+
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
1617
final class Preferred
1718
{
1819
}

src/Metadata/DateTimeOptions.php

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ final class DateTimeOptions implements \JsonSerializable
2929
/**
3030
* @note Passing a string for $deserializeFormats is deprecated, please pass an array instead
3131
*
32-
* @param string[]|string|null $deserializeFormats
32+
* @param string[]|null $deserializeFormats
3333
*/
34-
public function __construct(?string $format, ?string $zone, $deserializeFormats)
34+
public function __construct(?string $format, ?string $zone, ?array $deserializeFormats)
3535
{
3636
$this->format = $format;
3737
$this->zone = $zone;
38-
$this->deserializeFormats = \is_string($deserializeFormats) ? [$deserializeFormats] : $deserializeFormats;
38+
$this->deserializeFormats = $deserializeFormats;
3939
}
4040

4141
public function getFormat(): ?string
@@ -48,18 +48,6 @@ public function getZone(): ?string
4848
return $this->zone;
4949
}
5050

51-
/**
52-
* @deprecated Please use {@see getDeserializeFormats}
53-
*/
54-
public function getDeserializeFormat(): ?string
55-
{
56-
foreach ($this->deserializeFormats ?? [] as $format) {
57-
return $format;
58-
}
59-
60-
return null;
61-
}
62-
6351
public function getDeserializeFormats(): ?array
6452
{
6553
return $this->deserializeFormats;
@@ -70,7 +58,6 @@ public function jsonSerialize(): array
7058
return array_filter([
7159
'format' => $this->format,
7260
'zone' => $this->zone,
73-
'deserialize_format' => $this->getDeserializeFormat(),
7461
'deserialize_formats' => $this->deserializeFormats,
7562
]);
7663
}

src/Metadata/PropertyTypeDateTime.php

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,6 @@ public function getZone(): ?string
5858
return null;
5959
}
6060

61-
/**
62-
* @deprecated Please prefer {@link getDeserializeFormats}
63-
*/
64-
public function getDeserializeFormat(): ?string
65-
{
66-
if ($this->dateTimeOptions) {
67-
return $this->dateTimeOptions->getDeserializeFormat();
68-
}
69-
70-
return null;
71-
}
72-
7361
public function getDeserializeFormats(): ?array
7462
{
7563
if ($this->dateTimeOptions) {

src/ModelParser/JMSParser.php

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
*
5353
* @internal
5454
*/
55-
abstract class BaseJMSParser implements ModelParserInterface
55+
final class JMSParser implements ModelParserInterface
5656
{
5757
private const ACCESS_ORDER_CUSTOM = 'custom';
5858

@@ -69,7 +69,7 @@ abstract class BaseJMSParser implements ModelParserInterface
6969
/**
7070
* @var JMSTypeParser
7171
*/
72-
protected $jmsTypeParser;
72+
private $jmsTypeParser;
7373

7474
public function __construct(Reader $annotationsReader)
7575
{
@@ -228,22 +228,9 @@ private function gatherClassAnnotations(\ReflectionClass $reflectionClass): arra
228228
return $map;
229229
}
230230

231-
/**
232-
* If the annotation is about readonly information, update the $property accordingly and return true.
233-
*
234-
* This check is extracted to have different implementations for PHP 8.1 and newer, and for older PHP versions.
235-
* If the method returns true, we don't try to match the annotation type.
236-
*
237-
* @return bool whether $annotation was a readonly information
238-
*/
239-
abstract protected function parsePropertyAnnotationsReadOnly(object $annotation, PropertyVariationMetadata $property): bool;
240-
241231
private function parsePropertyAnnotations(RawClassMetadata $classMetadata, PropertyVariationMetadata $property, array $annotations): void
242232
{
243233
foreach ($annotations as $annotation) {
244-
if ($this->parsePropertyAnnotationsReadOnly($annotation, $property)) {
245-
continue;
246-
}
247234
switch (true) {
248235
case $annotation instanceof Type:
249236
if (null === $annotation->name) {
@@ -289,6 +276,10 @@ private function parsePropertyAnnotations(RawClassMetadata $classMetadata, Prope
289276
$property->setVersionRange($property->getVersionRange()->withUntil($annotation->version));
290277
break;
291278

279+
case $annotation instanceof ReadOnlyProperty:
280+
$property->setReadOnly(true);
281+
break;
282+
292283
case $annotation instanceof MaxDepth:
293284
$property->setMaxDepth($annotation->depth);
294285
break;
@@ -430,24 +421,3 @@ private function getMethodName(array $annotations, \ReflectionMethod $reflMethod
430421
return $name;
431422
}
432423
}
433-
434-
if (\PHP_VERSION_ID > 80100) {
435-
/**
436-
* Version for PHP 8.1+ without the ReadOnly annotation.
437-
*/
438-
final class JMSParser extends BaseJMSParser
439-
{
440-
protected function parsePropertyAnnotationsReadOnly(object $annotation, PropertyVariationMetadata $property): bool
441-
{
442-
if ($annotation instanceof ReadOnlyProperty) {
443-
$property->setReadOnly($annotation->readOnly);
444-
445-
return true;
446-
}
447-
448-
return false;
449-
}
450-
}
451-
} else {
452-
require 'JMSParserLegacy.php';
453-
}

src/ModelParser/JMSParserLegacy.php

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/ModelParser/LiipMetadataAnnotationParser.php

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@
2121
*/
2222
final class LiipMetadataAnnotationParser implements ModelParserInterface
2323
{
24-
/**
25-
* @var Reader
26-
*/
27-
private $annotationsReader;
24+
private Reader $annotationsReader;
2825

2926
public function __construct(Reader $annotationsReader)
3027
{
@@ -54,11 +51,7 @@ private function parseProperties(\ReflectionClass $reflClass, RawClassMetadata $
5451
continue;
5552
}
5653

57-
try {
58-
$annotations = $this->annotationsReader->getPropertyAnnotations($reflProperty);
59-
} catch (AnnotationException $e) {
60-
throw ParseException::propertyError((string) $classMetadata, $reflProperty->getName(), $e);
61-
}
54+
$annotations = $this->getPropertyAnnotations($classMetadata, $reflProperty);
6255

6356
$property = $classMetadata->getPropertyVariation($reflProperty->getName());
6457
$this->parsePropertyAnnotations($classMetadata, $property, $annotations);
@@ -79,11 +72,7 @@ private function parseMethods(\ReflectionClass $reflClass, RawClassMetadata $cla
7972
continue;
8073
}
8174

82-
try {
83-
$annotations = $this->annotationsReader->getMethodAnnotations($reflMethod);
84-
} catch (AnnotationException $e) {
85-
throw ParseException::propertyError((string) $classMetadata, $reflMethod->getName(), $e);
86-
}
75+
$annotations = $this->getMethodAnnotations($classMetadata, $reflMethod);
8776

8877
$property = $classMetadata->getPropertyVariation($this->getMethodName($reflMethod));
8978
$this->parsePropertyAnnotations($classMetadata, $property, $annotations);
@@ -117,4 +106,38 @@ private function getMethodName(\ReflectionMethod $reflMethod): string
117106

118107
return $name;
119108
}
109+
110+
private function getMethodAnnotations(RawClassMetadata $classMetadata, \ReflectionMethod $reflectionMethod): array
111+
{
112+
try {
113+
$annotations = $this->annotationsReader->getMethodAnnotations($reflectionMethod);
114+
} catch (AnnotationException $e) {
115+
throw ParseException::propertyError((string) $classMetadata, $reflectionMethod->getName(), $e);
116+
}
117+
118+
$attributes = $reflectionMethod->getAttributes();
119+
$attributes = array_map(
120+
static fn (\ReflectionAttribute $attribute) => $attribute->newInstance(),
121+
$attributes
122+
);
123+
124+
return array_merge($attributes, $annotations);
125+
}
126+
127+
private function getPropertyAnnotations(RawClassMetadata $classMetadata, \ReflectionProperty $reflectionProperty): array
128+
{
129+
try {
130+
$annotations = $this->annotationsReader->getPropertyAnnotations($reflectionProperty);
131+
} catch (AnnotationException $e) {
132+
throw ParseException::propertyError((string) $classMetadata, $reflectionProperty->getName(), $e);
133+
}
134+
135+
$attributes = $reflectionProperty->getAttributes();
136+
$attributes = array_map(
137+
static fn (\ReflectionAttribute $attribute) => $attribute->newInstance(),
138+
$attributes
139+
);
140+
141+
return array_merge($attributes, $annotations);
142+
}
120143
}

0 commit comments

Comments
 (0)