AbstractComposite::createNewQueryBuilder()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 10
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arp\DoctrineQueryFilter\Filter;
6
7
use Arp\DoctrineQueryFilter\Enum\WhereType;
8
use Arp\DoctrineQueryFilter\Exception\QueryFilterManagerException;
9
use Arp\DoctrineQueryFilter\Filter\Exception\FilterException;
10
use Arp\DoctrineQueryFilter\Metadata\MetadataInterface;
11
use Arp\DoctrineQueryFilter\QueryBuilderInterface;
12
use Doctrine\ORM\Query\Expr\Composite;
13
14
abstract class AbstractComposite extends AbstractFilter
15
{
16
    abstract protected function createComposite(QueryBuilderInterface $queryBuilder): Composite;
17
18
    /**
19
     * @throws FilterException
20
     */
21
    public function filter(QueryBuilderInterface $queryBuilder, MetadataInterface $metadata, array $criteria): void
22
    {
23
        if (empty($criteria['conditions'])) {
24
            return;
25
        }
26
        $qb = $this->createNewQueryBuilder($queryBuilder);
27
        $this->applyConditions($qb, $metadata, $criteria['conditions']);
28
29
        $parts = $qb->getQueryParts();
30
        if (
31
            !isset($parts['where'])
32
            || (!$parts['where'] instanceof Composite)
33
            || (!method_exists($parts['where'], 'getParts'))
34
        ) {
35
            return;
36
        }
37
38
        $compositeExpr = $this->createComposite($queryBuilder);
39
        $compositeExpr->addMultiple($parts['where']->getParts());
40
41
        if ($this->getWhereType($criteria) === WhereType::AND) {
42
            $queryBuilder->andWhere($compositeExpr);
43
        } else {
44
            $queryBuilder->orWhere($compositeExpr);
45
        }
46
47
        $queryBuilder->mergeParameters($qb);
48
    }
49
50
    protected function createNewQueryBuilder(QueryBuilderInterface $queryBuilder): QueryBuilderInterface
51
    {
52
        $qb = $queryBuilder->createQueryBuilder();
53
54
        $alias = $queryBuilder->getRootAlias();
55
        if (!empty($alias)) {
56
            $qb->setRootAlias($alias);
57
        }
58
59
        return $qb;
60
    }
61
62
    /**
63
     * @throws FilterException
64
     */
65
    private function applyConditions(QueryBuilderInterface $qb, MetadataInterface $metadata, iterable $conditions): void
66
    {
67
        try {
68
            $this->queryFilterManager->filter($qb, $metadata->getName(), ['filters' => $conditions]);
69
        } catch (QueryFilterManagerException $e) {
70
            throw new FilterException(
71
                sprintf('Failed to construct query filter \'%s\' conditions', static::class),
72
                $e->getCode(),
73
                $e
74
            );
75
        }
76
    }
77
}
78