Mappings::type()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
nc 1
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
ccs 5
cts 5
cp 1
crap 2
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 $associative
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