Column::getValue()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 4.125

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 3
cts 6
cp 0.5
rs 9.8333
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 4.125
1
<?php
2
3
/**
4
 * This file is part of the Grido (https://github.com/o5/grido)
5
 *
6
 * Copyright (c) 2011 Petr Bugyík (http://petr.bugyik.cz)
7
 *
8
 * For the full copyright and license information, please view
9
 * the file LICENSE.md that was distributed with this source code.
10
 */
11
12
namespace Grido\Components\Columns;
13
14
use Grido\Helpers;
15
use Grido\Exception;
16
17
/**
18
 * Column grid.
19
 *
20
 * @package     Grido
21
 * @subpackage  Components\Columns
22
 * @author      Petr Bugyík
23
 *
24
 * @property-read string $sort
25
 * @property-read \Nette\Utils\Html $cellPrototype
26
 * @property-read \Nette\Utils\Html $headerPrototype
27
 * @property-write callback $cellCallback
28
 * @property-write string $defaultSorting
29
 * @property mixed $customRender
30
 * @property-write array $customRenderVariables
31
 * @property-write mixed $customRenderExport
32
 * @property-write array $replacements
33
 * @property-write bool $sortable
34
 * @property string $column
35
 */
36
abstract class Column extends \Grido\Components\Component
37 1
{
38
    const ID = 'columns';
39
40
    const VALUE_IDENTIFIER = '%value';
41
42
    const ORDER_ASC = 'asc';
43
    const ORDER_DESC = 'desc';
44
45
    /** @var string */
46
    protected $sort;
47
48
    /** @var string */
49
    protected $column;
50
51
    /** @var \Nette\Utils\Html <td> html tag */
52
    protected $cellPrototype;
53
54
    /** @var callback returns td html element; function($row, Html $td) */
55
    protected $cellCallback;
56
57
    /** @var \Nette\Utils\Html <th> html tag */
58
    protected $headerPrototype;
59
60
    /** @var mixed custom rendering */
61
    protected $customRender;
62
63
    /** @var array custom rendering template variables */
64
    protected $customRenderVariables = [];
65
66
    /** @var mixed custom export rendering */
67
    protected $customRenderExport;
68
69
    /** @var bool */
70
    protected $sortable = FALSE;
71
72
    /** @var array of arrays('pattern' => 'replacement') */
73
    protected $replacements = [];
74 1
75
    /**
76
     * @param \Grido\Grid $grid
77
     * @param string $name
78
     * @param string $label
79
     */
80
    public function __construct($grid, $name, $label)
81
    {
82 1
        $this->addComponentToGrid($grid, Helpers::formatColumnName($name));
83
84 1
        $this->type = get_class($this);
85 1
        $this->label = $label;
86 1
    }
87
88
    /**
89
     * @param bool $sortable
90
     * @return Column
91
     */
92
    public function setSortable($sortable = TRUE)
93
    {
94 1
        $this->sortable = (bool) $sortable;
95 1
        return $this;
96
    }
97
98
    /**
99
     * @param array $replacement array('pattern' => 'replacement')
100
     * @return Column
101
     */
102
    public function setReplacement(array $replacement)
103
    {
104 1
        $this->replacements = $this->replacements + $replacement;
105 1
        return $this;
106
    }
107
108
    /**
109
     * @param mixed $column
110
     * @return Column
111
     */
112
    public function setColumn($column)
113
    {
114 1
        $this->column = $column;
115 1
        return $this;
116
    }
117
118
    /**
119
     * @param string $dir
120
     * @return Column
121
     */
122
    public function setDefaultSort($dir)
123
    {
124 1
        $this->grid->setDefaultSort([$this->getName() => $dir]);
125 1
        return $this;
126
    }
127
128
    /**
129
     * @param mixed $callback callback or string for name of template filename
130
     * @param array $variables - template variables
131
     * @return Column
132
     */
133
    public function setCustomRender($callback, $variables = [])
134
    {
135 1
        $this->customRender = $callback;
136 1
        $this->customRenderVariables = $variables;
137
138 1
        return $this;
139
    }
140
141
    /**
142
     * @param mixed $callback |
143
     * @return Column
144
     */
145
    public function setCustomRenderExport($callback)
146
    {
147 1
        $this->customRenderExport = $callback;
148 1
        return $this;
149
    }
150
151
    /**
152
     * @param callback $callback
153
     * @return Column
154
     */
155
    public function setCellCallback($callback)
156
    {
157 1
        $this->cellCallback = $callback;
158 1
        return $this;
159
    }
160
161
    /**********************************************************************************************/
162
163
    /**
164
     * Returns cell prototype (<td> html tag).
165
     * @param mixed $row
166
     * @return \Nette\Utils\Html
167
     */
168
    public function getCellPrototype($row = NULL)
169
    {
170 1
        $td = $this->cellPrototype;
171
172 1
        if ($td === NULL) { //cache
173 1
            $td = $this->cellPrototype = \Nette\Utils\Html::el('td')
174 1
                ->setClass(['grid-cell-' . $this->getName()]);
175 1
        }
176
177 1
        if ($this->cellCallback && $row !== NULL) {
178 1
            $td = clone $td;
179 1
            $td = call_user_func_array($this->cellCallback, [$row, $td]);
180 1
        }
181
182 1
        return $td;
183
    }
184
185
    /**
186
     * Returns header cell prototype (<th> html tag).
187
     * @return \Nette\Utils\Html
188
     */
189
    public function getHeaderPrototype()
190
    {
191 1
        if ($this->headerPrototype === NULL) {
192 1
            $this->headerPrototype = \Nette\Utils\Html::el('th')
193 1
                ->setClass(['column', 'grid-header-' . $this->getName()]);
194 1
        }
195
196 1
        if ($this->isSortable() && $this->getSort()) {
197 1
            $this->headerPrototype->class[] = $this->getSort() == self::ORDER_DESC
198 1
                ? 'desc'
199 1
                : 'asc';
200 1
        }
201
202 1
        return $this->headerPrototype;
203
    }
204
205
    /**
206
     * @return mixed
207
     * @internal
208
     */
209
    public function getColumn()
210
    {
211 1
        return $this->column ? $this->column : $this->getName();
212
    }
213
214
    /**
215
     * @return string
216
     * @internal
217
     */
218
    public function getSort()
219
    {
220 1
        if ($this->sort === NULL) {
221 1
            $name = $this->getName();
222
223 1
            $sort = isset($this->grid->sort[$name])
224 1
                ? $this->grid->sort[$name]
225 1
                : NULL;
226
227 1
            $this->sort = $sort === NULL ? NULL : $sort;
228 1
        }
229
230 1
        return $this->sort;
231
    }
232
233
    /**
234
     * @return mixed
235
     * @internal
236
     */
237
    public function getCustomRender()
238
    {
239 1
        return $this->customRender;
240
    }
241
242
    /**
243
     * @return array
244
     * @internal
245
     */
246
    public function getCustomRenderVariables()
247
    {
248 1
        return $this->customRenderVariables;
249
    }
250
251
    /**
252
     * @return mixed
253
     * @internal
254
     */
255
    public function getLabel()
256
    {
257 1
        return is_string($this->label)
258 1
            ? $this->translate($this->label)
259 1
            : $this->label;
260
    }
261
262
    /**********************************************************************************************/
263
264
    /**
265
     * @return bool
266
     * @internal
267
     */
268
    public function isSortable()
269
    {
270 1
        return $this->sortable;
271
    }
272
273
    /**
274
     * @return bool
275
     * @internal
276
     */
277
    public function hasFilter()
278
    {
279 1
        return (bool) $this->grid->getFilter($this->getName(), FALSE);
280
    }
281
282
    /**********************************************************************************************/
283
284
    /**
285
     * @param mixed $row
286
     * @return string
287
     * @internal
288
     */
289
    public function render($row)
290
    {
291 1
        if (is_callable($this->customRender)) {
292 1
            return call_user_func_array($this->customRender, [$row, $this->customRenderVariables]);
293
        }
294
295 1
        $value = $this->getValue($row);
296 1
        return $this->formatValue($value);
297
    }
298
299
    /**
300
     * @param mixed $row
301
     * @return string
302 1
     * @internal
303
     */
304
    public function renderExport($row)
305
    {
306 1
        if (is_callable($this->customRenderExport)) {
307 1
            return call_user_func_array($this->customRenderExport, [$row]);
308
        }
309
310 1
        $value = $this->getValue($row);
311 1
        return strip_tags($this->applyReplacement($value));
312 1
    }
313
314
    /**
315
     * @param mixed $row
316
     * @throws Exception
317
     * @return mixed
318
     */
319
    protected function getValue($row)
320
    {
321 1
        $column = $this->getColumn();
322 1
        if (is_string($column)) {
323 1
            return $this->grid->getProperty($row, Helpers::unformatColumnName($column));
324
325
        } elseif (is_callable($column)) {
326
            return call_user_func_array($column, [$row]);
327
328
        } else {
329
            throw new Exception('Column must be string or callback.');
330
        }
331
    }
332
333 1
    /**
334
     * @param mixed $value
335
     * @return mixed
336
     */
337
    protected function applyReplacement($value)
338
    {
339 1
        if ((is_scalar($value) || $value === NULL) && isset($this->replacements[$value])) {
340 1
            $replaced = $this->replacements[$value];
341 1
            if (is_scalar($replaced)) {
342 1
                $replaced = $this->translate($replaced);
343 1
            }
344
345 1
            $value = is_string($value)
346 1
                ? str_replace(static::VALUE_IDENTIFIER, $value, $replaced)
347 1
                : $replaced;
348 1
        }
349
350 1
        return $value;
351
    }
352
353 1
    /**
354
     * @param mixed $value
355
     * @return mixed
356
     */
357
    protected function formatValue($value)
358
    {
359 1
        $value = is_string($value)
360 1
            ? \Latte\Runtime\Filters::escapeHtml($value)
361 1
            : $value;
362
363 1
        return $this->applyReplacement($value);
364
    }
365
366
    /******************************* Aliases for filters ******************************************/
367
368
    /**
369
     * @return \Grido\Components\Filters\Text
370
     */
371
    public function setFilterText()
372
    {
373 1
        return $this->grid->addFilterText($this->getName(), $this->label);
374
    }
375
376
    /**
377
     * @return \Grido\Components\Filters\Date
378
     */
379
    public function setFilterDate()
380
    {
381 1
        return $this->grid->addFilterDate($this->getName(), $this->label);
382
    }
383
384
    /**
385
     * @return \Grido\Components\Filters\DateRange
386
     */
387
    public function setFilterDateRange()
388
    {
389 1
        return $this->grid->addFilterDateRange($this->getName(), $this->label);
390
    }
391
392
    /**
393
     * @return \Grido\Components\Filters\Check
394
     */
395
    public function setFilterCheck()
396
    {
397 1
        return $this->grid->addFilterCheck($this->getName(), $this->label);
398
    }
399
400
    /**
401
     * @param array $items
402
     * @return \Grido\Components\Filters\Select
403
     */
404
    public function setFilterSelect(array $items = NULL)
405
    {
406 1
        return $this->grid->addFilterSelect($this->getName(), $this->label, $items);
407
    }
408
409
    /**
410
     * @return \Grido\Components\Filters\Number
411
     */
412
    public function setFilterNumber()
413
    {
414 1
        return $this->grid->addFilterNumber($this->getName(), $this->label);
415
    }
416
417
    /**
418
     * @param \Nette\Forms\IControl $formControl
419
     * @return \Grido\Components\Filters\Custom
420
     */
421
    public function setFilterCustom(\Nette\Forms\IControl $formControl)
422
    {
423 1
        return $this->grid->addFilterCustom($this->getName(), $formControl);
424
    }
425
}
426