Here are the steps to reproduce:
- Enable Metatags, Entity Translation and Inline Entity Forms.
- Make a node type translateable (using Entity Translation) and add an entity reference field that uses the inline_entity_form widget (it doesn't matter what it points to).
- Create a node of that type, with custom meta tags and add one referenced entity, save it.
- Add a translation in another language, translate the meta tags and save the translation (you can also translate the referenced entity, this isn't relevant for this bug though). At this point we have all content as it should be.
- Now edit the translation again, leave the meta tags as they are (everything still looks fine) and make a modification to the referenced entity using the inline entity form widget, then save the entire form. The translated meta tags are gone and have been reset to the default values.
The cause of this issue is the following code in metatag_field_attach_form():
<?php
// Entity_Translation will trigger this hook again, skip it.
if (!empty($form_state['entity_translation']['is_translation'])) {
return;
}
?>
This code works as intended when adding a translation, but not when editing a translation, because in that case $form_state['entity_translation']['is_translation'] is not defined (it gets defined later, only after the code above has already been executed). However, even though the logic is broken, the resulting behavior is correct, because when editing a translation metatag_field_attach_form() doesn't actually get called twice as mentioned in the code comment, so we really don't want to return yet.
The problem arises when using the inline_entity_form widget, which reloads part of the form using Drupal's standard ajax mechanism. This causes the form to be rebuilt, and the code above from metatag_field_attach_form() is run again, but this time after Entity Translation has set $form_state['entity_translation']['is_translation']. The code is now running as intended, but the resulting functionality is broken. Now the function returns prematurely, $form['#metatags'] doesn't get set, metatags' hook_form_alter() gets skipped and the form submit handler doesn't get set in metatag_metatags_form(), so meta tag information gets lost and is replaced with the default value.
The solution is to fix the code above to only return when a new translation is being added, not anytime a translation is edited:
<?php
// Entity_Translation will trigger this hook again when adding a new translation, skip it.
if (isset($form_state['entity_translation']['is_translation']) && !empty($form_state['entity_translation']['is_translation'])) {
return;
}
?>