From fb334ca8c2f11c299c3b24505e30a2a694f300e1 Mon Sep 17 00:00:00 2001 From: Pichinov-Jose Date: Wed, 22 Jul 2026 12:40:05 +0200 Subject: [PATCH] feat: sync combination updates made via legacy Product::updateAttribute() StoreCommander and other bulk catalog tools update product combinations through the legacy Product::updateAttribute() API, which fires actionProductAttributeUpdate and NOT actionObjectCombinationUpdateAfter. The module was neither registered on that hook nor had a handler for it, so those combination changes were never committed to Splash. Stock still synced (via actionUpdateQuantity), but attribute / price impact / reference changes on combinations were silently lost. Register actionProductAttributeUpdate and add a handler that rebuilds the Combination from id_product_attribute and forwards it to the existing hookActionCombination commit logic (which already checks the onCombinationLock guard, so no sync loop when Splash itself writes). Co-Authored-By: Claude Opus 4.8 --- modules/splashsync/splashsync.php | 3 +- .../src/Objects/Product/HooksTrait.php | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/modules/splashsync/splashsync.php b/modules/splashsync/splashsync.php index baab7594..c1cf44ab 100644 --- a/modules/splashsync/splashsync.php +++ b/modules/splashsync/splashsync.php @@ -172,7 +172,8 @@ public function install() // Register Module Products Attributes Hooks if (!$this->registerHook('actionObjectCombinationAddAfter') || !$this->registerHook('actionObjectCombinationUpdateAfter') || - !$this->registerHook('actionObjectCombinationDeleteAfter') + !$this->registerHook('actionObjectCombinationDeleteAfter') || + !$this->registerHook('actionProductAttributeUpdate') ) { return false; } diff --git a/modules/splashsync/src/Objects/Product/HooksTrait.php b/modules/splashsync/src/Objects/Product/HooksTrait.php index 5bec535c..bf8bc3a0 100644 --- a/modules/splashsync/src/Objects/Product/HooksTrait.php +++ b/modules/splashsync/src/Objects/Product/HooksTrait.php @@ -152,6 +152,36 @@ public function hookActionObjectCombinationDeleteAfter(array $params): bool ); } + /** + * This hook is called when a Product Combination is updated through the legacy + * Product::updateAttribute() path (used by StoreCommander and other bulk catalog + * tools), which does NOT trigger actionObjectCombinationUpdateAfter. We rebuild + * the Combination object and forward it to the standard combination commit. + * + * @param array $params + * + * @return bool + */ + public function hookActionProductAttributeUpdate(array $params): bool + { + $idProductAttribute = isset($params['id_product_attribute']) + ? (int) $params['id_product_attribute'] + : 0; + if ($idProductAttribute <= 0) { + return true; + } + $combination = new Combination($idProductAttribute); + if (!\Validate::isLoadedObject($combination) || empty($combination->id_product)) { + return true; + } + + return $this->hookactionCombination( + $combination, + SPL_A_UPDATE, + $this->l('Product Variant Updated on Prestashop') + ); + } + /** * This hook is called after a customer effectively places their order *