SystemLogQuery::buildQuery()   F
last analyzed

Complexity

Conditions 13
Paths 2048

Size

Total Lines 49
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 23.816

Importance

Changes 0
Metric Value
cc 13
eloc 24
nc 2048
nop 1
dl 0
loc 49
ccs 15
cts 25
cp 0.6
crap 23.816
rs 2.45
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Elgg\SystemLog;
4
5
use Doctrine\DBAL\Query\Expression\CompositeExpression;
6
use Elgg\Database\QueryBuilder;
7
use Elgg\Database\Repository;
8
use Elgg\Database\Select;
9
use Elgg\Exceptions\Exception;
10
use Elgg\Values;
11
12
/**
13
 * System Log database table query
14
 */
15
class SystemLogQuery extends Repository {
16
17
	/**
18
	 * @var int[]
19
	 */
20
	public $id;
21
22
	/**
23
	 * @var int[]
24
	 */
25
	public $object_id;
26
27
	/**
28
	 * @var string[]
29
	 */
30
	public $object_class;
31
32
	/**
33
	 * @var string[]
34
	 */
35
	public $object_type;
36
37
	/**
38
	 * @var string[]
39
	 */
40
	public $object_subtype;
41
42
	/**
43
	 * @var string[]
44
	 */
45
	public $event;
46
47
	/**
48
	 * @var int[]
49
	 */
50
	public $performed_by_guid;
51
52
	/**
53
	 * @var int[]
54
	 */
55
	public $owner_guid;
56
	
57
	/**
58
	 * @var int[]
59
	 */
60
	public $access_id;
61
	
62
	/**
63
	 * @var string
64
	 */
65
	public $enabled;
66
	
67
	/**
68
	 * @var int|string|\DateTime
69
	 */
70
	public $created_after;
71
72
	/**
73
	 * @var int|string|\DateTime
74
	 */
75
	public $created_before;
76
77
	/**
78
	 * @var string[]
79
	 */
80
	public $ip_address;
81
82
	/**
83
	 * @var int
84
	 */
85
	public $limit;
86
87
	/**
88
	 * @var int
89
	 */
90
	public $offset;
91
92
	/**
93
	 * @var callable
94
	 */
95
	public $callback;
96
97
	/**
98
	 * Count rows
99
	 *
100
	 * @return int
101
	 */
102
	public function count(): int {
103
		$this->normalizeOptions();
104
105
		$qb = Select::fromTable('system_log');
106
		$qb->select('COUNT(*) as total');
107
		$wheres = $this->buildQuery($qb);
108
		if ($wheres) {
109
			$qb->where($wheres);
110
		}
111
112
		$result = _elgg_services()->db->getDataRow($qb);
113
		if (empty($result)) {
114
			return 0;
115
		}
116
117
		return (int) $result->total;
118
	}
119
120
	/**
121
	 * Apply numeric calculation to a column
122
	 *
123
	 * @param string $function      Calculation, e.g. max, min, avg
124
	 * @param string $property      Property name
125
	 * @param string $property_type Property type
126
	 *
127
	 * @return int|float
128
	 * @throws Exception
129
	 */
130
	public function calculate($function, $property, $property_type = null) {
131
		throw new Exception(__METHOD__ . ' not implemented');
132
	}
133
134
	/**
135
	 * Fetch rows
136
	 *
137
	 * @param int            $limit    Number of rows to fetch
138
	 * @param int            $offset   Index of the first row
139
	 * @param callable|false $callback Callback function to run database rows through
140
	 *
141
	 * @return \ElggData[]|false
142
	 */
143 2
	public function get($limit = null, $offset = null, $callback = null) {
144
145 2
		$this->normalizeOptions();
146
147 2
		$qb = Select::fromTable('system_log');
148 2
		$qb->select('*');
149 2
		$wheres = $this->buildQuery($qb);
150 2
		if ($wheres) {
151 1
			$qb->where($wheres);
152
		}
153
154 2
		$limit = (int) $limit;
155 2
		if ($limit > 0) {
156
			$qb->setMaxResults($limit);
157
			$qb->setFirstResult((int) $offset);
158
		}
159
160 2
		$qb->orderBy('time_created', 'DESC');
161 2
		$qb->addOrderBy('id', 'DESC');
162
163 2
		return _elgg_services()->db->getData($qb, $this->callback);
164
	}
165
166
	/**
167
	 * Apply correct execution method based on calculation, count or other criteria
168
	 *
169
	 * @return mixed
170
	 */
171 2
	public function execute() {
172
173 2
		if ($this->count) {
174
			return $this->count();
175
		}
176
177 2
		return $this->get($this->limit, $this->offset);
178
	}
179
180
	/**
181
	 * Normalizes options
182
	 *
183
	 * @return void
184
	 */
185 2
	protected function normalizeOptions(): void {
186 2
		$defaults = [
187 2
			'limit' => elgg_get_config('default_limit'),
188 2
			'offset' => 0,
189 2
		];
190
191 2
		foreach ($defaults as $key => $value) {
192 2
			if (!isset($this->$key)) {
193 2
				$this->$key = $value;
194
			}
195
		}
196
197 2
		if (!elgg_is_empty($this->performed_by_guid)) {
198
			$this->performed_by_guid = Values::normalizeGuids($this->performed_by_guid);
199
		}
200
		
201 2
		if (!elgg_is_empty($this->owner_guid)) {
202
			$this->owner_guid = Values::normalizeGuids($this->owner_guid);
203
		}
204
		
205 2
		if (!elgg_is_empty($this->object_id)) {
206
			$this->object_id = Values::normalizeIds($this->object_id);
207
		}
208
		
209 2
		if (!elgg_is_empty($this->access_id)) {
210
			$this->access_id = Values::normalizeIds($this->access_id);
211
		}
212
		
213 2
		if (!elgg_is_empty($this->created_after)) {
214
			$this->created_after = Values::normalizeTimestamp($this->created_after);
215
		}
216
		
217 2
		if (!elgg_is_empty($this->created_before)) {
218
			$this->created_before = Values::normalizeTimestamp($this->created_before);
219
		}
220
	}
221
222
	/**
223
	 * Build where clauses
224
	 *
225
	 * @param QueryBuilder $qb Query builder
226
	 *
227
	 * @return CompositeExpression|string
228
	 */
229 2
	protected function buildQuery(QueryBuilder $qb) {
230
231 2
		$wheres = [];
232
233 2
		if (!elgg_is_empty($this->performed_by_guid)) {
234
			$wheres[] = $qb->compare('performed_by_guid', '=', $this->performed_by_guid, ELGG_VALUE_INTEGER);
235
		}
236
		
237 2
		if (!elgg_is_empty($this->event)) {
238 1
			$wheres[] = $qb->compare('event', '=', $this->event, ELGG_VALUE_STRING);
239
		}
240
		
241 2
		if (!elgg_is_empty($this->object_id)) {
242
			$wheres[] = $qb->compare('object_id', '=', $this->object_id, ELGG_VALUE_INTEGER);
243
		}
244
		
245 2
		if (!elgg_is_empty($this->object_class)) {
246
			$wheres[] = $qb->compare('object_class', '=', $this->object_class, ELGG_VALUE_STRING);
247
		}
248
		
249 2
		if (!elgg_is_empty($this->object_type)) {
250
			$wheres[] = $qb->compare('object_type', '=', $this->object_type, ELGG_VALUE_STRING);
251
		}
252
		
253 2
		if (!elgg_is_empty($this->object_subtype)) {
254
			$wheres[] = $qb->compare('object_subtype', '=', $this->object_subtype, ELGG_VALUE_STRING);
255
		}
256
		
257 2
		if (!elgg_is_empty($this->ip_address)) {
258
			$wheres[] = $qb->compare('ip_address', '=', $this->ip_address, ELGG_VALUE_STRING);
259
		}
260
		
261 2
		if (!elgg_is_empty($this->owner_guid)) {
262
			$wheres[] = $qb->compare('owner_guid', '=', $this->owner_guid, ELGG_VALUE_INTEGER);
263
		}
264
		
265 2
		if (!elgg_is_empty($this->access_id)) {
266
			$wheres[] = $qb->compare('access_id', '=', $this->access_id, ELGG_VALUE_INTEGER);
267
		}
268
		
269 2
		if (!elgg_is_empty($this->enabled)) {
270
			$wheres[] = $qb->compare('enabled', '=', $this->enabled, ELGG_VALUE_STRING);
271
		}
272
		
273 2
		if (!elgg_is_empty($this->created_before) || !elgg_is_empty($this->created_after)) {
274
			$wheres[] = $qb->between('time_created', $this->created_after, $this->created_before, ELGG_VALUE_INTEGER);
275
		}
276
277 2
		return $qb->merge($wheres);
278
	}
279
280
	/**
281
	 * Set callback to use on DB rows after fetch
282
	 *
283
	 * @param callable $callback Callback
284
	 *
285
	 * @return void
286
	 */
287 2
	public function setCallback(callable $callback): void {
288 2
		$this->callback = $callback;
289
	}
290
}
291