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 — master ( 147b46...7e505e )
by Alessandro
03:19
created

QueryBuilderFactory::setSelect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
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 11
                    $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
            $orCondition['parameters'][] = [
359 6
                'field' => 'field_' . $filterObject->getFieldName() . $salt,
360 6
                'value' => $value
361
            ];
362
        } else {
363 5
            $isNotARelation = 0 !== strpos($filterObject->getFieldName(), 'Embedded.');
364 5
            if ($isNotARelation) {
365
                    $whereCondition .= ' ' . $this->entityAlias . '.' . $value;
366
                if (null != $orCondition['orCondition']) {
367
                    $orCondition['orCondition'] .= ' OR ' . $whereCondition;
368
                } else {
369
                    $orCondition['orCondition'] = $whereCondition;
370
                }
371
            }
372
        }
373
374
        // controllo se il filtro si riferisce ad una relazione dell'entità quindi devo fare dei join
375
        // esempio per users: filtering[_embedded.groups.name|eq]=admin
376 11
        if (strstr($filterObject->getRawFilter(), '_embedded.')) {
377
378 5
            $this->join($filterObject->getRawFilter(), self::OR_OPERATOR_LOGIC);
379 5
            $relationEntityAlias = $this->getRelationEntityAlias();
380
381 5
            $embeddedFields = explode('.', $filterObject->getFieldName());
382 5
            $embeddableFieldName = $this->parser->camelize($embeddedFields[count($embeddedFields) - 1]);
383
384 5
            $salt = '_' . random_int(111, 999);
385
386 5
            $whereCondition = $relationEntityAlias . '.' . $embeddableFieldName . ' '
387 5
                . $filterObject->getOperatorMeta();
388
389 5
            if ($filterObject->isListType()) {
390 1
                $whereCondition .= ' (:field_' . $embeddableFieldName . $salt . ')';
391 4
            } elseif ($filterObject->isNullType()) {
392 2
                $whereCondition .= ' ';
393
            } else {
394 2
                $whereCondition .= ' :field_' . $embeddableFieldName . $salt;
395
            }
396
397 5
            if (null != $orCondition['orCondition']) {
398 1
                $orCondition['orCondition'] .= ' OR ' . $whereCondition;
399
            } else {
400 5
                $orCondition['orCondition'] = $whereCondition;
401
            }
402
403 5
            if ($filterObject->haveOperatorSubstitutionPattern()) {
404 2
                if ($filterObject->isListType()) {
405 1
                    $value = explode(',', $value);
406
                } else {
407 1
                    $value = str_replace(
408 1
                        '{string}',
409 1
                        $value,
410 1
                        $filterObject->getOperatorsSubstitutionPattern()
411
                    );
412
                }
413
            }
414
415
            //if (!$filterObject->isNullType()) {
416 5
                $orCondition['parameters'][] = [
417 5
                    'field' => 'field_' . $embeddableFieldName . $salt,
418 5
                    'value' => $value
419
                ];
420
            //}
421
        }
422
423 11
        return $orCondition;
424
    }
425
426 5
    public function sort()
427
    {
428 5
        if (!$this->fields) {
429 1
            throw new \RuntimeException(
430 1
                'Oops! Fields are not defined'
431
            );
432
        }
433
434 4
        if (null === $this->sorting) {
435 1
            throw new \RuntimeException(
436 1
                'Oops! Sorting is not defined'
437
            );
438
        }
439
440 3
        foreach ($this->sorting as $sort => $val) {
441 3
            $val = strtolower($val);
442
443 3
            $fieldName = $this->parser->camelize($sort);
444
445 3
            if (in_array($fieldName, $this->fields)) {
446 2
                $direction = ($val === self::DIRECTION_AZ) ? self::DIRECTION_AZ : self::DIRECTION_ZA;
447 2
                $this->ensureQueryBuilderIsDefined();
448 1
                $this->qBuilder->addOrderBy($this->entityAlias . '.' . $fieldName, $direction);
449
            }
450
451 2
            if (strstr($sort, '_embedded.')) {
452 1
                $this->join($sort);
453 1
                $relationEntityAlias = $this->getRelationEntityAlias();
454
455 1
                $embeddedFields = explode('.', $sort);
456 1
                $fieldName = $this->parser->camelize($embeddedFields[2]);
457 1
                $direction = ($val === self::DIRECTION_AZ) ? self::DIRECTION_AZ : self::DIRECTION_ZA;
458
459 2
                $this->qBuilder->addOrderBy($relationEntityAlias . '.' . $fieldName, $direction);
460
            }
461
462
        }
463
464 2
        return $this;
465
    }
466
467 22
    public function getQueryBuilder() :QueryBuilder
468
    {
469 22
        if (!$this->qBuilder) {
470 1
            throw new UnInitializedQueryBuilderException();
471
        }
472
473 21
        return $this->qBuilder;
474
    }
475
476 11
    private function setRelationEntityAlias(string $relationEntityAlias)
477
    {
478 11
        $this->relationEntityAlias = $relationEntityAlias;
479 11
    }
480
481 11
    private function getRelationEntityAlias()
482
    {
483 11
        return $this->relationEntityAlias;
484
    }
485
486 10
    public function setRel(array $rel)
487
    {
488 10
        $this->rel = $rel;
489
490 10
        return $this;
491
    }
492
493 2
    public function getRel() : array
494
    {
495 2
        return $this->rel;
496
    }
497
498 1
    public function addRel($relation)
499
    {
500 1
        array_push($this->rel, $relation);
501 1
    }
502
503 2
    public function setPrinting($printing)
504
    {
505 2
        $this->printing = $printing;
506
507 2
        return $this;
508
    }
509
510 1
    public function getPrinting()
511
    {
512 1
        return $this->printing;
513
    }
514
515 2
    public function setPage(int $page)
516
    {
517 2
        $this->page = $page;
518
519 2
        return $this;
520
    }
521
522 1
    public function getPage() :int
523
    {
524 1
        return $this->page;
525
    }
526
527 2
    public function setPageLength($pageLength)
528
    {
529 2
        $this->pageLength = $pageLength;
530
531 2
        return $this;
532
    }
533
534 1
    public function getPageLength()
535
    {
536 1
        return $this->pageLength;
537
    }
538
539 2
    public function setSelect($select) : QueryBuilderFactory
540
    {
541 2
        $this->select = $select;
542
543 2
        return $this;
544
    }
545
546 1
    public function getSelect()
547
    {
548 1
        return $this->select;
549
    }
550
551 1
    public function getEntityManager() : EntityManager
552
    {
553 1
        return $this->manager;
554
    }
555
556 2
    public function ensureQueryBuilderIsDefined()
557
    {
558 2
        if (!$this->qBuilder) {
559 1
            throw new \RuntimeException(
560
                'Oops! QueryBuilder was never initialized. '
561
                . "\n" . 'QueryBuilderFactory::createQueryBuilder()'
562 1
                . "\n" . 'QueryBuilderFactory::createSelectAndGroupBy()'
563
            );
564
        }
565 1
    }
566
}
567