I am trying to add a node translation programmatically when a node is created (using hook_ENTITY_TYPE_insert). My code works fine except that the translation doesn't really have a content moderation state. My code is the following.

function mymodule_add_translation($node) {
  // get the current language, and determine the translation language
  $lang = \Drupal::languageManager()->getCurrentLanguage()->getId();
  $langcode = ($lang == 'en') ? 'fr' : $lang;
  $node->addTranslation($langcode, ['title' => $node->getTitle()])->save();

This is what the content_moderation_state_field_revision table looks like for two nodes; the first one was manually translated and the second one was translated using the above code.

content_moderation_state_field_revision table

I am clearly doing something incorrect. Any suggestion would be really appreciated.


What is the problem you're seeing with the moderation state table? What I think I'm seeing is:

  1. Revision 15 is the initial save of the node.
  2. Revision 16 is the second save, where fr has changes and en does not.

I can't see anything too unusual here, but if you are running into errors later in the lifecycle of the node, that would be helpful information.

One red flag I can see in the code is manually calling setRevisionTranslationAffected and addTranslation. Many of the Content Moderation tests use the following methods to add translations and to create revisions, because that's how additional bits of metadata like the revision_translation_affected column are set:

$storage = \Drupal::entityTypeManager()->getStorage('node');
// You may try either of these two methods for creating a revision or a translation.
$storage->createTranslation($node, 'fr', $node->toArray());
  • Hi @Sam152, thanks for responding. NID 13 is the one that the translation was added via the UI, so the revision IDs are good as you have indicated. NID 14 (the last row) is the one I added via the above code and clearly from the lack of entries in the table it is a bit off. ;) If I insert the missing rows via SQL everything works fine, but that is clearly a hack. I am just looking for the programmatic path to get there. Appreciate the help! – JoelB Apr 14 at 0:29
  • I tested calling createTranslation directly, but that failed. It looks like the addTranslation method really calls createTranslation with a the translation status set to new or existing... this part works correctly I believe. > public function addTranslation($langcode, array $values = []) { > $this->translations[$langcode]['status'] = !isset($this->translations[$langcode]['status_existed']) ? static::TRANSLATION_CREATED : static::TRANSLATION_EXISTING; > return $storage->createTranslation($this, $langcode, $values); > } – JoelB Apr 14 at 1:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.