diff --git a/core/modules/content_moderation/src/StateTransitionValidation.php b/core/modules/content_moderation/src/StateTransitionValidation.php index c4138e1..e8e2a4c 100644 --- a/core/modules/content_moderation/src/StateTransitionValidation.php +++ b/core/modules/content_moderation/src/StateTransitionValidation.php @@ -43,9 +43,22 @@ public function getValidTransitions(ContentEntityInterface $entity, AccountInter $current_state = $entity->moderation_state->value ? $workflow->getState($entity->moderation_state->value) : $workflow->getInitialState(); return array_filter($current_state->getTransitions(), function(Transition $transition) use ($workflow, $user, $entity) { - return $user->hasPermission('use ' . $workflow->id() . ' transition ' . $transition->id()) - && !(count($entity->getTranslationLanguages()) > 1 - && !($entity->isDefaultRevision() || $entity->isRevisionTranslationAffected())); + // Don't show the transition if the user doesn't have permission to use + // it. + if (!$user->hasPermission('use ' . $workflow->id() . ' transition ' . $transition->id())) { + return FALSE; + } + + // For entities with more than one translation and forward revisions we + // want to only allow specific transitions. + if (count($entity->getTranslationLanguages()) > 1 && $this->moderationInfo->hasForwardRevision($entity)) { + // The entity needs to be the latest and translation affected, or be + // going from and to the same default state. + return ($this->moderationInfo->isLatestRevision($entity) && $entity->isRevisionTranslationAffected()) + || (($entity->isDefaultRevision() && $transition->to()->isDefaultRevisionState()) || (!$entity->isDefaultRevision() && !$transition->to()->isDefaultRevisionState())); + } + + return TRUE; }); } diff --git a/core/modules/content_moderation/src/Tests/ModerationFormTest.php b/core/modules/content_moderation/src/Tests/ModerationFormTest.php index 9e72da2..07d221d 100644 --- a/core/modules/content_moderation/src/Tests/ModerationFormTest.php +++ b/core/modules/content_moderation/src/Tests/ModerationFormTest.php @@ -176,7 +176,38 @@ public function testContentTranslationNodeForm() { 'body[0][value]' => 'Forth version of the content.', ], t('Save and Create New Draft (this translation)')); + // Publish the french forward revision + $this->drupalGet('fr/' . $edit_path); + $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]')); + $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]')); + $this->assertFalse($this->xpath('//input[@value="Save and Archive (this translation)"]')); + $this->drupalPostForm(NULL, [ + 'body[0][value]' => 'Fifth version of the content.', + ], t('Save and Publish (this translation)')); + + // Now we can publish the english. + $this->drupalGet($edit_path); + $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]')); + $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]')); + $this->assertFalse($this->xpath('//input[@value="Save and Archive (this translation)"]')); + $this->drupalPostForm(NULL, [ + 'body[0][value]' => 'Sixth version of the content.', + ], t('Save and Publish (this translation)')); + + // Make sure we're allowed to create a forward french revision. + $this->drupalGet('fr/' . $edit_path); + $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]')); + $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]')); + $this->assertTrue($this->xpath('//input[@value="Save and Archive (this translation)"]')); + // Add a english forward revision. + $this->drupalGet($edit_path); + $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]')); + $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]')); + $this->assertTrue($this->xpath('//input[@value="Save and Archive (this translation)"]')); + $this->drupalPostForm(NULL, [ + 'body[0][value]' => 'Seventh version of the content.', + ], t('Save and Create New Draft (this translation)')); } }