Skip to content

Commit 469fe64

Browse files
committed
what I would like
1 parent a232425 commit 469fe64

File tree

7 files changed

+167
-93
lines changed

7 files changed

+167
-93
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
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\Metadata\Resource\Factory;
15+
16+
use ApiPlatform\Metadata\Operations;
17+
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
18+
19+
/**
20+
* Triggers resource deprecations.
21+
*
22+
* @internal
23+
*/
24+
final class BackedEnumResourceMetadataCollectionFactory implements ResourceMetadataCollectionFactoryInterface
25+
{
26+
public const PROVIDER = 'api_platform.state_provider.backed_enum';
27+
public function __construct(private readonly ResourceMetadataCollectionFactoryInterface $decorated)
28+
{
29+
}
30+
31+
public function create(string $resourceClass): ResourceMetadataCollection
32+
{
33+
$resourceMetadataCollection = $this->decorated->create($resourceClass);
34+
if (!is_a($resourceClass, \BackedEnum::class, true)) {
35+
return $resourceMetadataCollection;
36+
}
37+
38+
foreach ($resourceMetadataCollection as $i => $resourceMetadata) {
39+
$newOperations = [];
40+
foreach ($resourceMetadata->getOperations() as $operationName => $operation) {
41+
$newOperations[$operationName] = $operation;
42+
43+
if (null !== $operation->getProvider()) {
44+
continue;
45+
}
46+
47+
$newOperations[$operationName] = $operation->withProvider(self::PROVIDER);
48+
}
49+
50+
$newGraphQlOperations = [];
51+
foreach ($resourceMetadata->getGraphQlOperations() as $operationName => $operation) {
52+
$newGraphQlOperations[$operationName] = $operation;
53+
54+
if (null !== $operation->getProvider()) {
55+
continue;
56+
}
57+
58+
$newGraphQlOperations[$operationName] = $operation->withProvider(self::PROVIDER);
59+
}
60+
61+
$resourceMetadataCollection[$i] = $resourceMetadata->withOperations(new Operations($newOperations))->withGraphQlOperations($newGraphQlOperations);
62+
}
63+
64+
return $resourceMetadataCollection;
65+
}
66+
}

src/State/Provider/BackedEnumProvider.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,18 @@
1414
namespace ApiPlatform\State\Provider;
1515

1616
use ApiPlatform\Metadata\CollectionOperationInterface;
17+
use ApiPlatform\Metadata\Exception\RuntimeException;
1718
use ApiPlatform\Metadata\Operation;
1819
use ApiPlatform\State\ProviderInterface;
1920
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
2021

2122
final class BackedEnumProvider implements ProviderInterface
2223
{
23-
public function __construct(private ProviderInterface $decorated)
24-
{
25-
}
26-
2724
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
2825
{
2926
$resourceClass = $operation->getClass();
3027
if (!$resourceClass || !is_a($resourceClass, \BackedEnum::class, true)) {
31-
return $this->decorated->provide($operation, $uriVariables, $context);
28+
throw new RuntimeException('This resource is not an enum');
3229
}
3330

3431
if ($operation instanceof CollectionOperationInterface) {

src/Symfony/Bundle/Resources/config/graphql.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,6 @@
146146
<service id="api_platform.graphql.state_provider" alias="api_platform.state_provider.locator" />
147147
<service id="api_platform.graphql.state_processor" alias="api_platform.graphql.state_processor.normalize" />
148148

149-
<service id="api_platform.graphql.state_provider.backed_enum" class="ApiPlatform\State\Provider\BackedEnumProvider" decorates="api_platform.graphql.state_provider" decoration-priority="450">
150-
<argument type="service" id="api_platform.graphql.state_provider.backed_enum.inner" />
151-
</service>
152-
153149
<service id="api_platform.graphql.state_provider.read" class="ApiPlatform\GraphQl\State\Provider\ReadProvider" decorates="api_platform.graphql.state_provider" decoration-priority="500">
154150
<argument type="service" id="api_platform.graphql.state_provider.read.inner" />
155151
<argument type="service" id="api_platform.symfony.iri_converter" />

src/Symfony/Bundle/Resources/config/metadata/resource.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
<argument type="service" id="api_platform.metadata.resource.metadata_collection_factory.not_exposed_operation.inner" />
3030
</service>
3131

32+
<service id="api_platform.metadata.resource.metadata_collection_factory.backed_enum" class="ApiPlatform\Metadata\Resource\Factory\BackedEnumResourceMetadataCollectionFactory" decorates="api_platform.metadata.resource.metadata_collection_factory" decoration-priority="500" public="false">
33+
<argument type="service" id="api_platform.metadata.resource.metadata_collection_factory.backed_enum.inner" />
34+
</service>
35+
3236
<service id="api_platform.metadata.resource.metadata_collection_factory.uri_template" class="ApiPlatform\Metadata\Resource\Factory\UriTemplateResourceMetadataCollectionFactory" decorates="api_platform.metadata.resource.metadata_collection_factory" decoration-priority="500" public="false">
3337
<argument type="service" id="api_platform.metadata.resource.link_factory" />
3438
<argument type="service" id="api_platform.path_segment_name_generator" />

src/Symfony/Bundle/Resources/config/state/provider.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@
2525
<argument type="service" id="translator" on-invalid="null" />
2626
</service>
2727

28-
<service id="api_platform.state_provider.backed_enum" class="ApiPlatform\State\Provider\BackedEnumProvider" decorates="api_platform.state_provider.main" decoration-priority="300">
29-
<argument type="service" id="api_platform.state_provider.backed_enum.inner" />
28+
<service id="api_platform.state_provider.backed_enum" class="ApiPlatform\State\Provider\BackedEnumProvider">
29+
<tag name="api_platform.state_provider" key="ApiPlatform\State\Provider\BackedEnumProvidevr" />
30+
<tag name="api_platform.state_provider" key="api_platform.state_provider.backed_enum" />
3031
</service>
3132

3233
<service id="api_platform.error_listener" class="ApiPlatform\Symfony\EventListener\ErrorListener">

tests/Fixtures/TestBundle/ApiResource/Issue6264/Availability.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,20 @@
1616
use ApiPlatform\Metadata\ApiResource;
1717
use ApiPlatform\Metadata\Get;
1818
use ApiPlatform\Metadata\GetCollection;
19+
use ApiPlatform\Metadata\GraphQl\Query;
20+
use ApiPlatform\Metadata\GraphQl\QueryCollection;
1921

20-
#[ApiResource(normalizationContext: ['groups' => ['get']])]
21-
#[GetCollection(provider: Availability::class.'::getCases')]
22-
#[Get(provider: Availability::class.'::getCase')]
22+
#[ApiResource(
23+
normalizationContext: ['groups' => ['get']],
24+
operations: [
25+
new GetCollection(provider: Availability::class.'::getCases'),
26+
new Get(provider: Availability::class.'::getCase')
27+
],
28+
graphQlOperations: [
29+
new Query(),
30+
new QueryCollection(),
31+
]
32+
)]
2333
enum Availability: int
2434
{
2535
use BackedEnumTrait;

tests/Functional/BackedEnumResourceTest.php

Lines changed: 79 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -99,49 +99,6 @@ public function testItemJson(string $uri, string $mimeType, array $expected): vo
9999
$this->assertJsonEquals($expected);
100100
}
101101

102-
public static function providerEnumItemsGraphQl(): iterable
103-
{
104-
// Integer cases
105-
$query = <<<'GRAPHQL'
106-
query GetAvailability($identifier: ID!) {
107-
availability(id: $identifier) {
108-
value
109-
}
110-
}
111-
GRAPHQL;
112-
foreach (Availability::cases() as $case) {
113-
yield [$query, ['identifier' => '/availabilities/'.$case->value], ['data' => ['availability' => ['value' => $case->value]]]];
114-
}
115-
116-
// String cases
117-
$query = <<<'GRAPHQL'
118-
query GetAvailabilityStatus($identifier: ID!) {
119-
availabilityStatus(id: $identifier) {
120-
value
121-
}
122-
}
123-
GRAPHQL;
124-
foreach (AvailabilityStatus::cases() as $case) {
125-
yield [$query, ['identifier' => '/availability_statuses/'.$case->value], ['data' => ['availability_status' => ['value' => $case->value]]]];
126-
}
127-
}
128-
129-
/**
130-
* @dataProvider providerEnumItemsGraphQl
131-
*
132-
* @group legacy
133-
*/
134-
public function testItemGraphql(string $query, array $variables, array $expected): void
135-
{
136-
$options = (new HttpOptions())
137-
->setJson(['query' => $query, 'variables' => $variables])
138-
->setHeaders(['Content-Type' => 'application/json']);
139-
self::createClient()->request('POST', '/graphql', $options->toArray());
140-
141-
$this->assertResponseIsSuccessful();
142-
$this->assertJsonEquals($expected);
143-
}
144-
145102
public function testCollectionJson(): void
146103
{
147104
self::createClient()->request('GET', '/availabilities', ['headers' => ['Accept' => 'application/json']]);
@@ -500,32 +457,89 @@ public function testItem(string $mimeType, array $expected): void
500457
$this->assertJsonEquals($expected);
501458
}
502459

503-
public function testCollectionGraphQl(): void
460+
public static function provider404s(): iterable
504461
{
505-
$query = <<<'GRAPHQL'
506-
query {
507-
backedEnumIntegerResources {
508-
value
509-
}
510-
}
511-
GRAPHQL;
512-
$options = (new HttpOptions())
513-
->setJson(['query' => $query, 'variables' => []])
514-
->setHeaders(['Content-Type' => 'application/json']);
515-
self::createClient()->request('POST', '/graphql', $options->toArray());
462+
yield ['/backed_enum_integer_resources/42'];
463+
yield ['/backed_enum_integer_resources/fortytwo'];
464+
}
516465

517-
$this->assertResponseIsSuccessful();
518-
$this->assertJsonEquals([
519-
'data' => [
520-
'backedEnumIntegerResources' => [
521-
['value' => 1],
522-
['value' => 2],
523-
['value' => 3],
524-
],
525-
],
526-
]);
466+
/** @dataProvider provider404s */
467+
public function testItem404(string $uri): void
468+
{
469+
self::createClient()->request('GET', $uri);
470+
471+
$this->assertResponseStatusCodeSame(404);
527472
}
528473

474+
// public static function providerEnumItemsGraphQl(): iterable
475+
// {
476+
// // Integer cases
477+
// $query = <<<'GRAPHQL'
478+
// query GetAvailability($identifier: ID!) {
479+
// availability(id: $identifier) {
480+
// value
481+
// }
482+
// }
483+
// GRAPHQL;
484+
// foreach (Availability::cases() as $case) {
485+
// yield [$query, ['identifier' => '/availabilities/'.$case->value], ['data' => ['availability' => ['value' => $case->value]]]];
486+
// }
487+
//
488+
// // String cases
489+
// $query = <<<'GRAPHQL'
490+
// query GetAvailabilityStatus($identifier: ID!) {
491+
// availabilityStatus(id: $identifier) {
492+
// value
493+
// }
494+
// }
495+
// GRAPHQL;
496+
// foreach (AvailabilityStatus::cases() as $case) {
497+
// yield [$query, ['identifier' => '/availability_statuses/'.$case->value], ['data' => ['availability_status' => ['value' => $case->value]]]];
498+
// }
499+
// }
500+
//
501+
// /**
502+
// * @dataProvider providerEnumItemsGraphQl
503+
// *
504+
// * @group legacy
505+
// */
506+
// public function testItemGraphql(string $query, array $variables, array $expected): void
507+
// {
508+
// $options = (new HttpOptions())
509+
// ->setJson(['query' => $query, 'variables' => $variables])
510+
// ->setHeaders(['Content-Type' => 'application/json']);
511+
// self::createClient()->request('POST', '/graphql', $options->toArray());
512+
//
513+
// $this->assertResponseIsSuccessful();
514+
// $this->assertJsonEquals($expected);
515+
// }
516+
//
517+
// public function testCollectionGraphQl(): void
518+
// {
519+
// $query = <<<'GRAPHQL'
520+
// query {
521+
// backedEnumIntegerResources {
522+
// value
523+
// }
524+
// }
525+
// GRAPHQL;
526+
// $options = (new HttpOptions())
527+
// ->setJson(['query' => $query, 'variables' => []])
528+
// ->setHeaders(['Content-Type' => 'application/json']);
529+
// self::createClient()->request('POST', '/graphql', $options->toArray());
530+
//
531+
// $this->assertResponseIsSuccessful();
532+
// $this->assertJsonEquals([
533+
// 'data' => [
534+
// 'backedEnumIntegerResources' => [
535+
// ['value' => 1],
536+
// ['value' => 2],
537+
// ['value' => 3],
538+
// ],
539+
// ],
540+
// ]);
541+
// }
542+
529543
public function testItemGraphQlInteger(): void
530544
{
531545
$query = <<<'GRAPHQL'
@@ -551,18 +565,4 @@ public function testItemGraphQlInteger(): void
551565
],
552566
]);
553567
}
554-
555-
public static function provider404s(): iterable
556-
{
557-
yield ['/backed_enum_integer_resources/42'];
558-
yield ['/backed_enum_integer_resources/fortytwo'];
559-
}
560-
561-
/** @dataProvider provider404s */
562-
public function testItem404(string $uri): void
563-
{
564-
self::createClient()->request('GET', $uri);
565-
566-
$this->assertResponseStatusCodeSame(404);
567-
}
568568
}

0 commit comments

Comments
 (0)