Skip Navigation

[Resolved] WPML language duplicate not being created correctly 100% of the time

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- 10:00 – 13:00 10:00 – 13:00 10:00 – 13:00 10:00 – 13:00 10:00 – 13:00 -
- 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 -

Supporter timezone: Asia/Kolkata (GMT+05:30)

This topic contains 23 replies, has 2 voices.

Last updated by Minesh 11 months ago.

Assisted by: Minesh.

Author
Posts
#2677025

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

As you can see - the "cred_save_data" hook will be fired only when you will submit the post from frontend and the form data saved to the database using Toolset form:
- https://toolset.com/documentation/programmer-reference/cred-api/#cred_save_data

If you want to run such duplicate action for single post - then you should create a custom shortcode.

For example:

add_shortcode('setup_post_duplicates', 'func_setup_post_duplicates');
function func_setup_post_duplicates($atts) {

$post_id = $atts['post_id'];

if(is_numeric($post_id)) {
               do_action( 'wpml_make_post_duplicates', $post_id) ;
}

}

You can add this custom shortcode to "Custom Code" section and then you can call the above shortcode as:

[setup_post_duplicates post_id="27463"]

Now, you should create a test page and add the above shortcode and load this test page on frontend once so it will duplicate the provided post ID in other languages.

#2677302

Hi Minesh

I replied 2 days ago but it looks like my last reply hasn't been saved on the ticket properly. When I refresh the page I still see your reply as the last one.

I'll try again.

Thanks for that.

1) Is it not possible to simplify this further by simply inserting the offending post ID in the code and running it? Are we forced to create a new page with a shortcut solely for the purpose of triggering the code?

2) Also, it doesn't repair the small number posts on production which are already "broken". How is the link correctly established between original and translation posts, so that it can be guaranteed that changes made to an original language post are correctly propagated to a WPML language duplicate? Is this handled by the postmeta '_icl_lang_duplicate_of' or what does the WPML code look for so it knows which post to copy the original content to??

Thanks and have a nice weekend

Kind regards
Simon

#2677721

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

1) Is it not possible to simplify this further by simply inserting the offending post ID in the code and running it? Are we forced to create a new page with a shortcut solely for the purpose of triggering the code?
==>
Without adding teh shortcode to page/post - how you will run the custom shortcode. You can chose whatever method suits best for you.

2) Also, it doesn't repair the small number posts on production which are already "broken". How is the link correctly established between original and translation posts, so that it can be guaranteed that changes made to an original language post are correctly propagated to a WPML language duplicate? Is this handled by the postmeta '_icl_lang_duplicate_of' or what does the WPML code look for so it knows which post to copy the original content to??
===>
Can you please try to use the following modified code:

add_shortcode('setup_post_duplicates', 'func_setup_post_duplicates');
function func_setup_post_duplicates($atts) {
 global $sitepress;
$post_id = $atts['post_id'];

//getting the post object
$post_obj = get_post($post_id );
 
do_action( 'wpml_make_post_duplicates', $post_id) ;

    $trid = apply_filters( 'wpml_element_trid', NULL, $post_id, 'post_' . $post_obj->post_type );
        $translations = apply_filters( 'wpml_get_element_translations', NULL, $trid, 'post_' . $post_obj->post_type);
        // just the duplicate(s)
        foreach( $translations as $translation ){
            if ( $translation->element_id != $post_id ){
                // unlock synching of duplicate(s)
                delete_post_meta( $translation->element_id, '_icl_lang_duplicate_of' );
            }
        }

}

You can call the shortcode as:

[setup_post_duplicates post_id="27463"]
#2678468
Screenshot 2024-01-15 at 14.05.52.png

Hi Minesh

- I deactivated custom code "func-sync-language-duplicates-on-submission" temporarily.
- I created a new Nanny record from the front end
- New Nanny record in original lanugage English, ID 27592 was created
- Ran the page from the front end "hidden link" with the shortcode [setup_post_duplicates post_id="27592"]
- A German post duplicate was created ID 27597
- I re-activated custom code "func-sync-language-duplicates-on-submission" again and made some changes to the Nanny on the frontend via "hidden link"
- The changes I made were correctly updated in the German duplicate 27597.

1) Can you explain in English the steps of your code from line 11? What is it doing differently exactly from the code in your reply https://toolset.com/forums/topic/wpml-language-duplicate-not-being-created-correctly-100-of-the-time/page/2/#post-2677025

2) What post_meta is getting deleted in line 17?

3) Comparing the results in the database of the two SQLs (see screenshot, as I cannot upload Excel to you I think) I see two significant differences:

EXISTING CASE
select *
from wpdev_postmeta
where post_id in (27085, 27090)

NEW TEST CASE
select *
from wpdev_postmeta
where post_id in (27592, 27597)

In particular:
a) the German Nanny duplicate created using the [setup_post_duplicates post_id="27592"] shortcode is missing the "_icl_lang_duplicate_of" in the postmeta.
b) Both Nannies English 27085 and German 27090 both have "_edit_lock" for some reason. What is this?

Kind regards
Simon

#2678643

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

1) Can you explain in English the steps of your code from line 11? What is it doing differently exactly from the code in your reply https://toolset.com/forums/topic/wpml-language-duplicate-not-being-created-correctly-100-of-the-time/page/2/#post-2677025
===>
We are removing the post meta key "_icl_lang_duplicate_of" from the other language posts(other than original language in which the post is created).

2) What post_meta is getting deleted in line 17?
===>
post meta key "_icl_lang_duplicate_of"

3) Comparing the results in the database of the two SQLs (see screenshot, as I cannot upload Excel to you I think) I see two significant differences:

EXISTING CASE
select *
from wpdev_postmeta
where post_id in (27085, 27090)

NEW TEST CASE
select *
from wpdev_postmeta
where post_id in (27592, 27597)

In particular:
a) the German Nanny duplicate created using the [setup_post_duplicates post_id="27592"] shortcode is missing the "_icl_lang_duplicate_of" in the postmeta.
===>
Yes - because we deleted the post meta key "_icl_lang_duplicate_of"

b) Both Nannies English 27085 and German 27090 both have "_edit_lock" for some reason. What is this?
===>
_edit_lock is not from Toolset but its from WordPress itself. The _edit_lock is generated each time you edit a post or page. it consist the timecode and the user. so WordPress is knowing who is currently editing it.

I urge you to open a new ticket with every new question you may have as this help other users searching on the forum as well as help us to write correct problem resolution summery for original question reported with this ticket.

Thank you for understanding.

#2679461

Hi Minesh

In the original working case I cited: (post ID 27085, duplicate ID 27090), post meta key "_icl_lang_duplicate_of" is present, and that's the way it should be (as it is this way for all cases where the duplication worked successfully the 99.9% of the cases). Therefore I don't think it's correct to delete any post meta key "_icl_lang_duplicate_of" from the language duplicates.

- There can only ever be ONE original post id and ONE duplicate post id in our website.
- There should never be more than one duplicate of any post.
- The original post ID must be paired INDEFINITELY with the duplicate post ID, and this pairing should never change, nor should the IDs of the post duplicates.

Therefore I don't believe it would be incorrect to create and/or delete additional duplicate posts because they potentially have other data related to them (in our case for example posts of type "message").

The language duplicate posts are deliberately given this postmeta to indicate they are indeed language duplicates of original posts. It would therefore also seem incorrect to delete post meta key "_icl_lang_duplicate_of" from duplicate posts.

Thanks and kind regards
Simon

PS I am well aware of the sensible company policy regarding one issue for one ticket and its purpose. I do not need to be reminded of this, thank you! 😉 All my questions so far in this ticket have all been related to progressing the resolution of the original issue.

#2679571

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

What issue do you have now?

I am not getting you, if everything is sorted out, you are welcome to close this ticket.

#2679580

Hi Minesh

I created 2 new Nannies to demonstrate. Please read carefully and let me know if there is anything unclear in my description of the problem. I feel like we are going round in circles unnecessarily.

==========================================
Scenario 1: Everything works as it should, ie original nanny record is correctly synced on creation to create a language duplicate using the code in snippet "func-sync-language-duplicates-on-submission"

Nanny 1 details:

testnanny1_normalsync@example.com

Nanny records
EN 27669 (English original)
DE 27672 (German language duplicate, correctly automatically synced by code specified in "func-sync-language-duplicates-on-submission")

select *
from wpdev_postmeta
where post_id in (27669, 27672)

The German post, ID 27672, gets correct metadata of "_icl_lang_duplicate_of"
==========================================

==========================================
Scenario 2: "Edge case" that we're looking for a solution for in this ticket, ie original nanny record is NOT correctly synced on creation to create a language duplicate using the code in snippet "func-sync-language-duplicates-on-submission", and we have to use the NEW code to create the language duplicate manually

func-sync-language-duplicates-on-submission deactivated for the creation of the original to simulate the case where automatic synchronisation fails

Nanny 2 details:

testnanny2_postsynced@example.com

EN 27676 (English original, not automatically synced, because code func-sync-language-duplicates-on-submission is deactivated)
DE 27681 (created using the shortcode [setup_post_duplicates post_id="27676"] on hidden link)

select *
from wpdev_postmeta
where post_id in (27676, 27681)

The German post, ID 27681, created using the new code, DOES NOT GET correct metadata of "_icl_lang_duplicate_of", as it should!
==========================================

In summary,
- when all works "normally", the language duplicate gets correct metadata of "_icl_lang_duplicate_of".
- when in the odd case that the Nanny is not duplicated automatically and we have to force duplicate the original Nanny using the code provided in this ticket, the language duplicate DOES NOT GET correct metadata of "_icl_lang_duplicate_of".

When we use the manual code to duplicate the Nannies, the duplicate record should have all the postmeta created that happens when a Nanny language duplicate is created correctly automatically.

I hope the issue is clear now. Please let me know if there is anything unclear.

Could you also please refrain from prompting me to close tickets prematurely? The ticket will be marked as solved once I am satisfied that the solution offered works correctly and is tested and suitable to be applied on a production environment.

Thanks and kind regards
Simon

#2679593

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

I think you are missing part here:

See the reply here of point #2:
- https://toolset.com/forums/topic/wpml-language-duplicate-not-being-created-correctly-100-of-the-time/page/2/#post-2677721

Your question was:

2) Also, it doesn't repair the small number posts on production which are already "broken". How is the link correctly established between original and translation posts, so that it can be guaranteed that changes made to an original language post are correctly propagated to a WPML language duplicate? Is this handled by the postmeta '_icl_lang_duplicate_of' or what does the WPML code look for so it knows which post to copy the original content to??

And according to that the solution is shared.

So, from your last reply:

- when in the odd case that the Nanny is not duplicated automatically and we have to force duplicate the original Nanny using the code provided in this ticket, the language duplicate DOES NOT GET correct metadata of "_icl_lang_duplicate_of".

When we use the manual code to duplicate the Nannies, the duplicate record should have all the postmeta created that happens when a Nanny language duplicate is created correctly automatically.
====>
The "_icl_lang_duplicate_of" is intentionally deleted to respect the functionality that:

How is the link correctly established between original and translation posts, so that it can be guaranteed that changes made to an original language post are correctly propagated to a WPML language duplicate?

So when you make change to original language in custom field you will see its automatically reflected to secondary language.

I hope this makes sense, as its required to remove "_icl_lang_duplicate_of" meta key when you have odd case and you want to automatically replicate the changes you made to original language custom field will be reflected in secondary language.

I hope this is clear now.

#2680161

Hi Minesh

This is what I have understood from your explanation. Please read carefully and for each point confirm whether I have understood your explanations correctly.

1) It is expected behaviour that correctly automatically generated language duplicates will always maintain the "_icl_lang_duplicate_of" in the language duplicate but that manually generated language duplicates do not. (This is the main point where I see a logic break and don't fully understand why this should be the case! I would imagine automatically and manually created language duplicates should be indistinguishable.)

2) For the rare failed cases, where manual duplication becomes necessary, the REVISED code from reply

https://toolset.com/forums/topic/wpml-language-duplicate-not-being-created-correctly-100-of-the-time/page/2/#post-2677721

should be used to create the language duplicated MANUALLY.

3) The code provided in

https://toolset.com/forums/topic/wpml-language-duplicate-not-being-created-correctly-100-of-the-time/page/2/#post-2677025

should NOT be used, is superseded by code in 2), and can be ignored, rather always use the code from 2).

4) Language duplicates manually created from code in

https://toolset.com/forums/topic/wpml-language-duplicate-not-being-created-correctly-100-of-the-time/page/2/#post-2677721

have intentionally had "_icl_lang_duplicate_of" removed.

5) Language duplicates manually created from code in

https://toolset.com/forums/topic/wpml-language-duplicate-not-being-created-correctly-100-of-the-time/page/2/#post-2677721

will be updated correctly and automatically if the original changes, as long as code snippet "func-sync-language-duplicates-on-submission" is active.

If all 5 points are TRUE then I think we can close this ticket, however, I would appreciate a logical explanation of why automatically and manually created language duplicates differ in their metadata.

Thanks and kind regards
Simon

#2680370

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

1) It is expected behaviour that correctly automatically generated language duplicates will always maintain the "_icl_lang_duplicate_of" in the language duplicate but that manually generated language duplicates do not. (This is the main point where I see a logic break and don't fully understand why this should be the case! I would imagine automatically and manually created language duplicates should be indistinguishable.)
===>
Yes because duplicates will always maintain the "_icl_lang_duplicate_of" and the manually generated language (the edge case) where you also want to sync the custom field values across the other languages when you modify the custom field value in original language and to sync that modification across the other languages we have to remove the "_icl_lang_duplicate_of".

2) For the rare failed cases, where manual duplication becomes necessary, the REVISED code from reply
- https://toolset.com/forums/topic/wpml-language-duplicate-not-being-created-correctly-100-of-the-time/page/2/#post-2677721
should be used to create the language duplicated MANUALLY.
===>
Yes.

3) The code provided in
- https://toolset.com/forums/topic/wpml-language-duplicate-not-being-created-correctly-100-of-the-time/page/2/#post-2677025
should NOT be used, is superseded by code in 2), and can be ignored, rather always use the code from 2).
===>
Yes.

4) Language duplicates manually created from code in
- https://toolset.com/forums/topic/wpml-language-duplicate-not-being-created-correctly-100-of-the-time/page/2/#post-2677721
have intentionally had "_icl_lang_duplicate_of" removed.
===>
Yes.

5) Language duplicates manually created from code in
- https://toolset.com/forums/topic/wpml-language-duplicate-not-being-created-correctly-100-of-the-time/page/2/#post-2677721
will be updated correctly and automatically if the original changes, as long as code snippet "func-sync-language-duplicates-on-submission" is active.
===>
Yes.

If all 5 points are TRUE then I think we can close this ticket, however, I would appreciate a logical explanation of why automatically and manually created language duplicates differ in their metadata.
===>
Because "_icl_lang_duplicate_of" is the mete key that holds the value of what post ID is duplicate of and if there is no "_icl_lang_duplicate_of" available that means the the post is not duplicate and you can sync the changes done in original language to your addon other languages.