Skip Navigation

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

Problem:
If you're experiencing issues where changing a product's status to 'draft' in the default language (Italian) does not automatically sync the status to additional languages (English/Chinese) on your multilingual site, we have a solution for you.
Solution:
We recommend adding a custom code snippet to your theme's functions.php file to synchronize the publish status across all languages. Here's how you can do it:

function sync_publish_status_across_languages($post_id) {
    // Check if this is a valid post type (product) and that the post is not being autosaved
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
    if ('product' != get_post_type($post_id)) return;  // Check for WooCommerce product post type
  
    // Get the current post status
    $post_status = get_post_status($post_id);
  
    // Get the default language
    $default_language = apply_filters('wpml_default_language', null);
  
    // Get all translations of the post in different languages
    $translations = apply_filters('wpml_get_element_translations', null, $post_id, 'product');  // Updated for products
  
    foreach ($translations as $lang => $translation) {
        // Skip the default language post (we don't want to update it)
        if ($lang === $default_language) continue;
  
        // Get the translation post ID
        $translation_post_id = $translation->element_id;
  
        // Update the publish status of the translated post
        wp_update_post(array(
            'ID' => $translation_post_id,
            'post_status' => $post_status
        ));
    }
}
  
add_action('save_post', 'sync_publish_status_across_languages');

Please note that this solution might be outdated or not applicable to your specific case. If this does not resolve your issue, 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 you still need assistance, 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 8 replies, has 0 voices.

Last updated by Andreas W. 1 week ago.

Assisted by: Andreas W..

Author Posts
December 24, 2024 at 2:32 pm #16544039

ruikaiW

Background of the issue:
I have 3 languages on my site, with Italian as the default and English/Chinese as additional languages. When I change a product's status from 'published' to 'draft' in Italian, the Italian product disappears, but the English and Chinese versions remain published. I want to automate the status change for all languages.

Symptoms:
When changing a product's status to 'draft' in the default language (Italian), the status does not automatically sync to additional languages (English/Chinese).

Questions:
Is there a way to automatically sync the publish status across all languages when changing it in the default language?

December 24, 2024 at 3:40 pm #16544225

Andreas W.
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

Hello,

WPML does handle the status of each content in each language independently.

You could try using a code snippet, like the following example. If you save this snippets inside the function.php file of your theme and then save a original post, page or product, it should sync the status into all active languages.

function sync_publish_status_across_languages($post_id) {
    // Check if this is a valid post type and that the post is not being autosaved
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
    if ('post' != get_post_type($post_id)) return;

    // Get the current post status
    $post_status = get_post_status($post_id);

    // Get the default language
    $default_language = apply_filters( 'wpml_default_language', null );

    // Get all translations of the post in different languages
    $translations = apply_filters( 'wpml_get_element_translations', null, $post_id, 'post' );

    foreach ($translations as $lang => $translation) {
        // Skip the default language post (we don't want to update it)
        if ($lang === $default_language) continue;

        // Get the translation post ID
        $translation_post_id = $translation->element_id;

        // Update the publish status of the translated post
        wp_update_post(array(
            'ID' => $translation_post_id,
            'post_status' => $post_status
        ));
    }
}

add_action('save_post', 'sync_publish_status_across_languages');

Best regards
Andreas

December 28, 2024 at 8:43 pm #16550503

ruikaiW

it seems didn't work

$translations = apply_filters( 'wpml_get_element_translations', null, $post_id, 'post' );

when I log this out , $translations is empty , just looks like it's not getting the translated IDs

I also tried with a simple code

```
<?php

require('./wp-load.php');

$translations = apply_filters( 'wpml_get_element_translations', NULL, 78271, 'post' );
var_dump($translations);

```

also end up in empty result

from admin bar , I can see post ID as

```
wp-admin/post.php?post=78271&action=edit&lang=it
wp-admin/post.php?post=78273&action=edit&message=1&lang=en&admin_bar=1
wp-admin/post.php?post=78272&action=edit&message=1&lang=zh-hans&admin_bar=1
```

December 28, 2024 at 8:48 pm #16550507

ruikaiW

according to this

https://wpml.org/wpml-hook/wpml_get_element_translations/

I also tried

$translations = apply_filters( 'wpml_get_element_translations', null, $post_id, 'post_product' );
error_log(print_r($translations,true));

still empty result

December 29, 2024 at 2:09 am #16550614

Andreas W.
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

Thank you for your message. I actually did not test this snippet yet.

Usually the $translations variable only would be expected to be empty if no translations do exists yet for the post that you are saving.

I will run some tests for this snippets on Tuesday and then get back to you.

December 29, 2024 at 2:10 am #16550615

ruikaiW

thanks, pleaase keep me posted

for the record, the translations do exist on my test

I can see it from admin bar -> wpml language flag , that gives me links as

```
wp-admin/post.php?post=78271&action=edit&lang=it
wp-admin/post.php?post=78273&action=edit&message=1&lang=en&admin_bar=1
wp-admin/post.php?post=78272&action=edit&message=1&lang=zh-hans&admin_bar=1
```

December 31, 2024 at 3:12 pm #16556085

Andreas W.
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

I added the snippet to the following test site and it works as expected here for posts and pages.

One-Click-Login:
hidden link

Please take a look into it. If you get a different behavior on your site I can offer to take a look into it.

December 31, 2024 at 3:14 pm #16556086

ruikaiW

thanks, I workaround'ed it by search SKU through dtabase , since all 3 languages's product shows same SKU but with different post id , so I extract the post ID by returning SKU-matched query , then manually update the postmeta one by one

bit of weird , but at least it works

December 31, 2024 at 3:31 pm #16556115

Andreas W.
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

The code I earlier provided to you would only work for WordPress Posts or Pages.

If you are working with WooCommerce Products you will need to adapt the code:

function sync_publish_status_across_languages($post_id) {
    // Check if this is a valid post type (product) and that the post is not being autosaved
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
    if ('product' != get_post_type($post_id)) return;  // Check for WooCommerce product post type
 
    // Get the current post status
    $post_status = get_post_status($post_id);
 
    // Get the default language
    $default_language = apply_filters('wpml_default_language', null);
 
    // Get all translations of the post in different languages
    $translations = apply_filters('wpml_get_element_translations', null, $post_id, 'product');  // Updated for products
 
    foreach ($translations as $lang => $translation) {
        // Skip the default language post (we don't want to update it)
        if ($lang === $default_language) continue;
 
        // Get the translation post ID
        $translation_post_id = $translation->element_id;
 
        // Update the publish status of the translated post
        wp_update_post(array(
            'ID' => $translation_post_id,
            'post_status' => $post_status
        ));
    }
}
 
add_action('save_post', 'sync_publish_status_across_languages');