AbstractComposite   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 30
c 1
b 0
f 0
dl 0
loc 60
rs 10
wmc 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A createNewQueryBuilder() 0 10 2
A filter() 0 27 6
A applyConditions() 0 9 2
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