diff --git a/core/modules/content_moderation/src/EntityTypeInfo.php b/core/modules/content_moderation/src/EntityTypeInfo.php index 29ac68d4f8..3620c0abcd 100644 --- a/core/modules/content_moderation/src/EntityTypeInfo.php +++ b/core/modules/content_moderation/src/EntityTypeInfo.php @@ -13,6 +13,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Render\Markup; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; @@ -304,27 +305,39 @@ public function formAlter(array &$form, FormStateInterface $form_state, $form_id // - There are more than one translation languages. // - The entity has forward revisions. if (!$entity->isRevisionTranslationAffected() && count($entity->getTranslationLanguages()) > 1 && $this->moderationInfo->hasForwardRevision($entity)) { - $latest_revision = $this->getTranslationAffectedRevision($this->moderationInfo->getLatestRevision($entity->getEntityTypeId(), $entity->id())); - drupal_set_message(\Drupal::translation()->translate('It is not possible to save this @entity_type_label, publish or delete the latest draft revision to allow all workflow transitions.', ['@entity_type_label' => $entity->getEntityType()->getLabel(), '@latest_revision_edit_url' => $latest_revision->toUrl('edit-form', ['language' => $latest_revision->language()])->toString(), '@latest_revision_delete_url' => $latest_revision->toUrl('delete-form', ['language' => $latest_revision->language()])->toString()]), 'error'); + $latest_revision = $this->moderationInfo->getLatestRevision($entity->getEntityTypeId(), $entity->id()); + if ($entity->bundle()) { + $bundle_type_id = $entity->getEntityType()->getBundleEntityType(); + $bundle = $this->entityTypeManager->getStorage($bundle_type_id)->load($entity->bundle()); + $type_label = $bundle->label(); + } + else { + $type_label = $entity->getEntityType()->getLabel(); + } + $label = \Drupal::translation()->translate('Unable to save this @type_label.', ['@type_label' => $type_label]); + $message = \Drupal::translation()->translate('Publish or delete the latest draft revision to allow all workflow transitions.', ['@latest_revision_edit_url' => $latest_revision->toUrl('edit-form', ['language' => $latest_revision->language()])->toString(), '@latest_revision_delete_url' => $latest_revision->toUrl('delete-form', ['language' => $latest_revision->language()])->toString()]); + + drupal_set_message(Markup::create($label . ' ' . $message), 'error'); $form['actions']['#access'] = FALSE; $form['invalid_transitions'] = [ - 'rule' => [ - '#type' => 'item', - '#markup' => '
', - ], 'label' => [ '#type' => 'item', '#prefix' => '', - '#markup' => \Drupal::translation()->translate('It is not possible to save this @entity_type_label.', ['@entity_type_label' => $entity->getEntityType()->getLabel()]), + '#markup' => $label, '#suffix' => '', ], 'message' => [ '#type' => 'item', - '#markup' => \Drupal::translation()->translate('Publish or delete the latest draft revision to allow all workflow transitions.', ['@latest_revision_edit_url' => $latest_revision->toUrl('edit-form', ['language' => $latest_revision->language()])->toString(), '@latest_revision_delete_url' => $latest_revision->toUrl('delete-form', ['language' => $latest_revision->language()])->toString()]), + '#markup' => $message, ], '#weight' => 999, '#no_valid_transitions' => TRUE, ]; + + if ($form['footer']) { + $form['footer']['invalid_transitions'] = $form['invalid_transitions']; + unset($form['invalid_transitions']); + } } // Submit handler to redirect to the latest version, if available. diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php index e261954ab8..986ef3a4e5 100644 --- a/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php +++ b/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php @@ -343,7 +343,7 @@ public function testContentTranslationNodeForm() { $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]')); $this->assertTrue($this->xpath('//input[@value="Save and Archive (this translation)"]')); - // Create new moderated content in draft (revision 1). + // Create new moderated content. (revision 1). $this->drupalPostForm('node/add/moderated_content', [ 'title[0][value]' => 'Second moderated content', 'body[0][value]' => 'First version of the content.', @@ -369,6 +369,42 @@ public function testContentTranslationNodeForm() { $this->assertFalse($this->xpath('//input[@value="Save and Publish (this translation)"]')); $this->assertFalse($this->xpath('//input[@value="Save and Archive (this translation)"]')); $this->assertText('It is not possible to save this Content.'); + + // Create new moderated content (revision 1). + $this->drupalPostForm('node/add/moderated_content', [ + 'title[0][value]' => 'Third moderated content', + ], t('Save and Publish')); + + $node = $this->drupalGetNodeByTitle('Third moderated content'); + $this->assertTrue($node->language(), 'en'); + $edit_path = sprintf('node/%d/edit', $node->id()); + $translate_path = sprintf('node/%d/translations/add/en/fr', $node->id()); + + // Translate it, without updating data (revision 2). + $this->drupalGet($translate_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, [], t('Save and Create New Draft (this translation)')); + + // Add another draft for the translation (revision 2). + $this->drupalGet($translate_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, [], t('Save and Create New Draft (this translation)')); + + // It should be possible to create a further draft. + $this->drupalGet($translate_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)"]')); + + // Editing the original translation should also be possible. + $this->drupalGet($edit); + $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)"]')); } }