Passed
Push — master ( 074997...aebabc )
by Sebastian
03:08
created

ArrayDataCollection::setKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 2
1
<?php
2
/**
3
 * @package Application Utils
4
 * @subpackage Collections
5
 * @see \AppUtils\ArrayDataCollection
6
 */
7
8
declare(strict_types=1);
9
10
namespace AppUtils;
11
12
use AppUtils\ArrayDataCollection\ArrayDataCollectionException;
13
use JsonException;
14
15
/**
16
 * Collection class used to work with associative arrays used to
17
 * store key => value pairs.
18
 *
19
 * Offers strict typed methods to access the available keys, to
20
 * remove the hassle of checking whether keys exist, and whether
21
 * they are of the expected type.
22
 *
23
 * @package Application Utils
24
 * @subpackage Collections
25
 * @author Sebastian Mordziol <[email protected]>
26
 */
27
class ArrayDataCollection
28
{
29
    public const ERROR_JSON_DECODE_FAILED = 116001;
30
31
    /**
32
     * @var array<string,mixed>
33
     */
34
    protected array $data;
35
36
    /**
37
     * @param array<string,mixed> $data
38
     */
39
    public function __construct(array $data=array())
40
    {
41
        $this->data = $data;
42
    }
43
44
    public static function create(array $data=array()) : ArrayDataCollection
45
    {
46
        return new ArrayDataCollection($data);
47
    }
48
49
    /**
50
     * @return array<string,mixed>
51
     */
52
    public function getData() : array
53
    {
54
        return $this->data;
55
    }
56
57
    /**
58
     * @param array<string,mixed> $data
59
     * @return $this
60
     */
61
    public function setKeys(array $data) : self
62
    {
63
        foreach($data as $key => $value)
64
        {
65
            $this->setKey($key, $value);
66
        }
67
68
        return $this;
69
    }
70
71
    /**
72
     * @param string $name
73
     * @param mixed|NULL $value
74
     * @return $this
75
     */
76
    public function setKey(string $name, $value) : self
77
    {
78
        $this->data[$name] = $value;
79
        return $this;
80
    }
81
82
    /**
83
     * Merges the current collection's data with that of
84
     * the target collection, replacing existing values.
85
     *
86
     * @param ArrayDataCollection $collection
87
     * @return $this
88
     */
89
    public function mergeWith(ArrayDataCollection $collection) : self
90
    {
91
        return $this->setKeys($collection->getData());
92
    }
93
94
    /**
95
     * Combines the current collection's data with the
96
     * target collection, and returns a new collection
97
     * that contains the data of both collections.
98
     *
99
     * NOTE: The source collection's values are overwritten
100
     * by the target collection in the process.
101
     *
102
     * @param ArrayDataCollection $collection
103
     * @return ArrayDataCollection
104
     */
105
    public function combine(ArrayDataCollection $collection) : ArrayDataCollection
106
    {
107
        return self::create($this->data)->setKeys($collection->getData());
108
    }
109
110
    /**
111
     * @param string $name
112
     * @return mixed|null
113
     */
114
    public function getKey(string $name)
115
    {
116
        return $this->data[$name] ?? null;
117
    }
118
119
    /**
120
     * The stored value can be a string or a number.
121
     * All other types and values will return an empty
122
     * string.
123
     *
124
     * @param string $name
125
     * @return string
126
     */
127
    public function getString(string $name) : string
128
    {
129
        $value = $this->getKey($name);
130
131
        if(is_string($value)) {
132
            return $value;
133
        }
134
135
        if(is_numeric($value)) {
136
            return (string)$value;
137
        }
138
139
        return '';
140
    }
141
142
    /**
143
     * The stored value can be an integer or float,
144
     * or a string containing an integer or float.
145
     * All other types and values return <code>0</code>.
146
     *
147
     * @param string $name
148
     * @return int
149
     */
150
    public function getInt(string $name) : int
151
    {
152
        $value = $this->getKey($name);
153
154
        if(is_numeric($value)) {
155
            return (int)$value;
156
        }
157
158
        return 0;
159
    }
160
161
    /**
162
     * Attempts to decode the stored string as JSON.
163
     *
164
     * NOTE: Only JSON that decodes into an array is
165
     * accepted. Other values, like booleans or numbers,
166
     * will return an empty array.
167
     *
168
     * @param string $name
169
     * @return array<mixed>
170
     * @throws ArrayDataCollectionException
171
     */
172
    public function getJSONArray(string $name) : array
173
    {
174
        $value = $this->getString($name);
175
176
        if(empty($value)) {
177
            return array();
178
        }
179
180
        try
181
        {
182
            $value = json_decode($value, true, 512, JSON_THROW_ON_ERROR);
183
184
            if(is_array($value)) {
185
                return $value;
186
            }
187
188
            return array();
189
        }
190
        catch (JsonException $e)
191
        {
192
            throw new ArrayDataCollectionException(
193
                'Invalid JSON encountered in array data collection.',
194
                sprintf(
195
                    'The JSON string could not be decoded.'.PHP_EOL.
196
                    'Reason: %s'.PHP_EOL.
197
                    'Raw JSON given:'.PHP_EOL.
198
                    '---------------------------------------'.PHP_EOL.
199
                    '%s'.PHP_EOL.
200
                    '---------------------------------------'.PHP_EOL,
201
                    $e->getMessage(),
202
                    ConvertHelper::text_cut($value, 500)
203
                ),
204
                self::ERROR_JSON_DECODE_FAILED,
205
                $e
206
            );
207
        }
208
    }
209
210
    public function getArray(string $name) : array
211
    {
212
        $value = $this->getKey($name);
213
214
        if(is_array($value)) {
215
            return $value;
216
        }
217
218
        return array();
219
    }
220
221
    public function getBool(string $name) : bool
222
    {
223
        $value = $this->getKey($name);
224
225
        if(is_string($value)) {
226
            $value = strtolower($value);
227
        }
228
229
        return
230
            $value === true
231
            ||
232
            $value === 'true'
233
            ||
234
            $value === 'yes'
235
            ||
236
            $value === 1;
237
    }
238
239
    public function getFloat(string $name) : float
240
    {
241
        $value = $this->getKey($name);
242
243
        if(is_numeric($value)) {
244
            return (float)$value;
245
        }
246
247
        return 0.0;
248
    }
249
}
250