ActiveRecordQuery::getIterator()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * This file is part of the miBadger package.
5
 *
6
 * @author Michael Webbers <[email protected]>
7
 * @license http://opensource.org/licenses/Apache-2.0 Apache v2 License
8
 */
9
10
namespace miBadger\ActiveRecord;
11
12
use miBadger\Query\Query;
13
use miBadger\Query\QueryInterface;
14
use miBadger\Query\QueryExpression;
15
16
/**
17
 * The active record exception class.
18
 *
19
 * @since 2.0.0
20
 */
21
class ActiveRecordQuery implements \IteratorAggregate
22
{
23
	private $instance;
24
25
	private $query;
26
27
	private $type;
28
29
	private $clauses = [];
30
31
	private $maxresultCount;
0 ignored issues
show
introduced by
The private property $maxresultCount is not used, and could be removed.
Loading history...
32
33
	private $results;
34
	
35
	private $whereExpression = null;
36
37
	private $limit;
38
39
	private $offset;
40
41
	private $orderBy;
0 ignored issues
show
introduced by
The private property $orderBy is not used, and could be removed.
Loading history...
42
43
	private $orderDirection;
0 ignored issues
show
introduced by
The private property $orderDirection is not used, and could be removed.
Loading history...
44
45
	/**
46
	 * Constructs a new Active Record Query
47
	 */
48 19
	public function __construct(AbstractActiveRecord $instance, Array $additionalWhereClauses)
49
	{
50 19
		$this->instance = $instance;
51 19
		$this->query = new Query($instance->getPdo(), $instance->getTableName());
52 19
		$this->type = $instance;
53 19
		$this->clauses = $additionalWhereClauses;
54 19
		$this->maxResultCount = null;
0 ignored issues
show
Bug Best Practice introduced by
The property maxResultCount does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
55 19
		$this->results = null;
56 19
		$this->limit = null;
57 19
		$this->offset = null;
58 19
	}
59
60 18
	private function getWhereCondition()
61
	{
62 18
		$clauses = $this->clauses;
63
64
		// Optionally add user concatenated where expression
65 18
		if ($this->whereExpression !== null) {
66 10
			$clauses[] = $this->whereExpression;
67
		}
68
69
		// Construct where clause
70 18
		if (count($clauses) > 0) {
71 11
			return Query::AndArray($clauses);
72
		}
73 7
		return null;
74
	}
75
76
	/**
77
	 * Executes the query
78
	 */
79 17
	public function execute()
80
	{
81 17
		$whereCondition = $this->getWhereCondition();
82 17
		if ($whereCondition !== null) {
83 11
			$this->query->where($whereCondition);
84
		}
85
86 17
		$this->query->select();
87
88 17
		$this->results = $this->query->execute();
89
90 14
		return $this;
91
	}
92
93
	/**
94
	 * Returns an iterator for the result set
95
	 * @return ArrayIterator
0 ignored issues
show
Bug introduced by
The type miBadger\ActiveRecord\ArrayIterator was not found. Did you mean ArrayIterator? If so, make sure to prefix the type with \.
Loading history...
96
	 */
97
	public function getIterator()
98
	{
99
		return new \ArrayIterator($this->fetchAll());
100
	}
101
102
	/**
103
	 * returns the result set of ActiveRecord instances for this query
104
	 * @return Array
105
	 */
106 14
	public function fetchAll()
107
	{
108
		try {
109 14
			if ($this->results === null) {
110 14
				$this->execute();	
111
			}
112
113 12
			$entries = $this->results->fetchAll();
114 12
			if ($entries === false) {
115
				return [];
116
			}
117
118 12
			$typedResults = [];
119 12
			foreach ($entries as $entry) {
120 12
				$typedEntry = $this->type->newInstance();
121 12
				$typedEntry->fill($entry);
122 12
				$typedResults[] = $typedEntry;
123
			}
124
125 12
			return $typedResults;
126 2
		} catch (\PDOException $e) {
127 2
			throw new ActiveRecordException($e->getMessage(), 0, $e);
128
		}
129
	}
130
131
	public function fetchAllAsArray($readWhitelist)
132
	{
133
		$data = $this->fetchAll();
134
		$output = [];
135
		foreach ($data as $entry) {
136
			$output[] = $entry->toArray($readWhitelist);
137
		}
138
		return $output;
139
	}
140
141
	/**
142
	 * Fetch one record from the database
143
	 * @return AbstractActiveRecord 
144
	 */
145 3
	public function fetch()
146
	{
147
		try {
148 3
			if ($this->results === null) {
149 3
				$this->execute();
150
			}
151
152 2
			$typedResult = $this->type->newInstance();
153
154 2
			$entry = $this->results->fetch();
155 2
			if ($entry === false) {
156 1
				return null;
157
			}
158
159 1
			$typedResult->fill($entry);
160
161 1
			return $typedResult;
162 1
		} catch (\PDOException $e) {
163 1
			throw new ActiveRecordException($e->getMessage(), 0, $e);
164
		}
165
	}
166
167
	/**
168
	 * Fetch one record from the database and format it as an associative array, 
169
	 * 	 filtered by the entries in $readwhitelist
170
	 * @param Array $readWhitelist Array of whitelisted database column keys to be returned in the result
171
	 * @return Array|Null
172
	 */
173
	public function fetchAsArray($readWhitelist)
174
	{
175
		$res = $this->fetch();
176
		if ($res !== null) {
177
			return $res->toArray($readWhitelist);
178
		}
179
		return null;
180
	}
181
182 2
	public function countMaxResults()
183
	{
184 2
		if ($this->maxResultCount === null) {
185 2
			$query = new Query($this->instance->getPdo(), $this->instance->getTableName());
186 2
			$query->select(['count(*) as count'], false);
187
188 2
			$whereCondition = $this->getWhereCondition();
189 2
			if ($whereCondition !== null) {
190 1
				$query->where($whereCondition);
191
			}
192
193 2
			$this->maxResultCount = $query->execute()->fetch()['count'];
0 ignored issues
show
Bug Best Practice introduced by
The property maxResultCount does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
194
		}
195 2
		return $this->maxResultCount;
196
	}
197
198 1
	public function getNumberOfPages()
199
	{
200 1
		if ($this->limit === null) {
201
			return 1;
202
		}
203
204 1
		if ($this->limit === 0) {
205
			return 0;
206
		}
207
208 1
		$resultCount = $this->countMaxResults();
209 1
		if ($resultCount % $this->limit > 0) {
210 1
			return (int) floor($resultCount / $this->limit) + 1;
211
		}
212 1
		return (int) floor($resultCount / $this->limit);
213
	}
214
215 1
	public function getCurrentPage()
216
	{
217 1
		if ($this->offset === null || $this->offset === 0) {
218 1
			return 1;
219
		}
220
221
		if ($this->limit === null || $this->limit === 0) {
222
			return 1;
223
		}
224
225
		return (int) floor($this->offset / $this->limit);
226
	}
227
228
	/**
229
	 * Set the where condition
230
	 *
231
	 * @param QueryExpression $expression the query expression
232
	 * @return $this
233
	 * @see https://en.wikipedia.org/wiki/SQL#Operators
234
	 * @see https://en.wikipedia.org/wiki/Where_(SQL)
235
	 */
236 10
	public function where(QueryExpression $expression)
237
	{
238 10
		$this->whereExpression = $expression;
239 10
		return $this;
240
	}
241
242
	/**
243
	 * Set an additional group by.
244
	 *
245
	 * @param string $column
246
	 * @return $this
247
	 * @see https://en.wikipedia.org/wiki/SQL#Queries
248
	 */
249
	public function groupBy(string $column)
250
	{
251
		$this->query->groupBy($column);
252
		return $this;
253
	}
254
255
	/**
256
	 * Set an additional order condition.
257
	 *
258
	 * @param string $column
259
	 * @param string|null $order
260
	 * @return $this
261
	 * @see https://en.wikipedia.org/wiki/SQL#Queries
262
	 * @see https://en.wikipedia.org/wiki/Order_by
263
	 */
264 2
	public function orderBy(string $column, $order = null)
265
	{
266 2
		$this->query->orderBy($column, $order);	
267 2
		return $this;
268
	}
269
270
	/**
271
	 * Set the limit.
272
	 *
273
	 * @param mixed $limit
274
	 * @return $this
275
	 */
276 4
	public function limit($limit)
277
	{
278 4
		$this->limit = $limit;
279 4
		$this->query->limit($limit);
280 4
		return $this;
281
	}
282
283
	/**
284
	 * Set the offset.
285
	 *
286
	 * @param mixed $offset
287
 	 * @return $this
288
	 */
289 2
	public function offset($offset)
290
	{
291 2
		$this->offset = $offset;
292 2
		$this->query->offset($offset);
293 2
		return $this;
294
	}
295
}
296