Completed
Push — master ( fe6898...6997a4 )
by Pavel
20:55
created

Column::getTemplateVariables()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

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

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
442
443
			return $parent->link($href, $params);
444
		} catch (DataGridHasToBeAttachedToPresenterComponentException $e) {
0 ignored issues
show
Bug introduced by
The class Ublaboo\DataGrid\Column\...enterComponentException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
445
			$parent = $this->grid->getPresenter();
0 ignored issues
show
Documentation introduced by
The property grid does not exist on object<Ublaboo\DataGrid\Column\Column>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
446
447
		} catch (InvalidArgumentException $e) {
448
			$parent = $this->grid->getPresenter();
0 ignored issues
show
Documentation introduced by
The property grid does not exist on object<Ublaboo\DataGrid\Column\Column>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
449
450
		}
451
452
		return $parent->link($href, $params);
453
	}
454
455
}
456