Nodelist   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 248
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 97.18%

Importance

Changes 0
Metric Value
wmc 31
lcom 1
cbo 2
dl 0
loc 248
ccs 69
cts 71
cp 0.9718
rs 9.92
c 0
b 0
f 0

20 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A rewind() 0 5 1
A current() 0 5 1
A key() 0 4 1
A next() 0 5 1
A valid() 0 4 1
A count() 0 4 1
A offsetExists() 0 4 2
A offsetSet() 0 4 1
A offsetUnset() 0 4 1
A _load() 0 4 1
A locator() 0 4 1
A driver() 0 4 1
A first() 0 9 2
A __toString() 0 9 2
A seek() 0 9 2
A offsetGet() 0 7 2
A list_ids() 0 20 5
A last() 0 9 2
A as_array() 0 9 2
1
<?php
2
3
namespace Openbuildings\Spiderling;
4
5
/**
6
 * NodeList represents a list of dom nodes. Has lazy loading
7
 *
8
 * @package    Openbuildings\Spiderling
9
 * @author     Ivan Kerin
10
 * @copyright  (c) 2013 OpenBuildings Ltd.
11
 * @license    http://spdx.org/licenses/BSD-3-Clause
12
 */
13
class Nodelist implements \Iterator, \Countable, \SeekableIterator, \ArrayAccess {
14
15
	/**
16
	 * The driver for traversing this node and its children
17
	 * @var Driver
18
	 */
19
	protected $_driver;
20
21
	/**
22
	 * The parent node, NULL if root
23
	 * @var Node
24
	 */
25
	protected $_parent;
26
27
	/**
28
	 * Cache for the ids of this node list
29
	 * @var array
30
	 */
31
	protected $_list_ids;
32
33
	/**
34
	 * Single node object to be used during iteration
35
	 * @var Node
36
	 */
37
	protected $_node;
38
39
	/**
40
	 * Implementing Iterator
41
	 * @var integer
42
	 */
43
	protected $_current = 0;
44
45 18
	function __construct(Driver $driver, Locator $locator, Node $parent)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
46
	{
47 18
		$this->_driver  = $driver;
48 18
		$this->_locator = $locator;
0 ignored issues
show
Bug introduced by
The property _locator does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
49 18
		$this->_parent  = $parent;
50 18
		$this->_node = new Node($driver, $parent);
51 18
	}
52
53
	/**
54
	 * Returns a string representation of the collection.
55
	 *
56
	 * @return  string
57
	 */
58 1
	public function __toString()
59
	{
60 1
		$nodes = array();
61 1
		foreach($this as $node)
62
		{
63 1
			$nodes[] = $node->html();
64
		}
65 1
		return "Nodelist: \nLocator: {$this->locator()} \nContent: [\n".join("\n", $nodes)."\n]\n";
66
	}
67
68
	/**
69
	 * Implementation of the Iterator interface
70
	 * @return  Nodelist
71
	 */
72 2
	public function rewind()
73
	{
74 2
		$this->_current = 0;
75 2
		return $this;
76
	}
77
78
	/**
79
	 * Implementation of the Iterator interface
80
	 *
81
	 * @return  Node
82
	 */
83 2
	public function current()
84
	{
85 2
		$ids = $this->list_ids();
86 2
		return $this->_load($ids[$this->_current]);
87
	}
88
89
	/**
90
	 * Implementation of the Iterator interface
91
	 * @return  int
92
	 */
93 1
	public function key()
94
	{
95 1
		return $this->_current;
96
	}
97
98
	/**
99
	 * Implementation of the Iterator interface
100
	 * @return  Nodelist
101
	 */
102 2
	public function next()
103
	{
104 2
		++$this->_current;
105 2
		return $this;
106
	}
107
108
	/**
109
	 * Implementation of the Iterator interface
110
	 *
111
	 * @return  boolean
112
	 */
113 2
	public function valid()
114
	{
115 2
		return $this->offsetExists($this->_current);
116
	}
117
118
	/**
119
	 * Implementation of the Countable interface
120
	 *
121
	 * @return  int
122
	 */
123 3
	public function count()
124
	{
125 3
		return count($this->list_ids());
126
	}
127
128
	/**
129
	 * Implementation of SeekableIterator
130
	 *
131
	 * @param   mixed  $offset
132
	 * @return  boolean
133
	 */
134 1
	public function seek($offset)
135
	{
136 1
		if ($this->offsetExists($offset))
137
		{
138 1
			$this->_current = $offset;
139 1
			return TRUE;
140
		}
141 1
		return FALSE;
142
	}
143
144
	/**
145
	 * ArrayAccess: offsetExists
146
	 *
147
	 * @param   mixed  $offset
148
	 * @return  boolean
149
	 */
150 3
	public function offsetExists($offset)
151
	{
152 3
		return ($offset >= 0 AND $offset < $this->count());
153
	}
154
155
	/**
156
	 * ArrayAccess: offsetGet
157
	 *
158
	 * @param   mixed  $offset
159
	 * @return  Node
160
	 */
161 1
	public function offsetGet($offset)
162
	{
163 1
		if ( ! $this->offsetExists($offset))
164
			return NULL;
165 1
		$ids = $this->list_ids();
166 1
		return $this->_load($ids[$offset]);
167
	}
168
169
	/**
170
	 * ArrayAccess: offsetSet
171
	 *
172
	 * @throws  Kohana_Exception
173
	 * @param   mixed  $offset
174
	 * @param   mixed  $value
175
	 * @return  void
176
	 */
177 1
	public function offsetSet($offset, $value)
178
	{
179 1
		throw new Exception('Cannot modify Nodelist');
180
	}
181
182
	/**
183
	 * ArrayAccess: offsetUnset
184
	 *
185
	 * @throws  Kohana_Exception
186
	 * @param   mixed  $offset
187
	 * @return  void
188
	 */
189 1
	public function offsetUnset($offset)
190
	{
191 1
		throw new Exception('Cannot modify Nodelist');
192
	}
193
194 14
	protected function _load($id)
195
	{
196 14
		return $this->_node->load_new_id($id);
197
	}
198
199 15
	protected function list_ids()
200
	{
201 15
		if ($this->_list_ids === NULL)
202
		{
203 15
			$this->_list_ids = (array) $this->_driver->all($this->_locator->xpath(), $this->_parent->id());
204
205 15
			if ($this->_locator->filters())
206
			{
207 2
				foreach ($this->_list_ids as $offset => $id)
208
				{
209 2
					if ( ! $this->_locator->is_filtered($this->_load($id), $offset))
210
					{
211 2
						unset($this->_list_ids[$offset]);
212
					}
213
				}
214
			}
215
		}
216
217 15
		return $this->_list_ids;
218
	}
219
220 2
	public function locator()
221
	{
222 2
		return $this->_locator;
223
	}
224
225 1
	public function driver()
226
	{
227 1
		return $this->_driver;
228
	}
229
230 12
	public function first()
231
	{
232 12
		$ids = $this->list_ids();
233
234 12
		if (count($ids) <= 0)
235 3
			return NULL;
236
237 12
		return $this->_load(reset($ids));
238
	}
239
240 1
	public function last()
241
	{
242 1
		$ids = $this->list_ids();
243
244 1
		if (count($ids) <= 0)
245
			return NULL;
246
247 1
		return $this->_load(end($ids));
248
	}
249
250 1
	public function as_array()
251
	{
252 1
		$nodes = array();
253 1
		foreach ($this->list_ids() as $i => $id)
254
		{
255 1
			$nodes[] = new Node($this->_driver, $this->_parent, $id);
256
		}
257 1
		return $nodes;
258
	}
259
260
}
261