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

contributte / datagrid / 8416932662

13 Mar 2024 12:24PM UTC coverage: 34.102%. Remained the same
8416932662

push

github

web-flow
[7.x] Next (#1060)

* PHP 8.0

* Translator: switch from ITranslator to Translator (#973)

* [7.x] Bootstrap 5 + PHP 8 + vanilla javascript (#1021)

* Bootstrap 5

* Bootstrap 5 (docs)

* Bootstrap 5

* form-control -> form-select

* Bump bootstrap-select for Bootstrap 5 support

* Removed `input-sm` from Bootstrap 3

See https://getbootstrap.com/docs/4.0/migration/#forms-1

* Bootstrap 5: When selectpicker, replace form-select classes with form-control and refresh it

* Hide `underline` also for `dropdown-item`. And merged into one CSS rule.

* Update the filterMultiSelect initialization

* Text-align: left -> start

Co-authored-by: Radim Vaculík <radim.vaculik@gmail.com>
Co-authored-by: Jaroslav Líbal <jaroslav.libal@neatous.cz>

* [7.x] phpstan-deprecation-rules (#1061)

* Fix sort

* Add method for setting custom Action href, v6.x (#853)

* [7.x] Nextras ORM 4 support, closes #984

* Fix ElasticsearchDataSource.php data source (#1041)

* Error: Typed property Ublaboo\DataGrid\InlineEdit\InlineEdit::$itemID must not be accessed before initialization

* composer: allow-plugins: php-http/discovery

* ItemDetailForm: $httpPost: Typed property must not be accessed...

* phpstan: revert  --memory-limit=4G

* NetteDatabaseSelectionHelper: Context -> Explorer, getSupplementalDriver -> getDriver

* Update README.md

* Templates: fix variables

* data-bs-toggle attribute for multiaction button (#1072)

* dependabot.yml (#1078)

* Allow nette/utils:4.0 (#1077)

* Add onColumnShow and onColumnHide event methods (#1076)

* Add onColumnShow and onColumnHide event methods

* Add native type array

* Removed duplicity

* Return value of BackedEnum when reading Doctrine entity property. (#1081)

* Return value of BackedEnum when reading array value (#1083)

* Added method to check if filter is on default values; Closes #1082 (#1084)

* ublaboo -> contributte (#1067) (#1075)

* Delete depe... (continued)

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

1455 existing lines in 67 files now uncovered.

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

55.26
/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

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

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

45
                if ($dataSourceSqlBuilder->getGroup() !== '') {
1✔
UNCOV
46
                        return $this->dataSource->count(
×
UNCOV
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✔
UNCOV
90
                        call_user_func(
×
UNCOV
91
                                $sorting->getSortCallback(),
×
UNCOV
92
                                $this->dataSource,
×
93
                                $sorting->getSort()
×
94
                        );
95

UNCOV
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() === []) {
×
UNCOV
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
        protected function applyFilterDate(FilterDate $filter): void
125
        {
UNCOV
126
                $conditions = $filter->getCondition();
×
127

128
                try {
UNCOV
129
                        $date = DateTimeHelper::tryConvertToDateTime($conditions[$filter->getColumn()], [$filter->getPhpFormat()]);
×
130

NEW
131
                        $this->dataSource->where(sprintf('DATE(%s) = ?', $filter->getColumn()), $date->format('Y-m-d'));
×
NEW
132
                } catch (DatagridDateTimeHelperException) {
×
133
                        // ignore the invalid filter value
134
                }
135
        }
136

137
        protected function applyFilterDateRange(FilterDateRange $filter): void
138
        {
UNCOV
139
                $conditions = $filter->getCondition();
×
140

UNCOV
141
                $valueFrom = $conditions[$filter->getColumn()]['from'];
×
UNCOV
142
                $valueTo = $conditions[$filter->getColumn()]['to'];
×
143

UNCOV
144
                if ($valueFrom) {
×
145
                        try {
UNCOV
146
                                $dateFrom = DateTimeHelper::tryConvertToDateTime($valueFrom, [$filter->getPhpFormat()]);
×
UNCOV
147
                                $dateFrom->setTime(0, 0, 0);
×
148

UNCOV
149
                                $this->dataSource->where(
×
NEW
150
                                        sprintf('DATE(%s) >= ?', $filter->getColumn()),
×
UNCOV
151
                                        $dateFrom->format('Y-m-d')
×
152
                                );
NEW
153
                        } catch (DatagridDateTimeHelperException) {
×
154
                                // ignore the invalid filter value
155
                        }
156
                }
157

UNCOV
158
                if ($valueTo) {
×
159
                        try {
UNCOV
160
                                $dateTo = DateTimeHelper::tryConvertToDateTime($valueTo, [$filter->getPhpFormat()]);
×
UNCOV
161
                                $dateTo->setTime(23, 59, 59);
×
162

NEW
163
                                $this->dataSource->where(
×
NEW
164
                                        sprintf('DATE(%s) <= ?', $filter->getColumn()),
×
NEW
165
                                        $dateTo->format('Y-m-d')
×
166
                                );
NEW
167
                        } catch (DatagridDateTimeHelperException) {
×
168
                                // ignore the invalid filter value
169
                        }
170
                }
171
        }
172

173
        protected function applyFilterRange(FilterRange $filter): void
1✔
174
        {
175
                $conditions = $filter->getCondition();
1✔
176

177
                $valueFrom = $conditions[$filter->getColumn()]['from'];
1✔
178
                $valueTo = $conditions[$filter->getColumn()]['to'];
1✔
179

180
                if ($valueFrom) {
1✔
181
                        $this->dataSource->where(sprintf('%s >= ?', $filter->getColumn()), $valueFrom);
1✔
182
                }
183

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

189
        protected function applyFilterText(FilterText $filter): void
1✔
190
        {
191
                $or = [];
1✔
192
                $args = [];
1✔
193
                $bigOr = '(';
1✔
194
                $bigOrArgs = [];
1✔
195
                $condition = $filter->getCondition();
1✔
196

197
                foreach ($condition as $column => $value) {
1✔
198
                        $like = '(';
1✔
199
                        $args = [];
1✔
200

201
                        if ($filter->isExactSearch()) {
1✔
202
                                $like .= sprintf('%s = ? OR ', $column);
1✔
203
                                $args[] = sprintf('%s', $value);
1✔
204
                        } else {
205
                                $words = $filter->hasSplitWordsSearch() === false ? [$value] : explode(' ', $value);
1✔
206

207
                                foreach ($words as $word) {
1✔
208
                                        $like .= sprintf('%s LIKE ? OR ', $column);
1✔
209
                                        $args[] = sprintf('%%%s%%', $word);
1✔
210
                                }
211
                        }
212

213
                        $like = substr($like, 0, strlen($like) - 4) . ')';
1✔
214

215
                        $or[] = $like;
1✔
216
                        $bigOr .= sprintf('%s OR ', $like);
1✔
217
                        $bigOrArgs = [...$bigOrArgs, ...$args];
1✔
218
                }
219

220
                if (count($or) > 1) {
1✔
221
                        $bigOr = substr($bigOr, 0, strlen($bigOr) - 4) . ')';
1✔
222

223
                        $query = [...[$bigOr], ...$bigOrArgs];
1✔
224

225
                        call_user_func_array([$this->dataSource, 'where'], $query);
1✔
226
                } else {
227
                        $query = [...$or, ...$args];
1✔
228

229
                        call_user_func_array([$this->dataSource, 'where'], $query);
1✔
230
                }
231
        }
1✔
232

233
        protected function applyFilterMultiSelect(FilterMultiSelect $filter): void
234
        {
UNCOV
235
                $condition = $filter->getCondition();
×
UNCOV
236
                $values = $condition[$filter->getColumn()];
×
237
                $or = '(';
×
238

NEW
239
                if ((is_countable($values) ? count($values) : 0) > 1) {
×
NEW
240
                        $length = is_countable($values) ? count($values) : 0;
×
UNCOV
241
                        $i = 1;
×
242

NEW
243
                        for ($iterator = 0; $iterator < (is_countable($values) ? count($values) : 0); $iterator++) {
×
UNCOV
244
                                if ($i === $length) {
×
UNCOV
245
                                        $or .= $filter->getColumn() . ' = ?)';
×
246
                                } else {
UNCOV
247
                                        $or .= $filter->getColumn() . ' = ? OR ';
×
248
                                }
249

UNCOV
250
                                $i++;
×
251
                        }
252

UNCOV
253
                        array_unshift($values, $or);
×
254

UNCOV
255
                        call_user_func_array([$this->dataSource, 'where'], $values);
×
256
                } else {
UNCOV
257
                        $this->dataSource->where($filter->getColumn() . ' = ?', reset($values));
×
258
                }
259
        }
260

261
        protected function applyFilterSelect(FilterSelect $filter): void
1✔
262
        {
263
                $this->dataSource->where($filter->getCondition());
1✔
264
        }
1✔
265

266
        protected function getDataSource(): Selection
267
        {
UNCOV
268
                return $this->dataSource;
×
269
        }
270

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