Completed
Push — master ( b4d6a5...352f6d )
by Basil
02:42
created

ArrayHelper::arrayUnshiftAssoc()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
3
namespace luya\helpers;
4
5
use yii\helpers\BaseArrayHelper;
6
7
/**
8
 * Helper methods when dealing with Arrays.
9
 *
10
 * Extends the {{yii\helpers\ArrayHelper}} class by some usefull functions like:
11
 *
12
 * + {{luya\helpers\ArrayHelper::toObject()}}
13
 * + {{luya\helpers\ArrayHelper::arrayUnshiftAssoc()}}
14
 * + {{luya\helpers\ArrayHelper::typeCast()}}
15
 * + {{luya\helpers\ArrayHelper::search()}}
16
 * + {{luya\helpers\ArrayHelper::searchColumn()}}
17
 * + {{luya\helpers\ArrayHelper::searchColumns()}}
18
 * + {{luya\helpers\ArrayHelper::generateRange()}}
19
 *
20
 * @author Basil Suter <[email protected]>
21
 * @since 1.0.0
22
 */
23
class ArrayHelper extends BaseArrayHelper
24
{
25
    /**
26
     * @var array An array with sensitive keys which are used if no keys will be passed to {{luya\helpers\ArrayHelper::coverSensitiveValues()}}.
27
     * @since 1.0.10
28
     */
29
    public static $sensitiveDefaultKeys = ['password', 'pwd', 'pass', 'passwort', 'pw', 'token', 'hash', 'authorization', 'auth'];
30
    
31
    /**
32
     * Create an object from an array.
33
     *
34
     * @param array $array
35
     * @return object
36
     */
37
    public static function toObject(array $array)
38
    {
39
        return json_decode(json_encode($array), false);
40
    }
41
42
    /**
43
     * Cover senstive values from a given list of keys.
44
     *
45
     * The main purpose is to remove passwords transferd to api when existing in post, get or session.
46
     *
47
     * Example:
48
     *
49
     * ```php
50
     * $data = ArrayHelper::coverSensitiveValues(['username' => 'foo', 'password' => 'bar'], ['password']];
51
     *
52
     * var_dump($data); // array('username' => 'foo', 'password' => '***');
53
     * ```
54
     *
55
     * @param array $data The input data to cover given sensitive key values. `['username' => 'foo', 'password' => 'bar']`.
56
     * @param array $key The keys which can contain sensitive data inside the $data array. `['password', 'pwd', 'pass']` if no keys provided the {{luya\helpers\ArrayHelper::$sensitiveDefaultKeys}} is used.
0 ignored issues
show
Bug introduced by
There is no parameter named $key. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
57
     * @since 1.0.6
58
     */
59
    public static function coverSensitiveValues(array $data, array $keys = [])
60
    {
61
        if (empty($keys)) {
62
            $keys = self::$sensitiveDefaultKeys;
63
        }
64
        
65
        $clean = [];
66
        foreach ($keys as $key) {
67
            $kw = strtolower($key);
68
            foreach ($data as $k => $v) {
69
                if (is_array($v)) {
70
                    $clean[$k] = static::coverSensitiveValues($v, $keys);
71
                } elseif (is_scalar($v) && ($kw == strtolower($k) || StringHelper::startsWith(strtolower($k), $kw))) {
72
                    $v = str_repeat("*", strlen($v));
73
                    $clean[$k] = $v;
74
                }
75
            }
76
        }
77
        
78
        // the later overrides the former
79
        return array_replace($data, $clean);
80
    }
81
    
82
    /**
83
     * Prepend an assoc array item as first entry for a given array.
84
     *
85
     * Adds the given key with value as first entry to $arr
86
     *
87
     * @param array $arr The array where the value should be prepend
88
     * @param string $key The new array key
89
     * @param mixed $val The value for the new key
90
     * @return array
91
     */
92
    public static function arrayUnshiftAssoc(&$arr, $key, $val)
93
    {
94
        $arr = array_reverse($arr, true);
95
        $arr[$key] = $val;
96
        return array_reverse($arr, true);
97
    }
98
    
99
    /**
100
     * TypeCast values from a mixed array source. numeric values will be casted as integer.
101
     *
102
     * This method is often used to convert corect json respons arrays
103
     *
104
     * @param array $array The array which should be type casted
105
     * @return array An array with type casted values
106
     */
107
    public static function typeCast(array $array)
108
    {
109
        $return = [];
110
        
111
        foreach ($array as $k => $v) {
112
            if (is_numeric($v)) {
113
                $return[$k] = StringHelper::typeCastNumeric($v);
114
            } elseif (is_array($v)) {
115
                $return[$k] = self::typeCast($v);
116
            } else {
117
                $return[$k] = $v;
118
            }
119
        }
120
        
121
        return $return;
122
    }
123
    
124
    /**
125
     * Search trough all keys inside of an array, any occurence will return the rest of the array.
126
     *
127
     * ```php
128
     * $data  = [
129
     *     ['name' => 'Foo Bar', 'id' => 1],
130
     *     ['name' => 'Bar Baz', 'id' => 2],
131
     * ];
132
     * ```
133
     *
134
     * Assuming the above array the expression `ArrayHelper::search($data, 1)` would return:
135
     *
136
     * ```php
137
     * $data  = [
138
     *     ['name' => 'Foo Bar', 'id' => 1],
139
     * ];
140
     * ```
141
     *
142
     * Searching for the string `Bar` would return the the orignal array is bar would be found in both.
143
     *
144
     * In order to search only in certain keys defined $keys attribute:
145
     *
146
     * ```php
147
     * ArrayHelper::search($data, 'Foo', false, ['name']);
148
     * ```
149
     *
150
     * The above example will search only in the array key `name` for the `Foo` expression.
151
     *
152
     * @param array $array The multidimensional array keys.
153
     * @param string $searchText The text you where search inside the rows.
154
     * @param boolean $sensitive Whether to use strict sensitive search (true) or case insenstivie search (false).
155
     * @param array $keys A list of array keys which should be taken to search in, if empty or not provided it will lookup all array keys by default. {@since 1.0.24}
156
     * @return array The modified array depending on the search result hits.
157
     */
158
    public static function search(array $array, $searchText, $sensitive = false, array $keys = [])
159
    {
160
        $function = $sensitive ? 'strpos' : 'stripos';
161
        return array_filter($array, function ($item) use ($searchText, $function, $keys) {
162
            $response = false;
163
            foreach ($item as $key => $value) {
164
                if ($response) {
165
                    continue;
166
                }
167
168
                if (!empty($keys) && !in_array($key, $keys)) {
169
                    continue;
170
                }
171
                
172
                if ($function($value, "$searchText") !== false) {
173
                    $response = true;
174
                }
175
            }
176
            return $response;
177
        });
178
    }
179
    
180
    /**
181
     * Search for a Column Value inside a Multidimension array and return the array with the found key.
182
     *
183
     * Compare to searchColumns() this function return will return the first found result.
184
     *
185
     * ```php
186
     * $array = [
187
     *     ['name' => 'luya', 'userId' => 1],
188
     *     ['name' => 'nadar', 'userId' => 2],
189
     * ];
190
     *
191
     * $result = ArrayHelper::searchColumn($array, 'name', 'nadar');
192
     *
193
     * // output:
194
     * // array ('name' => 'nadar', 'userId' => 2);
195
     * ```
196
     *
197
     * > This will not work with assoc keys
198
     *
199
     * @param array $array The array with the multimensional array values.
200
     * @param string $column The column to lookup and compare with the $search string.
201
     * @param string $search The string to search inside the provided column.
202
     * @return array|boolean
203
     */
204
    public static function searchColumn(array $array, $column, $search)
205
    {
206
        $array = array_values($array); // align array keys
207
        $columns = array_column($array, $column);
208
        $key = array_search($search, $columns);
209
        return ($key !== false) ?  $array[$key] : false;
210
    }
211
    
212
    /**
213
     * Search for columns with the given search value, returns the full array with all valid items.
214
     *
215
     * Compare to searchColumn() this function return will return all found results.
216
     *
217
     * > This function is not casesensitive, which means FOO will match Foo, foo and FOO
218
     *
219
     * ```php
220
     * $array = [
221
     *     ['name' => 'luya', 'userId' => 1],
222
     *     ['name' => 'nadar', 'userId' => 1],
223
     * ];
224
     *
225
     * $result = ArrayHelper::searchColumns($array, 'userId', '1');
226
     *
227
     * // output:
228
     * // array (
229
     * //     array ('name' => 'luya', 'userId' => 1),
230
     * //     array ('name' => 'nadar', 'userId' => 1)
231
     * // );
232
     * ```
233
     *
234
     * @param array $array The multidimensional array input
235
     * @param string $column The column to compare with $search string
236
     * @param mixed $search The search string to compare with the column value.
237
     * @return array Returns an array with all valid elements.
238
     */
239
    public static function searchColumns(array $array, $column, $search)
240
    {
241
        $keys = array_filter($array, function ($var) use ($column, $search) {
242
            return strcasecmp($search, $var[$column]) == 0 ? true : false;
243
        });
244
        
245
        return $keys;
246
    }
247
    
248
    /**
249
     * Generate an Array from a Rang with an appending optional Text.
250
     *
251
     * This is commonly used when generate dropDowns in forms to select a number of something.
252
     *
253
     * When $text is an array, the first key is the singular value to use, the second is the pluralized value.
254
     *
255
     * ```php
256
     * $range = ArrayHelper::generateRange(1, 3, 'ticket');
257
     * // array (1 => "1 ticket", 2 => "2 ticket", 3 => "3 ticket")
258
     * ```
259
     *
260
     * Using the pluralized texts:
261
     *
262
     * ```php
263
     * $range = ArrayHelper::generateRange(1, 3, ['ticket', 'tickets']);
264
     * // array (1 => "1 ticket", 2 => "2 tickets", 3 => "3 tickets")
265
     * ```
266
     *
267
     * In php range() function is used to generate the array range.
268
     *
269
     * @param string|integer $from The range starts from
270
     * @param string|integer $to The range ends
271
     * @param string|array $text Optinal text to append to each element. If an array is given the first value is used
272
     * for the singular value, the second will be used for the pluralized values.
273
     * @return array An array where the key is the number and value the number with optional text.
274
     */
275
    public static function generateRange($from, $to, $text = null)
276
    {
277
        $range = range($from, $to);
278
        $array = array_combine($range, $range);
279
        
280
        if ($text) {
281
            array_walk($array, function (&$item, $key) use ($text) {
282
                if (is_array($text)) {
283
                    list($singular, $plural) = $text;
284
                    if ($key == 1) {
285
                        $item = "{$key} {$singular}";
286
                    } else {
287
                        $item = "{$key} {$plural}";
288
                    }
289
                } else {
290
                    $item = "{$key} {$text}";
291
                }
292
            });
293
        }
294
        
295
        return $array;
296
    }
297
298
    /**
299
     * Helper method to generate an array with the same keys and values.
300
     *
301
     * ```php
302
     * $data = ArrayHelper::combine(['foo', 'bar']);
303
     *
304
     * // generates
305
     * ['foo' => 'foo', 'bar' => 'bar'];
306
     * ```
307
     *
308
     * @param array $array The array to combine.
309
     * @return array
310
     * @since 1.0.24
311
     */
312
    public static function combine(array $array)
313
    {
314
        return array_combine($array, $array);
315
    }
316
}
317