diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index e1f427477e..855850f876 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -4,6 +4,7 @@ Yii Framework 2 Change Log 2.0.10 under development ------------------------ +- Bug #12649: Fixed consistency of `indexBy` handling for `yii\db\Query::column()` (silverfire) - Bug #7670: Added `UrlNormalizer` for normalizing requests with and without trailing slashes (rob006, cronfy, klimov-paul) - Bug #9027: Fixed descendant class of `yii\web\UploadedFile` returns parent instances in case invoked after it (andrewnester) - Bug #9101: Fixed `yii\web\View` to respect `yii\web\AssetManager::appendTimstamp` property (githubjeka, silverfire) diff --git a/framework/db/Query.php b/framework/db/Query.php index fe77784c06..2ce7656a31 100644 --- a/framework/db/Query.php +++ b/framework/db/Query.php @@ -268,19 +268,22 @@ class Query extends Component implements QueryInterface */ public function column($db = null) { - if (!is_string($this->indexBy)) { + if ($this->indexBy === null) { return $this->createCommand($db)->queryColumn(); } - if (is_array($this->select) && count($this->select) === 1) { + + if (is_string($this->indexBy) && is_array($this->select) && count($this->select) === 1) { $this->select[] = $this->indexBy; } $rows = $this->createCommand($db)->queryAll(); $results = []; foreach ($rows as $row) { - if (array_key_exists($this->indexBy, $row)) { - $results[$row[$this->indexBy]] = reset($row); + $value = reset($row); + + if ($this->indexBy instanceof \Closure) { + $results[call_user_func($this->indexBy, $row)] = $value; } else { - $results[] = reset($row); + $results[$row[$this->indexBy]] = $value; } } return $results; diff --git a/tests/framework/db/QueryTest.php b/tests/framework/db/QueryTest.php index e21e57947a..a5a68f1420 100644 --- a/tests/framework/db/QueryTest.php +++ b/tests/framework/db/QueryTest.php @@ -237,6 +237,23 @@ abstract class QueryTest extends DatabaseTestCase ->indexBy('id') ->column($db); $this->assertEquals([3 => 'user3', 2 => 'user2', 1 => 'user1'], $result); + + // https://github.com/yiisoft/yii2/issues/12649 + $result = (new Query)->from('customer') + ->select(['name', 'id']) + ->orderBy(['id' => SORT_DESC]) + ->indexBy(function ($row) { + return $row['id'] * 2; + }) + ->column($db); + $this->assertEquals([6 => 'user3', 4 => 'user2', 2 => 'user1'], $result); + + $result = (new Query)->from('customer') + ->select(['name']) + ->indexBy('name') + ->orderBy(['id' => SORT_DESC]) + ->column($db); + $this->assertEquals(['user3' => 'user3', 'user2' => 'user2', 'user1' => 'user1'], $result); } public function testCount()