• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

contributte / datagrid / 15346293061

30 May 2025 12:00PM UTC coverage: 35.433% (-0.06%) from 35.492%
15346293061

push

github

f3l1x
QA: fix phpstan

4 of 7 new or added lines in 2 files covered. (57.14%)

127 existing lines in 9 files now uncovered.

1198 of 3381 relevant lines covered (35.43%)

0.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

55.65
/src/DataSource/NetteDatabaseTableDataSource.php
1
<?php declare(strict_types = 1);
2

3
namespace Contributte\Datagrid\DataSource;
4

5
use Contributte\Datagrid\AggregationFunction\IAggregationFunction;
6
use Contributte\Datagrid\Exception\DatagridDateTimeHelperException;
7
use Contributte\Datagrid\Filter\FilterDate;
8
use Contributte\Datagrid\Filter\FilterDateRange;
9
use Contributte\Datagrid\Filter\FilterMultiSelect;
10
use Contributte\Datagrid\Filter\FilterRange;
11
use Contributte\Datagrid\Filter\FilterSelect;
12
use Contributte\Datagrid\Filter\FilterText;
13
use Contributte\Datagrid\Utils\DateTimeHelper;
14
use Contributte\Datagrid\Utils\Sorting;
15
use LogicException;
16
use Nette\Database\Table\Selection;
17
use Nette\Utils\Strings;
18

19
class NetteDatabaseTableDataSource extends FilterableDataSource implements IDataSource
20
{
21

22
        protected array $data = [];
23

24
        public function __construct(protected Selection $dataSource, protected string $primaryKey)
1✔
25
        {
26
        }
1✔
27

28
        public function getCount(): int
29
        {
30
                $dataSourceSqlBuilder = $this->dataSource->getSqlBuilder();
1✔
31

32
                try {
33
                        $primary = $this->dataSource->getPrimary();
1✔
34

35
                } catch (LogicException) {
×
36
                        if ($dataSourceSqlBuilder->getGroup() !== '') {
×
37
                                return $this->dataSource->count(
×
38
                                        'DISTINCT ' . Strings::replace($dataSourceSqlBuilder->getGroup(), '~ (DESC|ASC)~')
×
39
                                );
40
                        }
41

42
                        return $this->dataSource->count('*');
×
43
                }
44

45
                if ($dataSourceSqlBuilder->getGroup() !== '') {
1✔
46
                        return $this->dataSource->count(
×
47
                                'DISTINCT ' . Strings::replace($dataSourceSqlBuilder->getGroup(), '~ (DESC|ASC)~')
×
48
                        );
49
                }
50

51
                return $this->dataSource->count(
1✔
52
                        $this->dataSource->getName() . '.' . (is_array($primary) ? reset($primary) : $primary)
1✔
53
                );
54
        }
55

56
        /**
57
         * {@inheritDoc}
58
         */
59
        public function getData(): array
60
        {
61
                return $this->data !== []
1✔
62
                        ? $this->data
1✔
63
                        : $this->dataSource->fetchAll();
1✔
64
        }
65

66
        /**
67
         * {@inheritDoc}
68
         */
69
        public function filterOne(array $condition): IDataSource
1✔
70
        {
71
                $this->dataSource->where($condition)->limit(1);
1✔
72

73
                return $this;
1✔
74
        }
75

76
        /**
77
         * @phpstan-param positive-int|0 $offset
78
         * @phpstan-param positive-int|0 $limit
79
         */
80
        public function limit(int $offset, int $limit): IDataSource
1✔
81
        {
82
                $this->data = $this->dataSource->limit($limit, $offset)->fetchAll();
1✔
83

84
                return $this;
1✔
85
        }
86

87
        public function sort(Sorting $sorting): IDataSource
1✔
88
        {
89
                if (is_callable($sorting->getSortCallback())) {
1✔
90
                        call_user_func(
×
91
                                $sorting->getSortCallback(),
×
92
                                $this->dataSource,
×
93
                                $sorting->getSort()
×
94
                        );
95

96
                        return $this;
×
97
                }
98

99
                $sort = $sorting->getSort();
1✔
100

101
                if ($sort !== []) {
1✔
102
                        $this->dataSource->getSqlBuilder()->setOrder([], []);
1✔
103

104
                        foreach ($sort as $column => $order) {
1✔
105
                                $this->dataSource->order(sprintf('%s %s', $column, $order));
1✔
106
                        }
107
                } else {
108
                        /**
109
                         * Has the statement already a order by clause?
110
                         */
111
                        if ($this->dataSource->getSqlBuilder()->getOrder() === []) {
×
112
                                $this->dataSource->order($this->primaryKey);
×
113
                        }
114
                }
115

116
                return $this;
1✔
117
        }
118

119
        public function processAggregation(IAggregationFunction $function): void
120
        {
121
                $function->processDataSource(clone $this->dataSource);
×
122
        }
123

124
        public function getDataSource(): Selection
125
        {
126
                return $this->dataSource;
×
127
        }
128

129
        protected function applyFilterDate(FilterDate $filter): void
130
        {
131
                $conditions = $filter->getCondition();
×
132

133
                try {
UNCOV
134
                        $date = DateTimeHelper::tryConvertToDateTime($conditions[$filter->getColumn()], [$filter->getPhpFormat()]);
×
135

UNCOV
136
                        $this->dataSource->where(sprintf('DATE(%s) = ?', $filter->getColumn()), $date->format('Y-m-d'));
×
UNCOV
137
                } catch (DatagridDateTimeHelperException) {
×
138
                        // ignore the invalid filter value
139
                }
140
        }
141

142
        protected function applyFilterDateRange(FilterDateRange $filter): void
143
        {
144
                $conditions = $filter->getCondition();
×
145

146
                $valueFrom = $conditions[$filter->getColumn()]['from'];
×
147
                $valueTo = $conditions[$filter->getColumn()]['to'];
×
148

149
                if ($valueFrom) {
×
150
                        try {
151
                                $dateFrom = DateTimeHelper::tryConvertToDateTime($valueFrom, [$filter->getPhpFormat()]);
×
UNCOV
152
                                $dateFrom->setTime(0, 0, 0);
×
153

UNCOV
154
                                $this->dataSource->where(
×
UNCOV
155
                                        sprintf('DATE(%s) >= ?', $filter->getColumn()),
×
UNCOV
156
                                        $dateFrom->format('Y-m-d')
×
157
                                );
158
                        } catch (DatagridDateTimeHelperException) {
×
159
                                // ignore the invalid filter value
160
                        }
161
                }
162

163
                if ($valueTo) {
×
164
                        try {
165
                                $dateTo = DateTimeHelper::tryConvertToDateTime($valueTo, [$filter->getPhpFormat()]);
×
UNCOV
166
                                $dateTo->setTime(23, 59, 59);
×
167

UNCOV
168
                                $this->dataSource->where(
×
UNCOV
169
                                        sprintf('DATE(%s) <= ?', $filter->getColumn()),
×
UNCOV
170
                                        $dateTo->format('Y-m-d')
×
171
                                );
UNCOV
172
                        } catch (DatagridDateTimeHelperException) {
×
173
                                // ignore the invalid filter value
174
                        }
175
                }
176
        }
177

178
        protected function applyFilterRange(FilterRange $filter): void
1✔
179
        {
180
                $conditions = $filter->getCondition();
1✔
181

182
                $valueFrom = $conditions[$filter->getColumn()]['from'];
1✔
183
                $valueTo = $conditions[$filter->getColumn()]['to'];
1✔
184

185
                if ($valueFrom !== '') {
1✔
186
                        $this->dataSource->where(sprintf('%s >= ?', $filter->getColumn()), $valueFrom);
1✔
187
                }
188

189
                if ($valueTo !== '') {
1✔
190
                        $this->dataSource->where(sprintf('%s <= ?', $filter->getColumn()), $valueTo);
1✔
191
                }
192
        }
1✔
193

194
        protected function applyFilterText(FilterText $filter): void
1✔
195
        {
196
                $or = [];
1✔
197
                $args = [];
1✔
198
                $bigOr = '(';
1✔
199
                $bigOrArgs = [];
1✔
200
                $condition = $filter->getCondition();
1✔
201

202
                $operator = $filter->hasConjunctionSearch() ? 'AND' : 'OR';
1✔
203

204
                foreach ($condition as $column => $value) {
1✔
205
                        $like = '(';
1✔
206
                        $args = [];
1✔
207

208
                        if ($filter->isExactSearch()) {
1✔
209
                                $like .= sprintf('%s = ? %s ', $column, $operator);
1✔
210
                                $args[] = sprintf('%s', $value);
1✔
211
                        } else {
212
                                $words = $filter->hasSplitWordsSearch() === false ? [$value] : explode(' ', $value);
1✔
213

214
                                foreach ($words as $word) {
1✔
215
                                        $like .= sprintf('%s LIKE ? %s ', $column, $operator);
1✔
216
                                        $args[] = sprintf('%%%s%%', $word);
1✔
217
                                }
218
                        }
219

220
                        $like = substr($like, 0, strlen($like) - (strlen($operator) + 2)) . ')';
1✔
221

222
                        $or[] = $like;
1✔
223
                        $bigOr .= sprintf('%s %s ', $like, $operator);
1✔
224
                        $bigOrArgs = [...$bigOrArgs, ...$args];
1✔
225
                }
226

227
                if (count($or) > 1) {
1✔
228
                        $bigOr = substr($bigOr, 0, strlen($bigOr) - (strlen($operator) + 2)) . ')';
1✔
229

230
                        $query = [...[$bigOr], ...$bigOrArgs];
1✔
231

232
                        call_user_func_array([$this->dataSource, 'where'], $query);
1✔
233
                } else {
234
                        $query = [...$or, ...$args];
1✔
235

236
                        call_user_func_array([$this->dataSource, 'where'], $query);
1✔
237
                }
238
        }
1✔
239

240
        protected function applyFilterMultiSelect(FilterMultiSelect $filter): void
241
        {
242
                $condition = $filter->getCondition();
×
243
                $values = $condition[$filter->getColumn()];
×
UNCOV
244
                $or = '(';
×
245

246
                if ((is_countable($values) ? count($values) : 0) > 1) {
×
247
                        $length = is_countable($values) ? count($values) : 0;
×
UNCOV
248
                        $i = 1;
×
249

UNCOV
250
                        for ($iterator = 0; $iterator < (is_countable($values) ? count($values) : 0); $iterator++) {
×
UNCOV
251
                                if ($i === $length) {
×
252
                                        $or .= $filter->getColumn() . ' = ?)';
×
253
                                } else {
UNCOV
254
                                        $or .= $filter->getColumn() . ' = ? OR ';
×
255
                                }
256

257
                                $i++;
×
258
                        }
259

UNCOV
260
                        array_unshift($values, $or);
×
261

UNCOV
262
                        call_user_func_array([$this->dataSource, 'where'], $values);
×
263
                } else {
UNCOV
264
                        $this->dataSource->where($filter->getColumn() . ' = ?', reset($values));
×
265
                }
266
        }
267

268
        protected function applyFilterSelect(FilterSelect $filter): void
1✔
269
        {
270
                $this->dataSource->where($filter->getCondition());
1✔
271
        }
1✔
272

273
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc