Potential incorrect logic when selecting language for new content moderation entity

Created on 23 May 2019, about 6 years ago
Updated 1 July 2025, 4 days ago

Problem/Motivation

I'm having an odd issue where I am getting a 'default language cannot be changed' error when trying to save a translated node.
I've tracked it down to the attached content moderation entity, and in particular EntityOperations::updateOrCreateFromEntity()

  /**
   * Creates or updates the moderation state of an entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to update or create a moderation state for.
   */
  protected function updateOrCreateFromEntity(EntityInterface $entity) {
    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
    $entity_revision_id = $entity->getRevisionId();
    $workflow = $this->moderationInfo->getWorkflowForEntity($entity);
    $content_moderation_state = ContentModerationStateEntity::loadFromModeratedEntity($entity);
    /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
    $storage = $this->entityTypeManager->getStorage('content_moderation_state');

    if (!($content_moderation_state instanceof ContentModerationStateInterface)) {
      $content_moderation_state = $storage->create([
        'content_entity_type_id' => $entity->getEntityTypeId(),
        'content_entity_id' => $entity->id(),
        // Make sure that the moderation state entity has the same language code
        // as the moderated entity.
        'langcode' => $entity->language()->getId(),
      ]);
      $content_moderation_state->workflow->target_id = $workflow->id();
    }

    // Sync translations.
    if ($entity->getEntityType()->hasKey('langcode')) {
      $entity_langcode = $entity->language()->getId();
      if ($entity->isDefaultTranslation()) {
        $content_moderation_state->langcode = $entity_langcode;
      }
      else {
        if (!$content_moderation_state->hasTranslation($entity_langcode)) {
          $content_moderation_state->addTranslation($entity_langcode);
        }
        if ($content_moderation_state->language()->getId() !== $entity_langcode) {
          $content_moderation_state = $content_moderation_state->getTranslation($entity_langcode);
        }
      }
    }

    // If a new revision of the content has been created, add a new content
    // moderation state revision.
    if (!$content_moderation_state->isNew() && $content_moderation_state->content_entity_revision_id->value != $entity_revision_id) {
      $content_moderation_state = $storage->createRevision($content_moderation_state, $entity->isDefaultRevision());
    }

    // Create the ContentModerationState entity for the inserted entity.
    $moderation_state = $entity->moderation_state->value;
    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
    if (!$moderation_state) {
      $moderation_state = $workflow->getTypePlugin()->getInitialState($entity)->id();
    }

    $content_moderation_state->set('content_entity_revision_id', $entity_revision_id);
    $content_moderation_state->set('moderation_state', $moderation_state);
    ContentModerationStateEntity::updateOrCreateFromEntity($content_moderation_state);
  }

If the moderation state can't be found we create it with the langcode of the entity that we are saving. If that isn't the default langcode of the entity, then next time we go to save the default language of the eniity it tries to change the langcode and the api won't let it.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

๐Ÿ› Bug report
Status

Active

Version

11.0 ๐Ÿ”ฅ

Component

content_moderation.module

Created by

๐Ÿ‡บ๐Ÿ‡ธUnited States mikelutz Michigan, USA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024