1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Created by PhpStorm. |
4
|
|
|
* User: VITALYIEGOROV |
5
|
|
|
* Date: 11.12.15 |
6
|
|
|
* Time: 17:35 |
7
|
|
|
*/ |
8
|
|
|
namespace samsoncms\api\query; |
9
|
|
|
|
10
|
|
|
use samson\activerecord\dbQuery; |
11
|
|
|
use samsoncms\api\CMS; |
12
|
|
|
use samsoncms\api\exception\EntityFieldNotFound; |
13
|
|
|
use samsoncms\api\generated\Field; |
14
|
|
|
use samsoncms\api\generated\Material; |
15
|
|
|
use samsonframework\orm\Argument; |
16
|
|
|
use samsonframework\orm\ArgumentInterface; |
17
|
|
|
use samsonframework\orm\Condition; |
18
|
|
|
use samsonframework\orm\ConditionInterface; |
19
|
|
|
use samsonframework\orm\QueryInterface; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Generic SamsonCMS Entity query. |
23
|
|
|
* @package samsoncms\api\query |
24
|
|
|
*/ |
25
|
|
|
class Entity extends Generic |
26
|
|
|
{ |
27
|
|
|
/** @var array Collection of all additional fields names */ |
28
|
|
|
public static $fieldNames = array(); |
29
|
|
|
|
30
|
|
|
/** @var array Collection of localized additional fields identifiers */ |
31
|
|
|
public static $localizedFieldIDs = array(); |
32
|
|
|
|
33
|
|
|
/** @var array Collection of NOT localized additional fields identifiers */ |
34
|
|
|
public static $notLocalizedFieldIDs = array(); |
35
|
|
|
|
36
|
|
|
/** @var array Collection of all additional fields identifiers */ |
37
|
|
|
public static $fieldIDs = array(); |
38
|
|
|
|
39
|
|
|
/** @var @var array Collection of additional fields value column names */ |
40
|
|
|
public static $fieldValueColumns = array(); |
41
|
|
|
|
42
|
|
|
/** @var Condition Collection of entity field filter */ |
43
|
|
|
protected $fieldFilter = array(); |
44
|
|
|
|
45
|
|
|
/** @var string Query locale */ |
46
|
|
|
protected $locale = ''; |
47
|
|
|
|
48
|
|
|
/** @var array Collection of additional fields for ordering */ |
49
|
|
|
protected $entityOrderBy = array(); |
50
|
|
|
|
51
|
|
|
/** @var array Collection of search fields for query */ |
52
|
|
|
protected $searchFilter = array(); |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Generic constructor. |
56
|
|
|
* |
57
|
|
|
* @param QueryInterface $query Database query instance |
58
|
|
|
* @param string $locale Query localization |
59
|
|
|
*/ |
60
|
|
|
public function __construct(QueryInterface $query = null, $locale = null) |
61
|
|
|
{ |
62
|
|
|
$this->locale = $locale; |
63
|
|
|
|
64
|
|
|
parent::__construct(null === $query ? new dbQuery() : $query); |
65
|
|
|
|
66
|
|
|
// Work only with active entities |
67
|
|
|
$this->active(true); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* Select specified entity fields. |
72
|
|
|
* If this method is called then only selected entity fields |
73
|
|
|
* would be filled in entity instances. |
74
|
|
|
* |
75
|
|
|
* @param mixed $fieldNames Entity field name or collection of names |
76
|
|
|
* |
77
|
|
|
*@return $this Chaining |
78
|
|
|
*/ |
79
|
|
View Code Duplication |
public function select($fieldNames) |
|
|
|
|
80
|
|
|
{ |
81
|
|
|
// Convert argument to array and iterate |
82
|
|
|
foreach ((!is_array($fieldNames) ? array($fieldNames) : $fieldNames) as $fieldName) { |
83
|
|
|
// Try to find entity additional field |
84
|
|
|
$pointer = &static::$virtualFieldNames[$fieldName]; |
85
|
|
|
if (null !== $pointer) { |
86
|
|
|
// Store selected additional field buy FieldID and Field name |
87
|
|
|
$this->selectedFields[$pointer] = $fieldName; |
88
|
|
|
} |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
return $this; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Set additional field for sorting. |
96
|
|
|
* |
97
|
|
|
* @param string $fieldName Additional field name |
98
|
|
|
* @param string $order Sorting order |
99
|
|
|
* @return $this Chaining |
100
|
|
|
*/ |
101
|
|
|
public function orderBy($fieldName, $order = 'ASC') |
102
|
|
|
{ |
103
|
|
|
if (array_key_exists($fieldName, static::$virtualFieldNames)) { |
104
|
|
|
$this->entityOrderBy = array($fieldName, $order); |
105
|
|
|
} else { |
106
|
|
|
parent::orderBy($fieldName, $order); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
return $this; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Search entity fields by text. |
114
|
|
|
* |
115
|
|
|
* @param string $text Searching text |
116
|
|
|
* @return $this |
117
|
|
|
*/ |
118
|
|
|
public function search($text) |
119
|
|
|
{ |
120
|
|
|
$this->searchFilter[] = $text; |
121
|
|
|
|
122
|
|
|
return $this; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* Set resulting query limits. |
127
|
|
|
* |
128
|
|
|
* @param integer $offset Starting index |
129
|
|
|
* @param integer|null $count Entities count |
130
|
|
|
* @return $this Chaining |
131
|
|
|
*/ |
132
|
|
|
public function limit($offset, $count = null) |
133
|
|
|
{ |
134
|
|
|
$this->limit = array($offset, $count); |
135
|
|
|
|
136
|
|
|
return $this; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Perform SamsonCMS query and get collection of entities. |
141
|
|
|
* |
142
|
|
|
* @param int $page Page number |
143
|
|
|
* @param int $size Page size |
144
|
|
|
* |
145
|
|
|
* @return \samsoncms\api\Entity[] Collection of entity fields |
146
|
|
|
*/ |
147
|
|
|
public function find($page = null, $size = null) |
148
|
|
|
{ |
149
|
|
|
$return = array(); |
150
|
|
|
if (count($this->entityIDs = $this->findEntityIDs())) { |
151
|
|
|
// Apply search filter |
152
|
|
|
if (count($this->searchFilter)) { |
153
|
|
|
$this->entityIDs = $this->applySearch($this->entityIDs); |
154
|
|
|
|
155
|
|
|
// Return result if not ids |
156
|
|
|
if (count($this->entityIDs) === 0) { |
157
|
|
|
return $return; |
158
|
|
|
} |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
// Slice identifier array to match pagination |
162
|
|
|
if (null !== $page && null !== $size) { |
163
|
|
|
$this->entityIDs = array_slice($this->entityIDs, ($page - 1) * $size, $size); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
// Perform parent find() only if we have entity identifiers |
167
|
|
|
if (count($this->entityIDs)) { |
168
|
|
|
// Get entity additional field records |
169
|
|
|
$additionalFields = $this->findAdditionalFields($this->entityIDs); |
170
|
|
|
|
171
|
|
|
/** @var \samsoncms\api\Entity $item Find entity instances */ |
172
|
|
|
foreach (parent::find() as $item) { |
173
|
|
|
// Fill entity with additional fields |
174
|
|
|
$item = $this->fillEntityFields($item, $additionalFields); |
175
|
|
|
|
176
|
|
|
// Store entity by identifier |
177
|
|
|
$return[$item[Material::F_PRIMARY]] = $item; |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
//elapsed('Finish SamsonCMS '.static::$identifier.' query'); |
183
|
|
|
|
184
|
|
|
return $return; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* Prepare entity identifiers. |
189
|
|
|
* |
190
|
|
|
* @param array $entityIDs Collection of identifier for filtering |
191
|
|
|
* @return array Collection of entity identifiers |
192
|
|
|
*/ |
193
|
|
|
protected function findEntityIDs(array $entityIDs = array()) |
194
|
|
|
{ |
195
|
|
|
// TODO: Find and describe approach with maximum generic performance |
196
|
|
|
|
197
|
|
|
// Apply additional fields filtering first |
198
|
|
|
if (count($this->fieldFilter)) { |
199
|
|
|
$entityIDs = $this->findByAdditionalFields($this->fieldFilter, $entityIDs); |
|
|
|
|
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
// Apply navigation filtering secondly |
203
|
|
|
if (count($entityIDs) || !count($this->fieldFilter)) { |
204
|
|
|
$entityIDs = $this->findByNavigationIDs($entityIDs); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
// TODO: Possible performance issue - from generated queries we are passing Active true and get all materials from DB |
208
|
|
|
if ($this->conditions) { |
209
|
|
|
$entityIDs = $this->query |
210
|
|
|
->entity(Material::ENTITY) |
211
|
|
|
->where(Material::F_PRIMARY, $entityIDs) |
212
|
|
|
->whereCondition($this->conditions) |
213
|
|
|
->fields(Material::F_PRIMARY); |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
// Perform sorting if necessary |
217
|
|
View Code Duplication |
if (count($this->entityOrderBy) === 2) { |
|
|
|
|
218
|
|
|
$entityIDs = $this->applySorting($entityIDs, $this->entityOrderBy[0], $this->entityOrderBy[1]); |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
// Perform sorting in parent fields if necessary |
222
|
|
View Code Duplication |
if (count($this->orderBy) === 2) { |
|
|
|
|
223
|
|
|
$entityIDs = $this->applySorting($entityIDs, $this->orderBy[0], $this->orderBy[1]); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
// Perform limits if necessary |
227
|
|
|
if (count($this->limit)) { |
228
|
|
|
$entityIDs = array_slice($entityIDs, $this->limit[0], $this->limit[1]); |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
return $entityIDs; |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
/** |
235
|
|
|
* Get collection of entity identifiers filtered by additional field and its value. |
236
|
|
|
* |
237
|
|
|
* @param Condition[] $additionalFields Collection of additional field identifiers => values |
238
|
|
|
* @param array $entityIDs Additional collection of entity identifiers for filtering |
239
|
|
|
* @return array Collection of material identifiers by navigation identifiers |
240
|
|
|
*/ |
241
|
|
|
protected function findByAdditionalFields($additionalFields, $entityIDs = array()) |
242
|
|
|
{ |
243
|
|
|
/** |
244
|
|
|
* TODO: We have separate request to materialfield for each field, maybe faster to |
245
|
|
|
* make one single query with all fields conditions. Performance tests are needed. |
246
|
|
|
*/ |
247
|
|
|
|
248
|
|
|
/** @var Condition $fieldCondition Iterate all additional fields needed for filter condition */ |
249
|
|
|
foreach ($additionalFields as $fieldID => $fieldCondition) { |
250
|
|
|
// Get collection of entity identifiers passing already found identifiers |
251
|
|
|
$entityIDs = (new MaterialField($entityIDs))->idsByRelationID($fieldID, $fieldCondition, array(), $this->locale); |
252
|
|
|
|
253
|
|
|
// Stop execution if we have no entities found at this step |
254
|
|
|
if (!count($entityIDs)) { |
255
|
|
|
break; |
256
|
|
|
} |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
return $entityIDs; |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* Get collection of entity identifiers filtered by navigation identifiers. |
264
|
|
|
* |
265
|
|
|
* @param array $entityIDs Additional collection of entity identifiers for filtering |
266
|
|
|
* |
267
|
|
|
* @return array Collection of material identifiers by navigation identifiers |
268
|
|
|
*/ |
269
|
|
|
protected function findByNavigationIDs($entityIDs = array()) |
270
|
|
|
{ |
271
|
|
|
return (new MaterialNavigation($entityIDs))->idsByRelationID(static::$navigationIDs); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* Add sorting to entity identifiers. |
276
|
|
|
* |
277
|
|
|
* @param array $entityIDs |
278
|
|
|
* @param string $fieldName Additional field name for sorting |
279
|
|
|
* @param string $order Sorting order(ASC|DESC) |
280
|
|
|
* @return array Collection of entity identifiers ordered by additional field value |
281
|
|
|
*/ |
282
|
|
|
protected function applySorting(array $entityIDs, $fieldName, $order = 'ASC') |
283
|
|
|
{ |
284
|
|
|
if (array_key_exists($fieldName, static::$virtualFieldNames)) { |
285
|
|
|
// Get additional field metadata |
286
|
|
|
$fieldID = static::$virtualFieldNames[$fieldName]; |
287
|
|
|
$valueColumn = static::$virtualFieldValueColumns[$fieldID]; |
288
|
|
|
|
289
|
|
|
return $this->query |
290
|
|
|
->entity(CMS::MATERIAL_FIELD_RELATION_ENTITY) |
291
|
|
|
->where(Field::F_PRIMARY, $fieldID) |
292
|
|
|
->where(Material::F_PRIMARY, $entityIDs) |
293
|
|
|
->orderBy($valueColumn, $order) |
294
|
|
|
->fields(Material::F_PRIMARY); |
295
|
|
|
} else { // Nothing is changed |
296
|
|
|
return parent::applySorting($entityIDs, $fieldName, $order); |
297
|
|
|
} |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
/** |
301
|
|
|
* Get entities additional field values. |
302
|
|
|
* |
303
|
|
|
* @param array $entityIDs Collection of entity identifiers |
304
|
|
|
* @return array Collection of entities additional fields EntityID => [Additional field name => Value] |
305
|
|
|
* @throws EntityFieldNotFound |
306
|
|
|
*/ |
307
|
|
|
protected function findAdditionalFields($entityIDs) |
308
|
|
|
{ |
309
|
|
|
$return = array(); |
310
|
|
|
|
311
|
|
|
// Copy fields arrays |
312
|
|
|
$localized = static::$localizedFieldIDs; |
313
|
|
|
$notLocalized = static::$notLocalizedFieldIDs; |
314
|
|
|
|
315
|
|
|
// If we filter additional fields that we need to receive |
316
|
|
|
if (count($this->selectedFields)) { |
317
|
|
|
foreach ($this->selectedFields as $fieldID => $fieldName) { |
318
|
|
|
// Filter localized and not fields by selected fields |
319
|
|
|
if (!isset(static::$localizedFieldIDs[$fieldID])) { |
320
|
|
|
unset($localized[$fieldID]); |
321
|
|
|
} |
322
|
|
|
|
323
|
|
|
if (!isset(static::$notLocalizedFieldIDs[$fieldID])) { |
324
|
|
|
unset($notLocalized[$fieldID]); |
325
|
|
|
} |
326
|
|
|
} |
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
// Prepare localized additional field query condition |
330
|
|
|
$condition = new Condition(Condition::DISJUNCTION); |
331
|
|
|
foreach ($localized as $fieldID => $fieldName) { |
332
|
|
|
$condition->addCondition( |
333
|
|
|
(new Condition()) |
334
|
|
|
->add(Field::F_PRIMARY, $fieldID) |
335
|
|
|
->add(\samsoncms\api\MaterialField::F_LOCALE, $this->locale) |
336
|
|
|
); |
337
|
|
|
} |
338
|
|
|
|
339
|
|
|
// Prepare not localized fields condition |
340
|
|
|
foreach ($notLocalized as $fieldID => $fieldName) { |
341
|
|
|
$condition->add(Field::F_PRIMARY, $fieldID); |
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
// Get additional fields values for current entity identifiers |
345
|
|
|
foreach ($this->query->entity(CMS::MATERIAL_FIELD_RELATION_ENTITY) |
|
|
|
|
346
|
|
|
->where(Material::F_PRIMARY, $entityIDs) |
347
|
|
|
->whereCondition($condition) |
348
|
|
|
->where(Material::F_DELETION, true) |
349
|
|
|
->exec() as $additionalField |
350
|
|
|
) { |
351
|
|
|
// Get needed metadata |
352
|
|
|
$fieldID = $additionalField[Field::F_PRIMARY]; |
353
|
|
|
$materialID = $additionalField[Material::F_PRIMARY]; |
354
|
|
|
$valueField = &static::$virtualFieldValueColumns[$fieldID]; |
355
|
|
|
$fieldName = &static::$virtualFieldIDs[$fieldID]; |
356
|
|
|
|
357
|
|
|
// Check if we have this additional field in this entity query |
358
|
|
|
if (null === $valueField || null === $fieldName) { |
359
|
|
|
throw new EntityFieldNotFound($fieldID); |
360
|
|
|
} else { // Add field value to result |
361
|
|
|
$fieldValue = $additionalField[$valueField]; |
362
|
|
|
// Gather additional fields values by entity identifiers and field name |
363
|
|
|
$return[$materialID][$fieldName] = $fieldValue; |
364
|
|
|
} |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
return $return; |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
/** |
371
|
|
|
* @param array $entityIDs |
372
|
|
|
* |
373
|
|
|
* @return array |
374
|
|
|
*/ |
375
|
|
|
protected function applySearch(array $entityIDs) |
376
|
|
|
{ |
377
|
|
|
$condition = new Condition(ConditionInterface::DISJUNCTION); |
378
|
|
|
|
379
|
|
|
foreach ($this->searchFilter as $searchText) { |
380
|
|
|
foreach (static::$fieldValueColumns as $fieldId => $fieldColumn) { |
381
|
|
|
$condition->addCondition((new Condition()) |
382
|
|
|
->addArgument(new Argument($fieldColumn, '%' . $searchText . '%', ArgumentInterface::LIKE)) |
383
|
|
|
->addArgument(new Argument(\samsoncms\api\MaterialField::F_FIELDID, $fieldId))); |
384
|
|
|
} |
385
|
|
|
} |
386
|
|
|
|
387
|
|
|
return $this->query |
388
|
|
|
->entity(\samsoncms\api\MaterialField::class) |
389
|
|
|
->whereCondition($condition) |
390
|
|
|
->where(Material::F_PRIMARY, $entityIDs) |
391
|
|
|
->fields(Material::F_PRIMARY); |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
/** |
395
|
|
|
* Fill entity additional fields. |
396
|
|
|
* |
397
|
|
|
* @param \samsoncms\api\Entity $entity Entity instance for filling |
398
|
|
|
* @param array $additionalFields Collection of additional field values |
399
|
|
|
* @return Entity With filled additional field values |
400
|
|
|
*/ |
401
|
|
|
protected function fillEntityFields($entity, array $additionalFields) |
402
|
|
|
{ |
403
|
|
|
// If we have list of additional fields that we need |
404
|
|
|
$fieldIDs = count($this->selectedFields) ? $this->selectedFields : static::$virtualFieldIDs; |
405
|
|
|
|
406
|
|
|
// Iterate all entity additional fields |
407
|
|
|
foreach ($fieldIDs as $variable) { |
408
|
|
|
// Set only existing additional fields |
409
|
|
|
$pointer = &$additionalFields[$entity->id][$variable]; |
410
|
|
|
if (null !== $pointer) { |
411
|
|
|
$entity->$variable = $pointer; |
412
|
|
|
} |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
return $entity; |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
/** |
419
|
|
|
* Perform SamsonCMS query and get first matching entity. |
420
|
|
|
* |
421
|
|
|
* @return \samsoncms\api\Entity Firt matching entity |
422
|
|
|
*/ |
423
|
|
|
public function first() |
424
|
|
|
{ |
425
|
|
|
$return = null; |
426
|
|
|
if (count($entityIDs = $this->findEntityIDs())) { |
427
|
|
|
$this->primary($entityIDs); |
|
|
|
|
428
|
|
|
$additionalFields = $this->findAdditionalFields($entityIDs); |
429
|
|
|
|
430
|
|
|
if (null !== ($foundEntity = parent::first())) { |
431
|
|
|
$return = $this->fillEntityFields($foundEntity, $additionalFields); |
432
|
|
|
} |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
return $return; |
436
|
|
|
} |
437
|
|
|
|
438
|
|
|
/** |
439
|
|
|
* Perform SamsonCMS query and get collection of entities fields. |
440
|
|
|
* |
441
|
|
|
* @param string $fieldName Entity field name |
442
|
|
|
* @return array Collection of entity fields |
443
|
|
|
* @throws EntityFieldNotFound |
444
|
|
|
*/ |
445
|
|
|
public function fields($fieldName) |
446
|
|
|
{ |
447
|
|
|
$return = array(); |
448
|
|
|
if (count($entityIDs = $this->findEntityIDs())) { |
449
|
|
|
// Check if our entity has this field |
450
|
|
|
$fieldID = &static::$fieldNames[$fieldName]; |
451
|
|
|
if (isset($fieldID)) { |
452
|
|
|
$return = $this->query |
453
|
|
|
->entity(\samsoncms\api\MaterialField::ENTITY) |
454
|
|
|
->where(Material::F_PRIMARY, $entityIDs) |
455
|
|
|
->where(Field::F_PRIMARY, $fieldID) |
456
|
|
|
->where(\samsoncms\api\MaterialField::F_DELETION, true) |
457
|
|
|
->fields(static::$virtualFieldValueColumns[$fieldID]); |
458
|
|
|
} elseif (property_exists(static::$identifier, $fieldName)) { |
459
|
|
|
// TODO: Generalize real and virtual entity fields and manipulations with them |
460
|
|
|
// Set filtered entity identifiers |
461
|
|
|
$this->where(Material::F_PRIMARY, $entityIDs); |
|
|
|
|
462
|
|
|
// If this is parent field |
463
|
|
|
return parent::fields($fieldName); |
464
|
|
|
} else { |
465
|
|
|
throw new EntityFieldNotFound($fieldName); |
466
|
|
|
} |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
//elapsed('Finish SamsonCMS '.static::$identifier.' query'); |
470
|
|
|
|
471
|
|
|
return $return; |
472
|
|
|
} |
473
|
|
|
|
474
|
|
|
/** |
475
|
|
|
* Add condition to current query. |
476
|
|
|
* |
477
|
|
|
* @param string $fieldName Entity field name |
478
|
|
|
* @param string $fieldValue Value |
479
|
|
|
* @param string $fieldRelation Entity field to value relation |
480
|
|
|
* |
481
|
|
|
* @return $this Chaining |
482
|
|
|
*/ |
483
|
|
|
public function where($fieldName, $fieldValue = null, $fieldRelation = ArgumentInterface::EQUAL) |
484
|
|
|
{ |
485
|
|
|
// TODO #1 |
486
|
|
|
// unset(static::$virtualFieldNames['MaterialID']); |
487
|
|
|
// Try to find entity additional field |
488
|
|
|
if (array_key_exists($fieldName, static::$virtualFieldNames)) { |
489
|
|
|
$pointer = static::$virtualFieldNames[$fieldName]; |
490
|
|
|
// Store additional field filter value |
491
|
|
|
$this->fieldFilter[$pointer] = (new Condition())->add(static::$virtualFieldValueColumns[$pointer], $fieldValue, $fieldRelation); |
492
|
|
|
} else { |
493
|
|
|
parent::where($fieldName, $fieldValue, $fieldRelation); |
494
|
|
|
} |
495
|
|
|
|
496
|
|
|
return $this; |
497
|
|
|
} |
498
|
|
|
|
499
|
|
|
/** |
500
|
|
|
* Perform SamsonCMS query and get amount resulting entities. |
501
|
|
|
* |
502
|
|
|
* @return int Amount of resulting entities |
503
|
|
|
*/ |
504
|
|
|
public function count() |
505
|
|
|
{ |
506
|
|
|
$return = 0; |
|
|
|
|
507
|
|
|
if (count($entityIDs = $this->findEntityIDs())) { |
|
|
|
|
508
|
|
|
|
509
|
|
|
if (count($this->searchFilter)) { |
510
|
|
|
$entityIDs = $this->applySearch($entityIDs); |
511
|
|
|
|
512
|
|
|
// Return result if not ids |
513
|
|
|
if (count($entityIDs) === 0) { |
514
|
|
|
return 0; |
|
|
|
|
515
|
|
|
} |
516
|
|
|
} |
517
|
|
|
|
518
|
|
|
$this->primary($entityIDs); |
|
|
|
|
519
|
|
|
$return = parent::count(); |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
return $return; |
523
|
|
|
} |
524
|
|
|
} |
525
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.