Passed
Push — master ( 50a671...528684 )
by y
02:25
created

FieldValues::offsetExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Helix\Asana\Task;
4
5
use ArrayAccess;
6
use Countable;
7
use Generator;
8
use Helix\Asana\Base\Data;
9
use Helix\Asana\CustomField;
10
use Helix\Asana\Task;
11
use IteratorAggregate;
12
13
/**
14
 * Custom field value adapter for tasks.
15
 *
16
 * Field access is by GID.
17
 *
18
 * Enum values are set by option GID.
19
 */
20
class FieldValues extends Data implements ArrayAccess, Countable, IteratorAggregate {
21
22
    /**
23
     * ` [ field gid => data index ]`
24
     *
25
     * @var int[]
26
     */
27
    protected $index = [];
28
29
    /**
30
     * `[ enum gid => option gid => option name ]`
31
     *
32
     * @var string[][]
33
     */
34
    protected $optionNames = [];
35
36
    /**
37
     * @var Task
38
     */
39
    protected $task;
40
41
    /**
42
     * `[ field gid => type ]`
43
     *
44
     * @var string[]
45
     */
46
    protected $types = [];
47
48
    public function __construct (Task $task, array $data = []) {
49
        $this->task = $task;
50
        parent::__construct($task, $data);
51
    }
52
53
    /**
54
     * Strips Asana's beefy data array down to what we need and builds indexes.
55
     *
56
     * @param array $data
57
     */
58
    protected function _setData (array $data): void {
59
        $this->index = [];
60
        $this->optionNames = [];
61
        $keys = array_flip(['gid', 'name', 'type', 'enum_options', 'enum_value', 'text_value', 'number_value']);
62
        foreach ($data as $i => $field) {
63
            $field = array_intersect_key($field, $keys);
64
            if ($field['type'] === CustomField::TYPE_ENUM) {
65
                foreach ($field['enum_options'] as $j => $option) {
66
                    $field['enum_options'][$j] = ['gid' => $option['gid'], 'name' => $option['name']];
67
                    $this->optionNames[$field['gid']][$option['gid']] = $option['name'];
68
                }
69
                $field['enum_value'] = ['gid' => $field['enum_value']['gid']];
70
            }
71
            $this->index[$field['gid']] = $i;
72
            $data[$i] = $field;
73
        }
74
        parent::_setData($data);
75
    }
76
77
    /**
78
     * @return int
79
     */
80
    public function count () {
81
        return count($this->data);
82
    }
83
84
    /**
85
     * @param string $enumGid
86
     * @return null|string
87
     */
88
    public function getCurrentOptionName (string $enumGid): ?string {
89
        return $this->getOptionName($enumGid, $this[$enumGid]);
1 ignored issue
show
Bug introduced by
It seems like $this[$enumGid] can also be of type null; however, parameter $optionGid of Helix\Asana\Task\FieldValues::getOptionName() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

89
        return $this->getOptionName($enumGid, /** @scrutinizer ignore-type */ $this[$enumGid]);
Loading history...
90
    }
91
92
    public function getDiff (): array {
93
        $diff = [];
94
        foreach (array_keys($this->diff) as $index) {
95
            $gid = $this->index[$index];
96
            $diff[$gid] = $this[$gid];
97
        }
98
        return $diff;
99
    }
100
101
    /**
102
     * @return Generator
103
     */
104
    public function getIterator () {
105
        foreach (array_keys($this->index) as $gid) {
106
            yield $gid => $this[$gid];
107
        }
108
    }
109
110
    /**
111
     * @param string $fieldGid
112
     * @return null|string
113
     */
114
    public function getName (string $fieldGid): ?string {
115
        return $this->data[$this->index[$fieldGid]]['name'];
116
    }
117
118
    /**
119
     * Field names, keyed by GID.
120
     *
121
     * @return string[]
122
     */
123
    public function getNames () {
124
        return array_column($this->data, 'name', 'gid');
125
    }
126
127
    /**
128
     * @param string $enumGid
129
     * @param string $optionGid
130
     * @return null|string
131
     */
132
    public function getOptionName (string $enumGid, string $optionGid): ?string {
133
        return $this->optionNames[$enumGid][$optionGid];
134
    }
135
136
    /**
137
     * Enum option names, keyed by GID.
138
     *
139
     * @param string $enumGid
140
     * @return string[]
141
     */
142
    public function getOptionNames (string $enumGid) {
143
        return $this->optionNames[$enumGid];
144
    }
145
146
    /**
147
     * @param string $fieldGid
148
     * @return null|number|string
149
     */
150
    public function getValue (string $fieldGid) {
151
        $field = $this->data[$this->index[$fieldGid]];
152
        if ($field['type'] === CustomField::TYPE_ENUM) {
153
            return $field['enum_value']['gid'];
154
        }
155
        return $field["{$field['type']}_value"];
156
    }
157
158
    /**
159
     * @param string $fieldGid
160
     * @return bool
161
     */
162
    public function offsetExists ($fieldGid) {
163
        return array_key_exists($this->index[$fieldGid], $this->data);
164
    }
165
166
    /**
167
     * @param string $fieldGid
168
     * @return null|number|string
169
     */
170
    public function offsetGet ($fieldGid) {
171
        return $this->getValue($fieldGid);
172
    }
173
174
    /**
175
     * @param string $fieldGid
176
     * @param null|number|string $value
177
     */
178
    public function offsetSet ($fieldGid, $value) {
179
        $this->setValue($fieldGid, $value);
180
    }
181
182
    /**
183
     * Custom fields cannot be "removed" through this. This only sets them to `null`.
184
     *
185
     * @param string $fieldGid
186
     */
187
    public function offsetUnset ($fieldGid) {
188
        $this->setValue($fieldGid, null);
189
    }
190
191
    /**
192
     * @param string $fieldGid
193
     * @param null|number|string $value
194
     * @return $this
195
     */
196
    public function setValue (string $fieldGid, $value) {
197
        $i = $this->index[$fieldGid];
198
        $type = $this->data[$i]['type'];
199
        if ($type === CustomField::TYPE_ENUM) {
200
            $this->data[$i]['enum_value']['gid'] = $value;
201
        }
202
        else {
203
            $this->data["{$type}_value"] = $value;
204
        }
205
        $this->diff[$i] = true;
206
        $this->task->diff['custom_fields'] = true;
207
        return $this;
208
    }
209
}