Completed
Push — master ( 53b99e...05e097 )
by Basil
03:48
created

ArrayHelper::search()   A

Complexity

Conditions 5
Paths 2

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.4222
c 0
b 0
f 0
cc 5
nc 2
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
     * @param array $arr The array where the value should be prepend
86
     * @param string $key The new array key
87
     * @param mixed $val The value for the new key
88
     * @return array
89
     */
90
    public static function arrayUnshiftAssoc(&$arr, $key, $val)
91
    {
92
        $arr = array_reverse($arr, true);
93
        $arr[$key] = $val;
94
        return array_reverse($arr, true);
95
    }
96
    
97
    /**
98
     * TypeCast values from a mixed array source. numeric values will be casted as integer.
99
     *
100
     * This method is often used to convert corect json respons arrays
101
     *
102
     * @param array $array The array which should be type casted
103
     * @return array An array with type casted values
104
     */
105
    public static function typeCast(array $array)
106
    {
107
        $return = [];
108
        
109
        foreach ($array as $k => $v) {
110
            if (is_numeric($v)) {
111
                $return[$k] = StringHelper::typeCastNumeric($v);
112
            } elseif (is_array($v)) {
113
                $return[$k] = self::typeCast($v);
114
            } else {
115
                $return[$k] = $v;
116
            }
117
        }
118
        
119
        return $return;
120
    }
121
    
122
    /**
123
     * Search trough all keys inside of an array, any occurence will return the rest of the array.
124
     *
125
     * ```php
126
     * $data  = [
127
     *     ['name' => 'Foo Bar', 'id' => 1],
128
     *     ['name' => 'Bar Baz', 'id' => 2],
129
     * ];
130
     * ```
131
     *
132
     * Assuming the above array parameter searching for `1` would return:
133
     *
134
     * ```php
135
     * $data  = [
136
     *     ['name' => 'Foo Bar', 'id' => 1],
137
     * ];
138
     * ```
139
     *
140
     * Searching for the string `Bar` would return the the orignal array is bar would be found in both.
141
     *
142
     * @param array $array The multidimensional array keys.
143
     * @param string $searchText The text you where search inside the rows.
144
     * @param boolean $sensitive Whether to use strict sensitive search (true) or case insenstivie search (false).
145
     * @return array The modified array depending on the search result hits.
146
     */
147
    public static function search(array $array, $searchText, $sensitive = false)
148
    {
149
        $function = ($sensitive) ? 'strpos' : 'stripos';
150
        return array_filter($array, function ($item) use ($searchText, $function) {
151
            $response = false;
152
            foreach ($item as $key => $value) {
153
                if ($response) {
154
                    continue;
155
                }
156
                if ($function($value, "$searchText") !== false) {
157
                    $response = true;
158
                }
159
            }
160
            return $response;
161
        });
162
    }
163
    
164
    /**
165
     * Search for a Column Value inside a Multidimension array and return the array with the found key.
166
     *
167
     * Compare to searchColumns() this function return will return the first found result.
168
     *
169
     * ```php
170
     * $array = [
171
     *     ['name' => 'luya', 'userId' => 1],
172
     *     ['name' => 'nadar', 'userId' => 2],
173
     * ];
174
     *
175
     * $result = ArrayHelper::searchColumn($array, 'name', 'nadar');
176
     *
177
     * // output:
178
     * // array ('name' => 'nadar', 'userId' => 2);
179
     * ```
180
     *
181
     * > This will not work with assoc keys
182
     *
183
     * @param array $array The array with the multimensional array values.
184
     * @param string $column The column to lookup and compare with the $search string.
185
     * @param string $search The string to search inside the provided column.
186
     * @return array|boolean
187
     */
188
    public static function searchColumn(array $array, $column, $search)
189
    {
190
        $columns = array_column($array, $column);
191
        $key = array_search($search, $columns);
192
        return ($key !== false) ?  $array[$key] : false;
193
    }
194
    
195
    /**
196
     * Search for columns with the given search value, returns the full array with all valid items.
197
     *
198
     * Compare to searchColumn() this function return will return all found results.
199
     *
200
     * > This function is not casesensitive, which means FOO will match Foo, foo and FOO
201
     *
202
     * ```php
203
     * $array = [
204
     *     ['name' => 'luya', 'userId' => 1],
205
     *     ['name' => 'nadar', 'userId' => 1],
206
     * ];
207
     *
208
     * $result = ArrayHelper::searchColumns($array, 'userId', '1');
209
     *
210
     * // output:
211
     * // array (
212
     * //     array ('name' => 'luya', 'userId' => 1),
213
     * //     array ('name' => 'nadar', 'userId' => 1)
214
     * // );
215
     * ```
216
     *
217
     * @param array $array The multidimensional array input
218
     * @param string $column The column to compare with $search string
219
     * @param mixed $search The search string to compare with the column value.
220
     * @return array Returns an array with all valid elements.
221
     */
222
    public static function searchColumns(array $array, $column, $search)
223
    {
224
        $keys = array_filter($array, function ($var) use ($column, $search) {
225
            return strcasecmp($search, $var[$column]) == 0 ? true : false;
226
        });
227
        
228
        return $keys;
229
    }
230
    
231
    /**
232
     * Generate an Array from a Rang with an appending optional Text.
233
     *
234
     * This is commonly used when generate dropDowns in forms to select a number of something.
235
     *
236
     * When $text is an array, the first key is the singular value to use, the second is the pluralized value.
237
     *
238
     * ```php
239
     * $range = ArrayHelper::generateRange(1, 3, 'ticket');
240
     * // array (1 => "1 ticket", 2 => "2 ticket", 3 => "3 ticket")
241
     * ```
242
     *
243
     * Using the pluralized texts:
244
     *
245
     * ```php
246
     * $range = ArrayHelper::generateRange(1, 3, ['ticket', 'tickets']);
247
     * // array (1 => "1 ticket", 2 => "2 tickets", 3 => "3 tickets")
248
     * ```
249
     *
250
     * In php range() function is used to generate the array range.
251
     *
252
     * @param string|integer $from The range starts from
253
     * @param string|integer $to The range ends
254
     * @param string|array $text Optinal text to append to each element. If an array is given the first value is used
255
     * for the singular value, the second will be used for the pluralized values.
256
     * @return array An array where the key is the number and value the number with optional text.
257
     */
258
    public static function generateRange($from, $to, $text = null)
259
    {
260
        $range = range($from, $to);
261
        $array = array_combine($range, $range);
262
        
263
        if ($text) {
264
            array_walk($array, function (&$item, $key) use ($text) {
265
                if (is_array($text)) {
266
                    list($singular, $plural) = $text;
267
                    if ($key == 1) {
268
                        $item = "{$key} {$singular}";
269
                    } else {
270
                        $item = "{$key} {$plural}";
271
                    }
272
                } else {
273
                    $item = "{$key} {$text}";
274
                }
275
            });
276
        }
277
        
278
        return $array;
279
    }
280
}
281