Passed
Pull Request — master (#294)
by Christoffer
02:15
created

Execution::execute()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 33
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 16
nc 5
nop 8
dl 0
loc 33
rs 9.7333
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace Digia\GraphQL\Execution;
4
5
use Digia\GraphQL\Error\ErrorHandlerInterface;
6
use Digia\GraphQL\Error\ExecutionException;
7
use Digia\GraphQL\Language\Node\DocumentNode;
8
use Digia\GraphQL\Language\Node\FragmentDefinitionNode;
9
use Digia\GraphQL\Language\Node\FragmentSpreadNode;
10
use Digia\GraphQL\Language\Node\OperationDefinitionNode;
11
use Digia\GraphQL\Schema\Schema;
12
13
class Execution implements ExecutionInterface
14
{
15
16
    /**
17
     * @param Schema        $schema
18
     * @param DocumentNode  $documentNode
19
     * @param mixed         $rootValue
20
     * @param mixed         $contextValue
21
     * @param array         $variableValues
22
     * @param null|string   $operationName
23
     * @param callable|null $fieldResolver
24
     * @return ExecutionResult
25
     * @throws \Throwable
26
     */
27
    public function execute(
28
        Schema $schema,
29
        DocumentNode $documentNode,
30
        $rootValue = null,
31
        $contextValue = null,
32
        array $variableValues = [],
33
        ?string $operationName = null,
34
        ?callable $fieldResolver = null,
35
        ?ErrorHandlerInterface $errorHandler = null
36
    ): ExecutionResult {
37
        try {
38
            $context = $this->createContext(
39
                $schema,
40
                $documentNode,
41
                $rootValue,
42
                $contextValue,
43
                $variableValues,
44
                $operationName,
45
                $fieldResolver
46
            );
47
48
            // Return early errors if execution context failed.
49
            if (!empty($context->getErrors())) {
50
                return new ExecutionResult(null, $context->getErrors());
51
            }
52
        } catch (ExecutionException $error) {
53
            return new ExecutionResult(null, [$error]);
54
        }
55
56
        $data   = $this->createExecutor($context, $errorHandler)->execute();
57
        $errors = $context->getErrors();
58
59
        return new ExecutionResult($data, $errors);
60
    }
61
62
    /**
63
     * @param Schema        $schema
64
     * @param DocumentNode  $documentNode
65
     * @param mixed         $rootValue
66
     * @param mixed         $contextValue
67
     * @param mixed         $rawVariableValues
68
     * @param null|string   $operationName
69
     * @param callable|null $fieldResolver
70
     * @return ExecutionContext
71
     * @throws ExecutionException
72
     * @throws \Exception
73
     */
74
    protected function createContext(
75
        Schema $schema,
76
        DocumentNode $documentNode,
77
        $rootValue,
78
        $contextValue,
79
        $rawVariableValues,
80
        ?string $operationName = null,
81
        ?callable $fieldResolver = null
82
    ): ExecutionContext {
83
        $errors    = [];
84
        $fragments = [];
85
        $operation = null;
86
87
        foreach ($documentNode->getDefinitions() as $definition) {
88
            if ($definition instanceof OperationDefinitionNode) {
89
                if (null === $operationName && $operation) {
90
                    throw new ExecutionException(
91
                        'Must provide operation name if query contains multiple operations.'
92
                    );
93
                }
94
95
                if (null === $operationName || $definition->getNameValue() === $operationName) {
96
                    $operation = $definition;
97
                }
98
99
                continue;
100
            }
101
102
            if ($definition instanceof FragmentDefinitionNode || $definition instanceof FragmentSpreadNode) {
103
                $fragments[$definition->getNameValue()] = $definition;
104
105
                continue;
106
            }
107
        }
108
109
        if (null === $operation) {
110
            if (null !== $operationName) {
111
                throw new ExecutionException(sprintf('Unknown operation named "%s".', $operationName));
112
            }
113
114
            throw new ExecutionException('Must provide an operation.');
115
        }
116
117
        $coercedVariableValues = coerceVariableValues(
118
            $schema,
119
            $operation->getVariableDefinitions(),
120
            $rawVariableValues
121
        );
122
123
        $variableValues = $coercedVariableValues->getValue();
124
125
        if ($coercedVariableValues->hasErrors()) {
126
            $errors = $coercedVariableValues->getErrors();
127
        }
128
129
        return new ExecutionContext(
130
            $schema,
131
            $fragments,
132
            $rootValue,
133
            $contextValue,
134
            $variableValues,
135
            $fieldResolver,
136
            $operation,
137
            $errors
138
        );
139
    }
140
141
    /**
142
     * @param ExecutionContext           $context
143
     * @param ErrorHandlerInterface|null $errorHandler
144
     * @return Executor
145
     */
146
    protected function createExecutor(ExecutionContext $context, ?ErrorHandlerInterface $errorHandler = null): Executor
147
    {
148
        return new Executor($context, new FieldCollector($context), $errorHandler);
149
    }
150
}
151