Passed
Pull Request — master (#132)
by Christoffer
04:13 queued 01:55
created

ObjectType::isTypeOf()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 3
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Digia\GraphQL\Type\Definition;
4
5
use Digia\GraphQL\Config\ConfigObject;
6
use Digia\GraphQL\Error\InvariantException;
7
use Digia\GraphQL\Language\Node\NodeAwareInterface;
8
use Digia\GraphQL\Language\Node\NodeTrait;
9
use function Digia\GraphQL\Type\resolveThunk;
10
use function Digia\GraphQL\Util\invariant;
11
use React\Promise\PromiseInterface;
12
13
/**
14
 * Object Type Definition
15
 *
16
 * Almost all of the GraphQL types you define will be object types. Object types
17
 * have a name, but most importantly describe their fields.
18
 *
19
 * Example:
20
 *
21
 *     $AddressType = GraphQLObjectType([
22
 *       'name'   => 'Address',
23
 *       'fields' => [
24
 *         'street'    => ['type' => GraphQLString()],
25
 *         'number'    => ['type' => GraphQLInt()],
26
 *         'formatted' => [
27
 *           'type'    => GraphQLString(),
28
 *           'resolve' => function ($obj) {
29
 *             return $obj->number . ' ' . $obj->street
30
 *           }
31
 *         ]
32
 *       ]
33
 *     ]);
34
 *
35
 * When two types need to refer to each other, or a type needs to refer to
36
 * itself in a field, you can use a function expression (aka a closure or a
37
 * thunk) to supply the fields lazily.
38
 *
39
 * Example:
40
 *
41
 *     $PersonType = GraphQLObjectType([
42
 *       'name' => 'Person',
43
 *       'fields' => function () {
44
 *         return [
45
 *           'name'       => ['type' => GraphQLString()],
46
 *           'bestFriend' => ['type' => $PersonType],
47
 *         ];
48
 *       }
49
 *     ]);
50
 */
51
class ObjectType extends ConfigObject implements TypeInterface, NamedTypeInterface, CompositeTypeInterface,
52
    OutputTypeInterface, NodeAwareInterface
53
{
54
    use NameTrait;
55
    use DescriptionTrait;
56
    use FieldsTrait;
57
    use ResolveTrait;
58
    use NodeTrait;
59
    use ExtensionASTNodesTrait;
60
61
    /**
62
     * @var callable
63
     */
64
    protected $isTypeOfFunction;
65
66
    /**
67
     * @var array|callable
68
     */
69
    protected $interfacesOrThunk;
70
71
    /**
72
     * @var InterfaceType[]|null
73
     */
74
    protected $interfaces;
75
76
    /**
77
     * @inheritdoc
78
     */
79
    protected function afterConfig(): void
80
    {
81
        invariant(null !== $this->getName(), 'Must provide name.');
82
83
        if ($this->getIsTypeOf() !== null) {
84
            invariant(
85
                \is_callable($this->getIsTypeOf()),
86
                \sprintf('%s must provide "isTypeOf" as a function.', $this->getName())
87
            );
88
        }
89
    }
90
91
    /**
92
     * @param mixed $value
93
     * @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...
94
     * @param mixed $info
95
     * @return bool|PromiseInterface
96
     */
97
    public function isTypeOf($value, $context, $info)
98
    {
99
        return isset($this->isTypeOfFunction)
100
            ? \call_user_func($this->isTypeOfFunction, $value, $context, $info)
101
            : false;
102
    }
103
104
    /**
105
     * @return InterfaceType[]
106
     * @throws InvariantException
107
     */
108
    public function getInterfaces(): array
109
    {
110
        if (!isset($this->interfaces)) {
111
            $this->interfaces = $this->buildInterfaces($this->interfacesOrThunk ?? []);
112
        }
113
        return $this->interfaces;
114
    }
115
116
    /**
117
     * Objects are created using the `ConfigAwareTrait` constructor which will automatically
118
     * call this method when setting arguments from `$config['interfaces']`.
119
     *
120
     * @param array|callable $interfacesOrThunk
121
     * @return $this
122
     */
123
    protected function setInterfaces($interfacesOrThunk)
124
    {
125
        $this->interfacesOrThunk = $interfacesOrThunk;
126
        return $this;
127
    }
128
129
    /**
130
     * @return null|callable
131
     */
132
    public function getIsTypeOf(): ?callable
133
    {
134
        return $this->isTypeOfFunction;
135
    }
136
137
    /**
138
     * @param null|callable $isTypeOfFunction
139
     * @return $this
140
     */
141
    protected function setIsTypeOf(?callable $isTypeOfFunction)
142
    {
143
        $this->isTypeOfFunction = $isTypeOfFunction;
144
        return $this;
145
    }
146
147
    /**
148
     * @param array|callable $interfacesOrThunk
149
     * @return array
150
     * @throws InvariantException
151
     */
152
    protected function buildInterfaces($interfacesOrThunk): array
153
    {
154
        $interfaces = resolveThunk($interfacesOrThunk);
155
156
        invariant(
157
            \is_array($interfaces),
158
            \sprintf('%s interfaces must be an array or a function which returns an array.', $this->getName())
159
        );
160
161
        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...
162
    }
163
}
164