Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / core / modules / content_moderation / src / Entity / ContentModerationState.php
1 <?php
2
3 namespace Drupal\content_moderation\Entity;
4
5 use Drupal\Core\Entity\ContentEntityBase;
6 use Drupal\Core\Entity\EntityInterface;
7 use Drupal\Core\Entity\EntityTypeInterface;
8 use Drupal\Core\Field\BaseFieldDefinition;
9 use Drupal\Core\TypedData\TranslatableInterface;
10 use Drupal\user\UserInterface;
11
12 /**
13  * Defines the Content moderation state entity.
14  *
15  * @ContentEntityType(
16  *   id = "content_moderation_state",
17  *   label = @Translation("Content moderation state"),
18  *   label_singular = @Translation("content moderation state"),
19  *   label_plural = @Translation("content moderation states"),
20  *   label_count = @PluralTranslation(
21  *     singular = "@count content moderation state",
22  *     plural = "@count content moderation states"
23  *   ),
24  *   handlers = {
25  *     "storage_schema" = "Drupal\content_moderation\ContentModerationStateStorageSchema",
26  *     "views_data" = "\Drupal\views\EntityViewsData",
27  *     "access" = "Drupal\content_moderation\ContentModerationStateAccessControlHandler",
28  *   },
29  *   base_table = "content_moderation_state",
30  *   revision_table = "content_moderation_state_revision",
31  *   data_table = "content_moderation_state_field_data",
32  *   revision_data_table = "content_moderation_state_field_revision",
33  *   translatable = TRUE,
34  *   internal = TRUE,
35  *   entity_keys = {
36  *     "id" = "id",
37  *     "revision" = "revision_id",
38  *     "uuid" = "uuid",
39  *     "uid" = "uid",
40  *     "langcode" = "langcode",
41  *   }
42  * )
43  *
44  * @internal
45  *   This entity is marked internal because it should not be used directly to
46  *   alter the moderation state of an entity. Instead, the computed
47  *   moderation_state field should be set on the entity directly.
48  */
49 class ContentModerationState extends ContentEntityBase implements ContentModerationStateInterface {
50
51   /**
52    * {@inheritdoc}
53    */
54   public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
55     $fields = parent::baseFieldDefinitions($entity_type);
56
57     $fields['uid'] = BaseFieldDefinition::create('entity_reference')
58       ->setLabel(t('User'))
59       ->setDescription(t('The username of the entity creator.'))
60       ->setSetting('target_type', 'user')
61       ->setDefaultValueCallback('Drupal\content_moderation\Entity\ContentModerationState::getCurrentUserId')
62       ->setTranslatable(TRUE)
63       ->setRevisionable(TRUE);
64
65     $fields['workflow'] = BaseFieldDefinition::create('entity_reference')
66       ->setLabel(t('Workflow'))
67       ->setDescription(t('The workflow the moderation state is in.'))
68       ->setSetting('target_type', 'workflow')
69       ->setRequired(TRUE)
70       ->setRevisionable(TRUE);
71
72     $fields['moderation_state'] = BaseFieldDefinition::create('string')
73       ->setLabel(t('Moderation state'))
74       ->setDescription(t('The moderation state of the referenced content.'))
75       ->setRequired(TRUE)
76       ->setTranslatable(TRUE)
77       ->setRevisionable(TRUE);
78
79     $fields['content_entity_type_id'] = BaseFieldDefinition::create('string')
80       ->setLabel(t('Content entity type ID'))
81       ->setDescription(t('The ID of the content entity type this moderation state is for.'))
82       ->setRequired(TRUE)
83       ->setSetting('max_length', EntityTypeInterface::ID_MAX_LENGTH)
84       ->setRevisionable(TRUE);
85
86     $fields['content_entity_id'] = BaseFieldDefinition::create('integer')
87       ->setLabel(t('Content entity ID'))
88       ->setDescription(t('The ID of the content entity this moderation state is for.'))
89       ->setRequired(TRUE)
90       ->setRevisionable(TRUE);
91
92     $fields['content_entity_revision_id'] = BaseFieldDefinition::create('integer')
93       ->setLabel(t('Content entity revision ID'))
94       ->setDescription(t('The revision ID of the content entity this moderation state is for.'))
95       ->setRequired(TRUE)
96       ->setRevisionable(TRUE);
97
98     return $fields;
99   }
100
101   /**
102    * {@inheritdoc}
103    */
104   public function getOwner() {
105     return $this->get('uid')->entity;
106   }
107
108   /**
109    * {@inheritdoc}
110    */
111   public function getOwnerId() {
112     return $this->getEntityKey('uid');
113   }
114
115   /**
116    * {@inheritdoc}
117    */
118   public function setOwnerId($uid) {
119     $this->set('uid', $uid);
120     return $this;
121   }
122
123   /**
124    * {@inheritdoc}
125    */
126   public function setOwner(UserInterface $account) {
127     $this->set('uid', $account->id());
128     return $this;
129   }
130
131   /**
132    * Creates or updates an entity's moderation state whilst saving that entity.
133    *
134    * @param \Drupal\content_moderation\Entity\ContentModerationState $content_moderation_state
135    *   The content moderation entity content entity to create or save.
136    *
137    * @internal
138    *   This method should only be called as a result of saving the related
139    *   content entity.
140    */
141   public static function updateOrCreateFromEntity(ContentModerationState $content_moderation_state) {
142     $content_moderation_state->realSave();
143   }
144
145   /**
146    * Loads a content moderation state entity.
147    *
148    * @param \Drupal\Core\Entity\EntityInterface $entity
149    *   A moderated entity object.
150    *
151    * @return \Drupal\content_moderation\Entity\ContentModerationStateInterface|null
152    *   The related content moderation state or NULL if none could be found.
153    *
154    * @internal
155    *   This method should only be called by code directly handling the
156    *   ContentModerationState entity objects.
157    */
158   public static function loadFromModeratedEntity(EntityInterface $entity) {
159     $content_moderation_state = NULL;
160     $moderation_info = \Drupal::service('content_moderation.moderation_information');
161
162     if ($moderation_info->isModeratedEntity($entity)) {
163       /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
164       $storage = \Drupal::entityTypeManager()->getStorage('content_moderation_state');
165
166       $ids = $storage->getQuery()
167         ->condition('content_entity_type_id', $entity->getEntityTypeId())
168         ->condition('content_entity_id', $entity->id())
169         ->condition('workflow', $moderation_info->getWorkflowForEntity($entity)->id())
170         ->condition('content_entity_revision_id', $entity->getLoadedRevisionId())
171         ->allRevisions()
172         ->execute();
173
174       if ($ids) {
175         /** @var \Drupal\content_moderation\Entity\ContentModerationStateInterface $content_moderation_state */
176         $content_moderation_state = $storage->loadRevision(key($ids));
177       }
178     }
179
180     return $content_moderation_state;
181   }
182
183   /**
184    * Default value callback for the 'uid' base field definition.
185    *
186    * @see \Drupal\content_moderation\Entity\ContentModerationState::baseFieldDefinitions()
187    *
188    * @return array
189    *   An array of default values.
190    */
191   public static function getCurrentUserId() {
192     return [\Drupal::currentUser()->id()];
193   }
194
195   /**
196    * {@inheritdoc}
197    */
198   public function save() {
199     $related_entity = \Drupal::entityTypeManager()
200       ->getStorage($this->content_entity_type_id->value)
201       ->loadRevision($this->content_entity_revision_id->value);
202     if ($related_entity instanceof TranslatableInterface) {
203       $related_entity = $related_entity->getTranslation($this->activeLangcode);
204     }
205     $related_entity->moderation_state = $this->moderation_state;
206     return $related_entity->save();
207   }
208
209   /**
210    * Saves an entity permanently.
211    *
212    * When saving existing entities, the entity is assumed to be complete,
213    * partial updates of entities are not supported.
214    *
215    * @return int
216    *   Either SAVED_NEW or SAVED_UPDATED, depending on the operation performed.
217    *
218    * @throws \Drupal\Core\Entity\EntityStorageException
219    *   In case of failures an exception is thrown.
220    */
221   protected function realSave() {
222     return parent::save();
223   }
224
225   /**
226    * {@inheritdoc}
227    */
228   protected function getFieldsToSkipFromTranslationChangesCheck() {
229     $field_names = parent::getFieldsToSkipFromTranslationChangesCheck();
230     // We need to skip the parent entity revision ID, since that will always
231     // change on every save, otherwise every translation would be marked as
232     // affected regardless of actual changes.
233     $field_names[] = 'content_entity_revision_id';
234     return $field_names;
235   }
236
237 }