This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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) |
|
0 ignored issues
–
show
|
|||
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); |
||
0 ignored issues
–
show
$this->fieldFilter is of type object<samsonframework\orm\Condition> , but the function expects a array<integer,object<sam...amework\orm\Condition>> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
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) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. ![]() |
|||
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) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. ![]() |
|||
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) |
||
0 ignored issues
–
show
The expression
$this->query->entity(\sa...DELETION, true)->exec() of type boolean|array<integer,ob...k\orm\RecordInterface>> is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
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); |
||
0 ignored issues
–
show
$entityIDs is of type array , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
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); |
||
0 ignored issues
–
show
$entityIDs is of type array , but the function expects a string|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
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; |
||
0 ignored issues
–
show
|
|||
507 | if (count($entityIDs = $this->findEntityIDs())) { |
||
0 ignored issues
–
show
|
|||
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; |
||
0 ignored issues
–
show
The return type of
return 0; (integer ) is incompatible with the return type of the parent method samsoncms\api\query\Record::count of type boolean|samsonframework\orm\RecordInterface .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
515 | } |
||
516 | } |
||
517 | |||
518 | $this->primary($entityIDs); |
||
0 ignored issues
–
show
$entityIDs is of type array , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
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.