Completed
Push — master ( 110f49...7f2d1b )
by Pavel
02:45
created

Action::getPropertyStringOrCallableGetString()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 24
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 24
rs 8.6845
cc 4
eloc 9
nc 4
nop 3
1
<?php
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\Column;
10
11
use Nette\Utils\Html;
12
use Ublaboo\DataGrid\DataGrid;
13
use Ublaboo\DataGrid\Exception\DataGridHasToBeAttachedToPresenterComponentException;
14
use Ublaboo\DataGrid\Exception\DataGridException;
15
use Ublaboo\DataGrid\Exception\DataGridColumnRendererException;
16
use Ublaboo\DataGrid\Row;
17
use Ublaboo\DataGrid\Traits;
18
19
class Action extends Column
20
{
21
22
	use Traits\TButton;
23
	use Traits\TLink;
24
25
	/**
26
	 * @var string
27
	 */
28
	public static $data_confirm_attribute_name = 'datagrid-confirm';
29
30
	/**
31
	 * @var DataGrid
32
	 */
33
	protected $grid;
34
35
	/**
36
	 * @var string
37
	 */
38
	protected $href;
39
40
	/**
41
	 * @var string
42
	 */
43
	protected $name;
44
45
	/**
46
	 * @var array
47
	 */
48
	protected $params;
49
50
	/**
51
	 * @var array|callable
52
	 */
53
	protected $confirm;
54
55
	/**
56
	 * @var array
57
	 */
58
	protected $data_attributes = [];
59
60
	/**
61
	 * @var array
62
	 */
63
	protected $attributes = [];
64
65
66
	/**
67
	 * @param DataGrid $grid
68
	 * @param string   $href
69
	 * @param string   $name
70
	 * @param array    $params
71
	 */
72
	public function __construct(DataGrid $grid, $href, $name, $params)
73
	{
74
		$this->grid = $grid;
75
		$this->href = $href;
76
		$this->name = $name;
77
		$this->params = $params;
78
	}
79
80
81
	/**
82
	 * Render row item into template
83
	 * @param  Row   $row
84
	 * @return mixed
85
	 */
86
	public function render(Row $row)
87
	{
88
		/**
89
		 * Renderer function may be used
90
		 */
91
		try {
92
			return $this->useRenderer($row);
93
		} catch (DataGridColumnRendererException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
94
			/**
95
			 * Do not use renderer
96
			 */
97
		}
98
99
		$link = $this->createLink(
100
			$this->grid,
101
			$this->href,
102
			$this->getItemParams($row, $this->params)
103
		);
104
105
		$a = Html::el('a')->href($link);
106
107
		$this->tryAddIcon($a, $this->getIcon($row), $this->getName());
108
109
		if (!empty($this->data_attributes)) {
110
			foreach ($this->data_attributes as $key => $value) {
111
				$a->data($key, $value);
112
			}
113
		}
114
115
		if (!empty($this->attributes)) {
116
			$a->addAttributes($this->attributes);
117
		}
118
119
		$a->addText($this->translate($this->getName()));
120
121
		if ($this->title) {
122
			$a->title($this->translate($this->getTitle($row)));
123
		}
124
125
		if ($this->class) {
126
			$a->class($this->getClass($row));
127
		}
128
129
		if ($confirm = $this->getConfirm($row)) {
130
			$a->data(static::$data_confirm_attribute_name, $confirm);
131
		}
132
133
		return $a;
134
	}
135
136
137
	/**
138
	 * Set attribute title
139
	 * @param string|callable $title
140
	 * @return static
141
	 * @throws DataGridException
142
	 */
143
	public function setTitle($title)
144
	{
145
		$this->checkPropertyStringOrCallable($title, 'title');
146
147
		$this->title = $title;
148
149
		return $this;
150
	}
151
152
153
	/**
154
	 * Get attribute title
155
	 * @param Row $row
156
	 * @return string
157
	 * @throws DataGridException
158
	 */
159
	public function getTitle(Row $row)
160
	{
161
		/**
162
		 * If user callback was used for setting action title, it has to return string
163
		 */
164
		return $this->getPropertyStringOrCallableGetString($row, $this->title, 'title');
165
	}
166
167
168
	/**
169
	 * Set attribute class
170
	 * @param string|callable $class
171
	 * @return static
172
	 * @throws DataGridException
173
	 */
174
	public function setClass($class)
175
	{
176
		$this->checkPropertyStringOrCallable($class, 'class');
177
178
		$this->class = $class;
0 ignored issues
show
Documentation Bug introduced by
It seems like $class of type callable is incompatible with the declared type string of property $class.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
179
180
		return $this;
181
	}
182
183
184
	/**
185
	 * Get attribute class
186
	 * @param Row $row
187
	 * @return string
188
	 * @throws DataGridException
189
	 */
190
	public function getClass(Row $row)
191
	{
192
		/**
193
		 * If user callback was used for setting action class, it has to return string
194
		 */
195
		return $this->getPropertyStringOrCallableGetString($row, $this->class, 'class');
196
	}
197
198
199
	/**
200
	 * Set icon
201
	 * @param string|callable $icon
202
	 * @return static|callable
203
	 * @throws DataGridException
204
	 */
205
	public function setIcon($icon)
206
	{
207
		$this->checkPropertyStringOrCallable($icon, 'icon');
208
209
		$this->icon = $icon;
210
211
		return $this;
212
	}
213
214
215
	/**
216
	 * Get icon
217
	 * @param Row $row
218
	 * @return string
219
	 * @throws DataGridException
220
	 */
221
	public function getIcon(Row $row)
222
	{
223
		/**
224
		 * If user callback was used for setting action icon, it has to return string
225
		 */
226
		return $this->getPropertyStringOrCallableGetString($row, $this->icon, 'icon');
227
	}
228
229
230
	/**
231
	 * Set confirm dialog
232
	 * @param string|callable $message
233
	 * @param string $column
234
	 * @return static
235
	 * @throws DataGridException
236
	 */
237
	public function setConfirm($message, $column = NULL)
238
	{
239
		$this->checkPropertyStringOrCallable($message, 'confirmation message');
240
241
		$this->confirm = [$message, $column];
242
243
		return $this;
244
	}
245
246
247
	/**
248
	 * Get confirm dialog for particular row item
249
	 * @param Row $row
250
	 * @return string
251
	 * @throws DataGridException
252
	 */
253
	public function getConfirm(Row $row)
254
	{
255
		if (!$this->confirm) {
256
			return NULL;
257
		}
258
259
		$question = $this->confirm[0];
260
261
		if (is_string($question)) {
262
			$question = $this->translate($question);
263
		} else {
264
			/**
265
			 * If user callback was used for setting action confirmation dialog, it has to return string
266
			 */
267
			$question = $this->getPropertyStringOrCallableGetString($row, $question, 'confirmation dialog');
268
		}
269
270
		if (!$this->confirm[1]) {
271
			return $question;
272
		}
273
274
		return str_replace('%s', $row->getValue($this->confirm[1]), $question);
275
	}
276
277
278
	/**
279
	 * Setting data attributes
280
	 * @param string $key
281
	 * @param mixed $value
282
	 * @return static
283
	 */
284
	public function setDataAttribute($key, $value)
285
	{
286
		$this->data_attributes[$key] = $value;
287
		
288
		return $this;
289
	}
290
291
292
	/**
293
	 * Set attributes for a element
294
	 * @param array $attrs
295
	 * @return static
296
	 */
297
	public function addAttributes(array $attrs)
298
	{
299
		$this->attributes = $this->attributes + $attrs;
300
301
		return $this;
302
	}
303
304
305
	/**
306
	 * Check whether given property is string or callable
307
	 * @param  mixed $property
308
	 * @return void
309
	 * @throws DataGridException
310
	 */
311
	protected function checkPropertyStringOrCallable($property, $name)
312
	{
313
		if (!is_string($property) && !is_callable($property) && !is_null($property)) {
314
			throw new DataGridException(
315
				"Action {$name} has to be either string or a callback returning string"
316
			);
317
		}
318
	}
319
320
321
	/**
322
	 * Check whether given property is string or callable
323
	 * 	in that case call callback and check property and return it
324
	 * @param  Row                  $row
325
	 * @param  string|callable|null $property
326
	 * @param  string               $name
327
	 * @return string
328
	 * @throws DataGridException
329
	 */
330
	public function getPropertyStringOrCallableGetString(Row $row, $property, $name)
331
	{
332
		/**
333
		 * String
334
		 */
335
		if (is_string($property)) {
336
			return $property;
337
		}
338
339
		/**
340
		 * Callable
341
		 */
342
		if (is_callable($property)) {
343
			$value = call_user_func($property, $row->getItem());
344
345
			if (!is_string($value)) {
346
				throw new DataGridException("Action {$name} callback has to return a string");
347
			}
348
349
			return $value;
350
		}
351
352
		return $property;
353
	}
354
355
356
	/**
357
	 * Translator helper
358
	 * @param  string $message
359
	 * @return string
360
	 */
361
	protected function translate($message)
362
	{
363
		return $this->grid->getTranslator()->translate($message);
364
	}
365
366
}
367