Completed
Push — master ( a8d3e3...cc8041 )
by James
8s
created

Collection   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 225
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 71.67%

Importance

Changes 0
Metric Value
wmc 32
c 0
b 0
f 0
lcom 1
cbo 1
dl 0
loc 225
ccs 43
cts 60
cp 0.7167
rs 9.6

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 2
B add() 0 13 5
B remove() 0 17 7
A at() 0 3 2
A map() 0 3 1
A filter() 0 3 1
A key() 0 3 1
A find() 0 9 3
A serialize() 0 9 2
A current() 0 3 1
A next() 0 3 1
A valid() 0 3 1
A rewind() 0 3 1
A count() 0 3 1
A parse_config() 0 11 3
1
<?php
2
namespace Intraxia\Jaxion\Axolotl;
3
4
use Countable;
5
use Intraxia\Jaxion\Contract\Axolotl\Serializes;
6
use Iterator;
7
use LogicException;
8
use RuntimeException;
9
10
/**
11
 * Class Collection
12
 *
13
 * @package Intraxia\Jaxion
14
 * @subpackage Axolotl
15
 */
16
class Collection implements Countable, Iterator, Serializes {
17
	/**
18
	 * Collection elements.
19
	 *
20
	 * @var array
21
	 */
22
	protected $elements = array();
23
24
	/**
25
	 * Collection configuration.
26
	 *
27
	 * @var array
28
	 */
29
	protected $config = array();
30
31
	/**
32
	 * Models registered to the collection.
33
	 *
34
	 * @var string
35
	 */
36
	protected $model;
37
38
	/**
39
	 * Where Collection is in loop.
40
	 *
41
	 * @var int
42
	 */
43
	protected $position = 0;
44
45
	/**
46
	 * Collection constructor.
47
	 *
48
	 * @param array $elements
49
	 * @param array $config
50
	 */
51 60
	public function __construct( array $elements = array(), array $config = array() ) {
52 60
		$this->parse_config( $this->config = $config );
53
54 57
		foreach ( $elements as $element ) {
55 24
			$this->add( $element );
56 57
		}
57 57
	}
58
59
	/**
60
	 * Adds a new element to the Collection.
61
	 *
62
	 * @param mixed $element
63
	 *
64
	 * @throws RuntimeException
65
	 *
66
	 * @return $this
67
	 */
68 27
	public function add( $element ) {
69 27
		if ( $this->model && is_array( $element ) ) {
70 9
			$element = new $this->model( $element );
71 9
		}
72
73 27
		if ( $this->model && ! ( $element instanceof $this->model ) ) {
74 3
			throw new RuntimeException;
75
		}
76
77 24
		$this->elements[] = $element;
78
79 24
		return $this;
80
	}
81
82
	/**
83
	 * Removes an element by index or value.
84
	 *
85
	 * @param mixed $index
86
	 *
87
	 * @return $this
88
	 */
89
	public function remove( $index ) {
90
		if ( ! is_string( $index ) || ! is_numeric( $index ) || ! isset( $this->elements[ $index ] ) ) {
91
			foreach ( $this->elements as $key => $element ) {
92
				if ( $element === $index ) {
93
					$index = $key;
94
					break;
95
				}
96
			}
97
		}
98
99
		if ( isset( $this->elements[ $index ] ) ) {
100
			unset( $this->elements[ $index ] );
101
			$this->elements = array_values( $this->elements );
102
		}
103
104
		return $this;
105
	}
106
107
	/**
108
	 * Fetches the element at the provided index.
109
	 *
110
	 * @param int $index
111
	 *
112
	 * @return mixed|null
113
	 */
114 12
	public function at( $index ) {
115 12
		return isset( $this->elements[ $index ] ) ? $this->elements[ $index ] : null;
116
	}
117
118
	/**
119
	 * Maps over the Collection's elements,
120
	 *
121
	 * @param callable $callback
122
	 *
123
	 * @return Collection
124
	 */
125
	protected function map( callable $callback ) {
126
		return new Collection( array_map( $callback, $this->elements ), $this->config );
127
	}
128
129
	/**
130
	 * Filters the Collection's elements.
131
	 *
132
	 * @param callable $callback
133
	 *
134
	 * @return Collection
135
	 */
136
	public function filter( callable $callback ) {
137
		return new Collection( array_filter( $this->elements, $callback ) );
138
	}
139
140
	/**
141
	 * Fetches a single element in the Collection by callback.
142
	 *
143
	 * @param callable $callback
144
	 *
145
	 * @return mixed|null
146 9
	 */
147 6
	public function find( callable $callback ) {
148 3
		foreach ( $this->elements as $element ) {
149
			if ( call_user_func( $callback, $element ) ) {
150
				return $element;
151 3
			}
152 9
		}
153
154
		return null;
155
	}
156
157
	/**
158
	 * {@inheritDoc}
159
	 *
160 3
	 * @return array
161 3
	 */
162
	public function serialize() {
163
		return array_map(function( $element ) {
164
			if ( $element instanceof Serializes ) {
165
				return $element->serialize();
166
			}
167 3
168 3
			return $element;
169 3
		}, $this->elements);
170
	}
171
172
	/**
173
	 * Return the current element.
174
	 *
175
	 * @return mixed
176 3
	 */
177 3
	public function current() {
178
		return $this->at( $this->position );
179
	}
180
181
	/**
182
	 * Move forward to next element.
183
	 */
184
	public function next() {
185 3
		$this->position ++;
186 3
	}
187
188
	/**
189
	 * Return the key of the current element.
190
	 *
191
	 * @return mixed
192 3
	 */
193 3
	public function key() {
194 3
		return $this->position;
195
	}
196
197
	/**
198
	 * Checks if current position is valid.
199
	 *
200
	 * @return bool
201 6
	 */
202 6
	public function valid() {
203
		return isset( $this->elements[ $this->position ] );
204
	}
205
206
	/**
207
	 * Rewind the Iterator to the first element.
208
	 */
209
	public function rewind() {
210
		$this->position = 0;
211
	}
212 60
213 60
	/**
214 15
	 * Count elements of an object.
215
	 *
216 15
	 * @return int
217 3
	 */
218
	public function count() {
219
		return count( $this->elements );
220 12
	}
221 12
222 57
	/**
223
	 * Parses the Collection config to set its properties.
224
	 *
225
	 * @param array $config
226
	 *
227
	 * @throws LogicException
228
	 */
229
	protected function parse_config( array $config ) {
230
		if ( isset( $config['model'] ) ) {
231
			$model = $config['model'];
232
233
			if ( ! is_subclass_of( $model, 'Intraxia\Jaxion\Axolotl\Model' ) ) {
234
				throw new LogicException;
235
			}
236
237
			$this->model = $model;
238
		}
239
	}
240
}
241