Completed
Pull Request — master (#15)
by Christoffer
02:55 queued 44s
created

__DirectiveLocation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 71
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 71
rs 9.1369
c 0
b 0
f 0
cc 2
eloc 46
nc 2
nop 0

How to fix   Long Method   

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:

1
<?php
2
3
namespace Digia\GraphQL\Type;
4
5
use Digia\GraphQL\Language\AST\DirectiveLocationEnum;
6
use Digia\GraphQL\Type\Contract\SchemaInterface;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Digia\GraphQL\Type\SchemaInterface. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
Bug introduced by
The type Digia\GraphQL\Type\Contract\SchemaInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Digia\GraphQL\Type\Definition\AbstractType;
8
use Digia\GraphQL\Type\Definition\Contract\DirectiveInterface;
0 ignored issues
show
Bug introduced by
The type Digia\GraphQL\Type\Defin...ract\DirectiveInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Digia\GraphQL\Type\Definition\Contract\TypeInterface;
0 ignored issues
show
Bug introduced by
The type Digia\GraphQL\Type\Defin...\Contract\TypeInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Digia\GraphQL\Type\Definition\EnumType;
11
use Digia\GraphQL\Type\Definition\Field;
12
use Digia\GraphQL\Type\Definition\InputObjectType;
13
use Digia\GraphQL\Type\Definition\InterfaceType;
14
use Digia\GraphQL\Type\Definition\ListType;
15
use Digia\GraphQL\Type\Definition\NonNullType;
16
use Digia\GraphQL\Type\Definition\ObjectType;
17
use Digia\GraphQL\Type\Definition\ScalarType;
18
use Digia\GraphQL\Type\Definition\UnionType;
19
use function Digia\GraphQL\Util\arraySome;
20
21
/**
22
 * @return ObjectType
23
 */
24
function __Schema(): ObjectType
25
{
26
    static $instance = null;
27
28
    if (null === $instance) {
29
        $instance = GraphQLObjectType([
30
            'name'            => '__Schema',
31
            'isIntrospection' => true,
32
            'description'     =>
33
                'A GraphQL Schema defines the capabilities of a GraphQL server. It ' .
34
                'exposes all available types and directives on the server, as well as ' .
35
                'the entry points for query, mutation, and subscription operations.',
36
            'fields'          => function () {
37
                return [
38
                    'types'            => [
39
                        'description' => 'A list of all types supported by this server.',
40
                        'type'        => GraphQLNonNull(GraphQLList(GraphQLNonNull(__Type()))),
41
                        'resolve'     => function (SchemaInterface $schema): array {
42
                            return array_values($schema->getTypeMap());
43
                        },
44
                    ],
45
                    'queryType'        => [
46
                        'description' => 'The type that query operations will be rooted at.',
47
                        'type'        => GraphQLNonNull(__Type()),
48
                        'resolve'     => function (SchemaInterface $schema): ObjectType {
49
                            return $schema->getQuery();
50
                        },
51
                    ],
52
                    'mutationType'     => [
53
                        'description' =>
54
                            'If this server supports mutation, the type that ' .
55
                            'mutation operations will be rooted at.',
56
                        'type'        => __Type(),
57
                        'resolve'     => function (SchemaInterface $schema): ObjectType {
58
                            return $schema->getMutation();
59
                        },
60
                    ],
61
                    'subscriptionType' => [
62
                        'description' =>
63
                            'If this server support subscription, the type that ' .
64
                            'subscription operations will be rooted at.',
65
                        'type'        => __Type(),
66
                        'resolve'     => function (SchemaInterface $schema): ObjectType {
67
                            return $schema->getSubscription();
68
                        },
69
                    ],
70
                    'directives'       => [
71
                        'description' => 'A list of all directives supported by this server.',
72
                        'type'        => GraphQLNonNull(GraphQLList(GraphQLNonNull(__Directive()))),
73
                        'resolve'     => function (SchemaInterface $schema): array {
74
                            return $schema->getDirectives();
75
                        },
76
                    ],
77
                ];
78
            }
79
        ]);
80
    }
81
82
    return $instance;
83
}
84
85
/**
86
 * @return ObjectType
87
 */
88
function __Directive(): ObjectType
89
{
90
    static $instance = null;
91
92
    if (null === $instance) {
93
        $instance = GraphQLObjectType([
94
            'name'            => '__Directive',
95
            'isIntrospection' => true,
96
            'description'     =>
97
                'A Directive provides a way to describe alternate runtime execution and ' .
98
                'type validation behavior in a GraphQL document.' .
99
                "\n\nIn some cases, you need to provide options to alter GraphQL's " .
100
                'execution behavior in ways field arguments will not suffice, such as ' .
101
                'conditionally including or skipping a field. Directives provide this by ' .
102
                'describing additional information to the executor.',
103
            'fields'          => function () {
104
                return [
105
                    'name'        => ['type' => GraphQLNonNull(GraphQLString())],
106
                    'description' => ['type' => GraphQLString()],
107
                    'locations'   => [
108
                        'type' => GraphQLNonNull(GraphQLList(GraphQLNonNull(__DirectiveLocation()))),
109
                    ],
110
                    'args'        => [
111
                        'type'    => GraphQLNonNull(GraphQLList(GraphQLNonNull(__InputValue()))),
112
                        'resolve' => function (DirectiveInterface $directive): array {
113
                            return $directive->getArgs() ?: [];
114
                        },
115
                    ],
116
                ];
117
            }
118
        ]);
119
    }
120
121
    return $instance;
122
}
123
124
/**
125
 * @return EnumType
126
 */
127
function __DirectiveLocation(): EnumType
128
{
129
    static $instance = null;
130
131
    if (null === $instance) {
132
        $instance = GraphQLEnumType([
133
            'name'            => '__DirectiveLocation',
134
            'isIntrospection' => true,
135
            'description'     =>
136
                'A Directive can be adjacent to many parts of the GraphQL language, a ' .
137
                '__DirectiveLocation describes one such possible adjacencies.',
138
            'values'          => [
139
                DirectiveLocationEnum::QUERY                  => [
140
                    'description' => 'Location adjacent to a query operation.',
141
                ],
142
                DirectiveLocationEnum::MUTATION               => [
143
                    'description' => 'Location adjacent to a mutation operation.',
144
                ],
145
                DirectiveLocationEnum::SUBSCRIPTION           => [
146
                    'description' => 'Location adjacent to a subscription operation.',
147
                ],
148
                DirectiveLocationEnum::FIELD                  => [
149
                    'description' => 'Location adjacent to a field.',
150
                ],
151
                DirectiveLocationEnum::FRAGMENT_DEFINITION    => [
152
                    'description' => 'Location adjacent to a fragment definition.',
153
                ],
154
                DirectiveLocationEnum::FRAGMENT_SPREAD        => [
155
                    'description' => 'Location adjacent to a fragment spread.',
156
                ],
157
                DirectiveLocationEnum::INLINE_FRAGMENT        => [
158
                    'description' => 'Location adjacent to an inline fragment.',
159
                ],
160
                DirectiveLocationEnum::SCHEMA                 => [
161
                    'description' => 'Location adjacent to a schema definition.',
162
                ],
163
                DirectiveLocationEnum::SCALAR                 => [
164
                    'description' => 'Location adjacent to a scalar definition.',
165
                ],
166
                DirectiveLocationEnum::OBJECT                 => [
167
                    'description' => 'Location adjacent to an object type definition.',
168
                ],
169
                DirectiveLocationEnum::FIELD_DEFINITION       => [
170
                    'description' => 'Location adjacent to a field definition.',
171
                ],
172
                DirectiveLocationEnum::ARGUMENT_DEFINITION    => [
173
                    'description' => 'Location adjacent to an argument definition.',
174
                ],
175
                DirectiveLocationEnum::INTERFACE              => [
176
                    'description' => 'Location adjacent to an interface definition.',
177
                ],
178
                DirectiveLocationEnum::UNION                  => [
179
                    'description' => 'Location adjacent to a union definition.',
180
                ],
181
                DirectiveLocationEnum::ENUM                   => [
182
                    'description' => 'Location adjacent to an enum definition.',
183
                ],
184
                DirectiveLocationEnum::ENUM_VALUE             => [
185
                    'description' => 'Location adjacent to an enum value definition.',
186
                ],
187
                DirectiveLocationEnum::INPUT_OBJECT           => [
188
                    'description' => 'Location adjacent to an input object type definition.',
189
                ],
190
                DirectiveLocationEnum::INPUT_FIELD_DEFINITION => [
191
                    'description' => 'Location adjacent to an input object field definition.',
192
                ],
193
            ],
194
        ]);
195
    }
196
197
    return $instance;
198
}
199
200
/**
201
 * @return ObjectType
202
 */
203
function __Type(): ObjectType
204
{
205
    static $instance = null;
206
207
    if (null === $instance) {
208
        $instance = GraphQLObjectType([
209
            'name'            => '__Type',
210
            'isIntrospection' => true,
211
            'description'     =>
212
                'The fundamental unit of any GraphQL Schema is the type. There are ' .
213
                'many kinds of types in GraphQL as represented by the `__TypeKind` enum.' .
214
                '\n\nDepending on the kind of a type, certain fields describe ' .
215
                'information about that type. Scalar types provide no information ' .
216
                'beyond a name and description, while Enum types provide their values. ' .
217
                'Object and Interface types provide the fields they describe. Abstract ' .
218
                'types, Union and Interface, provide the Object types possible ' .
219
                'at runtime. List and NonNull types compose other types.',
220
            'fields'          => function () {
221
                return [
222
                    'kind'          => [
223
                        'type'    => GraphQLNonNull(__TypeKind()),
224
                        'resolve' => function (TypeInterface $type) {
225
                            if ($type instanceof ScalarType) {
226
                                return TypeKindEnum::SCALAR;
227
                            }
228
                            if ($type instanceof ObjectType) {
229
                                return TypeKindEnum::OBJECT;
230
                            }
231
                            if ($type instanceof InterfaceType) {
232
                                return TypeKindEnum::INTERFACE;
233
                            }
234
                            if ($type instanceof UnionType) {
235
                                return TypeKindEnum::UNION;
236
                            }
237
                            if ($type instanceof EnumType) {
238
                                return TypeKindEnum::ENUM;
239
                            }
240
                            if ($type instanceof InputObjectType) {
241
                                return TypeKindEnum::INPUT_OBJECT;
242
                            }
243
                            if ($type instanceof ListType) {
244
                                return TypeKindEnum::LIST;
245
                            }
246
                            if ($type instanceof NonNullType) {
247
                                return TypeKindEnum::NON_NULL;
248
                            }
249
250
                            throw new \Exception(sprintf('Unknown kind of type: %s', $type));
251
                        },
252
                    ],
253
                    'name'          => ['type' => GraphQLString()],
254
                    'description'   => ['type' => GraphQLString()],
255
                    'fields'        => [
256
                        'type'    => GraphQLList(GraphQLNonNull(__Field())),
257
                        'args'    => [
258
                            'includeDeprecated' => ['type' => GraphQLBoolean(), 'defaultValue' => false],
259
                        ],
260
                        'resolve' => function (TypeInterface $type, array $args): ?array {
261
                            list ($includeDeprecated) = $args;
262
263
                            if ($type instanceof ObjectType || $type instanceof InterfaceType) {
264
                                $fields = array_values($type->getFields());
265
266
                                if (!$includeDeprecated) {
267
                                    $fields = array_filter($fields, function (Field $field) {
268
                                        return !$field->isDeprecated();
269
                                    });
270
                                }
271
272
                                return $fields;
273
                            }
274
275
                            return null;
276
                        },
277
                    ],
278
                    'interfaces'    => [
279
                        'type'    => GraphQLList(GraphQLNonNull(__Type())),
280
                        'resolve' => function (TypeInterface $type): ?array {
281
                            return $type instanceof ObjectType ? $type->getInterfaces() : null;
282
                        },
283
                    ],
284
                    'possibleTypes' => [
285
                        'type'    => GraphQLList(GraphQLNonNull(__Type())),
286
                        'resolve' => function (TypeInterface $type, $args, $context, $info): ?array {
287
                            /** @var SchemaInterface $schema */
288
                            list ($schema) = $info;
289
                            return $type instanceof AbstractType ? $schema->getPossibleTypes($type) : null;
290
                        },
291
                    ],
292
                    'enumValues'    => [
293
                        'type'    => GraphQLList(GraphQLNonNull(__EnumValue())),
294
                        'args'    => [
295
                            'includeDeprecated' => ['type' => GraphQLBoolean(), 'defaultValue' => false],
296
                        ],
297
                        'resolve' => function (TypeInterface $type, array $args): ?array {
298
                            list ($includeDeprecated) = $args;
299
300
                            if ($type instanceof EnumType) {
301
                                $values = array_values($type->getValues());
302
303
                                if (!$includeDeprecated) {
304
                                    $values = array_filter($values, function (Field $field) {
305
                                        return !$field->isDeprecated();
306
                                    });
307
                                }
308
309
                                return $values;
310
                            }
311
312
                            return null;
313
                        },
314
                    ],
315
                    'inputFields'   => [
316
                        'type'    => GraphQLList(GraphQLNonNull(__InputValue())),
317
                        'resolve' => function (TypeInterface $type): ?array {
318
                            return $type instanceof InputObjectType ? $type->getFields() : null;
319
                        },
320
                    ],
321
                    'ofType'        => ['type' => __Type()],
322
                ];
323
            }
324
        ]);
325
    }
326
327
    return $instance;
328
}
329
330
/**
331
 * @return ObjectType
332
 */
333
function __Field(): ObjectType
334
{
335
    static $instance = null;
336
337
    if (null === $instance) {
338
        $instance = GraphQLObjectType([
339
            'name'            => '__Field',
340
            'isIntrospection' => true,
341
            'description'     =>
342
                'Object and Interface types are described by a list of Fields, each of ' .
343
                'which has a name, potentially a list of arguments, and a return type.',
344
            'fields'          => function () {
345
                return [
346
                    'name'              => ['type' => GraphQLNonNull(GraphQLString())],
347
                    'description'       => ['type' => GraphQLString()],
348
                    'args'              => [
349
                        'type'    => GraphQLNonNull(GraphQLList(GraphQLNonNull(__InputValue()))),
350
                        'resolve' => function (DirectiveInterface $directive): array {
351
                            return $directive->getArgs() ?: [];
352
                        },
353
                    ],
354
                    'type'              => ['type' => GraphQLNonNull(__Type())],
355
                    'isDeprecated'      => ['type' => GraphQLNonNull(GraphQLBoolean())],
356
                    'deprecationReason' => ['type' => GraphQLString()],
357
                ];
358
            }
359
        ]);
360
    }
361
362
    return $instance;
363
}
364
365
/**
366
 * @return ObjectType
367
 */
368
function __InputValue(): ObjectType
369
{
370
    static $instance = null;
371
372
    if (null === $instance) {
373
        $instance = GraphQLObjectType([
374
            'name'            => '__InputValue',
375
            'isIntrospection' => true,
376
            'description'     =>
377
                'Arguments provided to Fields or Directives and the input fields of an ' .
378
                'InputObject are represented as Input Values which describe their type ' .
379
                'and optionally a default value.',
380
            'fields'          => function () {
381
                return [
382
                    'name'         => ['type' => GraphQLNonNull(GraphQLString())],
383
                    'description'  => ['type' => GraphQLString()],
384
                    'type'         => ['type' => GraphQLNonNull(__Type())],
385
                    'defaultValue' => [
386
                        'type'        => GraphQLString(),
387
                        'description' =>
388
                            'A GraphQL-formatted string representing the default value for this ' .
389
                            'input value.',
390
                        'resolve'     => function ($inputValue) {
0 ignored issues
show
Unused Code introduced by
The parameter $inputValue is not used and could be removed. ( Ignorable by Annotation )

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

390
                        'resolve'     => function (/** @scrutinizer ignore-unused */ $inputValue) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
391
                            // TODO: Implement this when we have support for printing AST.
392
                            return null;
393
                        }
394
                    ],
395
                ];
396
            }
397
        ]);
398
    }
399
400
    return $instance;
401
}
402
403
/**
404
 * @return ObjectType
405
 */
406
function __EnumValue(): ObjectType
407
{
408
    static $instance = null;
409
410
    if (null === $instance) {
411
        $instance = GraphQLObjectType([
412
            'name'            => '__EnumValue',
413
            'isIntrospection' => true,
414
            'description'     =>
415
                'One possible value for a given Enum. Enum values are unique values, not ' .
416
                'a placeholder for a string or numeric value. However an Enum value is ' .
417
                'returned in a JSON response as a string.',
418
            'fields'          => function () {
419
                return [
420
                    'name'              => ['type' => GraphQLNonNull(GraphQLString())],
421
                    'description'       => ['type' => GraphQLString()],
422
                    'isDeprecated'      => ['type' => GraphQLNonNull(GraphQLBoolean())],
423
                    'deprecationReason' => ['type' => GraphQLString()],
424
                ];
425
            }
426
        ]);
427
    }
428
429
    return $instance;
430
}
431
432
function __TypeKind(): EnumType
433
{
434
    static $instance = null;
435
436
    if (null === $instance) {
437
        $instance = GraphQLEnumType([
438
            'name'            => '__TypeKind',
439
            'isIntrospection' => true,
440
            'description'     => 'An enum describing what kind of type a given `__Type` is.',
441
            'values'          => [
442
                TypeKindEnum::SCALAR => [
443
                    'description' => 'Indicates this type is a scalar.',
444
                ],
445
                TypeKindEnum::OBJECT => [
446
                    'description' => 'Indicates this type is an object. `fields` and `interfaces` are valid fields.',
447
                ],
448
                TypeKindEnum::INTERFACE => [
449
                    'description' => 'Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.',
450
                ],
451
                TypeKindEnum::UNION => [
452
                    'description' => 'Indicates this type is a union. `possibleTypes` is a valid field.',
453
                ],
454
                TypeKindEnum::ENUM => [
455
                    'description' => 'Indicates this type is an enum. `enumValues` is a valid field.',
456
                ],
457
                TypeKindEnum::INPUT_OBJECT => [
458
                    'description' => 'Indicates this type is an input object. `inputFields` is a valid field.',
459
                ],
460
                TypeKindEnum::LIST => [
461
                    'description' => 'Indicates this type is a list. `ofType` is a valid field.',
462
                ],
463
                TypeKindEnum::NON_NULL => [
464
                    'description' => 'Indicates this type is a non-null. `ofType` is a valid field.',
465
                ],
466
            ],
467
        ]);
468
    }
469
470
    return $instance;
471
}
472
473
/**
474
 * @return Field
475
 * @throws \TypeError
476
 */
477
function SchemaMetaFieldDefinition(): Field
478
{
479
    return new Field([
480
        'name' => '__schema',
481
        'type' => GraphQLNonNull(__Schema()),
482
        'description' => 'Access the current type schema of this server.',
483
        'resolve' => function ($source, $args, $context, $info): SchemaInterface {
484
            list ($schema) = $info;
485
            return $schema;
486
        }
487
    ]);
488
}
489
490
/**
491
 * @return Field
492
 * @throws \TypeError
493
 */
494
function TypeMetaFieldDefinition(): Field
495
{
496
    return new Field([
497
        'name' => '__type',
498
        'type' => __Type(),
499
        'description' => 'Request the type information of a single type.',
500
        'args' => [
501
            'name' => ['type' => GraphQLNonNull(GraphQLString())],
502
        ],
503
        'resolve' => function ($source, $args, $context, $info): TypeInterface {
504
            /** @var SchemaInterface $schema */
505
            list ($name) = $args;
506
            list ($schema) = $info;
507
            return $schema->getType($name);
508
        }
509
    ]);
510
}
511
512
/**
513
 * @return Field
514
 * @throws \TypeError
515
 */
516
function TypeNameMetaFieldDefinition(): Field
517
{
518
    return new Field([
519
        'name' => '__typename',
520
        'type' => GraphQLNonNull(GraphQLString()),
521
        'description' => 'The name of the current Object type at runtime.',
522
        'resolve' => function ($source, $args, $context, $info): string {
523
            /** @var TypeInterface $parentType */
524
            list ($parentType) = $info;
525
            return $parentType->getName();
526
        }
527
    ]);
528
}
529
530
/**
531
 * @return array
532
 */
533
function introspectionTypes(): array
534
{
535
    return [
536
        __Schema(),
537
        __Directive(),
538
        __DirectiveLocation(),
539
        __Type(),
540
        __Field(),
541
        __InputValue(),
542
        __EnumValue(),
543
        __TypeKind(),
544
    ];
545
}
546
547
/**
548
 * @param TypeInterface $type
549
 * @return bool
550
 */
551
function isIntrospectionType(TypeInterface $type): bool
552
{
553
    return arraySome(
554
        introspectionTypes(),
555
        function (TypeInterface $introspectionType) use ($type) {
556
            return $type->getName() === $introspectionType->getName();
557
        }
558
    );
559
}
560