qTranslate-Team/qtranslate-x

new tag created with wrong slug

picasso opened this issue · 83 comments

The problem is the following:

I have tags which are linked to post with custom type (in my case 'movie').

For example tag with Name

[:en]Barolo[:ru]Бароло[:]

and with Slug in English

barolo

When I change something in my post with this tag (the content for example) and then update it

  • if my WordPress Admin interface is English everything is OK.
  • if my WordPress Admin interface is Russian then a new tag created with the same Name ([:en]Barolo[:ru]Бароло[:]) but with Slug in Russian (Бароло). Old tag with English slug (barolo) is unlinked from the post and the new tag with Russian slug is linked.

Could you check it? It's very annoying to re-check all tags and delete/relink them...

Do you use QTranslate-Slug?

No... It's another plugin? I use qtranslate-x only

Than that plugin is not compatible with q-translate-x
also q-translate slug is somewhat 80% compatible tags work but it does
break the site.

On Thu, Apr 28, 2016 at 3:17 PM, Dmitry notifications@github.com wrote:

No... It's another plugin? I use qtranslate-x only


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#366 (comment)

I do not use QTranslate-Slug

Is this only happening for custom types? Which plugin do you use to manage custom types?

I have not tried this with a regular post... I will try it today.
I use Types plugin to manage custom types.

Hi Dmitry, could you test if your problem solved here: https://github.com/qTranslate-Team/qtranslate-x/archive/stable.zip ?

Hi John, I've tried it with a regular post - the same result, a new tag created with a wrong slug.
The link you provided - is it 3.4.6.7?
I have qtranslate-x 3.4.6.7 installed on my site and I tested a regular post on this version... that means the problem not solved yet...

Link I gave you is the latest updated https://github.com/qTranslate-Team/qtranslate-x/blob/stable/qtranslate.php#L6

You probably looked in readme https://github.com/qTranslate-Team/qtranslate-x/blob/stable/readme.txt#L7, which I have not finalized yet.

The changes made which should target your problem is ad28ac4

;-)

Ok, I've tried this 3.4.6.8
But the problem is still here... :(

Are you sure? Did you do deactivation/activation? I cannot reproduce it anymore. You may need some clean up on older tags. Did you try a brand new tag and post?

Hi Dmitry, would you have time to test it deeper soon enough? I want to release 3.4.6.8, but I wish to make sure that you are ok first. I cannot reproduce the problem anymore by the steps you listed. Am I doing something else than you do? Could you think of a better way for me to reproduce if the problem is indeed still there? Thanks a lot.

Hi John,

sorry, I was away from my computer for 2 days...
Ok, I tested it again.

What I found out:

  • if I use a brand new tag (one I created after install of 3.4.6.8) the problem is solved.
  • if I add to a brand new post an old tag (one of I created before 3.4.6.8) - the problem is still here.

I'm glad that with new tags it works, but what should I do with my old tags?
I have 540 tags and all of them are linked many times to different posts... I cannot recreate them and relink again... Maybe you could write some kind of script which I could use to "heal" my old tags?

Wow, sorry about this. I guess, the easy way would be to fix it in db. I assume you know how to edit database, right? Fix table wp_terms first. Edit names and slugs as you wish them to be. Names should be in the default language without any "[]", same way as they would be without qtx. Then copy content of option 'qtranslate_term_name' into a text file to be able to edit it. It is a hash with keys to be the term name and value is a hash of "xx" => "name translation". Make sure the keys are the same as names in wp_terms table. I assume you know how to edit hashes in db? The tricky part is to adjust the length if you change some string.

If you think it is too complex, send me .sql file with wp_terms and value of option 'qtranslate_term_name' via qtranslateteam at gm ail d c om. I will try to fix id and may come up with some cleaning script, as I assume some other people would have this problem too. Interesting that you are the only one so far to notice this trouble. I guess, people do not use tags much, or do not translate them.

Hi John, I've sent you a mail with .sql files.

Hi, Dmitry, we are working on an option to clean up term translations, as it seems to be a problem inherited from old qt-. Now WordPress did so many changes, that old way, qt- was dealing with term translations, is totally obsolete now and needs to be re-designed anyway.

Does this issue hold you from going ahead with your development? Your db file shows just a few broken tags, which you may edit manually in a normal way at /wp-admin/term.php page and it should correct the problem from now on. Is that right?

Hi John,

no, this issue does not hold me. I just found out that I need regularly check the terms after my editors made some changes in the posts. I takes 5-10 minutes to clean up after them.

But certainly I prefer to resolve this problem in the future and forget about it.
What do you mean under "you may edit manually in a normal way at /wp-admin/term.php page and it should correct the problem from now on"?

Could you give me some clues how manually correct my old tags? Just "Edit Tag" and then press "Update"?

Yes, I think just making sure that all the values, including slug, are correct at term.php and pressing "Update" should fix database entry. All ids and relationship with posts are staying the same this way, only tags names and slug get adjusted in a correct way. I did not try though. What does that do for you? You should use LSB mode at term.php. Raw Editor Mode is discovered broken at term.php and we are working on fixing it too.

Hi Dmitry, could you please test https://github.com/qTranslate-Team/qtranslate-x/archive/stable.zip as much as you can? This should be a fix for your issue, as well as editing of tags in Raw Editor Mode, etc. It should even allow you now to add a new tag on /wp-admin/post.php?post=xx&action=edit using Raw ML format. Naturally, you cannot control slug auto-generated in this case and you may need to adjust it later on /wp-admin/term.php

Apply database operation "Clean Legacy Term Names" from page /wp-admin/options-general.php?page=qtranslate-x#import (keep backup before, of course).

Please, try really hard to break it for a few days and let me know if you find problems. Thank you very much.

Hi John,
I was away from computer...
I will try this pre-release really hard :)

Any news?

I hope you are ok, Dmitry, are you? Have you gotten a chance to test at least a little bit?

Sorry. I'm ok now...

I've tried operation "Clean Legacy Term Names" and after that I get the following log:

Error: Term "layout" (id=509) cannot be loaded. Error message:
"Invalid taxonomy"
This term has been removed.

Legacy term names have been cleaned up:
Term "Бургундия" (id=6) has been modified from:
"Burgundy" => { en => "Burgundy", ru => "Бургундия" }
to:
"Бургундия" => { en => "Burgundy", ru => "Бургундия" }
Term "Кло де Реа" (id=9) has been modified from:
"Clos de Reas" => { en => "Clos de Reas", ru => "Кло де Реа" }
to:
"Кло де Реа" => { en => "Clos de Reas", ru => "Кло де Реа" }
Term "Анна-Франсуаза Гро" (id=11) has been modified from:
"Anne-Francoise Gros" => { en => "Anne-Francoise Gros", ru => "Анна-Франсуаза Гро" }
to:
"Анна-Франсуаза Гро" => { en => "Anne-Francoise Gros", ru => "Анна-Франсуаза Гро" }
Term "Жан Гро" (id=12) has been modified from:
"Jean Gros" => { en => "Jean Gros", ru => "Жан Гро" }
to:
"Жан Гро" => { en => "Jean Gros", ru => "Жан Гро" }

.....and so on...

It's strange how it was modified (or maybe it's only wrong way to write in the log)...
but the problem is that after this operation all my tags are in Russian. The slug is english but the name is Russian and it does not change if I switch the language. Either in admin or in front.

So I restored the database from backup.

But then I found out that tag names do not change when I switch the language even after restore the database.
I returned to version 3.4.6.8
Now tag name is changed after the switch.
Something is wrong with the new release...

Yeah, the "Clean Legacy Term Names" did not seem to work ... I did not have a way to really test it.
What is your default language, en or ru? Also, what is your first language in the list in the configuration?

Did you try to do anything else besides "Clean Legacy Term Names" before you gave up?

That operation was not the main point of the update at all, but it is for you ... I am sorry. Anyway we'll take a look why it did not work.

Thanks a lot for the testing!

My default language is English. My first language in the list is also English.
No, I have not tried anything else. As I remember the previous release solved the problem with a new created tag. And only problem I have now - my legacy term names.
I could test tomorrow but what concrete I should test if not "Clean legacy term names"?

Hi Dmitry, we cannot find what is wrong. The only explanation would be that you call some filters in your other code which we remove during the run of "Clean Legacy Term Names".

Unfortunately, we do not have a good testing case and you will probably be the only user of this code in the nearest future. This makes it hard for us to test and puts a pressure on you ;) Please help us to resolve this.

We altered the code a bit to allow filters, but still not sure if that was a real cause. In order to save your time on db recovery in case it is still not working right, please, after you dowload the latest stable branch, https://github.com/qTranslate-Team/qtranslate-x/archive/stable.zip, comment/uncomment the following lines of code in "qtranslate-x/admin/qtx_admin_utils_db.php" before running operation "Clean Legacy Term Names".

Comment lines:

L502: wp_update_term( $id, $taxonomy, array('name' => $nm) );
L530: update_option('qtranslate_term_name', $term_name);

which will prevent saving the result of the operation into the database. The report will still be generated.

Make sure to enable WP_DEBUG - change or add line as "define('WP_DEBUG', true);" in /wp-config.php. Then uncomment lines with calls to qtranxf_dbg_log: 434, 501, 528 and 529.

This will record additional debugging information in file /wp-content/debug-qtranslate.log. Then you can re-run this operation again and again without altering the database, until you get report and additional debugging information correctly.

Only the default language of all the terms have to be saved in db field wp_terms:name. Option "qtranslate_term_name" should have mapping like this:

"Burgundy" => { en => "Burgundy", ru => "Бургундия" }

where "Burgundy" is the term name in the default language.

Please, if the things go wrong again, troubleshoot it and let us know what needs to be fixed. I think that with that additional debugging output, the troubleshooting should not be difficult, I am sure you can do it quickly enough.

If all goes well, then continue testing all operations you normally do with terms like creation from different pages, alternation of them and so on. The whole term framework was changed comparing to the version you currently use. That is why the testing of all the operations is important - that is what I meant to test when I asked if you tested all the rest ;)

Thank you very much for your help. I hope it will take a bit quicker than a few weeks for you this time ;)

We would like to release the new version in a few days. I think you are the best case to test it all and I would not release it until you say that all is ok for you. A few other testers already reported "no problem". Please, I hope you can help us.

Thanks a lot.

Any news?

Dmitry, how is it going?

Hi John,
sorry, I was away from my computer...
I will try to test it this evening...

Hi John,

I tried to find the problem...

  1. Sorry, I was wrong - my default language is Russian.
    Therefore, the procedure "Clean Legacy Term Names" works most likely correct.
    I cannot confirm it now because I cannot see the results in front-end (see #2)
    What I was confused - was the change log. I propose to add the slug in the description because the slug was my problem first and I was worried about what it would be after the changes.
    With something like this:
    Term with id = 652 and slug = "ah-so-wine-opener" has been modified from:
    "цыганский штопор" => {en => "ah-so wine opener", ru => "цыганский штопор"}
    to:
    "Ah-so wine opener" => {en => "ah-so wine opener", ru => "цыганский штопор"}
  2. The tags on my front-end are no longer switched.
    Most likely this is because the changes of the tag 'Name'.
    Before I manually did the transformation of the name in the appropriate language:
    $tags = get_the_tags($post_id);
    foreach ($tags as $tag) {
    $name = function_exists( 'qtranxf_gettext')? qtranxf_gettext ($tag->name): $tag-> name;
    ....
    }

How should I do it now?

If you provide me with an explanation how to get a right name of the tag on my front-end I will be able to finish my tests and give you a definitive answer.

If all is correct, at front end get_the_tags should bring terms translated to the active language. At admin side, they will be in Raw ML format which is submitted to admin fields to edit with the help of LSB or in Raw ML manually. You should not need to use qtranxf_gettext. Also, instead of "function_exists( 'qtranxf_gettext')?", you can use https://qtranslatexteam.wordpress.com/faq/#DevelperNotes, if needed.

I am confused on your new report again, because if ru is the default, then it should show:

Term with id = 652 and slug = "ah-so-wine-opener" has been modified from:
"Ah-so wine opener" => {en => "ah-so wine opener", ru => "цыганский штопор"}
to:
"цыганский штопор" => {en => "ah-so wine opener", ru => "цыганский штопор"}

like it was on the first report. BTW, how "Ah-so wine opener" got capitalized? You did not type it manually, did you?

However, order of "en", "ru", suggests that en is the default, unless, you use order "en", "ru", while "ru" is the default?

"all is correct" means:

  1. Table wp_terms has "name" in the default language. If the default is 'ru', the values may be scrambled with %xx encoding in the db, which should be ok.
  2. Option "qtranslate_term_name" has mapping like "term_name_in_default_language" => array("en" =>"en_value", "ru" =>"ru_value" ).

Thanks a lot for all your help!

If all is correct, at front end get_the_tags should bring terms translated to the active language.

ok, I check it again today. But yesterday it did not work or I missed something.

I am confused on your new report again...

Sorry, I was tried to understand what was going on and I switched the default language many times for it.
I think I took this part from the log when my default language was English.
I will check if "Ah-so wine opener" get capitalized.
Yes, my order is "en" then "ru", while "ru" is the default.

switched the default language many times

This would screw you up big time :) Now, I guess, your troubles start making sense ;) Once set, never change the default language. We should give a warning about this in the plugin on the default language change, but it is not there yet ... sorry.

BTW, with this new operation "Clean Legacy Term Names", changing the default language can now be easier, but anyway, some 3rd-party plugins may save term values for their purpose and then it all will not work correctly. Woocommerce, for example will get screwed for sure.

Basically, the default language should not be changed during the lifespan of the site. Not yet, at least. Actually, this would rather always be a difficult operation anyway, since we never know what other plugins do with term names.

I updated Startup Guide with a note about changing the default language and two-letter language codes in the first item.

HI John,

I tested again. It works. Sometimes I do not see the changes but it's because of caching... I should do something with it. But "Clean Legacy Term Names" works. The name not got capitalized.

Once set, never change the default language.

Yes, it should be written before installing the plugin... During the development of my site I changed my mind concerning the default language twice :)

Thanks a lot, this is a good news. Could you please, try adding/editing/deleting terms via term.php and post.php pages? It should not do anything unexpected and it should allow any input including raw ml in any field where a category or tag can be entered under any editor mode. Could you find something not working? It is a lot of testing, if you could spend some time on it, it would be of great help. I am pretty sure you can be inventive on the ways to break it ;) Thanks!

Ok, I will test it but tomorrow.

Hi John,

I'm still do not understand how it works on front end.

here you can see my own log:

$locale=en_US  ==> $tag->name=Шампань

$tag->name=WP_Term::__set_state(array(
   'term_id' => 25,
   'name' => 'Шампань',
   'slug' => 'champagne',
   'term_group' => 0,
   'term_taxonomy_id' => 25,
   'taxonomy' => 'post_tag',
   'description' => '',
   'parent' => 0,
   'count' => 16,
   'filter' => 'raw',
   'object_id' => 2055,
   'i18n_config' => 
  array (
    'name' => 
    array (
      'ts' => 
      array (
        'en' => 'Champagne',
        'ru' => 'Шампань',
      ),
    ),
  ),
))

and then after switching the language:

$locale=ru_RU  ==> $tag->name=Шампань

$tag->name=WP_Term::__set_state(array(
   'term_id' => 25,
   'name' => 'Шампань',
   'slug' => 'champagne',
   'term_group' => 0,
   'term_taxonomy_id' => 25,
   'taxonomy' => 'post_tag',
   'description' => '',
   'parent' => 0,
   'count' => 16,
   'filter' => 'raw',
   'object_id' => 2055,
   'i18n_config' => 
  array (
    'name' => 
    array (
      'ts' => 
      array (
        'en' => 'Champagne',
        'ru' => 'Шампань',
      ),
    ),
  ),
))

Yesterday I thought it was connected with caching but it is not.
I'm ready to test it, but I do not know where to look for...

Strange, but I found some posts where this happens.
Other posts show correct tags in the needed language. The same tags!
If you tell me where in QTranslate-X you work with get_the_tags() I would add the logging and debug it...

But sometimes the log looks like this:

post='Бонжорно, Бароло!'
$locale='ru_RU  ==> $tag->name=Бароло'
$tag->name=WP_Term::__set_state(array(
   'term_id' => 42,
   'name' => 'Бароло',
   'slug' => 'barolo',
   'term_group' => 0,
   'term_taxonomy_id' => 42,
   'taxonomy' => 'post_tag',
   'description' => '',
   'parent' => 0,
   'count' => 17,
   'filter' => 'raw',
   'i18n_config' => 
  array (
    'name' => 
    array (
      'ts' => 
      array (
        'en' => 'Barolo',
        'ru' => 'Бароло',
      ),
    ),
  ),
))
post='Джованни, Джакомо, Джованни'
$locale='ru_RU  ==> $tag->name=Barolo'
$tag->name=WP_Term::__set_state(array(
   'term_id' => 42,
   'name' => 'Barolo',
   'slug' => 'barolo',
   'term_group' => 0,
   'term_taxonomy_id' => 42,
   'taxonomy' => 'post_tag',
   'description' => '',
   'parent' => 0,
   'count' => 17,
   'filter' => 'raw',
   'i18n_config' => 
  array (
    'name' => 
    array (
      'ts' => 
      array (
        'ru' => 'Barolo',
      ),
    ),
  ),
))

It is indeed strange. That is exactly why I wanted you to test it deeply ;) Thanks a lot.

This translation happens in function qtranxf_term_use in /inc/qtx_taxonomy.php.

It may has to do with timing. If terms are loaded before language framework is initialized in action 'plugins_loaded'? Actually, how did you get i18n_config there then. I guess I take it back.

The second case of barolo is explainable. Maybe you have duplicated entries for this term in table wp_terms or in option? I guess, you first should make sure that both, the list of terms in table wp_terms and option qtranslate_term, are as expected. Then test it all?

Hi Dmitry, any other news?

John,

first I checked entries in tables wp_terms and option. There are not duplicated entries.

Then I started to debug qtx_taxonomy.php

But I do not have a lot of time now and I cannot find where term->name get the right name according to active language. I thought that it's done in function qtranxf_term_name_in()
but this function is not called.

Could you help me? I cannot trace the whole algorithm to find a place where a name is set according to active language....

So far I found the following:

when you create i18n_config with call of qtranxf_term_set_i18n_config($obj);
sometimes $obj->name = 'Barolo' and sometimes $obj->name = 'Бароло'

when $obj->name = 'Бароло' the following code is executed:

        if(isset($q_config['term_name'][$term->name])){
            $ts = $q_config['term_name'][$term->name];
            $ts[$default_language] = $term->name;
            //$ml = qtranxf_join_b($q_config['term_name'][$term->name]);
            //$term->i18n_config['name'] = array( 'ts' => $ts, 'ml' => $ml );
        }else{

and certainly $ts is:

$ts=array (
  'en' => 'Barolo',
  'ru' => 'Бароло',
)

but when $obj->name = 'Barolo' the following code is executed (because certainly there is not entry with key 'Barolo'):

        }else{
            $ts = array( $default_language => $term->name );
        }

and $ts is:

$ts=array (
  'ru' => 'Barolo',
)

One thing I cannot trace - where you take $obj?

I can also add that I see many calls of qtranxf_term_use() for the same tag (with id=42) for one page...



$lang='en'
before i18n_config=NULL

INSIDE i18n_config !!! $term->name='Бароло'
$ts=array (
  'en' => 'Barolo',
  'ru' => 'Бароло',
)
$lang='en'
before i18n_config=NULL

INSIDE i18n_config !!! $term->name='Бароло'
$ts=array (
  'en' => 'Barolo',
  'ru' => 'Бароло',
)

$lang='en'
before i18n_config=NULL

INSIDE i18n_config !!! $term->name='Бароло'
$ts=array (
  'en' => 'Barolo',
  'ru' => 'Бароло',
)

$lang='en'
before i18n_config=NULL

INSIDE i18n_config !!! $term->name='Barolo'
$ts=array (
  'ru' => 'Barolo',
)

$lang='en'
before i18n_config=NULL

INSIDE i18n_config !!! $term->name='Barolo'
$ts=array (
  'ru' => 'Barolo',
)

and after language switch:

$lang='ru'
before i18n_config=NULL

INSIDE i18n_config !!! $term->name='Barolo'
$ts=array (
  'ru' => 'Barolo',
)

$lang='ru'
before i18n_config=NULL

INSIDE i18n_config !!! $term->name='Бароло'
$ts=array (
  'en' => 'Barolo',
  'ru' => 'Бароло',
)

$lang='ru'
before i18n_config=NULL

INSIDE i18n_config !!! $term->name='Бароло'
$ts=array (
  'en' => 'Barolo',
  'ru' => 'Бароло',
)

$lang='ru'
before i18n_config=NULL

INSIDE i18n_config !!! $term->name='Barolo'
$ts=array (
  'ru' => 'Barolo',
)

$lang='ru'
before i18n_config=NULL

INSIDE i18n_config !!! $term->name='Barolo'
$ts=array (
  'ru' => 'Barolo',
)

I cannot find where term->name get the right name according to active language. Could you help me?

Sure, it gets set in /inc/qtx_taxonomy.php, function qtranxf_term_use, lines 43-49:

43      if(!isset($obj->i18n_config)){
44          qtranxf_term_set_i18n_config($obj);
45          if(isset($obj->i18n_config['name']['ts'][$lang]))
46              $obj->name = $obj->i18n_config['name']['ts'][$lang];
47          if(isset($obj->i18n_config['description']['ts'][$lang]))
48              $obj->description = $obj->i18n_config['description']['ts'][$lang];
49      }

It gets executed on load of each object ($obj) WP_term, one time only, if cache $obj->i18n_config is not yet set. Variable $lang is active language at this point. It is assumed that $obj->name is in the default language on the initial call, as it came from database. Once $obj->i18n_config is set, then $obj->name is changed to the translation in active language on line 46. If this function is called again by any chance on the same object, then nothing happens, as cache i18n_config is already set, and $obj->name stays the same, in the active language, as it was set on the first call of qtranxf_term_use on the same object.

Your log confirms this logic and all would look correct, if $term->name is correct to begin with, but

sometimes $obj->name = 'Barolo' and sometimes $obj->name = 'Бароло'

is what needs to be explained. I do not understand how you get $term->name='Barolo' on the initial call, when $term->i18n_config is not yet set. The default language is ru, so the wp_terms.name should have value 'Бароло'. Could you double check which value of wp_terms.name is in the database for that term with id 42?

There are three possible explanations I can imagine:

  1. You have both 'Barolo' and 'Бароло' in 'wp_terms' table in column 'name'. To find it out, I would print $term->term_id at the same time as you print $term->name, and see if it is the same object or they are different objects.
  2. There is some other place, which we overlooked, where $term->name gets changed before coming to function qtranxf_term_use for the first time. Then it would be very important to find out where exactly it happens.
  3. The cache value $obj->i18n_config gets cleared somewhere in WP code between the first and a subsequent call to qtranxf_term_use. Then this is not a good way to cache the translations and we should cache it by other method. This would be easy enough to fix.

If item 1 is the case, then we should improve the code of gtranxf_db_clean_terms to deal with case of both 'Barolo' and 'Бароло' to exists in wp_trems when they are also the translations of each other. Since you've been changing the default language, it is possible that you now have both of them in wp_terms.name. But first, let us find out what exactly is happening.

Thanks a lot!

Just occurred to me another possible case:

Case 4. $term->name='Barolo' comes from a caching plugin, which cached the value from a previous call with different language. Do you use any advanced caching plugin? I have no idea yet how to deal with it. Probably we need to address that with caching plugin, which should always cache values by the value of locale in addition to what they are already doing.

John, sorry... today I cannot debug this case... I need to leave home and I'll be back tomorrow only.
But some my thoughts:

You have both 'Barolo' and 'Бароло' in 'wp_terms' table in column 'name'

No, I checked 'wp_terms' table yesterday many times. There is only one entry for 'Бароло' with id=42
I forgot to mention but all my logs were done with this code:

function qtranxf_term_set_i18n_config($term){
    $term->i18n_config = array();
if($term->term_id == 42) {__dbug_log('\nINSIDE i18n_config !!! $term->name=', $term->name); }

As you can see I logged only for id=42 (without this my log was too big and confusing).

There is some other place, which we overlooked, where $term->name gets changed before coming to function

I think that it's a reason.
I could try to find 'this place' tomorrow.

But I would like to ask you - why use a tag Name as key in array?
My best choice would term_id - it's not changed.
And even we find out that the problem is connected with cache - it will be solved easily if not to use the Name as the key.

I am not too sure why the original design used term name as a key. I can only guess, that term_id is not always available where the translation needed to happen. The original design did not use caching and did not alter terms on their loading. It would only replace term name as a string with another string inside relevant filters. Now, after we changed it to do translation on load, it is possible to use term_id instead. I thought we would change this design later to use term_id, after this intermediate step is proved to work well. The future idea is to reduce number of filters needed to run by doing translation of terms on term loading. This would improve the performance, if we can make it work right.

I was trying to look for another place, where term name gets translated and I could not find one so far. I look forward to seeing the results of your investigation.

If it is case 4 (external caching), then switching to term_id would not help actually much, unless we always execute line 46 on each call of the function, which can be done with name as a key as well, but the idea was to make it a little more efficient and to execute that line one time only.

Thanks again for your invaluable help. I look forward to hearing from you.

John, what I found so far:

  • I call function get_the_tags()
  • it leads to call of get_the_terms() at [/wp-includes/category-template.php]

and in get_the_terms data will be fetched from the cache or from the database if it is not available from cache. And it's not a 3rd-party plugin - it's a regular WP algorithm.

function get_the_terms( $post, $taxonomy ) {
    if ( ! $post = get_post( $post ) )
        return false;

    $terms = get_object_term_cache( $post->ID, $taxonomy );
    if ( false === $terms ) {
        $terms = wp_get_object_terms( $post->ID, $taxonomy );

and then - it is a matter of chance.
On the same page there are a lot of calls to this function - WPSEO_OpenGraph, post_class () and so on.
If in the cache will be stored variant of the Russian language - that is, with name 'Бароло' - then everything will work out well. If it will be stored into the cache with the English name - all the breaks (because in option table a translation stored with Russian name as key).

I do not know what to do and how prevent it...

Well, I do not see how this explains the problem. I knew that part of the code. On the very first call to the get_the_terms or to get_term the same cache is created for each term object. During this first time, it should pass through our function, which adds additional property i18n_config and changes the term name. These changes get stored in cached object and then subsequent calls use the same cached object with properties already adjusted.

That is the theory, and this is how it works on my testing server. I am not sure what exactly is different on your server, I am only very glad we did testing on your server before releasing this code. It could have broken like a half of our users ...

We need to figure it out. I am starting thinking that it may be easier if you could setup an admin access for us including FTP? Maybe to a testing server which shows the same problem? It would take some time for you to set it up for us, but it might be less time for you to spend than to finish troubleshooting on your own? What do you think? Is there an easy enough way to set such a server instance up? Or maybe you could use plugin like Duplicator to create a copy of your site (with the minimum content) that we could instantiate on our local server? Meanwhile I'll try to run some tests with calls to get_the_terms, maybe I would be able to reproduce the same problem.

John, I do not see any problem to give you access to my server.
My site is located at WPEngine - so I could create a staging version for you and give a full access to this instance. Give me your mail and I will send the credentials.

I've sent via the form. Please confirm that you got it.
you should use truewine.ru instead of truewine.staging.wpengine.com
If you need - I could create a user for you in WP.
Best url to test it http://truewine.ru/en/movie/giacomo-conterno-barolo-1955-2/

I added the credentials to my main site because I cannot reproduce the problem on Staging... which leads me to idea that it's connected with the cache of WPEngine which is not active on Staging.
I do not use any caching plugin - only solution from WPEngine which is embedded in the hosting.

Ah, finally we are getting somewhere, so it is case 4, external caching? Is there a way to enable caching on staging? Could you talk to the provider if they can use locale as a cache key as well? Is there any control panel for caching, with some options to adjust?

WPEngine is a very big provider... there is not any control of their caching... I do not think I can make any influence on them...

Does not hurt to ask, they should have a solution for multilingual sites. But let us first make sure that it is indeed from their caching. Cache should go by URL, right? If you turn off option "Hide URL language information for default language.", then URL will define the language uniquely. Does this help?

I will ask them.
the option "Hide URL language information for default language." was off

We found out so far, that the problem was coming from older version of yoast-qtx integration plugin.

Dmitry, did you manage to find more problems on further testing?

John, It looks like the problem is still here.
But I'm not sure... I've cleaned all caches now and after that I cannot reproduce it... but I need some more time for testing in different conditions.

Hi Dmitry, Any luck to reproduce it again? I played a bit more and could not reproduce it. Did you try to test all other stuff? Are you working on this site or is it more or less done and no further plans to improve for now?

Hi John,

I can reproduce it again. The same place, the same tag... Your fix does not help.
I tested the tag creation and I modified different tags... it works.
I do not understand how the button "Copy from" works... or it does not work?

This site is more or less done, I only improve some things and add new posts.

"Copy From" fills empty fields only, otherwise it can be damaging. Clear the text of field wanted before copying.

I cannot reproduce in any of my browsers. Same page? What did you do before you could reproduce it again?

try the following:

http://truewine.ru/en/movie/giacomo-conterno-barolo-1955/

switch to RU

switch to EN

then press "Next" on the picture

when loaded switch to RU


in my browser the tag Barolo is does not change to Бароло

if it does not work try to move between posts with "Next" and "Previous" buttons and switch the language

Yes, I could reproduce now. Wow. That one is probably case 4 now, advanced caching. This is not reproducible on staging server either, is it for you? I'll try to investigate for more details. Thanks!

Did you figure out "Copy From"? Is it helpful?

Did you figure out "Copy From"? Is it helpful?

you know, I implemented "Copy from" for myself one year ago. My implementation was not "general", it was very connected with my site (so I decided myself which fields I would like to copy). But I have a "visual confirmation" in my implementation: when I press button - the fields changed. I still have a chance to reject these changes - I just need NOT TO PRESS the "Update" button.

in your implementation if the field is not empty - nothing happens. NOTHING. If I get message that "the fields should be empty" - maybe it would be helpful. But sometimes I NEED to REWRITE the fields after some changes in the post. In my implementation I press the button "Copy" and then if I'm sure - "Update". In your case - too much work to empty all fields.

Maybe it will be helpful for you.

Yes, I could reproduce now. Wow. That one is probably case 4 now, advanced caching.

But I cannot understand - why the "Title", "Description", "menu" and all other things are switched with "advanced caching" and only tags - NOT?

That is what needs to be figured out, and that is what I meant by "advanced caching", which might be done on per-object base, not per-link base. We should find the true cause before jumping to a conclusion in any case.

too much work to empty all field

My idea was that if you have something in the field, then you do not want to copy other language, you simply edit what you already have. I saw the use of it only when a new translation is started. Occasionally, if user really wants to redo one particular field over, then they may empty it before pressing "Copy From". Overwriting all the fields every time is too much, since user will want to change just one field in most of cases, unless a completely new translation is being started - and then all MLFs are already empty to begin with.

Having a separate button for each field is too much too, as it is a feature of rather rare use.

How do you suggest to implement it?

I could reproduce it a few times. Then switched yoast plugins off and then could not reproduce it anymore, which gave me a suggestion that the problem is still in yoast plugin. I turned them on again, and then still cannot reproduce it no matter what I tried. What a heck that could possibly be?

I notice that you use wp-content/object-cache.php. But you have it in staging too, where we could not reproduce the problem ...

I am not sure for now how to proceed. It is very hard to troubleshoot when there is no a consistent way to reproduce ...

I turned yoast off again and was able to reproduce the problem at some point. Let us keep it off for now, would you mind? It simplifies the execution a little bit. I'll do more research.

After more research, our current theory is that it is persistent object-based cache issue coming from file /wp-content/object-cache.php It has a tricky expiring mechanism, which makes problem appear like random. I temporarily moved that file to /wp-content/tmp/object-cache.php in order to disable it. Let us see if the problem indeed disappeared. Please, try to reproduce it again. If you cannot, then we will think what to do about it, it is not obvious at all. Thanks a lot!

I have just activated yoast plugins back, since I realised that we should now test full configuration now to see if disabling of cache helped. BTW, please, pay attention to the change in speed. Does that advanced caching make a considerable difference? Now your site should be felt slower, is it indeed?

Any news?

Do we have a confirmation, that it is ok now with cache off?

I did not have much time these days to test it.
But all my tests so far show that it's ok when the cache is off.
When the cache is on - the problem is reproducible.