GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — feature/makefile ( faa705...e32d27 )
by Simone
03:12
created

QueryBuilderFactory::getPage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Mado\QueryBundle\Queries;
4
5
use Doctrine\ORM\EntityManager;
6
use Doctrine\ORM\QueryBuilder;
7
use Mado\QueryBundle\Component\Meta\Exceptions\UnInitializedQueryBuilderException;
8
use Mado\QueryBundle\Dictionary;
9
use Mado\QueryBundle\Exceptions;
10
use Mado\QueryBundle\Queries\Objects\FilterObject;
11
12
class QueryBuilderFactory extends AbstractQuery
13
{
14
    const DIRECTION_AZ = 'asc';
15
16
    const DIRECTION_ZA = 'desc';
17
18
    const DEFAULT_OPERATOR = 'eq';
19
20
    private const AND_OPERATOR_LOGIC = 'AND';
21
22
    private const OR_OPERATOR_LOGIC = 'OR';
23
24
    protected $qBuilder;
25
26
    protected $fields;
27
28
    protected $andFilters;
29
30
    protected $orFilters;
31
32
    private $relationEntityAlias;
33
34
    protected $sorting;
35
36
    private $joins;
37
38
    protected $rel;
39
40
    protected $printing;
41
42
    protected $page;
43
44
    protected $pageLength;
45
46
    protected $select;
47
48 1
    public function getAvailableFilters()
49
    {
50 1
        return array_keys($this->getValueAvailableFilters());
51
    }
52
53 2
    public function getValueAvailableFilters()
54
    {
55 2
        return Dictionary::getOperators();
56
    }
57
58 29
    public function setFields(array $fields = [])
59
    {
60 29
        $this->fields = $fields;
61
62 29
        return $this;
63
    }
64
65 2
    public function getFields()
66
    {
67 2
        if (null === $this->fields) {
68 1
            throw new \RuntimeException(
69 1
                'Oops! Fields are not defined'
70
            );
71
        }
72
73 1
        return $this->fields;
74
    }
75
76
    /** @since version 2.2 */
77 14
    public function setAndFilters(array $andFilters = [])
78
    {
79 14
        $this->andFilters = $andFilters;
80
81 14
        return $this;
82
    }
83
84 13
    public function setOrFilters(array $orFilters = [])
85
    {
86 13
        $this->orFilters = $orFilters;
87
88 13
        return $this;
89
    }
90
91 4
    public function setSorting(array $sorting = [])
92
    {
93 4
        $this->sorting = $sorting;
94
95 4
        return $this;
96
    }
97
98 1
    public function getAndFilters()
99
    {
100 1
        return $this->andFilters;
101
    }
102
103 1
    public function getOrFilters()
104
    {
105 1
        return $this->orFilters;
106
    }
107
108 11
    private function noExistsJoin($prevEntityAlias, $currentEntityAlias)
109
    {
110 11
        if (null === $this->joins) {
111 11
            $this->joins = [];
112
        }
113
114 11
        $needle = $prevEntityAlias . '_' . $currentEntityAlias;
115
116 11
        return !in_array($needle, $this->joins);
117
    }
118
119 11
    private function storeJoin($prevEntityAlias, $currentEntityAlias)
120
    {
121 11
        $needle = $prevEntityAlias . '_' . $currentEntityAlias;
122 11
        $this->joins[$needle] = $needle;
123 11
    }
124
125
    /**
126
     * @param String $relation Nome della relazione semplice (groups.name) o con embedded (_embedded.groups.name)
127
     * @return $this
128
     */
129 11
    public function join(String $relation, $logicOperator = self::AND_OPERATOR_LOGIC)
130
    {
131 11
        $relation = explode('|', $relation)[0];
132 11
        $relations = [$relation];
133
134
135 11
        if (strstr($relation, '_embedded.')) {
136 11
            $embeddedFields = explode('.', $relation);
137 11
            $this->parser->camelize($embeddedFields[1]);
138
139
            // elimino l'ultimo elemento che dovrebbe essere il nome del campo
140 11
            unset($embeddedFields[count($embeddedFields) - 1]);
141
142
            // elimino il primo elemento _embedded
143 11
            unset($embeddedFields[0]);
144
145 11
            $relations = $embeddedFields;
146
        }
147
148 11
        $entityName = $this->getEntityName();
149 11
        $entityAlias = $this->entityAlias;
150
151 11
        foreach ($relations as $relation) {
152 11
            $relation = $this->parser->camelize($relation);
153 11
            $relationEntityAlias = 'table_' . $relation;
154
155 11
            $metadata = $this->manager->getClassMetadata($entityName);
156
157 11
            if ($metadata->hasAssociation($relation)) {
158
159 11
                $association = $metadata->getAssociationMapping($relation);
160
161 11
                $fieldName = $this->parser->camelize($association['fieldName']);
162
163 11
                if ($this->noExistsJoin($relationEntityAlias, $relation)) {
164 11
                    if ($logicOperator === self::AND_OPERATOR_LOGIC) {
165 6
                        $this->qBuilder->innerJoin($entityAlias . "." . $fieldName, $relationEntityAlias);
166 5
                    } elseif ($logicOperator === self::OR_OPERATOR_LOGIC) {
167 5
                        $this->qBuilder->leftJoin($entityAlias . "." . $fieldName, $relationEntityAlias);
168
                    } else {
169
                        throw new Exceptions('Missing Logic operator');
170
                    }
171
172 11
                    $this->storeJoin($relationEntityAlias, $relation);
173
                }
174
175 11
                $entityName = $association['targetEntity'];
176 11
                $entityAlias = $relationEntityAlias;
177
            }
178
179 11
            $this->setRelationEntityAlias($relationEntityAlias);
180
        }
181
182 11
        return $this;
183
    }
184
185 25
    public function filter()
186
    {
187 25
        if (null === $this->andFilters && null === $this->orFilters) {
188 1
            throw new Exceptions\MissingFiltersException();
189
        }
190
191 24
        if (!$this->fields) {
192 1
            throw new Exceptions\MissingFieldsException();
193
        }
194
195 23
        if (null !== $this->andFilters) {
196 12
            foreach ($this->andFilters as $filter => $value) {
197 12
                $this->applyFilterAnd(
198 12
                    Objects\FilterObject::fromRawFilter($filter),
199 12
                    $value,
200 12
                    Objects\Value::fromFilter($value)
201
                );
202
            }
203
        }
204
205 23
        if (null !== $this->orFilters) {
206 11
            $orFilter = [];
207 11
            $orFilter['orCondition'] = null;
208 11
            $orFilter['parameters'] = [];
209
210 11
            foreach ($this->orFilters as $filter => $value) {
211 11
                $orFilter = $this->applyFilterOr(
212 11
                    Objects\FilterObject::fromRawFilter($filter),
213 11
                    $value,
214 11
                    $orFilter
215
                );
216
            }
217
218 11
            if ((count($orFilter) > 0) && (null != $orFilter['orCondition'])) {
219 11
                $this->qBuilder->andWhere($orFilter['orCondition']);
220
221 11
                foreach ($orFilter['parameters'] as $parameter) {
222 7
                    $this->qBuilder->setParameter($parameter['field'], $parameter['value']);
223
                }
224
            }
225
        }
226
227 23
        return $this;
228
    }
229
230 12
    private function applyFilterAnd(
231
        Objects\FilterObject $filterObject,
232
        $value,
233
        Objects\Value $filterValue
234
    ) {
235 12
        $whereCondition = $this->entityAlias . '.' . $filterObject->getFieldName() . ' '
236 12
            . $filterObject->getOperatorMeta();
237
238 12
        if (in_array($filterObject->getFieldName(), $this->fields)) {
239 7
            $salt = '_' . random_int(111, 999);
240
241 7
            if ($filterObject->isListType()) {
242 1
                $whereCondition .= ' (:field_' . $filterObject->getFieldName() . $salt . ')';
243 6
            } elseif ($filterObject->isFieldEqualityType()) {
244 1
                $whereCondition .= ' ' . $this->entityAlias . '.' . $value;
245 5
            } elseif ($filterObject->isNullType()) {
246 2
                $whereCondition .= ' ';
247
            } else {
248 3
                $whereCondition .= ' :field_' . $filterObject->getFieldName() . $salt;
249
            }
250
            
251 7
            $this->qBuilder->andWhere($whereCondition);
252
253 7
            if ($filterObject->haveOperatorSubstitutionPattern()) {
254 2
                if ($filterObject->isListType()) {
255 1
                    $value = explode(',', $value);
256
                } else {
257 1
                    $value = str_replace(
258 1
                        '{string}',
259 1
                        $value,
260 1
                        $filterObject->getOperatorsSubstitutionPattern()
261
                    );
262
                }
263
            }
264
265 7
            if (!$filterObject->isNullType()) {
266 7
                $this->qBuilder->setParameter('field_' . $filterObject->getFieldName() . $salt, $value);
267
            }
268
        } else {
269 5
            if (strpos($filterObject->getFieldName(), 'Embedded.') === false) {
270
                $whereCondition .= ' ' . $this->entityAlias . '.' . $value;
271
                $this->qBuilder->andWhere($whereCondition);
272
            }
273
        }
274
275
        // controllo se il filtro si riferisce ad una relazione dell'entità quindi devo fare dei join
276
        // esempio per users: filtering[_embedded.groups.name|eq]=admin
277 12
        if (strstr($filterObject->getRawFilter(), '_embedded.')) {
278
279 5
            $this->join($filterObject->getRawFilter());
280 5
            $relationEntityAlias = $this->getRelationEntityAlias();
281
282 5
            $embeddedFields = explode('.', $filterObject->getFieldName());
283 5
            $embeddedFieldName = $this->parser->camelize($embeddedFields[count($embeddedFields) - 1]);
284
285 5
            $salt = '_' . random_int(111, 999);
286
287 5
            $whereCondition = $relationEntityAlias . '.' . $embeddedFieldName . ' '
288 5
                . $filterObject->getOperatorMeta();
289
290 5
            if ($filterObject->isListType()) {
291 1
                $whereCondition .= ' (:field_' . $embeddedFieldName . $salt . ')';
292 4
            } elseif ($filterObject->isNullType()) {
293 2
                $whereCondition .= ' ';
294
            } else {
295 2
                $whereCondition .= ' :field_' . $embeddedFieldName . $salt;
296
            }
297
298 5
            $this->qBuilder->andWhere($whereCondition);
299 5
            if ($filterObject->haveOperatorSubstitutionPattern()) {
300 2
                if ($filterObject->isListType()) {
301 1
                    $value = explode(',', $filterValue->getFilter());
302
                } else {
303 1
                    $value = str_replace(
304 1
                        '{string}',
305 1
                        $value,
306 1
                        $filterObject->getOperatorsSubstitutionPattern()
307
                    );
308
                }
309
            }
310
            
311 5
            if (!$filterObject->isNullType()) {
312 3
                $this->qBuilder->setParameter('field_' . $embeddedFieldName . $salt, $value);
313
            }
314
        }
315 12
    }
316
317 11
    private function applyFilterOr(
318
        Objects\FilterObject $filterObject,
319
        $value,
320
        $orCondition
321
    ) {
322 11
        $whereCondition = $this->entityAlias . '.' . $filterObject->getFieldName() . ' '
323 11
            . $filterObject->getOperatorMeta();
324
325
        // controllo se il filtro che mi arriva dalla richiesta è una proprietà di questa entità
326
        // esempio per users: filtering[username|contains]=mado
327 11
        if (in_array($filterObject->getFieldName(), $this->fields)) {
328 6
            $salt = '_' . random_int(111, 999);
329
330 6
            if ($filterObject->isListType()) {
331 1
                $whereCondition .= ' (:field_' . $filterObject->getFieldName() . $salt . ')';
332 5
            } else if ($filterObject->isFieldEqualityType()) {
333 1
                $whereCondition .= $this->entityAlias . '.' . $value;
334 4
            } elseif ($filterObject->isNullType()) {
335 2
                $whereCondition .= ' ';
336
            } else {
337 2
                $whereCondition .= ' :field_' . $filterObject->getFieldName() . $salt;
338
            }
339
340 6
            if (null != $orCondition['orCondition']) {
341
                $orCondition['orCondition'] .= ' OR ' . $whereCondition;
342
            } else {
343 6
                $orCondition['orCondition'] = $whereCondition;
344
            }
345
346 6
            if ($filterObject->haveOperatorSubstitutionPattern()) {
347 2
                if ($filterObject->isListType()) {
348 1
                    $value = explode(',', $value);
349
                } else {
350 1
                    $value = str_replace(
351 1
                        '{string}',
352 1
                        $value,
353 1
                        $filterObject->getOperatorsSubstitutionPattern()
354
                    );
355
                }
356
            }
357
358 6
            if (!$filterObject->isNullType()) {
359 4
                $orCondition['parameters'][] = [
360 4
                    'field' => 'field_' . $filterObject->getFieldName() . $salt,
361 6
                    'value' => $value
362
                ];
363
            }
364
        } else {
365 5
            $isNotARelation = 0 !== strpos($filterObject->getFieldName(), 'Embedded.');
366 5
            if ($isNotARelation) {
367
                    $whereCondition .= ' ' . $this->entityAlias . '.' . $value;
368
                if (null != $orCondition['orCondition']) {
369
                    $orCondition['orCondition'] .= ' OR ' . $whereCondition;
370
                } else {
371
                    $orCondition['orCondition'] = $whereCondition;
372
                }
373
            }
374
        }
375
376
        // controllo se il filtro si riferisce ad una relazione dell'entità quindi devo fare dei join
377
        // esempio per users: filtering[_embedded.groups.name|eq]=admin
378 11
        if (strstr($filterObject->getRawFilter(), '_embedded.')) {
379
380 5
            $this->join($filterObject->getRawFilter(), self::OR_OPERATOR_LOGIC);
381 5
            $relationEntityAlias = $this->getRelationEntityAlias();
382
383 5
            $embeddedFields = explode('.', $filterObject->getFieldName());
384 5
            $embeddableFieldName = $this->parser->camelize($embeddedFields[count($embeddedFields) - 1]);
385
386 5
            $salt = '_' . random_int(111, 999);
387
388 5
            $whereCondition = $relationEntityAlias . '.' . $embeddableFieldName . ' '
389 5
                . $filterObject->getOperatorMeta();
390
391 5
            if ($filterObject->isListType()) {
392 1
                $whereCondition .= ' (:field_' . $embeddableFieldName . $salt . ')';
393 4
            } elseif ($filterObject->isNullType()) {
394 2
                $whereCondition .= ' ';
395
            } else {
396 2
                $whereCondition .= ' :field_' . $embeddableFieldName . $salt;
397
            }
398
399 5
            if (null != $orCondition['orCondition']) {
400 1
                $orCondition['orCondition'] .= ' OR ' . $whereCondition;
401
            } else {
402 5
                $orCondition['orCondition'] = $whereCondition;
403
            }
404
405 5
            if ($filterObject->haveOperatorSubstitutionPattern()) {
406 2
                if ($filterObject->isListType()) {
407 1
                    $value = explode(',', $value);
408
                } else {
409 1
                    $value = str_replace(
410 1
                        '{string}',
411 1
                        $value,
412 1
                        $filterObject->getOperatorsSubstitutionPattern()
413
                    );
414
                }
415
            }
416
417 5
            if (!$filterObject->isNullType()) {
418 3
                $orCondition['parameters'][] = [
419 3
                    'field' => 'field_' . $embeddableFieldName . $salt,
420 3
                    'value' => $value
421
                ];
422
            }
423
        }
424
425 11
        return $orCondition;
426
    }
427
428 5
    public function sort()
429
    {
430 5
        if (!$this->fields) {
431 1
            throw new \RuntimeException(
432 1
                'Oops! Fields are not defined'
433
            );
434
        }
435
436 4
        if (null === $this->sorting) {
437 1
            throw new \RuntimeException(
438 1
                'Oops! Sorting is not defined'
439
            );
440
        }
441
442 3
        foreach ($this->sorting as $sort => $val) {
443 3
            $val = strtolower($val);
444
445 3
            $fieldName = $this->parser->camelize($sort);
446
447 3
            if (in_array($fieldName, $this->fields)) {
448 2
                $direction = ($val === self::DIRECTION_AZ) ? self::DIRECTION_AZ : self::DIRECTION_ZA;
449 2
                $this->ensureQueryBuilderIsDefined();
450 1
                $this->qBuilder->addOrderBy($this->entityAlias . '.' . $fieldName, $direction);
451
            }
452
453 2
            if (strstr($sort, '_embedded.')) {
454 1
                $this->join($sort);
455 1
                $relationEntityAlias = $this->getRelationEntityAlias();
456
457 1
                $embeddedFields = explode('.', $sort);
458 1
                $fieldName = $this->parser->camelize($embeddedFields[2]);
459 1
                $direction = ($val === self::DIRECTION_AZ) ? self::DIRECTION_AZ : self::DIRECTION_ZA;
460
461 2
                $this->qBuilder->addOrderBy($relationEntityAlias . '.' . $fieldName, $direction);
462
            }
463
464
        }
465
466 2
        return $this;
467
    }
468
469 22
    public function getQueryBuilder() :QueryBuilder
470
    {
471 22
        if (!$this->qBuilder) {
472 1
            throw new UnInitializedQueryBuilderException();
473
        }
474
475 21
        return $this->qBuilder;
476
    }
477
478 11
    private function setRelationEntityAlias(string $relationEntityAlias)
479
    {
480 11
        $this->relationEntityAlias = $relationEntityAlias;
481 11
    }
482
483 11
    private function getRelationEntityAlias()
484
    {
485 11
        return $this->relationEntityAlias;
486
    }
487
488 10
    public function setRel(array $rel)
489
    {
490 10
        $this->rel = $rel;
491
492 10
        return $this;
493
    }
494
495 2
    public function getRel() : array
496
    {
497 2
        return $this->rel;
498
    }
499
500 1
    public function addRel($relation)
501
    {
502 1
        array_push($this->rel, $relation);
503 1
    }
504
505 2
    public function setPrinting($printing)
506
    {
507 2
        $this->printing = $printing;
508
509 2
        return $this;
510
    }
511
512 1
    public function getPrinting()
513
    {
514 1
        return $this->printing;
515
    }
516
517 2
    public function setPage(int $page)
518
    {
519 2
        $this->page = $page;
520
521 2
        return $this;
522
    }
523
524 1
    public function getPage() :int
525
    {
526 1
        return $this->page;
527
    }
528
529 2
    public function setPageLength($pageLength)
530
    {
531 2
        $this->pageLength = $pageLength;
532
533 2
        return $this;
534
    }
535
536 1
    public function getPageLength()
537
    {
538 1
        return $this->pageLength;
539
    }
540
541 2
    public function setSelect($select) : QueryBuilderFactory
542
    {
543 2
        $this->select = $select;
544
545 2
        return $this;
546
    }
547
548 1
    public function getSelect()
549
    {
550 1
        return $this->select;
551
    }
552
553 1
    public function getEntityManager() : EntityManager
554
    {
555 1
        return $this->manager;
556
    }
557
558 2
    public function ensureQueryBuilderIsDefined()
559
    {
560 2
        if (!$this->qBuilder) {
561 1
            throw new \RuntimeException(
562
                'Oops! QueryBuilder was never initialized. '
563
                . "\n" . 'QueryBuilderFactory::createQueryBuilder()'
564 1
                . "\n" . 'QueryBuilderFactory::createSelectAndGroupBy()'
565
            );
566
        }
567 1
    }
568
}
569