• 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

39.83
/src/Row.php
1
<?php declare(strict_types = 1);
2

3
namespace Contributte\Datagrid;
4

5
use Contributte\Datagrid\Column\Column;
6
use Contributte\Datagrid\Exception\DatagridException;
7
use Contributte\Datagrid\Utils\PropertyAccessHelper;
8
use Dibi\Row as DibiRow;
9
use LeanMapper\Entity;
10
use Nette\Database\Row as NetteRow;
11
use Nette\Database\Table\ActiveRow;
12
use Nette\MemberAccessException;
13
use Nette\Utils\Html;
14
use Nextras\Orm\Entity\Entity as NextrasEntity;
15

16
class Row
17
{
18

19
        protected mixed $id;
20

21
        protected Html $control;
22

23
        public function __construct(protected Datagrid $datagrid, protected mixed $item, protected string $primaryKey)
1✔
24
        {
25
                $this->control = Html::el('tr');
1✔
26
                $this->id = $this->getValue($primaryKey);
1✔
27

28
                if ($datagrid->getColumnsSummary() instanceof ColumnsSummary) {
1✔
29
                        $datagrid->getColumnsSummary()->add($this);
×
30
                }
31
        }
1✔
32

33
        public function getId(): mixed
34
        {
35
                if (is_object($this->id) && method_exists($this->id, '__toString')) {
1✔
36
                        return (string) $this->id;
×
37
                }
38

39
                return $this->id;
1✔
40
        }
41

42
        public function getValue(mixed $key): mixed
1✔
43
        {
44
                if ($this->item instanceof Entity) {
1✔
45
                        return $this->getLeanMapperEntityProperty($this->item, $key);
1✔
46
                }
47

48
                if ($this->item instanceof NextrasEntity) {
1✔
49
                        return $this->getNextrasEntityProperty($this->item, $key);
×
50
                }
51

52
                if ($this->item instanceof DibiRow) {
1✔
53
                        return $this->item[$this->formatDibiRowKey($key)];
×
54
                }
55

56
                if ($this->item instanceof ActiveRow) {
1✔
57
                        return $this->getActiveRowProperty($this->item, $key);
×
58
                }
59

60
                if ($this->item instanceof NetteRow) {
1✔
61
                        return $this->item->{$key};
×
62
                }
63

64
                if (is_array($this->item)) {
1✔
65
                        $arrayValue = $this->item[$key];
1✔
66

67
                        if (is_object($arrayValue) && method_exists($arrayValue, '__toString')) {
1✔
68
                                return (string) $arrayValue;
×
69
                        }
70

71
                        if (interface_exists(\BackedEnum::class) && $arrayValue instanceof \BackedEnum) {
1✔
72
                                return $arrayValue->value;
1✔
73
                        }
74

75
                        return $arrayValue;
1✔
76
                }
77

78
                return $this->getDoctrineEntityProperty($this->item, $key);
1✔
79
        }
80

81
        public function getControl(): Html
82
        {
83
                return $this->control;
1✔
84
        }
85

86
        public function getControlClass(): string
87
        {
88
                $class = $this->control->getAttribute('class');
1✔
89

90
                if ($class === null) {
1✔
91
                        return '';
×
92
                }
93

94
                return implode(' ', array_keys($class));
1✔
95
        }
96

97
        public function getActiveRowProperty(ActiveRow $item, string $key): mixed
98
        {
99
                if (preg_match('/^:([a-zA-Z0-9_$]+)\.([a-zA-Z0-9_$]+)(:([a-zA-Z0-9_$]+))?$/', $key, $matches) === 1) {
×
100
                        $relatedTable = $matches[1];
×
101
                        $relatedColumn = $matches[2];
×
102
                        $throughColumn = $matches[4] ?? null;
×
103

104
                        try {
105
                                $relatedRow = $item->related($relatedTable, $throughColumn)->fetch();
×
NEW
106
                        } catch (MemberAccessException) {
×
107
                                return null;
×
108
                        }
109

110
                        return $relatedRow !== null
×
111
                                ? $relatedRow[$relatedColumn]
×
112
                                : null;
×
113
                }
114

115
                if (preg_match('/^([a-zA-Z0-9_$]+)\.([a-zA-Z0-9_$]+)(:([a-zA-Z0-9_$]+))?$/', $key, $matches) === 1) {
×
116
                        $referencedTable = $matches[1];
×
117
                        $referencedColumn = $matches[2];
×
118
                        $throughColumn = $matches[4] ?? null;
×
119

120
                        try {
121
                                $referencedRow = $item->ref($referencedTable, $throughColumn);
×
NEW
122
                        } catch (MemberAccessException) {
×
123
                                return null;
×
124
                        }
125

126
                        return $referencedRow === null
×
127
                                ? null
×
128
                                : $referencedRow[$referencedColumn];
×
129
                }
130

131
                return $item[$key];
×
132
        }
133

134
        /**
135
         * LeanMapper: Access object properties to get a item value
136
         */
137
        public function getLeanMapperEntityProperty(Entity $item, string $key): mixed
1✔
138
        {
139
                $properties = explode('.', $key);
1✔
140
                $value = $item;
1✔
141

142
                for (;;) {
1✔
143
                        $property = array_shift($properties);
1✔
144

145
                        if ($property === null) {
1✔
146
                                break;
1✔
147
                        }
148

149
                        if (!$value->__isset($property)) {
1✔
150
                                if ($this->datagrid->strictEntityProperty) {
×
NEW
151
                                        throw new DatagridException(sprintf(
×
152
                                                'Target Property [%s] is not an object or is empty, trying to get [%s]',
×
153
                                                $value,
154
                                                str_replace('.', '->', $key)
×
155
                                        ));
156
                                }
157

158
                                return null;
×
159
                        }
160

161
                        $value = $value->__get($property);
1✔
162
                }
163

164
                return $value;
1✔
165
        }
166

167
        /**
168
         * Nextras: Access object properties to get a item value
169
         */
170
        public function getNextrasEntityProperty(NextrasEntity $item, string $key): mixed
171
        {
172
                $properties = explode('.', $key);
×
173
                $value = $item;
×
174

175
                while ($property = array_shift($properties)) {
×
176
                        if (!$value->__isset($property)) {
×
177
                                if ($this->datagrid->strictEntityProperty) {
×
NEW
178
                                        throw new DatagridException(sprintf(
×
179
                                                'Target Property [%s] is not an object or is empty, trying to get [%s]',
×
180
                                                $value,
181
                                                str_replace('.', '->', $key)
×
182
                                        ));
183
                                }
184

185
                                return null;
×
186
                        }
187

188
                        $value = $value->__get($property);
×
189
                }
190

191
                return $value;
×
192
        }
193

194
        /**
195
         * Doctrine: Access object properties to get a item value
196
         */
197
        public function getDoctrineEntityProperty(mixed $item, mixed $key): mixed
1✔
198
        {
199
                $properties = explode('.', $key);
1✔
200
                $value = $item;
1✔
201
                $accessor = PropertyAccessHelper::getAccessor();
1✔
202

203
                while ($property = array_shift($properties)) {
1✔
204
                        if (!is_object($value) && ! (bool) $value) {
1✔
205
                                if ($this->datagrid->strictEntityProperty) {
×
NEW
206
                                        throw new DatagridException(sprintf(
×
207
                                                'Target Property [%s] is not an object or is empty, trying to get [%s]',
×
208
                                                $value,
209
                                                str_replace('.', '->', $key)
×
210
                                        ));
211
                                }
212

213
                                return null;
×
214
                        }
215

216
                        $value = $accessor->getValue($value, $property);
1✔
217
                }
218

219
                if (is_object($value) && method_exists($value, '__toString')) {
1✔
220
                        return (string) $value;
×
221
                }
222

223
                if (interface_exists(\BackedEnum::class) && $value instanceof \BackedEnum) {
1✔
224
                        return $value->value;
1✔
225
                }
226

227
                return $value;
1✔
228
        }
229

230
        /**
231
         * Get original item
232
         */
233
        public function getItem(): mixed
234
        {
235
                return $this->item;
1✔
236
        }
237

238
        /**
239
         * Has particular row group actions allowed?
240
         */
241
        public function hasGroupAction(): bool
242
        {
243
                $condition = $this->datagrid->getRowCondition('group_action');
×
244

245
                if (is_callable($condition)) {
×
246
                        return ($condition)($this->item);
×
247
                }
248

249
                return true;
×
250
        }
251

252
        /**
253
         * Has particular row a action allowed?
254
         */
255
        public function hasAction(mixed $key): bool
256
        {
257
                $condition = $this->datagrid->getRowCondition('action', $key);
×
258

259
                if (is_callable($condition)) {
×
260
                        return ($condition)($this->item);
×
261
                }
262

263
                return true;
×
264
        }
265

266
        /**
267
         * Has particular row inlie edit allowed?
268
         */
269
        public function hasInlineEdit(): bool
270
        {
271
                $condition = $this->datagrid->getRowCondition('inline_edit');
×
272

273
                if (is_callable($condition)) {
×
274
                        return ($condition)($this->item);
×
275
                }
276

277
                return true;
×
278
        }
279

280
        public function applyColumnCallback(string $key, Column $column): Column
281
        {
282
                $callback = $this->datagrid->getColumnCallback($key);
×
283

284
                if ($callback !== null) {
×
285
                        call_user_func($callback, $column, $this->getItem());
×
286
                }
287

288
                return $column;
×
289
        }
290

291
        /**
292
         * Key may contain ".", get rid of it (+ the table alias)
293
         */
294
        private function formatDibiRowKey(string $key): string
295
        {
296
                $offset = strpos($key, '.');
×
297

298
                if ($offset !== false) {
×
299
                        return substr($key, $offset + 1);
×
300
                }
301

302
                return $key;
×
303
        }
304

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