Passed
Pull Request — master (#128)
by Christoffer
02:40
created

FieldsTrait::setFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
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\Error\InvariantException;
6
use function Digia\GraphQL\Type\isAssocArray;
7
use function Digia\GraphQL\Type\resolveThunk;
8
use function Digia\GraphQL\Util\invariant;
9
use function Digia\GraphQL\Util\toString;
10
11
trait FieldsTrait
12
{
13
14
    /**
15
     * @var array|callable
16
     */
17
    private $_fieldsThunk;
18
19
    /**
20
     * @var Field[]
21
     */
22
    private $_fieldMap = [];
23
24
    /**
25
     * @var bool
26
     */
27
    private $_isFieldMapDefined = false;
28
29
    /**
30
     * @return Field[]
31
     */
32
    public function getFields(): array
33
    {
34
        $this->defineFieldMapIfNecessary();
35
36
        return $this->_fieldMap;
37
    }
38
39
    /**
40
     *
41
     */
42
    protected function defineFieldMapIfNecessary(): void
43
    {
44
        // Fields are built lazily to avoid concurrency issues.
45
        if (!$this->_isFieldMapDefined) {
46
            $this->_fieldMap = array_merge($this->defineFieldMap($this->_fieldsThunk), $this->_fieldMap);
47
48
            $this->_isFieldMapDefined = true;
49
        }
50
    }
51
52
    /**
53
     * @param array|callable $fieldsThunk
54
     * @return $this
55
     */
56
    protected function setFields($fieldsThunk)
57
    {
58
        $this->_fieldsThunk = $fieldsThunk;
59
60
        return $this;
61
    }
62
63
    /**
64
     * @param mixed $fieldsThunk
65
     * @return array
66
     * @throws InvariantException
67
     */
68
    protected function defineFieldMap($fieldsThunk): array
69
    {
70
        $fields = resolveThunk($fieldsThunk) ?: [];
71
72
        invariant(
73
            isAssocArray($fields),
74
            sprintf(
75
                '%s fields must be an associative array with field names as key or a callable which returns such an array.',
76
                $this->getName()
0 ignored issues
show
Bug introduced by
It seems like getName() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

76
                $this->/** @scrutinizer ignore-call */ 
77
                       getName()
Loading history...
77
            )
78
        );
79
80
        $fieldMap = [];
81
82
        foreach ($fields as $fieldName => $fieldConfig) {
83
            invariant(
84
                is_array($fieldConfig),
85
                sprintf('%s.%s field config must be an array', $this->getName(), $fieldName)
86
            );
87
88
            invariant(
89
                !isset($fieldConfig['isDeprecated']),
90
                sprintf(
91
                    '%s.%s should provide "deprecationReason" instead of "isDeprecated".',
92
                    $this->getName(),
93
                    $fieldName
94
                )
95
            );
96
97
            if (isset($fieldConfig['resolve'])) {
98
                invariant(
99
                    $this->isValidResolver($fieldConfig['resolve']),
100
                    sprintf(
101
                        '%s.%s field resolver must be a function if provided, but got: %s',
102
                        $this->getName(),
103
                        $fieldName,
104
                        toString($fieldConfig['resolve'])
105
                    )
106
                );
107
            }
108
109
            $fieldMap[$fieldName] = new Field(array_merge($fieldConfig, ['name' => $fieldName]));
110
        }
111
112
        return $fieldMap;
113
    }
114
115
    /**
116
     * @param $resolver
117
     * @return bool
118
     */
119
    protected function isValidResolver($resolver): bool
120
    {
121
        return $resolver === null || \is_callable($resolver);
122
    }
123
}
124