Passed
Pull Request — master (#201)
by Christoffer
02:32
created

ObjectType::buildInterfaces()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
namespace Digia\GraphQL\Type\Definition;
4
5
use Digia\GraphQL\Error\InvariantException;
6
use Digia\GraphQL\Language\Node\ASTNodeAwareInterface;
7
use Digia\GraphQL\Language\Node\ASTNodeTrait;
8
use Digia\GraphQL\Language\Node\ObjectTypeDefinitionNode;
9
use Digia\GraphQL\Language\Node\ObjectTypeExtensionNode;
10
use React\Promise\PromiseInterface;
11
use function Digia\GraphQL\Type\resolveThunk;
12
use function Digia\GraphQL\Util\invariant;
13
14
/**
15
 * Object Type Definition
16
 *
17
 * Almost all of the GraphQL types you define will be object types. Object types
18
 * have a name, but most importantly describe their fields.
19
 *
20
 * Example:
21
 *
22
 *     $AddressType = newObjectType([
23
 *       'name'   => 'Address',
24
 *       'fields' => [
25
 *         'street'    => ['type' => String()],
26
 *         'number'    => ['type' => LInt()],
27
 *         'formatted' => [
28
 *           'type'    => String(),
29
 *           'resolve' => function ($obj) {
30
 *             return $obj->number . ' ' . $obj->street
31
 *           }
32
 *         ]
33
 *       ]
34
 *     ]);
35
 *
36
 * When two types need to refer to each other, or a type needs to refer to
37
 * itself in a field, you can use a function expression (aka a closure or a
38
 * thunk) to supply the fields lazily.
39
 *
40
 * Example:
41
 *
42
 *     $PersonType = newObjectType([
43
 *       'name' => 'Person',
44
 *       'fields' => function () {
45
 *         return [
46
 *           'name'       => ['type' => String()],
47
 *           'bestFriend' => ['type' => $PersonType],
48
 *         ];
49
 *       }
50
 *     ]);
51
 */
52
class ObjectType implements TypeInterface, NamedTypeInterface, CompositeTypeInterface, OutputTypeInterface,
53
    ASTNodeAwareInterface
54
{
55
    use NameTrait;
56
    use DescriptionTrait;
57
    use FieldsTrait;
58
    use ResolveTrait;
59
    use ASTNodeTrait;
60
    use ExtensionASTNodesTrait;
61
62
    /**
63
     * @var callable
64
     */
65
    protected $isTypeOfCallback;
66
67
    /**
68
     * Interfaces can be defined either as an array or as a thunk.
69
     * Using thunks allows for cross-referencing of interfaces.
70
     *
71
     * @var array|callable
72
     */
73
    protected $interfacesOrThunk;
74
75
    /**
76
     * A list of interface instances.
77
     *
78
     * @var InterfaceType[]|null
79
     */
80
    protected $interfaces;
81
82
    /**
83
     * ObjectType constructor.
84
     *
85
     * @param string                        $name
86
     * @param null|string                   $description
87
     * @param array|callable                $fieldsOrThunk
88
     * @param array|callable                $interfacesOrThunk
89
     * @param callable|null                 $isTypeOfCallback
90
     * @param ObjectTypeDefinitionNode|null $astNode
91
     * @param ObjectTypeExtensionNode[]     $extensionASTNodes
92
     * @throws InvariantException
93
     */
94
    public function __construct(
95
        string $name,
96
        ?string $description,
97
        $fieldsOrThunk,
98
        $interfacesOrThunk,
99
        ?callable $isTypeOfCallback,
100
        ?ObjectTypeDefinitionNode $astNode,
101
        array $extensionASTNodes
102
    ) {
103
        $this->name              = $name;
104
        $this->description       = $description;
105
        $this->fieldsOrThunk     = $fieldsOrThunk;
106
        $this->interfacesOrThunk = $interfacesOrThunk;
107
        $this->isTypeOfCallback  = $isTypeOfCallback;
108
        $this->astNode           = $astNode;
109
        $this->extensionAstNodes = $extensionASTNodes;
110
111
        invariant(null !== $this->getName(), 'Must provide name.');
112
113
        if (null !== $this->isTypeOfCallback) {
114
            invariant(
115
                \is_callable($this->getIsTypeOf()),
116
                \sprintf('%s must provide "isTypeOf" as a function.', $this->getName())
117
            );
118
        }
119
    }
120
121
    /**
122
     * @param mixed $value
123
     * @param mixed context
0 ignored issues
show
Bug introduced by
The type Digia\GraphQL\Type\Definition\context 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...
124
     * @param mixed $info
125
     * @return bool|PromiseInterface
126
     */
127
    public function isTypeOf($value, $context, $info)
128
    {
129
        return isset($this->isTypeOfCallback)
130
            ? \call_user_func($this->isTypeOfCallback, $value, $context, $info)
131
            : false;
132
    }
133
134
    /**
135
     * @return InterfaceType[]
136
     * @throws InvariantException
137
     */
138
    public function getInterfaces(): array
139
    {
140
        if (!isset($this->interfaces)) {
141
            $this->interfaces = $this->buildInterfaces($this->interfacesOrThunk);
142
        }
143
        return $this->interfaces;
144
    }
145
146
    /**
147
     * @return null|callable
148
     */
149
    public function getIsTypeOf(): ?callable
150
    {
151
        return $this->isTypeOfCallback;
152
    }
153
154
    /**
155
     * @param array|callable $interfacesOrThunk
156
     * @return array
157
     * @throws InvariantException
158
     */
159
    protected function buildInterfaces($interfacesOrThunk): array
160
    {
161
        $interfaces = resolveThunk($interfacesOrThunk);
162
163
        invariant(
164
            \is_array($interfaces),
165
            \sprintf('%s interfaces must be an array or a function which returns an array.', $this->getName())
166
        );
167
168
        return $interfaces;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $interfaces could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
169
    }
170
}
171