Problem/Motivation

tldr;
The translated entity was never updated on save after upgrading module to alpha3.

When updating a translation for a block_content, the translated content did not appear on the translated entity but appears on the original source language entity instead after saving it. This happens on translatable node content types as well.

The root cause is happening from conflict_entity_prepare_form line 118, where it overridden the entity set within form_object, which is further used by content_translation module on content_translation.module line 391 to retrieve its entity object again and down the line it determine the active langcode to update the target translation of the entity being saved.

In short, the entity fetched from conflict_entity_prepare_form has an activeLangcode = "x-default", while the translated entity should be saved has its activeLangcode = "en" (when x-default langcode being zh-hant), the latter was overridden by "x-default".

@file conflict.module

function conflict_entity_prepare_form(EntityInterface $entity, $operation, FormStateInterface $form_state) {
  if (!$entity->isNew() && !$form_state->isCached()) {
    $conflict_entity_original_hash = $form_state->getUserInput()['conflict_entity_original_hash'] ?? NULL;
    if ($conflict_entity_original_hash) {
      $original_entity = \Drupal::keyValueExpirable('conflict_original_entity')->get($conflict_entity_original_hash);
      if ($original_entity) {
        $original_entity = unserialize($original_entity);
        /** @var \Drupal\Core\Entity\EntityFormInterface $form_object */
        $form_object = $form_state->getFormObject();
        $form_object->setEntity($original_entity);             <---- root cause on this line
        $form_state->set('conflict-exchanged-entity', TRUE);
      }
    }
  }
}
@file content_translation.module

function content_translation_form_alter(array &$form, FormStateInterface $form_state) {
  $form_object = $form_state->getFormObject();
  if (!($form_object instanceof ContentEntityFormInterface)) {
    return;
  }
  $entity = $form_object->getEntity();   <--- the entity content_translation wants to fetch
  $op = $form_object->getOperation();
}

Steps to reproduce

  1. Install fresh Drupal 9.5.1
  2. Select a language other then English on installation "Chinese, Traditional"
  3. Enable module content_translation, config_translation, conflict 8.x-2.0-alpha3
  4. Add a second language at [site:url]/admin/config/regional/language
  5. Enable content type 'article' translation config at /admin/structure/types/manage/article, leave default language as "Site's default language"
  6. Create a new node for article node 1 by default language (TITLE: This is not English)
  7. Create new translation for English on node 1 (Title: This is English ), new translation and contents are created as normal
  8. Update your translation at /en/node/1 edit with (Title: This is English v2), save, and the translation is not changed.
  9. Check /node/1 and it has (Title: This is English v2)
  1. translation overview
  2. Update node translation and save.
  3. Original node title and content was overriddentranslation overview

Proposed resolution

Rewrite conflict_entity_prepare_form to respect and set the translated entity in its form_object.

P.S. We downgraded our module alpha2 temporarily before this issue is resolved.

Remaining tasks

User interface changes

API changes

Data model changes

Issue fork conflict-3333138

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

g-brodiei created an issue. See original summary.

g-brodiei’s picture

Issue summary: View changes

Update issue summary.

vood002’s picture

I just spent several hours trying to track down the culprit breaking my multilingual Paragraphs site and it lead me to the conflict module.

I'm experiencing similar symptoms as OP. I wasn't able to find this bug report. I ended up isolating the upgrade from alpha2 to alpha3 by brute forcing version downgrading across my site.

For me, when editing translated paragraphs entities, if using widget settings that default paragraphs to "closed" they would load on page load with the proper translation. But, when I edited any paragraph (loading the form + editable content asynchronously) the original wrong translation would be incorrectly loaded.

If I changed my widget settings to open all paragraphs as editable by default, they would load in the correct language. But, upon saving, no fields were updated. New revisions were created on the original (wrong) language, not on the translated language. Neither version appeared to change when I saved changes.

The above paragraphs are mostly to inject some search terms into this thread so other people who experience similar behaviors can find it more easily than I could.

g-brodiei’s picture

Priority: Major » Critical

Changing status to critical as this bug overrides unintended target language of node, block contents and paragraph contents.

mattea.turnbull’s picture

Thank you so much to the OP for creating this issue report I broke my site a month ago and could not figure out which update it was.

For anyone with this issue, until their is a patch, use the alpha2 version by using

composer require drupal/conflict:2.0.0-alpha2

g-brodiei’s picture

Title: Original entity content got overwritten instead when updating translated entity on save for a multilingual site » Original language entity content got overwritten when updating translated entity for multilingual site

Glad it helped @mattea.turnbull! We were affected while updating one of Acquia's distribution lightning/workflow which has conflict module as one of its dependencies.

Rewriting title for easier understanding.

rkamepalli’s picture

Thanks @mattea.turnbull. Downgrading to alpha 2 worked. We are using acquia/blt-project and with latest upgrade we moved to alpha 3 introduced issue.

wilco made their first commit to this issue’s fork.

wilco’s picture

StatusFileSize
new1.11 KB

I think I may have found a solution around the problem highlighted in this issue.

I am including a patch file for those that wish to use this immediately.

Basically, the proceedure conflict_entity_load() attempts to clone an entity that has yet to have been fully loaded. The problem is this entity is only partially complete when compared against the RouteMatch Object the form uses in certain instances. Imagine a Node or Taxonomy Term which is built using multilingual mechanism.

While inspecting the source of the complete object vs the cloned object I noted a lack of translation elements.

By ensuring the entity being loaded is in fact of instance TranslatableInterface we actually get a better cloned entity. Thus, resolving these incorrect conflicts.

This article lead me to this conclusion: Entity Translation API. Specifically the third bullet point.

wilco’s picture

StatusFileSize
new1.11 KB

Fixed the patched file. Seems to not want to apply properly.

joseph.olstad’s picture

Is there a category higher than "critical" ?

joseph.olstad’s picture

Would be nice to have automated test coverage for this but ya, critical fix that needs to go in asap, I suggest to put the fix in and follow up with a new issue to add automated test coverage.

martijn houtman’s picture

Confirmed this is happening on several of our sites as well. Thanks for catching this, it took me some time to find out the conflict module was the culprit.

Confirmed patch #10 fixes the issue.

joseph.olstad’s picture

The patch works well however due to the lack of support in this project we've chosen to uninstall the conflict module instead of patch it.

joseph.olstad’s picture

I have sent a message to three project maintainers about this critical issue. I also sent messages to maintainers 2 months ago as well. This is a repeat.

@dww, @drumm and @hchonov have been notified of the severity of this issue. It absolutely must be resolved asap. Patch 10 works perfectly.

dww’s picture

Status: Active » Needs review

If this is so urgent and ready, why is the status only “active”?

I’m unavailable for the next few days, but I hope to take a closer look later this week.

joseph.olstad’s picture

@dww, it's RTBC+ by @wilco , @Martijn Houtman and myself. I assure you this is a critical fix that is needed and that patch 10 is the correct solution. It was a very tough issue to figure out and plagued two of the projects I worked on for several months before @wilco figured it out. I found a workaround which was to enable the editorial workflow on media entities. With that said, no one should be forced to use a workflow in order to prevent data loss.

joseph.olstad’s picture

Status: Needs review » Reviewed & tested by the community

Test scenario setup steps:

  1. Install Drupal core 9.5.8
  2. enable the content_translation module
  3. Enable translation on a node bundle
  4. Enable translation on a media bundle
  5. composer require drupal/conflict
  6. install the "conflict" module composer require drupal/conflict and drush en conflict
  7. DO NOT use workflows, do not install the workflows module
  8. add a node of the translateable type, translate the node entity
  9. add a media entity of the translatable type, translate the media entity
  10. publish the media entity
  11. publish the node entity
  12. edit the node translation and publish it
  13. edit the media translation and publish it
  14. edit the node translation again, notice that it clobbers the other language
  15. edit the media translation again, notice that it clobbers the other language
  16. Delete your node translation, it will clobber the entity
  17. Delete your media translation, it will clobber the entity


so, why is this critical?

  • data loss on edit translation
  • data loss on delete translation

To fix the problem:

three choices:

  1. Uninstall the conflict module
  2. Rather than uninstall the conflict module, use patch 10
  3. Rather than use the patch, install the workflow module and add the entity into a workflow (workaround, but still breaks taxonomy term translation also).

The best fix is patch 10.

joseph.olstad’s picture

Issue tags: +data loss
joseph.olstad’s picture

@dww , three lines of code is all that is needed, please have a look at patch 10.

joseph.olstad’s picture

FYI , all my projects no longer use this module because this issue is being ignored. This is a critical issue that needs to be fixed and it's only 3 lines of code that is needed to fix it.

mattea.turnbull’s picture

What does this module do and what are the consequences of uninstalling it. This was a major high stress event when this broke and I'd like to evaluate if I should drop it vs applying the patch.

joseph.olstad’s picture

@mattea.turnbull, either option use patch or uninstall the module will fix the regression. If you uninstall this module you won't have the regression however if you apply the patch you'll benefit from automatic conflict resolution if two people publish or edit a draft content at the same time.

Meanwhile I have put in a request to take over maintainership of this project.
#3381341: Offer to maintain Conflict

joseph.olstad’s picture

My offer to maintain this project has been ignored for more than 6 weeks after several unsuccessful attempts to reach the maintainers.

Pushing offer to the ownership queue.
#3381341: Offer to maintain Conflict

hchonov’s picture

Status: Reviewed & tested by the community » Needs work

The current patch is altering in which language the entity is being loaded as snapshot in conflict_entity_load(). The cause is to be searched at the place that is using it and not loading it. This is only covering up the bug that might come up at a harder place to search for later. So please check about the usages of $entity->{EntityConflictHandlerInterface::CONFLICT_ENTITY_ORIGINAL}. If we would accept the current change then $entity->language() and $entity->{EntityConflictHandlerInterface::CONFLICT_ENTITY_ORIGINAL}->language() will return a different language which would be inconsistent.

joseph.olstad’s picture

Until this is resolved, maintaining recommendation to uninstall this module when using more than one language as this is a critical bug causing data loss.

joseph.olstad’s picture

There was a core commit made today that "might" improve this situation, I haven't tested it.

#3329066: Creating a new translation may delete translations with drafts

mattea.turnbull’s picture

With the patch I had been getting constant, 'you have a conflict' statements and stuff not saving in drupal 10.01. I have uninstalled conflict and that resolved those issues (previously in drupal 9.5 I never saw that dialog or had issues).

I also had to uninstall autosave_form (unrelated to this but it seemed to break in drupal 10.0.1 with multilingual site).

I am having issues where after I save French (my secondary language) it takes up to 5 minutes to display the saved changes onto the front end of the site (if you have any clue what updated with drupal 10 that would cause that?)

Mattea

mattea.turnbull’s picture

I'm currently testing content_lock module as an alternative to using the conflict module.

serg.linkin’s picture

StatusFileSize
new1.18 KB

We are currently trying to use #10 patch with Drupal 9.5.11. But it breaks jsonapi responses that check access to individual resources or unpublished translations, for example, with ERR_EMPTY_RESPONSE or '50x' server status code.

So I've improved it by using the 'entity_upcast' context to fix this, based on the jsonapi module code.

levmyshkin’s picture

Hi mattea.turnbull, I went here because I already use Content Lock module coupled with Conflict module. Because Authors need to have ability to lock translation revision, not locking entire node. And I also have this problem.

joseph.olstad’s picture

Status: Needs work » Needs review

Patch #31 seems like a very safe change to make with the extra validation compared with patch #11

joseph.olstad’s picture

Status: Needs review » Fixed
joseph.olstad’s picture

oops somehow authored by incorrectly credited, it was Wilco that did this patch, I got wilco and serg.linkin in the commit also .

https://www.drupal.org/project/conflict/releases/3.0.0-alpha4

d.o removed the automatic author option, I must have put the wrong id in

joseph.olstad’s picture

Committed #31, tagged and released

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.