Completed
Push — master ( 91ef18...a6f36a )
by Pavel
03:04
created

Column::getItemParams()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 3
eloc 5
nc 3
nop 2
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\InvalidArgumentException;
12
use Ublaboo;
13
use Ublaboo\DataGrid\DataGrid;
14
use Ublaboo\DataGrid\Row;
15
use Ublaboo\DataGrid\Exception\DataGridException;
16
use Ublaboo\DataGrid\Exception\DataGridColumnRendererException;
17
use Ublaboo\DataGrid\Exception\DataGridHasToBeAttachedToPresenterComponentException;
18
19
abstract class Column extends Ublaboo\DataGrid\Object
20
{
21
22
	/**
23
	 * @var string
24
	 */
25
	protected $column;
26
27
	/**
28
	 * @var string
29
	 */
30
	protected $name;
31
32
	/**
33
	 * @var array
34
	 */
35
	protected $replacements = [];
36
37
	/**
38
	 * @var Renderer|NULL
39
	 */
40
	protected $renderer;
41
42
	/**
43
	 * @var string
44
	 */
45
	protected $template;
46
47
	/**
48
	 * @var boolean
49
	 */
50
	protected $is_sortable = FALSE;
51
52
	/**
53
	 * @var array
54
	 */
55
	protected $sort;
56
57
	/**
58
	 * @var bool
59
	 */
60
	protected $template_escaping = TRUE;
61
62
	/**
63
	 * @var string
64
	 */
65
	protected $align;
66
67
	/**
68
	 * @var array
69
	 */
70
	protected $template_variables;
71
72
	/**
73
	 * @var callable
74
	 */
75
	protected $editable_callback;
76
77
	/**
78
	 * @var DataGrid
79
	 */
80
	protected $grid;
81
82
83
	/**
84
	 * @param string $column
85
	 * @param string $name
86
	 */
87
	public function __construct($column, $name)
88
	{
89
		$this->column = $column;
90
		$this->name = $name;
91
	}
92
93
94
	/**
95
	 * Render row item into template
96
	 * @param  Row   $row
97
	 * @return mixed
98
	 */
99
	public function render(Row $row)
100
	{
101
		/**
102
		 * Renderer function may be used
103
		 */
104
		try {
105
			return $this->useRenderer($row);
106
		} catch (DataGridColumnRendererException $e) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
107
108
		/**
109
		 * Or replacements may be applied
110
		 */
111
		list($do_replace, $replaced) = $this->applyReplacements($row);
112
		if ($do_replace) {
113
			return $replaced;
114
		}
115
116
		return $this->getColumnValue($row);
117
	}
118
119
120
	/**
121
	 * Try to render item with custom renderer
122
	 * @param  Row   $row
123
	 * @return mixed
124
	 */
125
	public function useRenderer(Row $row)
126
	{
127
		$renderer = $this->getRenderer();
128
129
		if (!$renderer) {
130
			throw new DataGridColumnRendererException;
131
		}
132
133
		if ($renderer->getConditionCallback()) {
134
			if (!call_user_func_array($renderer->getConditionCallback(), [$row->getItem()])) {
135
				throw new DataGridColumnRendererException;
136
			}
137
138
			return call_user_func_array($renderer->getCallback(), [$row->getItem()]);
139
		}
140
141
		return call_user_func_array($renderer->getCallback(), [$row->getItem()]);
142
	}
143
144
145
	/**
146
	 * Should be column values escaped in latte?
147
	 * @param boolean $template_escaping
148
	 */
149
	public function setTemplateEscaping($template_escaping = TRUE)
150
	{
151
		$this->template_escaping = (bool) $template_escaping;
152
153
		return $this;
154
	}
155
156
157
	public function isTemplateEscaped()
158
	{
159
		return $this->template_escaping;
160
	}
161
162
163
	/**
164
	 * Set column sortable or not
165
	 * @param bool $sortable
166
	 */
167
	public function setSortable($sortable = TRUE)
168
	{
169
		$this->is_sortable = (bool) $sortable;
170
171
		return $this;
172
	}
173
174
175
	/**
176
	 * Tell whether column is sortable
177
	 * @return boolean
178
	 */
179
	public function isSortable()
180
	{
181
		return $this->is_sortable;
182
	}
183
184
185
	/**
186
	 * Get column name
187
	 * @return string
188
	 */
189
	public function getColumnName()
190
	{
191
		return $this->column;
192
	}
193
194
195
	/**
196
	 * Get column value of row item
197
	 * @param  Row   $row
198
	 * @return mixed
199
	 */
200
	public function getColumnValue(Row $row)
201
	{
202
		return $row->getValue($this->column);
203
	}
204
205
206
	public function getName()
207
	{
208
		return $this->name;
209
	}
210
211
212
	/**
213
	 * Set column replacements
214
	 * @param  array $replacements
215
	 * @return Column
216
	 */
217
	public function setReplacement(array $replacements)
218
	{
219
		$this->replacements = $replacements;
220
221
		return $this;
222
	}
223
224
225
	/**
226
	 * Tell whether columns has replacements
227
	 * @return boolean
228
	 */
229
	public function hasReplacements()
230
	{
231
		return (bool) $this->replacements;
232
	}
233
234
235
	/**
236
	 * Apply replacements
237
	 * @param  Row   $row
238
	 * @return array
239
	 */
240
	public function applyReplacements(Row $row)
241
	{
242
		$value = $row->getValue($this->column);
243
244
		if ((is_scalar($value) || is_null($value)) && isset($this->replacements[$value])) {
245
			return [TRUE, $this->replacements[$value]];
246
		}
247
248
		return [FALSE, NULL];
249
	}
250
251
252
	/**
253
	 * Set renderer callback and (it may be optional - the condition callback will decide)
254
	 * @param callable $renderer
255
	 */
256
	public function setRenderer($renderer, $condition_callback = NULL)
257
	{
258
		if ($this->hasReplacements()) {
259
			throw new DataGridException(
260
				"Use either Column::setReplacement() or Column::setRenderer, not both."
261
			);
262
		}
263
264
		if (!is_callable($renderer)) {
265
			throw new DataGridException(
266
				"Renderer (method Column::setRenderer()) must be callable."
267
			);
268
		}
269
270
		if (NULL != $condition_callback && !is_callable($condition_callback)) {
271
			throw new DataGridException(
272
				"Renderer (method Column::setRenderer()) must be callable."
273
			);
274
		}
275
276
		$this->renderer = new Renderer($renderer, $condition_callback);
277
278
		return $this;
279
	}
280
281
282
	/**
283
	 * Set renderer callback just if condition is truthy
284
	 * @param callable $renderer
285
	 */
286
	public function setRendererOnCondition($renderer, $condition_callback)
287
	{
288
		return $this->setRenderer($renderer, $condition_callback);
289
	}
290
291
292
	/**
293
	 * Return custom renderer callback
294
	 * @return Renderer|null
295
	 */
296
	public function getRenderer()
297
	{
298
		return $this->renderer;
299
	}
300
301
302
	/**
303
	 * Column may have its own template
304
	 * @param string $template
305
	 */
306
	public function setTemplate($template, array $template_variables = [])
307
	{
308
		$this->template = $template;
309
		$this->template_variables = $template_variables;
310
311
		return $this;
312
	}
313
314
315
	/**
316
	 * Column can have variables that will be passed to custom template scope
317
	 * @return array
318
	 */
319
	public function getTemplateVariables()
320
	{
321
		return $this->template_variables;
322
	}
323
324
325
	/**
326
	 * Tell whether column has its owntemplate
327
	 * @return bool
328
	 */
329
	public function hasTemplate()
330
	{
331
		return (bool) $this->template;
332
	}
333
334
335
	/**
336
	 * Get column template path
337
	 * @return string
338
	 */
339
	public function getTemplate()
340
	{
341
		return $this->template;
342
	}
343
344
345
	/**
346
	 * Tell whether data source is sorted by this collumn
347
	 * @return boolean
348
	 */
349
	public function isSortedBy()
350
	{
351
		return (bool) $this->sort;
352
	}
353
354
355
	/**
356
	 * Tell column his sorting options
357
	 * @param array $sort
358
	 */
359
	public function setSort(array $sort)
360
	{
361
		$this->sort = $sort[$this->column];
362
363
		return $this;
364
	}
365
366
367
	/**
368
	 * What sorting will be applied after next click?
369
	 * @return array
370
	 */
371
	public function getSortNext()
372
	{
373
		if ($this->sort == 'ASC') {
374
			return [$this->column => 'DESC'];
375
		} else if ($this->sort == 'DESC') {
376
			return [$this->column => NULL];
377
		}
378
379
		return [$this->column => 'ASC'];
380
	}
381
382
383
	/**
384
	 * Is sorting ascending?
385
	 * @return boolean
386
	 */
387
	public function isSortAsc()
388
	{
389
		return $this->sort == 'ASC';
390
	}
391
392
393
	/**
394
	 * Set column alignment
395
	 * @param string $align
396
	 */
397
	public function setAlign($align)
398
	{
399
		$this->align = (string) $align;
400
401
		return $this;
402
	}
403
404
405
	/**
406
	 * Has column some alignment?
407
	 * @return boolean [description]
408
	 */
409
	public function hasAlign()
410
	{
411
		return (bool) $this->align;
412
	}
413
414
415
	/**
416
	 * Get column alignment
417
	 * @return string
418
	 */
419
	public function getAlign()
420
	{
421
		return $this->align;
422
	}
423
424
425
	/**
426
	 * Set callback that will be called after inline editing
427
	 * @param callable $editable_callback
428
	 */
429
	public function setEditableCallback(callable $editable_callback)
430
	{
431
		$this->editable_callback = $editable_callback;
432
433
		return $this;
434
	}
435
436
437
	/**
438
	 * Return callback that is used after inline editing
439
	 * @return callable
440
	 */
441
	public function getEditableCallback()
442
	{
443
		return $this->editable_callback;
444
	}
445
446
447
	/**
448
	 * Is column editable?
449
	 * @return boolean
450
	 */
451
	public function isEditable()
452
	{
453
		return (bool) $this->getEditableCallback();
454
	}
455
456
457
	/**
458
	 * Create link to custom destination
459
	 * @param  string $href
460
	 * @param  array  $params
461
	 * @return string
462
	 * @throws DataGridHasToBeAttachedToPresenterComponentException
463
	 * @throws InvalidArgumentException
464
	 */
465
	protected function createLink($href, $params)
466
	{
467
		try {
468
			$parent = $this->grid->getParent();
469
470
			return $parent->link($href, $params);
471
		} catch (DataGridHasToBeAttachedToPresenterComponentException $e) {
472
			$parent = $this->grid->getPresenter();
473
474
		} catch (InvalidArgumentException $e) {
475
			$parent = $this->grid->getPresenter();
476
477
		}
478
479
		return $parent->link($href, $params);
480
	}
481
482
483
	/**
484
	 * Get row item params (E.g. action may be called id => $item->id, name => $item->name, ...)
485
	 * @param  Row   $row
486
	 * @param  array $params_list
487
	 * @return array
488
	 */
489
	protected function getItemParams(Row $row, array $params_list)
490
	{
491
		$return = [];
492
493
		foreach ($params_list as $param_name => $param) {
494
			$return[is_string($param_name) ? $param_name : $param] = $row->getValue($param);
495
		}
496
497
		return $return;
498
	}
499
500
}
501