Completed
Pull Request — master (#15)
by Christoffer
06:08 queued 03:44
created

FieldsTrait::addField()   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 function Digia\GraphQL\Type\isAssocArray;
6
use function Digia\GraphQL\Type\isValidResolver;
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
     * @throws \Exception
32
     */
33
    public function getFields(): array
34
    {
35
        $this->defineFieldMapIfNecessary();
36
37
        return $this->_fieldMap;
38
    }
39
40
    /**
41
     * @throws \Exception
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 \Exception
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
                    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