1 | <?php |
||||
2 | /** |
||||
3 | * @link https://www.yiiframework.com/ |
||||
4 | * @copyright Copyright (c) 2008 Yii Software LLC |
||||
5 | * @license https://www.yiiframework.com/license/ |
||||
6 | */ |
||||
7 | |||||
8 | namespace yii\grid; |
||||
9 | |||||
10 | use Closure; |
||||
11 | use yii\base\Model; |
||||
12 | use yii\data\ActiveDataProvider; |
||||
13 | use yii\data\ArrayDataProvider; |
||||
14 | use yii\db\ActiveQueryInterface; |
||||
15 | use yii\helpers\ArrayHelper; |
||||
16 | use yii\helpers\Html; |
||||
17 | use yii\helpers\Inflector; |
||||
18 | |||||
19 | /** |
||||
20 | * DataColumn is the default column type for the [[GridView]] widget. |
||||
21 | * |
||||
22 | * It is used to show data columns and allows [[enableSorting|sorting]] and [[filter|filtering]] them. |
||||
23 | * |
||||
24 | * A simple data column definition refers to an attribute in the data model of the |
||||
25 | * GridView's data provider. The name of the attribute is specified by [[attribute]]. |
||||
26 | * |
||||
27 | * By setting [[value]] and [[label]], the header and cell content can be customized. |
||||
28 | * |
||||
29 | * A data column differentiates between the [[getDataCellValue|data cell value]] and the |
||||
30 | * [[renderDataCellContent|data cell content]]. The cell value is an un-formatted value that |
||||
31 | * may be used for calculation, while the actual cell content is a [[format|formatted]] version of that |
||||
32 | * value which may contain HTML markup. |
||||
33 | * |
||||
34 | * For more details and usage information on DataColumn, see the [guide article on data widgets](guide:output-data-widgets). |
||||
35 | * |
||||
36 | * @author Qiang Xue <[email protected]> |
||||
37 | * @since 2.0 |
||||
38 | */ |
||||
39 | class DataColumn extends Column |
||||
40 | { |
||||
41 | /** |
||||
42 | * @var string the attribute name associated with this column. When neither [[content]] nor [[value]] |
||||
43 | * is specified, the value of the specified attribute will be retrieved from each data model and displayed. |
||||
44 | * |
||||
45 | * Also, if [[label]] is not specified, the label associated with the attribute will be displayed. |
||||
46 | */ |
||||
47 | public $attribute; |
||||
48 | /** |
||||
49 | * @var string|null label to be displayed in the [[header|header cell]] and also to be used as the sorting |
||||
50 | * link label when sorting is enabled for this column. |
||||
51 | * If it is not set and the models provided by the GridViews data provider are instances |
||||
52 | * of [[\yii\db\ActiveRecord]], the label will be determined using [[\yii\db\ActiveRecord::getAttributeLabel()]]. |
||||
53 | * Otherwise [[\yii\helpers\Inflector::camel2words()]] will be used to get a label. |
||||
54 | */ |
||||
55 | public $label; |
||||
56 | /** |
||||
57 | * @var bool whether the header label should be HTML-encoded. |
||||
58 | * @see label |
||||
59 | * @since 2.0.1 |
||||
60 | */ |
||||
61 | public $encodeLabel = true; |
||||
62 | /** |
||||
63 | * @var string|Closure|null an anonymous function or a string that is used to determine the value to display in the current column. |
||||
64 | * |
||||
65 | * If this is an anonymous function, it will be called for each row and the return value will be used as the value to |
||||
66 | * display for every data model. The signature of this function should be: `function ($model, $key, $index, $column)`. |
||||
67 | * Where `$model`, `$key`, and `$index` refer to the model, key and index of the row currently being rendered |
||||
68 | * and `$column` is a reference to the [[DataColumn]] object. |
||||
69 | * |
||||
70 | * You may also set this property to a string representing the attribute name to be displayed in this column. |
||||
71 | * This can be used when the attribute to be displayed is different from the [[attribute]] that is used for |
||||
72 | * sorting and filtering. |
||||
73 | * |
||||
74 | * If this is not set, `$model[$attribute]` will be used to obtain the value, where `$attribute` is the value of [[attribute]]. |
||||
75 | */ |
||||
76 | public $value; |
||||
77 | /** |
||||
78 | * @var string|array|Closure in which format should the value of each data model be displayed as (e.g. `"raw"`, `"text"`, `"html"`, |
||||
79 | * `['date', 'php:Y-m-d']`). Supported formats are determined by the [[GridView::formatter|formatter]] used by |
||||
80 | * the [[GridView]]. Default format is "text" which will format the value as an HTML-encoded plain text when |
||||
81 | * [[\yii\i18n\Formatter]] is used as the [[GridView::$formatter|formatter]] of the GridView. |
||||
82 | * @see \yii\i18n\Formatter::format() |
||||
83 | */ |
||||
84 | public $format = 'text'; |
||||
85 | /** |
||||
86 | * @var bool whether to allow sorting by this column. If true and [[attribute]] is found in |
||||
87 | * the sort definition of [[GridView::dataProvider]], then the header cell of this column |
||||
88 | * will contain a link that may trigger the sorting when being clicked. |
||||
89 | */ |
||||
90 | public $enableSorting = true; |
||||
91 | /** |
||||
92 | * @var array the HTML attributes for the link tag in the header cell |
||||
93 | * generated by [[\yii\data\Sort::link]] when sorting is enabled for this column. |
||||
94 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. |
||||
95 | */ |
||||
96 | public $sortLinkOptions = []; |
||||
97 | /** |
||||
98 | * @var string|array|null|false the HTML code representing a filter input (e.g. a text field, a dropdown list) |
||||
99 | * that is used for this data column. This property is effective only when [[GridView::filterModel]] is set. |
||||
100 | * |
||||
101 | * - If this property is not set, a text field will be generated as the filter input with attributes defined |
||||
102 | * with [[filterInputOptions]]. See [[\yii\helpers\BaseHtml::activeInput]] for details on how an active |
||||
103 | * input tag is generated. |
||||
104 | * - If this property is an array, a dropdown list will be generated that uses this property value as |
||||
105 | * the list options. |
||||
106 | * - If you don't want a filter for this data column, set this value to be false. |
||||
107 | */ |
||||
108 | public $filter; |
||||
109 | /** |
||||
110 | * @var array the HTML attributes for the filter input fields. This property is used in combination with |
||||
111 | * the [[filter]] property. When [[filter]] is not set or is an array, this property will be used to |
||||
112 | * render the HTML attributes for the generated filter input fields. |
||||
113 | * |
||||
114 | * Empty `id` in the default value ensures that id would not be obtained from the model attribute thus |
||||
115 | * providing better performance. |
||||
116 | * |
||||
117 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. |
||||
118 | */ |
||||
119 | public $filterInputOptions = ['class' => 'form-control', 'id' => null]; |
||||
120 | /** |
||||
121 | * @var string|null the attribute name of the [[GridView::filterModel]] associated with this column. If not set, |
||||
122 | * will have the same value as [[attribute]]. |
||||
123 | * @since 2.0.41 |
||||
124 | */ |
||||
125 | public $filterAttribute; |
||||
126 | |||||
127 | |||||
128 | /** |
||||
129 | * {@inheritdoc} |
||||
130 | */ |
||||
131 | 9 | public function init() |
|||
132 | { |
||||
133 | 9 | parent::init(); |
|||
134 | 9 | if ($this->filterAttribute === null) { |
|||
135 | 8 | $this->filterAttribute = $this->attribute; |
|||
136 | } |
||||
137 | } |
||||
138 | |||||
139 | /** |
||||
140 | * {@inheritdoc} |
||||
141 | */ |
||||
142 | 1 | protected function renderHeaderCellContent() |
|||
143 | { |
||||
144 | 1 | if ($this->header !== null || $this->label === null && $this->attribute === null) { |
|||
145 | return parent::renderHeaderCellContent(); |
||||
146 | } |
||||
147 | |||||
148 | 1 | $label = $this->getHeaderCellLabel(); |
|||
149 | 1 | if ($this->encodeLabel) { |
|||
150 | 1 | $label = Html::encode($label); |
|||
151 | } |
||||
152 | |||||
153 | if ( |
||||
154 | 1 | $this->attribute !== null && $this->enableSorting && |
|||
155 | 1 | ($sort = $this->grid->dataProvider->getSort()) !== false && $sort->hasAttribute($this->attribute) |
|||
156 | ) { |
||||
157 | 1 | return $sort->link($this->attribute, array_merge($this->sortLinkOptions, ['label' => $label])); |
|||
158 | } |
||||
159 | |||||
160 | return $label; |
||||
161 | } |
||||
162 | |||||
163 | /** |
||||
164 | * {@inheritdoc} |
||||
165 | * @since 2.0.8 |
||||
166 | */ |
||||
167 | 3 | protected function getHeaderCellLabel() |
|||
168 | { |
||||
169 | 3 | $provider = $this->grid->dataProvider; |
|||
170 | |||||
171 | 3 | if ($this->label === null) { |
|||
172 | 3 | if ($this->attribute === null) { |
|||
173 | $label = ''; |
||||
174 | 3 | } elseif ($provider instanceof ActiveDataProvider && $provider->query instanceof ActiveQueryInterface) { |
|||
175 | /* @var $modelClass Model */ |
||||
176 | 1 | $modelClass = $provider->query->modelClass; |
|||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
177 | 1 | $model = $modelClass::instance(); |
|||
178 | 1 | $label = $model->getAttributeLabel($this->attribute); |
|||
179 | 2 | } elseif ($provider instanceof ArrayDataProvider && $provider->modelClass !== null) { |
|||
180 | /* @var $modelClass Model */ |
||||
181 | 1 | $modelClass = $provider->modelClass; |
|||
182 | 1 | $model = $modelClass::instance(); |
|||
183 | 1 | $label = $model->getAttributeLabel($this->attribute); |
|||
184 | 1 | } elseif ($this->grid->filterModel !== null && $this->grid->filterModel instanceof Model) { |
|||
185 | 1 | $label = $this->grid->filterModel->getAttributeLabel($this->filterAttribute); |
|||
186 | } else { |
||||
187 | $models = $provider->getModels(); |
||||
188 | if (($model = reset($models)) instanceof Model) { |
||||
189 | /* @var $model Model */ |
||||
190 | $label = $model->getAttributeLabel($this->attribute); |
||||
191 | } else { |
||||
192 | 3 | $label = Inflector::camel2words($this->attribute); |
|||
193 | } |
||||
194 | } |
||||
195 | } else { |
||||
196 | 1 | $label = $this->label; |
|||
197 | } |
||||
198 | |||||
199 | 3 | return $label; |
|||
200 | } |
||||
201 | |||||
202 | /** |
||||
203 | * {@inheritdoc} |
||||
204 | */ |
||||
205 | 5 | protected function renderFilterCellContent() |
|||
206 | { |
||||
207 | 5 | if (is_string($this->filter)) { |
|||
208 | 1 | return $this->filter; |
|||
209 | } |
||||
210 | |||||
211 | 4 | $model = $this->grid->filterModel; |
|||
212 | |||||
213 | 4 | if ($this->filter !== false && $model instanceof Model && $this->filterAttribute !== null && $model->isAttributeActive($this->filterAttribute)) { |
|||
214 | 4 | if ($model->hasErrors($this->filterAttribute)) { |
|||
215 | Html::addCssClass($this->filterOptions, 'has-error'); |
||||
216 | $error = ' ' . Html::error($model, $this->filterAttribute, $this->grid->filterErrorOptions); |
||||
217 | } else { |
||||
218 | 4 | $error = ''; |
|||
219 | } |
||||
220 | 4 | if (is_array($this->filter)) { |
|||
221 | 1 | $options = array_merge(['prompt' => '', 'strict' => true], $this->filterInputOptions); |
|||
222 | 1 | return Html::activeDropDownList($model, $this->filterAttribute, $this->filter, $options) . $error; |
|||
223 | 3 | } elseif ($this->format === 'boolean') { |
|||
224 | 1 | $options = array_merge(['prompt' => '', 'strict' => true], $this->filterInputOptions); |
|||
225 | 1 | return Html::activeDropDownList($model, $this->filterAttribute, [ |
|||
226 | 1 | 1 => $this->grid->formatter->booleanFormat[1], |
|||
227 | 1 | 0 => $this->grid->formatter->booleanFormat[0], |
|||
228 | 1 | ], $options) . $error; |
|||
229 | } |
||||
230 | 2 | $options = array_merge(['maxlength' => true], $this->filterInputOptions); |
|||
231 | |||||
232 | 2 | return Html::activeTextInput($model, $this->filterAttribute, $options) . $error; |
|||
233 | } |
||||
234 | |||||
235 | return parent::renderFilterCellContent(); |
||||
236 | } |
||||
237 | |||||
238 | /** |
||||
239 | * Returns the data cell value. |
||||
240 | * @param mixed $model the data model |
||||
241 | * @param mixed $key the key associated with the data model |
||||
242 | * @param int $index the zero-based index of the data model among the models array returned by [[GridView::dataProvider]]. |
||||
243 | * @return string the data cell value |
||||
244 | */ |
||||
245 | public function getDataCellValue($model, $key, $index) |
||||
246 | { |
||||
247 | if ($this->value !== null) { |
||||
248 | if (is_string($this->value)) { |
||||
249 | return ArrayHelper::getValue($model, $this->value); |
||||
250 | } |
||||
251 | |||||
252 | return call_user_func($this->value, $model, $key, $index, $this); |
||||
253 | } elseif ($this->attribute !== null) { |
||||
254 | return ArrayHelper::getValue($model, $this->attribute); |
||||
255 | } |
||||
256 | |||||
257 | return null; |
||||
258 | } |
||||
259 | |||||
260 | /** |
||||
261 | * {@inheritdoc} |
||||
262 | */ |
||||
263 | protected function renderDataCellContent($model, $key, $index) |
||||
264 | { |
||||
265 | if ($this->content === null) { |
||||
266 | return $this->grid->formatter->format($this->getDataCellValue($model, $key, $index), $this->format); |
||||
0 ignored issues
–
show
The method
format() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
267 | } |
||||
268 | |||||
269 | return parent::renderDataCellContent($model, $key, $index); |
||||
270 | } |
||||
271 | } |
||||
272 |