Skip to content

Commit 4f0d4c1

Browse files
committed
use operation in graphql
1 parent b204609 commit 4f0d4c1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+404
-513
lines changed

src/GraphQl/Resolver/Factory/CollectionResolverFactory.php

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@
1313

1414
namespace ApiPlatform\GraphQl\Resolver\Factory;
1515

16-
use ApiPlatform\Exception\OperationNotFoundException;
1716
use ApiPlatform\GraphQl\Resolver\QueryCollectionResolverInterface;
1817
use ApiPlatform\GraphQl\Resolver\Stage\ReadStageInterface;
1918
use ApiPlatform\GraphQl\Resolver\Stage\SecurityPostDenormalizeStageInterface;
2019
use ApiPlatform\GraphQl\Resolver\Stage\SecurityStageInterface;
2120
use ApiPlatform\GraphQl\Resolver\Stage\SerializeStageInterface;
22-
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
21+
use ApiPlatform\Metadata\GraphQl\Operation;
2322
use ApiPlatform\Util\CloneTrait;
2423
use GraphQL\Type\Definition\ResolveInfo;
2524
use Psr\Container\ContainerInterface;
@@ -42,22 +41,20 @@ final class CollectionResolverFactory implements ResolverFactoryInterface
4241
private $serializeStage;
4342
private $queryResolverLocator;
4443
private $requestStack;
45-
private $resourceMetadataCollectionFactory;
4644

47-
public function __construct(ReadStageInterface $readStage, SecurityStageInterface $securityStage, SecurityPostDenormalizeStageInterface $securityPostDenormalizeStage, SerializeStageInterface $serializeStage, ContainerInterface $queryResolverLocator, ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, RequestStack $requestStack = null)
45+
public function __construct(ReadStageInterface $readStage, SecurityStageInterface $securityStage, SecurityPostDenormalizeStageInterface $securityPostDenormalizeStage, SerializeStageInterface $serializeStage, ContainerInterface $queryResolverLocator, RequestStack $requestStack = null)
4846
{
4947
$this->readStage = $readStage;
5048
$this->securityStage = $securityStage;
5149
$this->securityPostDenormalizeStage = $securityPostDenormalizeStage;
5250
$this->serializeStage = $serializeStage;
5351
$this->queryResolverLocator = $queryResolverLocator;
5452
$this->requestStack = $requestStack;
55-
$this->resourceMetadataCollectionFactory = $resourceMetadataCollectionFactory;
5653
}
5754

58-
public function __invoke(?string $resourceClass = null, ?string $rootClass = null, ?string $operationName = null): callable
55+
public function __invoke(?string $resourceClass = null, ?string $rootClass = null, ?Operation $operation = null): callable
5956
{
60-
return function (?array $source, array $args, $context, ResolveInfo $info) use ($resourceClass, $rootClass, $operationName) {
57+
return function (?array $source, array $args, $context, ResolveInfo $info) use ($resourceClass, $rootClass, $operation) {
6158
// If authorization has failed for a relation field (e.g. via ApiProperty security), the field is not present in the source: null can be returned directly to ensure the collection isn't in the response.
6259
if (null === $resourceClass || null === $rootClass || (null !== $source && !\array_key_exists($info->fieldName, $source))) {
6360
return null;
@@ -70,22 +67,14 @@ public function __invoke(?string $resourceClass = null, ?string $rootClass = nul
7067
);
7168
}
7269

73-
$operationName = $operationName ?? 'collection_query';
7470
$resolverContext = ['source' => $source, 'args' => $args, 'info' => $info, 'is_collection' => true, 'is_mutation' => false, 'is_subscription' => false];
7571

76-
$collection = ($this->readStage)($resourceClass, $rootClass, $operationName, $resolverContext);
72+
$collection = ($this->readStage)($resourceClass, $rootClass, $operation, $resolverContext);
7773
if (!is_iterable($collection)) {
7874
throw new \LogicException('Collection from read stage should be iterable.');
7975
}
8076

81-
$resourceMetadataCollection = $this->resourceMetadataCollectionFactory->create($resourceClass);
82-
try {
83-
$operation = $resourceMetadataCollection->getOperation($operationName);
84-
$queryResolverId = $operation->getResolver();
85-
} catch (OperationNotFoundException $e) {
86-
$queryResolverId = null;
87-
}
88-
77+
$queryResolverId = $operation->getResolver();
8978
if (null !== $queryResolverId) {
9079
/** @var QueryCollectionResolverInterface $queryResolver */
9180
$queryResolver = $this->queryResolverLocator->get($queryResolverId);
@@ -94,20 +83,20 @@ public function __invoke(?string $resourceClass = null, ?string $rootClass = nul
9483

9584
// Only perform security stage on the top-level query
9685
if (null === $source) {
97-
($this->securityStage)($resourceClass, $operationName, $resolverContext + [
86+
($this->securityStage)($resourceClass, $operation, $resolverContext + [
9887
'extra_variables' => [
9988
'object' => $collection,
10089
],
10190
]);
102-
($this->securityPostDenormalizeStage)($resourceClass, $operationName, $resolverContext + [
91+
($this->securityPostDenormalizeStage)($resourceClass, $operation, $resolverContext + [
10392
'extra_variables' => [
10493
'object' => $collection,
10594
'previous_object' => $this->clone($collection),
10695
],
10796
]);
10897
}
10998

110-
return ($this->serializeStage)($collection, $resourceClass, $operationName, $resolverContext);
99+
return ($this->serializeStage)($collection, $resourceClass, $operation, $resolverContext);
111100
};
112101
}
113102
}

src/GraphQl/Resolver/Factory/ItemMutationResolverFactory.php

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
use ApiPlatform\GraphQl\Resolver\Stage\SerializeStageInterface;
2323
use ApiPlatform\GraphQl\Resolver\Stage\ValidateStageInterface;
2424
use ApiPlatform\GraphQl\Resolver\Stage\WriteStageInterface;
25-
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
25+
use ApiPlatform\Metadata\DeleteOperationInterface;
26+
use ApiPlatform\Metadata\GraphQl\Operation;
2627
use ApiPlatform\Util\ClassInfoTrait;
2728
use ApiPlatform\Util\CloneTrait;
2829
use GraphQL\Type\Definition\ResolveInfo;
@@ -47,10 +48,9 @@ final class ItemMutationResolverFactory implements ResolverFactoryInterface
4748
private $writeStage;
4849
private $validateStage;
4950
private $mutationResolverLocator;
50-
private $resourceMetadataCollectionFactory;
5151
private $securityPostValidationStage;
5252

53-
public function __construct(ReadStageInterface $readStage, SecurityStageInterface $securityStage, SecurityPostDenormalizeStageInterface $securityPostDenormalizeStage, SerializeStageInterface $serializeStage, DeserializeStageInterface $deserializeStage, WriteStageInterface $writeStage, ValidateStageInterface $validateStage, ContainerInterface $mutationResolverLocator, ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, SecurityPostValidationStageInterface $securityPostValidationStage)
53+
public function __construct(ReadStageInterface $readStage, SecurityStageInterface $securityStage, SecurityPostDenormalizeStageInterface $securityPostDenormalizeStage, SerializeStageInterface $serializeStage, DeserializeStageInterface $deserializeStage, WriteStageInterface $writeStage, ValidateStageInterface $validateStage, ContainerInterface $mutationResolverLocator, SecurityPostValidationStageInterface $securityPostValidationStage)
5454
{
5555
$this->readStage = $readStage;
5656
$this->securityStage = $securityStage;
@@ -60,46 +60,42 @@ public function __construct(ReadStageInterface $readStage, SecurityStageInterfac
6060
$this->writeStage = $writeStage;
6161
$this->validateStage = $validateStage;
6262
$this->mutationResolverLocator = $mutationResolverLocator;
63-
$this->resourceMetadataCollectionFactory = $resourceMetadataCollectionFactory;
6463
$this->securityPostValidationStage = $securityPostValidationStage;
6564
}
6665

67-
public function __invoke(?string $resourceClass = null, ?string $rootClass = null, ?string $operationName = null): callable
66+
public function __invoke(?string $resourceClass = null, ?string $rootClass = null, ?Operation $operation = null): callable
6867
{
69-
return function (?array $source, array $args, $context, ResolveInfo $info) use ($resourceClass, $rootClass, $operationName) {
70-
if (null === $resourceClass || null === $operationName) {
68+
return function (?array $source, array $args, $context, ResolveInfo $info) use ($resourceClass, $rootClass, $operation) {
69+
if (null === $resourceClass || null === $operation) {
7170
return null;
7271
}
7372

7473
$resolverContext = ['source' => $source, 'args' => $args, 'info' => $info, 'is_collection' => false, 'is_mutation' => true, 'is_subscription' => false];
7574

76-
$item = ($this->readStage)($resourceClass, $rootClass, $operationName, $resolverContext);
75+
$item = ($this->readStage)($resourceClass, $rootClass, $operation, $resolverContext);
7776
if (null !== $item && !\is_object($item)) {
7877
throw new \LogicException('Item from read stage should be a nullable object.');
7978
}
80-
($this->securityStage)($resourceClass, $operationName, $resolverContext + [
79+
($this->securityStage)($resourceClass, $operation, $resolverContext + [
8180
'extra_variables' => [
8281
'object' => $item,
8382
],
8483
]);
8584
$previousItem = $this->clone($item);
8685

87-
if ('delete' === $operationName) {
88-
($this->securityPostDenormalizeStage)($resourceClass, $operationName, $resolverContext + [
86+
if ('delete' === $operation->getName() || $operation instanceof DeleteOperationInterface) {
87+
($this->securityPostDenormalizeStage)($resourceClass, $operation, $resolverContext + [
8988
'extra_variables' => [
9089
'object' => $item,
9190
'previous_object' => $previousItem,
9291
],
9392
]);
94-
$item = ($this->writeStage)($item, $resourceClass, $operationName, $resolverContext);
93+
$item = ($this->writeStage)($item, $resourceClass, $operation, $resolverContext);
9594

96-
return ($this->serializeStage)($item, $resourceClass, $operationName, $resolverContext);
95+
return ($this->serializeStage)($item, $resourceClass, $operation, $resolverContext);
9796
}
9897

99-
$item = ($this->deserializeStage)($item, $resourceClass, $operationName, $resolverContext);
100-
101-
$resourceMetadataCollection = $this->resourceMetadataCollectionFactory->create($resourceClass);
102-
$operation = $resourceMetadataCollection->getOperation($operationName);
98+
$item = ($this->deserializeStage)($item, $resourceClass, $operation, $resolverContext);
10399

104100
$mutationResolverId = $operation->getResolver();
105101
if (null !== $mutationResolverId) {
@@ -111,27 +107,27 @@ public function __invoke(?string $resourceClass = null, ?string $rootClass = nul
111107
}
112108
}
113109

114-
($this->securityPostDenormalizeStage)($resourceClass, $operationName, $resolverContext + [
110+
($this->securityPostDenormalizeStage)($resourceClass, $operation, $resolverContext + [
115111
'extra_variables' => [
116112
'object' => $item,
117113
'previous_object' => $previousItem,
118114
],
119115
]);
120116

121117
if (null !== $item) {
122-
($this->validateStage)($item, $resourceClass, $operationName, $resolverContext);
118+
($this->validateStage)($item, $resourceClass, $operation, $resolverContext);
123119

124-
($this->securityPostValidationStage)($resourceClass, $operationName, $resolverContext + [
120+
($this->securityPostValidationStage)($resourceClass, $operation, $resolverContext + [
125121
'extra_variables' => [
126122
'object' => $item,
127123
'previous_object' => $previousItem,
128124
],
129125
]);
130126

131-
$persistResult = ($this->writeStage)($item, $resourceClass, $operationName, $resolverContext);
127+
$persistResult = ($this->writeStage)($item, $resourceClass, $operation, $resolverContext);
132128
}
133129

134-
return ($this->serializeStage)($persistResult ?? $item, $resourceClass, $operationName, $resolverContext);
130+
return ($this->serializeStage)($persistResult ?? $item, $resourceClass, $operation, $resolverContext);
135131
};
136132
}
137133
}

src/GraphQl/Resolver/Factory/ItemResolverFactory.php

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
use ApiPlatform\GraphQl\Resolver\Stage\SecurityPostDenormalizeStageInterface;
1919
use ApiPlatform\GraphQl\Resolver\Stage\SecurityStageInterface;
2020
use ApiPlatform\GraphQl\Resolver\Stage\SerializeStageInterface;
21+
use ApiPlatform\Metadata\GraphQl\Operation;
22+
use ApiPlatform\Metadata\GraphQl\Query;
2123
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
2224
use ApiPlatform\Util\ClassInfoTrait;
2325
use ApiPlatform\Util\CloneTrait;
@@ -53,25 +55,31 @@ public function __construct(ReadStageInterface $readStage, SecurityStageInterfac
5355
$this->resourceMetadataCollectionFactory = $resourceMetadataCollectionFactory;
5456
}
5557

56-
public function __invoke(?string $resourceClass = null, ?string $rootClass = null, ?string $operationName = null): callable
58+
public function __invoke(?string $resourceClass = null, ?string $rootClass = null, ?Operation $operation = null): callable
5759
{
58-
return function (?array $source, array $args, $context, ResolveInfo $info) use ($resourceClass, $rootClass, $operationName) {
60+
return function (?array $source, array $args, $context, ResolveInfo $info) use ($resourceClass, $rootClass, $operation) {
5961
// Data already fetched and normalized (field or nested resource)
6062
if ($source && \array_key_exists($info->fieldName, $source)) {
6163
return $source[$info->fieldName];
6264
}
6365

64-
$operationName = $operationName ?? 'item_query';
6566
$resolverContext = ['source' => $source, 'args' => $args, 'info' => $info, 'is_collection' => false, 'is_mutation' => false, 'is_subscription' => false];
6667

67-
$item = ($this->readStage)($resourceClass, $rootClass, $operationName, $resolverContext);
68+
if (!$operation) {
69+
$operation = new Query();
70+
}
71+
72+
$item = ($this->readStage)($resourceClass, $rootClass, $operation, $resolverContext);
6873
if (null !== $item && !\is_object($item)) {
6974
throw new \LogicException('Item from read stage should be a nullable object.');
7075
}
7176

77+
// The item retrieved can be of another type when using an identifier (see Relay Nodes at query.feature:23)
7278
$resourceClass = $this->getResourceClass($item, $resourceClass);
73-
$resourceMetadataCollection = $this->resourceMetadataCollectionFactory->create($resourceClass);
74-
$operation = $resourceMetadataCollection->getOperation($operationName);
79+
// if ($test !== $operation->getClass()) {
80+
// $resourceMetadataCollection = $this->resourceMetadataCollectionFactory->create($resourceClass);
81+
// $operation = $resourceMetadataCollection->getOperation($operationName);
82+
// }
7583

7684
$queryResolverId = $operation->getResolver();
7785
if (null !== $queryResolverId) {
@@ -81,19 +89,19 @@ public function __invoke(?string $resourceClass = null, ?string $rootClass = nul
8189
$resourceClass = $this->getResourceClass($item, $resourceClass, sprintf('Custom query resolver "%s"', $queryResolverId).' has to return an item of class %s but returned an item of class %s.');
8290
}
8391

84-
($this->securityStage)($resourceClass, $operationName, $resolverContext + [
92+
($this->securityStage)($resourceClass, $operation, $resolverContext + [
8593
'extra_variables' => [
8694
'object' => $item,
8795
],
8896
]);
89-
($this->securityPostDenormalizeStage)($resourceClass, $operationName, $resolverContext + [
97+
($this->securityPostDenormalizeStage)($resourceClass, $operation, $resolverContext + [
9098
'extra_variables' => [
9199
'object' => $item,
92100
'previous_object' => $this->clone($item),
93101
],
94102
]);
95103

96-
return ($this->serializeStage)($item, $resourceClass, $operationName, $resolverContext);
104+
return ($this->serializeStage)($item, $resourceClass, $operation, $resolverContext);
97105
};
98106
}
99107

0 commit comments

Comments
 (0)