FieldEntry::getCustomField()   A
last analyzed

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 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Helix\Asana\Task;
4
5
use Helix\Asana\Base\Data;
6
use Helix\Asana\CustomField;
7
use Helix\Asana\Event\Change;
8
9
/**
10
 * A task's custom field entry.
11
 *
12
 * Enum values are set by option GID (recommended) or name.
13
 *
14
 * @method string getGid    () The custom field's GID.
15
 * @method string getName   ()
16
 * @method string getType   ()
17
 */
18
class FieldEntry extends Data {
19
20
    /**
21
     * @var Change|FieldEntries
22
     */
23
    protected $caller;
24
25
    /**
26
     * @var array
27
     */
28
    protected $data = [];
29
30
    /**
31
     * @param Change|FieldEntries $caller
32
     * @param array $data
33
     */
34
    public function __construct ($caller, array $data = []) {
35
        $this->caller = $caller;
36
        parent::__construct($caller, $data);
37
    }
38
39
    /**
40
     * @return string
41
     */
42
    public function __toString (): string {
43
        if ($this->isEnum()) {
44
            return (string)$this->getCurrentOptionName();
45
        }
46
        return (string)$this->getValue();
47
    }
48
49
    /**
50
     * Strips Asana's beefy data array down to what we need.
51
     *
52
     * @param array $data
53
     */
54
    protected function _setData (array $data): void {
55
        if (isset($data['resource_subtype'])) { // sentinel for bloat
56
            $tiny = array_intersect_key($data, array_flip([
57
                'gid',
58
                'name',
59
                'type', // "deprecated"
60
                'enum_options',
61
                "{$data['type']}_value"
62
            ]));
63
            if (isset($tiny['enum_options'])) {
64
                $tiny['enum_options'] = array_map(function(array $option) {
65
                    return ['gid' => $option['gid'], 'name' => $option['name']];
66
                }, $tiny['enum_options']);
67
                if (isset($tiny['enum_value'])) {
68
                    $tiny['enum_value'] = ['gid' => $tiny['enum_value']['gid']];
69
                }
70
            }
71
            $data = $tiny;
72
        }
73
        parent::_setData($data);
74
    }
75
76
    /**
77
     * @param null|string $value
78
     * @return null|string
79
     */
80
    protected function _toEnumOptionGid ($value) {
81
        return $this->getEnumOptionValues()[$value] ?? $value;
82
    }
83
84
    /**
85
     * @return string
86
     */
87
    final public function getCurrentOptionName (): string {
88
        return $this->getEnumOptionNames()[$this->getValue()];
89
    }
90
91
    /**
92
     * @return CustomField
93
     */
94
    public function getCustomField () {
95
        return $this->api->getCustomField($this->getGid());
96
    }
97
98
    /**
99
     * Option names keyed by GID.
100
     *
101
     * @return string[]
102
     */
103
    final public function getEnumOptionNames () {
104
        static $names = []; // shared
105
        $gid = $this->data['gid'];
106
        return $names[$gid] ?? $names[$gid] = array_column($this->data['enum_options'], 'name', 'gid');
107
    }
108
109
    /**
110
     * Option GIDs keyed by name.
111
     *
112
     * @return string[]
113
     */
114
    final public function getEnumOptionValues () {
115
        static $values = []; // shared
116
        $gid = $this->data['gid'];
117
        return $values[$gid] ?? $values[$gid] = array_column($this->data['enum_options'], 'gid', 'name');
118
    }
119
120
    /**
121
     * @return null|number|string
122
     */
123
    final public function getValue () {
124
        $type = $this->data['type'];
125
        if ($type === CustomField::TYPE_ENUM) {
126
            return $this->data['enum_value']['gid'] ?? null;
127
        }
128
        return $this->data["{$type}_value"];
129
    }
130
131
    /**
132
     * @return bool
133
     */
134
    final public function isEnum (): bool {
135
        return $this->getType() === CustomField::TYPE_ENUM;
136
    }
137
138
    /**
139
     * @return bool
140
     */
141
    final public function isNumber (): bool {
142
        return $this->getType() === CustomField::TYPE_NUMBER;
143
    }
144
145
    /**
146
     * @return bool
147
     */
148
    final public function isText (): bool {
149
        return $this->getType() === CustomField::TYPE_TEXT;
150
    }
151
152
    /**
153
     * @param null|number|string $value
154
     * @return $this
155
     */
156
    final public function setValue ($value) {
157
        if ($this->caller instanceof FieldEntries) { // read-only if the entry is in an event change.
158
            $type = $this->data['type'];
159
            $this->diff["{$type}_value"] = true;
160
            $this->caller->__set($this->data['gid'], true);
161
            if ($type === CustomField::TYPE_ENUM) {
162
                $this->data['enum_value']['gid'] = $this->_toEnumOptionGid($value);
163
            }
164
            else {
165
                $this->data["{$type}_value"] = $value;
166
            }
167
        }
168
        return $this;
169
    }
170
171
}