Passed
Pull Request — master (#5)
by Alex
02:11
created

AbstractComposite::applyConditions()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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