diff --git a/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php index d7c3672..9302662 100644 --- a/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php +++ b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php @@ -2,6 +2,8 @@ namespace Drupal\content_moderation\Plugin\Field; +use Drupal\content_moderation\ContentModerationStateInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Field\FieldItemList; /** @@ -13,12 +15,12 @@ class ModerationStateFieldItemList extends FieldItemList { /** - * Gets the moderation state entity linked to a content entity revision. + * Gets the moderation state ID linked to a content entity revision. * * @return string|null - * The moderation state linked to a content entity revision. + * The moderation state ID linked to a content entity revision. */ - protected function getModerationState() { + protected function getModerationStateId() { $entity = $this->getEntity(); /** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */ @@ -27,43 +29,67 @@ protected function getModerationState() { return NULL; } - if ($entity->id()) { - $revisions = \Drupal::service('entity.query')->get('content_moderation_state') - ->condition('content_entity_type_id', $entity->getEntityTypeId()) - ->condition('content_entity_id', $entity->id()) - ->condition('content_entity_revision_id', $entity->isNewRevision() ? $entity->getLoadedRevisionId() : $entity->getRevisionId()) - ->condition('workflow', $moderation_info->getWorkFlowForEntity($entity)->id()) - ->allRevisions() - ->sort('revision_id', 'DESC') - ->execute(); - - if ($revision_to_load = key($revisions)) { - /** @var \Drupal\content_moderation\ContentModerationStateInterface $content_moderation_state */ - $content_moderation_state = \Drupal::entityTypeManager() - ->getStorage('content_moderation_state') - ->loadRevision($revision_to_load); - - // Return the correct translation. - if ($entity->getEntityType()->hasKey('langcode')) { - $langcode = $entity->language()->getId(); - if (!$content_moderation_state->hasTranslation($langcode)) { - $content_moderation_state->addTranslation($langcode); - } - if ($content_moderation_state->language()->getId() !== $langcode) { - $content_moderation_state = $content_moderation_state->getTranslation($langcode); - } - } - - return $content_moderation_state->get('moderation_state')->value; - } + // Existing entities will have a corresponding content_moderation_state + // entity associated with them. + if (!$entity->isNew() && $content_moderation_state = $this->loadContentModerationStateRevision($entity)) { + $content_moderation_state = $this->loadCorrespondingContentModerationStateLanguage($entity, $content_moderation_state); + return $content_moderation_state->moderation_state->value; } + // It is possible that the bundle does not exist at this point. For example, // the node type form creates a fake Node entity to get default values. // @see \Drupal\node\NodeTypeForm::form() $workflow = $moderation_info->getWorkFlowForEntity($entity); - if ($workflow) { - return $workflow->getInitialState()->id(); + return $workflow ? $workflow->getInitialState()->id() : NULL; + } + + /** + * Load the correct language based on the language of the given entity. + * + * @param \Drupal\Core\Entity\ContentEntityInterface $entity + * The entity that will be used to determine the language loaded. + * @param \Drupal\content_moderation\ContentModerationStateInterface $content_moderation_state + * The entity whose language needs to match the given content entity. + * + * @return \Drupal\content_moderation\ContentModerationStateInterface + * The content moderation state entity matching the given language code. + */ + protected function loadCorrespondingContentModerationStateLanguage(ContentEntityInterface $entity, ContentModerationStateInterface $content_moderation_state) { + if (!$entity->getEntityType()->hasKey('langcode')) { + return $content_moderation_state; + } + $langcode = $entity->language()->getId(); + if (!$content_moderation_state->hasTranslation($langcode)) { + $content_moderation_state->addTranslation($langcode); } + return $content_moderation_state->language()->getId() !== $langcode ? $content_moderation_state->getTranslation($langcode) : $content_moderation_state; + } + + /** + * Load the content moderation state revision associated with an entity. + * + * @param \Drupal\Core\Entity\ContentEntityInterface $entity + * The entity the content moderation state entity will be loaded from. + * + * @return \Drupal\content_moderation\Entity\ContentModerationState|null + * The content_moderation_state revision or FALSE if none exists. + */ + protected function loadContentModerationStateRevision(ContentEntityInterface $entity) { + $moderation_info = \Drupal::service('content_moderation.moderation_information'); + $content_moderation_storage = \Drupal::entityTypeManager()->getStorage('content_moderation_state'); + + $revisions = \Drupal::service('entity.query')->get('content_moderation_state') + ->condition('content_entity_type_id', $entity->getEntityTypeId()) + ->condition('content_entity_id', $entity->id()) + // Ensure the correct revision is loaded in scenarios where a revision is + // being reverted. + ->condition('content_entity_revision_id', $entity->isNewRevision() ? $entity->getLoadedRevisionId() : $entity->getRevisionId()) + ->condition('workflow', $moderation_info->getWorkFlowForEntity($entity)->id()) + ->allRevisions() + ->sort('revision_id', 'DESC') + ->execute(); + + return !empty($revisions) ? $content_moderation_storage->loadRevision(key($revisions)) : NULL; } /** @@ -93,7 +119,7 @@ protected function computeModerationFieldItemList() { $index = 0; if (!isset($this->list[$index]) || $this->list[$index]->isEmpty()) { - $moderation_state = $this->getModerationState(); + $moderation_state = $this->getModerationStateId(); // Do not store NULL values in the static cache. if ($moderation_state) { $this->list[$index] = $this->createItem($index, $moderation_state);