diff --git a/core/modules/content_moderation/config/install/workflows.workflow.editorial.yml b/core/modules/content_moderation/config/install/workflows.workflow.editorial.yml
index d8daa51..9625065 100644
--- a/core/modules/content_moderation/config/install/workflows.workflow.editorial.yml
+++ b/core/modules/content_moderation/config/install/workflows.workflow.editorial.yml
@@ -23,7 +23,7 @@ transitions:
to: archived
weight: 2
archived_draft:
- label: 'Restore to Draft'
+ label: 'Restore to draft'
from:
- archived
to: draft
@@ -35,7 +35,7 @@ transitions:
to: published
weight: 4
create_new_draft:
- label: 'Create New Draft'
+ label: 'Create new draft'
from:
- draft
- published
diff --git a/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php b/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php
index e64dc97..5350c01 100644
--- a/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php
+++ b/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php
@@ -2,6 +2,10 @@
namespace Drupal\content_moderation\Plugin\Field\FieldWidget;
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\AppendCommand;
+use Drupal\Core\Ajax\InsertCommand;
+use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
@@ -126,52 +130,62 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
$transitions = $this->validator->getValidTransitions($entity, $this->currentUser);
$target_states = [];
+ $transition_labels = [];
foreach ($transitions as $transition) {
- $target_states[$transition->to()->id()] = $transition->label();
+ $target_states[$transition->to()->id()] = $transition->to()->label();
+ $transition_labels[$transition->to()->id()] = $transition->label();
}
// @todo https://www.drupal.org/node/2779933 write a test for this.
$element += [
- '#type' => 'select',
- '#options' => $target_states,
- '#default_value' => isset($target_states[$default->id()]) ? $default->id() : NULL,
- '#empty_option' => '- Select moderation state -',
- '#key_column' => $this->column,
+ '#type' => 'container',
+ 'current' => [
+ '#type' => 'item',
+ '#wrapper_attributes' => ['class' => ['current-moderation-state', 'container-inline']],
+ '#markup' => '
' . t('Current moderation state') . '
' . $default->label(),
+ ],
+ 'state' => [
+ '#type' => 'select',
+ '#options' => $target_states,
+ '#default_value' => isset($target_states[$default->id()]) ? $default->id() : NULL,
+ '#empty_option' => '- Select new state -',
+ '#key_column' => $this->column,
+ '#transitions' => $transition_labels,
+ '#description' => isset($transition_labels[$default->id()]) ? $transition_labels[$default->id()] . ' when saved.' : '',
+ '#ajax' => [
+ 'callback' => [get_class($this), 'change'],
+ 'event' => 'change',
+ 'wrapper' => 'edit-moderation-state-0-state--description',
+ 'method' => 'html',
+ ]
+ ]
];
- $element['#element_validate'][] = array(get_class($this), 'validateElement');
+ $element['#element_validate'][] = [get_class($this), 'validateElement'];
return $element;
}
/**
- * {@inheritdoc}
+ * @param array $element
+ * @param \Drupal\Core\Form\FormStateInterface $form_state
+ *
+ * @return array
*/
- public static function validateElement(array $element, FormStateInterface $form_state) {
- if (empty($element['#value'])) {
- $form_state->setError($element, t('Please select a moderation state.'));
- return;
- }
- $form_state->setValueForElement($element, [$element['#key_column'] => $element['#value']]);
+ public static function change(array $element, FormStateInterface $form_state) {
+ $state = $form_state->getValue('moderation_state')[0]['value'];
+ $transition_labels = $element['moderation_state']['widget'][0]['state']['#transitions'];
+ return ['#plain_text' => isset($transition_labels[$state]) ? $transition_labels[$state] . ' when saved.' : ''];
}
-
/**
- * Entity builder updating the node moderation state with the submitted value.
- *
- * @param string $entity_type_id
- * The entity type identifier.
- * @param \Drupal\Core\Entity\ContentEntityInterface $entity
- * The entity updated with the submitted values.
- * @param array $form
- * The complete form array.
- * @param \Drupal\Core\Form\FormStateInterface $form_state
- * The current state of the form.
+ * {@inheritdoc}
*/
- public static function updateStatus($entity_type_id, ContentEntityInterface $entity, array $form, FormStateInterface $form_state) {
- $element = $form_state->getTriggeringElement();
- if (isset($element['#moderation_state'])) {
- $entity->moderation_state->value = $element['#moderation_state'];
+ public static function validateElement(array $element, FormStateInterface $form_state) {
+ if (empty($element['state']['#value'])) {
+ $form_state->setError($element, t('Please select a moderation state.'));
+ return;
}
+ $form_state->setValueForElement($element, [$element['state']['#key_column'] => $element['state']['#value']]);
}
/**
diff --git a/core/modules/content_moderation/src/Tests/ModerationFormTest.php b/core/modules/content_moderation/src/Tests/ModerationFormTest.php
index 778bc9a..9522c78 100644
--- a/core/modules/content_moderation/src/Tests/ModerationFormTest.php
+++ b/core/modules/content_moderation/src/Tests/ModerationFormTest.php
@@ -34,7 +34,7 @@ public function testModerationForm() {
$this->drupalPostForm('node/add/moderated_content', [
'title[0][value]' => 'Some moderated content',
'body[0][value]' => 'First version of the content.',
- 'moderation_state[0]' => 'draft',
+ 'moderation_state[0][state]' => 'draft',
], t('Save'));
$node = $this->drupalGetNodeByTitle('Some moderated content');
@@ -51,19 +51,19 @@ public function testModerationForm() {
// Try saving with no moderation state.
$this->drupalGet($edit_path);
- $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0"]'), 'draft');
+ $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0-state"]'), 'draft');
$this->drupalPostForm($edit_path, [
'body[0][value]' => 'Second version of the content.',
- 'moderation_state[0]' => '',
+ 'moderation_state[0][state]' => '',
], t('Save'));
$this->assertText('Please select a moderation state.');
// Update the draft.
$this->drupalGet($edit_path);
- $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0"]'), 'draft');
+ $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0-state"]'), 'draft');
$this->drupalPostForm($edit_path, [
'body[0][value]' => 'Second version of the content.',
- 'moderation_state[0]' => 'draft',
+ 'moderation_state[0][state]' => 'draft',
], t('Save'));
// The latest version page should not show, because there is still no
@@ -73,26 +73,26 @@ public function testModerationForm() {
// Publish the draft.
$this->drupalGet($edit_path);
- $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0"]'), 'draft');
+ $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0-state"]'), 'draft');
$this->drupalPostForm($edit_path, [
'body[0][value]' => 'Third version of the content.',
- 'moderation_state[0]' => 'published',
+ 'moderation_state[0][state]' => 'published',
], t('Save'));
// Archive the published entity.
$this->drupalGet($edit_path);
- $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0"]'), 'published');
+ $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0-state"]'), 'published');
$this->drupalPostForm($edit_path, [
'body[0][value]' => 'Fourth version of the content.',
- 'moderation_state[0]' => 'archived',
+ 'moderation_state[0][state]' => 'archived',
], t('Save'));
// Then back to Published so we can add a forward revision.
$this->drupalGet($edit_path);
- $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0"]'), '');
+ $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0-state"]'), '');
$this->drupalPostForm($edit_path, [
'body[0][value]' => 'Fifth version of the content.',
- 'moderation_state[0]' => 'published',
+ 'moderation_state[0][state]' => 'published',
], t('Save'));
// The published view should not have a moderation form, because it is the
@@ -108,10 +108,10 @@ public function testModerationForm() {
// Make a forward revision.
$this->drupalGet($edit_path);
- $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0"]'), 'published');
+ $this->assertFieldsByValue($this->xpath('//select[@id="edit-moderation-state-0-state"]'), 'published');
$this->drupalPostForm($edit_path, [
'body[0][value]' => 'Sixth version of the content.',
- 'moderation_state[0]' => 'draft',
+ 'moderation_state[0][state]' => 'draft',
], t('Save'));
// The published view should not have a moderation form, because it is the
diff --git a/core/modules/content_moderation/src/Tests/ModerationStateBlockTest.php b/core/modules/content_moderation/src/Tests/ModerationStateBlockTest.php
index 9990f60..9f0b6a4 100644
--- a/core/modules/content_moderation/src/Tests/ModerationStateBlockTest.php
+++ b/core/modules/content_moderation/src/Tests/ModerationStateBlockTest.php
@@ -67,7 +67,7 @@ public function testCustomBlockModeration() {
$body = 'Body of moderated block';
$edit = [
'info[0][value]' => 'Moderated block',
- 'moderation_state[0]' => 'draft',
+ 'moderation_state[0][state]' => 'draft',
'body[0][value]' => $body,
];
$this->drupalPostForm('block/add', $edit, t('Save'));
@@ -92,7 +92,7 @@ public function testCustomBlockModeration() {
$updated_body = 'This is the new body value';
$edit = [
'body[0][value]' => $updated_body,
- 'moderation_state[0]' => 'draft'
+ 'moderation_state[0][state]' => 'draft'
];
$this->drupalPostForm('block/' . $block->id(), $edit, t('Save'));
$this->assertText(t('basic Moderated block has been updated.'));
@@ -105,14 +105,14 @@ public function testCustomBlockModeration() {
// Publish the block so we can create a forward revision.
$this->drupalPostForm('block/' . $block->id(), [
- 'moderation_state[0]' => 'published'
+ 'moderation_state[0][state]' => 'published'
], t('Save'));
// Create a forward revision.
$forward_revision_body = 'This is the forward revision body value';
$edit = [
'body[0][value]' => $forward_revision_body,
- 'moderation_state[0]' => 'draft'
+ 'moderation_state[0][state]' => 'draft'
];
$this->drupalPostForm('block/' . $block->id(), $edit, t('Save'));
$this->assertText(t('basic Moderated block has been updated.'));
diff --git a/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php b/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php
index 3652ddc..1861872 100644
--- a/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php
+++ b/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php
@@ -28,7 +28,7 @@ protected function setUp() {
public function testCreatingContent() {
$this->drupalPostForm('node/add/moderated_content', [
'title[0][value]' => 'moderated content',
- 'moderation_state[0]' => 'draft'
+ 'moderation_state[0][state]' => 'draft'
], t('Save'));
$node = $this->getNodeByTitle('moderated content');
if (!$node) {
@@ -39,7 +39,7 @@ public function testCreatingContent() {
$path = 'node/' . $node->id() . '/edit';
// Set up published revision.
$this->drupalPostForm($path, [
- 'moderation_state[0]' => 'published'
+ 'moderation_state[0][state]' => 'published'
], t('Save'));
\Drupal::entityTypeManager()->getStorage('node')->resetCache([$node->id()]);
/* @var \Drupal\node\NodeInterface $node */
@@ -83,7 +83,7 @@ public function testFormSaveDestination() {
$this->drupalPostForm('node/add/moderated_content', [
'title[0][value]' => 'Some moderated content',
'body[0][value]' => 'First version of the content.',
- 'moderation_state[0]' => 'draft'
+ 'moderation_state[0][state]' => 'draft'
], t('Save'));
$node = $this->drupalGetNodeByTitle('Some moderated content');
@@ -98,7 +98,7 @@ public function testFormSaveDestination() {
// URL, but viewing the second revision.
$this->drupalPostForm($edit_path, [
'body[0][value]' => 'Second version of the content.',
- 'moderation_state[0]' => 'draft'
+ 'moderation_state[0][state]' => 'draft'
], t('Save'));
$this->assertUrl(Url::fromRoute('entity.node.canonical', ['node' => $node->id()]));
$this->assertText('Second version of the content.');
@@ -107,7 +107,7 @@ public function testFormSaveDestination() {
// canonical URL.
$this->drupalPostForm($edit_path, [
'body[0][value]' => 'Third version of the content.',
- 'moderation_state[0]' => 'published'
+ 'moderation_state[0][state]' => 'published'
], t('Save'));
$this->assertUrl(Url::fromRoute('entity.node.canonical', ['node' => $node->id()]));
$this->assertText('Third version of the content.');
@@ -116,7 +116,7 @@ public function testFormSaveDestination() {
// version" tab.
$this->drupalPostForm($edit_path, [
'body[0][value]' => 'Fourth version of the content.',
- 'moderation_state[0]' => 'draft'
+ 'moderation_state[0][state]' => 'draft'
], t('Save'));
$this->assertUrl(Url::fromRoute('entity.node.latest_version', ['node' => $node->id()]));
$this->assertText('Fourth version of the content.');
diff --git a/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php b/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php
index f0dd6cc..f72e6c5 100644
--- a/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php
+++ b/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php
@@ -67,7 +67,7 @@ public function testEnablingOnExistingContent() {
$this->assertLinkByHref('node/' . $node->id() . '/edit');
$this->drupalGet('node/' . $node->id() . '/edit');
$this->assertResponse(200);
- $this->assertRaw('Create New Draft');
+ $this->assertRaw('Draft');
$this->assertRaw('Publish');
}
diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php
index 92b6a3b..3523e98 100644
--- a/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php
@@ -53,7 +53,7 @@ public function testTranslateModeratedContent() {
$edit = [
'title[0][value]' => 'Published English node',
'langcode[0][value]' => 'en',
- 'moderation_state[0]' => 'published'
+ 'moderation_state[0][state]' => 'published'
];
$this->drupalPostForm('node/add/article', $edit, t('Save'));
$this->assertText(t('Article Published English node has been created.'));
@@ -64,7 +64,7 @@ public function testTranslateModeratedContent() {
$this->clickLink(t('Add'));
$edit = [
'title[0][value]' => 'French node Draft',
- 'moderation_state[0]' => 'draft'
+ 'moderation_state[0][state]' => 'draft'
];
$this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
// Here the error has occurred "The website encountered an unexpected error.
@@ -76,7 +76,7 @@ public function testTranslateModeratedContent() {
$edit = [
'title[0][value]' => 'English node',
'langcode[0][value]' => 'en',
- 'moderation_state[0]' => 'draft',
+ 'moderation_state[0][state]' => 'draft',
];
$this->drupalPostForm('node/add/article', $edit, t('Save'));
$this->assertText(t('Article English node has been created.'));
@@ -87,7 +87,7 @@ public function testTranslateModeratedContent() {
$this->clickLink(t('Add'));
$edit = [
'title[0][value]' => 'French node',
- 'moderation_state[0]' => 'draft'
+ 'moderation_state[0][state]' => 'draft'
];
$this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
$this->assertText(t('Article French node has been updated.'));
@@ -96,7 +96,7 @@ public function testTranslateModeratedContent() {
// Publish the English article and check that the translation stays
// unpublished.
$this->drupalPostForm('node/' . $english_node->id() . '/edit', [
- 'moderation_state[0]' => 'published',
+ 'moderation_state[0][state]' => 'published',
], t('Save (this translation)'));
$this->assertText(t('Article English node has been updated.'));
$english_node = $this->drupalGetNodeByTitle('English node', TRUE);
@@ -112,7 +112,7 @@ public function testTranslateModeratedContent() {
// the translation first.
$edit = [
'title[0][value]' => 'Another node',
- 'moderation_state[0]' => 'draft',
+ 'moderation_state[0][state]' => 'draft',
];
$this->drupalPostForm('node/add/article', $edit, t('Save'));
$this->assertText(t('Article Another node has been created.'));
@@ -123,7 +123,7 @@ public function testTranslateModeratedContent() {
$this->clickLink(t('Add'));
$edit = [
'title[0][value]' => 'Translated node',
- 'moderation_state[0]' => 'draft',
+ 'moderation_state[0][state]' => 'draft',
];
$this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
$this->assertText(t('Article Translated node has been updated.'));
@@ -132,7 +132,7 @@ public function testTranslateModeratedContent() {
// Publish the translation and check that the source language version stays
// unpublished.
$this->drupalPostForm('fr/node/' . $english_node->id() . '/edit', [
- 'moderation_state[0]' => 'published',
+ 'moderation_state[0][state]' => 'published',
], t('Save (this translation)'));
$this->assertText(t('Article Translated node has been updated.'));
$english_node = $this->drupalGetNodeByTitle('Another node', TRUE);
@@ -145,7 +145,7 @@ public function testTranslateModeratedContent() {
// Now check that we can create a new draft of the translation.
$edit = [
'title[0][value]' => 'New draft of translated node',
- 'moderation_state[0]' => 'draft',
+ 'moderation_state[0][state]' => 'draft',
];
$this->drupalPostForm('fr/node/' . $english_node->id() . '/edit', $edit, t('Save (this translation)'));
$this->assertText(t('Article New draft of translated node has been updated.'));
@@ -169,7 +169,7 @@ public function testTranslateModeratedContent() {
// Publish the English article before testing the archive transition.
$this->drupalPostForm('node/' . $english_node->id() . '/edit', [
- 'moderation_state[0]' => 'published',
+ 'moderation_state[0][state]' => 'published',
], t('Save (this translation)'));
$this->assertText(t('Article Another node has been updated.'));
$english_node = $this->drupalGetNodeByTitle('Another node', TRUE);
@@ -177,11 +177,11 @@ public function testTranslateModeratedContent() {
// Archive the node and its translation.
$this->drupalPostForm('node/' . $english_node->id() . '/edit', [
- 'moderation_state[0]' => 'archived',
+ 'moderation_state[0][state]' => 'archived',
], t('Save (this translation)'));
$this->assertText(t('Article Another node has been updated.'));
$this->drupalPostForm('fr/node/' . $english_node->id() . '/edit', [
- 'moderation_state[0]' => 'archived',
+ 'moderation_state[0][state]' => 'archived',
], t('Save (this translation)'));
$this->assertText(t('Article New draft of translated node has been updated.'));
$english_node = $this->drupalGetNodeByTitle('Another node', TRUE);
@@ -195,7 +195,7 @@ public function testTranslateModeratedContent() {
// after creating a forward french revision.
$edit = [
'title[0][value]' => 'An english node',
- 'moderation_state[0]' => 'draft',
+ 'moderation_state[0][state]' => 'draft',
];
$this->drupalPostForm('node/add/article', $edit, t('Save'));
$this->assertText(t('Article An english node has been created.'));
@@ -207,7 +207,7 @@ public function testTranslateModeratedContent() {
$this->clickLink(t('Add'));
$edit = [
'title[0][value]' => 'A french node',
- 'moderation_state[0]' => 'published',
+ 'moderation_state[0][state]' => 'published',
];
$this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
$english_node = $this->drupalGetNodeByTitle('An english node', TRUE);
@@ -217,7 +217,7 @@ public function testTranslateModeratedContent() {
// Create a forward revision
$this->drupalPostForm('fr/node/' . $english_node->id() . '/edit', [
- 'moderation_state[0]' => 'draft',
+ 'moderation_state[0][state]' => 'draft',
], t('Save (this translation)'));
$english_node = $this->drupalGetNodeByTitle('An english node', TRUE);
$french_node = $english_node->getTranslation('fr');
@@ -227,7 +227,7 @@ public function testTranslateModeratedContent() {
// Publish the english node and the default french node not the latest
// french node should be used.
$this->drupalPostForm('/node/' . $english_node->id() . '/edit', [
- 'moderation_state[0]' => 'published',
+ 'moderation_state[0][state]' => 'published',
], t('Save (this translation)'));
$english_node = $this->drupalGetNodeByTitle('An english node', TRUE);
$french_node = $english_node->getTranslation('fr');
diff --git a/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php b/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
index facab6f..6849289 100644
--- a/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
@@ -28,7 +28,7 @@ public function testPageAccess() {
// Create a node to test with.
$this->drupalPostForm('node/add/moderated_content', [
'title[0][value]' => 'moderated content',
- 'moderation_state[0]' => 'draft'
+ 'moderation_state[0][state]' => 'draft'
], t('Save'));
$node = $this->getNodeByTitle('moderated content');
if (!$node) {
@@ -41,7 +41,7 @@ public function testPageAccess() {
// Publish the node.
$this->drupalPostForm($edit_path, [
- 'moderation_state[0]' => 'published'
+ 'moderation_state[0][state]' => 'published'
], t('Save'));
// Ensure access works correctly for anonymous users.
@@ -59,7 +59,7 @@ public function testPageAccess() {
$this->drupalLogin($this->adminUser);
$this->drupalPostForm($edit_path, [
'title[0][value]' => 'moderated content revised',
- 'moderation_state[0]' => 'draft'
+ 'moderation_state[0][state]' => 'draft'
], t('Save'));
// Now make a new user and verify that the new user's access is correct.