Completed
Pull Request — master (#49)
by Luke
02:09
created

functions.php ➔ is_arrayable()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 1
dl 0
loc 13
ccs 6
cts 6
cp 1
crap 4
rs 9.2
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 InvalidArgumentException;
13
use Iterator;
14
use Noz\Collection\Collection;
15
use Noz\Contracts\CollectionInterface;
16
use Traversable;
17
18
/**
19
 * Collection factory.
20
 *
21
 * Simply an alias to (new Collection($in)). Allows for a little more concise and
22
 * simpler instantiation of a collection. Also I plan to eventually support
23
 * additional input types that will make this function more flexible and forgiving
24
 * than simply instantiating a Collection object, but for now the two are identical.
25
 *
26
 * @param array|Iterator $data Either an array or an iterator of data
27
 *
28
 * @return CollectionInterface
29
 */
30
function collect($data = null)
31
{
32 27
    return Collection::factory($data);
33
}
34
35
/**
36
 * Invoke a callable and return result.
37
 *
38
 * Pass in a callable followed by whatever arguments you want passed to
39
 * it and this function will invoke it with your arguments and return
40
 * the result.
41
 *
42
 * @param callable $callback The callback function to invoke
43
 * @param array ...$args     The args to pass to your callable
44
 *
45
 * @return mixed The result of your invoked callable
46
 */
47
function invoke(callable $callback, ...$args)
48
{
49 2
    return $callback(...$args);
50
}
51
52
/**
53
 * Determine if data is traversable.
54
 *
55
 * Pass in any variable and this function will tell you whether or not it
56
 * is traversable. Basically this just means that it is either an array or an iterator.
57
 * This function was written simply because I was tired of if statements that checked
58
 * whether a variable was an array or a descendant of \Iterator. So I wrote this guy.
59
 *
60
 * @param mixed $data The variable to determine traversability
61
 *
62
 * @return bool True if $input is an array or an Iterator
63
 */
64
function is_traversable($data)
65
{
66 93
    return is_array($data) || $data instanceof Traversable;
67
}
68
69
/**
70
 * Can data be converted to an array?
71
 *
72
 * @param mixed $data The data to check
73
 *
74
 * @return bool
75
 */
76
function is_arrayable($data)
77
{
78 36
    if (!is_array($data)) {
79 34
        if (is_object($data)) {
80
            return (
81 3
                method_exists($data, 'toArray') ||
82
                $data instanceof Traversable
83 3
            );
84
        }
85 34
        return false;
86
    }
87 8
    return true;
88
}
89
90
/**
91
 * Convert any traversable to an array.
92
 *
93
 * @todo I'm not sure if this function is necessary or not. Does iterator_to_array do everything this can do?
94
 *
95
 * @param Traversable $data Traversable data
96
 *
97
 * @return array
98
 */
99
function traversable_to_array(Traversable $data)
100
{
101
    $arr = [];
102
    foreach ($data as $key => $val) {
103
        $arr[$key] = $val;
104
    }
105
    return $arr;
106
}
107
108
/**
109
 * Convert data to an array.
110
 *
111
 * Accepts any kind of data and converts it to an array. If strict mode is on, only data that returns true from
112
 * is_arrayable() will be converted to an array. Anything else will cause an InvalidArgumentException to be thrown.
113
114
 * @param mixed $data   Data to convert to array
115
 * @param bool  $strict Whether to use strict mode
116
117
 * @return array
118
 *
119
 * @throws InvalidArgumentException
120
 */
121
function to_array($data, $strict = true)
122
{
123 8
    if (is_arrayable($data)) {
124 8
        if (is_array($data)) {
125 7
            return $data;
126
        }
127
        // this is what makes toArray() work recursively
128
        // it must stay right where it is do not move it
129 2
        if (method_exists($data, 'toArray')) {
130 2
            return $data->toArray();
131
        }
132 1
        if ($data instanceof Iterator) {
133 1
            return iterator_to_array($data);
134
        }
135
        if ($data instanceof Traversable) {
136
            return traversable_to_array($data);
137
        }
138
    }
139 1
    if ($strict) {
140
        throw new InvalidArgumentException(sprintf(
141
            'Invalid argument for "%s". Cannot convert "%s" to an array.',
142
            __FUNCTION__,
143
            typeof($data)
144
        ));
145
    }
146 1
    if (is_object($data)) {
147 1
        $values = [];
148 1
        foreach ($data as $key => $val) {
149 1
            $values[$key] = $val;
150 1
        }
151 1
        return $values;
152
    }
153 1
    if (is_null($data)) {
154 1
        return [];
155
    }
156 1
    return [$data];
157
}
158
159
/**
160
 * Get data type.
161
 *
162
 * Inspects data to determine its type.
163
 *
164
 * @param mixed  $data       The data to check
165
 * @param bool   $meta       Whether to include meta data such as length/size
166
// * @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...
167
 *
168
 * @return string
169
 */
170
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...
171
{
172 1
    $type = gettype($data);
173 1
    if ($meta) {
174
        switch($type) {
175 1
            case 'object':
176 1
                $class = get_class($data);
177 1
                return "{$type} <{$class}>";
178 1
            case 'resource':
179 1
                $restype = get_resource_type($data);
180 1
                return "{$type} <{$restype}>";
181
        }
182 1
    } else {
183
        switch($type) {
184 1
            case 'object':
185 1
                return get_class($data);
186 1
            case 'resource':
187 1
                return get_resource_type($data);
188
        }
189
    }
190 1
    return $type;
191
//    $params = [
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% 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...
192
//        'type' => strtolower(gettype($data)),
193
//        'class' => null,
194
//        'size' => null,
195
//        'value' => null
196
//    ];
197
//    switch($params['type']) {
198
//        case 'object':
199
//            $params['class'] = get_class($data);
200
//            break;
201
//        case 'resource':
202
//            $params['class'] = get_resource_type($data);
203
//            break;
204
//        case 'array':
205
//            $params['size'] = count($data);
206
//            break;
207
//        case 'boolean':
208
//            $params['value'] = $data ? 'true' : 'false';
209
//            break;
210
//        case 'string':
211
//            $params['size'] = strlen($data);
212
//            $params['value'] = $data;
213
//            break;
214
//        case 'integer':
215
//            $params['size'] = strlen($data);
216
//            $params['value'] = $data;
217
//            break;
218
//        case 'double':
219
//            list($real, $decimal) = explode('.', $data, 2);
220
//            $params['size'] = strlen($real) . ',' . strlen($decimal);
221
//            $params['value'] = $data;
222
//            break;
223
//        case 'null':
224
//            break;
225
//        case 'unknown type':
226
//        default:
227
//            $params['type'] = 'undefined';
228
//            break;
229
//    }
230
//    if ($returnType == 'array') {
231
//        if (!$meta) {
232
//            return ['type' => $params['type']];
233
//        }
234
//        return collect($params)->filter(function($val) {
235
//            return !is_null($val);
236
//        })->toArray();
237
//    }
238
//    if (!$meta) {
239
//        return $params['type'];
240
//    }
241
//    $return = $params['type'];
242
//    if (!is_null($params['class'])) {
243
//        $return .= " <{$params['class']}>";
244
//    }
245
//    if (!is_null($params['size'])) {
246
//        $return .= " <{$params['size']}>";
247
//    }
248
//    if (!is_null($params['value'])) {
249
//        $return .= " ({$params['value']})";
250
//    }
251
//    return $return;
252
}
253
254
/**
255
 * Dump and die.
256
 *
257
 * @param mixed $input Data to dump
258
 * @param bool  $exit  Should we exit after dump?
259
 * @param bool  $label Should we print a label?
260
 * @codeCoverageIgnore
261
 */
262
function dd($input, $exit = true, $label = null)
263
{
264
    if (is_null($label)) {
265
        $trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1);
266
        $label = 'File: ';
267
        $label .= pathinfo($trace[0]['file'], PATHINFO_FILENAME);
268
        $label .= ':' . $trace[0]['line'];
269
        echo $label . "\n";
270
    } else {
271
        echo $label . "\n" . implode(
272
                array_map(
273
                    function () {
274
                        return '-';
275
                    },
276
                    str_split($label)
277
                )
278
            ) . "\n";
279
    }
280
    var_dump($input);
281
    echo "\n";
282
    if ($exit) {
283
        exit;
284
    }
285
}
286