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
Pull Request — 2.4 (#133)
by Alessandro
05:21 queued 56s
created

QueryBuilderFactory::getFields()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

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