Completed
Pull Request — master (#648)
by
unknown
32:38 queued 12:41
created

Row::getActiveRowProperty()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 24
Code Lines 14

Duplication

Lines 18
Ratio 75 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 18
loc 24
rs 8.5125
ccs 0
cts 13
cp 0
cc 5
eloc 14
nc 5
nop 2
crap 30
1
<?php declare(strict_types = 1);
2
3
/**
4
 * @copyright   Copyright (c) 2015 ublaboo <[email protected]>
5
 * @author      Pavel Janda <[email protected]>
6
 * @package     Ublaboo
7
 */
8
9
namespace Ublaboo\DataGrid;
10
11
use Dibi\Row as DibiRow;
12
use LeanMapper;
13
use Nette;
14
use Nette\Database\Table\ActiveRow;
15
use Nette\SmartObject;
16
use Nette\Utils\Html;
17
use Nextras;
18
use Ublaboo\DataGrid\Exception\DataGridException;
19
use Ublaboo\DataGrid\Utils\PropertyAccessHelper;
20
21 1
class Row
22
{
23
24 1
	use SmartObject;
25
26
	/**
27
	 * @var DataGrid
28
	 */
29
	protected $datagrid;
30
31
	/**
32
	 * @var mixed
33
	 */
34
	protected $item;
35
36
	/**
37
	 * @var string
38
	 */
39
	protected $primary_key;
40
41
	/**
42
	 * @var mixed
43
	 */
44
	protected $id;
45
46
	/**
47
	 * @var Html
48
	 */
49
	protected $control;
50
51
/**
52
 * @param DataGrid $datagrid
53
 * @param mixed    $item
54
 * @param string   $primary_key
55
 */
56
	public function __construct(DataGrid $datagrid, $item, $primary_key)
57
	{
58
		$this->control = Html::el('tr');
59 1
		$this->datagrid = $datagrid;
60 1
		$this->item = $item;
61 1
		$this->primary_key = $primary_key;
62 1
		$this->id = $this->getValue($primary_key);
63 1
64
		if ($datagrid->hasColumnsSummary()) {
65 1
			$datagrid->getColumnsSummary()->add($this);
66
		}
67
	}
68 1
69
70
	/**
71
	 * Get id value of item
72
	 *
73
	 * @return mixed
74
	 */
75
	public function getId()
76
	{
77 1
		return $this->id;
78
	}
79
80
81
	/**
82
	 * Get item value of key
83
	 *
84
	 * @param  mixed $key
85
	 * @return mixed
86
	 */
87
	public function getValue($key)
88 1
	{
89 1
		if ($this->item instanceof LeanMapper\Entity) {
90
			return $this->getLeanMapperEntityProperty($this->item, $key);
91 1
92
		} elseif ($this->item instanceof Nextras\Orm\Entity\Entity) {
93
			return $this->getNextrasEntityProperty($this->item, $key);
94 1
95
		} elseif ($this->item instanceof DibiRow) {
96
			return $this->item->{$this->formatDibiRowKey($key)};
97 1
98
		} elseif ($this->item instanceof ActiveRow) {
99
			return $this->getActiveRowProperty($this->item, $key);
100 1
101
		} elseif ($this->item instanceof Nette\Database\Row) {
102
			return $this->item->{$key};
103 1
104 1
		} elseif (is_array($this->item)) {
105
			return $this->item[$key];
106
107
		} else {
108
			/**
109
			 * Doctrine entity
110 1
			 */
111
			return $this->getDoctrineEntityProperty($this->item, $key);
112
		}
113
	}
114
115
116
	/**
117
	 * @return Html
118
	 */
119
	public function getControl(): Html
120 1
	{
121
		return $this->control;
122
	}
123
124
125
	/**
126
	 * @return string
127
	 */
128
	public function getControlClass(): string
129 1
	{
130
		if (!$class = $this->control->class) {
131
			return '';
132
		}
133 1
134
		return implode(' ', array_keys($class));
135
	}
136
137
138
	/**
139
	 * @param  ActiveRow $item
140
	 * @param  string    $key
141
	 * @return mixed|NULL
142
	 */
143
	public function getActiveRowProperty(ActiveRow $item, string $key)
144
	{
145 View Code Duplication
		if (preg_match('/^:([a-zA-Z0-9_$]+)\.([a-zA-Z0-9_$]+)(:([a-zA-Z0-9_$]+))?$/', $key, $matches)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
146
			$relatedTable = $matches[1];
147
			$relatedColumn = $matches[2];
148
			$throughColumn = $matches[4] ?? null;
149
150
			$relatedRow = $item->related($relatedTable, $throughColumn)->fetch();
151
152
			return $relatedRow ? $relatedRow->{$relatedColumn} : null;
153
		}
154
155 View Code Duplication
		if (preg_match('/^([a-zA-Z0-9_$]+)\.([a-zA-Z0-9_$]+)(:([a-zA-Z0-9_$]+))?$/', $key, $matches)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
156
			$referencedTable = $matches[1];
157
			$referencedColumn = $matches[2];
158
			$throughColumn = $matches[4] ?? null;
159
160
			$referencedRow = $item->ref($referencedTable, $throughColumn);
161
162
			return $referencedRow ? $referencedRow->{$referencedColumn} : null;
163
		}
164
165
		return $item->{$key};
166
	}
167
168
169
	/**
170
	 * LeanMapper: Access object properties to get a item value
171
	 *
172
	 * @param  LeanMapper\Entity $item
173
	 * @param  mixed             $key
174
	 * @return mixed
175
	 */
176 1 View Code Duplication
	public function getLeanMapperEntityProperty(LeanMapper\Entity $item, $key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
177 1
	{
178
		$properties = explode('.', $key);
179 1
		$value = $item;
180 1
181
		while ($property = array_shift($properties)) {
182
			if (!isset($value->{$property})) {
183
				if ($this->datagrid->strict_entity_property) {
184
					throw new DataGridException(sprintf(
185
						'Target Property [%s] is not an object or is empty, trying to get [%s]',
186
						$value,
187
						str_replace('.', '->', $key)
188
					));
189
				}
190
191 1
				return null;
192
			}
193
194 1
			$value = $value->{$property};
195
		}
196
197
		return $value;
198
	}
199
200
201
	/**
202
	 * Nextras: Access object properties to get a item value
203
	 *
204
	 * @param  Nextras\Orm\Entity\Entity $item
205
	 * @param  string                    $key
206
	 * @return mixed
207
	 */
208 View Code Duplication
	public function getNextrasEntityProperty(Nextras\Orm\Entity\Entity $item, string $key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
209
	{
210
		$properties = explode('.', $key);
211
		$value = $item;
212
213
		while ($property = array_shift($properties)) {
214
			if (!isset($value->{$property})) {
215
				if ($this->datagrid->strict_entity_property) {
216
					throw new DataGridException(sprintf(
217
						'Target Property [%s] is not an object or is empty, trying to get [%s]',
218
						$value,
219
						str_replace('.', '->', $key)
220
					));
221
				}
222
223
				return null;
224
			}
225
226
			$value = $value->{$property};
227
		}
228
229
		return $value;
230
	}
231
232
233
	/**
234
	 * Doctrine: Access object properties to get a item value
235
	 *
236 1
	 * @param  mixed $item
237 1
	 * @param  mixed $key
238 1
	 * @return mixed
239
	 */
240 1
	public function getDoctrineEntityProperty($item, $key)
241 1
	{
242
		$properties = explode('.', $key);
243
		$value = $item;
244
		$accessor = PropertyAccessHelper::getAccessor();
245
246
		while ($property = array_shift($properties)) {
247
			if (!is_object($value) && !$value) {
248
				if ($this->datagrid->strict_entity_property) {
249
					throw new DataGridException(sprintf(
250
						'Target Property [%s] is not an object or is empty, trying to get [%s]',
251
						$value,
252 1
						str_replace('.', '->', $key)
253
					));
254
				}
255 1
256
				return null;
257
			}
258
259
			$value = $accessor->getValue($value, $property);
260
		}
261
262
		return $value;
263
	}
264
265 1
266
	/**
267
	 * Get original item
268
	 *
269
	 * @return mixed
270
	 */
271
	public function getItem()
272
	{
273
		return $this->item;
274
	}
275
276
277
	/**
278
	 * Has particular row group actions allowed?
279
	 *
280
	 * @return bool
281
	 */
282
	public function hasGroupAction(): bool
283
	{
284
		$condition = $this->datagrid->getRowCondition('group_action');
285
286
		return $condition ? $condition($this->item) : true;
287
	}
288
289
290
	/**
291
	 * Has particular row a action allowed?
292
	 *
293
	 * @param  mixed  $key
294
	 * @return bool
295
	 */
296
	public function hasAction($key): bool
297
	{
298
		$condition = $this->datagrid->getRowCondition('action', $key);
299
300
		return $condition ? $condition($this->item) : true;
301
	}
302
303
304
	/**
305
	 * Has particular row inlie edit allowed?
306
	 */
307
	public function hasInlineEdit(): bool
308
	{
309
		$condition = $this->datagrid->getRowCondition('inline_edit');
310
311
		return $condition ? $condition($this->item) : true;
312
	}
313
314
315
	public function applyColumnCallback(string $key, Column\Column $column): Column\Column
316
	{
317
		$callback = $this->datagrid->getColumnCallback($key);
318
319
		if ($callback !== null) {
320
			call_user_func($callback, $column, $this->getItem());
321
		}
322
323
		return $column;
324
	}
325
326
327
	/**
328
	 * Key may contain ".", get rid of it (+ the table alias)
329
	 */
330
	private function formatDibiRowKey(string $key): string
331
	{
332
		if ($offset = strpos($key, '.')) {
333
			return substr($key, $offset + 1);
334
		}
335
336
		return $key;
337
	}
338 1
339
}
340