Skip to content
This repository has been archived by the owner on Mar 8, 2023. It is now read-only.

Commit

Permalink
Merge e041562 into 934e00a
Browse files Browse the repository at this point in the history
  • Loading branch information
hungneox committed Feb 27, 2018
2 parents 934e00a + e041562 commit aa49ad7
Show file tree
Hide file tree
Showing 13 changed files with 583 additions and 173 deletions.
131 changes: 10 additions & 121 deletions src/Execution/Execution.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@

use Digia\GraphQL\Error\GraphQLError;
use Digia\GraphQL\Language\AST\Node\DocumentNode;
use Digia\GraphQL\Language\AST\Node\FieldNode;
use Digia\GraphQL\Language\AST\Node\OperationDefinitionNode;
use Digia\GraphQL\Language\AST\Node\SelectionSetNode;
use Digia\GraphQL\Language\AST\NodeKindEnum;
use Digia\GraphQL\Type\Definition\ObjectType;
use Digia\GraphQL\Type\Schema;

/**
Expand Down Expand Up @@ -49,8 +45,7 @@ public static function execute(
$variableValues = null,
$operationName = null,
callable $fieldResolver = null
)
{
) {
try {
$context = self::buildExecutionContext(
$schema,
Expand All @@ -62,19 +57,16 @@ public static function execute(
$fieldResolver
);
} catch (GraphQLError $error) {
return new ExecutionResult(null, [$error]);
return new ExecutionResult(['data' => null], [$error]);
}

$executor = new self($context);
$data = $context->getExecutionStrategy()->execute();

return $executor->executeOperation(
$context,
$context->getOperation(),
$rootValue
);
return new ExecutionResult($data, $context->getErrors());
}

/**
* @TODO: Consider to create a ExecutionContextBuilder
* @param Schema $schema
* @param DocumentNode $documentNode
* @param $rootValue
Expand All @@ -93,12 +85,11 @@ private static function buildExecutionContext(
$rawVariableValues,
$operationName = null,
callable $fieldResolver = null
): ExecutionContext
{
): ExecutionContext {
//TODO: Validate raw variables, operation name etc.
//TODO: Validate document definition

$errors = [];
$errors = [];
$fragments = [];
$operation = null;

Expand All @@ -110,17 +101,18 @@ private static function buildExecutionContext(
'Must provide operation name if query contains multiple operations.'
);
}

if (!$operationName || (!empty($definition->getName()) && $definition->getName()->getValue() === $operationName)) {
$operation = $definition;
}
break;
case NodeKindEnum::FRAGMENT_DEFINITION:
case NodeKindEnum::FRAGMENT_SPREAD:
$fragments[$definition->getName()->getValue()] = $definition;
break;
default:
throw new GraphQLError(
"GraphQL cannot execute a request containing a {$definition->getKind()}.",
[$definition]
"GraphQL cannot execute a request containing a {$definition->getKind()}."
);
}
}
Expand All @@ -138,107 +130,4 @@ private static function buildExecutionContext(

return $executionContext;
}

/**
* @param ExecutionContext $context
* @param OperationDefinitionNode $operation
* @param $rootValue
*
* @return ExecutionResult
*/
private function executeOperation(
ExecutionContext $context,
OperationDefinitionNode $operation,
$rootValue
): ExecutionResult
{
//MUTATION
//SUBSCRIPTION
//QUERY

//result = executionStrategy.execute(executionContext, parameters);
// type: query|mutation|suscription
$query = $context->getSchema()->getQuery();
$fields = $this->collectFields($query, $operation->getSelectionSet(), [], []);
$path = [];

if ($context->getOperation()->getName()->getValue() === 'query') {
$data = $this->executeFields($query, $rootValue, $path, $fields);

return new ExecutionResult($data, []);
}

return new ExecutionResult([], []);
}

private function collectFields(
ObjectType $runtimeType,
SelectionSetNode $selectionSet,
$fields,
$visitedFragmentNames
)
{
foreach ($selectionSet->getSelections() as $selection) {
switch ($selection->getKind()) {
case NodeKindEnum::FIELD:
/** @var FieldNode $selection */
$name = $selection->getName()->getValue();
$fields[$name][] = $selection;
break;
}
}

return $fields;
}

/**
* Implements the "Evaluating selection sets" section of the spec
* for "read" mode.
* @param ObjectType $parentType
* @param $source
* @param $path
* @param $fields
*
* @return array
*/
private function executeFields(ObjectType $parentType, $source, $path, $fields): array
{
$finalResults = [];
foreach ($fields as $responseName => $fieldNodes) {
$fieldPath = $path;
$fieldPath[] = $responseName;

$result = $this->resolveField($parentType, $source, $fieldNodes, $fieldPath);

$finalResults[$responseName] = $result;
}

return $finalResults;
}

/**
* @param ObjectType $parentType
* @param $source
* @param $fieldNodes
* @param $path
*
* @return array|\Exception|mixed|null
*/
private function resolveField(ObjectType $parentType, $source, $fieldNodes, $path)
{
/** @var FieldNode $fieldNode */
$fieldNode = $fieldNodes[0];

$field = $parentType->getFields()[$fieldNode->getName()->getValue()];

$inputValues = $fieldNode->getArguments() ?? [];

$args = [];

foreach($inputValues as $value) {
$args[] = $value->getDefaultValue()->getValue();
}

return $field->resolve(...$args);
}
}
27 changes: 27 additions & 0 deletions src/Execution/ExecutionContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,25 @@ public function getSchema(): Schema
return $this->schema;
}

/**
* @return array|FragmentDefinitionNode[]
*/
public function getFragments()
{
return $this->fragments;
}

/**
* Create proper ExecutionStrategy when needed
*
* @return ExecutionStrategy
*/
public function getExecutionStrategy(): ExecutionStrategy
{
//We can probably return different strategy in the future e.g:AsyncExecutionStrategy
return new ExecutorExecutionStrategy($this, $this->operation, $this->rootValue);
}

/**
* @param GraphQLError $error
* @return ExecutionContext
Expand All @@ -106,4 +125,12 @@ public function addError(GraphQLError $error)
$this->errors[] = $error;
return $this;
}

/**
* @return array|GraphQLError[]
*/
public function getErrors()
{
return $this->errors;
}
}
8 changes: 8 additions & 0 deletions src/Execution/ExecutionResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ public function __construct(array $data, array $errors)
$this->data = $data;
}

/**
* @return array|GraphQLError[]
*/
public function getErrors(): array
{
return $this->errors;
}

/**
* @param GraphQLError $error
* @return ExecutionResult
Expand Down

0 comments on commit aa49ad7

Please sign in to comment.