Skip to content
Snippets Groups Projects
Verified Commit ce189a3f authored by Lee Rowlands's avatar Lee Rowlands
Browse files

Issue #3067943 by andypost, jhodgdon, Amber Himes Matz, pwolanin: Add...

Issue #3067943 by andypost, jhodgdon, Amber Himes Matz, pwolanin: Add capability for search blocks on non-default search
parent a1535f12
No related branches found
No related tags found
No related merge requests found
Showing
with 207 additions and 17 deletions
......@@ -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',
......
......@@ -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'
<?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';
});
}
......@@ -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'] = [
......
......@@ -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');
}
}
......@@ -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);
}
}
<?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']);
}
}
......@@ -17,6 +17,7 @@ settings:
label: Search
provider: search
label_display: visible
page_id: node_search
cache:
max_age: -1
status: true
......
......@@ -16,4 +16,5 @@ settings:
label: Search
provider: search
label_display: visible
page_id: node_search
visibility: { }
......@@ -16,4 +16,5 @@ settings:
label: Search
provider: search
label_display: visible
page_id: node_search
visibility: { }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment