From 7446b7cdf8baf3a9017173b312f915a3319b2262 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Thu, 30 Apr 2026 15:32:46 +0700 Subject: [PATCH 1/3] Fix indexed and associative values on `upsert()` --- src/ActiveRecord.php | 5 +---- tests/ActiveRecordTest.php | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/ActiveRecord.php b/src/ActiveRecord.php index bf708298a..1e073b08f 100644 --- a/src/ActiveRecord.php +++ b/src/ActiveRecord.php @@ -162,10 +162,7 @@ protected function upsertInternal(?array $insertProperties = null, array|bool $u $updateNames = array_filter($updateProperties, is_int(...), ARRAY_FILTER_USE_KEY); if (!empty($updateNames)) { - $updateProperties = array_merge( - array_diff_key($updateProperties, $updateNames), - $this->newPropertyValues($updateNames), - ); + $updateProperties = array_diff_key($updateProperties, $updateNames) + $this->newValues($updateNames); } /** @psalm-var array $updateProperties */ diff --git a/tests/ActiveRecordTest.php b/tests/ActiveRecordTest.php index bf34129f7..c0ea97f18 100644 --- a/tests/ActiveRecordTest.php +++ b/tests/ActiveRecordTest.php @@ -1293,7 +1293,7 @@ public static function dataUpsert(): array 'expected' => [ 'id' => 3, 'email' => 'user3@example.com', - 'address' => 'insert address', + 'address' => 'update address', ], ], ]; From fb877b0eb722cf70a4986ea15a42f58a09dbe617 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Fri, 1 May 2026 08:55:51 +0700 Subject: [PATCH 2/3] Update doc and add a line to CHANGELOG.md [skip ci] --- CHANGELOG.md | 1 + src/ActiveRecordInterface.php | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0159ad092..68ee60b5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Bug #558: Fix `SoftDelete` with initiated custom date (@Tigrov) - Enh #564: Clarify `$relations` parameter type in `JoinWith::__construct()` from `array` to `array` (@vjik) +- Bug #562: Fix `ActiveRecordInterface::upsert()` to prioritize passed associative values during updates (@Tigrov) ## 1.0.2 March 11, 2026 diff --git a/src/ActiveRecordInterface.php b/src/ActiveRecordInterface.php index fcf37768a..8ad87bfae 100644 --- a/src/ActiveRecordInterface.php +++ b/src/ActiveRecordInterface.php @@ -697,10 +697,12 @@ public function updateAll(array $propertyValues, array|string $condition = [], a * ``` * * @param array|null $insertProperties List of property names or name-values pairs that need to be inserted. + * If name-value pairs are specified, the values will be used for insertion. * Defaults to `null`, meaning all changed property values will be inserted. * @param array|bool $updateProperties List of property names or name-values pairs that need to be updated - * if the record already exists. Also available a boolean value: - * - `true` the record values will be updated to match the insert property values; + * if the record already exists. If name-value pairs are specified, the values will be used for update. + * Also available a boolean value: + * - `true` the record values will be updated to match the inserted property values; * - `false` no update will be performed if the record already exist. * * @throws InvalidConfigException From 4b0c2deb711f7fafd5f6a07065c47f6e41ffd991 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Fri, 1 May 2026 09:18:07 +0700 Subject: [PATCH 3/3] Update `BeforeUpsert` doc [skip ci] --- src/Event/BeforeUpsert.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Event/BeforeUpsert.php b/src/Event/BeforeUpsert.php index 526f29ab8..b9bfd94d8 100644 --- a/src/Event/BeforeUpsert.php +++ b/src/Event/BeforeUpsert.php @@ -16,9 +16,12 @@ final class BeforeUpsert extends AbstractEvent { /** * @param ActiveRecordInterface $model The model being upserted. - * @param array|null $insertProperties Properties to be inserted. If null, the properties will be taken from the model. - * @param array|bool $updateProperties Properties to be updated. If false, no properties will be updated. - * If true, `$insertProperties` will be used for update as well. + * @param array|null $insertProperties List of property names or name-values pairs that need to be inserted. + * If name-value pairs are specified, the values will be used for insertion. + * If `null`, the properties will be taken from the model. + * @param array|bool $updateProperties List of property names or name-values pairs that need to be updated + * if the record already exists. If name-value pairs are specified, the values will be used for update. + * If `true`, `$insertProperties` will be used for update as well. If `false`, no properties will be updated. */ public function __construct( ActiveRecordInterface $model,