From 0781b02cc355b171e2eb544bc7897bc458ec56d8 Mon Sep 17 00:00:00 2001 From: PowerGamer1 Date: Wed, 13 Jan 2021 10:47:30 +0200 Subject: [PATCH] Fix #18455: Add ability to use separate attributes for data model and filter model of `yii\grid\GridView` in `yii\grid\DataColumn` --- framework/CHANGELOG.md | 1 + framework/grid/DataColumn.php | 31 ++++++++++++++++++++++++------- tests/framework/grid/DataColumnTest.php | 29 +++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 9a5aea7..70ba095 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -4,6 +4,7 @@ Yii Framework 2 Change Log 2.0.41 under development ------------------------ +- Enh #18455: Add ability to use separate attributes for data model and filter model of `yii\grid\GridView` in `yii\grid\DataColumn` (PowerGamer1) - Enh #18447: Do not use `getLastInsertID` to get PK from insert query to lower collision probability for concurrent inserts (darkdef) - Bug #18448: Fix issues in queries and tests for older MSSQL versions (darkdef) - Bug #18464: Fix bug with processing fallback messages when translation language is set to `null` (bizley) diff --git a/framework/grid/DataColumn.php b/framework/grid/DataColumn.php index b5a61c2..8760104 100644 --- a/framework/grid/DataColumn.php +++ b/framework/grid/DataColumn.php @@ -117,7 +117,24 @@ class DataColumn extends Column * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. */ public $filterInputOptions = ['class' => 'form-control', 'id' => null]; + /** + * @var string the attribute name of the [[GridView::filterModel]] associated with this column. If not set, + * will have the same value as [[attribute]]. + * @since 2.0.41 + */ + public $filterAttribute; + + /** + * {@inheritdoc} + */ + public function init() + { + parent::init(); + if($this->filterAttribute === null) { + $this->filterAttribute = $this->attribute; + } + } /** * {@inheritdoc} @@ -161,7 +178,7 @@ class DataColumn extends Column $model = $modelClass::instance(); $label = $model->getAttributeLabel($this->attribute); } elseif ($this->grid->filterModel !== null && $this->grid->filterModel instanceof Model) { - $label = $this->grid->filterModel->getAttributeLabel($this->attribute); + $label = $this->grid->filterModel->getAttributeLabel($this->filterAttribute); } else { $models = $provider->getModels(); if (($model = reset($models)) instanceof Model) { @@ -189,26 +206,26 @@ class DataColumn extends Column $model = $this->grid->filterModel; - if ($this->filter !== false && $model instanceof Model && $this->attribute !== null && $model->isAttributeActive($this->attribute)) { - if ($model->hasErrors($this->attribute)) { + if ($this->filter !== false && $model instanceof Model && $this->filterAttribute !== null && $model->isAttributeActive($this->filterAttribute)) { + if ($model->hasErrors($this->filterAttribute)) { Html::addCssClass($this->filterOptions, 'has-error'); - $error = ' ' . Html::error($model, $this->attribute, $this->grid->filterErrorOptions); + $error = ' ' . Html::error($model, $this->filterAttribute, $this->grid->filterErrorOptions); } else { $error = ''; } if (is_array($this->filter)) { $options = array_merge(['prompt' => ''], $this->filterInputOptions); - return Html::activeDropDownList($model, $this->attribute, $this->filter, $options) . $error; + return Html::activeDropDownList($model, $this->filterAttribute, $this->filter, $options) . $error; } elseif ($this->format === 'boolean') { $options = array_merge(['prompt' => ''], $this->filterInputOptions); - return Html::activeDropDownList($model, $this->attribute, [ + return Html::activeDropDownList($model, $this->filterAttribute, [ 1 => $this->grid->formatter->booleanFormat[1], 0 => $this->grid->formatter->booleanFormat[0], ], $options) . $error; } $options = array_merge(['maxlength' => true], $this->filterInputOptions); - return Html::activeTextInput($model, $this->attribute, $options) . $error; + return Html::activeTextInput($model, $this->filterAttribute, $options) . $error; } return parent::renderFilterCellContent(); diff --git a/tests/framework/grid/DataColumnTest.php b/tests/framework/grid/DataColumnTest.php index 9d0e001..487d15d 100644 --- a/tests/framework/grid/DataColumnTest.php +++ b/tests/framework/grid/DataColumnTest.php @@ -235,4 +235,33 @@ HTML HTML , $result); } + + /** + * @see DataColumn::$filterAttribute + * @see DataColumn::renderFilterCellContent() + */ + public function testFilterInputWithFilterAttribute() + { + $this->mockApplication(); + + $grid = new GridView([ + 'dataProvider' => new ArrayDataProvider([ + 'allModels' => [], + ]), + 'columns' => [ + 0 => [ + 'attribute' => 'username', + 'filterAttribute' => 'user_id', + ], + ], + 'filterModel' => new \yiiunit\data\base\RulesModel(['rules' => [['user_id', 'safe']]]), + ]); + + $dataColumn = $grid->columns[0]; + $method = new \ReflectionMethod($dataColumn, 'renderFilterCellContent'); + $method->setAccessible(true); + $result = $method->invoke($dataColumn); + + $this->assertEquals('', $result); + } }