Passed
Pull Request — master (#64)
by
unknown
03:08
created

Mappings::select()   B

Complexity

Conditions 8
Paths 1

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 8

Importance

Changes 0
Metric Value
cc 8
nc 1
nop 4
dl 0
loc 31
rs 8.1795
c 0
b 0
f 0
ccs 19
cts 19
cp 1
crap 8
1
<?php
2
/**
3
 * @copyright Zicht Online <http://zicht.nl>
4
 */
5
6
namespace Zicht\Itertools\util;
7
8
class Mappings
9
{
10
    /**
11
     * Returns a closure that strips any matching $chars from the left of the input string
12
     *
13
     * @param string $chars
14
     * @return \Closure
15
     */
16 5
    public static function lstrip($chars = " \t\n\r\0\x0B")
17
    {
18
        return function ($value) use ($chars) {
19 5
            return ltrim($value, $chars);
20 5
        };
21
    }
22
23
    /**
24
     * Returns a closure that strips any matching $chars from the right of the input string
25
     *
26
     * @param string $chars
27
     * @return \Closure
28
     */
29 5
    public static function rstrip($chars = " \t\n\r\0\x0B")
30
    {
31
        return function ($value) use ($chars) {
32 5
            return rtrim($value, $chars);
33 5
        };
34
    }
35
36
    /**
37
     * Returns a closure that strips any matching $chars from the left and right of the input string
38
     *
39
     * @param string $chars
40
     * @return \Closure
41
     */
42 6
    public static function strip($chars = " \t\n\r\0\x0B")
43
    {
44
        return function ($value) use ($chars) {
45 5
            return trim($value, $chars);
46 6
        };
47
    }
48
49
    /**
50
     * Returns a closure that returns the length of the input
51
     *
52
     * @return \Closure
53
     */
54 3
    public static function length()
55
    {
56
        return function ($value) {
57 3
            if (is_null($value)) {
58 3
                return 0;
59
            }
60 3
            if (is_string($value)) {
61 3
                return strlen($value);
62
            }
63 3
            return sizeof($value);
64 3
        };
65
    }
66
67
    /**
68
     * Returns a closure that returns the key
69
     *
70
     * @return \Closure
71
     */
72 5
    public static function key()
73
    {
74
        return function ($value, $key) {
75 5
            return $key;
76 5
        };
77
    }
78
79
    /**
80
     * Returns a closure that returns the string value lower cased
81
     *
82
     * @return \Closure
83
     */
84 1
    public static function lower()
85
    {
86
        return function ($value) {
87 1
            return strtolower($value);
88 1
        };
89
    }
90
91
    /**
92
     * Returns a closure that returns the string value upper cased
93
     *
94
     * @return \Closure
95
     */
96 1
    public static function upper()
97
    {
98
        return function ($value) {
99 1
            return strtoupper($value);
100 1
        };
101
    }
102
103
    /**
104
     * Returns a closure that returns the value cast to a string
105
     *
106
     * @return \Closure
107
     */
108 1
    public static function string()
109
    {
110
        return function ($value) {
111 1
            return (string)$value;
112 1
        };
113
    }
114
115
    /**
116
     * Returns a closure that returns the value as a json_encoded string
117
     *
118
     * @param int $options
119
     * @param int $depth
120
     * @return \Closure
121
     */
122 1
    public static function jsonEncode($options = 0, $depth = 512)
123
    {
124
        return function ($value) use ($options, $depth) {
125 1
            return \json_encode($value, $options, $depth);
126 1
        };
127
    }
128
129
    /**
130
     * Returns a closure that returns the json_encoded value as decoded value
131
     *
132
     * @param boolean $assoc
0 ignored issues
show
Bug introduced by
There is no parameter named $assoc. 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...
133
     * @param int $options
134
     * @param int $depth
135
     * @return \Closure
136
     */
137 1
    public static function jsonDecode($associative = false, $options = 0, $depth = 512)
138
    {
139
        return function ($value) use ($associative, $options, $depth) {
140 1
            return \json_decode($value, $associative, $depth, $options);
141 1
        };
142
    }
143
144
    /**
145
     * Returns a closure that applies multiple mappings to the value and returns the results
146
     *
147
     * > $compute = function ($value, $key) {
148
     * >    return 'some computation result';
149
     * > };
150
     * > $list = iterable([new Data(1), new Data(2), new Data(3)]);
151
     * > $list->map(Mappings::select(['data' => null, 'id' => 'Identifier', 'desc' => 'Value.DescriptionName', 'comp' => $compute]));
152
     * [
153
     *    [
154
     *       'data' => Data(1),
155
     *       'id' => Data(1)->Identifier,
156
     *       'desc' => Data(1)->Value->DescriptionName,
157
     *       'comp' => $compute(Data(1), 0),
158
     *    ],
159
     *    ...
160
     *    [
161
     *       'data' => Data(3),
162
     *       'id' => Data(3)->Identifier,
163
     *       'desc' => Data(3)->Value->DescriptionName,
164
     *       'comp' => $compute(Data(3), 2),
165
     *    ],
166
     * ]
167
     *
168
     * @param array|object $mappings
169
     * @param null|string|\Closure $strategy
170
     * @param boolean $discardNull
171
     * @param boolean $discardEmptyContainer
172
     * @return \Closure
173
     */
174 9
    public static function select($mappings, $strategy = null, $discardNull = false, $discardEmptyContainer = false)
175
    {
176 9
        $castToObject = is_object($mappings);
177 9
        $mappings = array_map('\Zicht\Itertools\util\Conversions::mixedToValueGetter', (array)$mappings);
178 9
        $strategy = Conversions::mixedToValueGetter($strategy);
179
180
        return function ($value, $key) use ($mappings, $strategy, $discardNull, $discardEmptyContainer, $castToObject) {
181 9
            $value = $strategy($value);
182 9
            $res = [];
183 9
            foreach ($mappings as $strategyKey => $strategy) {
184 7
                $res[$strategyKey] = $strategy($value, $key);
185
            }
186 9
            if ($discardNull || $discardEmptyContainer) {
187 2
                $res = array_filter(
188 2
                    $res,
189
                    function ($value) use ($discardNull, $discardEmptyContainer) {
190 2
                        if (null === $value) {
191 1
                            return !$discardNull;
192
                        }
193
194 2
                        if (is_array($value) && 0 === sizeof($value)) {
195 1
                            return !$discardEmptyContainer;
196
                        }
197
198 2
                        return true;
199 2
                    }
200
                );
201
            }
202 9
            return $castToObject ? (object)$res : $res;
203 9
        };
204
    }
205
206
    /**
207
     * Returns a closure that returns random integer numbers between $MIN and $MAX
208
     *
209
     * @param int $min
210
     * @param null|int $max
211
     * @return \Closure
212
     */
213 5
    public static function random($min = 0, $max = null)
214
    {
215 5
        if (null === $max) {
216 1
            $max = getrandmax();
217
        }
218
219
        return function () use ($min, $max) {
220 5
            return rand($min, $max);
221 5
        };
222
    }
223
224
    /**
225
     * Returns a closure that returns either the class name, given an object, or otherwise the type
226
     *
227
     * @param null|string|\Closure $strategy
228
     * @return \Closure
229
     */
230 6
    public static function type($strategy = null)
231
    {
232 6
        $strategy = Conversions::mixedToValueGetter($strategy);
233
        return function ($value) use ($strategy) {
234 6
            $value = $strategy($value);
235 6
            return is_object($value) ? get_class($value) : gettype($value);
236 6
        };
237
    }
238
239
    /**
240
     * Returns a closure that calls the mapping on each element once.
241
     *
242
     * > $compute = function ($value, $key) {
243
     * >    return 'some expensive computation result';
244
     * > };
245
     * > $list = iterable([['id' => 42, ...], ['id' => 43, ...], ['id' => 42, ...]]);
246
     * > $list->map(Mappings::cache($compute, 'id'));
247
     * [
248
     *    $compute(['id' => 42, ...]), // <-- calls the $compute method
249
     *    $compute(['id' => 43, ...]), // <-- calls the $compute method
250
     *    $compute(['id' => 42, ...])  // <-- does not call, instead, populates with cached values
251
     * ]
252
     *
253
     * @param null|string|\Closure $mapping
254
     * @param null|string|\Closure $strategy
255
     * @return \Closure
256
     */
257 2
    public static function cache($mapping, $strategy = null)
258
    {
259 2
        $mapping = Conversions::mixedToValueGetter($mapping);
260 2
        $strategy = Conversions::mixedToValueGetter($strategy);
261 2
        $cache = [];
262
        return function ($value, $key = null) use ($mapping, $strategy, &$cache) {
263 2
            $cacheKey = \json_encode($strategy($value, $key));
264 2
            if (!array_key_exists($cacheKey, $cache)) {
265 2
                $cache[$cacheKey] = $mapping($value, $key);
266
            }
267 2
            return $cache[$cacheKey];
268 2
        };
269
    }
270
271
    /**
272
     * Returns a closure that returns the same value every time it is called.
273
     *
274
     * @param null|string|int|float|bool|object|array $value
275
     * @return \Closure
276
     */
277
    public static function constant($value)
278
    {
279 1
        return function () use ($value) {
280 1
            return $value;
281 1
        };
282
    }
283
284
    /**
285
     * @param string $name
286
     * @return \Closure
287
     * @deprecated will be removed in version 3.0
288
     */
289
    public static function getMapping($name /* [argument, [arguments, ...] */)
290
    {
291
        switch ($name) {
292
            case 'ltrim':
293
            case 'lstrip':
294
                return call_user_func_array('\Zicht\Itertools\util\Mappings::lstrip', array_slice(func_get_args(), 1));
295
296
            case 'rtrim':
297
            case 'rstrip':
298
                return call_user_func_array('\Zicht\Itertools\util\Mappings::rstrip', array_slice(func_get_args(), 1));
299
300
            case 'trim':
301
            case 'strip':
302
                return call_user_func_array('\Zicht\Itertools\util\Mappings::strip', array_slice(func_get_args(), 1));
303
304
            case 'length':
305
                return call_user_func_array('\Zicht\Itertools\util\Mappings::length', array_slice(func_get_args(), 1));
306
307
            default:
308
                throw new \InvalidArgumentException(sprintf('$NAME "%s" is not a valid mapping.', $name));
309
        }
310
    }
311
}
312