Completed
Pull Request — master (#648)
by
unknown
12:11
created

Row::getActiveRowProperty()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 24
Code Lines 14

Duplication

Lines 18
Ratio 75 %

Code Coverage

Tests 2
CRAP Score 16.7636

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 18
loc 24
rs 8.5125
ccs 2
cts 9
cp 0.2222
cc 5
eloc 14
nc 5
nop 2
crap 16.7636
1
<?php declare(strict_types = 1);
2
3
namespace Ublaboo\DataGrid;
4
5
use Dibi\Row as DibiRow;
6
use LeanMapper;
7
use Nette;
8
use Nette\Database\Table\ActiveRow;
9
use Nette\SmartObject;
10
use Nette\Utils\Html;
11
use Nextras;
12
use Ublaboo\DataGrid\Exception\DataGridException;
13
use Ublaboo\DataGrid\Utils\PropertyAccessHelper;
14
15
class Row
16
{
17
18
	use SmartObject;
19
20
	/**
21 1
	 * @var DataGrid
22
	 */
23
	protected $datagrid;
24 1
25
	/**
26
	 * @var mixed
27
	 */
28
	protected $item;
29
30
	/**
31
	 * @var string
32
	 */
33
	protected $primary_key;
34
35
	/**
36
	 * @var mixed
37
	 */
38
	protected $id;
39
40
	/**
41
	 * @var Html
42
	 */
43
	protected $control;
44
45
/**
46
 * @param mixed    $item
47
 * @param string   $primary_key
48
 */
49
	public function __construct(DataGrid $datagrid, $item, $primary_key)
50
	{
51
		$this->control = Html::el('tr');
52
		$this->datagrid = $datagrid;
53
		$this->item = $item;
54
		$this->primary_key = $primary_key;
55
		$this->id = $this->getValue($primary_key);
56
57
		if ($datagrid->hasColumnsSummary()) {
58
			$datagrid->getColumnsSummary()->add($this);
59 1
		}
60 1
	}
61 1
62 1
63 1
	/**
64
	 * Get id value of item
65 1
	 *
66
	 * @return mixed
67
	 */
68 1
	public function getId()
69
	{
70
		return $this->id;
71
	}
72
73
74
	/**
75
	 * Get item value of key
76
	 *
77 1
	 * @param  mixed $key
78
	 * @return mixed
79
	 */
80
	public function getValue($key)
81
	{
82
		if ($this->item instanceof LeanMapper\Entity) {
83
			return $this->getLeanMapperEntityProperty($this->item, $key);
84
85
		} elseif ($this->item instanceof Nextras\Orm\Entity\Entity) {
86
			return $this->getNextrasEntityProperty($this->item, $key);
87
88 1
		} elseif ($this->item instanceof DibiRow) {
89 1
			return $this->item->{$this->formatDibiRowKey($key)};
90
91 1
		} elseif ($this->item instanceof ActiveRow) {
92
			return $this->getActiveRowProperty($this->item, $key);
93
94 1
		} elseif ($this->item instanceof Nette\Database\Row) {
95
			return $this->item->{$key};
96
97 1
		} elseif (is_array($this->item)) {
98
			return $this->item[$key];
99
100 1
		} else {
101
			/**
102
			 * Doctrine entity
103 1
			 */
104 1
			return $this->getDoctrineEntityProperty($this->item, $key);
105
		}
106
	}
107
108
109
	public function getControl(): Html
110 1
	{
111
		return $this->control;
112
	}
113
114
115
	public function getControlClass(): string
116
	{
117
		if (!$class = $this->control->class) {
118
			return '';
119
		}
120 1
121
		return implode(' ', array_keys($class));
122
	}
123
124
125
	/**
126
	 * @return mixed|NULL
127
	 */
128
	public function getActiveRowProperty(ActiveRow $item, string $key)
129 1
	{
130 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...
131
			$relatedTable = $matches[1];
132
			$relatedColumn = $matches[2];
133 1
			$throughColumn = $matches[4] ?? null;
134
135
			$relatedRow = $item->related($relatedTable, $throughColumn)->fetch();
136
137
			return $relatedRow ? $relatedRow->{$relatedColumn} : null;
138
		}
139
140 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...
141
			$referencedTable = $matches[1];
142
			$referencedColumn = $matches[2];
143
			$throughColumn = $matches[4] ?? null;
144
145
			$referencedRow = $item->ref($referencedTable, $throughColumn);
146
147
			return $referencedRow ? $referencedRow->{$referencedColumn} : null;
148
		}
149
150
		return $item->{$key};
151
	}
152
153
154
	/**
155
	 * LeanMapper: Access object properties to get a item value
156
	 *
157
	 * @param  mixed             $key
158
	 * @return mixed
159
	 */
160 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...
161
	{
162
		$properties = explode('.', $key);
163
		$value = $item;
164
165
		while ($property = array_shift($properties)) {
166
			if (!isset($value->{$property})) {
167
				if ($this->datagrid->strict_entity_property) {
168
					throw new DataGridException(sprintf(
169
						'Target Property [%s] is not an object or is empty, trying to get [%s]',
170
						$value,
171
						str_replace('.', '->', $key)
172
					));
173
				}
174
175
				return null;
176 1
			}
177 1
178
			$value = $value->{$property};
179 1
		}
180 1
181
		return $value;
182
	}
183
184
185
	/**
186
	 * Nextras: Access object properties to get a item value
187
	 *
188
	 * @return mixed
189
	 */
190 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...
191 1
	{
192
		$properties = explode('.', $key);
193
		$value = $item;
194 1
195
		while ($property = array_shift($properties)) {
196
			if (!isset($value->{$property})) {
197
				if ($this->datagrid->strict_entity_property) {
198
					throw new DataGridException(sprintf(
199
						'Target Property [%s] is not an object or is empty, trying to get [%s]',
200
						$value,
201
						str_replace('.', '->', $key)
202
					));
203
				}
204
205
				return null;
206
			}
207
208
			$value = $value->{$property};
209
		}
210
211
		return $value;
212
	}
213
214
215
	/**
216
	 * Doctrine: Access object properties to get a item value
217
	 *
218
	 * @param  mixed $item
219
	 * @param  mixed $key
220
	 * @return mixed
221
	 */
222
	public function getDoctrineEntityProperty($item, $key)
223
	{
224
		$properties = explode('.', $key);
225
		$value = $item;
226
		$accessor = PropertyAccessHelper::getAccessor();
227
228
		while ($property = array_shift($properties)) {
229
			if (!is_object($value) && !$value) {
230
				if ($this->datagrid->strict_entity_property) {
231
					throw new DataGridException(sprintf(
232
						'Target Property [%s] is not an object or is empty, trying to get [%s]',
233
						$value,
234
						str_replace('.', '->', $key)
235
					));
236 1
				}
237 1
238 1
				return null;
239
			}
240 1
241 1
			$value = $accessor->getValue($value, $property);
242
		}
243
244
		return $value;
245
	}
246
247
248
	/**
249
	 * Get original item
250
	 *
251
	 * @return mixed
252 1
	 */
253
	public function getItem()
254
	{
255 1
		return $this->item;
256
	}
257
258
259
	/**
260
	 * Has particular row group actions allowed?
261
	 */
262
	public function hasGroupAction(): bool
263
	{
264
		$condition = $this->datagrid->getRowCondition('group_action');
265 1
266
		return $condition ? $condition($this->item) : true;
267
	}
268
269
270
	/**
271
	 * Has particular row a action allowed?
272
	 *
273
	 * @param  mixed  $key
274
	 */
275
	public function hasAction($key): bool
276
	{
277
		$condition = $this->datagrid->getRowCondition('action', $key);
278
279
		return $condition ? $condition($this->item) : true;
280
	}
281
282
283
	/**
284
	 * Has particular row inlie edit allowed?
285
	 */
286
	public function hasInlineEdit(): bool
287
	{
288
		$condition = $this->datagrid->getRowCondition('inline_edit');
289
290
		return $condition ? $condition($this->item) : true;
291
	}
292
293
294
	public function applyColumnCallback(string $key, Column\Column $column): Column\Column
295
	{
296
		$callback = $this->datagrid->getColumnCallback($key);
297
298
		if ($callback !== null) {
299
			call_user_func($callback, $column, $this->getItem());
300
		}
301
302
		return $column;
303
	}
304
305
306
	/**
307
	 * Key may contain ".", get rid of it (+ the table alias)
308
	 */
309
	private function formatDibiRowKey(string $key): string
310
	{
311
		if ($offset = strpos($key, '.')) {
312
			return substr($key, $offset + 1);
313
		}
314
315
		return $key;
316
	}
317
318
}
319