Completed
Push — master ( 6de470...9e4701 )
by Dmitry
12:25
created

GridView::columns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * Advanced Grid for Yii2
4
 *
5
 * @link      https://github.com/hiqdev/yii2-higrid
6
 * @package   yii2-higrid
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\higrid;
12
13
use Closure;
14
use hiqdev\yii2\assets\JqueryResizableColumns\ResizableColumnsAsset;
15
use Yii;
16
use yii\data\ArrayDataProvider;
17
use yii\helpers\ArrayHelper;
18
use yii\helpers\Json;
19
use yii\web\JsExpression;
20
21
/**
22
 * Class GridView
23
 * Todo: good description.
24
 * For now see [[columns()]] docs
25
 *
26
 * @author Andrii Vasyliev <[email protected]>
27
 * @author Dmytro Naumenko <[email protected]>
28
 */
29
class GridView extends \yii\grid\GridView
30
{
31
    /**
32
     * {@inheritdoc}
33
     */
34
    public $dataColumnClass = DataColumn::class;
35
36
    /**
37
     * {@inheritdoc}
38
     */
39
    public $detailViewClass = DetailView::class;
40
41
    /**
42
     * @var array|boolean
43
     *  - array: options for Jquery Resizable Columns plugin initiate call
44
     *  - boolean false: resizable is disabled
45
     *
46
     * Defaults to `['store' => new JsExpression('store')]`
47
     * @see registerResizableColumns()
48
     */
49
    public $resizableColumns = [];
50
51
    public function run()
52
    {
53
        $this->registerResizableColumns();
54
        parent::run();
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60
    public function getId($autoGenerate = true)
61
    {
62
        if ($autoGenerate && parent::getId(false) === null) {
63
            $this->id = hash('crc32b', Json::encode($this->columns));
64
        }
65
66
        return parent::getId();
67
    }
68
69
    /**
70
     * Registers ResizableColumns plugin when [[resizableColumns]] is not false.
71
     * TODO: move somewhere
72
     */
73
    public function registerResizableColumns()
74
    {
75
        if (!$this->resizableColumns !== false) {
76
            return;
77
        }
78
79
        $this->tableOptions['data-resizable-columns-id'] = $this->id;
80
81
        ResizableColumnsAsset::register($this->getView());
82
        $resizableColumns = Json::encode(ArrayHelper::merge([
83
            'store' => new JsExpression('store'),
84
        ], $this->resizableColumns));
85
        $this->getView()->registerJs("$('#{$this->id} table[data-resizable-columns-id]').resizableColumns($resizableColumns);");
86
    }
87
88
    /**
89
     * Runs DetailView widget based on this GridView.
90
     *
91
     * @param array $config Config that will be passed to [[detailViewClass]] initialisation.
92
     * Special element `gridOptions` will be merged to `GridView` initialisation config array.
93
     *
94
     * @throws \yii\base\InvalidConfigException
95
     *
96
     * @return mixed
97
     */
98
    public static function detailView(array $config = [])
99
    {
100
        /** @var static $grid */
101
        $grid = Yii::createObject(ArrayHelper::merge([
102
            'class' => get_called_class(),
103
            'dataProvider' => new ArrayDataProvider(['allModels' => [$config['model']]]),
104
        ], ArrayHelper::remove($config, 'gridOptions', [])));
105
        $class = $grid->detailViewClass ?: DetailView::class;
106
        $config['grid'] = $grid;
107
108
        return call_user_func([$class, 'widget'], $config);
109
    }
110
111
    /**
112
     * Returns array of columns configurations that will be used by widget to create
113
     * data columns and render them.
114
     *
115
     * Array format:
116
     *  key - column alias
117
     *  value - column configuration array
118
     *
119
     * Example:
120
     *
121
     * ```php
122
     * return [
123
     *     'login_and_avatar' => [
124
     *         'format' => 'raw',
125
     *         'value' => function ($model) {
126
     *             return Html::img($model->avatar) . $model->username;
127
     *         }
128
     *     ]
129
     * ];
130
     * ```
131
     *
132
     * Despite model does not have a `login_and_avatar` attribute, the following widget call will
133
     * use the definition above to render value:
134
     *
135
     * ```php
136
     * echo GridView::widget([
137
     *     'dataProvider' => $dataProvider,
138
     *     'columns' => ['login_and_avatar', 'status', 'actions'],
139
     * ]);
140
     * ```
141
     *
142
     * @return array
143
     */
144
    public function columns()
145
    {
146
        return [];
147
    }
148
149
    /**
150
     * Creates a [[DataColumn]] object with given config.
151
     *
152
     * @param array $config config for [[DataColumn]]
153
     * @return DataColumn the column instance
154
     */
155
    protected function createDataColumnByConfig(array $config = [])
156
    {
157
        return Yii::createObject(array_merge([
158
            'class' => $this->dataColumnClass ?: \yii\grid\DataColumn::class,
159
            'grid'  => $this,
160
        ], $config));
161
    }
162
163
    /**
164
     * {@inheritdoc}
165
     */
166
    protected function createDataColumn($text)
167
    {
168
        $columns = $this->columns();
169
170
        if (!isset($columns[$text]) || !is_array($columns[$text])) {
171
            return parent::createDataColumn($text);
172
        }
173
174
        $config = array_merge(['attribute' => $text], $columns[$text]);
175
        return $this->createDataColumnByConfig($config);
176
    }
177
178
    /**
179
     * @var Closure use it to change default summary rendering
180
     * Method signature:
181
     *
182
     * ```php
183
     * function ($grid, $defaultSummaryCallback)
184
     * ```
185
     *
186
     * Argument `$defaultSummaryCallback` will contain a Closure that will
187
     * render default summary.
188
     * ```
189
     *
190
     */
191
    public $summaryRenderer;
192
193
    /**
194
     * {@inheritdoc}
195
     */
196
    public function renderSummary()
197
    {
198
        if ($this->summaryRenderer instanceof Closure) {
199
            return call_user_func($this->summaryRenderer, $this, function () {
200
                return parent::renderSummary();
201
            });
202
        }
203
204
        return parent::renderSummary();
205
    }
206
}
207