Completed
Push — master ( 71429f...426b40 )
by SuRaMoN
02:07
created

IterUtil::getCurrentAndAdvance()   C

Complexity

Conditions 7
Paths 15

Size

Total Lines 26
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 26
rs 6.7272
c 2
b 0
f 0
cc 7
eloc 19
nc 15
nop 2
1
<?php
2
3
namespace itertools;
4
5
use UnexpectedValueException;
6
use ArrayIterator;
7
use Exception;
8
use InvalidArgumentException;
9
use Iterator;
10
use IteratorAggregate;
11
use IteratorIterator;
12
use Traversable;
13
14
15
class IterUtil
16
{
17
    public static function traversableToIterator(Traversable $traversable)
18
    {
19
        if($traversable instanceof Iterator) {
20
            return $traversable;
21
        } else if($traversable instanceof IteratorAggregate) {
22
            return $traversable->getIterator();
23
        } else {
24
            return new IteratorIterator($traversable);
25
        }
26
    }
27
28
    public static function asTraversable($iterable)
29
    {
30
        if(is_array($iterable)) {
31
            return new ArrayIterator($iterable);
32
        }
33
        if(!($iterable instanceof Traversable)) {
34
            throw new InvalidArgumentException('Can\'t create a traversable out of: ' . (is_object($iterable) ? get_class($iterable) : gettype($iterable)));
35
        }
36
        return $iterable;
37
    }
38
39
    public static function asIterator($iterable)
40
    {
41
        if(is_array($iterable)) {
42
            return new ArrayIterator($iterable);
43
        } else {
44
            return self::traversableToIterator($iterable);
45
        }
46
    }
47
48
    public static function isCollection($value)
49
    {
50
        switch(true) {
51
            case is_array($value):
52
            case $value instanceof Traversable:
53
                return true;
54
            default:
55
                return false;
56
        }
57
    }
58
59
    public static function any($iterable, $callable = null)
60
    {
61
        if(null !== $callable && ! is_callable($callable)) {
62
            throw new InvalidArgumentException('No valid callable is supplied');
63
        }
64
        if(null === $callable) {
65
            return self::anyWithoutCallable($iterable);
66
        } else {
67
            return self::anyWithCallable($iterable, $callable);
68
        }
69
    }
70
71
    protected static function anyWithoutCallable($iterable)
72
    {
73
        foreach($iterable as $element) {
74
            if($element) {
75
                return true;
76
            }
77
        }
78
        return false;
79
    }
80
81
    protected static function anyWithCallable($iterable, $callable)
82
    {
83
        foreach($iterable as $element) {
84
            if(call_user_func($callable, $element)) {
85
                return true;
86
            }
87
        }
88
        return false;
89
    }
90
91
    public static function all($iterable, $callable = null)
92
    {
93
        if(null !== $callable && ! is_callable($callable)) {
94
            throw new InvalidArgumentException('No valid callable is supplied');
95
        }
96
        if(null === $callable) {
97
            return self::allWithoutCallable($iterable);
98
        } else {
99
            return self::allWithCallable($iterable, $callable);
100
        }
101
    }
102
103
    protected static function allWithoutCallable($iterable)
104
    {
105
        foreach($iterable as $element) {
106
            if(! $element) {
107
                return false;
108
            }
109
        }
110
        return true;
111
    }
112
113
    protected static function allWithCallable($iterable, $callable)
114
    {
115
        foreach($iterable as $element) {
116
            if(! call_user_func($callable, $element)) {
117
                return false;
118
            }
119
        }
120
        return true;
121
    }
122
123
    public static function invoke($iterable, $method)
124
    {
125
        return new MapIterator($iterable, function($element) use ($method) {
126
            return $element->$method();
127
        });
128
    }
129
130
    public static function sum($iterable, $initialValue = 0)
131
    {
132
        self::assertIsCollection($iterable);
133
        $sum = $initialValue;
134
        foreach($iterable as $element) {
135
            $sum += $element;
136
        }
137
        return $sum;
138
    }
139
140
    public static function iterator_reduce($iterable, $callable, $initial = null)
141
    {
142
        $returnValue = $initial;
143
        foreach ($iterable as $element) {
144
            $returnValue = $callable($initial, $element);
145
        }
146
        return $returnValue;
147
    }
148
149
    public static function recursive_iterator_to_array(Iterator $iterator, $useKeys = true)
150
    {
151
        $resultArray = array();
152
        $index = 0;
153
        foreach($iterator as $key => $element) {
154
            if(!$useKeys) {
155
                $key = $index;
156
            }
157
            if($element instanceof Iterator) {
158
                $resultArray[$key] = self::recursive_iterator_to_array($element, $useKeys);
159
            } else {
160
                $resultArray[$key] = $element;
161
            }
162
            $index += 1;
163
        }
164
        return $resultArray;
165
    }
166
167
    public static function assertIsCollection($value)
168
    {
169
        if(!self::isCollection($value)) {
170
            throw new UnexpectedValueException('The provided argument is not a collection: ' . (is_object($value) ? get_class($value) : gettype($value)));
171
        }
172
    }
173
174
    public static function getCurrentAndAdvance(&$iterable, $options = array())
175
    {
176
        if(is_array($iterable)) {
177
            if (null === key($iterable)) {
178
                $current = false;
179
            } else {
180
                $current = ['value' => current($iterable)];
181
                next($iterable);
182
            }
183
        } else if($iterable instanceof Iterator) {
184
            if(!$iterable->valid()) {
185
                $current = false;
186
            } else {
187
                $current = array('value' => $iterable->current());
188
                $iterable->next();
189
            }
190
        }
191
        if($current === false) {
0 ignored issues
show
Bug introduced by
The variable $current does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
192
            if(array_key_exists('default', $options)) {
193
                return $options['default'];
194
            } else {
195
                throw new UnexpectedValueException('Error while advancing iterable');
196
            }
197
        }
198
        return $current['value'];
199
    }
200
}
201
202