Reading list Switch to dark mode

    Update module multi-lang data using association with PrestaShop native API

    Updated 26 September 2022

    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 :

    Start your headless eCommerce
    now.
    Find out More
    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 :

    screenshot-2022.09.23-21_18_38

    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]

    . . .

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    Be the first to comment.

    Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home