diff --git a/phpstan/ignore-by-php-version.neon.php b/phpstan/ignore-by-php-version.neon.php index a7156b63c..d5d5a0520 100644 --- a/phpstan/ignore-by-php-version.neon.php +++ b/phpstan/ignore-by-php-version.neon.php @@ -9,6 +9,9 @@ if (PHP_VERSION_ID < 80100) { $includes[] = __DIR__ . '/no-enum.neon'; } +if (PHP_VERSION_ID >= 80000) { + $includes[] = __DIR__ . '/ignore-missing-attribute.neon'; +} if (PHP_VERSION_ID >= 80100 && PHP_VERSION_ID < 80200) { $includes[] = __DIR__ . '/php-81.neon'; } diff --git a/phpstan/ignore-missing-attribute.neon b/phpstan/ignore-missing-attribute.neon new file mode 100644 index 000000000..22b569d97 --- /dev/null +++ b/phpstan/ignore-missing-attribute.neon @@ -0,0 +1,3 @@ +parameters: + ignoreErrors: + - '#^Attribute class JMS\\Serializer\\Tests\\Fixtures\\MissingAttribute does not exist\.$#' diff --git a/src/Metadata/Driver/AnnotationOrAttributeDriver.php b/src/Metadata/Driver/AnnotationOrAttributeDriver.php index 9f6f514c5..a3d14f035 100644 --- a/src/Metadata/Driver/AnnotationOrAttributeDriver.php +++ b/src/Metadata/Driver/AnnotationOrAttributeDriver.php @@ -48,6 +48,8 @@ use Metadata\Driver\DriverInterface; use Metadata\MethodMetadata; +use function array_filter; + class AnnotationOrAttributeDriver implements DriverInterface { use ExpressionMetadataTrait; @@ -309,7 +311,12 @@ protected function getClassAnnotations(\ReflectionClass $class): array static function (\ReflectionAttribute $attribute): object { return $attribute->newInstance(); }, - $class->getAttributes() + array_filter( + $class->getAttributes(), + static function (\ReflectionAttribute $attribute): bool { + return class_exists($attribute->getName()); + } + ) ); } @@ -332,7 +339,12 @@ protected function getMethodAnnotations(\ReflectionMethod $method): array static function (\ReflectionAttribute $attribute): object { return $attribute->newInstance(); }, - $method->getAttributes() + array_filter( + $method->getAttributes(), + static function (\ReflectionAttribute $attribute): bool { + return class_exists($attribute->getName()); + } + ) ); } @@ -355,7 +367,12 @@ protected function getPropertyAnnotations(\ReflectionProperty $property): array static function (\ReflectionAttribute $attribute): object { return $attribute->newInstance(); }, - $property->getAttributes() + array_filter( + $property->getAttributes(), + static function (\ReflectionAttribute $attribute): bool { + return class_exists($attribute->getName()); + } + ) ); } diff --git a/src/Metadata/Driver/AttributeDriver.php b/src/Metadata/Driver/AttributeDriver.php index 8d794c64b..8c2437613 100644 --- a/src/Metadata/Driver/AttributeDriver.php +++ b/src/Metadata/Driver/AttributeDriver.php @@ -4,6 +4,8 @@ namespace JMS\Serializer\Metadata\Driver; +use function array_filter; + class AttributeDriver extends AnnotationOrAttributeDriver { /** @@ -15,7 +17,12 @@ protected function getClassAnnotations(\ReflectionClass $class): array static function (\ReflectionAttribute $attribute): object { return $attribute->newInstance(); }, - $class->getAttributes() + array_filter( + $class->getAttributes(), + static function (\ReflectionAttribute $attribute): bool { + return class_exists($attribute->getName()); + } + ) ); } @@ -28,7 +35,12 @@ protected function getMethodAnnotations(\ReflectionMethod $method): array static function (\ReflectionAttribute $attribute): object { return $attribute->newInstance(); }, - $method->getAttributes() + array_filter( + $method->getAttributes(), + static function (\ReflectionAttribute $attribute): bool { + return class_exists($attribute->getName()); + } + ) ); } @@ -41,7 +53,12 @@ protected function getPropertyAnnotations(\ReflectionProperty $property): array static function (\ReflectionAttribute $attribute): object { return $attribute->newInstance(); }, - $property->getAttributes() + array_filter( + $property->getAttributes(), + static function (\ReflectionAttribute $attribute): bool { + return class_exists($attribute->getName()); + } + ) ); } } diff --git a/tests/Fixtures/MissingAttributeObject.php b/tests/Fixtures/MissingAttributeObject.php new file mode 100644 index 000000000..15f09af75 --- /dev/null +++ b/tests/Fixtures/MissingAttributeObject.php @@ -0,0 +1,24 @@ +markTestSkipped('Short expose syntax not supported on annotations or attribute'); } + + public function testCanHandleMissingAttributes(): void + { + $metadata = $this->getDriver()->loadMetadataForClass(new ReflectionClass(MissingAttributeObject::class)); + self::assertArrayHasKey('property', $metadata->propertyMetadata); + + if (PHP_VERSION_ID >= 80000) { + self::assertArrayHasKey('propertyFromMethod', $metadata->propertyMetadata); + } + } }