From 55e309fc33895bf2d629825b08486c40d07212fc Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Fri, 14 Apr 2017 07:36:40 +0100 Subject: [PATCH] Issue #2862988 by timmillwood, catch: EntityOperations::entityPresave doesn't always set the correct default revision --- .../src/EntityOperations.php | 30 ++--- .../src/Kernel/DefaultRevisionStateTest.php | 109 ++++++++++++++++++ 2 files changed, 125 insertions(+), 14 deletions(-) create mode 100644 core/modules/content_moderation/tests/src/Kernel/DefaultRevisionStateTest.php diff --git a/core/modules/content_moderation/src/EntityOperations.php b/core/modules/content_moderation/src/EntityOperations.php index af87f6fc329c..5c8d5c0f0872 100644 --- a/core/modules/content_moderation/src/EntityOperations.php +++ b/core/modules/content_moderation/src/EntityOperations.php @@ -105,9 +105,10 @@ public function entityPresave(EntityInterface $entity) { /** @var \Drupal\content_moderation\ContentModerationState $current_state */ $current_state = $workflow->getState($entity->moderation_state->value); - // This entity is default if it is new, the default revision, or the - // default revision is not published. + // This entity is default if it is new, a new translation, the default + // revision, or the default revision is not published. $update_default_revision = $entity->isNew() + || $entity->isNewTranslation() || $current_state->isDefaultRevisionState() || !$this->isDefaultRevisionPublished($entity, $workflow); @@ -250,8 +251,8 @@ public function entityView(array &$build, EntityInterface $entity, EntityViewDis * Check if the default revision for the given entity is published. * * The default revision is the same as the entity retrieved by "default" from - * the storage handler. If the entity is translated, use the default revision - * of the same language as the given entity. + * the storage handler. If the entity is translated, check if any of the + * translations are published. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity being saved. @@ -262,21 +263,22 @@ public function entityView(array &$build, EntityInterface $entity, EntityViewDis * TRUE if the default revision is published. FALSE otherwise. */ protected function isDefaultRevisionPublished(EntityInterface $entity, WorkflowInterface $workflow) { - $storage = $this->entityTypeManager->getStorage($entity->getEntityTypeId()); - $default_revision = $storage->load($entity->id()); + $default_revision = $this->entityTypeManager->getStorage($entity->getEntityTypeId())->load($entity->id()); - // Ensure we are comparing the same translation as the current entity. + // Ensure we are checking all translations of the default revision. if ($default_revision instanceof TranslatableInterface && $default_revision->isTranslatable()) { - // If there is no translation, then there is no default revision and is - // therefore not published. - if (!$default_revision->hasTranslation($entity->language()->getId())) { - return FALSE; + // Loop through each language that has a translation. + foreach ($default_revision->getTranslationLanguages() as $language) { + // Load the translated revision. + $language_revision = $default_revision->getTranslation($language->getId()); + // Return TRUE if a translation with a published state is found. + if ($workflow->getState($language_revision->moderation_state->value)->isPublishedState()) { + return TRUE; + } } - - $default_revision = $default_revision->getTranslation($entity->language()->getId()); } - return $default_revision && $workflow->getState($default_revision->moderation_state->value)->isPublishedState(); + return $workflow->getState($default_revision->moderation_state->value)->isPublishedState(); } } diff --git a/core/modules/content_moderation/tests/src/Kernel/DefaultRevisionStateTest.php b/core/modules/content_moderation/tests/src/Kernel/DefaultRevisionStateTest.php new file mode 100644 index 000000000000..274e8b525dc1 --- /dev/null +++ b/core/modules/content_moderation/tests/src/Kernel/DefaultRevisionStateTest.php @@ -0,0 +1,109 @@ +<?php + +namespace Drupal\Tests\content_moderation\Kernel; + +use Drupal\KernelTests\KernelTestBase; +use Drupal\language\Entity\ConfigurableLanguage; +use Drupal\node\Entity\Node; +use Drupal\node\Entity\NodeType; +use Drupal\workflows\Entity\Workflow; + +/** + * Tests the correct default revision is set. + * + * @group content_moderation + */ +class DefaultRevisionStateTest extends KernelTestBase { + + /** + * {@inheritdoc} + */ + public static $modules = [ + 'entity_test', + 'node', + 'block_content', + 'content_moderation', + 'user', + 'system', + 'language', + 'content_translation', + 'text', + 'workflows', + ]; + + /** + * @var \Drupal\Core\Entity\EntityTypeManager + */ + protected $entityTypeManager; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $this->installSchema('node', 'node_access'); + $this->installEntitySchema('node'); + $this->installEntitySchema('user'); + $this->installEntitySchema('entity_test_with_bundle'); + $this->installEntitySchema('entity_test_rev'); + $this->installEntitySchema('entity_test_mulrevpub'); + $this->installEntitySchema('block_content'); + $this->installEntitySchema('content_moderation_state'); + $this->installConfig('content_moderation'); + + $this->entityTypeManager = $this->container->get('entity_type.manager'); + } + + /** + * Tests a translatable Node. + */ + public function testMultilingual() { + // Enable French. + ConfigurableLanguage::createFromLangcode('fr')->save(); + $node_type = NodeType::create([ + 'type' => 'example', + ]); + $node_type->save(); + + $this->container->get('content_translation.manager')->setEnabled('node', 'example', TRUE); + + $workflow = Workflow::load('editorial'); + $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example'); + $workflow->save(); + + $english_node = Node::create([ + 'type' => 'example', + 'title' => 'Test title', + ]); + // Revision 1 (en). + $english_node + ->setUnpublished() + ->save(); + $this->assertEquals('draft', $english_node->moderation_state->value); + $this->assertFalse($english_node->isPublished()); + $this->assertTrue($english_node->isDefaultRevision()); + + // Revision 2 (fr) + $french_node = $english_node->addTranslation('fr', ['title' => 'French title']); + $french_node->moderation_state->value = 'published'; + $french_node->save(); + $this->assertTrue($french_node->isPublished()); + $this->assertTrue($french_node->isDefaultRevision()); + + // Revision 3 (fr) + $node = Node::load($english_node->id())->getTranslation('fr'); + $node->moderation_state->value = 'draft'; + $node->save(); + $this->assertFalse($node->isPublished()); + $this->assertFalse($node->isDefaultRevision()); + + // Revision 4 (en) + $latest_revision = $this->entityTypeManager->getStorage('node')->loadRevision(3); + $latest_revision->moderation_state->value = 'draft'; + $latest_revision->save(); + $this->assertFalse($latest_revision->isPublished()); + $this->assertFalse($latest_revision->isDefaultRevision()); + } + +} -- GitLab