• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

overblog / GraphQLBundle / 18365138739

29 Aug 2025 02:08PM UTC coverage: 98.279% (-0.09%) from 98.368%
18365138739

push

github

web-flow
Merge pull request #1203 from Nyholm/reset

add kernel.reset tag to allow clearing memory between request

0 of 4 new or added lines in 2 files covered. (0.0%)

4339 of 4415 relevant lines covered (98.28%)

39.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.75
/src/Request/Executor.php
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\Type\Schema;
12
use GraphQL\Validator\DocumentValidator;
13
use GraphQL\Validator\Rules\DisableIntrospection;
14
use GraphQL\Validator\Rules\QueryComplexity;
15
use GraphQL\Validator\Rules\QueryDepth;
16
use Overblog\GraphQLBundle\Event\Events;
17
use Overblog\GraphQLBundle\Event\ExecutorArgumentsEvent;
18
use Overblog\GraphQLBundle\Event\ExecutorContextEvent;
19
use Overblog\GraphQLBundle\Event\ExecutorResultEvent;
20
use Overblog\GraphQLBundle\Executor\ExecutorInterface;
21
use RuntimeException;
22
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
23
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
24

25
use function array_keys;
26
use function is_callable;
27
use function sprintf;
28

29
class Executor
30
{
31
    public const PROMISE_ADAPTER_SERVICE_ID = 'overblog_graphql.promise_adapter';
32

33
    private array $schemas = [];
34
    private EventDispatcherInterface $dispatcher;
35
    private PromiseAdapter $promiseAdapter;
36
    private ExecutorInterface $executor;
37

38
    /**
39
     * @var callable|null
40
     */
41
    private $defaultFieldResolver;
42

43
    public function __construct(
44
        ExecutorInterface $executor,
45
        PromiseAdapter $promiseAdapter,
46
        EventDispatcherInterface $dispatcher,
47
        ?callable $defaultFieldResolver = null
48
    ) {
49
        $this->executor = $executor;
137✔
50
        $this->promiseAdapter = $promiseAdapter;
137✔
51
        $this->dispatcher = $dispatcher;
137✔
52
        $this->defaultFieldResolver = $defaultFieldResolver;
137✔
53
    }
137✔
54

55
    public function setExecutor(ExecutorInterface $executor): self
56
    {
57
        $this->executor = $executor;
×
58

59
        return $this;
×
60
    }
61

62
    public function addSchemaBuilder(string $name, Closure $builder): self
63
    {
64
        $this->schemas[$name] = $builder;
129✔
65

66
        return $this;
129✔
67
    }
68

69
    public function addSchema(string $name, Schema $schema): self
70
    {
71
        $this->schemas[$name] = $schema;
120✔
72

73
        return $this;
120✔
74
    }
75

76
    public function getSchema(?string $name = null): Schema
77
    {
78
        if (empty($this->schemas)) {
122✔
79
            throw new RuntimeException('At least one schema should be declare.');
1✔
80
        }
81

82
        if (null === $name) {
121✔
83
            $name = isset($this->schemas['default']) ? 'default' : array_key_first($this->schemas);
115✔
84
        }
85

86
        if (!isset($this->schemas[$name])) {
121✔
87
            throw new NotFoundHttpException(sprintf('Could not find "%s" schema.', $name));
1✔
88
        }
89

90
        $schema = $this->schemas[$name];
120✔
91
        if (is_callable($schema)) {
120✔
92
            $schema = $schema();
120✔
93
            $this->addSchema((string) $name, $schema);
119✔
94
        }
95

96
        return $schema;
119✔
97
    }
98

99
    public function getSchemasNames(): array
100
    {
101
        return array_keys($this->schemas);
1✔
102
    }
103

104
    public function setMaxQueryDepth(int $maxQueryDepth): void
105
    {
106
        /** @var QueryDepth $queryDepth */
107
        $queryDepth = DocumentValidator::getRule(QueryDepth::class);
135✔
108
        $queryDepth->setMaxQueryDepth($maxQueryDepth);
135✔
109
    }
135✔
110

111
    public function setMaxQueryComplexity(int $maxQueryComplexity): void
112
    {
113
        /** @var QueryComplexity $queryComplexity */
114
        $queryComplexity = DocumentValidator::getRule(QueryComplexity::class);
135✔
115
        $queryComplexity->setMaxQueryComplexity($maxQueryComplexity);
135✔
116
    }
135✔
117

118
    public function enableIntrospectionQuery(): void
119
    {
120
        DocumentValidator::addRule(new DisableIntrospection(DisableIntrospection::DISABLED));
134✔
121
    }
134✔
122

123
    public function disableIntrospectionQuery(): void
124
    {
125
        DocumentValidator::addRule(new DisableIntrospection(DisableIntrospection::ENABLED));
1✔
126
    }
1✔
127

128
    /**
129
     * @param array|ArrayObject|object|null $rootValue
130
     */
131
    public function execute(?string $schemaName, array $request, $rootValue = null): ExecutionResult
132
    {
133
        $schema = $this->getSchema($schemaName);
118✔
134
        /** @var string $schemaName */
135
        $schemaName = array_search($schema, $this->schemas);
116✔
136

137
        $executorArgumentsEvent = $this->preExecute(
116✔
138
            $schemaName,
116✔
139
            $schema,
140
            $request[ParserInterface::PARAM_QUERY] ?? null,
116✔
141
            new ArrayObject(),
116✔
142
            $rootValue,
143
            $request[ParserInterface::PARAM_VARIABLES],
116✔
144
            $request[ParserInterface::PARAM_OPERATION_NAME] ?? null
116✔
145
        );
146

147
        $executorArgumentsEvent->getSchema()->processExtensions();
116✔
148

149
        $result = $this->executor->execute(
116✔
150
            $this->promiseAdapter,
116✔
151
            $executorArgumentsEvent->getSchema(),
116✔
152
            $executorArgumentsEvent->getRequestString(),
116✔
153
            $executorArgumentsEvent->getRootValue(),
116✔
154
            $executorArgumentsEvent->getContextValue(),
116✔
155
            $executorArgumentsEvent->getVariableValue(),
116✔
156
            $executorArgumentsEvent->getOperationName(),
116✔
157
            $this->defaultFieldResolver
116✔
158
        );
159

160
        $result = $this->postExecute($result, $executorArgumentsEvent);
116✔
161

162
        return $result;
114✔
163
    }
164

165
    /**
166
     * @param mixed $rootValue
167
     */
168
    private function preExecute(
169
        string $schemaName,
170
        Schema $schema,
171
        string $requestString,
172
        ArrayObject $contextValue,
173
        $rootValue = null,
174
        ?array $variableValue = null,
175
        ?string $operationName = null
176
    ): ExecutorArgumentsEvent {
177
        // @phpstan-ignore-next-line (only for Symfony 4.4)
178
        $this->dispatcher->dispatch(new ExecutorContextEvent($contextValue), Events::EXECUTOR_CONTEXT);
116✔
179

180
        /** @var ExecutorArgumentsEvent $object */
181
        // @phpstan-ignore-next-line (only for Symfony 4.4)
182
        $object = $this->dispatcher->dispatch(
116✔
183
            // @phpstan-ignore-next-line
184
            ExecutorArgumentsEvent::create($schemaName, $schema, $requestString, $contextValue, $rootValue, $variableValue, $operationName),
116✔
185
            Events::PRE_EXECUTOR
116✔
186
        );
187

188
        return $object;
116✔
189
    }
190

191
    private function postExecute(ExecutionResult $result, ExecutorArgumentsEvent $executorArguments): ExecutionResult
192
    {
193
        // @phpstan-ignore-next-line (only for Symfony 4.4)
194
        return $this->dispatcher->dispatch(
116✔
195
            new ExecutorResultEvent($result, $executorArguments),
116✔
196
            Events::POST_EXECUTOR
116✔
197
        )->getResult();
114✔
198
    }
199

200
    public function reset(): void
201
    {
NEW
202
        $this->schemas = [];
×
NEW
203
    }
×
204
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc