From e65e7886ed723bdbdbd6cfa504bc9d31198339b5 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Fri, 10 Jan 2025 15:29:31 +0000
Subject: [PATCH] =?UTF-8?q?Issue=20#3351706=20by=20plopesc,=20gxleano,=20e?=
 =?UTF-8?q?lber,=20nikhil=5F110,=20penyaskito,=20smustgrave,=20quietone,?=
 =?UTF-8?q?=20longwave,=20g=C3=A1bor=20hojtsy,=20pameeela:=20Provide=20a?=
 =?UTF-8?q?=20block=20for=20clearing=20caches=20from=20a=20dashboard?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../src/Controller/PerformanceController.php  | 11 ++-
 .../system/src/Form/ClearCacheForm.php        |  9 +--
 .../src/Plugin/Block/ClearCacheBlock.php      | 67 +++++++++++++++++++
 .../Functional/Block/ClearCacheBlockTest.php  | 67 +++++++++++++++++++
 4 files changed, 145 insertions(+), 9 deletions(-)
 create mode 100644 core/modules/system/src/Plugin/Block/ClearCacheBlock.php
 create mode 100644 core/modules/system/tests/src/Functional/Block/ClearCacheBlockTest.php

diff --git a/core/modules/system/src/Controller/PerformanceController.php b/core/modules/system/src/Controller/PerformanceController.php
index de0cb03bb9ff..56a548217ac4 100644
--- a/core/modules/system/src/Controller/PerformanceController.php
+++ b/core/modules/system/src/Controller/PerformanceController.php
@@ -19,8 +19,17 @@ class PerformanceController extends ControllerBase {
    *   configuration form.
    */
   public function build(): array {
+    // Load the cache form and embed it in a details element.
+    $cache_clear = $this->formBuilder()->getForm(ClearCacheForm::class);
+    $cache_clear['clear_cache'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Clear cache'),
+      '#open' => TRUE,
+      'clear' => $cache_clear['clear'],
+    ];
+    unset($cache_clear['clear']);
     return [
-      'cache_clear' => $this->formBuilder()->getForm(ClearCacheForm::class),
+      'cache_clear' => $cache_clear,
       'performance' => $this->formBuilder()->getForm(PerformanceForm::class),
     ];
   }
diff --git a/core/modules/system/src/Form/ClearCacheForm.php b/core/modules/system/src/Form/ClearCacheForm.php
index f8d3d5638f9c..5cdf1d59cdf7 100644
--- a/core/modules/system/src/Form/ClearCacheForm.php
+++ b/core/modules/system/src/Form/ClearCacheForm.php
@@ -23,14 +23,7 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-
-    $form['clear_cache'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Clear cache'),
-      '#open' => TRUE,
-    ];
-
-    $form['clear_cache']['clear'] = [
+    $form['clear'] = [
       '#type' => 'submit',
       '#value' => $this->t('Clear all caches'),
     ];
diff --git a/core/modules/system/src/Plugin/Block/ClearCacheBlock.php b/core/modules/system/src/Plugin/Block/ClearCacheBlock.php
new file mode 100644
index 000000000000..bc7006d65412
--- /dev/null
+++ b/core/modules/system/src/Plugin/Block/ClearCacheBlock.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Drupal\system\Plugin\Block;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Access\AccessResultInterface;
+use Drupal\Core\Block\Attribute\Block;
+use Drupal\Core\Block\BlockBase;
+use Drupal\Core\Form\FormBuilderInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\system\Form\ClearCacheForm;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a block to display 'Clear cache' elements.
+ */
+#[Block(
+  id: "system_clear_cache_block",
+  admin_label: new TranslatableMarkup("Clear cache")
+)]
+class ClearCacheBlock extends BlockBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * Creates a ClearCacheBlock instance.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Form\FormBuilderInterface $formBuilder
+   *   The form builder.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, protected FormBuilderInterface $formBuilder) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('form_builder'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build(): array {
+    return $this->formBuilder->getForm(ClearCacheForm::class);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function blockAccess(AccountInterface $account): AccessResultInterface {
+    return AccessResult::allowedIfHasPermission($account, 'administer site configuration');
+  }
+
+}
diff --git a/core/modules/system/tests/src/Functional/Block/ClearCacheBlockTest.php b/core/modules/system/tests/src/Functional/Block/ClearCacheBlockTest.php
new file mode 100644
index 000000000000..4ef2ffc8c7f9
--- /dev/null
+++ b/core/modules/system/tests/src/Functional/Block/ClearCacheBlockTest.php
@@ -0,0 +1,67 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\system\Functional\Block;
+
+use Drupal\block\BlockInterface;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests clear cache block behavior.
+ *
+ * @group Block
+ *
+ * @see \Drupal\system\Plugin\Block\ClearCacheBlock
+ */
+class ClearCacheBlockTest extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'block',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * The clear cache block instance.
+   *
+   * @var \Drupal\block\BlockInterface
+   */
+  protected BlockInterface $clearCacheBlock;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $admin_user = $this->drupalCreateUser(['administer site configuration']);
+    $this->drupalLogin($admin_user);
+    $this->clearCacheBlock = $this->placeBlock('system_clear_cache_block', [
+      'label' => 'Clear cache block',
+    ]);
+  }
+
+  /**
+   * Tests block behavior and access based on permissions.
+   */
+  public function testCacheClearBlock(): void {
+    $this->drupalGet('<front>');
+    $this->assertSession()->pageTextContains('Clear cache block');
+    $page = $this->getSession()->getPage();
+    $page->pressButton('Clear all caches');
+    $this->assertSession()->statusMessageContains('Caches cleared.');
+
+    // Confirm that access is not allowed for non-authorized users.
+    $this->drupalLogout();
+    $this->drupalGet('<front>');
+    $this->assertSession()->pageTextNotContains('Clear cache block');
+  }
+
+}
-- 
GitLab