Completed
Pull Request — master (#201)
by Christoffer
02:54
created

UnionType::afterConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
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\UnionTypeDefinitionNode;
9
use function Digia\GraphQL\Type\resolveThunk;
10
use function Digia\GraphQL\Util\invariant;
11
12
/**
13
 * Union Type Definition
14
 *
15
 * When a field can return one of a heterogeneous set of types, a Union type
16
 * is used to describe what types are possible as well as providing a function
17
 * to determine which type is actually used when the field is resolved.
18
 *
19
 * Example:
20
 *
21
 *     $PetType = GraphQLUnionType([
22
 *       'name' => 'Pet',
23
 *       'types' => [$DogType, $CatType],
24
 *       'resolveType' => function ($value) {
25
 *         if ($value instanceof Dog) {
26
 *           return $DogType;
27
 *         }
28
 *         if ($value instanceof Cat) {
29
 *           return $CatType;
30
 *         }
31
 *       }
32
 *     ]);
33
 */
34
class UnionType implements AbstractTypeInterface, NamedTypeInterface, CompositeTypeInterface, OutputTypeInterface,
35
    ASTNodeAwareInterface
36
{
37
    use NameTrait;
38
    use DescriptionTrait;
39
    use ResolveTypeTrait;
40
    use ASTNodeTrait;
41
42
    /**
43
     * Types can be defined either as an array or as a thunk.
44
     * Using thunks allows for cross-referencing of types.
45
     *
46
     * @var array|callable
47
     */
48
    protected $typesOrThunk;
49
50
    /**
51
     * A key-value map over type names and their corresponding type instances.
52
     *
53
     * @var TypeInterface[]
54
     */
55
    protected $typeMap;
56
57
    /**
58
     * UnionType constructor.
59
     *
60
     * @param string                       $name
61
     * @param null|string                  $description
62
     * @param array|callable               $typesOrThunk
63
     * @param callable|null                $resolveTypeCallback
64
     * @param UnionTypeDefinitionNode|null $astNode
65
     * @throws InvariantException
66
     */
67
    public function __construct(
68
        string $name,
69
        ?string $description,
70
        $typesOrThunk,
71
        ?callable $resolveTypeCallback,
72
        ?UnionTypeDefinitionNode $astNode
73
    ) {
74
        $this->name                = $name;
75
        $this->description         = $description;
76
        $this->typesOrThunk        = $typesOrThunk;
77
        $this->resolveTypeCallback = $resolveTypeCallback;
78
        $this->astNode             = $astNode;
79
80
        invariant(null !== $this->getName(), 'Must provide name.');
81
    }
82
83
    /**
84
     * @return NamedTypeInterface[]
85
     * @throws InvariantException
86
     */
87
    public function getTypes(): array
88
    {
89
        // Types are built lazily to avoid concurrency issues.
90
        if (!isset($this->typeMap)) {
91
            $this->typeMap = $this->buildTypeMap($this->typesOrThunk);
92
        }
93
        return $this->typeMap;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->typeMap returns an array which contains values of type Digia\GraphQL\Type\Definition\TypeInterface which are incompatible with the documented value type Digia\GraphQL\Type\Definition\NamedTypeInterface.
Loading history...
94
    }
95
96
    /**
97
     * @param array|callable $typesOrThunk
98
     * @return UnionType
99
     */
100
    protected function setTypes($typesOrThunk): UnionType
101
    {
102
        $this->typesOrThunk = $typesOrThunk;
103
        return $this;
104
    }
105
106
    /**
107
     * @param array|callable $typesOrThunk
108
     * @return array
109
     * @throws InvariantException
110
     */
111
    protected function buildTypeMap($typesOrThunk): array
112
    {
113
        $typeMap = resolveThunk($typesOrThunk);
114
115
        invariant(
116
            \is_array($typeMap),
117
            \sprintf(
118
                'Must provide Array of types or a function which returns such an array for Union %s.',
119
                $this->name
120
            )
121
        );
122
123
        return $typeMap;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $typeMap 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...
124
    }
125
}
126