Completed
Pull Request — master (#128)
by Christoffer
02:13
created

FieldsTrait::defineFieldMap()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 45
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

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

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