Skip Navigation

This thread is resolved. Here is a description of the problem and solution.

Problem:
The client is using a custom script to update stock and prices of products via the WooCommerce API. This script updates only the main language, and while the stock and prices reflect correctly across all languages, the translations for product names and descriptions are reset to match the main language.
Solution:
1. We recommend checking if the 'save_post' hook is being executed after updates. This hook helps ensure that changes are properly synchronized across translations.
2. Verify if the WPML translation editor is disabled for the products. If it's not, any save in the default language might reset manually added translations. For more details on using different translation editors, visit Using Different Translation Editors for Different Pages.
3. If products were duplicated using WPML's 'Translation Management', check the post meta table for 'icl_duplicate_of' and delete if any entries are found. This can prevent content from syncing/duplicating incorrectly on save.

If these steps do not resolve the issue or if the solution seems outdated or irrelevant to your case, we highly recommend checking related known issues at https://wpml.org/known-issues/, verifying the version of the permanent fix, and confirming that you have installed the latest versions of themes and plugins. If the problem persists, please open a new support ticket at WPML support forum.

This is the technical support forum for WPML - the multilingual WordPress plugin.

Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.

Tagged: 

This topic contains 3 replies, has 1 voice.

Last updated by aleksandrsC 1 day, 20 hours ago.

Assisted by: Dražen.

Author Posts
January 17, 2025 at 4:57 pm #16607607

aleksandrsC

Background of the issue:
I wrote a script to update the stock and prices of products using the WooCommerce API. The script modifies only the main language via requests by product ID, expecting the other languages to synchronize automatically for stock and price. When I perform the same process manually through the admin panel, everything works as expected, and the translations are not reset. Link to a page where the issue can be seen:


from googleapiclient.discovery import build
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime  # Для работы со временем
 
# Настройки Google Sheets API
SPREADSHEET_ID = '-------------------'  # ID вашей таблицы
SHEET_NAME = 'Hook'  # Имя листа в таблице
 
# Настройки WooCommerce API
WC_API_URL = '<em><u>hidden link</u></em>'
CONSUMER_KEY = '--------'
CONSUMER_SECRET = '--------------'
 
# Фиксация времени начала
start_time = datetime.now()
print(f"Время начала: {start_time.strftime('%Y-%m-%d %H:%M:%S')}")
 
# Подключение к Google Sheets
service = build('sheets', 'v4', developerKey='--------------------')
sheet = service.spreadsheets()
 
# Считывание данных
range_name = f'{SHEET_NAME}!A:E'  # Диапазон данных (например, A и E колонки)
result = sheet.values().get(spreadsheetId=SPREADSHEET_ID, range=range_name).execute()
rows = result.get('values', [])
 
# Проверка: есть ли данные
if not rows:
    print("Нет данных для обработки.")
    exit()
 
# Формируем список продуктов для обновления
products_to_update = []
 
print("Данные из таблицы Google Sheets:")
for row in rows:
    if len(row) >= 5:  # Убедимся, что нужные колонки существуют
        product_id = row[1]  # ID продукта
        in_stock = row[3]  # Статус наличия
        price = row[4]  # Цена
 
        stock_status = "instock" if in_stock == '1' else "outofstock"
         
        # Добавляем продукт в список для batch-обновления
        products_to_update.append({
            "id": int(product_id),
            "stock_status": stock_status,
            "regular_price": price
        })
        print(f"ID продукта: {product_id}, В наличии: {stock_status}, Цена: {price}")
 
# Если нечего обновлять, завершаем выполнение
if not products_to_update:
    print("Нет товаров для обновления.")
    exit()
 
# Максимальное количество товаров в одном запросе
BATCH_SIZE = 50
MAX_WORKERS = 3  # Количество потоков для асинхронной обработки
 
# Функция для отправки batch-запроса
def send_batch_update(batch, start_index):
    payload = {"update": batch}
    try:
        response = requests.post(WC_API_URL, auth=(CONSUMER_KEY, CONSUMER_SECRET), json=payload)
        if response.status_code == 200:
            print(f"Успешно обновлены товары (с {start_index + 1} по {start_index + len(batch)}):")
            for updated_product in response.json().get("update", []):
                print(f"- Product ID {updated_product['id']}: {updated_product['stock_status']}, Цена: {updated_product.get('regular_price', 'N/A')}")
        else:
            print(f"Ошибка при обновлении батча с {start_index + 1} по {start_index + len(batch)}: {response.text}")
    except Exception as e:
        print(f"Ошибка в запросе с {start_index + 1} по {start_index + len(batch)}: {e}")
 
# Функция разделения на батчи и асинхронной отправки
def update_products_bulk_async(products):
    with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
        futures = []
        for i in range(0, len(products), BATCH_SIZE):
            batch = products[i:i + BATCH_SIZE]
            futures.append(executor.submit(send_batch_update, batch, i))
         
        # Обработка завершенных задач
        for future in as_completed(futures):
            try:
                future.result()  # Проверяем результат выполнения
            except Exception as e:
                print(f"Ошибка выполнения задачи: {e}")
 
# Основной код
print("Начало массового обновления товаров...")
try:
    update_products_bulk_async(products_to_update)
except Exception as e:
    print(f"Ошибка при выполнении batch-обновления: {e}")
print("Обновление завершено.")
 
# Фиксация времени окончания
end_time = datetime.now()
print(f"Время окончания: {end_time.strftime('%Y-%m-%d %H:%M:%S')}")
 
# Вывод длительности выполнения
duration = end_time - start_time
print(f"Общее время выполнения: {duration}")
print("Обновление завершено.")

Symptoms:
After each use of the script, the translations for all the products involved in the process are reset and end up matching the main language.

Questions:
Why do translations reset after using the script?
How can I prevent translations from being overwritten?

January 21, 2025 at 9:33 am #16617297

Alejandro
Supporter

Languages: English (English ) Spanish (Español ) Italian (Italiano )

Timezone: Europe/Rome (GMT+01:00)

Hello,

I'll help you get started while a supporter takes your case.

1) Please know that we do not support custom coding so we can't really help much here. However, when you do things manually and save a post, you're actually executing a series of hooks that are not being executed here. try to find and use the "save_post" hook and see if by calling it after you finish making changes to it, the content gets updated.

2) Did this code ever work before? if so do you know when did it stop working?

Regards,

January 21, 2025 at 11:11 pm #16620705

aleksandrsC

Hello,

I understand that custom coding is not supported, but anyway maybe I can receive some suggestions.
The script perfectly does its job. It sends only id, stock_status, and regular_price fields to the API to ensure minimal changes.
While the updates for stock and prices are correctly reflected on all languages, the translations (such as product names and descriptions) for the affected products are reset to match the main language.

Here are my questions:

Why does updating products via WooCommerce REST API reset translations?
How can I prevent translations from being overwritten when updating stock and prices through the API?

Thank you,
Aleksandrs.

January 22, 2025 at 7:11 am #16621247

Dražen
Supporter

Languages: English (English )

Timezone: Europe/Zagreb (GMT+01:00)

Hello Aleksandrs,

update of stock and price should not reset translations, but could be that you added this translation manually but have not disabled WPML editor. Then any save in default language will reset manual added translations. Can you please check?

- https://wpml.org/documentation/translating-your-contents/using-different-translation-editors-for-different-pages/

Regards,
Drazen

step-1-arrow-wp-editor-1.jpg
January 22, 2025 at 10:27 am #16622172

aleksandrsC

Hello Drazen,

Thanks for your reply. Actually I'm using same design for every language.

When I add new products to the website, I duplicate every product to all languages via WPML "Translation Management" tab to get new ID for every language. After that I update every new duplicated product by ID via WordPress product import CSV (every language separately).

Should I disable WPML editor in this case?
And there is a option how to disable WPML editor for all products at once?

Best regards,
Aleksandrs.

January 22, 2025 at 12:12 pm #16622729

Dražen
Supporter

Languages: English (English )

Timezone: Europe/Zagreb (GMT+01:00)

Hello Aleksandrs,

since you duplicated them, maybe they are still left as duplicates so it sync /duplicates content on save., I would advise checking post meta table for icl_duplicate_of and delete if any.

If not, when you switch to WP editor there will be a popup asking you if you wish to switch for that post, all posts or website.

Regards,
Drazen

January 29, 2025 at 11:38 am #16645968

aleksandrsC

Hello Drazen,

Thanks for your advice. I didn't found any icl_duplicate_of entries in database.

Could you please clarify the steps with Editor? Which popup I'm searching for?
Should I change anything in translation editor settings? (screenshot attached).

Best regards,
Aleksandrs.

Untitled.png
January 29, 2025 at 12:10 pm #16646200

Dražen
Supporter

Languages: English (English )

Timezone: Europe/Zagreb (GMT+01:00)

Hello Aleksandrs,

I am talking about the WordPress editor switch from edit page screen, as shown in the docs I shared:

- https://wpml.org/documentation/translating-your-contents/using-different-translation-editors-for-different-pages/

Also, I would advise checking if the same issue happens when you manually update data in the default language, just to exclude if the issue is related to WPML or maybe your code/script.

Thanks,
Drazen

January 29, 2025 at 11:27 pm #16648913

aleksandrsC

Hello Drazen,

First of all, using your advice, I decided to check what happens if manually update product in the main product language. The translations were reset, so the problem is not in the custom script.

After that I switched WPML translation editor to WordPress editor according to your advice, and still it did not help, after making changes to the main language - all translations are reset.

Actually I mentioned that one of the translation languages is "Ņot updated" for some quantity of products and this is the only language which doesn't reset after making changes in main product language (screenshot attached).

Best regards,
Aleksandrs.

Untitled.png
January 30, 2025 at 7:15 am #16649580

Dražen
Supporter

Languages: English (English )

Timezone: Europe/Zagreb (GMT+01:00)

Hello Aleksandrs,

as I have said this is expected if you have the switch set to WPML editor but add translations manually.

You need to make sure you have pthe encil icon showing for all languages, that means translations are completed, make sure to click on the arrows icon and finish the translation jobs. Then switch for that page to the WordPress editor, make changes and edit 2nd language and add and edit it how you wish, and it should work fine then, and kept saved / not overwritten for any further update.

Since any content added manually while the WPML editor is active / translation in progress will be lost when you re-save the default language. Since WPML is syncing content as it is expecting that you are using WPML editor and translating like that.

Regards,
Drazen

January 30, 2025 at 12:53 pm #16651588

aleksandrsC

Hello Drazen,

Tried the following, but that didn't help. Maybe I did some mistake or forgot something important.

Completed steps:
1) Choose product with all translations completed (with the pencil icon).
2) Changed for this product WPML Translation Editor to WordPress Editor.
3) Updated/saved main language product inventory status manually. --> Lead to translations reset.
4) Restored translation via WordPress bulk import CSV file (by ID).
5) Updated/saved main language product inventory status manually. --> Lead to translations reset again.

Any suggestions what else can I try?

Best regards,
Aleksandrs.

January 30, 2025 at 1:19 pm #16651794

Dražen
Supporter

Languages: English (English )

Timezone: Europe/Zagreb (GMT+01:00)

Hello,

let me have a look so I can better understand the issue.

Please make sure to disable all non-related plugins and if possible use WP default theme, to avoid any conflicts. The best would be to provide a staging site so I can safely check.

Please share product I can use to test.

Thanks,
Drazen

January 31, 2025 at 7:50 am #16654138

Dražen
Supporter

Languages: English (English )

Timezone: Europe/Zagreb (GMT+01:00)

Hello,

thanks, I have tried to disable all other plugins and switch the theme to default WP, but I get a critical error.

Please check and make sure I can do test it in a minimal configuration.

Thanks for the CSV, but I will not be needing it, I will just test saving the product and overwrite of data. If there isa specific product please share the URL with me.

Thanks,
Drazen

January 31, 2025 at 9:55 am #16654878

aleksandrsC

Hello,

This staging site is dead. Can you make another private message for me, so I can provide access to a new staging site?

Best regards,
Aleksandrs.

January 31, 2025 at 10:17 am #16654927

Dražen
Supporter

Languages: English (English )

Timezone: Europe/Zagreb (GMT+01:00)

Hello,

sure.

I have enabled private reply.

Regards,
Drazen