Version 1
[yaffs-website] / web / core / modules / content_moderation / src / Plugin / Field / ModerationStateFieldItemList.php
1 <?php
2
3 namespace Drupal\content_moderation\Plugin\Field;
4
5 use Drupal\Core\Entity\ContentEntityInterface;
6 use Drupal\Core\Field\FieldItemList;
7
8 /**
9  * A computed field that provides a content entity's moderation state.
10  *
11  * It links content entities to a moderation state configuration entity via a
12  * moderation state content entity.
13  */
14 class ModerationStateFieldItemList extends FieldItemList {
15
16   /**
17    * Gets the moderation state ID linked to a content entity revision.
18    *
19    * @return string|null
20    *   The moderation state ID linked to a content entity revision.
21    */
22   protected function getModerationStateId() {
23     $entity = $this->getEntity();
24
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())) {
28       return NULL;
29     }
30
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;
35     }
36
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;
42   }
43
44   /**
45    * Load the content moderation state revision associated with an entity.
46    *
47    * @param \Drupal\Core\Entity\ContentEntityInterface $entity
48    *   The entity the content moderation state entity will be loaded from.
49    *
50    * @return \Drupal\content_moderation\ContentModerationStateInterface|null
51    *   The content_moderation_state revision or FALSE if none exists.
52    */
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');
56
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
61       // being reverted.
62       ->condition('content_entity_revision_id', $entity->isNewRevision() ? $entity->getLoadedRevisionId() : $entity->getRevisionId())
63       ->condition('workflow', $moderation_info->getWorkflowForEntity($entity)->id())
64       ->allRevisions()
65       ->sort('revision_id', 'DESC')
66       ->execute();
67     if (empty($revisions)) {
68       return NULL;
69     }
70
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);
77       }
78       if ($content_moderation_state->language()->getId() !== $langcode) {
79         $content_moderation_state = $content_moderation_state->getTranslation($langcode);
80       }
81     }
82     return $content_moderation_state;
83   }
84
85   /**
86    * {@inheritdoc}
87    */
88   public function get($index) {
89     if ($index !== 0) {
90       throw new \InvalidArgumentException('An entity can not have multiple moderation states at the same time.');
91     }
92     $this->computeModerationFieldItemList();
93     return isset($this->list[$index]) ? $this->list[$index] : NULL;
94   }
95
96   /**
97    * {@inheritdoc}
98    */
99   public function getIterator() {
100     $this->computeModerationFieldItemList();
101     return parent::getIterator();
102   }
103
104   /**
105    * Recalculate the moderation field item list.
106    */
107   protected function computeModerationFieldItemList() {
108     // Compute the value of the moderation state.
109     $index = 0;
110     if (!isset($this->list[$index]) || $this->list[$index]->isEmpty()) {
111
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);
116       }
117     }
118   }
119
120 }