Commit c53b3228 authored by catch's avatar catch

Issue #2068063 by timmillwood, Berdir, tduong, Manuel Garcia, nlisgo,...

Issue #2068063 by timmillwood, Berdir, tduong, Manuel Garcia, nlisgo, yongt9412, esod, lauriii, jonathan1055, vijaycs85, yoroy, amit.drupal, tkoleary, ifrik, Bojhan, xjm, tstoeckler, amateescu: Change "Save and keep un-/published" buttons to a "Published" checkbox and an included "Save" button
parent 19854be6
......@@ -33,8 +33,7 @@ public static function publishedBaseFieldDefinitions(EntityTypeInterface $entity
}
return [$entity_type->getKey('published') => BaseFieldDefinition::create('boolean')
->setLabel(new TranslatableMarkup('Publishing status'))
->setDescription(new TranslatableMarkup('A boolean indicating the published state.'))
->setLabel(new TranslatableMarkup('Published'))
->setRevisionable(TRUE)
->setTranslatable(TRUE)
->setDefaultValue(TRUE)];
......
......@@ -33,6 +33,13 @@ content:
weight: 15
region: content
third_party_settings: { }
status:
type: boolean_checkbox
settings:
display_label: true
weight: 120
region: content
third_party_settings: { }
sticky:
type: boolean_checkbox
settings:
......
......@@ -741,8 +741,8 @@ public function testBookNavigationBlockOnUnpublishedBook() {
$this->drupalPlaceBlock('book_navigation', ['block_mode' => 'book pages']);
// Unpublish book node.
$edit = [];
$this->drupalPostForm('node/' . $this->book->id() . '/edit', $edit, t('Save and unpublish'));
$edit = ['status[value]' => FALSE];
$this->drupalPostForm('node/' . $this->book->id() . '/edit', $edit, t('Save'));
// Test node page.
$this->drupalGet('node/' . $this->book->id());
......
......@@ -86,14 +86,14 @@ public function testCommentStatusFieldAccessStatus() {
$assert->fieldNotExists('comment[0][status]');
$this->submitForm([
'title[0][value]' => 'Node 1',
], t('Save and publish'));
], t('Save'));
$assert->fieldExists('subject[0][value]');
$this->drupalLogin($this->commentAdmin);
$this->drupalGet('node/add/article');
$assert->fieldExists('comment[0][status]');
$this->submitForm([
'title[0][value]' => 'Node 2',
], t('Save and publish'));
], t('Save'));
$assert->fieldExists('subject[0][value]');
}
......
......@@ -14,6 +14,8 @@
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
......@@ -166,6 +168,27 @@ function content_moderation_node_access(NodeInterface $node, $operation, Account
return $access_result;
}
/**
* Implements hook_entity_field_access().
*/
function content_moderation_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
if ($items && $operation === 'edit') {
/** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */
$moderation_info = Drupal::service('content_moderation.moderation_information');
$entity_type = \Drupal::entityTypeManager()->getDefinition($field_definition->getTargetEntityTypeId());
$entity = $items->getEntity();
// Deny edit access to the published field if the entity is being moderated.
if ($entity_type->hasKey('published') && $moderation_info->isModeratedEntity($entity) && $entity->moderation_state && $field_definition->getName() == $entity_type->getKey('published')) {
return AccessResult::forbidden();
}
}
return AccessResult::neutral();
}
/**
* Implements hook_theme().
*/
......
......@@ -62,7 +62,7 @@ public function testCreatingContent() {
// Create a new node.
$this->drupalPostForm('node/add/moderated_content', [
'title[0][value]' => 'non-moderated content',
], t('Save and publish'));
], t('Save'));
$node = $this->getNodeByTitle('non-moderated content');
if (!$node) {
......
......@@ -18,10 +18,10 @@ public function testNotModerated() {
$this->assertText('The content type Not moderated has been added.');
$this->grantUserPermissionToCreateContentOfType($this->adminUser, 'not_moderated');
$this->drupalGet('node/add/not_moderated');
$this->assertRaw('Save as unpublished');
$this->assertRaw('Save');
$this->drupalPostForm(NULL, [
'title[0][value]' => 'Test',
], t('Save and publish'));
], t('Save'));
$this->assertText('Not moderated Test has been created.');
}
......@@ -53,7 +53,7 @@ public function testEnablingOnExistingContent() {
$this->drupalGet('node/add/not_moderated');
$this->drupalPostForm(NULL, [
'title[0][value]' => 'Test',
], t('Save and publish'));
], t('Save'));
$this->assertText('Not moderated Test has been created.');
// Now enable moderation state.
......
......@@ -46,7 +46,7 @@ class NodeAccessTest extends ModerationStateTestBase {
protected function setUp() {
parent::setUp();
$this->drupalLogin($this->adminUser);
$this->createContentTypeFromUi('Moderated content', 'moderated_content', TRUE);
$this->createContentTypeFromUi('Moderated content', 'moderated_content', FALSE);
$this->grantUserPermissionToCreateContentOfType($this->adminUser, 'moderated_content');
// Rebuild permissions because hook_node_grants() is implemented by the
......@@ -60,8 +60,20 @@ protected function setUp() {
public function testPageAccess() {
$this->drupalLogin($this->adminUser);
// Access the node form before moderation is enabled, the publication state
// should now be visible.
$this->drupalGet('node/add/moderated_content');
$this->assertSession()->fieldExists('Published');
// Now enable the workflow.
$this->enableModerationThroughUi('moderated_content', 'editorial');
// Access that the status field is no longer visible.
$this->drupalGet('node/add/moderated_content');
$this->assertSession()->fieldNotExists('Published');
// Create a node to test with.
$this->drupalPostForm('node/add/moderated_content', [
$this->drupalPostForm(NULL, [
'title[0][value]' => 'moderated content',
], t('Save and Create New Draft'));
$node = $this->getNodeByTitle('moderated content');
......
......@@ -73,12 +73,12 @@ public function testLanguageChange() {
$edit = [
'title[0][value]' => 'english_title',
];
$this->drupalPostForm(NULL, $edit, t('Save and publish'));
$this->drupalPostForm(NULL, $edit, t('Save'));
// Create a translation in French.
$this->clickLink('Translate');
$this->clickLink('Add');
$this->drupalPostForm(NULL, [], t('Save and keep published (this translation)'));
$this->drupalPostForm(NULL, [], t('Save (this translation)'));
$this->clickLink('Translate');
// Edit English translation.
......@@ -90,7 +90,7 @@ public function testLanguageChange() {
'files[field_image_field_0]' => $images->uri,
];
$this->drupalPostForm(NULL, $edit, t('Upload'));
$this->drupalPostForm(NULL, ['field_image_field[0][alt]' => 'alternative_text'], t('Save and keep published (this translation)'));
$this->drupalPostForm(NULL, ['field_image_field[0][alt]' => 'alternative_text'], t('Save (this translation)'));
// Check that the translation languages are correct.
$node = $this->getNodeByTitle('english_title');
......@@ -109,13 +109,13 @@ public function testTitleDoesNotChangesOnChangingLanguageWidgetAndTriggeringAjax
'title[0][value]' => 'english_title',
'test_field_only_en_fr' => 'node created',
];
$this->drupalPostForm(NULL, $edit, t('Save and publish'));
$this->drupalPostForm(NULL, $edit, t('Save'));
$this->assertEqual('node created', \Drupal::state()->get('test_field_only_en_fr'));
// Create a translation in French.
$this->clickLink('Translate');
$this->clickLink('Add');
$this->drupalPostForm(NULL, [], t('Save and keep published (this translation)'));
$this->drupalPostForm(NULL, [], t('Save (this translation)'));
$this->clickLink('Translate');
// Edit English translation.
......@@ -137,7 +137,7 @@ public function testTitleDoesNotChangesOnChangingLanguageWidgetAndTriggeringAjax
'langcode[0][value]' => 'en',
'field_image_field[0][alt]' => 'alternative_text'
];
$this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
$this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
// Check that the translation languages are correct.
$node = $this->getNodeByTitle('english_title');
......
......@@ -62,7 +62,7 @@ public function testEntityReferenceXSS() {
'title[0][value]' => $this->randomString(),
'entity_reference_test' => $referenced_node->id()
];
$this->drupalPostForm(NULL, $edit, 'Save and publish');
$this->drupalPostForm(NULL, $edit, 'Save');
$this->assertEscaped($referenced_node->getTitle());
// Test the options_buttons type.
......
......@@ -138,7 +138,7 @@ protected function doTestNodeWithFileWithoutTitle() {
$label = 'Save';
}
else {
$label = 'Save and publish';
$label = 'Save';
}
$this->drupalPostForm(NULL, $edit, $label);
$this->assertResponse(200);
......
......@@ -77,7 +77,7 @@ public function testNodeDisplay() {
// Turn the "display" option off and check that the file is no longer displayed.
$edit = [$field_name . '[0][display]' => FALSE];
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
$this->assertNoRaw($default_output, 'Field is hidden when "display" option is unchecked.');
......@@ -87,7 +87,7 @@ public function testNodeDisplay() {
$field_name . '[0][description]' => $description,
$field_name . '[0][display]' => TRUE,
];
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
$this->assertText($description);
// Ensure the filename in the link's title attribute is escaped.
......@@ -167,7 +167,7 @@ public function testDescToggle() {
'title[0][value]' => $title,
'files[field_' . $field_name . '_0]' => drupal_realpath($file->uri),
];
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
$node = $this->drupalGetNodeByTitle($title);
$this->drupalGet('node/' . $node->id() . '/edit');
$this->assertText(t('The description may be used as the label of the link to the file.'));
......
......@@ -63,7 +63,7 @@ public function testRevisions() {
// Save a new version of the node without any changes.
// Check that the file is still the same as the previous revision.
$this->drupalPostForm('node/' . $nid . '/edit', ['revision' => '1'], t('Save and keep published'));
$this->drupalPostForm('node/' . $nid . '/edit', ['revision' => '1'], t('Save'));
$node_storage->resetCache([$nid]);
$node = $node_storage->load($nid);
$node_file_r3 = File::load($node->{$field_name}->target_id);
......
......@@ -227,7 +227,7 @@ public function uploadNodeFiles(array $files, $field_name, $nid_or_type, $new_re
$edit[$name][] = $file_path;
}
}
$this->drupalPostForm("node/$nid/edit", $edit, t('Save and keep published'));
$this->drupalPostForm("node/$nid/edit", $edit, t('Save'));
return $nid;
}
......@@ -243,7 +243,7 @@ public function removeNodeFile($nid, $new_revision = TRUE) {
];
$this->drupalPostForm('node/' . $nid . '/edit', [], t('Remove'));
$this->drupalPostForm(NULL, $edit, t('Save and keep published'));
$this->drupalPostForm(NULL, $edit, t('Save'));
}
/**
......@@ -256,7 +256,7 @@ public function replaceNodeFile($file, $field_name, $nid, $new_revision = TRUE)
];
$this->drupalPostForm('node/' . $nid . '/edit', [], t('Remove'));
$this->drupalPostForm(NULL, $edit, t('Save and keep published'));
$this->drupalPostForm(NULL, $edit, t('Save'));
}
/**
......
......@@ -29,7 +29,7 @@ public function testRequired() {
// Try to post a new node without uploading a file.
$edit = [];
$edit['title[0][value]'] = $this->randomMachineName();
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
$this->assertRaw(t('@title field is required.', ['@title' => $field->getLabel()]), 'Node save failed when required file field was empty.');
// Create a new node with the uploaded file.
......@@ -50,7 +50,7 @@ public function testRequired() {
// Try to post a new node without uploading a file in the multivalue field.
$edit = [];
$edit['title[0][value]'] = $this->randomMachineName();
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
$this->assertRaw(t('@title field is required.', ['@title' => $field->getLabel()]), 'Node save failed when required multiple value file field was empty.');
// Create a new node with the uploaded file into the multivalue field.
......
......@@ -121,7 +121,7 @@ public function testSingleValuedWidget() {
$this->assertTrue(isset($label[0]), 'Label for upload found.');
// Save the node and ensure it does not have the file.
$this->drupalPostForm(NULL, [], t('Save and keep published'));
$this->drupalPostForm(NULL, [], t('Save'));
$node_storage->resetCache([$nid]);
$node = $node_storage->load($nid);
$this->assertTrue(empty($node->{$field_name}->target_id), 'File was successfully removed from the node.');
......@@ -238,8 +238,7 @@ public function testMultiValuedWidget() {
$this->assertNoFieldByXPath('//input[@type="submit"]', t('Remove'), format_string('After removing all files, there is no "Remove" button displayed (JSMode=%type).', ['%type' => $type]));
// Save the node and ensure it does not have any files.
$this->drupalPostForm(NULL, ['title[0][value]' => $this->randomMachineName()], t('Save and publish'));
$matches = [];
$this->drupalPostForm(NULL, ['title[0][value]' => $this->randomMachineName()], t('Save'));
preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
$nid = $matches[1];
$node_storage->resetCache([$nid]);
......@@ -368,7 +367,7 @@ public function testPrivateFileComment() {
$edit = [
'title[0][value]' => $this->randomMachineName(),
];
$this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
$this->drupalPostForm('node/add/article', $edit, t('Save'));
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
// Add a comment with a file.
......@@ -402,7 +401,8 @@ public function testPrivateFileComment() {
// Unpublishes node.
$this->drupalLogin($this->adminUser);
$this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and unpublish'));
$edit = ['status[value]' => FALSE];
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
// Ensures normal user can no longer download the file.
$this->drupalLogin($user);
......
......@@ -72,10 +72,10 @@ public function testPrivateFile() {
// Attempt to reuse the file when editing a node.
$edit = [];
$edit['title[0][value]'] = $this->randomMachineName();
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
$new_node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
$edit[$field_name . '[0][fids]'] = $node_file->id();
$this->drupalPostForm('node/' . $new_node->id() . '/edit', $edit, t('Save and keep published'));
$this->drupalPostForm('node/' . $new_node->id() . '/edit', $edit, t('Save'));
// Make sure the form submit failed - we stayed on the edit form.
$this->assertUrl('node/' . $new_node->id() . '/edit');
// Check that we got the expected constraint form error.
......@@ -86,7 +86,7 @@ public function testPrivateFile() {
$edit = [];
$edit['title[0][value]'] = $this->randomMachineName();
$edit[$field_name . '[0][fids]'] = $node_file->id();
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
$new_node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
$this->assertTrue(empty($new_node), 'Node was not created.');
$this->assertUrl('node/add/' . $type_name);
......
......@@ -60,7 +60,7 @@ public function testFilterHooks() {
$edit['title[0][value]'] = $title;
$edit['body[0][value]'] = $this->randomMachineName(32);
$edit['body[0][format]'] = $format_id;
$this->drupalPostForm("node/add/{$type->id()}", $edit, t('Save and publish'));
$this->drupalPostForm("node/add/{$type->id()}", $edit, t('Save'));
$this->assertText(t('@type @title has been created.', ['@type' => $type_name, '@title' => $title]));
// Disable the text format.
......
......@@ -42,6 +42,13 @@ content:
weight: 15
region: content
third_party_settings: { }
status:
type: boolean_checkbox
settings:
display_label: true
weight: 120
region: content
third_party_settings: { }
sticky:
type: boolean_checkbox
settings:
......
......@@ -170,7 +170,7 @@ protected function createForumTopics($count = 5) {
];
// Create the forum topic, preselecting the forum ID via a URL parameter.
$this->drupalPostForm('node/add/forum', $edit, t('Save and publish'), ['query' => ['forum_id' => 1]]);
$this->drupalPostForm('node/add/forum', $edit, t('Save'), ['query' => ['forum_id' => 1]]);
$topics[] = $title;
}
......
......@@ -44,7 +44,7 @@ public function testForumIndexStatus() {
$this->drupalGet("forum/$tid");
$this->clickLink(t('Add new @node_type', ['@node_type' => 'Forum topic']));
$this->assertUrl('node/add/forum', ['query' => ['forum_id' => $tid]]);
$this->drupalPostForm(NULL, $edit, t('Save and publish'));
$this->drupalPostForm(NULL, $edit, t('Save'));
// Check that the node exists in the database.
$node = $this->drupalGetNodeByTitle($title);
......@@ -71,7 +71,8 @@ public function testForumIndexStatus() {
// Unpublish the node.
$this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and unpublish'));
$edit = ['status[value]' => FALSE];
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
$this->drupalGet('node/' . $node->id());
$this->assertText(t('Access denied'), 'Unpublished node is no longer accessible.');
......
......@@ -282,7 +282,7 @@ public function testImageFieldSettings() {
$field_name . '[0][alt]' => $image['#alt'],
$field_name . '[0][title]' => $image['#title'],
];
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
$default_output = str_replace("\n", NULL, $renderer->renderRoot($image));
$this->assertRaw($default_output, 'Image displayed using user supplied alt and title attributes.');
......@@ -292,7 +292,7 @@ public function testImageFieldSettings() {
$field_name . '[0][alt]' => $this->randomMachineName($test_size),
$field_name . '[0][title]' => $this->randomMachineName($test_size),
];
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
$schema = $field->getFieldStorageDefinition()->getSchema();
$this->assertRaw(t('Alternative text cannot be longer than %max characters but is currently %length characters long.', [
'%max' => $schema['columns']['alt']['length'],
......@@ -314,9 +314,9 @@ public function testImageFieldSettings() {
$edit = [
'files[' . $field_name . '_1][]' => drupal_realpath($test_image->uri),
];
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
// Add the required alt text.
$this->drupalPostForm(NULL, [$field_name . '[1][alt]' => $alt], t('Save and keep published'));
$this->drupalPostForm(NULL, [$field_name . '[1][alt]' => $alt], t('Save'));
$this->assertText(format_string('Article @title has been updated.', ['@title' => $node->getTitle()]));
// Assert ImageWidget::process() calls FieldWidget::process().
......
......@@ -90,10 +90,10 @@ public function uploadNodeImage($image, $field_name, $type, $alt = '') {
'title[0][value]' => $this->randomMachineName(),
];
$edit['files[' . $field_name . '_0]'] = drupal_realpath($image->uri);
$this->drupalPostForm('node/add/' . $type, $edit, t('Save and publish'));
$this->drupalPostForm('node/add/' . $type, $edit, t('Save'));
if ($alt) {
// Add alt text.
$this->drupalPostForm(NULL, [$field_name . '[0][alt]' => $alt], t('Save and publish'));
$this->drupalPostForm(NULL, [$field_name . '[0][alt]' => $alt], t('Save'));
}
// Retrieve ID of the newly created node from the current URL.
......
......@@ -119,7 +119,7 @@ public function testRequiredAttributes() {
$edit = [
'title[0][value]' => $this->randomMachineName(),
];
$this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
$this->drupalPostForm('node/add/article', $edit, t('Save'));
$this->assertNoText(t('Alternative text field is required.'));
$this->assertNoText(t('Title field is required.'));
......@@ -132,7 +132,7 @@ public function testRequiredAttributes() {
$edit = [
'title[0][value]' => $this->randomMachineName(),
];
$this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
$this->drupalPostForm('node/add/article', $edit, t('Save'));
$this->assertNoText(t('Alternative text field is required.'));
$this->assertNoText(t('Title field is required.'));
......
......@@ -85,7 +85,7 @@ public function testFragmentLink() {
// Only enter a title in the node add form and leave the body field empty.
$edit = ['edit-title-0-value' => 'Test inline form error with CKEditor'];
$this->submitForm($edit, 'Save and publish');
$this->submitForm($edit, 'Save');
// Add a bottom margin to the title field to be sure the body field is not
// visible. PhantomJS runs with a resolution of 1024x768px.
......
......@@ -70,7 +70,7 @@ public function testDomain() {
'title[0][value]' => 'Test',
'path[0][alias]' => '/eng/test',
];
$this->drupalPostForm('node/add/article', $nodeValues, $this->t('Save and publish'));
$this->drupalPostForm('node/add/article', $nodeValues, $this->t('Save'));
$this->assertSession()->statusCodeEquals(200);
}
......
......@@ -134,8 +134,7 @@ public function testMenuNodeFormWidget() {
$this->drupalGet('test-page');
$this->assertNoLink($node_title);
// Use not only the save button, but also the two special buttons:
// 'Save and publish' as well as 'Save and keep published'.
// Make sure the menu links only appear when the node is published.
// These buttons just appear for 'administer nodes' users.
$admin_user = $this->drupalCreateUser([
'access administration pages',
......@@ -146,21 +145,20 @@ public function testMenuNodeFormWidget() {
'edit any page content',
]);
$this->drupalLogin($admin_user);
foreach (['Save and unpublish' => FALSE, 'Save and keep unpublished' => FALSE, 'Save and publish' => TRUE, 'Save and keep published' => TRUE] as $submit => $visible) {
$edit = [
'menu[enabled]' => 1,
'menu[title]' => $node_title,
];
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, $submit);
// Assert that the link exists.
$this->drupalGet('test-page');
if ($visible) {
$this->assertLink($node_title, 0, 'Found a menu link after submitted with ' . $submit);
}
else {
$this->assertNoLink($node_title, 'Found no menu link after submitted with ' . $submit);
}
}
// Assert that the link does not exist if unpublished.
$edit = [
'menu[enabled]' => 1,
'menu[title]' => $node_title,
'status[value]' => FALSE,
];
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save');
$this->drupalGet('test-page');
$this->assertNoLink($node_title, 'Found no menu link with the node unpublished');
// Assert that the link exists if published.
$edit['status[value]'] = TRUE;
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save');
$this->drupalGet('test-page');
$this->assertLink($node_title, 0, 'Found a menu link with the node published');
// Log back in as normal user.
$this->drupalLogin($this->editor);
......
<?php
/**
* @file
* Post update functions for Node.
*/
use Drupal\Core\Entity\Entity\EntityFormDisplay;
/**
* Load all form displays for nodes, add status with these settings, save.
*/
function node_post_update_configure_status_field_widget() {
$query = \Drupal::entityQuery('entity_form_display')->condition('targetEntityType', 'node');
$ids = $query->execute();
$form_displays = EntityFormDisplay::loadMultiple($ids);
// Assign status settings for each 'node' target entity types with 'default'
// form mode.
foreach ($form_displays as $id => $form_display) {
/** @var \Drupal\Core\Entity\Display\EntityDisplayInterface $form_display */
$form_display->setComponent('status', [
'type' => 'boolean_checkbox',
'settings' => [
'display_label' => TRUE,
],
])->save();
}
}
......@@ -340,6 +340,16 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
])
->setDisplayConfigurable('form', TRUE);
$fields['status']
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'settings' => [
'display_label' => TRUE,
],
'weight' => 120,
])
->setDisplayConfigurable('form', TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Authored on'))
->setDescription(t('The time that the node was created.'))
......
......@@ -86,7 +86,10 @@ public function form(array $form, FormStateInterface $form_state) {
$node = $this->entity;
if ($this->operation == 'edit') {
$form['#title'] = $this->t('<em>Edit @type</em> @title', ['@type' => node_get_type_label($node), '@title' => $node->label()]);
$form['#title'] = $this->t('<em>Edit @type</em> @title', [
'@type' => node_get_type_label($node),
'@title' => $node->label()
]);
}
// Changed must be sent to the client, for later overwrite error checking.
......@@ -99,6 +102,15 @@ public function form(array $form, FormStateInterface $form_state) {
$form['advanced']['#attributes']['class'][] = 'entity-meta';
$form['footer'] = [
'#type' => 'container',
'#weight' => 99,
'#attributes' => [
'class' => ['node-form-footer']
]
];
$form['status']['#group'] = 'footer';
// Node author information for administrators.
$form['author'] = [
'#type' => 'details',
......@@ -147,8 +159,6 @@ public function form(array $form, FormStateInterface $form_state) {
$form['#attached']['library'][] = 'node/form';
$form['#entity_builders']['update_status'] = '::updateStatus';
return $form;
}
......@@ -165,6 +175,9 @@ public function form(array $form, FormStateInterface $form_state) {
* The current state of the form.
*
* @see \Drupal\node\NodeForm::form()
*
* @deprecated in Drupal 8.4.x, will be removed before Drupal 9.0.0.
* The "Publish" button was removed.
*/
public function updateStatus($entity_type_id, NodeInterface $node, array $form, FormStateInterface $form_state) {
$element = $form_state->getTriggeringElement();
......@@ -183,59 +196,6 @@ protected function actions(array $form, FormStateInterface $form_state) {
$element['submit']['#access'] = $preview_mode != DRUPAL_REQUIRED || $form_state->get('has_been_previewed');
// If saving is an option, privileged users get dedicated form submit
// buttons to adjust the publishing status while saving in one go.
// @todo This adjustment makes it close to impossible for contributed
// modules to integrate with "the Save operation" of this form. Modules
// need a way to plug themselves into 1) the ::submit() step, and
// 2) the ::save() step, both decoupled from the pressed form button.
if ($element['submit']['#access'] && \Drupal::currentUser()->hasPermission('administer nodes')) {
// isNew | prev status » default & publish label & unpublish label
// 1 | 1 » publish & Save and publish & Save as unpublished
// 1 | 0 » unpublish & Save and publish & Save as unpublished
// 0 | 1 » publish & Save and keep published & Save and unpublish
// 0 | 0 » unpublish & Save and keep unpublished & Save and publish
// Add a "Publish" button.
$element['publish'] = $element['submit'];
// If the "Publish" button is clicked, we want to update the status to "published".
$element['publish']['#published_status'] = TRUE;
$element['publish']['#dropbutton'] = 'save';
if ($node->isNew()) {
$element['publish']['#value'] = t('Save and publish');
}
else {
$element['publish']['#value'] = $node->isPublished() ? t('Save and keep published') : t('Save and publish');
}
$element['publish']['#weight'] = 0;
// Add a "Unpublish" button.
$element['unpublish'] = $element['submit'];
// If the "Unpublish" button is clicked, we want to update the status to "unpublished".