Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Passed
Pull Request — master (#695)
by Timur
07:00
created

Executor::execute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 29
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 20
dl 0
loc 29
ccs 20
cts 20
cp 1
rs 9.6
c 0
b 0
f 0
cc 2
nc 2
nop 3
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Overblog\GraphQLBundle\Request;
6
7
use ArrayObject;
8
use Closure;
9
use GraphQL\Executor\ExecutionResult;
10
use GraphQL\Executor\Promise\PromiseAdapter;
11
use GraphQL\GraphQL;
12
use GraphQL\Type\Schema;
13
use GraphQL\Validator\DocumentValidator;
14
use GraphQL\Validator\Rules\DisableIntrospection;
15
use GraphQL\Validator\Rules\QueryComplexity;
16
use GraphQL\Validator\Rules\QueryDepth;
17
use Overblog\GraphQLBundle\Definition\Type\ExtensibleSchema;
18
use Overblog\GraphQLBundle\Event\Events;
19
use Overblog\GraphQLBundle\Event\ExecutorArgumentsEvent;
20
use Overblog\GraphQLBundle\Event\ExecutorContextEvent;
21
use Overblog\GraphQLBundle\Event\ExecutorResultEvent;
22
use Overblog\GraphQLBundle\Executor\ExecutorInterface;
23
use RuntimeException;
24
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
25
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
26
use function array_keys;
27
use function is_callable;
28
use function sprintf;
29
30
class Executor
31
{
32
    public const PROMISE_ADAPTER_SERVICE_ID = 'overblog_graphql.promise_adapter';
33
34
    private array $schemas = [];
35
    private EventDispatcherInterface $dispatcher;
36
    private PromiseAdapter $promiseAdapter;
37
    private ExecutorInterface $executor;
38
    private bool $useExperimentalExecutor;
39
40
    /**
41
     * @var callable|null
42
     */
43
    private $defaultFieldResolver;
44
45 124
    public function __construct(
46
        ExecutorInterface $executor,
47
        PromiseAdapter $promiseAdapter,
48
        EventDispatcherInterface $dispatcher,
49
        ?callable $defaultFieldResolver = null,
50
        bool $useExperimental = false
51
    ) {
52 124
        $this->executor = $executor;
53 124
        $this->promiseAdapter = $promiseAdapter;
54 124
        $this->dispatcher = $dispatcher;
55 124
        $this->defaultFieldResolver = $defaultFieldResolver;
56 124
        $this->useExperimentalExecutor = $useExperimental;
57 124
    }
58
59
    public function setExecutor(ExecutorInterface $executor): self
60
    {
61
        $this->executor = $executor;
62
63
        return $this;
64
    }
65
66 116
    public function addSchemaBuilder(string $name, Closure $builder): self
67
    {
68 116
        $this->schemas[$name] = $builder;
69
70 116
        return $this;
71
    }
72
73 107
    public function addSchema(string $name, Schema $schema): self
74
    {
75 107
        $this->schemas[$name] = $schema;
76
77 107
        return $this;
78
    }
79
80 109
    public function getSchema(string $name = null): Schema
81
    {
82 109
        if (empty($this->schemas)) {
83 1
            throw new RuntimeException('At least one schema should be declare.');
84
        }
85
86 108
        if (null === $name) {
87
            // TODO(mcg-web): Replace by array_key_first PHP 7 >= 7.3.0.
88 102
            foreach ($this->schemas as $name => $schema) {
89 102
                break;
90
            }
91
        }
92 108
        if (!isset($this->schemas[$name])) {
93 1
            throw new NotFoundHttpException(sprintf('Could not found "%s" schema.', $name));
94
        }
95 107
        $schema = $this->schemas[$name];
96 107
        if (is_callable($schema)) {
97 107
            $schema = $schema();
98 106
            $this->addSchema((string) $name, $schema);
99
        }
100
101 106
        return $schema;
102
    }
103
104 1
    public function getSchemasNames(): array
105
    {
106 1
        return array_keys($this->schemas);
107
    }
108
109 122
    public function setMaxQueryDepth(int $maxQueryDepth): void
110
    {
111
        /** @var QueryDepth $queryDepth */
112 122
        $queryDepth = DocumentValidator::getRule('QueryDepth');
113 122
        $queryDepth->setMaxQueryDepth($maxQueryDepth);
114 122
    }
115
116 122
    public function setMaxQueryComplexity(int $maxQueryComplexity): void
117
    {
118
        /** @var QueryComplexity $queryComplexity */
119 122
        $queryComplexity = DocumentValidator::getRule('QueryComplexity');
120 122
        $queryComplexity->setMaxQueryComplexity($maxQueryComplexity);
121 122
    }
122
123 121
    public function enableIntrospectionQuery(): void
124
    {
125 121
        DocumentValidator::addRule(new DisableIntrospection(DisableIntrospection::DISABLED));
126 121
    }
127
128 1
    public function disableIntrospectionQuery(): void
129
    {
130 1
        DocumentValidator::addRule(new DisableIntrospection());
131 1
    }
132
133
    /**
134
     * @param array|ArrayObject|object|null $rootValue
135
     */
136 105
    public function execute(?string $schemaName, array $request, $rootValue = null): ExecutionResult
137
    {
138 105
        $this->useExperimentalExecutor ? GraphQL::useExperimentalExecutor() : GraphQL::useReferenceExecutor();
139
140 105
        $executorArgumentsEvent = $this->preExecute(
141 105
            $this->getSchema($schemaName),
142 103
            $request[ParserInterface::PARAM_QUERY] ?? null,
0 ignored issues
show
Bug introduced by
It seems like $request[Overblog\GraphQ...e::PARAM_QUERY] ?? null can also be of type null; however, parameter $requestString of Overblog\GraphQLBundle\R...\Executor::preExecute() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

142
            /** @scrutinizer ignore-type */ $request[ParserInterface::PARAM_QUERY] ?? null,
Loading history...
143 103
            new ArrayObject(),
144
            $rootValue,
145 103
            $request[ParserInterface::PARAM_VARIABLES],
146 103
            $request[ParserInterface::PARAM_OPERATION_NAME] ?? null
147
        );
148
149 103
        $executorArgumentsEvent->getSchema()->processExtensions();
150
151 103
        $result = $this->executor->execute(
152 103
            $this->promiseAdapter,
153 103
            $executorArgumentsEvent->getSchema(),
154 103
            $executorArgumentsEvent->getRequestString(),
155 103
            $executorArgumentsEvent->getRootValue(),
156 103
            $executorArgumentsEvent->getContextValue(),
157 103
            $executorArgumentsEvent->getVariableValue(),
158 103
            $executorArgumentsEvent->getOperationName(),
159 103
            $this->defaultFieldResolver
160
        );
161
162 103
        $result = $this->postExecute($result, $executorArgumentsEvent);
163
164 101
        return $result;
165
    }
166
167
    /**
168
     * @param mixed $rootValue
169
     */
170 103
    private function preExecute(
171
        Schema $schema,
172
        string $requestString,
173
        ArrayObject $contextValue,
174
        $rootValue = null,
175
        ?array $variableValue = null,
176
        ?string $operationName = null
177
    ): ExecutorArgumentsEvent {
178
        // @phpstan-ignore-next-line (only for Symfony 4.4)
179 103
        $this->dispatcher->dispatch(new ExecutorContextEvent($contextValue), Events::EXECUTOR_CONTEXT);
180
181
        /** @var ExecutorArgumentsEvent $object */
182
        // @phpstan-ignore-next-line (only for Symfony 4.4)
183 103
        $object = $this->dispatcher->dispatch(
184
            /** @var ExtensibleSchema $schema */
185 103
            ExecutorArgumentsEvent::create($schema, $requestString, $contextValue, $rootValue, $variableValue, $operationName),
186 103
            Events::PRE_EXECUTOR
187
        );
188
189 103
        return $object;
190
    }
191
192 103
    private function postExecute(ExecutionResult $result, ExecutorArgumentsEvent $executorArguments): ExecutionResult
193
    {
194
        // @phpstan-ignore-next-line (only for Symfony 4.4)
195 103
        return $this->dispatcher->dispatch(
196 103
            new ExecutorResultEvent($result, $executorArguments),
197 103
            Events::POST_EXECUTOR
198 101
        )->getResult();
199
    }
200
}
201