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

contributte / datagrid / 8230157862

11 Mar 2024 09:02AM UTC coverage: 34.102%. First build
8230157862

Pull #1060

github

radimvaculik
Fix failing tests
Pull Request #1060: [7.x] Next

117 of 435 new or added lines in 54 files covered. (26.9%)

1124 of 3296 relevant lines covered (34.1%)

0.34 hits per line

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

56.59
/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✔
54
                                        $data = (array) call_user_func_array(
×
55
                                                $filter->getConditionCallback(),
×
56
                                                [$this->data, $filter->getValue()]
×
57
                                        );
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

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

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✔
98
                        $data = call_user_func(
×
99
                                $sorting->getSortCallback(),
×
100
                                $this->data,
×
101
                                $sorting->getSort()
×
102
                        );
103

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

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

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
                                $sort_by = is_object($item[$column]) && $item[$column] instanceof DateTimeInterface
1✔
120
                                        ? $item[$column]->format('Y-m-d H:i:s')
×
121
                                        : (string) $item[$column];
1✔
122

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

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

132
                        $dataSource = [];
1✔
133

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

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

143
                return $this;
1✔
144
        }
145

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

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

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

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

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

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

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

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

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

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

183
                                foreach ($words as $word) {
1✔
184
                                        if (str_contains($row_value, strtolower(Strings::toAscii($word)))) {
1✔
185
                                                return $row;
1✔
186
                                        }
187
                                }
188
                        }
189
                }
190

191
                return false;
1✔
192
        }
193

194
        protected function applyFilterMultiSelect(mixed $row, FilterMultiSelect $filter): bool
195
        {
196
                $condition = $filter->getCondition();
×
197
                $values = $condition[$filter->getColumn()];
×
198

199
                return in_array($row[$filter->getColumn()], $values, true);
×
200
        }
201

202
        protected function applyFilterRange(mixed $row, FilterRange $filter): bool
1✔
203
        {
204
                $condition = $filter->getCondition();
1✔
205
                $values = $condition[$filter->getColumn()];
1✔
206

207
                if ($values['from'] !== null && $values['from'] !== '') {
1✔
208
                        if ($values['from'] > $row[$filter->getColumn()]) {
1✔
209
                                return false;
1✔
210
                        }
211
                }
212

213
                if ($values['to'] !== null && $values['to'] !== '') {
1✔
214
                        if ($values['to'] < $row[$filter->getColumn()]) {
1✔
215
                                return false;
1✔
216
                        }
217
                }
218

219
                return true;
1✔
220
        }
221

222
        protected function applyFilterDateRange(mixed $row, FilterDateRange $filter): bool
223
        {
224
                $format = $filter->getPhpFormat();
×
225
                $condition = $filter->getCondition();
×
226
                $values = $condition[$filter->getColumn()];
×
227
                $row_value = $row[$filter->getColumn()];
×
228

229
                if ($values['from'] !== null && $values['from'] !== '') {
×
230
                        $date_from = DateTimeHelper::tryConvertToDate($values['from'], [$format]);
×
231
                        $date_from->setTime(0, 0, 0);
×
232

233
                        if (!($row_value instanceof DateTime)) {
×
234
                                /**
235
                                 * Try to convert string to DateTime object
236
                                 */
237
                                try {
238
                                        $row_value = DateTimeHelper::tryConvertToDate($row_value);
×
NEW
239
                                } catch (DatagridDateTimeHelperException) {
×
240
                                        /**
241
                                         * Otherwise just return raw string
242
                                         */
243
                                        return false;
×
244
                                }
245
                        }
246

247
                        if ($row_value->getTimestamp() < $date_from->getTimestamp()) {
×
248
                                return false;
×
249
                        }
250
                }
251

252
                if ($values['to'] !== null && $values['to'] !== '') {
×
253
                        $date_to = DateTimeHelper::tryConvertToDate($values['to'], [$format]);
×
254
                        $date_to->setTime(23, 59, 59);
×
255

256
                        if (!($row_value instanceof DateTime)) {
×
257
                                /**
258
                                 * Try to convert string to DateTime object
259
                                 */
260
                                try {
261
                                        $row_value = DateTimeHelper::tryConvertToDate($row_value);
×
NEW
262
                                } catch (DatagridDateTimeHelperException) {
×
263
                                        /**
264
                                         * Otherwise just return raw string
265
                                         */
266
                                        return false;
×
267
                                }
268
                        }
269

270
                        if ($row_value->getTimestamp() > $date_to->getTimestamp()) {
×
271
                                return false;
×
272
                        }
273
                }
274

275
                return true;
×
276
        }
277

278
        /**
279
         * Apply fitler date and tell whether row value matches or not
280
         */
281
        protected function applyFilterDate(mixed $row, FilterDate $filter): bool
282
        {
283
                $format = $filter->getPhpFormat();
×
284
                $condition = $filter->getCondition();
×
285

286
                foreach ($condition as $column => $value) {
×
287
                        $row_value = $row[$column];
×
288

289
                        $date = DateTimeHelper::tryConvertToDateTime($value, [$format]);
×
290

291
                        if (!($row_value instanceof DateTime)) {
×
292
                                /**
293
                                 * Try to convert string to DateTime object
294
                                 */
295
                                try {
296
                                        $row_value = DateTimeHelper::tryConvertToDateTime($row_value);
×
NEW
297
                                } catch (DatagridDateTimeHelperException) {
×
298
                                        /**
299
                                         * Otherwise just return raw string
300
                                         */
301
                                        return false;
×
302
                                }
303
                        }
304

305
                        return $row_value->format($format) === $date->format($format);
×
306
                }
307

308
                return false;
×
309
        }
310

311
        /**
312
         * Set the data
313
         */
314
        private function setData(array $dataSource): IDataSource
1✔
315
        {
316
                $this->data = $dataSource;
1✔
317

318
                return $this;
1✔
319
        }
320

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

© 2025 Coveralls, Inc