From c58565137eafa9fc8aa99b52e53b005f73039336 Mon Sep 17 00:00:00 2001 From: Minh Vuong Date: Sun, 28 Apr 2024 07:19:09 +0700 Subject: [PATCH] fix: declare nullable variable --- src/Execution/DelegateResolver.php | 45 +++++++++++------------------- tests/IntegrationTest.php | 19 ++++++++++++- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/Execution/DelegateResolver.php b/src/Execution/DelegateResolver.php index c2ed854..913a418 100644 --- a/src/Execution/DelegateResolver.php +++ b/src/Execution/DelegateResolver.php @@ -73,11 +73,8 @@ public function resolve(): Promise $fragments = $this->collectFragments($operationType, $operation->selectionSet); $relations = $this->collectRelations($operationType, $operation->selectionSet, $fragments); - /// All selection set is clear, let collects using variables - $variables = $this->collectVariables($operation, $fragments); - - $operation->variableDefinitions = $this->createVariableDefinitions($variables); - + /// All selection set is clear, let resolve variables + $variables = $this->resolveVariables($operation, $fragments); $promise = $this->delegateToExecute($subSchemaName, $operation, $fragments, $variables); $promises[] = $promise->then( @@ -317,10 +314,11 @@ private function collectRelations( /** * @param OperationDefinitionNode $operation - * @param FragmentDefinitionNode[] $fragments + * @param array $fragments * @return array + * @throws \JsonException */ - private function collectVariables(OperationDefinitionNode $operation, array $fragments): array + private function resolveVariables(OperationDefinitionNode $operation, array $fragments): array { $variables = []; $names = [ @@ -328,7 +326,17 @@ private function collectVariables(OperationDefinitionNode $operation, array $fra ...Variable::getVariablesInFragments($fragments), ]; - foreach ($names as $name) { + foreach ($this->rootOperation->variableDefinitions as $definition) { + /** @var VariableDefinitionNode $definition */ + $name = $definition->variable->name->value; + + if (!in_array($name, $names, true)) { + continue; + } + + $operation->variableDefinitions[] = $definition->cloneDeep(); + + /// Nullable variable may not declare, so we need to check before get if (array_key_exists($name, $this->variables)) { $variables[$name] = $this->variables[$name]; } @@ -451,10 +459,7 @@ private function delegateRelationQueries( $operationType = $this->executionSchema->getOperationType($operation->operation); $fragments = $this->collectFragments($operationType, $operation->selectionSet); $relationsRelations = $this->collectRelations($operationType, $operation->selectionSet, $fragments); - $variables += $this->collectVariables($operation, $fragments); - $variableDefinitions = $this->createVariableDefinitions($variables)->merge($operation->variableDefinitions); - - $operation->variableDefinitions = $variableDefinitions; + $variables += $this->resolveVariables($operation, $fragments); return $this ->delegateToExecute($subSchemaName, $operation, $fragments, $variables) @@ -734,22 +739,6 @@ private function createOperation(string $operation): OperationDefinitionNode ]); } - private function createVariableDefinitions(array $variables): NodeList - { - $definitions = new NodeList([]); - - foreach ($this->rootOperation->variableDefinitions as $definition) { - /** @var VariableDefinitionNode $definition */ - $name = $definition->variable->name->value; - - if (array_key_exists($name, $variables)) { - $definitions[] = $definition->cloneDeep(); - } - } - - return $definitions; - } - private function getUid(): string { static $uid = null; diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index bdaba3e..4225c8d 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -427,7 +427,7 @@ public static function executionProvider(): array ] ] ], - 'use null variable' => [ + 'nullable variable' => [ <<<'GQL' query($code: ID) { findPersonByLanguageCode(code: $code) { @@ -445,6 +445,23 @@ public static function executionProvider(): array ] ] ], + ], + 'not declare nullable variable' => [ + <<<'GQL' +query($code: ID) { + findPersonByLanguageCode(code: $code) { + name + } +} +GQL, + [], + [ + 'data' => [ + 'findPersonByLanguageCode' => [ + 'name' => 'John Doe unknown', + ] + ] + ], ] ]; }