diff --git a/core/modules/page_cache/tests/src/Functional/PageCacheTagsIntegrationTest.php b/core/modules/page_cache/tests/src/Functional/PageCacheTagsIntegrationTest.php index 40cefba95287ae441d90cdb329b19320b11e9005..dd41bc25daaf01bb382f8024737f98b5a1da32d4 100644 --- a/core/modules/page_cache/tests/src/Functional/PageCacheTagsIntegrationTest.php +++ b/core/modules/page_cache/tests/src/Functional/PageCacheTagsIntegrationTest.php @@ -111,7 +111,6 @@ public function testPageCacheTags() { 'user:' . $author_1->id(), 'config:filter.format.basic_html', 'config:color.theme.bartik', - 'config:search.settings', 'config:system.menu.account', 'config:system.menu.tools', 'config:system.menu.footer', @@ -152,7 +151,6 @@ public function testPageCacheTags() { 'user:' . $author_2->id(), 'config:color.theme.bartik', 'config:filter.format.full_html', - 'config:search.settings', 'config:system.menu.account', 'config:system.menu.tools', 'config:system.menu.footer', diff --git a/core/modules/search/config/schema/search.schema.yml b/core/modules/search/config/schema/search.schema.yml index 2ed4c09ba9a843c2faa633c78098f1267ed50e58..64d75b8db9a982603d331ae4b02857c5577fa006 100644 --- a/core/modules/search/config/schema/search.schema.yml +++ b/core/modules/search/config/schema/search.schema.yml @@ -88,3 +88,11 @@ search.page.*: label: 'Plugin' configuration: type: search.plugin.[%parent.plugin] + +block.settings.search_form_block: + type: block_settings + label: 'Search block' + mapping: + page_id: + type: string + label: 'Search page' diff --git a/core/modules/search/search.post_update.php b/core/modules/search/search.post_update.php new file mode 100644 index 0000000000000000000000000000000000000000..a6b1fd968b87c471350c1a8b3dcfe1fd10808a74 --- /dev/null +++ b/core/modules/search/search.post_update.php @@ -0,0 +1,24 @@ +<?php + +/** + * @file + * Post update functions for Search module. + */ + +use Drupal\block\BlockInterface; +use Drupal\Core\Config\Entity\ConfigEntityUpdater; + +/** + * Configures default search page for instantiated blocks. + */ +function search_post_update_block_page(&$sandbox = NULL) { + if (!\Drupal::moduleHandler()->moduleExists('block')) { + // Early exit when block module disabled. + return; + } + \Drupal::classResolver(ConfigEntityUpdater::class) + ->update($sandbox, 'block', function (BlockInterface $block) { + // Save search block to set default search page from plugin. + return $block->getPluginId() === 'search_form_block'; + }); +} diff --git a/core/modules/search/src/Form/SearchBlockForm.php b/core/modules/search/src/Form/SearchBlockForm.php index 0a373663bda8bd32ad4020f40ea485e1068dff1d..4edcd73a10497193b01a9cfc8ddec319af8f274f 100644 --- a/core/modules/search/src/Form/SearchBlockForm.php +++ b/core/modules/search/src/Form/SearchBlockForm.php @@ -75,16 +75,17 @@ public function getFormId() { /** * {@inheritdoc} */ - public function buildForm(array $form, FormStateInterface $form_state) { + public function buildForm(array $form, FormStateInterface $form_state, $entity_id = NULL) { // Set up the form to submit using GET to the correct search page. - $entity_id = $this->searchPageRepository->getDefaultSearchPage(); - - // SearchPageRepository::getDefaultSearchPage() depends on search.settings. - // The dependency needs to be added before the conditional return, otherwise - // the block would get cached without the necessary cacheablity metadata in - // case there is no default search page and would not be invalidated if that - // changes. - $this->renderer->addCacheableDependency($form, $this->configFactory->get('search.settings')); + if (!$entity_id) { + $entity_id = $this->searchPageRepository->getDefaultSearchPage(); + // SearchPageRepository::getDefaultSearchPage() depends on + // search.settings. The dependency needs to be added before the + // conditional return, otherwise the block would get cached without the + // necessary cacheability metadata in case there is no default search page + // and would not be invalidated if that changes. + $this->renderer->addCacheableDependency($form, $this->configFactory->get('search.settings')); + } if (!$entity_id) { $form['message'] = [ diff --git a/core/modules/search/src/Plugin/Block/SearchBlock.php b/core/modules/search/src/Plugin/Block/SearchBlock.php index d956d7ae3d69bded3f995cfa0a9f1eb33a91f5a9..d1a1f249fd22f7d9333f4bf41ba8c8aef980fa48 100644 --- a/core/modules/search/src/Plugin/Block/SearchBlock.php +++ b/core/modules/search/src/Plugin/Block/SearchBlock.php @@ -3,8 +3,14 @@ namespace Drupal\search\Plugin\Block; use Drupal\Core\Access\AccessResult; -use Drupal\Core\Session\AccountInterface; use Drupal\Core\Block\BlockBase; +use Drupal\Core\Form\FormBuilderInterface; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Session\AccountInterface; +use Drupal\search\Form\SearchBlockForm; +use Drupal\search\SearchPageRepositoryInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides a 'Search form' block. @@ -15,7 +21,51 @@ * category = @Translation("Forms") * ) */ -class SearchBlock extends BlockBase { +class SearchBlock extends BlockBase implements ContainerFactoryPluginInterface { + + /** + * The form builder. + * + * @var \Drupal\Core\Form\FormBuilderInterface + */ + protected $formBuilder; + + /** + * The search page repository. + * + * @var \Drupal\search\SearchPageRepositoryInterface + */ + protected $searchPageRepository; + + /** + * Constructs a new SearchLocalTask. + * + * @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 $form_builder + * The form builder. + * @param \Drupal\search\SearchPageRepositoryInterface $search_page_repository + * The search page repository. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, FormBuilderInterface $form_builder, SearchPageRepositoryInterface $search_page_repository) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->formBuilder = $form_builder; + $this->searchPageRepository = $search_page_repository; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static($configuration, $plugin_id, $plugin_definition, + $container->get('form_builder'), + $container->get('search.search_page_repository') + ); + } /** * {@inheritdoc} @@ -28,7 +78,49 @@ protected function blockAccess(AccountInterface $account) { * {@inheritdoc} */ public function build() { - return \Drupal::formBuilder()->getForm('Drupal\search\Form\SearchBlockForm'); + $page = $this->configuration['page_id'] ?? NULL; + return $this->formBuilder->getForm(SearchBlockForm::class, $page); + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return [ + 'page_id' => '', + ]; + } + + /** + * {@inheritdoc} + */ + public function blockForm($form, FormStateInterface $form_state) { + // The configuration for this block is which search page to connect the + // form to. Options are all configured/active search pages. + $options = []; + $active_search_pages = $this->searchPageRepository->getActiveSearchPages(); + foreach ($this->searchPageRepository->sortSearchPages($active_search_pages) as $entity_id => $entity) { + $options[$entity_id] = $entity->label(); + } + + $form['page_id'] = [ + '#type' => 'select', + '#title' => $this->t('Search page'), + '#description' => $this->t('The search page that the form submits to, or Default for the default search page.'), + '#default_value' => $this->configuration['page_id'], + '#options' => $options, + '#empty_option' => $this->t('Default'), + '#empty_value' => '', + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function blockSubmit($form, FormStateInterface $form_state) { + $this->configuration['page_id'] = $form_state->getValue('page_id'); } } diff --git a/core/modules/search/tests/src/Functional/SearchBlockTest.php b/core/modules/search/tests/src/Functional/SearchBlockTest.php index eedb1a6243863f92a6e5d385bb12cb4b41211791..31e16b13b993cd1fb00b3098b9d556edece4f7e1 100644 --- a/core/modules/search/tests/src/Functional/SearchBlockTest.php +++ b/core/modules/search/tests/src/Functional/SearchBlockTest.php @@ -15,14 +15,29 @@ class SearchBlockTest extends BrowserTestBase { /** * {@inheritdoc} */ - protected static $modules = ['block', 'node', 'search', 'dblog']; + protected static $modules = ['block', 'node', 'search', 'dblog', 'user']; + /** + * The administrative user. + * + * @var \Drupal\Core\Session\AccountInterface + */ + protected $adminUser; + + /** + * {@inheritdoc} + */ protected function setUp() { parent::setUp(); // Create and log in user. - $admin_user = $this->drupalCreateUser(['administer blocks', 'search content']); - $this->drupalLogin($admin_user); + $this->adminUser = $this->drupalCreateUser([ + 'administer blocks', + 'search content', + 'access user profiles', + 'access content', + ]); + $this->drupalLogin($this->adminUser); } /** @@ -105,6 +120,16 @@ public function testSearchFormBlock() { $this->drupalPostForm(NULL, ['keys' => $this->randomMachineName()], t('Search'), [], 'search-form'); $this->assertNoText('You must include at least one keyword to match in the content', 'Keyword message is not displayed when searching for long word after short word search'); + // Edit the block configuration so that it searches users instead of nodes, + // and test. + $this->drupalPostForm('admin/structure/block/manage/' . $block->id(), + [ + 'settings[page_id]' => 'user_search', + ], 'Save block'); + $name = $this->adminUser->getAccountName(); + $email = $this->adminUser->getEmail(); + $this->drupalPostForm('node', ['keys' => $name], t('Search')); + $this->assertLink($name); } } diff --git a/core/modules/search/tests/src/Functional/Update/BlockPageSettingTest.php b/core/modules/search/tests/src/Functional/Update/BlockPageSettingTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d11ef0bdefdc2302daa0723b617c4de943f68a6a --- /dev/null +++ b/core/modules/search/tests/src/Functional/Update/BlockPageSettingTest.php @@ -0,0 +1,39 @@ +<?php + +namespace Drupal\Tests\search\Functional\Update; + +use Drupal\FunctionalTests\Update\UpdatePathTestBase; + +/** + * Tests search blocks upgrade to default page setting. + * + * @group Update + * @group legacy + */ +class BlockPageSettingTest extends UpdatePathTestBase { + + /** + * {@inheritdoc} + */ + protected function setDatabaseDumpFiles() { + $this->databaseDumpFiles = [ + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + ]; + } + + /** + * Tests existing search block settings upgrade. + * + * @see search_post_update_block_page() + */ + public function testUpdateActionPlugins() { + $config = \Drupal::configFactory()->get('block.block.bartik_search'); + $this->assertArrayNotHasKey('page_id', $config->get('settings')); + + $this->runUpdates(); + + $config = \Drupal::configFactory()->get('block.block.bartik_search'); + $this->assertSame('', $config->get('settings')['page_id']); + } + +} diff --git a/core/modules/system/tests/fixtures/update/block.block.secondtestfor2354889.yml b/core/modules/system/tests/fixtures/update/block.block.secondtestfor2354889.yml index 1a8a9046ffb0f770134ca43b00bb221a05e1af08..e7ee5eda13f1b7ef21f34e299f03f1552c072acf 100644 --- a/core/modules/system/tests/fixtures/update/block.block.secondtestfor2354889.yml +++ b/core/modules/system/tests/fixtures/update/block.block.secondtestfor2354889.yml @@ -17,6 +17,7 @@ settings: label: Search provider: search label_display: visible + page_id: node_search cache: max_age: -1 status: true diff --git a/core/profiles/demo_umami/config/install/block.block.umami_search.yml b/core/profiles/demo_umami/config/install/block.block.umami_search.yml index 047f516255a1a5ce6a312ab7a2279f3199b17680..4acc93c78e1aaa525f9a7ba71ddba76285b510a3 100644 --- a/core/profiles/demo_umami/config/install/block.block.umami_search.yml +++ b/core/profiles/demo_umami/config/install/block.block.umami_search.yml @@ -16,4 +16,5 @@ settings: label: Search provider: search label_display: visible + page_id: node_search visibility: { } diff --git a/core/profiles/standard/config/install/block.block.bartik_search.yml b/core/profiles/standard/config/install/block.block.bartik_search.yml index 90b81cbfeef3f102ac278f0c5e406a7cb72122c4..8a21f816dc6b5d394e575a377fd888e1b0c31266 100644 --- a/core/profiles/standard/config/install/block.block.bartik_search.yml +++ b/core/profiles/standard/config/install/block.block.bartik_search.yml @@ -16,4 +16,5 @@ settings: label: Search provider: search label_display: visible + page_id: node_search visibility: { }