Completed
Push — master ( bddf64...3d2dea )
by Basil
04:40
created

ArrayHelper::coverSensitiveValues()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 8.2222
c 0
b 0
f 0
cc 7
eloc 11
nc 5
nop 2
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
     * Create an object from an array.
27
     *
28
     * @param array $array
29
     * @return object
30
     */
31
    public static function toObject(array $array)
32
    {
33
        return json_decode(json_encode($array), false);
34
    }
35
36
    /**
37
     * Cover senstive values from a given list of keys.
38
     *
39
     * The main purpose is to remove passwords transferd to api when existing in post, get or session.
40
     * 
41
     * Example:
42
     * 
43
     * ```php
44
     * $data = ArrayHelper::coverSensitiveValues(['username' => 'foo', 'password' => 'bar'], ['password']];
45
     * 
46
     * var_dump($data); // array('username' => 'foo', 'password' => '***');
47
     * ```
48
     *
49
     * @param array $data The input data to cover given sensitive key values. `['username' => 'foo', 'password' => 'bar']`.
50
     * @param array $key The keys which can contain sensitive data inside the $data array. `['password', 'pwd', 'pass']`.
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...
51
     * @since 1.0.6
52
     */
53
    public static function coverSensitiveValues(array $data, array $keys)
54
    {
55
        $clean = [];
56
        foreach ($keys as $key) {
57
            $kw = strtolower($key);
58
            foreach ($data as $k => $v) {
59
                if (is_array($v)) {
60
                    $clean[$k] = static::coverSensitiveValues($v, $keys);
61
                } elseif (is_scalar($v) && ($kw == strtolower($k) || StringHelper::startsWith(strtolower($k), $kw))) {
62
                    $v = str_repeat("*", strlen($v));
63
                    $clean[$k] = $v;
64
                }
65
            }
66
        }
67
        
68
        // the later overrides the former
69
        return array_replace($data, $clean);
70
    }
71
    
72
    /**
73
     * Prepend an assoc array item as first entry for a given array.
74
     *
75
     * @param array $arr The array where the value should be prepend
76
     * @param string $key The new array key
77
     * @param mixed $val The value for the new key
78
     * @return array
79
     */
80
    public static function arrayUnshiftAssoc(&$arr, $key, $val)
81
    {
82
        $arr = array_reverse($arr, true);
83
        $arr[$key] = $val;
84
        return array_reverse($arr, true);
85
    }
86
    
87
    /**
88
     * TypeCast values from a mixed array source. numeric values will be casted as integer.
89
     *
90
     * This method is often used to convert corect json respons arrays
91
     *
92
     * @param array $array The array which should be type casted
93
     * @return array An array with type casted values
94
     */
95
    public static function typeCast(array $array)
96
    {
97
        $return = [];
98
        
99
        foreach ($array as $k => $v) {
100
            if (is_numeric($v)) {
101
                $return[$k] = StringHelper::typeCastNumeric($v);
102
            } elseif (is_array($v)) {
103
                $return[$k] = self::typeCast($v);
104
            } else {
105
                $return[$k] = $v;
106
            }
107
        }
108
        
109
        return $return;
110
    }
111
    
112
    /**
113
     * Search trough all keys inside of an array, any occurence will return the rest of the array.
114
     *
115
     * ```php
116
     * $data  = [
117
     *     ['name' => 'Foo Bar', 'id' => 1],
118
     *     ['name' => 'Bar Baz', 'id' => 2],
119
     * ];
120
     * ```
121
     *
122
     * Assuming the above array parameter searching for `1` would return:
123
     *
124
     * ```php
125
     * $data  = [
126
     *     ['name' => 'Foo Bar', 'id' => 1],
127
     * ];
128
     * ```
129
     *
130
     * Searching for the string `Bar` would return the the orignal array is bar would be found in both.
131
     *
132
     * @param array $array The multidimensional array keys.
133
     * @param string $searchText The text you where search inside the rows.
134
     * @param boolean $sensitive Whether to use strict sensitive search (true) or case insenstivie search (false).
135
     * @return array The modified array depending on the search result hits.
136
     */
137
    public static function search(array $array, $searchText, $sensitive = false)
138
    {
139
        $function = ($sensitive) ? 'strpos' : 'stripos';
140
        return array_filter($array, function ($item) use ($searchText, $function) {
141
            $response = false;
142
            foreach ($item as $key => $value) {
143
                if ($response) {
144
                    continue;
145
                }
146
                if ($function($value, "$searchText") !== false) {
147
                    $response = true;
148
                }
149
            }
150
            return $response;
151
        });
152
    }
153
    
154
    /**
155
     * Search for a Column Value inside a Multidimension array and return the array with the found key.
156
     *
157
     * Compare to searchColumns() this function return will return the first found result.
158
     *
159
     * ```php
160
     * $array = [
161
     *     ['name' => 'luya', 'userId' => 1],
162
     *     ['name' => 'nadar', 'userId' => 2],
163
     * ];
164
     *
165
     * $result = ArrayHelper::searchColumn($array, 'name', 'nadar');
166
     *
167
     * // output:
168
     * // array ('name' => 'nadar', 'userId' => 2);
169
     * ```
170
     *
171
     * > This will not work with assoc keys
172
     *
173
     * @param array $array The array with the multimensional array values.
174
     * @param string $column The column to lookup and compare with the $search string.
175
     * @param string $search The string to search inside the provided column.
176
     * @return array|boolean
177
     */
178
    public static function searchColumn(array $array, $column, $search)
179
    {
180
        $columns = array_column($array, $column);
181
        $key = array_search($search, $columns);
182
        return ($key !== false) ?  $array[$key] : false;
183
    }
184
    
185
    /**
186
     * Search for columns with the given search value, returns the full array with all valid items.
187
     *
188
     * Compare to searchColumn() this function return will return all found results.
189
     *
190
     * > This function is not casesensitive, which means FOO will match Foo, foo and FOO
191
     *
192
     * ```php
193
     * $array = [
194
     *     ['name' => 'luya', 'userId' => 1],
195
     *     ['name' => 'nadar', 'userId' => 1],
196
     * ];
197
     *
198
     * $result = ArrayHelper::searchColumns($array, 'userId', '1');
199
     *
200
     * // output:
201
     * // array (
202
     * //     array ('name' => 'luya', 'userId' => 1),
203
     * //     array ('name' => 'nadar', 'userId' => 1)
204
     * // );
205
     * ```
206
     *
207
     * @param array $array The multidimensional array input
208
     * @param string $column The column to compare with $search string
209
     * @param mixed $search The search string to compare with the column value.
210
     * @return array Returns an array with all valid elements.
211
     */
212
    public static function searchColumns(array $array, $column, $search)
213
    {
214
        $keys = array_filter($array, function ($var) use ($column, $search) {
215
            return strcasecmp($search, $var[$column]) == 0 ? true : false;
216
        });
217
        
218
        return $keys;
219
    }
220
    
221
    /**
222
     * Generate an Array from a Rang with an appending optional Text.
223
     *
224
     * This is commonly used when generate dropDowns in forms to select a number of something.
225
     *
226
     * When $text is an array, the first key is the singular value to use, the second is the pluralized value.
227
     *
228
     * ```php
229
     * $range = ArrayHelper::generateRange(1, 3, 'ticket');
230
     * // array (1 => "1 ticket", 2 => "2 ticket", 3 => "3 ticket")
231
     * ```
232
     *
233
     * Using the pluralized texts:
234
     *
235
     * ```php
236
     * $range = ArrayHelper::generateRange(1, 3, ['ticket', 'tickets']);
237
     * // array (1 => "1 ticket", 2 => "2 tickets", 3 => "3 tickets")
238
     * ```
239
     *
240
     * In php range() function is used to generate the array range.
241
     *
242
     * @param string|integer $from The range starts from
243
     * @param string|integer $to The range ends
244
     * @param string|array $text Optinal text to append to each element. If an array is given the first value is used
245
     * for the singular value, the second will be used for the pluralized values.
246
     * @return array An array where the key is the number and value the number with optional text.
247
     */
248
    public static function generateRange($from, $to, $text = null)
249
    {
250
        $range = range($from, $to);
251
        $array = array_combine($range, $range);
252
        
253
        if ($text) {
254
            array_walk($array, function (&$item, $key) use ($text) {
255
                if (is_array($text)) {
256
                    list($singular, $plural) = $text;
257
                    if ($key == 1) {
258
                        $item = "{$key} {$singular}";
259
                    } else {
260
                        $item = "{$key} {$plural}";
261
                    }
262
                } else {
263
                    $item = "{$key} {$text}";
264
                }
265
            });
266
        }
267
        
268
        return $array;
269
    }
270
}
271