Total Complexity | 81 |
Total Lines | 530 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like QueryBuilderFactory often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use QueryBuilderFactory, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class QueryBuilderFactory extends AbstractQuery |
||
14 | { |
||
15 | const DIRECTION_AZ = 'asc'; |
||
16 | |||
17 | const DIRECTION_ZA = 'desc'; |
||
18 | |||
19 | const DEFAULT_OPERATOR = 'eq'; |
||
20 | |||
21 | protected $qBuilder; |
||
22 | |||
23 | protected $fields; |
||
24 | |||
25 | protected $andFilters; |
||
26 | |||
27 | protected $orFilters; |
||
28 | |||
29 | private $relationEntityAlias; |
||
30 | |||
31 | protected $sorting; |
||
32 | |||
33 | private $joins; |
||
34 | |||
35 | protected $rel; |
||
36 | |||
37 | protected $printing; |
||
38 | |||
39 | protected $page; |
||
40 | |||
41 | protected $pageLength; |
||
42 | |||
43 | protected $select; |
||
44 | |||
45 | public function getAvailableFilters() |
||
46 | { |
||
47 | return array_keys($this->getValueAvailableFilters()); |
||
48 | } |
||
49 | |||
50 | public function getValueAvailableFilters() |
||
51 | { |
||
52 | return Dictionary::getOperators(); |
||
53 | } |
||
54 | |||
55 | public function setFields(array $fields = []) |
||
56 | { |
||
57 | $this->fields = $fields; |
||
58 | |||
59 | return $this; |
||
60 | } |
||
61 | |||
62 | public function getFields() |
||
63 | { |
||
64 | if (null === $this->fields) { |
||
65 | throw new \RuntimeException( |
||
66 | 'Oops! Fields are not defined' |
||
67 | ); |
||
68 | } |
||
69 | |||
70 | return $this->fields; |
||
71 | } |
||
72 | |||
73 | /** @deprecated since version 2.2.2 will be removed in version 2.3 */ |
||
74 | public function setFilters(array $andFilters = []) |
||
79 | } |
||
80 | |||
81 | /** @since version 2.2.2 */ |
||
82 | public function setAndFilters(array $andFilters = []) |
||
83 | { |
||
84 | return $this->setFilters($andFilters); |
||
|
|||
85 | } |
||
86 | |||
87 | public function setOrFilters(array $orFilters = []) |
||
88 | { |
||
89 | $this->orFilters = $orFilters; |
||
90 | |||
91 | return $this; |
||
92 | } |
||
93 | |||
94 | public function setSorting(array $sorting = []) |
||
95 | { |
||
96 | $this->sorting = $sorting; |
||
97 | |||
98 | return $this; |
||
99 | } |
||
100 | |||
101 | public function getAndFilters() |
||
102 | { |
||
103 | return $this->andFilters; |
||
104 | } |
||
105 | |||
106 | public function getOrFilters() |
||
107 | { |
||
108 | return $this->orFilters; |
||
109 | } |
||
110 | |||
111 | private function noExistsJoin($prevEntityAlias, $currentEntityAlias) |
||
112 | { |
||
113 | if (null === $this->joins) { |
||
114 | $this->joins = []; |
||
115 | } |
||
116 | |||
117 | $needle = $prevEntityAlias . '_' . $currentEntityAlias; |
||
118 | |||
119 | return ! in_array($needle, $this->joins); |
||
120 | } |
||
121 | |||
122 | private function storeJoin($prevEntityAlias, $currentEntityAlias) |
||
123 | { |
||
124 | $needle = $prevEntityAlias . '_' . $currentEntityAlias; |
||
125 | $this->joins[$needle] = $needle; |
||
126 | } |
||
127 | |||
128 | /** |
||
129 | * @param String $relation Nome della relazione semplice (groups.name) o con embedded (_embedded.groups.name) |
||
130 | * @return $this |
||
131 | */ |
||
132 | public function join(String $relation) |
||
179 | } |
||
180 | |||
181 | public function filter() |
||
182 | { |
||
183 | if (null === $this->andFilters && null === $this->orFilters) { |
||
184 | throw new Exceptions\MissingFiltersException(); |
||
185 | } |
||
226 | } |
||
227 | |||
228 | private function applyFilterAnd( |
||
229 | Objects\FilterObject $filterObject, |
||
230 | $value, |
||
231 | Objects\Value $filterValue |
||
232 | ) { |
||
233 | $whereCondition = $this->entityAlias . '.' . $filterObject->getFieldName() . ' ' |
||
234 | . $filterObject->getOperatorMeta(); |
||
235 | |||
236 | if (in_array($filterObject->getFieldName(), $this->fields)) { |
||
237 | $salt = '_' . random_int(111, 999); |
||
238 | |||
239 | if ($filterObject->isListType()) { |
||
240 | $whereCondition .= ' (:field_' . $filterObject->getFieldName() . $salt . ')'; |
||
241 | } elseif ($filterObject->isFieldEqualityType()) { |
||
242 | $whereCondition .= ' ' . $this->entityAlias . '.' . $value; |
||
243 | } else { |
||
244 | $whereCondition .= ' :field_' . $filterObject->getFieldName() . $salt; |
||
245 | } |
||
246 | |||
247 | $this->qBuilder->andWhere($whereCondition); |
||
248 | |||
249 | if ($filterObject->haveOperatorSubstitutionPattern()) { |
||
250 | if ($filterObject->isListType()) { |
||
251 | $value = explode(',', $value); |
||
252 | } else { |
||
253 | $value = str_replace( |
||
254 | '{string}', |
||
255 | $value, |
||
256 | $filterObject->getOperatorsSubstitutionPattern() |
||
257 | ); |
||
258 | } |
||
259 | } |
||
260 | |||
261 | $this->qBuilder->setParameter('field_' . $filterObject->getFieldName() . $salt, $value); |
||
262 | } else { |
||
263 | $isNotARelation = 0 !== strpos($filterObject->getFieldName(), 'Embedded.'); |
||
264 | if ($isNotARelation) { |
||
265 | $whereCondition .= ' ' . $this->entityAlias . '.' . $value; |
||
266 | $this->qBuilder->andWhere($whereCondition); |
||
267 | } |
||
268 | } |
||
269 | |||
270 | // controllo se il filtro si riferisce ad una relazione dell'entità quindi devo fare dei join |
||
271 | // esempio per users: filtering[_embedded.groups.name|eq]=admin |
||
272 | if (strstr($filterObject->getRawFilter(), '_embedded.')) { |
||
273 | |||
274 | $this->join($filterObject->getRawFilter()); |
||
275 | $relationEntityAlias = $this->getRelationEntityAlias(); |
||
276 | |||
277 | $embeddedFields = explode('.', $filterObject->getFieldName()); |
||
278 | $embeddedFieldName = $this->parser->camelize($embeddedFields[count($embeddedFields)-1]); |
||
279 | |||
280 | $salt = '_' . random_int(111, 999); |
||
281 | |||
282 | $whereCondition = $relationEntityAlias . '.' . $embeddedFieldName . ' ' |
||
283 | . $filterObject->getOperatorMeta(); |
||
284 | |||
285 | if ($filterObject->isListType()) { |
||
286 | $whereCondition .= ' (:field_' . $embeddedFieldName . $salt . ')'; |
||
287 | } else { |
||
288 | $whereCondition .= ' :field_' . $embeddedFieldName . $salt; |
||
289 | } |
||
290 | |||
291 | $this->qBuilder->andWhere($whereCondition); |
||
292 | if ($filterObject->haveOperatorSubstitutionPattern()) { |
||
293 | if ($filterObject->isListType()) { |
||
294 | $value = explode(',', $filterValue->getFilter()); |
||
295 | } else { |
||
296 | $value = str_replace( |
||
297 | '{string}', |
||
298 | $value, |
||
299 | $filterObject->getOperatorsSubstitutionPattern() |
||
300 | ); |
||
301 | } |
||
302 | } |
||
303 | |||
304 | $this->qBuilder->setParameter('field_' . $embeddedFieldName . $salt, $value); |
||
305 | } |
||
306 | } |
||
307 | |||
308 | private function applyFilterOr( |
||
409 | } |
||
410 | |||
411 | public function sort() |
||
412 | { |
||
413 | if (!$this->fields) { |
||
414 | throw new \RuntimeException( |
||
415 | 'Oops! Fields are not defined' |
||
416 | ); |
||
417 | } |
||
418 | |||
419 | if (null === $this->sorting) { |
||
420 | throw new \RuntimeException( |
||
421 | 'Oops! Sorting is not defined' |
||
422 | ); |
||
423 | } |
||
424 | |||
425 | foreach ($this->sorting as $sort => $val) { |
||
426 | $val = strtolower($val); |
||
427 | |||
428 | $fieldName = $this->parser->camelize($sort); |
||
429 | |||
430 | if (in_array($fieldName, $this->fields)) { |
||
431 | $direction = ($val === self::DIRECTION_AZ) ? self::DIRECTION_AZ : self::DIRECTION_ZA; |
||
432 | $this->ensureQueryBuilderIsDefined(); |
||
433 | $this->qBuilder->addOrderBy($this->entityAlias .'.'. $fieldName, $direction); |
||
434 | } |
||
435 | |||
436 | if (strstr($sort, '_embedded.')) { |
||
437 | $this->join($sort); |
||
438 | $relationEntityAlias = $this->getRelationEntityAlias(); |
||
439 | |||
440 | $embeddedFields = explode('.', $sort); |
||
441 | $fieldName = $this->parser->camelize($embeddedFields[2]); |
||
442 | $direction = ($val === self::DIRECTION_AZ) ? self::DIRECTION_AZ : self::DIRECTION_ZA; |
||
443 | |||
444 | $this->qBuilder->addOrderBy($relationEntityAlias.'.'.$fieldName, $direction); |
||
445 | } |
||
446 | |||
447 | } |
||
448 | |||
449 | return $this; |
||
450 | } |
||
451 | |||
452 | public function getQueryBuilder() :QueryBuilder |
||
453 | { |
||
454 | if (!$this->qBuilder) { |
||
455 | throw new UnInitializedQueryBuilderException(); |
||
456 | } |
||
457 | |||
458 | return $this->qBuilder; |
||
459 | } |
||
460 | |||
461 | private function setRelationEntityAlias(string $relationEntityAlias) |
||
462 | { |
||
463 | $this->relationEntityAlias = $relationEntityAlias; |
||
464 | } |
||
465 | |||
466 | private function getRelationEntityAlias() |
||
467 | { |
||
468 | return $this->relationEntityAlias; |
||
469 | } |
||
470 | |||
471 | public function setRel($rel) |
||
472 | { |
||
473 | $this->rel = $rel; |
||
474 | |||
475 | return $this; |
||
476 | } |
||
477 | |||
478 | public function getRel() |
||
479 | { |
||
480 | return $this->rel; |
||
481 | } |
||
482 | |||
483 | public function setPrinting($printing) |
||
484 | { |
||
485 | $this->printing = $printing; |
||
486 | |||
487 | return $this; |
||
488 | } |
||
489 | |||
490 | public function getPrinting() |
||
493 | } |
||
494 | |||
495 | public function setPage(int $page) |
||
496 | { |
||
497 | $this->page = $page; |
||
498 | |||
499 | return $this; |
||
500 | } |
||
501 | |||
502 | public function getPage() :int |
||
503 | { |
||
504 | return $this->page; |
||
505 | } |
||
506 | |||
507 | public function setPageLength($pageLength) |
||
508 | { |
||
509 | $this->pageLength = $pageLength; |
||
510 | |||
511 | return $this; |
||
512 | } |
||
513 | |||
514 | public function getPageLength() |
||
515 | { |
||
516 | return $this->pageLength; |
||
517 | } |
||
518 | |||
519 | public function setSelect( $select) : QueryBuilderFactory |
||
520 | { |
||
521 | $this->select = $select; |
||
522 | |||
523 | return $this; |
||
524 | } |
||
525 | |||
526 | public function getSelect() |
||
529 | } |
||
530 | |||
531 | public function getEntityManager() : EntityManager |
||
532 | { |
||
533 | return $this->manager; |
||
534 | } |
||
535 | |||
536 | public function ensureQueryBuilderIsDefined() |
||
543 | ); |
||
544 | } |
||
545 | } |
||
546 | } |
||
547 |
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.