Passed
Push — master ( 2bade0...67af33 )
by Radu
02:03
created

ArrayStorage::get()   B

Complexity

Conditions 8
Paths 6

Size

Total Lines 53
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 13
nc 6
nop 3
dl 0
loc 53
rs 7.1199
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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