Completed
Branch feature/rework (8c4d59)
by Pavel
07:53
created

QueryBuilderDataProvider::gteDate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
4
namespace Pfilsx\DataGrid\Grid\Providers;
5
6
7
use DateTime;
8
use Doctrine\ORM\EntityManager;
9
use Doctrine\ORM\QueryBuilder;
10
use Pfilsx\DataGrid\DataGridException;
11
use Pfilsx\DataGrid\Grid\DataGridItem;
12
use Pfilsx\DataGrid\Grid\Hydrators\DataGridHydrator;
13
use ReflectionClass;
14
15
class QueryBuilderDataProvider extends DataProvider
16
{
17
    /**
18
     * @var QueryBuilder
19
     */
20
    protected $builder;
21
    protected $entityManager;
22
23
    public function __construct(QueryBuilder $builder, EntityManager $manager)
24
    {
25
        $this->builder = $builder;
26
        $this->entityManager = $manager;
27
    }
28
29
    public function getItems(): array
30
    {
31
        $this->builder
32
            ->setMaxResults($this->getPager()->getLimit())
33
            ->setFirstResult($this->getPager()->getFirst());
34
35
        $hydrator = new ReflectionClass(DataGridHydrator::class);
36
        $hydratorName = $hydrator->getShortName();
37
        $this->builder->getEntityManager()->getConfiguration()
38
            ->addCustomHydrationMode($hydratorName, DataGridHydrator::class);
39
40
        return array_map(function ($row) {
41
            $item = new DataGridItem();
42
            $item->setRow($row);
43
            $item->setEntityManager($this->entityManager);
44
            return $item;
45
        }, $this->builder->getQuery()->getResult($hydratorName));
46
    }
47
48
    public function getTotalCount(): int
49
    {
50
        if (empty($this->countFieldName)) {
51
            throw new DataGridException("countableFieldName must be set for " . static::class);
52
        }
53
        $countQueryBuilder = clone($this->builder);
54
        $countQueryBuilder->select("count({$this->countFieldName})");
55
        $countQueryBuilder->setMaxResults(null);
56
        $countQueryBuilder->setFirstResult(null);
57
        $countQueryBuilder->resetDQLPart('groupBy');
58
        $countQueryBuilder->resetDQLPart('orderBy');
59
60
        return $countQueryBuilder->getQuery()->getSingleScalarResult();
61
    }
62
63
    public function setSort(array $sort): DataProviderInterface
64
    {
65
        foreach ($sort as $key => $value) {
66
            $this->builder->addOrderBy($key, $value);
67
        }
68
        return $this;
69
    }
70
71
    public function addEqualFilter(string $attribute, $value): DataProviderInterface
72
    {
73
        if ($value === null) {
74
            $this->builder->andWhere($this->builder->expr()->isNull($attribute));
75
        } else {
76
            $placeholderName = str_replace('.', '_', $attribute);
77
            $this->builder->andWhere($this->builder->expr()->eq($attribute, ':' . $placeholderName));
78
            $this->builder->setParameter($placeholderName, $value);
79
        }
80
        return $this;
81
    }
82
83
    public function addLikeFilter(string $attribute, $value): DataProviderInterface
84
    {
85
        $placeholderName = str_replace('.', '_', $attribute);
86
        $this->builder->andWhere($this->builder->expr()->like('lower(' . $attribute . ')', ':' . $placeholderName));
87
        $this->builder->setParameter($placeholderName, '%' . mb_strtolower($value) . '%');
88
        return $this;
89
    }
90
91
    public function addCustomFilter(string $attribute, $value, callable $callback): DataProviderInterface
92
    {
93
        $builder = $this->builder;
94
        call_user_func_array($callback, [&$builder, $attribute, $value]);
95
        return $this;
96
    }
97
98
    protected function equalDate($attribute, $value): void
99
    {
100
        $date = new DateTime($value);
101
        $nextDate = (clone $date)->modify('+1 day');
102
        $placeholderName = str_replace('.', '_', $attribute);
103
        $placeholderNameNext = str_replace('.', '_', $attribute) . '_next';
104
        $this->builder
105
            ->andWhere($this->builder->expr()->gte($attribute, ':' . $placeholderName))
106
            ->andWhere($this->builder->expr()->lt($attribute, ':' . $placeholderNameNext));
107
        $this->builder->setParameters([
108
            $placeholderName => $date,
109
            $placeholderNameNext => $nextDate
110
        ]);
111
    }
112
113
    protected function ltDate($attribute, $value): void
114
    {
115
        $date = new DateTime($value);
116
        $placeholderName = str_replace('.', '_', $attribute);
117
        $this->builder
118
            ->andWhere($this->builder->expr()->lt($attribute, ':' . $placeholderName));
119
        $this->builder->setParameter($placeholderName, $date);
120
    }
121
122
    protected function lteDate($attribute, $value): void
123
    {
124
        $date = (new DateTime($value))->modify('+1 day');
125
        $placeholderName = str_replace('.', '_', $attribute);
126
        $this->builder
127
            ->andWhere($this->builder->expr()->lt($attribute, ':' . $placeholderName));
128
        $this->builder->setParameter($placeholderName, $date);
129
    }
130
131
    protected function gtDate($attribute, $value): void
132
    {
133
        $date = (new DateTime($value))->modify('+1 day');
134
        $placeholderName = str_replace('.', '_', $attribute);
135
        $this->builder
136
            ->andWhere($this->builder->expr()->gte($attribute, ':' . $placeholderName));
137
        $this->builder->setParameter($placeholderName, $date);
138
    }
139
140
    protected function gteDate($attribute, $value): void
141
    {
142
        $date = new DateTime($value);
143
        $placeholderName = str_replace('.', '_', $attribute);
144
        $this->builder
145
            ->andWhere($this->builder->expr()->gte($attribute, ':' . $placeholderName));
146
        $this->builder->setParameter($placeholderName, $date);
147
    }
148
}