Skip to content

Commit fc639ea

Browse files
fix(metadata): do not auto-generate NotExposed operation when using custom operation classes
* fix(metadata): do not auto-generate NotExposed operation when using custom operation classes * Update src/Metadata/Resource/Factory/NotExposedOperationResourceMetadataCollectionFactory.php Co-authored-by: Antoine Bluchet <[email protected]>
1 parent 11ed63d commit fc639ea

File tree

3 files changed

+79
-2
lines changed

3 files changed

+79
-2
lines changed

src/Metadata/Resource/Factory/NotExposedOperationResourceMetadataCollectionFactory.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Metadata\Resource\Factory;
1515

1616
use ApiPlatform\Metadata\ApiResource;
17+
use ApiPlatform\Metadata\CollectionOperationInterface;
1718
use ApiPlatform\Metadata\Get;
1819
use ApiPlatform\Metadata\HttpOperation;
1920
use ApiPlatform\Metadata\NotExposed;
@@ -58,7 +59,7 @@ public function create(string $resourceClass): ResourceMetadataCollection
5859

5960
foreach ($operations as $operation) {
6061
// An item operation has been found, nothing to do anymore in this factory
61-
if ($operation instanceof Get || ($operation->getExtraProperties()['is_legacy_resource_metadata'] ?? false)) {
62+
if ((HttpOperation::METHOD_GET === $operation->getMethod() && !$operation instanceof CollectionOperationInterface) || ($operation->getExtraProperties()['is_legacy_resource_metadata'] ?? false)) {
6263
return $resourceMetadataCollection;
6364
}
6465
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Tests\Fixtures\TestBundle\Metadata;
15+
16+
use ApiPlatform\Metadata\HttpOperation;
17+
18+
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
19+
final class Get extends HttpOperation
20+
{
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
public function __construct(...$args)
25+
{
26+
parent::__construct(self::METHOD_GET, ...$args);
27+
}
28+
}

tests/Metadata/Resource/Factory/NotExposedOperationResourceMetadataCollectionFactoryTest.php

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
2525
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
2626
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\AttributeResource;
27+
use ApiPlatform\Tests\Fixtures\TestBundle\Metadata\Get as CustomGet;
2728
use ApiPlatform\Tests\ProphecyTrait;
2829
use PHPUnit\Framework\TestCase;
2930
use Prophecy\Argument;
@@ -68,8 +69,8 @@ class: AttributeResource::class
6869
new ApiResource(
6970
shortName: 'AttributeResource',
7071
operations: [
71-
'_api_AttributeResource_get' => new Get(uriVariables: ['id' => new Link(fromClass: AttributeResource::class, identifiers: ['id'])], controller: 'api_platform.action.placeholder', shortName: 'AttributeResource', class: AttributeResource::class),
7272
'_api_AttributeResource_get_collection' => new GetCollection(controller: 'api_platform.action.placeholder', shortName: 'AttributeResource', class: AttributeResource::class),
73+
'_api_AttributeResource_get' => new Get(uriVariables: ['id' => new Link(fromClass: AttributeResource::class, identifiers: ['id'])], controller: 'api_platform.action.placeholder', shortName: 'AttributeResource', class: AttributeResource::class),
7374
],
7475
uriVariables: ['id' => new Link(fromClass: AttributeResource::class, identifiers: ['id'])],
7576
class: AttributeResource::class
@@ -88,8 +89,55 @@ class: AttributeResource::class
8889
new ApiResource(
8990
shortName: 'AttributeResource',
9091
operations: [
92+
'_api_AttributeResource_get_collection' => new GetCollection(controller: 'api_platform.action.placeholder', shortName: 'AttributeResource', class: AttributeResource::class),
9193
'_api_AttributeResource_get' => new Get(uriVariables: ['id' => new Link(fromClass: AttributeResource::class, identifiers: ['id'])], controller: 'api_platform.action.placeholder', shortName: 'AttributeResource', class: AttributeResource::class),
94+
],
95+
uriVariables: ['id' => new Link(fromClass: AttributeResource::class, identifiers: ['id'])],
96+
class: AttributeResource::class
97+
),
98+
]),
99+
$factory->create(AttributeResource::class)
100+
);
101+
}
102+
103+
public function testItIgnoresResourcesWithAnItemOperationUsingCustomClass()
104+
{
105+
$linkFactoryProphecy = $this->prophesize(LinkFactoryInterface::class);
106+
$linkFactoryProphecy->createLinksFromIdentifiers(Argument::type(HttpOperation::class))->shouldNotBeCalled();
107+
108+
$resourceCollectionMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
109+
$resourceCollectionMetadataFactoryProphecy->create(AttributeResource::class)->willReturn(
110+
new ResourceMetadataCollection(AttributeResource::class, [
111+
new ApiResource(
112+
shortName: 'AttributeResource',
113+
operations: [],
114+
class: AttributeResource::class
115+
),
116+
new ApiResource(
117+
shortName: 'AttributeResource',
118+
operations: [
119+
'_api_AttributeResource_get_collection' => new GetCollection(controller: 'api_platform.action.placeholder', shortName: 'AttributeResource', class: AttributeResource::class),
120+
'_api_AttributeResource_get' => new CustomGet(uriVariables: ['id' => new Link(fromClass: AttributeResource::class, identifiers: ['id'])], controller: 'api_platform.action.placeholder', shortName: 'AttributeResource', class: AttributeResource::class),
121+
],
122+
uriVariables: ['id' => new Link(fromClass: AttributeResource::class, identifiers: ['id'])],
123+
class: AttributeResource::class
124+
),
125+
]),
126+
);
127+
128+
$factory = new NotExposedOperationResourceMetadataCollectionFactory($linkFactoryProphecy->reveal(), $resourceCollectionMetadataFactoryProphecy->reveal());
129+
$this->assertEquals(
130+
new ResourceMetadataCollection(AttributeResource::class, [
131+
new ApiResource(
132+
shortName: 'AttributeResource',
133+
operations: [],
134+
class: AttributeResource::class
135+
),
136+
new ApiResource(
137+
shortName: 'AttributeResource',
138+
operations: [
92139
'_api_AttributeResource_get_collection' => new GetCollection(controller: 'api_platform.action.placeholder', shortName: 'AttributeResource', class: AttributeResource::class),
140+
'_api_AttributeResource_get' => new CustomGet(uriVariables: ['id' => new Link(fromClass: AttributeResource::class, identifiers: ['id'])], controller: 'api_platform.action.placeholder', shortName: 'AttributeResource', class: AttributeResource::class),
93141
],
94142
uriVariables: ['id' => new Link(fromClass: AttributeResource::class, identifiers: ['id'])],
95143
class: AttributeResource::class

0 commit comments

Comments
 (0)