Passed
Push — 9.0-dev ( e3b0ad...6e45f1 )
by Radu
01:42
created

ArrayStorage::clear()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
namespace WebServCo\Framework;
3
4
final class ArrayStorage
5
{
6
    /**
7
     * Parse the setting key to make sure it's a simple string
8
     * or an array.
9
     */
10
    private static function parseSetting($setting)
11
    {
12
        if (is_string($setting) &&
13
        false !== strpos($setting, \WebServCo\Framework\Settings::DIVIDER)) {
14
            return explode(\WebServCo\Framework\Settings::DIVIDER, $setting);
15
        }
16
        return $setting;
17
    }
18
    
19
    /**
20
     * Retrieve a value from a storage array.
21
     *
22
     * @param array $storage
23
     * @param mixed $setting Can be an array, a string,
24
     *                          or a special formatted string
25
     *                          (eg 'app/path/project').
26
     * @param mixed $defaultValue
27
     * @return mixed
28
     */
29
    public static function get($storage, $setting = null, $defaultValue = false)
30
    {
31
        $setting = self::parseSetting($setting);
32
        
33
        if (empty($setting) || empty($storage)) {
34
            return $defaultValue;
35
        }
36
        
37
        /**
38
         * If $setting is an array, process it recursively.
39
         */
40
        if (is_array($setting)) {
41
            /**
42
             * Check if we have the first $setting element in the
43
             * configuration data array.
44
             */
45
            if (array_key_exists(0, $setting) && array_key_exists($setting[0], $storage)) {
46
                /**
47
                 * Remove first element from $setting.
48
                 */
49
                $key = array_shift($setting);
50
                /**
51
                 * At the end of the recursion $setting will be
52
                 * an empty array. In this case we simply return the
53
                 * current configuration data.
54
                 */
55
                if (empty($setting)) {
56
                    return $storage[$key];
57
                }
58
                /**
59
                 * Go down one element in the configuration data
60
                 * and call the method again, with the remainig setting.
61
                 */
62
                return self::get($storage[$key], $setting, $defaultValue);
63
            }
64
            /**
65
             * The requested setting doesn't exist in our
66
             * configuration data array.
67
             */
68
            return $defaultValue;
69
        }
70
        
71
        /**
72
         * If we arrive here, $setting must be a simple string.
73
         */
74
        if (array_key_exists($setting, $storage)) {
75
            return $storage[$setting];
76
        }
77
        
78
        /**
79
         * If we got this far, there is no data to return.
80
         */
81
        return $defaultValue;
82
    }
83
    
84
    /**
85
     * Sets a value in a storage array.
86
     *
87
     * @param array $storage
88
     * @param mixed $setting Can be an array, a string,
89
     *                          or a special formatted string
90
     *                          (eg 'app/path/project').
91
     * @param mixed $value The value to be stored.
92
     *
93
     * @return array The storage array with new data.
94
     * @throws \ErrorException
95
     */
96
    public static function set($storage, $setting, $value)
97
    {
98
        if (!is_array($storage) || empty($setting)) {
99
            throw new \ErrorException('Invalid parameters specified');
100
        }
101
        $setting = self::parseSetting($setting);
102
        if (is_array($setting)) {
103
            $reference = &$storage;
104
            foreach ($setting as $item) {
105
                $reference = &$reference[$item];
106
            }
107
            $reference = $value;
108
            unset($reference);
109
            return $storage;
110
        }
111
        $storage[$setting] = $value;
112
        return $storage;
113
    }
114
    
115
    /**
116
     * Clears a value from a storage array
117
     * @param array $storage
118
     * @param mixed $setting Can be an array, a string,
119
     *                          or a special formatted string
120
     *                          (eg 'app/path/project').
121
     *
122
     * @return array The updates storage array.
123
     */
124
    public static function clear($storage, $setting)
125
    {
126
        return self::set($storage, $setting, null);
127
    }
128
    
129
    /**
130
     * Append data to a storage array.
131
     *
132
     * @param array $storage
133
     * @param mixed $data
134
     * @return array
135
     * @throws \ErrorException
136
     */
137
    public static function append($storage, $data = [])
138
    {
139
        if (!is_array($storage) || !is_array($data)) {
140
            throw new \ErrorException('Invalid parameters specified');
141
        }
142
        foreach ($data as $setting => $value) {
143
            if (array_key_exists($setting, $storage) &&
144
                is_array($storage[$setting]) &&
145
                is_array($value)
146
            ) {
147
                $storage[$setting] = self::append($storage[$setting], $value);
148
            } else {
149
                $storage[$setting] = $value;
150
            }
151
        }
152
        return $storage;
153
    }
154
    
155
    /**
156
     * Removes a setting from a storage array.
157
     *
158
     * @param array $storage
159
     * @param mixed $setting Can be an array, a string,
160
     *                          or a special formatted string
161
     *                          (eg 'app/path/project').
162
     *
163
     * @return array The updated storage array.
164
     * @throws \ErrorException
165
     */
166
    public static function unset($storage, $setting)
167
    {
168
        if (!is_array($storage) || empty($setting)) {
169
            throw new \ErrorException('Invalid parameters specified');
170
        }
171
        
172
        $setting = self::parseSetting($setting);
173
        
174
        if (empty($setting)) {
175
            throw new \ErrorException('Empty setting');
176
        }
177
        
178
        if (is_array($setting)) {
179
            return self::removeByIndex($storage, $setting);
180
        }
181
        if (!array_key_exists($setting, $storage)) {
182
            throw new \ErrorException(
183
                sprintf('"%s" does not exist in storage object', $setting)
184
            );
185
        }
186
        unset($storage[$setting]);
187
        return $storage;
188
    }
189
    
190
    /**
191
     * Remove index from multi-dimensional array.
192
     *
193
     * https://stackoverflow.com/questions/26661828/
194
     *
195
     * @param array $array
196
     *   The array to remove the index from.
197
     * @param array $indices
198
     *   Indexed array containing the indices chain up to the index that should be
199
     *   removed.
200
     * @return array
201
     *   The array with the index removed.
202
     * @throws \ErrorException
203
     *   If the index does not exist within the array.
204
     */
205
    protected static function removeByIndex($array, $indices)
206
    {
207
        if (!is_array($array) || !is_array($indices)) {
0 ignored issues
show
introduced by
The condition ! is_array($array) || ! is_array($indices) can never be true.
Loading history...
208
            throw new \ErrorException('Invalid parameters specified');
209
        }
210
        // Create a reference to the original array.
211
        $a = &$array;
212
        // Count all passed indices, remove one because arrays are zero based.
213
        $c = count($indices) - 1;
214
        // Iterate over all passed indices.
215
        for ($i = 0; $i <= $c; ++$i) {
216
            // Make sure the index to go down for deletion actually exists.
217
            if (!array_key_exists($indices[$i], $a)) {
218
                throw new \ErrorException(
219
                    sprintf('"%s" does not exist in storage object', $indices[$i])
220
                );
221
            }
222
            // This is the target if we reached the last index that was passed.
223
            if ($i === $c) {
224
                unset($a[$indices[$i]]);
225
            } elseif (is_array($a[$indices[$i]])) {
226
                // Make sure we have an array to go further down.
227
                $a = &$a[$indices[$i]];
228
            } else {
229
                throw new \ErrorException(
230
                    sprintf('"%s" does not exist in storage object', $indices[$i])
231
                );
232
            }
233
        }
234
        return $array;
235
    }
236
}
237