3 namespace Drupal\content_moderation\Plugin\Field;
5 use Drupal\Core\Entity\ContentEntityInterface;
6 use Drupal\Core\Field\FieldItemList;
9 * A computed field that provides a content entity's moderation state.
11 * It links content entities to a moderation state configuration entity via a
12 * moderation state content entity.
14 class ModerationStateFieldItemList extends FieldItemList {
17 * Gets the moderation state ID linked to a content entity revision.
20 * The moderation state ID linked to a content entity revision.
22 protected function getModerationStateId() {
23 $entity = $this->getEntity();
25 /** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */
26 $moderation_info = \Drupal::service('content_moderation.moderation_information');
27 if (!$moderation_info->shouldModerateEntitiesOfBundle($entity->getEntityType(), $entity->bundle())) {
31 // Existing entities will have a corresponding content_moderation_state
32 // entity associated with them.
33 if (!$entity->isNew() && $content_moderation_state = $this->loadContentModerationStateRevision($entity)) {
34 return $content_moderation_state->moderation_state->value;
37 // It is possible that the bundle does not exist at this point. For example,
38 // the node type form creates a fake Node entity to get default values.
39 // @see \Drupal\node\NodeTypeForm::form()
40 $workflow = $moderation_info->getWorkFlowForEntity($entity);
41 return $workflow ? $workflow->getTypePlugin()->getInitialState($workflow, $entity)->id() : NULL;
45 * Load the content moderation state revision associated with an entity.
47 * @param \Drupal\Core\Entity\ContentEntityInterface $entity
48 * The entity the content moderation state entity will be loaded from.
50 * @return \Drupal\content_moderation\ContentModerationStateInterface|null
51 * The content_moderation_state revision or FALSE if none exists.
53 protected function loadContentModerationStateRevision(ContentEntityInterface $entity) {
54 $moderation_info = \Drupal::service('content_moderation.moderation_information');
55 $content_moderation_storage = \Drupal::entityTypeManager()->getStorage('content_moderation_state');
57 $revisions = \Drupal::service('entity.query')->get('content_moderation_state')
58 ->condition('content_entity_type_id', $entity->getEntityTypeId())
59 ->condition('content_entity_id', $entity->id())
60 // Ensure the correct revision is loaded in scenarios where a revision is
62 ->condition('content_entity_revision_id', $entity->isNewRevision() ? $entity->getLoadedRevisionId() : $entity->getRevisionId())
63 ->condition('workflow', $moderation_info->getWorkflowForEntity($entity)->id())
65 ->sort('revision_id', 'DESC')
67 if (empty($revisions)) {
71 /** @var \Drupal\content_moderation\ContentModerationStateInterface $content_moderation_state */
72 $content_moderation_state = $content_moderation_storage->loadRevision(key($revisions));
73 if ($entity->getEntityType()->hasKey('langcode')) {
74 $langcode = $entity->language()->getId();
75 if (!$content_moderation_state->hasTranslation($langcode)) {
76 $content_moderation_state->addTranslation($langcode);
78 if ($content_moderation_state->language()->getId() !== $langcode) {
79 $content_moderation_state = $content_moderation_state->getTranslation($langcode);
82 return $content_moderation_state;
88 public function get($index) {
90 throw new \InvalidArgumentException('An entity can not have multiple moderation states at the same time.');
92 $this->computeModerationFieldItemList();
93 return isset($this->list[$index]) ? $this->list[$index] : NULL;
99 public function getIterator() {
100 $this->computeModerationFieldItemList();
101 return parent::getIterator();
105 * Recalculate the moderation field item list.
107 protected function computeModerationFieldItemList() {
108 // Compute the value of the moderation state.
110 if (!isset($this->list[$index]) || $this->list[$index]->isEmpty()) {
112 $moderation_state = $this->getModerationStateId();
113 // Do not store NULL values in the static cache.
114 if ($moderation_state) {
115 $this->list[$index] = $this->createItem($index, $moderation_state);