From 8f8a12e1cb1678b6a576707a6d010a725db3bbe9 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Fri, 24 May 2024 16:09:10 +0700 Subject: [PATCH 1/4] Refactor `ActiveQuery::removeDuplicatedModels()` to separate `ArrayAccess` implementation --- src/ActiveQuery.php | 70 ++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/ActiveQuery.php b/src/ActiveQuery.php index dd866912b..6d93bddf5 100644 --- a/src/ActiveQuery.php +++ b/src/ActiveQuery.php @@ -23,6 +23,11 @@ use Yiisoft\Definitions\Exception\NotInstantiableException; use Yiisoft\Factory\NotFoundException; +use function array_column; +use function array_combine; +use function array_flip; +use function array_intersect_key; +use function array_map; use function array_merge; use function array_values; use function count; @@ -289,53 +294,48 @@ public function populate(array $rows, Closure|string|null $indexBy = null): arra */ private function removeDuplicatedModels(array $models): array { - $hash = []; + $model = reset($models); - $pks = $this->getARInstance()->primaryKey(); + if ($this->asArray) { + $pks = $this->getARInstance()->primaryKey(); - if (count($pks) > 1) { - // Composite primary key. - foreach ($models as $i => $model) { - $key = []; - foreach ($pks as $pk) { - if (!isset($model[$pk])) { - // Don't continue if the primary key isn't part of the result set. - break 2; - } - $key[] = $model[$pk]; - } - - $key = serialize($key); - - if (isset($hash[$key])) { - unset($models[$i]); - } else { - $hash[$key] = true; - } + if (empty($pks)) { + throw new InvalidConfigException("Primary key of '$this->arClass' can not be empty."); } - } elseif (empty($pks)) { - throw new InvalidConfigException("Primary key of '$this->arClass' can not be empty."); - } else { - // Single column primary key. - $pk = reset($pks); - foreach ($models as $i => $model) { + foreach ($pks as $pk) { if (!isset($model[$pk])) { - // Don't continue if the primary key isn't part of the result set. - break; + return $models; } + } - $key = $model[$pk]; + if (count($pks) === 1) { + $hash = array_column($models, reset($pks)); + } else { + $flippedPks = array_flip($pks); + $hash = array_map(static fn ($model) => serialize(array_intersect_key($model, $flippedPks)), $models); + } + } else { + $pks = $model->getPrimaryKey(true); - if (isset($hash[$key])) { - unset($models[$i]); - } else { - $hash[$key] = true; + if (empty($pks)) { + throw new InvalidConfigException("Primary key of '$this->arClass' can not be empty."); + } + + foreach ($pks as $pk) { + if ($pk === null) { + return $models; } } + + if (count($pks) === 1) { + $hash = array_map(static fn ($model) => $model->getPrimaryKey(), $models); + } else { + $hash = array_map(static fn ($model) => serialize($model->getPrimaryKey(true)), $models); + } } - return array_values($models); + return array_values(array_combine($hash, $models)); } /** From cd572eb3ee660c681036a00322375abb0060ce42 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Fri, 24 May 2024 16:15:49 +0700 Subject: [PATCH 2/4] Fix psalm issues --- src/ActiveQuery.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ActiveQuery.php b/src/ActiveQuery.php index 6d93bddf5..d583855ea 100644 --- a/src/ActiveQuery.php +++ b/src/ActiveQuery.php @@ -329,9 +329,9 @@ private function removeDuplicatedModels(array $models): array } if (count($pks) === 1) { - $hash = array_map(static fn ($model) => $model->getPrimaryKey(), $models); + $hash = array_map(static fn ($model): mixed => $model->getPrimaryKey(), $models); } else { - $hash = array_map(static fn ($model) => serialize($model->getPrimaryKey(true)), $models); + $hash = array_map(static fn ($model): mixed => serialize($model->getPrimaryKey(true)), $models); } } From 022e521f6d9e0a65e84404fd9d20b98ba8b43168 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Sat, 25 May 2024 10:55:33 +0700 Subject: [PATCH 3/4] Improve --- src/ActiveQuery.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ActiveQuery.php b/src/ActiveQuery.php index d583855ea..a95cdf29c 100644 --- a/src/ActiveQuery.php +++ b/src/ActiveQuery.php @@ -27,6 +27,7 @@ use function array_combine; use function array_flip; use function array_intersect_key; +use function array_key_first; use function array_map; use function array_merge; use function array_values; @@ -35,6 +36,7 @@ use function in_array; use function is_array; use function is_int; +use function is_scalar; use function is_string; use function preg_match; use function reset; @@ -313,7 +315,10 @@ private function removeDuplicatedModels(array $models): array $hash = array_column($models, reset($pks)); } else { $flippedPks = array_flip($pks); - $hash = array_map(static fn ($model) => serialize(array_intersect_key($model, $flippedPks)), $models); + $hash = array_map( + static fn ($model): string => serialize(array_intersect_key($model, $flippedPks)), + $models + ); } } else { $pks = $model->getPrimaryKey(true); @@ -329,9 +334,10 @@ private function removeDuplicatedModels(array $models): array } if (count($pks) === 1) { - $hash = array_map(static fn ($model): mixed => $model->getPrimaryKey(), $models); + $key = array_key_first($pks); + $hash = array_map(static fn ($model): string => (string) $model->getAttribute($key), $models); } else { - $hash = array_map(static fn ($model): mixed => serialize($model->getPrimaryKey(true)), $models); + $hash = array_map(static fn ($model): string => serialize($model->getPrimaryKey(true)), $models); } } From 09830cce969e843f867cc13710067bbf63f42979 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Sat, 25 May 2024 03:55:53 +0000 Subject: [PATCH 4/4] Apply fixes from StyleCI --- src/ActiveQuery.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ActiveQuery.php b/src/ActiveQuery.php index a95cdf29c..c9a0394ec 100644 --- a/src/ActiveQuery.php +++ b/src/ActiveQuery.php @@ -36,7 +36,6 @@ use function in_array; use function is_array; use function is_int; -use function is_scalar; use function is_string; use function preg_match; use function reset;