Skip Navigation

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.

Elementor users - please update WPML to the latest version to maintain compatibility. More details here - https://wpml.org/changelog/2024/12/wpml-4-6-15-critical-update-for-elementor-sites/
Sun Mon Tue Wed Thu Fri Sat
- - 9:00 – 18:00 9:00 – 18:00 9:00 – 18:00 9:00 – 18:00 9:00 – 18:00
- - - - - - -

Supporter timezone: America/Lima (GMT-05:00)

Tagged: 

This topic contains 8 replies, has 0 voices.

Last updated by Andreas W. 4 days, 4 hours 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');