Passed
Push — features/47-laravelmethods ( baa4b5...734d23 )
by Luke
02:25
created

functions.php ➔ get_range_start_end()   C

Complexity

Conditions 8
Paths 21

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
cc 8
eloc 15
nc 21
nop 2
dl 0
loc 24
ccs 0
cts 19
cp 0
crap 72
rs 5.7377
c 0
b 0
f 0
1
<?php
2
/*
3
 * Nozavroni/Collections
4
 * Just another collections library for PHP5.6+.
5
 *
6
 * @copyright Copyright (c) 2016 Luke Visinoni <[email protected]>
7
 * @author    Luke Visinoni <[email protected]>
8
 * @license   https://github.com/nozavroni/collections/blob/master/LICENSE The MIT License (MIT)
9
 */
10
namespace Noz;
11
12
use Closure;
13
use Illuminate\Support\Str;
14
use InvalidArgumentException;
15
use Iterator;
16
use Noz\Collection\Collection;
17
use Noz\Collection\Sequence;
18
use Noz\Contracts\CollectionInterface;
19
use RuntimeException;
20
use Traversable;
21
22
/**
23
 * Collection factory.
24
 *
25
 * Simply an alias to (new Collection($in)). Allows for a little more concise and
26
 * simpler instantiation of a collection. Also I plan to eventually support
27
 * additional input types that will make this function more flexible and forgiving
28
 * than simply instantiating a Collection object, but for now the two are identical.
29
 *
30
 * @param array|Iterator $data Either an array or an iterator of data
31
 *
32
 * @return CollectionInterface
0 ignored issues
show
Documentation introduced by
Should the return type not be Illuminate\Support\Collection?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
33
 */
34
function collect($data = null)
35
{
36 42
    return Collection::factory($data);
37
}
38
39
/**
40
 * Invoke a callable and return result.
41
 *
42
 * Pass in a callable followed by whatever arguments you want passed to
43
 * it and this function will invoke it with your arguments and return
44
 * the result.
45
 *
46
 * @param callable $callback The callback function to invoke
47
 * @param array ...$args     The args to pass to your callable
48
 *
49
 * @return mixed The result of your invoked callable
50
 */
51
function invoke(callable $callback, ...$args)
52
{
53 7
    return call_user_func($callback, ...$args);
54
}
55
56
/**
57
 * Underscore function.
58
59
 * This function is meant to work sort of like jQuery's "$()". It is a contextual catch-all type function. It works
60
 * as a short-hand alias for invoke, collect, and with.
61
62
 * @param callable|mixed    $in
63
 * @param mixed ...         $_
64
 *
65
 * @return mixed|CollectionInterface
66
 */
67
function _($in, ...$args)
68
{
69 3
    if (is_callable($in)) {
70 3
        return invoke($in, ...$args);
71
    }
72
    if (is_traversable($in)) {
73
        return collect($in);
74
    }
75
    return $in;
76
}
77
78
/**
79
 * Determine if data is traversable.
80
 *
81
 * Pass in any variable and this function will tell you whether or not it
82
 * is traversable. Basically this just means that it is either an array or an iterator.
83
 * This function was written simply because I was tired of if statements that checked
84
 * whether a variable was an array or a descendant of \Iterator. So I wrote this guy.
85
 *
86
 * @param mixed $data The variable to determine traversability
87
 *
88
 * @return bool True if $input is an array or an Iterator
89
 */
90
function is_traversable($data)
91
{
92 62
    return is_array($data) || $data instanceof Traversable;
93
}
94
95
/**
96
 * Can data be converted to an array?
97
 *
98
 * @param mixed $data The data to check
99
 *
100
 * @return bool
101
 */
102
function is_arrayable($data)
103
{
104 38
    if (!is_array($data)) {
105 35
        if (is_object($data)) {
106
            return (
107 3
                method_exists($data, 'toArray') ||
108
                $data instanceof Traversable
109 3
            );
110
        }
111 35
        return false;
112
    }
113 8
    return true;
114
}
115
116
/**
117
 * Convert any traversable to an array.
118
 *
119
 * @todo I'm not sure if this function is necessary or not. Does iterator_to_array do everything this can do?
120
 *
121
 * @param Traversable $data Traversable data
122
 *
123
 * @return array
124
 */
125
function traversable_to_array(Traversable $data)
126
{
127
    $arr = [];
128
    foreach ($data as $key => $val) {
129
        $arr[$key] = $val;
130
    }
131
    return $arr;
132
}
133
134
/**
135
 * Convert data to an array.
136
 *
137
 * Accepts any kind of data and converts it to an array. If strict mode is on, only data that returns true from
138
 * is_arrayable() will be converted to an array. Anything else will cause an InvalidArgumentException to be thrown.
139
140
 * @param mixed $data   Data to convert to array
141
 * @param bool  $strict Whether to use strict mode
142
143
 * @return array
144
 *
145
 * @throws InvalidArgumentException
146
 */
147
function to_array($data, $strict = true)
148
{
149 8
    if (is_arrayable($data)) {
150 8
        if (is_array($data)) {
151 7
            return $data;
152
        }
153
        // this is what makes toArray() work recursively
154
        // it must stay right where it is do not move it
155 2
        if (method_exists($data, 'toArray')) {
156 2
            return $data->toArray();
157
        }
158 1
        if ($data instanceof Iterator) {
159 1
            return iterator_to_array($data);
160
        }
161
        // @todo I don't think this will EVER be called...
162
        if ($data instanceof Traversable) {
163
            return traversable_to_array($data);
164
        }
165
    }
166 1
    if ($strict) {
167
        throw new InvalidArgumentException(sprintf(
168
            'Invalid argument for "%s". Cannot convert "%s" to an array.',
169
            __FUNCTION__,
170
            typeof($data)
171
        ));
172
    }
173 1
    if (is_object($data)) {
174 1
        $values = [];
175 1
        foreach ($data as $key => $val) {
176 1
            $values[$key] = $val;
177 1
        }
178 1
        return $values;
179
    }
180 1
    if (is_null($data)) {
181 1
        return [];
182
    }
183 1
    return [$data];
184
}
185
186
function get_range_start_end($range, $count)
187
{
188
    if (Str::contains($range, Sequence::SLICE_DELIM)) {
189
        // return slice as a new sequence
190
        list($start, $end) = explode(Sequence::SLICE_DELIM, $range, 2);
191
        if ($start == '') {
192
            $start = 0;
193
        }
194
        if ($end == '') {
195
            $end = $count - 1;
196
        }
197
        if (is_numeric($start) && is_numeric($end)) {
198
            if ($start < 0) {
199
                $start = $count - abs($start);
200
            }
201
            if ($end < 0) {
202
                $end = $count - abs($end);
203
            }
204
            $length = $end - $start + 1;
205
            return [$start, $length];
206
        }
207
    }
208
    throw new RuntimeException('Invalid index range/offset.');
209
}
210
211
/**
212
 * Get data type.
213
 *
214
 * Inspects data to determine its type.
215
 *
216
 * @param mixed  $data       The data to check
217
 * @param bool   $meta       Whether to include meta data such as length/size
218
// * @param string $returnType What type of value to return (array or string)
0 ignored issues
show
Bug introduced by
There is no parameter named $returnType. 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...
219
 *
220
 * @return string
221
 */
222
function typeof($data, $meta = true/*, $returnType = 'string'*/)
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
223
{
224 3
    $type = gettype($data);
225 3
    if ($meta) {
226
        switch($type) {
227 3
            case 'object':
228 1
                $class = get_class($data);
229 1
                return "{$type} <{$class}>";
230 3
            case 'resource':
231 1
                $restype = get_resource_type($data);
232 1
                return "{$type} <{$restype}>";
233
        }
234 3
    } else {
235
        switch($type) {
236 1
            case 'object':
237 1
                return get_class($data);
238 1
            case 'resource':
239 1
                return get_resource_type($data);
240
        }
241
    }
242 3
    return $type;
243
}
244
245
// BEGIN debug/testing functions
246
247
/**
248
 * Dump and die.
249
 *
250
 * @param mixed $input Data to dump
251
 * @param bool  $exit  Should we exit after dump?
252
 * @param bool  $label Should we print a label?
253
 * @codeCoverageIgnore
254
 */
255
function dd($input, $exit = true, $label = null)
256
{
257
    if (is_null($label)) {
258
        $trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1);
259
        $label = 'File: ';
260
        $label .= pathinfo($trace[0]['file'], PATHINFO_FILENAME);
261
        $label .= ':' . $trace[0]['line'];
262
        echo $label . "\n";
263
    } else {
264
        echo $label . "\n" . implode(
265
                array_map(
266
                    function () {
267
                        return '-';
268
                    },
269
                    str_split($label)
270
                )
271
            ) . "\n";
272
    }
273
    var_dump($input);
274
    echo "\n";
275
    if ($exit) {
276
        exit;
277
    }
278
}
279
280
/**
281
 * Exactly the same as var_dump, except that it returns its output rather than dumping it.
282
 */
283
function sdump($var)
284
{
285 22
    ob_start();
286 22
    var_dump($var);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($var); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
287 22
    return ob_get_clean();
288
}
289
290
/**
291
 * Get object hash/checksum.
292
 * Using a var_dump of an object, this will return a hash that tells you if anything in your object has changed. Just
293
 * create a hash of an object, do some stuff with it, then create another hash of it and compare the two. If they are
294
 * different, teh object has changed in some way.
295
 *
296
 * @param object $obj The object to hash
297
 * @param string $alg The hash algorithm (supports md5 or sha1)
298
 *
299
 * @return string
300
 *
301
 * @throws InvalidArgumentException
302
 */
303
function object_hash($obj, $alg = 'md5')
304
{
305 22
    $algorithms = ['md5', 'sha1'];
306 22
    if (!in_array($alg, $algorithms)) {
307
        throw new InvalidArgumentException(sprintf(
308
            '"%s" is not a valid hash algorithm (%s).',
309
            $alg,
310
            implode(', ', $algorithms)
311
        ));
312
    }
313 22
    return call_user_func($alg, sdump($obj));
314
}
315