From 0b43aa4f8158b47e3fea14d6f44a10b8510f8bf3 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 24 Nov 2013 13:47:40 -0500 Subject: [PATCH] Fixes #1310: ActiveRelation does not preserve order of items on find via() and viaTable() --- framework/yii/db/ActiveRelationTrait.php | 41 +++++++++++++++++++------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/framework/yii/db/ActiveRelationTrait.php b/framework/yii/db/ActiveRelationTrait.php index be42eb6..2960196 100644 --- a/framework/yii/db/ActiveRelationTrait.php +++ b/framework/yii/db/ActiveRelationTrait.php @@ -142,35 +142,42 @@ trait ActiveRelationTrait */ private function buildBuckets($models, $link, $viaModels = null, $viaLink = null) { - $buckets = []; - $linkKeys = array_keys($link); - foreach ($models as $i => $model) { - $key = $this->getModelKey($model, $linkKeys); - if ($this->indexBy !== null) { - $buckets[$key][$i] = $model; - } else { - $buckets[$key][] = $model; - } - } - if ($viaModels !== null) { - $viaBuckets = []; + $map = []; $viaLinkKeys = array_keys($viaLink); $linkValues = array_values($link); foreach ($viaModels as $viaModel) { $key1 = $this->getModelKey($viaModel, $viaLinkKeys); $key2 = $this->getModelKey($viaModel, $linkValues); - if (isset($buckets[$key2])) { - foreach ($buckets[$key2] as $i => $bucket) { + $map[$key2][$key1] = true; + } + } + + $buckets = []; + $linkKeys = array_keys($link); + + if (isset($map)) { + foreach ($models as $i => $model) { + $key = $this->getModelKey($model, $linkKeys); + if (isset($map[$key])) { + foreach (array_keys($map[$key]) as $key2) { if ($this->indexBy !== null) { - $viaBuckets[$key1][$i] = $bucket; + $buckets[$key2][$i] = $model; } else { - $viaBuckets[$key1][] = $bucket; + $buckets[$key2][] = $model; } } } } - $buckets = $viaBuckets; + } else { + foreach ($models as $i => $model) { + $key = $this->getModelKey($model, $linkKeys); + if ($this->indexBy !== null) { + $buckets[$key][$i] = $model; + } else { + $buckets[$key][] = $model; + } + } } if (!$this->multiple) {