Completed
Push — master ( ee4164...27a827 )
by ignace nyamagana
03:48
created

ImmutableCollectionTrait::validateOffset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * League.Uri (http://uri.thephpleague.com)
4
 *
5
 * @package   League.uri
6
 * @author    Ignace Nyamagana Butera <[email protected]>
7
 * @copyright 2013-2015 Ignace Nyamagana Butera
8
 * @license   https://github.com/thephpleague/uri/blob/master/LICENSE (MIT License)
9
 * @version   4.2.0
10
 * @link      https://github.com/thephpleague/uri/
11
 */
12
namespace League\Uri\Types;
13
14
use ArrayIterator;
15
use InvalidArgumentException;
16
use League\Uri\Interfaces\Collection;
17
use Traversable;
18
19
/**
20
 * Common methods for Immutable Collection objects
21
 *
22
 * @package League.uri
23
 * @author  Ignace Nyamagana Butera <[email protected]>
24
 * @since  4.0.0
25
 */
26
trait ImmutableCollectionTrait
27
{
28
    /**
29
     * The Component Data
30
     *
31
     * @var array
32
     */
33
    protected $data = [];
34
35
    /**
36
     * Count elements of an object
37
     *
38
     * @return int
39
     */
40 24
    public function count()
41
    {
42 24
        return count($this->data);
43
    }
44
45
    /**
46
     * Returns an external iterator
47
     *
48
     * @return ArrayIterator
49
     */
50 69
    public function getIterator()
51
    {
52 69
        return new ArrayIterator($this->data);
53
    }
54
55
    /**
56
     * Returns an array representation of the collection
57
     *
58
     * @return array
59
     */
60 339
    public function toArray()
61
    {
62 339
        return $this->data;
63
    }
64
65
    /**
66
     * Returns whether the given key exists in the current instance
67
     *
68
     * @param string $offset
69
     *
70
     * @return bool
71
     */
72 66
    public function hasKey($offset)
73
    {
74 66
        return array_key_exists($offset, $this->data);
75
    }
76
77
    /**
78
     * Returns the component $keys.
79
     *
80
     * If a value is specified only the keys associated with
81
     * the given value will be returned
82
     *
83
     * @return array
84
     */
85 12
    public function keys()
86
    {
87 12
        if (0 == func_num_args()) {
88 9
            return array_keys($this->data);
89
        }
90
91 9
        return array_keys($this->data, func_get_arg(0), true);
92
    }
93
94
    /**
95
     * Returns an instance without the specified keys
96
     *
97
     * This method MUST retain the state of the current instance, and return
98
     * an instance that contains the modified component
99
     *
100
     * @param array $offsets the list of keys to remove from the collection
101
     *
102
     * @return static
103
     */
104 42
    public function without(array $offsets)
105
    {
106 42
        $data = $this->data;
107 42
        foreach ($offsets as $offset) {
108 42
            unset($data[$offset]);
109 28
        }
110
111 42
        return $this->newCollectionInstance($data);
112
    }
113
114
    /**
115
     * Returns an instance with only the specified value
116
     *
117
     * This method MUST retain the state of the current instance, and return
118
     * an instance that contains the modified component
119
     *
120
     * @param callable $callable the list of keys to keep from the collection
121
     * @param int      $flag     flag to determine what argument are sent to callback
122
     *
123
     * @return static
124
     */
125 54
    public function filter(callable $callable, $flag = Collection::FILTER_USE_VALUE)
126
    {
127 18
        static $flags_list = [
128
            Collection::FILTER_USE_VALUE => 1,
129
            Collection::FILTER_USE_BOTH => 1,
130
            Collection::FILTER_USE_KEY => 1,
131 36
        ];
132
133 54
        if (!isset($flags_list[$flag])) {
134 3
            throw new InvalidArgumentException('Invalid or Unknown flag parameter');
135
        }
136
137 51
        if ($flag == Collection::FILTER_USE_KEY) {
138 18
            return $this->filterByKeys($callable);
139
        }
140
141 33
        if ($flag == Collection::FILTER_USE_BOTH) {
142 3
            return $this->filterBoth($callable);
143
        }
144
145 30
        return $this->newCollectionInstance(array_filter($this->data, $callable));
146
    }
147
148
    /**
149
     * Return a new instance when needed
150
     *
151
     * @param array $data
152
     *
153
     * @return static
154
     */
155
    abstract protected function newCollectionInstance(array $data);
156
157
    /**
158
     * Filter The Collection according to its offsets
159
     *
160
     * @param callable $callable
161
     *
162
     * @return static
163
     */
164 18
    protected function filterByKeys(callable $callable)
165
    {
166 18
        $data = [];
167 18
        foreach (array_filter(array_keys($this->data), $callable) as $offset) {
168 12
            $data[$offset] = $this->data[$offset];
169 12
        }
170
171 18
        return $this->newCollectionInstance($data);
172
    }
173
174
    /**
175
     * Filter The Collection according to its offsets AND its values
176
     *
177
     * @param callable $callable
178
     *
179
     * @return static
180
     */
181 3
    protected function filterBoth(callable $callable)
182
    {
183 3
        $data = [];
184 3
        foreach ($this->data as $key => $value) {
185 3
            if (true === call_user_func($callable, $value, $key)) {
186 3
                $data[$key] = $value;
187 2
            }
188 2
        }
189
190 3
        return $this->newCollectionInstance($data);
191
    }
192
193
    /**
194
     * Validate an Iterator or an array
195
     *
196
     * @param Traversable|array $data
197
     *
198
     * @throws InvalidArgumentException if the value can not be converted
199
     *
200
     * @return array
201
     */
202 1066
    protected static function validateIterator($data)
203
    {
204 1066
        if ($data instanceof Traversable) {
205 75
            $data = iterator_to_array($data, true);
206 50
        }
207
208 1066
        if (!is_array($data)) {
209 30
            throw new InvalidArgumentException(
210 10
                'Data passed to the method must be an array or a Traversable object'
211 20
            );
212
        }
213
214 1036
        return $data;
215
    }
216
}
217