From 648d7aa9f721cd89896cdf76c9f138ce0402b86f Mon Sep 17 00:00:00 2001 From: catch Date: Mon, 6 Apr 2020 09:42:08 +0100 Subject: [PATCH] Issue #3030989 by Lendude, emyu01, ravi.shankar, nisha_gupta, kaszarobert: Error while trying to bulk delete already deleted nodes (cherry picked from commit c266bb6e96bec2cb9b77399acead7ac3715d1d6d) --- .../views/src/Plugin/views/field/BulkForm.php | 9 ++-- .../tests/src/Functional/BulkFormTest.php | 52 +++++++++++++++++++ 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/core/modules/views/src/Plugin/views/field/BulkForm.php b/core/modules/views/src/Plugin/views/field/BulkForm.php index 917a81aa1af..b6f28d4b60b 100644 --- a/core/modules/views/src/Plugin/views/field/BulkForm.php +++ b/core/modules/views/src/Plugin/views/field/BulkForm.php @@ -406,7 +406,10 @@ class BulkForm extends FieldPluginBase implements CacheableDependencyInterface { foreach ($selected as $bulk_form_key) { $entity = $this->loadEntityFromBulkFormKey($bulk_form_key); - + // Skip execution if current entity does not exist. + if (empty($entity)) { + continue; + } // Skip execution if the user did not have access. if (!$action->getPlugin()->access($entity, $this->view->getUser())) { $this->messenger->addError($this->t('No access to execute %action on the @entity_type_label %entity_label.', [ @@ -461,8 +464,8 @@ class BulkForm extends FieldPluginBase implements CacheableDependencyInterface { * {@inheritdoc} */ public function viewsFormValidate(&$form, FormStateInterface $form_state) { - $selected = array_filter($form_state->getValue($this->options['id'])); - if (empty($selected)) { + $ids = $form_state->getValue($this->options['id']); + if (empty($ids) || empty(array_filter($ids))) { $form_state->setErrorByName('', $this->emptySelectedMessage()); } } diff --git a/core/modules/views/tests/src/Functional/BulkFormTest.php b/core/modules/views/tests/src/Functional/BulkFormTest.php index 8f49155b889..fbb1e8f49a3 100644 --- a/core/modules/views/tests/src/Functional/BulkFormTest.php +++ b/core/modules/views/tests/src/Functional/BulkFormTest.php @@ -43,6 +43,7 @@ class BulkFormTest extends BrowserTestBase { // array. $timestamp = REQUEST_TIME - $i; $nodes[] = $this->drupalCreateNode([ + 'title' => 'Node ' . $i, 'sticky' => FALSE, 'created' => $timestamp, 'changed' => $timestamp, @@ -157,6 +158,57 @@ class BulkFormTest extends BrowserTestBase { $this->assertText(t('Deleted 5 content items.')); // Check if we got redirected to the original page. $this->assertUrl('test_bulk_form'); + + // Test that the bulk form works when a node gets deleted by another user + // before the loaded bulk form can be used. + $this->drupalGet('test_bulk_form'); + // Now delete the node we want to delete with the bulk form. + $link = $this->getSession()->getPage()->findLink($nodes[6]->label()); + $checkbox = $link->getParent()->getParent()->find('css', 'input'); + $nodes[6]->delete(); + $edit = [ + $checkbox->getAttribute('name') => TRUE, + 'action' => 'node_delete_action', + ]; + $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); + // Make sure we just return to the bulk view with no warnings. + $this->assertUrl('test_bulk_form'); + $errors = $this->xpath('//div[contains(@class, "messages--status")]'); + $this->assertEmpty($errors, 'No action message shown.'); + + // Test that the bulk form works when multiple nodes are selected + // but one of the selected nodes are already deleted by another user before + // the loaded bulk form was submitted. + $this->drupalGet('test_bulk_form'); + // Call the node delete action. + $nodes[7]->delete(); + $edit = [ + 'node_bulk_form[0]' => TRUE, + 'node_bulk_form[1]' => TRUE, + 'action' => 'node_delete_action', + ]; + $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); + // Make sure we don't show an action message while we are still on the + // confirmation page. + $errors = $this->xpath('//div[contains(@class, "messages--status")]'); + $this->assertEmpty($errors, 'No action message shown.'); + $this->drupalPostForm(NULL, [], t('Delete')); + $this->assertText(t('Deleted 1 content item.')); + + // Test that the bulk form works when multiple nodes are selected + // but all of the selected nodes are already deleted + // by another user before the loaded bulk form was submitted. + $this->drupalGet('test_bulk_form'); + // Call the node delete action. + foreach ($nodes as $key => $node) { + $node->delete(); + } + $edit = [ + 'node_bulk_form[0]' => TRUE, + 'action' => 'node_delete_action', + ]; + $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); + $this->assertText('No content selected.'); } }