Passed
Pull Request — master (#318)
by Sam
03:54
created

GraphQL::process()   B

Complexity

Conditions 9
Paths 7

Size

Total Lines 53
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 27
nc 7
nop 8
dl 0
loc 53
rs 8.0555
c 0
b 0
f 0

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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;
4
5
use Digia\GraphQL\Error\Handler\ErrorHandlerInterface;
6
use Digia\GraphQL\Error\InvariantException;
7
use Digia\GraphQL\Execution\ExecutionInterface;
8
use Digia\GraphQL\Execution\ExecutionProvider;
9
use Digia\GraphQL\Execution\ExecutionResult;
10
use Digia\GraphQL\Language\LanguageProvider;
11
use Digia\GraphQL\Language\Node\DocumentNode;
12
use Digia\GraphQL\Language\Node\NodeInterface;
13
use Digia\GraphQL\Language\Node\TypeNodeInterface;
14
use Digia\GraphQL\Language\Node\ValueNodeInterface;
15
use Digia\GraphQL\Language\NodePrinterInterface;
16
use Digia\GraphQL\Language\ParserInterface;
17
use Digia\GraphQL\Language\Source;
18
use Digia\GraphQL\Language\SyntaxErrorException;
19
use Digia\GraphQL\Schema\Building\SchemaBuilderInterface;
20
use Digia\GraphQL\Schema\Building\SchemaBuildingProvider;
21
use Digia\GraphQL\Schema\Extension\SchemaExtenderInterface;
22
use Digia\GraphQL\Schema\Extension\SchemaExtensionProvider;
23
use Digia\GraphQL\Schema\Resolver\ResolverRegistry;
24
use Digia\GraphQL\Schema\Resolver\ResolverRegistryInterface;
25
use Digia\GraphQL\Schema\Schema;
26
use Digia\GraphQL\Schema\Validation\SchemaValidationProvider;
27
use Digia\GraphQL\Schema\Validation\SchemaValidatorInterface;
28
use Digia\GraphQL\Type\CoercerProvider;
29
use Digia\GraphQL\Type\DirectivesProvider;
30
use Digia\GraphQL\Type\IntrospectionProvider;
31
use Digia\GraphQL\Type\ScalarTypesProvider;
32
use Digia\GraphQL\Validation\RulesProvider;
33
use Digia\GraphQL\Validation\ValidationProvider;
34
use Digia\GraphQL\Validation\ValidatorInterface;
35
use League\Container\Container;
36
37
class GraphQL
38
{
39
    public const BOOLEAN = 'GraphQLBoolean';
40
    public const FLOAT   = 'GraphQLFloat';
41
    public const INT     = 'GraphQLInt';
42
    public const ID      = 'GraphQLID';
43
    public const STRING  = 'GraphQLString';
44
45
    public const DEPRECATED_DIRECTIVE = 'GraphQLDeprecatedDirective';
46
    public const INCLUDE_DIRECTIVE    = 'GraphQLIncludeDirective';
47
    public const SKIP_DIRECTIVE       = 'GraphQLSkipDirective';
48
49
    public const SCHEMA_INTROSPECTION             = '__Schema';
50
    public const DIRECTIVE_INTROSPECTION          = '__Directive';
51
    public const DIRECTIVE_LOCATION_INTROSPECTION = '__DirectiveLocation';
52
    public const TYPE_INTROSPECTION               = '__Type';
53
    public const FIELD_INTROSPECTION              = '__Field';
54
    public const INPUT_VALUE_INTROSPECTION        = '__InputValue';
55
    public const ENUM_VALUE_INTROSPECTION         = '__EnumValue';
56
    public const TYPE_KIND_INTROSPECTION          = '__TypeKind';
57
58
    public const SCHEMA_META_FIELD_DEFINITION    = 'SchemaMetaFieldDefinition';
59
    public const TYPE_META_FIELD_DEFINITION      = 'TypeMetaFieldDefinition';
60
    public const TYPE_NAME_META_FIELD_DEFINITION = 'TypeNameMetaFieldDefinition';
61
62
    /**
63
     * @var array
64
     */
65
    private static $providers = [
66
        LanguageProvider::class,
67
        SchemaBuildingProvider::class,
68
        SchemaExtensionProvider::class,
69
        SchemaValidationProvider::class,
70
        CoercerProvider::class,
71
        IntrospectionProvider::class,
72
        ScalarTypesProvider::class,
73
        DirectivesProvider::class,
74
        RulesProvider::class,
75
        ValidationProvider::class,
76
        ExecutionProvider::class,
77
    ];
78
79
    /**
80
     * @var GraphQL
81
     */
82
    private static $instance;
83
84
    /**
85
     * @var Container
86
     */
87
    protected $container;
88
89
    /**
90
     * GraphQL constructor.
91
     */
92
    private function __construct()
93
    {
94
        $container = new Container();
95
96
        $this->registerProviders($container);
97
98
        $this->container = $container;
99
    }
100
101
    /**
102
     * @return GraphQL
103
     */
104
    public static function getInstance(): self
105
    {
106
        if (null === self::$instance) {
107
            self::$instance = new self();
108
        }
109
110
        return self::$instance;
111
    }
112
113
    /**
114
     * @param string $id
115
     * @return mixed
116
     */
117
    public static function make(string $id)
118
    {
119
        return static::getInstance()
120
            ->getContainer()
121
            ->get($id);
122
    }
123
124
    /**
125
     * @param Source                          $source
126
     * @param array|ResolverRegistryInterface $resolverRegistry
127
     * @param array                           $options
128
     * @return Schema
129
     */
130
    public static function buildSchema(Source $source, $resolverRegistry, array $options = []): Schema
131
    {
132
        /** @var SchemaBuilderInterface $schemaBuilder */
133
        $schemaBuilder = static::make(SchemaBuilderInterface::class);
134
135
        return $schemaBuilder->build(
136
            static::parse($source, $options),
137
            $resolverRegistry instanceof ResolverRegistryInterface
138
                ? $resolverRegistry
139
                : new ResolverRegistry($resolverRegistry),
140
            $options
141
        );
142
    }
143
144
    /**
145
     * @param Schema                          $schema
146
     * @param Source                          $source
147
     * @param array|ResolverRegistryInterface $resolverRegistry
148
     * @param array                           $options
149
     * @return Schema
150
     */
151
    public static function extendSchema(
152
        Schema $schema,
153
        Source $source,
154
        $resolverRegistry,
155
        array $options = []
156
    ): Schema {
157
        /** @var SchemaExtenderInterface $schemaExtender */
158
        $schemaExtender = static::make(SchemaExtenderInterface::class);
159
160
        return $schemaExtender->extend(
161
            $schema,
162
            static::parse($source, $options),
163
            $resolverRegistry instanceof ResolverRegistryInterface
164
                ? $resolverRegistry
165
                : new ResolverRegistry($resolverRegistry),
166
            $options
167
        );
168
    }
169
170
    /**
171
     * @param Schema $schema
172
     * @return array
173
     */
174
    public static function validateSchema(Schema $schema): array
175
    {
176
        /** @var SchemaValidatorInterface $schemaValidator */
177
        $schemaValidator = static::make(SchemaValidatorInterface::class);
178
179
        return $schemaValidator->validate($schema);
180
    }
181
182
    /**
183
     * @param Source $source
184
     * @param array  $options
185
     * @return DocumentNode
186
     */
187
    public static function parse(Source $source, array $options = []): DocumentNode
188
    {
189
        /** @var ParserInterface $parser */
190
        $parser = static::make(ParserInterface::class);
191
192
        return $parser->parse($source, $options);
193
    }
194
195
    /**
196
     * @param Source $source
197
     * @param array  $options
198
     * @return ValueNodeInterface
199
     */
200
    public static function parseValue(Source $source, array $options = []): ValueNodeInterface
201
    {
202
        /** @var ParserInterface $parser */
203
        $parser = static::make(ParserInterface::class);
204
205
        return $parser->parseValue($source, $options);
0 ignored issues
show
Bug introduced by
The method parseValue() does not exist on Digia\GraphQL\Language\ParserInterface. Did you maybe mean parse()? ( Ignorable by Annotation )

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

205
        return $parser->/** @scrutinizer ignore-call */ parseValue($source, $options);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
206
    }
207
208
    /**
209
     * @param Source $source
210
     * @param array  $options
211
     * @return TypeNodeInterface
212
     */
213
    public static function parseType(Source $source, array $options = []): TypeNodeInterface
214
    {
215
        /** @var ParserInterface $parser */
216
        $parser = static::make(ParserInterface::class);
217
218
        return $parser->parseType($source, $options);
0 ignored issues
show
Bug introduced by
The method parseType() does not exist on Digia\GraphQL\Language\ParserInterface. Did you maybe mean parse()? ( Ignorable by Annotation )

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

218
        return $parser->/** @scrutinizer ignore-call */ parseType($source, $options);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
219
    }
220
221
    /**
222
     * @param Schema       $schema
223
     * @param DocumentNode $document
224
     * @return array
225
     */
226
    public static function validate(Schema $schema, DocumentNode $document): array
227
    {
228
        /** @var ValidatorInterface $validator */
229
        $validator = static::make(ValidatorInterface::class);
230
231
        return $validator->validate($schema, $document);
232
    }
233
234
    /**
235
     * @param Schema                     $schema
236
     * @param DocumentNode               $document
237
     * @param mixed                      $rootValue
238
     * @param mixed                      $contextValue
239
     * @param array                      $variableValues
240
     * @param string|null                $operationName
241
     * @param callable|null              $fieldResolver
242
     * @param ErrorHandlerInterface|null $errorHandler
243
     * @return ExecutionResult
244
     */
245
    public static function execute(
246
        Schema $schema,
247
        DocumentNode $document,
248
        $rootValue = null,
249
        $contextValue = null,
250
        array $variableValues = [],
251
        $operationName = null,
252
        callable $fieldResolver = null,
253
        ?ErrorHandlerInterface $errorHandler = null
254
    ): ExecutionResult {
255
        /** @var ExecutionInterface $execution */
256
        $execution = static::make(ExecutionInterface::class);
257
258
        return $execution->execute(
259
            $schema,
260
            $document,
261
            $rootValue,
262
            $contextValue,
263
            $variableValues,
264
            $operationName,
265
            $fieldResolver,
266
            $errorHandler
267
        );
268
    }
269
270
    /**
271
     * @param Schema                     $schema
272
     * @param string                     $source
273
     * @param mixed                      $rootValue
274
     * @param mixed                      $contextValue
275
     * @param array                      $variableValues
276
     * @param null|string                $operationName
277
     * @param callable|null              $fieldResolver
278
     * @param ErrorHandlerInterface|null $errorHandler
279
     * @return ExecutionResult
280
     * @throws InvariantException
281
     * @throws SyntaxErrorException
282
     */
283
    public static function process(
284
        Schema $schema,
285
        string $source,
286
        $rootValue = null,
287
        $contextValue = null,
288
        array $variableValues = [],
289
        ?string $operationName = null,
290
        ?callable $fieldResolver = null,
291
        ?ErrorHandlerInterface $errorHandler = null
292
    ): ExecutionResult {
293
        $schemaValidationErrors = validateSchema($schema);
294
295
        if (!empty($schemaValidationErrors)) {
296
            if (null !== $errorHandler) {
297
                foreach ($schemaValidationErrors as $schemaValidationError) {
298
                    $errorHandler->handleError($schemaValidationError);
299
                }
300
            }
301
302
            return new ExecutionResult(null, $schemaValidationErrors);
303
        }
304
305
        try {
306
            $document = parse($source);
307
        } catch (SyntaxErrorException $error) {
308
            if (null !== $errorHandler) {
309
                $errorHandler->handleError($error);
310
            }
311
312
            return new ExecutionResult(null, [$error]);
313
        }
314
315
        $validationErrors = validate($schema, $document);
316
317
        if (!empty($validationErrors)) {
318
            if (null !== $errorHandler) {
319
                foreach ($validationErrors as $validationError) {
320
                    $errorHandler->handleError($validationError);
321
                }
322
            }
323
324
            return new ExecutionResult(null, $validationErrors);
325
        }
326
327
        return execute(
328
            $schema,
329
            $document,
330
            $rootValue,
331
            $contextValue,
332
            $variableValues,
333
            $operationName,
334
            $fieldResolver,
335
            $errorHandler
336
        );
337
    }
338
339
    /**
340
     * @param NodeInterface $node
341
     * @return string
342
     */
343
    public static function print(NodeInterface $node): string
344
    {
345
        /** @var NodePrinterInterface $nodePrinter */
346
        $nodePrinter = static::make(NodePrinterInterface::class);
347
348
        return $nodePrinter->print($node);
349
    }
350
351
    /**
352
     * @return Container
353
     */
354
    public function getContainer(): Container
355
    {
356
        return $this->container;
357
    }
358
359
    /**
360
     * Registers the service provides with the container.
361
     *
362
     * @param Container $container
363
     */
364
    protected function registerProviders(Container $container): void
365
    {
366
        foreach (self::$providers as $className) {
367
            $container->addServiceProvider($className);
368
        }
369
    }
370
}
371