QueryBuilderAdapter::getRootAlias()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php declare(strict_types=1);
2
3
namespace Mgid\Component\Pagination\Adapter\Doctrine\ORM;
4
5
use Doctrine\ORM\QueryBuilder;
6
use Mgid\Component\Pagination\Contract\SortableInterface;
7
use Mgid\Component\Pagination\Contract\PaginationInterface;
8
use Mgid\Component\Pagination\Contract\FilterableInterface;
9
use Mgid\Component\Pagination\Adapter\QueryBuilderAdapterInterface;
10
11
final class QueryBuilderAdapter implements QueryBuilderAdapterInterface
12
{
13
    private const OPERATORS = [
14
        FilterableInterface::EQUAL => 'eq',
15
        FilterableInterface::NOT_EQUAL => 'neq',
16
        FilterableInterface::IN => 'in',
17
        FilterableInterface::NOT_IN => 'notIn',
18
        FilterableInterface::LESS_THEN => 'lt',
19
        FilterableInterface::LESS_THEN_OR_EQUAL => 'lte',
20
        FilterableInterface::GREATER_THEN => 'gt',
21
        FilterableInterface::GREATER_THEN_OR_EQUAL => 'gte',
22
        FilterableInterface::LIKE => 'like',
23
    ];
24
25
    /**
26
     * @var QueryBuilder
27
     */
28
    private QueryBuilder $builder;
29
30
    /**
31
     * @param QueryBuilder $builder
32
     */
33
    public function __construct(QueryBuilder $builder)
34
    {
35
        $this->builder = $builder;
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function getRootAlias(): ?string
42
    {
43
        return $this->builder->getRootAliases()[0] ?? null;
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function addOrders(SortableInterface $sortable): void
50
    {
51
        foreach ($sortable->getOrders() as $fieldName => $order) {
52
            $this->builder->addOrderBy($fieldName, $order);
53
        }
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function addFilters(FilterableInterface $filterable): void
60
    {
61
        $i = 0;
62
        $expr = $this->builder->expr();
63
64
        foreach ($filterable->getFilters() as $fieldName => $operators) {
65
            foreach ($operators as $operator => $value) {
66
                $this->builder->setParameter(++$i, $value);
67
                $this->builder->andWhere($expr->{$this->getOperator($operator)}($fieldName, \sprintf('?%d', $i)));
68
            }
69
        }
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function addPagination(PaginationInterface $pagination): void
76
    {
77
        if ($pagination->getOffset() > 0) {
78
            $this->builder->setFirstResult($pagination->getOffset());
79
        }
80
81
        if ($pagination->getLimit() > 0) {
82
            $this->builder->setMaxResults($pagination->getLimit());
83
        }
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     *
89
     * @throws \Doctrine\ORM\NoResultException
90
     * @throws \Doctrine\ORM\NonUniqueResultException
91
     */
92
    public function getCount(): int
93
    {
94
        return (int) (clone $this->builder)->select('COUNT(1)')->getQuery()->getSingleScalarResult();
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100
    public function getItems(): iterable
101
    {
102
        return $this->builder->getQuery()->getArrayResult();
103
    }
104
105
    /**
106
     * @param string $alias
107
     *
108
     * @return string
109
     */
110
    private function getOperator(string $alias): string
111
    {
112
        return self::OPERATORS[$alias];
113
    }
114
}
115