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 — master (#87)
by Simone
02:26
created

QueryBuilderFactory::getRelationEntityAlias()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 1
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Mado\QueryBundle\Queries;
4
5
use Doctrine\ORM\QueryBuilder;
6
use Mado\QueryBundle\Dictionary;
7
use Mado\QueryBundle\Queries\Objects\FilterObject;
8
use Mado\QueryBundle\Queries\Objects\Operator;
0 ignored issues
show
Bug introduced by
The type Mado\QueryBundle\Queries\Objects\Operator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
10
class QueryBuilderFactory extends AbstractQuery
11
{
12
    const DIRECTION_AZ = 'asc';
13
14
    const DIRECTION_ZA = 'desc';
15
16
    const DEFAULT_OPERATOR = 'eq';
17
18
    protected $qBuilder;
19
20
    protected $fields;
21
22
    protected $filtering;
23
24
    protected $orFiltering;
25
26
    protected $relationEntityAlias;
27
28
    protected $sorting;
29
30
    protected $joins;
31
32
    protected $rel;
33
34
    protected $printing;
35
36
    protected $page;
37
38
    protected $pageLength;
39
40
    protected $select;
41
42
    public function getAvailableFilters()
43
    {
44
        return array_keys($this->getValueAvailableFilters());
45
    }
46
47
    public function getValueAvailableFilters()
48
    {
49
        return Dictionary::getOperators();
50
    }
51
52
    public function setFields(array $fields = [])
53
    {
54
        $this->fields = $fields;
55
56
        return $this;
57
    }
58
59
    public function getFields()
60
    {
61
        if (null === $this->fields) {
62
            throw new \RuntimeException(
63
                'Oops! Fields are not defined'
64
            );
65
        }
66
67
        return $this->fields;
68
    }
69
70
    public function setFilters(array $filtering = [])
71
    {
72
        $this->filtering = $filtering;
73
74
        return $this;
75
    }
76 1
77
    public function setOrFilters(array $orFiltering = [])
78 1
    {
79
        $this->orFiltering = $orFiltering;
80
81
        return $this;
82
    }
83
84
    public function setSorting(array $sorting = [])
85
    {
86
        $this->sorting = $sorting;
87
88
        return $this;
89
    }
90
91
    public function getFilters()
92
    {
93
        return $this->filtering;
94
    }
95
96
    public function getOrFilters()
97
    {
98
        return $this->orFiltering;
99
    }
100
101
    private function noExistsJoin($prevEntityAlias, $currentEntityAlias)
102
    {
103
        if (null === $this->joins) {
104
            $this->joins = [];
105
        }
106
107
        $needle = $prevEntityAlias . "_" . $currentEntityAlias;
108
109
        return ! in_array($needle, $this->joins);
110
    }
111
112
    private function storeJoin($prevEntityAlias, $currentEntityAlias)
113
    {
114
        $needle = $prevEntityAlias . "_" . $currentEntityAlias;
115
        $this->joins[$needle] = $needle;
116
    }
117
118
    /**
119
     * @param String $relation Nome della relazione semplice (groups.name) o con embedded (_embedded.groups.name)
120
     * @return $this
121
     */
122
    public function join(String $relation)
123
    {
124
        $relation = explode('|', $relation)[0];
125
        $relations = [$relation];
126
127
        if (strstr($relation, '_embedded.')) {
128
            $embeddedFields = explode('.', $relation);
129
            $relation = $this->parser->camelize($embeddedFields[1]);
0 ignored issues
show
Unused Code introduced by
The assignment to $relation is dead and can be removed.
Loading history...
130
131
            // elimino l'ultimo elemento che dovrebbe essere il nome del campo
132
            unset($embeddedFields[count($embeddedFields) - 1]);
133
134
            // elimino il primo elemento _embedded
135
            unset($embeddedFields[0]);
136
137
            $relations = $embeddedFields;
138
        }
139
140
        $entityName = $this->getEntityName();
141
        $entityAlias = $this->entityAlias;
142
143
        foreach ($relations as $relation) {
144
145
            $relation = $this->parser->camelize($relation);
146
            $relationEntityAlias = 'table_' . $relation;
147
148
            $metadata = $this->manager->getClassMetadata($entityName);
149
150
            if ($metadata->hasAssociation($relation)) {
151
152
                $association = $metadata->getAssociationMapping($relation);
153
154
                $fieldName = $this->parser->camelize($association['fieldName']);
155
156
                if ($this->noExistsJoin($relationEntityAlias, $relation)) {
157
                    $this->qBuilder->join($entityAlias . "." . $fieldName, $relationEntityAlias);
158
                    $this->storeJoin($relationEntityAlias, $relation);
159
                }
160
161
                $entityName = $association['targetEntity'];
162
                $entityAlias = $relationEntityAlias;
163
            }
164
165
            $this->setRelationEntityAlias($relationEntityAlias);
166
        }
167
168
        return $this;
169
    }
170
171
    public function filter()
172
    {
173
        if (null === $this->filtering) {
174
            throw new \RuntimeException(
175
                'Oops! Filtering is not defined'
176
            );
177
        }
178
179
        if (!$this->fields) {
180
            throw new \RuntimeException(
181
                'Oops! Fields are not defined'
182
            );
183
        }
184
185
        foreach ($this->filtering as $filter => $value) {
186
            $this->applyFilterAnd(
187
                Objects\FilterObject::fromRawFilter($filter),
188
                $value,
189
                Objects\Value::fromFilter($value)
190
            );
191
        }
192
193
        if (null !== $this->orFiltering) {
194
            $orFilter = [];
195
            $orFilter['orCondition'] = null;
196
            $orFilter['parameters'] = [];
197
198
            foreach ($this->orFiltering as $filter => $value) {
199
                $orFilter = $this->applyFilterOr(
200
                    Objects\FilterObject::fromRawFilter($filter),
201
                    $value,
202
                    $orFilter
203
                );
204
            }
205
206
            if ((count($orFilter) > 0) && ($orFilter['orCondition'] != null)) {
207
                $this->qBuilder->andWhere($orFilter['orCondition']);
208
209
                foreach ($orFilter['parameters'] as $parameter) {
210
                    $this->qBuilder->setParameter($parameter['field'], $parameter['value']);
211
                }
212
            }
213
        }
214
215
        return $this;
216
    }
217
218
    private function applyFilterAnd(
219
        Objects\FilterObject $filterObject,
220
        $value,
221
        Objects\Value $filterValue
222
    ) {
223
        $whereCondition = $this->entityAlias . '.' . $filterObject->getFieldName() . ' '
224
            . $filterObject->getOperatorMeta();
225
226
        if (in_array($filterObject->getFieldName(), $this->fields)) {
227
            $salt = '';
228
            foreach ($this->qBuilder->getParameters() as $parameter) {
229
                if ($parameter->getName() == 'field_' . $filterObject->getFieldName()) {
230
                    $salt = '_' . rand(111, 999);
231
                }
232
            }
233
234
            if ($filterObject->isListType()) {
235
                $whereCondition .= ' (:field_' . $filterObject->getFieldName() . $salt . ')';
236
            } elseif ($filterObject->isFieldEqualityType()) {
237
                $whereCondition .= ' ' . $this->entityAlias . '.' . $value;
238
            } else {
239
                $whereCondition .= ' :field_' . $filterObject->getFieldName() . $salt;
240
            }
241
242
            $this->qBuilder->andWhere($whereCondition);
243
244
            if ($filterObject->haveOperatorSubstitutionPattern()) {
245
                if ($filterObject->isListType()) {
246
                    $value = explode(',', $value);
247
                } else {
248
                    $value = str_replace(
249
                        '{string}',
250
                        $value,
251
                        $filterObject->getOperatorsSubstitutionPattern()
252
                    );
253
                }
254
            }
255
256
            $this->qBuilder->setParameter('field_' . $filterObject->getFieldName() . $salt, $value);
257
        } else {
258
            $isNotARelation = 0 !== strpos($filterObject->getFieldName(), 'Embedded.');
259
            if ($isNotARelation) {
260
                $whereCondition .= ' ' . $this->entityAlias . '.' . $value;
261
                $this->qBuilder->andWhere($whereCondition);
262
            }
263
        }
264
265
        // controllo se il filtro si riferisce ad una relazione dell'entità quindi devo fare dei join
266
        // esempio per users: filtering[_embedded.groups.name|eq]=admin
267
        if (strstr($filterObject->getRawFilter(), '_embedded.')) {
268
269
            $this->join($filterObject->getRawFilter());
270
            $relationEntityAlias = $this->getRelationEntityAlias();
271
272
            $embeddedFields = explode('.', $filterObject->getFieldName());
273
            $embeddedFieldName = $this->parser->camelize($embeddedFields[count($embeddedFields)-1]);
274
275
            $salt = '';
276
            foreach ($this->qBuilder->getParameters() as $parameter) {
277
                if ($parameter->getName() == 'field_' . $embeddedFieldName) {
278
                    $salt = '_' . rand(111, 999);
279
                }
280
            }
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(
309
        Objects\FilterObject $filterObject,
310
        $value,
311
        $orCondition
312
    ) {
313
        $whereCondition = $this->entityAlias . '.' . $filterObject->getFieldName() . ' '
314
            . $filterObject->getOperatorMeta();
315
316
        // controllo se il filtro che mi arriva dalla richiesta è una proprietà di questa entità
317
        // esempio per users: filtering[username|contains]=mado
318
        if (in_array($filterObject->getFieldName(), $this->fields)) {
319
            $salt = '';
320
            foreach ($this->qBuilder->getParameters() as $parameter) {
321
                if ($parameter->getName() == 'field_' . $filterObject->getFieldName()) {
322
                    $salt = '_' . rand(111, 999);
323
                }
324
            }
325
326
            if ($salt == '') {
327
                $salt = '_' . rand(111, 999);
328
            }
329
330
            if ($filterObject->isListType()) {
331
                $whereCondition .= ' (:field_' . $filterObject->getFieldName() . $salt . ')';
332
            } else if ($filterObject->isFieldEqualityType()) {
333
                $whereCondition .= $this->entityAlias . '.' . $value;
334
            } else {
335
                $whereCondition .= ' :field_' . $filterObject->getFieldName() . $salt;
336
            }
337
338
            if ($orCondition['orCondition'] != null) {
339
                $orCondition['orCondition'] .= ' OR ' . $whereCondition;
340
            } else {
341
                $orCondition['orCondition'] = $whereCondition;
342
            }
343
344
            if ($filterObject->haveOperatorSubstitutionPattern()) {
345
                if ($filterObject->isListType()) {
346
                    $value = explode(',', $value);
347
                } else {
348
                    $value = str_replace(
349
                        '{string}',
350
                        $value,
351
                        $filterObject->getOperatorsSubstitutionPattern()
352
                    );
353
                }
354
            }
355
356
            $orCondition['parameters'][] = [
357
                'field' => 'field_' . $filterObject->getFieldName() . $salt,
358
                'value' => $value
359
            ];
360
        } else {
361
            $isNotARelation = 0 !== strpos($filterObject->getFieldName(), 'Embedded.');
362
            if ($isNotARelation) {
363
                    $whereCondition .= ' ' . $this->entityAlias . '.' . $value;
364
                if ($orCondition['orCondition'] != null) {
365
                    $orCondition['orCondition'] .= ' OR ' . $whereCondition;
366
                } else {
367
                    $orCondition['orCondition'] = $whereCondition;
368
                }
369
            }
370
        }
371
372
        // controllo se il filtro si riferisce ad una relazione dell'entità quindi devo fare dei join
373
        // esempio per users: filtering[_embedded.groups.name|eq]=admin
374
        if (strstr($filterObject->getRawFilter(), '_embedded.')) {
375
376
            $this->join($filterObject->getRawFilter());
377
            $relationEntityAlias = $this->getRelationEntityAlias();
378
379
            $embeddedFields = explode('.', $filterObject->getFieldName());
380
            $embeddableFieldName = $this->parser->camelize($embeddedFields[count($embeddedFields)-1]);
381
382
            $salt = '';
383
            foreach ($this->qBuilder->getParameters() as $parameter) {
384
                if ($parameter->getName() == 'field_' . $embeddableFieldName) {
385
                    $salt = '_' . rand(111, 999);
386
                }
387
            }
388
389
            if ($salt == '') {
390
                $salt = '_' . rand(111, 999);
391
            }
392
393
            $whereCondition = $relationEntityAlias . '.' . $embeddableFieldName . ' '
394
                . $filterObject->getOperatorMeta();
395
396
            if (isset($filterAndOperator[1]) && $op->isListOrNlist()) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $op seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $filterAndOperator seems to never exist and therefore isset should always be false.
Loading history...
397
                $whereCondition .= ' (:field_' . $embeddableFieldName . $salt . ')';
398
            } else {
399
                $whereCondition .=' :field_' . $embeddableFieldName . $salt;
400
            }
401
402
            if ($orCondition['orCondition'] != null) {
403
                $orCondition['orCondition'] .= ' OR ' . $whereCondition;
404
            } else {
405
                $orCondition['orCondition'] = $whereCondition;
406
            }
407
408
            if ($filterObject->haveOperatorSubstitutionPattern()) {
409
                if ($filterObject->isListType()) {
410
                    $value = explode(',', $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

410
                    $value = explode(',', /** @scrutinizer ignore-type */ $value);
Loading history...
411
                } else {
412
                    $value = str_replace(
413
                        '{string}',
414
                        $value,
415
                        $filterObject->getOperatorsSubstitutionPattern()
416
                    );
417
                }
418
            }
419
420
            $orCondition['parameters'][] = [
421
                'field' => 'field_' . $embeddableFieldName . $salt,
422
                'value' => $value
423
            ];
424
        }
425
426
        return $orCondition;
427
    }
428
429
    public function sort()
430
    {
431
        if (!$this->fields) {
432
            throw new \RuntimeException(
433
                'Oops! Fields are not defined'
434
            );
435
        }
436
437
        if (null === $this->sorting) {
438
            throw new \RuntimeException(
439
                'Oops! Sorting is not defined'
440
            );
441
        }
442
443
        foreach ($this->sorting as $sort => $val) {
444
            $val = strtolower($val);
445
446
            $fieldName = $this->parser->camelize($sort);
447
448
            if (in_array($fieldName, $this->fields)) {
449
                $direction = ($val === self::DIRECTION_AZ) ? self::DIRECTION_AZ : self::DIRECTION_ZA;
450
                $this->qBuilder->addOrderBy($this->entityAlias .'.'. $fieldName, $direction);
451
            }
452
453
            if (strstr($sort, '_embedded.')) {
454
                $this->join($sort);
455
                $relationEntityAlias = $this->getRelationEntityAlias();
456
457
                $embeddedFields = explode('.', $sort);
458
                $fieldName = $this->parser->camelize($embeddedFields[2]);
459
                $direction = ($val === self::DIRECTION_AZ) ? self::DIRECTION_AZ : self::DIRECTION_ZA;
460
461
                $this->qBuilder->addOrderBy($relationEntityAlias.'.'.$fieldName, $direction);
462
            }
463
464
        }
465
466
        return $this;
467
    }
468
469
    public function getQueryBuilder()
470
    {
471
        if (!$this->qBuilder) {
472
            throw new \RuntimeException(
473
                "Oops! Query builder was never initialized! call ::createQueryBuilder('entityName', 'alias') to start."
474
            );
475
        }
476
477
        return $this->qBuilder;
478
    }
479
480
    private function setRelationEntityAlias(string $relationEntityAlias)
481
    {
482
        $this->relationEntityAlias = $relationEntityAlias;
483
    }
484
485
    private function getRelationEntityAlias()
486
    {
487
        return $this->relationEntityAlias;
488
    }
489
490
    public function setRel($rel)
491
    {
492
        $this->rel = $rel;
493
494
        return $this;
495
    }
496
497
    public function getRel()
498
    {
499
        return $this->rel;
500
    }
501
502
    public function setPrinting($printing)
503
    {
504
        $this->printing = $printing;
505
506
        return $this;
507
    }
508
509
    public function getPrinting()
510
    {
511
        return $this->printing;
512
    }
513
514
    public function setPage($page)
515
    {
516
        $this->page = $page;
517
518
        return $this;
519
    }
520
521
    public function getPage()
522
    {
523
        return $this->page;
524
    }
525
526
    public function setPageLength($pageLength)
527
    {
528
        $this->pageLength = $pageLength;
529
530
        return $this;
531
    }
532
533
    public function getPageLength()
534
    {
535
        return $this->pageLength;
536
    }
537
538
    public function setSelect( $select) : QueryBuilderFactory
539
    {
540
        $this->select = $select;
541
542
        return $this;
543
    }
544
545
    public function getSelect()
546
    {
547
        return $this->select;
548
    }
549
550
    public function getEntityManager()
551
    {
552
        return $this->manager;
553
    }
554
}
555