diff --git a/src/Metadata/Resource/Factory/AttributesResourceMetadataCollectionFactory.php b/src/Metadata/Resource/Factory/AttributesResourceMetadataCollectionFactory.php index dfd7babcb3c..7c839030cd1 100644 --- a/src/Metadata/Resource/Factory/AttributesResourceMetadataCollectionFactory.php +++ b/src/Metadata/Resource/Factory/AttributesResourceMetadataCollectionFactory.php @@ -84,7 +84,7 @@ private function buildResourceOperations(array $attributes, string $resourceClas $operationPriority = 0; foreach ($attributes as $attribute) { - if (ApiResource::class === $attribute->getName()) { + if (is_a($attribute->getName(), ApiResource::class, true)) { $resource = $this->getResourceWithDefaults($resourceClass, $shortName, $attribute->newInstance()); $operations = []; foreach ($resource->getOperations() ?? new Operations() as $operation) { @@ -165,7 +165,7 @@ private function buildResourceOperations(array $attributes, string $resourceClas private function hasResourceAttributes(\ReflectionClass $reflectionClass): bool { foreach ($reflectionClass->getAttributes() as $attribute) { - if (ApiResource::class === $attribute->getName() || is_subclass_of($attribute->getName(), HttpOperation::class) || is_subclass_of($attribute->getName(), GraphQlOperation::class)) { + if (is_a($attribute->getName(), ApiResource::class, true) || is_subclass_of($attribute->getName(), HttpOperation::class) || is_subclass_of($attribute->getName(), GraphQlOperation::class)) { return true; } } diff --git a/src/Metadata/Resource/Factory/AttributesResourceNameCollectionFactory.php b/src/Metadata/Resource/Factory/AttributesResourceNameCollectionFactory.php index cebfc8f9699..2c736fb307a 100644 --- a/src/Metadata/Resource/Factory/AttributesResourceNameCollectionFactory.php +++ b/src/Metadata/Resource/Factory/AttributesResourceNameCollectionFactory.php @@ -57,7 +57,7 @@ public function create(): ResourceNameCollection private function isResource(\ReflectionClass $reflectionClass): bool { - if ($reflectionClass->getAttributes(ApiResource::class)) { + if ($reflectionClass->getAttributes(ApiResource::class, \ReflectionAttribute::IS_INSTANCEOF)) { return true; } diff --git a/tests/Fixtures/TestBundle/Attributes/RestfulApi.php b/tests/Fixtures/TestBundle/Attributes/RestfulApi.php new file mode 100644 index 00000000000..30b07742817 --- /dev/null +++ b/tests/Fixtures/TestBundle/Attributes/RestfulApi.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Tests\Fixtures\TestBundle\Attributes; + +use ApiPlatform\Metadata\ApiResource; + +#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)] +class RestfulApi extends ApiResource +{ +} diff --git a/tests/Fixtures/TestBundle/Entity/InstanceOfApiResource.php b/tests/Fixtures/TestBundle/Entity/InstanceOfApiResource.php new file mode 100644 index 00000000000..66e00e39926 --- /dev/null +++ b/tests/Fixtures/TestBundle/Entity/InstanceOfApiResource.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Tests\Fixtures\TestBundle\Entity; + +use ApiPlatform\Tests\Fixtures\TestBundle\Attributes\RestfulApi; +use Doctrine\ORM\Mapping as ORM; + +#[RestfulApi] +#[ORM\Entity] +class InstanceOfApiResource +{ + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue(strategy: 'AUTO')] + private $id; + + public function __construct() + { + } + + public function getId() + { + return $this->id; + } +} diff --git a/tests/Metadata/Resource/Factory/AttributesResourceNameCollectionFactoryTest.php b/tests/Metadata/Resource/Factory/AttributesResourceNameCollectionFactoryTest.php new file mode 100644 index 00000000000..cdb4a6f3f66 --- /dev/null +++ b/tests/Metadata/Resource/Factory/AttributesResourceNameCollectionFactoryTest.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Tests\Metadata\Resource\Factory; + +use ApiPlatform\Metadata\Resource\Factory\AttributesResourceNameCollectionFactory; +use ApiPlatform\Tests\Fixtures\TestBundle\Entity\InstanceOfApiResource; +use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; + +/** + * @author Yoann Brieux + */ +class AttributesResourceNameCollectionFactoryTest extends TestCase +{ + use ProphecyTrait; + + public function testCreateWithInstanceOfApiResource(): void + { + $attributesResourceNameCollectionFactory = new AttributesResourceNameCollectionFactory(paths: [__DIR__.'/../../../Fixtures/TestBundle/Entity/']); + + $this->assertContains(InstanceOfApiResource::class, $attributesResourceNameCollectionFactory->create()->getIterator()); + } +}