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\DataGridColumnRendererException; |
14
|
|
|
use Ublaboo\DataGrid\Exception\DataGridException; |
15
|
|
|
use Ublaboo\DataGrid\Row; |
16
|
|
|
use Ublaboo\DataGrid\Traits; |
17
|
|
|
|
18
|
1 |
|
class Action extends Column |
19
|
|
|
{ |
20
|
1 |
|
use Traits\TButtonTryAddIcon; |
21
|
1 |
|
use Traits\TButtonText; |
22
|
1 |
|
use Traits\TLink; |
23
|
1 |
|
use Traits\TRenderCondition; |
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
|
|
|
* @var array |
67
|
|
|
*/ |
68
|
|
|
protected $parameters = []; |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* @var string|callable |
72
|
|
|
*/ |
73
|
|
|
protected $icon; |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* @var string|callable |
77
|
|
|
*/ |
78
|
|
|
protected $class = 'btn btn-xs btn-default'; |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* @var bool |
82
|
|
|
*/ |
83
|
|
|
protected $open_in_new_tab = false; |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* @var string|callable |
87
|
|
|
*/ |
88
|
|
|
private $title; |
89
|
|
|
|
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* @param DataGrid $grid |
93
|
|
|
* @param string $href |
94
|
|
|
* @param string $name |
95
|
|
|
* @param array $params |
96
|
|
|
*/ |
97
|
|
View Code Duplication |
public function __construct(DataGrid $grid, $href, $name, $params) |
|
|
|
|
98
|
|
|
{ |
99
|
1 |
|
$this->grid = $grid; |
100
|
1 |
|
$this->href = $href; |
101
|
1 |
|
$this->name = $name; |
102
|
1 |
|
$this->params = $params; |
103
|
1 |
|
} |
104
|
|
|
|
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Render row item into template |
108
|
|
|
* @param Row $row |
109
|
|
|
* @return mixed |
110
|
|
|
*/ |
111
|
|
|
public function render(Row $row) |
112
|
|
|
{ |
113
|
1 |
|
if (!$this->shouldBeRendered($row)) { |
114
|
1 |
|
return null; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
try { |
118
|
|
|
// Renderer function may be used |
119
|
1 |
|
return $this->useRenderer($row); |
120
|
1 |
|
} catch (DataGridColumnRendererException $e) { |
121
|
|
|
// Do not use renderer |
122
|
|
|
} |
123
|
|
|
|
124
|
1 |
|
$link = $this->createLink( |
125
|
1 |
|
$this->grid, |
126
|
1 |
|
$this->href, |
127
|
1 |
|
$this->getItemParams($row, $this->params) + $this->parameters |
128
|
|
|
); |
129
|
|
|
|
130
|
1 |
|
$a = Html::el('a')->href($link); |
131
|
|
|
|
132
|
1 |
|
$this->tryAddIcon($a, $this->getIcon($row), $this->getName()); |
|
|
|
|
133
|
|
|
|
134
|
1 |
|
if (!empty($this->data_attributes)) { |
135
|
|
|
foreach ($this->data_attributes as $key => $value) { |
136
|
|
|
$a->data($key, $value); |
137
|
|
|
} |
138
|
|
|
} |
139
|
|
|
|
140
|
1 |
|
if (!empty($this->attributes)) { |
141
|
|
|
$a->addAttributes($this->attributes); |
142
|
|
|
} |
143
|
|
|
|
144
|
1 |
|
$a->addText($this->translate($this->getName())); |
|
|
|
|
145
|
|
|
|
146
|
1 |
|
if ($this->title) { |
147
|
1 |
|
$a->title($this->translate($this->getTitle($row))); |
148
|
|
|
} |
149
|
|
|
|
150
|
1 |
|
if ($this->class) { |
151
|
1 |
|
$a->class($this->getClass($row)); |
152
|
|
|
} |
153
|
|
|
|
154
|
1 |
|
if ($confirm = $this->getConfirm($row)) { |
155
|
1 |
|
$a->data(static::$data_confirm_attribute_name, $confirm); |
156
|
|
|
} |
157
|
|
|
|
158
|
1 |
|
if ($this->open_in_new_tab) { |
159
|
|
|
$a->addAttributes(['target' => '_blank']); |
160
|
|
|
} |
161
|
|
|
|
162
|
1 |
|
return $a; |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Add parameters to link |
168
|
|
|
* @param array $parameters |
169
|
|
|
* @return static |
170
|
|
|
*/ |
171
|
|
|
public function addParameters(array $parameters) |
172
|
|
|
{ |
173
|
|
|
$this->parameters = $parameters; |
174
|
|
|
|
175
|
|
|
return $this; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* Set attribute title |
181
|
|
|
* @param string|callable $title |
182
|
|
|
* @return static |
183
|
|
|
* @throws DataGridException |
184
|
|
|
*/ |
185
|
|
|
public function setTitle($title) |
186
|
|
|
{ |
187
|
1 |
|
$this->checkPropertyStringOrCallable($title, 'title'); |
188
|
|
|
|
189
|
1 |
|
$this->title = $title; |
190
|
|
|
|
191
|
1 |
|
return $this; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* Get attribute title |
197
|
|
|
* @param Row $row |
198
|
|
|
* @return string |
199
|
|
|
* @throws DataGridException |
200
|
|
|
*/ |
201
|
|
|
public function getTitle(Row $row) |
202
|
|
|
{ |
203
|
|
|
/** |
204
|
|
|
* If user callback was used for setting action title, it has to return string |
205
|
|
|
*/ |
206
|
1 |
|
return $this->getPropertyStringOrCallableGetString($row, $this->title, 'title'); |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Set attribute class |
212
|
|
|
* @param string|callable $class |
213
|
|
|
* @return static |
214
|
|
|
* @throws DataGridException |
215
|
|
|
*/ |
216
|
|
|
public function setClass($class) |
217
|
|
|
{ |
218
|
1 |
|
$this->checkPropertyStringOrCallable($class, 'class'); |
219
|
|
|
|
220
|
1 |
|
$this->class = $class; |
221
|
|
|
|
222
|
1 |
|
return $this; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Get attribute class |
228
|
|
|
* @param Row $row |
229
|
|
|
* @return string |
230
|
|
|
* @throws DataGridException |
231
|
|
|
*/ |
232
|
|
|
public function getClass(Row $row) |
233
|
|
|
{ |
234
|
|
|
/** |
235
|
|
|
* If user callback was used for setting action class, it has to return string |
236
|
|
|
*/ |
237
|
1 |
|
return $this->getPropertyStringOrCallableGetString($row, $this->class, 'class'); |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* Set icon |
243
|
|
|
* @param string|callable $icon |
244
|
|
|
* @return static|callable |
245
|
|
|
* @throws DataGridException |
246
|
|
|
*/ |
247
|
|
|
public function setIcon($icon) |
248
|
|
|
{ |
249
|
1 |
|
$this->checkPropertyStringOrCallable($icon, 'icon'); |
250
|
|
|
|
251
|
1 |
|
$this->icon = $icon; |
252
|
|
|
|
253
|
1 |
|
return $this; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Get icon |
259
|
|
|
* @param Row $row |
260
|
|
|
* @return string |
261
|
|
|
* @throws DataGridException |
262
|
|
|
*/ |
263
|
|
|
public function getIcon(Row $row) |
264
|
|
|
{ |
265
|
|
|
/** |
266
|
|
|
* If user callback was used for setting action icon, it has to return string |
267
|
|
|
*/ |
268
|
1 |
|
return $this->getPropertyStringOrCallableGetString($row, $this->icon, 'icon'); |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
|
272
|
|
|
/** |
273
|
|
|
* Set confirm dialog |
274
|
|
|
* @param string|callable $message |
275
|
|
|
* @param string $column |
276
|
|
|
* @return static |
277
|
|
|
* @throws DataGridException |
278
|
|
|
*/ |
279
|
|
|
public function setConfirm($message, $column = null) |
280
|
|
|
{ |
281
|
1 |
|
$this->checkPropertyStringOrCallable($message, 'confirmation message'); |
282
|
|
|
|
283
|
1 |
|
$this->confirm = [$message, $column]; |
284
|
|
|
|
285
|
1 |
|
return $this; |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
|
289
|
|
|
/** |
290
|
|
|
* Get confirm dialog for particular row item |
291
|
|
|
* @param Row $row |
292
|
|
|
* @return string |
293
|
|
|
* @throws DataGridException |
294
|
|
|
*/ |
295
|
|
|
public function getConfirm(Row $row) |
296
|
|
|
{ |
297
|
1 |
|
if (!$this->confirm) { |
298
|
1 |
|
return null; |
299
|
|
|
} |
300
|
|
|
|
301
|
1 |
|
$question = $this->confirm[0]; |
302
|
|
|
|
303
|
1 |
|
if (is_string($question)) { |
304
|
1 |
|
$question = $this->translate($question); |
305
|
|
|
} else { |
306
|
|
|
/** |
307
|
|
|
* If user callback was used for setting action confirmation dialog, it has to return string |
308
|
|
|
*/ |
309
|
|
|
$question = $this->getPropertyStringOrCallableGetString($row, $question, 'confirmation dialog'); |
310
|
|
|
} |
311
|
|
|
|
312
|
1 |
|
if (!$this->confirm[1]) { |
313
|
1 |
|
return $question; |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
return str_replace('%s', $row->getValue($this->confirm[1]), $question); |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* Setting data attributes |
322
|
|
|
* @param string $key |
323
|
|
|
* @param mixed $value |
324
|
|
|
* @return static |
325
|
|
|
*/ |
326
|
|
|
public function setDataAttribute($key, $value) |
327
|
|
|
{ |
328
|
|
|
$this->data_attributes[$key] = $value; |
329
|
|
|
|
330
|
|
|
return $this; |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
|
334
|
|
|
/** |
335
|
|
|
* Set attributes for a element |
336
|
|
|
* @param array $attrs |
337
|
|
|
* @return static |
338
|
|
|
*/ |
339
|
|
|
public function addAttributes(array $attrs) |
340
|
|
|
{ |
341
|
|
|
$this->attributes = $this->attributes + $attrs; |
342
|
|
|
|
343
|
|
|
return $this; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
|
347
|
|
|
/** |
348
|
|
|
* Check whether given property is string or callable |
349
|
|
|
* @param mixed $property |
350
|
|
|
* @return void |
351
|
|
|
* @throws DataGridException |
352
|
|
|
*/ |
353
|
|
|
protected function checkPropertyStringOrCallable($property, $name) |
354
|
|
|
{ |
355
|
1 |
|
if (!is_string($property) && !is_callable($property) && $property !== null) { |
356
|
|
|
throw new DataGridException( |
357
|
|
|
"Action {$name} has to be either string or a callback returning string" |
358
|
|
|
); |
359
|
|
|
} |
360
|
1 |
|
} |
361
|
|
|
|
362
|
|
|
|
363
|
|
|
/** |
364
|
|
|
* Check whether given property is string or callable |
365
|
|
|
* in that case call callback and check property and return it |
366
|
|
|
* @param Row $row |
367
|
|
|
* @param string|callable|null $property |
368
|
|
|
* @param string $name |
369
|
|
|
* @return string |
370
|
|
|
* @throws DataGridException |
371
|
|
|
*/ |
372
|
|
|
public function getPropertyStringOrCallableGetString(Row $row, $property, $name) |
373
|
|
|
{ |
374
|
|
|
/** |
375
|
|
|
* String |
376
|
|
|
*/ |
377
|
1 |
|
if (is_string($property)) { |
378
|
1 |
|
return $property; |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
/** |
382
|
|
|
* Callable |
383
|
|
|
*/ |
384
|
1 |
|
if (is_callable($property)) { |
385
|
|
|
$value = call_user_func($property, $row->getItem()); |
386
|
|
|
|
387
|
|
|
if (!is_string($value)) { |
388
|
|
|
throw new DataGridException("Action {$name} callback has to return a string"); |
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
return $value; |
392
|
|
|
} |
393
|
|
|
|
394
|
1 |
|
return $property; |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
|
398
|
|
|
/** |
399
|
|
|
* Translator helper |
400
|
|
|
* @param string $message |
401
|
|
|
* @return string |
402
|
|
|
*/ |
403
|
|
|
protected function translate($message) |
404
|
|
|
{ |
405
|
1 |
|
return $this->grid->getTranslator()->translate($message); |
406
|
|
|
} |
407
|
|
|
|
408
|
|
|
|
409
|
|
|
/** |
410
|
|
|
* Open link in new window/tab? |
411
|
|
|
* @return boolean |
412
|
|
|
*/ |
413
|
|
|
public function isOpenInNewTab() |
414
|
|
|
{ |
415
|
|
|
return $this->open_in_new_tab; |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
|
419
|
|
|
/** |
420
|
|
|
* Set link to open in new tab/window or not |
421
|
|
|
* @param bool $open_in_new_tab |
422
|
|
|
* @return $this |
423
|
|
|
*/ |
424
|
|
|
public function setOpenInNewTab($open_in_new_tab = true) |
425
|
|
|
{ |
426
|
|
|
$this->open_in_new_tab = $open_in_new_tab; |
427
|
|
|
return $this; |
428
|
|
|
} |
429
|
|
|
} |
430
|
|
|
|
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.