comparison core/modules/content_moderation/src/EntityOperations.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 1fec387a4317
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 namespace Drupal\content_moderation;
4
5 use Drupal\content_moderation\Entity\ContentModerationState as ContentModerationStateEntity;
6 use Drupal\content_moderation\Entity\ContentModerationStateInterface;
7 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
8 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
9 use Drupal\Core\Entity\EntityInterface;
10 use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
11 use Drupal\Core\Entity\EntityTypeManagerInterface;
12 use Drupal\Core\Form\FormBuilderInterface;
13 use Drupal\content_moderation\Form\EntityModerationForm;
14 use Symfony\Component\DependencyInjection\ContainerInterface;
15
16 /**
17 * Defines a class for reacting to entity events.
18 *
19 * @internal
20 */
21 class EntityOperations implements ContainerInjectionInterface {
22
23 /**
24 * The Moderation Information service.
25 *
26 * @var \Drupal\content_moderation\ModerationInformationInterface
27 */
28 protected $moderationInfo;
29
30 /**
31 * The Entity Type Manager service.
32 *
33 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
34 */
35 protected $entityTypeManager;
36
37 /**
38 * The Form Builder service.
39 *
40 * @var \Drupal\Core\Form\FormBuilderInterface
41 */
42 protected $formBuilder;
43
44 /**
45 * The entity bundle information service.
46 *
47 * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
48 */
49 protected $bundleInfo;
50
51 /**
52 * Constructs a new EntityOperations object.
53 *
54 * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_info
55 * Moderation information service.
56 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
57 * Entity type manager service.
58 * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
59 * The form builder.
60 * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info
61 * The entity bundle information service.
62 */
63 public function __construct(ModerationInformationInterface $moderation_info, EntityTypeManagerInterface $entity_type_manager, FormBuilderInterface $form_builder, EntityTypeBundleInfoInterface $bundle_info) {
64 $this->moderationInfo = $moderation_info;
65 $this->entityTypeManager = $entity_type_manager;
66 $this->formBuilder = $form_builder;
67 $this->bundleInfo = $bundle_info;
68 }
69
70 /**
71 * {@inheritdoc}
72 */
73 public static function create(ContainerInterface $container) {
74 return new static(
75 $container->get('content_moderation.moderation_information'),
76 $container->get('entity_type.manager'),
77 $container->get('form_builder'),
78 $container->get('entity_type.bundle.info')
79 );
80 }
81
82 /**
83 * Acts on an entity and set published status based on the moderation state.
84 *
85 * @param \Drupal\Core\Entity\EntityInterface $entity
86 * The entity being saved.
87 *
88 * @see hook_entity_presave()
89 */
90 public function entityPresave(EntityInterface $entity) {
91 if (!$this->moderationInfo->isModeratedEntity($entity)) {
92 return;
93 }
94
95 if ($entity->moderation_state->value) {
96 $workflow = $this->moderationInfo->getWorkflowForEntity($entity);
97 /** @var \Drupal\content_moderation\ContentModerationState $current_state */
98 $current_state = $workflow->getTypePlugin()
99 ->getState($entity->moderation_state->value);
100
101 // This entity is default if it is new, a new translation, the default
102 // revision, or the default revision is not published.
103 $update_default_revision = $entity->isNew()
104 || $entity->isNewTranslation()
105 || $current_state->isDefaultRevisionState()
106 || !$this->moderationInfo->isDefaultRevisionPublished($entity);
107
108 // Fire per-entity-type logic for handling the save process.
109 $this->entityTypeManager
110 ->getHandler($entity->getEntityTypeId(), 'moderation')
111 ->onPresave($entity, $update_default_revision, $current_state->isPublishedState());
112 }
113 }
114
115 /**
116 * @param \Drupal\Core\Entity\EntityInterface $entity
117 * The entity that was just saved.
118 *
119 * @see hook_entity_insert()
120 */
121 public function entityInsert(EntityInterface $entity) {
122 if ($this->moderationInfo->isModeratedEntity($entity)) {
123 $this->updateOrCreateFromEntity($entity);
124 }
125 }
126
127 /**
128 * @param \Drupal\Core\Entity\EntityInterface $entity
129 * The entity that was just saved.
130 *
131 * @see hook_entity_update()
132 */
133 public function entityUpdate(EntityInterface $entity) {
134 if ($this->moderationInfo->isModeratedEntity($entity)) {
135 $this->updateOrCreateFromEntity($entity);
136 }
137 }
138
139 /**
140 * Creates or updates the moderation state of an entity.
141 *
142 * @param \Drupal\Core\Entity\EntityInterface $entity
143 * The entity to update or create a moderation state for.
144 */
145 protected function updateOrCreateFromEntity(EntityInterface $entity) {
146 /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
147 $entity_revision_id = $entity->getRevisionId();
148 $workflow = $this->moderationInfo->getWorkflowForEntity($entity);
149 $content_moderation_state = ContentModerationStateEntity::loadFromModeratedEntity($entity);
150
151 if (!($content_moderation_state instanceof ContentModerationStateInterface)) {
152 $storage = $this->entityTypeManager->getStorage('content_moderation_state');
153 $content_moderation_state = $storage->create([
154 'content_entity_type_id' => $entity->getEntityTypeId(),
155 'content_entity_id' => $entity->id(),
156 // Make sure that the moderation state entity has the same language code
157 // as the moderated entity.
158 'langcode' => $entity->language()->getId(),
159 ]);
160 $content_moderation_state->workflow->target_id = $workflow->id();
161 }
162 elseif ($content_moderation_state->content_entity_revision_id->value != $entity_revision_id) {
163 // If a new revision of the content has been created, add a new content
164 // moderation state revision.
165 $content_moderation_state->setNewRevision(TRUE);
166 }
167
168 // Sync translations.
169 if ($entity->getEntityType()->hasKey('langcode')) {
170 $entity_langcode = $entity->language()->getId();
171 if (!$content_moderation_state->hasTranslation($entity_langcode)) {
172 $content_moderation_state->addTranslation($entity_langcode);
173 }
174 if ($content_moderation_state->language()->getId() !== $entity_langcode) {
175 $content_moderation_state = $content_moderation_state->getTranslation($entity_langcode);
176 }
177 }
178
179 // Create the ContentModerationState entity for the inserted entity.
180 $moderation_state = $entity->moderation_state->value;
181 /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
182 if (!$moderation_state) {
183 $moderation_state = $workflow->getTypePlugin()->getInitialState($entity)->id();
184 }
185
186 // @todo what if $entity->moderation_state is null at this point?
187 $content_moderation_state->set('content_entity_revision_id', $entity_revision_id);
188 $content_moderation_state->set('moderation_state', $moderation_state);
189 ContentModerationStateEntity::updateOrCreateFromEntity($content_moderation_state);
190 }
191
192 /**
193 * @param \Drupal\Core\Entity\EntityInterface $entity
194 * The entity being deleted.
195 *
196 * @see hook_entity_delete()
197 */
198 public function entityDelete(EntityInterface $entity) {
199 $content_moderation_state = ContentModerationStateEntity::loadFromModeratedEntity($entity);
200 if ($content_moderation_state) {
201 $content_moderation_state->delete();
202 }
203 }
204
205 /**
206 * @param \Drupal\Core\Entity\EntityInterface $entity
207 * The entity revision being deleted.
208 *
209 * @see hook_entity_revision_delete()
210 */
211 public function entityRevisionDelete(EntityInterface $entity) {
212 /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
213 if (!$entity->isDefaultRevision()) {
214 $content_moderation_state = ContentModerationStateEntity::loadFromModeratedEntity($entity);
215 if ($content_moderation_state) {
216 $this->entityTypeManager
217 ->getStorage('content_moderation_state')
218 ->deleteRevision($content_moderation_state->getRevisionId());
219 }
220 }
221 }
222
223 /**
224 * @param \Drupal\Core\Entity\EntityInterface $translation
225 * The entity translation being deleted.
226 *
227 * @see hook_entity_translation_delete()
228 */
229 public function entityTranslationDelete(EntityInterface $translation) {
230 /** @var \Drupal\Core\Entity\ContentEntityInterface $translation */
231 if (!$translation->isDefaultTranslation()) {
232 $langcode = $translation->language()->getId();
233 $content_moderation_state = ContentModerationStateEntity::loadFromModeratedEntity($translation);
234 if ($content_moderation_state && $content_moderation_state->hasTranslation($langcode)) {
235 $content_moderation_state->removeTranslation($langcode);
236 ContentModerationStateEntity::updateOrCreateFromEntity($content_moderation_state);
237 }
238 }
239 }
240
241 /**
242 * Act on entities being assembled before rendering.
243 *
244 * @see hook_entity_view()
245 * @see EntityFieldManagerInterface::getExtraFields()
246 */
247 public function entityView(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
248 if (!$this->moderationInfo->isModeratedEntity($entity)) {
249 return;
250 }
251 if (!$this->moderationInfo->isLatestRevision($entity)) {
252 return;
253 }
254 if ($this->moderationInfo->isLiveRevision($entity)) {
255 return;
256 }
257 // Don't display the moderation form when when:
258 // - The revision is not translation affected.
259 // - There are more than one translation languages.
260 // - The entity has pending revisions.
261 if (!$this->moderationInfo->isPendingRevisionAllowed($entity)) {
262 return;
263 }
264
265 $component = $display->getComponent('content_moderation_control');
266 if ($component) {
267 $build['content_moderation_control'] = $this->formBuilder->getForm(EntityModerationForm::class, $entity);
268 }
269 }
270
271 }