From fca86410e6b8741fc16a08d8eeb62f4bb83d4570 Mon Sep 17 00:00:00 2001
From: Lauri Eskola <lauri.eskola@acquia.com>
Date: Fri, 8 Dec 2023 11:30:24 +0200
Subject: [PATCH] Issue #3325167 by smustgrave, acbramley, murilohp, rkoller,
 larowlan, AaronMcHale, dww, BramDriesen: Revisit the redirect to 'add block'
 form in the 'add block content' form

---
 .../block_content/src/BlockContentForm.php    | 69 +++++++++++++++----
 .../Functional/BlockContentCreationTest.php   | 47 +++++++++++--
 .../src/Functional/BlockContentTypeTest.php   |  2 +-
 3 files changed, 101 insertions(+), 17 deletions(-)

diff --git a/core/modules/block_content/src/BlockContentForm.php b/core/modules/block_content/src/BlockContentForm.php
index f9ae31821c05..f7503d345d75 100644
--- a/core/modules/block_content/src/BlockContentForm.php
+++ b/core/modules/block_content/src/BlockContentForm.php
@@ -38,6 +38,51 @@ public function form(array $form, FormStateInterface $form_state) {
     return $form;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function actions(array $form, FormStateInterface $form_state): array {
+    $element = parent::actions($form, $form_state);
+
+    if ($this->getRequest()->query->has('theme')) {
+      $element['submit']['#value'] = $this->t('Save and configure');
+    }
+
+    if ($this->currentUser()->hasPermission('administer blocks') && !$this->getRequest()->query->has('theme') && $this->entity->isNew()) {
+      $element['configure_block'] = [
+        '#type' => 'submit',
+        '#value' => $this->t('Save and configure'),
+        '#weight' => 20,
+        '#submit' => array_merge($element['submit']['#submit'], ['::configureBlock']),
+      ];
+    }
+
+    return $element;
+  }
+
+  /**
+   * Form submission handler for the 'configureBlock' action.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   */
+  public function configureBlock(array $form, FormStateInterface $form_state): void {
+    $block = $this->entity;
+    if (!$theme = $block->getTheme()) {
+      $theme = $this->config('system.theme')->get('default');
+    }
+    $form_state->setRedirect(
+      'block.admin_add',
+      [
+        'plugin_id' => 'block_content:' . $block->uuid(),
+        'theme' => $theme,
+      ]
+    );
+    $form_state->setIgnoreDestination();
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -64,19 +109,19 @@ public function save(array $form, FormStateInterface $form_state) {
       $form_state->setValue('id', $block->id());
       $form_state->set('id', $block->id());
       if ($insert) {
-        if (!$theme = $block->getTheme()) {
-          $theme = $this->config('system.theme')->get('default');
+        $theme = $block->getTheme();
+        if ($theme) {
+          $form_state->setRedirect(
+            'block.admin_add',
+            [
+              'plugin_id' => 'block_content:' . $block->uuid(),
+              'theme' => $theme,
+            ]
+          );
+        }
+        else {
+          $form_state->setRedirectUrl($block->toUrl('collection'));
         }
-        $form_state->setRedirect(
-          'block.admin_add',
-          [
-            'plugin_id' => 'block_content:' . $block->uuid(),
-            'theme' => $theme,
-          ]
-        );
-      }
-      else {
-        $form_state->setRedirectUrl($block->toUrl('collection'));
       }
     }
     else {
diff --git a/core/modules/block_content/tests/src/Functional/BlockContentCreationTest.php b/core/modules/block_content/tests/src/Functional/BlockContentCreationTest.php
index bd499aa22be8..71eb497607fb 100644
--- a/core/modules/block_content/tests/src/Functional/BlockContentCreationTest.php
+++ b/core/modules/block_content/tests/src/Functional/BlockContentCreationTest.php
@@ -95,10 +95,7 @@ public function testBlockContentCreationMultipleViewModes() {
     $edit['info[0][value]'] = 'Test Block';
     $edit['body[0][value]'] = $this->randomMachineName(16);
     $this->drupalGet('block/add/basic');
-    $this->submitForm($edit, 'Save');
-
-    // Check that the Basic block has been created.
-    $this->assertSession()->pageTextContains('basic ' . $edit['info[0][value]'] . ' has been created.');
+    $this->submitForm($edit, 'Save and configure');
 
     // Save our block permanently
     $this->submitForm(['region' => 'content'], 'Save block');
@@ -143,6 +140,48 @@ public function testBlockContentCreationMultipleViewModes() {
     $this->assertNotEmpty($block, 'Content Block found in database.');
   }
 
+  /**
+   * Tests the redirect workflow of creating a block_content and block.
+   */
+  public function testBlockContentFormSubmitHandlers() {
+    $this->drupalLogin($this->adminUser);
+
+    // Create a block and place in block layout.
+    $this->drupalGet('/admin/content/block');
+    $this->clickLink('Add content block');
+    // Verify destination URL, when clicking "Save and configure" this
+    // destination will be ignored.
+    $base = base_path();
+    $url = 'block/add?destination=' . $base . 'admin/content/block';
+    $this->assertSession()->addressEquals($url);
+    $edit = [];
+    $edit['info[0][value]'] = 'Test Block';
+    $edit['body[0][value]'] = $this->randomMachineName(16);
+    $this->submitForm($edit, 'Save and configure');
+    $this->assertSession()->pageTextContains('basic ' . $edit['info[0][value]'] . ' has been created.');
+    $this->assertSession()->pageTextContains('Configure block');
+
+    // Verify when editing a block "Save and configure" does not appear.
+    $this->drupalGet('/admin/content/block/1');
+    $this->assertSession()->buttonNotExists('Save and configure');
+
+    // Create a block but go back to block library.
+    $edit = [];
+    $edit['info[0][value]'] = 'Test Block';
+    $edit['body[0][value]'] = $this->randomMachineName(16);
+    $this->drupalGet('block/add/basic');
+    $this->submitForm($edit, 'Save');
+    // Check that the Basic block has been created.
+    $this->assertSession()->pageTextContains('basic ' . $edit['info[0][value]'] . ' has been created.');
+    $this->assertSession()->addressEquals('/admin/content/block');
+
+    // Test with user who doesn't have permission to place a block.
+    $this->drupalLogin($this->drupalCreateUser(['administer block content']));
+    $this->drupalGet('block/add/basic');
+    $this->assertSession()->buttonNotExists('Save and configure');
+
+  }
+
   /**
    * Create a default content block.
    *
diff --git a/core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php b/core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
index e38cddafdfe2..741eadfe3ff5 100644
--- a/core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
+++ b/core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
@@ -233,7 +233,7 @@ public function testsBlockContentAddTypes() {
         $this->clickLink('foo');
         // Create a new block.
         $edit = ['info[0][value]' => $this->randomMachineName(8)];
-        $this->submitForm($edit, 'Save');
+        $this->submitForm($edit, 'Save and configure');
         $blocks = $storage->loadByProperties(['info' => $edit['info[0][value]']]);
         if (!empty($blocks)) {
           $block = reset($blocks);
-- 
GitLab