Completed
Branch master (eefb7e)
by De Cramer
02:16 queued 17s
created

AssociativeArray::makeReadOnly()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace oliverde8\AssociativeArraySimplified;
4
5
use oliverde8\AssociativeArraySimplified\Exception\ReadOnlyException;
6
7
/**
8
 * Class AssociativeArray
9
 *
10
 * @author    de Cramer Oliver<[email protected]>
11
 * @copyright 2017 Smile
12
 * @package oliverde8\AssociativeArraySimplified
13
 */
14
class AssociativeArray
15
{
16
    /**
17
     * True associative array storing the data.
18
     *
19
     * @var array
20
     */
21
    protected $data = [];
22
23
    /**
24
     * Separation string for recursive search.
25
     *
26
     * @var
27
     */
28
    protected $separator;
29
30
    /**
31
     * Block this object so that it can't be modified
32
     *
33
     * @var bool
34
     */
35
    protected $readOnly = false;
36
37
    /**
38
     * AssociativeArray constructor.
39
     *
40
     * @param array $data The original array with the data.
41
     * @param string $keySeparator
42
     */
43 14
    function __construct($data = [], $keySeparator = '/')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
44
    {
45 14
        $this->data = $data;
46 14
        $this->separator = $keySeparator;
47 14
    }
48
49
    /**
50
     * Get value from, if is not set then return default value(null)
51
     *
52
     * @param string[]|string $key       Key or path to the value
53
     *                                   (either array or string separated with the separator)
54
     * @param mixed           $default   Default value to return if none was find
55
     *
56
     * @return mixed
57
     */
58 9
    public function get($key, $default = null) {
59 9
        return self::getFromKey($this->data, $key, $default, $this->separator);
60
    }
61
62
    /**
63
     * Check if a value for the key exists.
64
     *
65
     * @param string[]|string $key       Key or path to the value
66
     *                                   (either array or string separated with the separator)
67
     *
68
     * @return mixed
69
     */
70 1
    public function keyExist($key)
71
    {
72 1
        return self::checkKeyExist($this->data, $key, $this->separator);
73
    }
74
75
    /**
76
     * Set data inside
77
     *
78
     * @param string[]|string $key       Key or path to the value to set
79
     *                                   (either array or string separated with the separator)
80
     * @param mixed           $value     Value to put
81
     */
82 4
    public function set($key, $value) {
83 4
        $this->checkReadOnly();
84 3
        self::setFromKey($this->data, $key, $value, $this->separator);
85 3
    }
86
87
    /**
88
     * Empty the data stored.
89
     */
90
    public function clear()
91
    {
92
        $this->checkReadOnly();
93
        $this->data = [];
94
    }
95
96
97
    /**
98
     * Get the array with all the data.
99
     *
100
     * @return array All the data
101
     */
102 3
    public function getArray(){
103 3
        return $this->data;
104
    }
105
106
107
    /**
108
     * Replace the current array entirely.
109
     *
110
     * @param array $data new data
111
     */
112
    public function setData($data) {
113
        $this->checkReadOnly();
114
        $this->data = $data;
115
    }
116
117
    /**
118
     * Makes the data inside read only !!
119
     */
120 1
    public function makeReadOnly() {
121 1
        $this->readOnly = true;
122 1
    }
123
124
    /**
125
     * Checks if the associative array is read only.
126
     *
127
     * @throws ReadOnlyException
128
     */
129 4
    public function checkReadOnly() {
130 4
        if ($this->readOnly) {
131 1
            throw new ReadOnlyException('Trying to edit content in read only AssociativeArray !');
132
        }
133 3
    }
134
135
    /**
136
     * Get value from array, if is not set then return default value(null)
137
     *
138
     * @param array           $data      Array to get data from
139
     * @param string[]|string $key       Key or path to the value
140
     *                                   (either array or string separated with the separator)
141
     * @param mixed           $default   Default value to return if none was find
142
     * @param string          $separator Separator to use
143
     *
144
     * @return mixed
145
     */
146 9
    public static function getFromKey($data, $key, $default = null, $separator = '/')
147
    {
148 9
        if (!is_array($key)) {
149 9
            $key = explode($separator, $key);
150
        }
151 9
        return self::recursiveGetFromKey($data, $key, $default);
152
    }
153
154
    /**
155
     * Private unsecured function for getFromKey
156
     *
157
     * @param $data
158
     * @param $key
159
     * @param $default
160
     *
161
     * @return mixed
162
     */
163 9
    private static function recursiveGetFromKey($data, $key, $default)
164
    {
165 9
        if (empty($key)) {
166 5
            return $data;
167
        } else {
168 9
            $currentKey = array_shift($key);
169 9
            return isset($data[$currentKey]) ? self::recursiveGetFromKey($data[$currentKey], $key, $default) : $default;
170
        }
171
    }
172
173
    /**
174
     * Get value from array, if is not set then return default value(null)
175
     *
176
     * @param array           $data      Array to get data from
177
     * @param string[]|string $key       Key or path to the value
178
     *                                   (either array or string separated with the separator)
179
     * @param string          $separator Separator to use
180
     *
181
     * @return mixed
182
     */
183 1
    public static function checkKeyExist($data, $key, $separator = '/')
184
    {
185 1
        if (!is_array($key)) {
186 1
            $key = explode($separator, $key);
187
        }
188 1
        return self::recursiveKeyExist($data, $key);
189
    }
190
191
    /**
192
     * @param array     $data      Array to get data from
193
     * @param string[]  $key       Key or path to the value
194
     *                             (either array or string separated with the separator)
195
     * @param $data
196
     * @param $key
197
     *
198
     * @return mixed
199
     */
200 1
    private static function recursiveKeyExist($data, $key)
201
    {
202 1
        if (empty($key)) {
203 1
            return true;
204
        } else {
205 1
            $currentKey = array_shift($key);
206 1
            return isset($data[$currentKey]) ? self::recursiveKeyExist($data[$currentKey], $key) : false;
207
        }
208
    }
209
210
    /**
211
     * Set data inside an array
212
     *
213
     * @param array           $data      array to set new value in
214
     * @param string[]|string $key       Key or path to the value to set
215
     *                                   (either array or string separated with the separator)
216
     * @param mixed           $value     Value to put
217
     * @param string          $separator separator to use with the string
218
     */
219 3
    public static function setFromKey(&$data, $key, $value, $separator = '/')
220
    {
221 3
        if (is_string($key)) {
222 3
            $key = explode($separator, $key);
223
        }
224 3
        $data = self::recursiveSetFromKey($data, $key, $value);
225 3
    }
226
227
    /**
228
     * Private unsecured method to set data in array
229
     *
230
     * @param $data
231
     * @param $key
232
     * @param $value
233
     *
234
     * @return array
235
     */
236 3
    private static function recursiveSetFromKey($data, $key, $value)
237
    {
238 3
        if (empty($key)) {
239 3
            return $value;
240
        } else {
241 3
            if (!is_array($data)) {
242
                $data = [];
243
            }
244 3
            $currentKey = array_shift($key);
245
246 3
            if (!isset($data[$currentKey])) {
247 2
                $data[$currentKey] = [];
248
            }
249
250 3
            $data[$currentKey] = self::recursiveSetFromKey($data[$currentKey], $key, $value);
251 3
            return $data;
252
        }
253
    }
254
}