In this blog, we are going to learn how to update module multi-lang data or configurations with native PrestaShop Webservices.
In the previous blog, we updated the data that was not related to PrestaShop’s multi-lang concept. The process to enable the web services in Prestashop are same as mentioned in the previous blog.
Suppose, we have a module demomodule that has a multi-lang field in the table and we want to update/get the language-wise data with Prestashop’s post/get API requests. For this, we use the concept of association.
Override $webserviceParameters protected variable of core Prestashop file product.php by module and add association for demomodule in the demomodule/override/product.php like below code :
protected $webserviceParameters = [ 'objectMethods' => [ 'add' => 'addWs', 'update' => 'updateWs', ], 'objectNodeNames' => 'products', 'fields' => [ 'id_manufacturer' => [ 'xlink_resource' => 'manufacturers', ], 'id_supplier' => [ 'xlink_resource' => 'suppliers', ], 'id_category_default' => [ 'xlink_resource' => 'categories', ], 'new' => [], 'cache_default_attribute' => [], 'id_default_image' => [ 'getter' => 'getCoverWs', 'setter' => 'setCoverWs', 'xlink_resource' => [ 'resourceName' => 'images', 'subResourceName' => 'products', ], ], 'id_default_combination' => [ 'getter' => 'getWsDefaultCombination', 'setter' => 'setWsDefaultCombination', 'xlink_resource' => [ 'resourceName' => 'combinations', ], ], 'id_tax_rules_group' => [ 'xlink_resource' => [ 'resourceName' => 'tax_rule_groups', ], ], 'position_in_category' => [ 'getter' => 'getWsPositionInCategory', 'setter' => 'setWsPositionInCategory', ], 'manufacturer_name' => [ 'getter' => 'getWsManufacturerName', 'setter' => false, ], 'quantity' => [ 'getter' => false, 'setter' => false, ], 'type' => [ 'getter' => 'getWsType', 'setter' => 'setWsType', ], ], 'associations' => [ 'categories' => [ 'resource' => 'category', 'fields' => [ 'id' => ['required' => true], ], ], 'images' => [ 'resource' => 'image', 'fields' => ['id' => []], ], 'combinations' => [ 'resource' => 'combination', 'fields' => [ 'id' => ['required' => true], ], ], 'product_option_values' => [ 'resource' => 'product_option_value', 'fields' => [ 'id' => ['required' => true], ], ], 'product_features' => [ 'resource' => 'product_feature', 'fields' => [ 'id' => ['required' => true], 'id_feature_value' => [ 'required' => true, 'xlink_resource' => 'product_feature_values', ], ], ], 'tags' => ['resource' => 'tag', 'fields' => [ 'id' => ['required' => true], ], ], 'stock_availables' => ['resource' => 'stock_available', 'fields' => [ 'id' => ['required' => true], 'id_product_attribute' => ['required' => true], ], 'setter' => false, ], 'attachments' => [ 'resource' => 'attachment', 'api' => 'attachments', 'fields' => [ 'id' => ['required' => true], ], ], 'accessories' => [ 'resource' => 'product', 'api' => 'products', 'fields' => [ 'id' => [ 'required' => true, 'xlink_resource' => 'products', ], ], ], 'product_bundle' => [ 'resource' => 'product', 'api' => 'products', 'fields' => [ 'id' => ['required' => true], 'id_product_attribute' => [], 'quantity' => [], ], ], 'wk_fields' => [ 'resource' => 'wk_field', 'api' => 'products', 'fields' => [ 'fav_country' => ['required' => true, 'i18n' => true], ], 'setter' => 'setFavCountryFieldData', 'getter' => 'getFavCountryFieldData' ], ], ];
With the i18n parameter, it will create a language-wise node of data associated with the product and write the given code in the getter function of demomodule/override/product.php
public function getFavCountryFieldData() { $records = Db::getInstance()->executeS( 'SELECT * FROM `'._DB_PREFIX_.'wk_field` WHERE `id_product` = '.(int)$this->id ); $finalData = []; if (!empty($records)) { foreach ($records as $data) { $fieldData = []; foreach (LanguageCore::getLanguages(true) as $lang) { $langData = Db::getInstance()->getValue( 'SELECT `fav_country` FROM `'._DB_PREFIX_.'wk_field_lang` WHERE `id_wk_field` = '.(int)$data['id_wk_field'] . ' AND `id_lang` = '.(int)$lang['id_lang'] ); $fieldData[$lang['id_lang']] = $langData; } $finalData[]['fav_country'] = $fieldData; } } return $finalData; }
The output will be like this on API call :
To update data, we need to override /classes/webservice/WebserviceRequest.php class function saveEntityFromXml like the below code
if (isset($attributes->associations)) { foreach ($attributes->associations->children() as $association) { if (isset($this->resourceConfiguration['associations'][$association->getName()])) { $assocItems = $association->children(); $values = []; foreach ($assocItems as $assocItem) { $fields = $assocItem->children(); $entry = []; foreach ($fields as $fieldName => $fieldValue) { if ($fieldName == 'fav_country') { foreach ($fieldValue as $v) { $entry[$fieldName][(int) $v['id']] = (string)$v[0]; } } else { $entry[$fieldName] = (string) $fieldValue; } } $values[] = $entry; } $setter = $this->resourceConfiguration['associations'][$association->getName()]['setter']; if (null !== $setter && $setter && method_exists($object, $setter) && !$object->$setter($values)) { $this->setError(500, 'Error occurred while setting the ' . $association->getName() . ' value', 85); return false; } } elseif ($association->getName() != 'i18n') { $this->setError(400, 'The association "' . $association->getName() . '" does not exists', 86); return false; } } }
In the above code, we have added the fav_country country condition to pass the language-wise data array to the setter function
Now, define the setter function in the demomodule/override/product.php file like this
public function setFavCountryFieldData($postData) { /* Do update activity You will get language wise data array on API call like 'fav_country' = array( 1 => 'Test EN' 2 => 'Test FR' 3 => 'Test DE' ) */ return true; }
Note: After the above process disable and enable the installed module (demomodule).
That’s all about this blog.
If any issue or doubt please feel free to mention it in the comment section.
I would be happy to help.
Also, you can explore our PrestaShop Development Services & a large range of quality PrestaShop Modules.
For any doubt contact us at [email protected]
Be the first to comment.