wapmakerw Posted April 26, 2021 Share Posted April 26, 2021 (edited) Hello everyone, This is my first forum post here. I have a multi-shop Prestashop (1.7.5.2) site with two subdomains (shop1 & shop2). The problem I am facing: On shop1, when I go to Back-Office -> Catalogue -> Products -> Product choose -> Options tab -> Customization Head and enter the some Customization text as a Text Field for one shop (check screenshot attached). On saving, it gets saved but the Text Field disappears from the shop2. The same behavior occurs when I save the Text Field from the shop2. I cannot simultaneously have the Customization text fields on both shops. (The same issue occurs on Prestashop version 1.7.7 also) I looked into the code and found that in `src/Adapter/Product/AdminProductWrapper.php` the following function calls delete all other text fields than the ones currently entered. $product->softDeleteCustomizationFields($customization_ids); // and Customization::deleteCustomizationFieldLangByShop($customizationFiled['id_customization_field'], $shopList); I could not find how to fix it though. Can anyone please help me with this asap? I'll be highly grateful. Edited April 27, 2021 by wapmakerw Added more information (see edit history) Link to comment Share on other sites More sharing options...
wapmakerw Posted April 27, 2021 Author Share Posted April 27, 2021 (edited) Finally, it seems to be a bug in Prestashop core. Customization fields don't seem to be configured correctly for multi-shop Prestashop. For anyone facing the same issue, you can fix this bug by patching the core Prestashop files: src/Adapter/Product/AdminProductWrapper.php // make function changes public function processProductCustomization($product, $data) { $customization_ids = []; if ($data) { foreach ($data as $customization) { $customization_ids[] = (int) $customization['id_customization_field']; } } $shopList = Shop::getContextListShopID(); $usedCustomizationIds = $product->getUsedCustomizationFieldsIds(); $usedCustomizationIds = array_column($usedCustomizationIds, 'index'); $usedCustomizationIds = array_map('intval', $usedCustomizationIds); $usedCustomizationIds = array_unique(array_merge($usedCustomizationIds, $customization_ids), SORT_REGULAR); /* Update the customization fields to be deleted in the next step if not used */ $product->softDeleteCustomizationFieldsByShop($usedCustomizationIds, $shopList); // only from current shop //remove customization field langs for current context shops $productCustomization = $product->getCustomizationFieldIdsByShop($shopList); // for current shop only $toDeleteCustomizationIds = []; if($productCustomization){ foreach ($productCustomization as $customizationFiled) { if (!in_array((int) $customizationFiled['id_customization_field'], $usedCustomizationIds)) { $toDeleteCustomizationIds[] = (int) $customizationFiled['id_customization_field']; } //if the customization_field is still in use, only delete the current context shops langs, if (in_array((int) $customizationFiled['id_customization_field'], $customization_ids)) { Customization::deleteCustomizationFieldLangByShop($customizationFiled['id_customization_field'], $shopList); } } } //remove unused customization for the product $product->deleteUnusedCustomizationFields($toDeleteCustomizationIds); Finally add the following functions to: classes/Product.php public function getCustomizationFieldIdsByShop(array $shopIds) { if(count($shopIds) == 0) return []; if (!Customization::isFeatureActive()) { return []; } return Db::getInstance()->executeS(' SELECT cf.`id_customization_field`, cf.`type`, cf.`required` FROM `' . _DB_PREFIX_ . 'customization_field` cf LEFT JOIN `' . _DB_PREFIX_ . 'customization_field_lang` cfl ON cf.`id_customization_field`=cfl.`id_customization_field` WHERE cf.`id_product` = ' . (int) $this->id.' AND cfl.`id_shop` in ('.implode(", ", array_map('intval', $shopIds)).') GROUP BY cf.`id_customization_field`'); } /** * Update the customization fields to be deleted if not used. * * @param array $customizationIds - Array of excluded customization fields IDs * * @param array $shopList - Array of shop ids * * @return bool * * @throws PrestaShopDatabaseException */ public function softDeleteCustomizationFieldsByShop($customizationIds, $shopList) { $return = true; $updateQuery = 'UPDATE `' . _DB_PREFIX_ . 'customization_field` cf SET cf.`is_deleted` = 1 WHERE cf.`id_product` = ' . (int) $this->id . ' AND cf.`is_deleted` = 0 '; if (is_array($customizationIds) && !empty($customizationIds)) { $updateQuery .= 'AND cf.`id_customization_field` NOT IN (' . implode(',', array_map('intval', $customizationIds)) . ')'; } if (is_array($shopList) && !empty($shopList)) { $updateQuery .= ' AND (SELECT cfl.`id_shop` from `' . _DB_PREFIX_ . 'customization_field_lang` cfl where `id_customization_field` = cf.`id_customization_field` LIMIT 1) IN (' . implode(',', array_map('intval', $shopList)) . ')'; } $return &= Db::getInstance()->execute($updateQuery); if (!$return) { throw new PrestaShopDatabaseException('An error occurred while soft deletion the customization fields'); } return $return; } Edited April 27, 2021 by wapmakerw (see edit history) Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now