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 ( 1c78c4...dfac51 )
by Simone
03:00
created

QueryBuilderFactory::setRel()   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
    protected $qBuilder;
21
22
    protected $fields;
23
24
    protected $andFilters;
25
26
    protected $orFilters;
27
28
    private $relationEntityAlias;
29
30
    protected $sorting;
31
32
    private $joins;
33
34
    protected $rel;
35
36
    protected $printing;
37
38
    protected $page;
39
40
    protected $pageLength;
41
42
    protected $select;
43
44 1
    public function getAvailableFilters()
45
    {
46 1
        return array_keys($this->getValueAvailableFilters());
47
    }
48
49 2
    public function getValueAvailableFilters()
50
    {
51 2
        return Dictionary::getOperators();
52
    }
53
54 13
    public function setFields(array $fields = [])
55
    {
56 13
        $this->fields = $fields;
57
58 13
        return $this;
59
    }
60
61 2
    public function getFields()
62
    {
63 2
        if (null === $this->fields) {
64 1
            throw new \RuntimeException(
65 1
                'Oops! Fields are not defined'
66
            );
67
        }
68
69 1
        return $this->fields;
70
    }
71
72
    /** @deprecated since version 2.2.2 will be removed in version 2.3 */
73 9
    public function setFilters(array $andFilters = [])
74
    {
75 9
        $this->andFilters = $andFilters;
76
77 9
        return $this;
78
    }
79
80
    /** @since version 2.2.2 */
81 9
    public function setAndFilters(array $andFilters = [])
82
    {
83 9
        return $this->setFilters($andFilters);
0 ignored issues
show
Deprecated Code introduced by
The function Mado\QueryBundle\Queries...erFactory::setFilters() has been deprecated: since version 2.2.2 will be removed in version 2.3 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

83
        return /** @scrutinizer ignore-deprecated */ $this->setFilters($andFilters);

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.

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