QueryBuilderDataProvider   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 69
c 2
b 1
f 0
dl 0
loc 126
rs 10
wmc 16

12 Methods

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