X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=web%2Fcore%2Fmodules%2Fcontent_moderation%2Fsrc%2FEntityOperations.php;h=8c6d3325089840426b950cfebeaef7f20fe03ad8;hb=1c1cb0980bfa6caf0c24cce671b6bb541dc87583;hp=a7fcf7e8d925564688513fc409c42631850f2330;hpb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;p=yaffs-website diff --git a/web/core/modules/content_moderation/src/EntityOperations.php b/web/core/modules/content_moderation/src/EntityOperations.php index a7fcf7e8d..8c6d33250 100644 --- a/web/core/modules/content_moderation/src/EntityOperations.php +++ b/web/core/modules/content_moderation/src/EntityOperations.php @@ -5,12 +5,16 @@ namespace Drupal\content_moderation; use Drupal\content_moderation\Entity\ContentModerationState as ContentModerationStateEntity; use Drupal\content_moderation\Entity\ContentModerationStateInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityPublishedInterface; use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormBuilderInterface; use Drupal\content_moderation\Form\EntityModerationForm; +use Drupal\Core\Routing\RouteBuilderInterface; +use Drupal\workflows\Entity\Workflow; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -48,6 +52,13 @@ class EntityOperations implements ContainerInjectionInterface { */ protected $bundleInfo; + /** + * The router builder service. + * + * @var \Drupal\Core\Routing\RouteBuilderInterface + */ + protected $routerBuilder; + /** * Constructs a new EntityOperations object. * @@ -59,12 +70,15 @@ class EntityOperations implements ContainerInjectionInterface { * The form builder. * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info * The entity bundle information service. + * @param \Drupal\Core\Routing\RouteBuilderInterface $router_builder + * The router builder service. */ - public function __construct(ModerationInformationInterface $moderation_info, EntityTypeManagerInterface $entity_type_manager, FormBuilderInterface $form_builder, EntityTypeBundleInfoInterface $bundle_info) { + public function __construct(ModerationInformationInterface $moderation_info, EntityTypeManagerInterface $entity_type_manager, FormBuilderInterface $form_builder, EntityTypeBundleInfoInterface $bundle_info, RouteBuilderInterface $router_builder) { $this->moderationInfo = $moderation_info; $this->entityTypeManager = $entity_type_manager; $this->formBuilder = $form_builder; $this->bundleInfo = $bundle_info; + $this->routerBuilder = $router_builder; } /** @@ -75,7 +89,8 @@ class EntityOperations implements ContainerInjectionInterface { $container->get('content_moderation.moderation_information'), $container->get('entity_type.manager'), $container->get('form_builder'), - $container->get('entity_type.bundle.info') + $container->get('entity_type.bundle.info'), + $container->get('router.builder') ); } @@ -98,10 +113,9 @@ class EntityOperations implements ContainerInjectionInterface { $current_state = $workflow->getTypePlugin() ->getState($entity->moderation_state->value); - // This entity is default if it is new, a new translation, the default - // revision, or the default revision is not published. + // This entity is default if it is new, the default revision, or the + // default revision is not published. $update_default_revision = $entity->isNew() - || $entity->isNewTranslation() || $current_state->isDefaultRevisionState() || !$this->moderationInfo->isDefaultRevisionPublished($entity); @@ -134,6 +148,12 @@ class EntityOperations implements ContainerInjectionInterface { if ($this->moderationInfo->isModeratedEntity($entity)) { $this->updateOrCreateFromEntity($entity); } + // When updating workflow settings for Content Moderation, we need to + // rebuild routes as we may be enabling new entity types and the related + // entity forms. + elseif ($entity instanceof Workflow && $entity->getTypePlugin()->getPluginId() == 'content_moderation') { + $this->routerBuilder->setRebuildNeeded(); + } } /** @@ -147,9 +167,10 @@ class EntityOperations implements ContainerInjectionInterface { $entity_revision_id = $entity->getRevisionId(); $workflow = $this->moderationInfo->getWorkflowForEntity($entity); $content_moderation_state = ContentModerationStateEntity::loadFromModeratedEntity($entity); + /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */ + $storage = $this->entityTypeManager->getStorage('content_moderation_state'); if (!($content_moderation_state instanceof ContentModerationStateInterface)) { - $storage = $this->entityTypeManager->getStorage('content_moderation_state'); $content_moderation_state = $storage->create([ 'content_entity_type_id' => $entity->getEntityTypeId(), 'content_entity_id' => $entity->id(), @@ -159,23 +180,29 @@ class EntityOperations implements ContainerInjectionInterface { ]); $content_moderation_state->workflow->target_id = $workflow->id(); } - elseif ($content_moderation_state->content_entity_revision_id->value != $entity_revision_id) { - // If a new revision of the content has been created, add a new content - // moderation state revision. - $content_moderation_state->setNewRevision(TRUE); - } // Sync translations. if ($entity->getEntityType()->hasKey('langcode')) { $entity_langcode = $entity->language()->getId(); - if (!$content_moderation_state->hasTranslation($entity_langcode)) { - $content_moderation_state->addTranslation($entity_langcode); + if ($entity->isDefaultTranslation()) { + $content_moderation_state->langcode = $entity_langcode; } - if ($content_moderation_state->language()->getId() !== $entity_langcode) { - $content_moderation_state = $content_moderation_state->getTranslation($entity_langcode); + else { + if (!$content_moderation_state->hasTranslation($entity_langcode)) { + $content_moderation_state->addTranslation($entity_langcode); + } + if ($content_moderation_state->language()->getId() !== $entity_langcode) { + $content_moderation_state = $content_moderation_state->getTranslation($entity_langcode); + } } } + // If a new revision of the content has been created, add a new content + // moderation state revision. + if (!$content_moderation_state->isNew() && $content_moderation_state->content_entity_revision_id->value != $entity_revision_id) { + $content_moderation_state = $storage->createRevision($content_moderation_state, $entity->isDefaultRevision()); + } + // Create the ContentModerationState entity for the inserted entity. $moderation_state = $entity->moderation_state->value; /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ @@ -183,7 +210,6 @@ class EntityOperations implements ContainerInjectionInterface { $moderation_state = $workflow->getTypePlugin()->getInitialState($entity)->id(); } - // @todo what if $entity->moderation_state is null at this point? $content_moderation_state->set('content_entity_revision_id', $entity_revision_id); $content_moderation_state->set('moderation_state', $moderation_state); ContentModerationStateEntity::updateOrCreateFromEntity($content_moderation_state); @@ -245,27 +271,53 @@ class EntityOperations implements ContainerInjectionInterface { * @see EntityFieldManagerInterface::getExtraFields() */ public function entityView(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) { + /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ if (!$this->moderationInfo->isModeratedEntity($entity)) { return; } - if (!$this->moderationInfo->isLatestRevision($entity)) { + if (isset($entity->in_preview) && $entity->in_preview) { + return; + } + // If the component is not defined for this display, we have nothing to do. + if (!$display->getComponent('content_moderation_control')) { return; } - if ($this->moderationInfo->isLiveRevision($entity)) { + // The moderation form should be displayed only when viewing the latest + // (translation-affecting) revision, unless it was created as published + // default revision. + if (($entity->isDefaultRevision() || $entity->wasDefaultRevision()) && $this->isPublished($entity)) { return; } - // Don't display the moderation form when when: - // - The revision is not translation affected. - // - There are more than one translation languages. - // - The entity has pending revisions. - if (!$this->moderationInfo->isPendingRevisionAllowed($entity)) { + if (!$entity->isLatestRevision() && !$entity->isLatestTranslationAffectedRevision()) { return; } - $component = $display->getComponent('content_moderation_control'); - if ($component) { - $build['content_moderation_control'] = $this->formBuilder->getForm(EntityModerationForm::class, $entity); + $build['content_moderation_control'] = $this->formBuilder->getForm(EntityModerationForm::class, $entity); + } + + /** + * Checks if the entity is published. + * + * This method is optimized to not have to unnecessarily load the moderation + * state and workflow if it is not required. + * + * @param \Drupal\Core\Entity\ContentEntityInterface $entity + * The entity to check. + * + * @return bool + * TRUE if the entity is published, FALSE otherwise. + */ + protected function isPublished(ContentEntityInterface $entity) { + // If the entity implements EntityPublishedInterface directly, check that + // first, otherwise fall back to check through the workflow state. + if ($entity instanceof EntityPublishedInterface) { + return $entity->isPublished(); + } + if ($moderation_state = $entity->get('moderation_state')->value) { + $workflow = $this->moderationInfo->getWorkflowForEntity($entity); + return $workflow->getTypePlugin()->getState($moderation_state)->isPublishedState(); } + return FALSE; } }