• 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

58.65
/src/DataSource/ArrayDataSource.php
1
<?php declare(strict_types = 1);
2

3
namespace Contributte\Datagrid\DataSource;
4

5
use ArrayAccess;
6
use Contributte\Datagrid\Exception\DatagridArrayDataSourceException;
7
use Contributte\Datagrid\Exception\DatagridDateTimeHelperException;
8
use Contributte\Datagrid\Filter\Filter;
9
use Contributte\Datagrid\Filter\FilterDate;
10
use Contributte\Datagrid\Filter\FilterDateRange;
11
use Contributte\Datagrid\Filter\FilterMultiSelect;
12
use Contributte\Datagrid\Filter\FilterRange;
13
use Contributte\Datagrid\Filter\FilterSelect;
14
use Contributte\Datagrid\Filter\FilterText;
15
use Contributte\Datagrid\Utils\DateTimeHelper;
16
use Contributte\Datagrid\Utils\Sorting;
17
use DateTime;
18
use DateTimeInterface;
19
use Nette\Utils\Strings;
20

21
class ArrayDataSource implements IDataSource
22
{
23

24
        protected array $data = [];
25

26
        protected int $count = 0;
27

28
        public function __construct(array $dataSource)
1✔
29
        {
30
                $this->setData($dataSource);
1✔
31
        }
1✔
32

33
        public function getCount(): int
34
        {
35
                return count($this->data);
1✔
36
        }
37

38
        /**
39
         * {@inheritDoc}
40
         */
41
        public function getData(): array
42
        {
43
                return $this->data;
1✔
44
        }
45

46
        /**
47
         * {@inheritDoc}
48
         */
49
        public function filter(array $filters): void
1✔
50
        {
51
                foreach ($filters as $filter) {
1✔
52
                        if ($filter->isValueSet()) {
1✔
53
                                if ($filter->getConditionCallback() !== null) {
1✔
UNCOV
54
                                        $data = (array) call_user_func_array(
×
55
                                                $filter->getConditionCallback(),
×
56
                                                [$this->data, $filter->getValue()]
×
57
                                        );
UNCOV
58
                                        $this->setData($data);
×
59
                                } else {
60
                                        $data = array_filter($this->data, fn ($row) => $this->applyFilter($row, $filter));
1✔
61
                                        $this->setData($data);
1✔
62
                                }
63
                        }
64
                }
65
        }
1✔
66

67
        /**
68
         * {@inheritDoc}
69
         */
70
        public function filterOne(array $condition): IDataSource
1✔
71
        {
72
                foreach ($this->data as $item) {
1✔
73
                        foreach ($condition as $key => $value) {
1✔
74
                                if ($item[$key] === $value) {
1✔
75
                                        $this->setData([$item]);
1✔
76

77
                                        return $this;
1✔
78
                                }
79
                        }
80
                }
81

UNCOV
82
                $this->setData([]);
×
83

UNCOV
84
                return $this;
×
85
        }
86

87
        public function limit(int $offset, int $limit): IDataSource
1✔
88
        {
89
                $data = array_slice($this->data, $offset, $limit);
1✔
90
                $this->setData($data);
1✔
91

92
                return $this;
1✔
93
        }
94

95
        public function sort(Sorting $sorting): IDataSource
1✔
96
        {
97
                if (is_callable($sorting->getSortCallback())) {
1✔
UNCOV
98
                        $data = call_user_func(
×
99
                                $sorting->getSortCallback(),
×
100
                                $this->data,
×
101
                                $sorting->getSort()
×
102
                        );
103

UNCOV
104
                        if (!is_array($data)) {
×
105
                                throw new DatagridArrayDataSourceException('Sorting callback has to return array');
×
106
                        }
107

UNCOV
108
                        $this->setData($data);
×
109

UNCOV
110
                        return $this;
×
111
                }
112

113
                $sort = $sorting->getSort();
1✔
114

115
                foreach ($sort as $column => $order) {
1✔
116
                        $data = [];
1✔
117

118
                        foreach ($this->data as $item) {
1✔
119
                                $value = is_object($item) ? $item->$column : $item[$column]; // @phpstan-ignore-line
1✔
120
                                $sort_by = $value instanceof DateTimeInterface ? $value->format('Y-m-d H:i:s') : (string) $value;
1✔
121

122
                                $data[$sort_by][] = $item;
1✔
123
                        }
124

125
                        if ($order === 'ASC') {
1✔
UNCOV
126
                                ksort($data, SORT_LOCALE_STRING);
×
127
                        } else {
128
                                krsort($data, SORT_LOCALE_STRING);
1✔
129
                        }
130

131
                        $dataSource = [];
1✔
132

133
                        foreach ($data as $i) {
1✔
134
                                foreach ($i as $item) {
1✔
135
                                        $dataSource[] = $item;
1✔
136
                                }
137
                        }
138

139
                        $this->setData($dataSource);
1✔
140
                }
141

142
                return $this;
1✔
143
        }
144

145
        protected function applyFilter(mixed $row, Filter $filter): mixed
1✔
146
        {
147
                if (is_array($row) || $row instanceof ArrayAccess) {
1✔
148
                        if ($filter instanceof FilterDate) {
1✔
UNCOV
149
                                return $this->applyFilterDate($row, $filter);
×
150
                        }
151

152
                        if ($filter instanceof FilterMultiSelect) {
1✔
UNCOV
153
                                return $this->applyFilterMultiSelect($row, $filter);
×
154
                        }
155

156
                        if ($filter instanceof FilterDateRange) {
1✔
UNCOV
157
                                return $this->applyFilterDateRange($row, $filter);
×
158
                        }
159

160
                        if ($filter instanceof FilterRange) {
1✔
161
                                return $this->applyFilterRange($row, $filter);
1✔
162
                        }
163

164
                        $condition = $filter->getCondition();
1✔
165

166
                        foreach ($condition as $column => $value) {
1✔
167
                                $value = (string) $value;
1✔
168
                                $rowVal = (string) $row[$column];
1✔
169

170
                                if ($filter instanceof FilterSelect) {
1✔
171
                                        return $rowVal === $value;
1✔
172
                                }
173

174
                                if ($filter instanceof FilterText && $filter->isExactSearch()) {
1✔
175
                                        return $rowVal === $value;
1✔
176
                                }
177

178
                                $words = $filter instanceof FilterText && $filter->hasSplitWordsSearch() === false ? [$value] : explode(' ', $value);
1✔
179

180
                                $row_value = strtolower(Strings::toAscii((string) $row[$column]));
1✔
181

182
                                $found = [];
1✔
183

184
                                foreach ($words as $word) {
1✔
185
                                        if (str_contains($row_value, strtolower(Strings::toAscii($word)))) {
1✔
186
                                                if ($filter instanceof FilterText && !$filter->hasConjunctionSearch()) {
1✔
187
                                                        return $row;
1✔
188
                                                } else {
189
                                                        $found[] = true;
1✔
190
                                                }
191
                                        }
192
                                }
193

194
                                if (count($found) === count($words)) {
1✔
195
                                        return $row;
1✔
196
                                }
197
                        }
198
                }
199

200
                return false;
1✔
201
        }
202

203
        protected function applyFilterMultiSelect(mixed $row, FilterMultiSelect $filter): bool
204
        {
UNCOV
205
                $condition = $filter->getCondition();
×
206
                $values = $condition[$filter->getColumn()];
×
207

UNCOV
208
                return in_array($row[$filter->getColumn()], $values, true);
×
209
        }
210

211
        protected function applyFilterRange(mixed $row, FilterRange $filter): bool
1✔
212
        {
213
                $condition = $filter->getCondition();
1✔
214
                $values = $condition[$filter->getColumn()];
1✔
215

216
                if ($values['from'] !== null && $values['from'] !== '') {
1✔
217
                        if ($values['from'] > $row[$filter->getColumn()]) {
1✔
218
                                return false;
1✔
219
                        }
220
                }
221

222
                if ($values['to'] !== null && $values['to'] !== '') {
1✔
223
                        if ($values['to'] < $row[$filter->getColumn()]) {
1✔
224
                                return false;
1✔
225
                        }
226
                }
227

228
                return true;
1✔
229
        }
230

231
        protected function applyFilterDateRange(mixed $row, FilterDateRange $filter): bool
232
        {
UNCOV
233
                $format = $filter->getPhpFormat();
×
234
                $condition = $filter->getCondition();
×
235
                $values = $condition[$filter->getColumn()];
×
236
                $row_value = $row[$filter->getColumn()];
×
237

UNCOV
238
                if ($values['from'] !== null && $values['from'] !== '') {
×
239
                        $date_from = DateTimeHelper::tryConvertToDate($values['from'], [$format]);
×
240
                        $date_from->setTime(0, 0, 0);
×
241

UNCOV
242
                        if (!($row_value instanceof DateTime)) {
×
243
                                /**
244
                                 * Try to convert string to DateTime object
245
                                 */
246
                                try {
UNCOV
247
                                        $row_value = DateTimeHelper::tryConvertToDate($row_value);
×
248
                                } catch (DatagridDateTimeHelperException) {
×
249
                                        /**
250
                                         * Otherwise just return raw string
251
                                         */
UNCOV
252
                                        return false;
×
253
                                }
254
                        }
255

UNCOV
256
                        if ($row_value->getTimestamp() < $date_from->getTimestamp()) {
×
257
                                return false;
×
258
                        }
259
                }
260

UNCOV
261
                if ($values['to'] !== null && $values['to'] !== '') {
×
262
                        $date_to = DateTimeHelper::tryConvertToDate($values['to'], [$format]);
×
263
                        $date_to->setTime(23, 59, 59);
×
264

UNCOV
265
                        if (!($row_value instanceof DateTime)) {
×
266
                                /**
267
                                 * Try to convert string to DateTime object
268
                                 */
269
                                try {
UNCOV
270
                                        $row_value = DateTimeHelper::tryConvertToDate($row_value);
×
271
                                } catch (DatagridDateTimeHelperException) {
×
272
                                        /**
273
                                         * Otherwise just return raw string
274
                                         */
UNCOV
275
                                        return false;
×
276
                                }
277
                        }
278

UNCOV
279
                        if ($row_value->getTimestamp() > $date_to->getTimestamp()) {
×
280
                                return false;
×
281
                        }
282
                }
283

UNCOV
284
                return true;
×
285
        }
286

287
        /**
288
         * Apply fitler date and tell whether row value matches or not
289
         */
290
        protected function applyFilterDate(mixed $row, FilterDate $filter): bool
291
        {
UNCOV
292
                $format = $filter->getPhpFormat();
×
293
                $condition = $filter->getCondition();
×
294

UNCOV
295
                foreach ($condition as $column => $value) {
×
296
                        $row_value = $row[$column];
×
297

UNCOV
298
                        $date = DateTimeHelper::tryConvertToDateTime($value, [$format]);
×
299

UNCOV
300
                        if (!($row_value instanceof DateTime)) {
×
301
                                /**
302
                                 * Try to convert string to DateTime object
303
                                 */
304
                                try {
UNCOV
305
                                        $row_value = DateTimeHelper::tryConvertToDateTime($row_value);
×
306
                                } catch (DatagridDateTimeHelperException) {
×
307
                                        /**
308
                                         * Otherwise just return raw string
309
                                         */
UNCOV
310
                                        return false;
×
311
                                }
312
                        }
313

UNCOV
314
                        return $row_value->format($format) === $date->format($format);
×
315
                }
316

UNCOV
317
                return false;
×
318
        }
319

320
        /**
321
         * Set the data
322
         */
323
        private function setData(array $dataSource): IDataSource
1✔
324
        {
325
                $this->data = $dataSource;
1✔
326

327
                return $this;
1✔
328
        }
329

330
}
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