Issue #3067943 by andypost, jhodgdon, Amber Himes Matz, pwolanin: Add capability for search blocks on non-default search
							parent
							
								
									a1535f1203
								
							
						
					
					
						commit
						ce189a3f75
					
				| 
						 | 
				
			
			@ -111,7 +111,6 @@ class PageCacheTagsIntegrationTest extends BrowserTestBase {
 | 
			
		|||
      '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 @@ class PageCacheTagsIntegrationTest extends BrowserTestBase {
 | 
			
		|||
      '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'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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';
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -75,16 +75,17 @@ class SearchBlockForm extends FormBase {
 | 
			
		|||
  /**
 | 
			
		||||
   * {@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.
 | 
			
		||||
    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 cacheablity metadata in
 | 
			
		||||
    // case there is no default search page and would not be invalidated if that
 | 
			
		||||
    // changes.
 | 
			
		||||
      // 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 @@ use Drupal\Core\Block\BlockBase;
 | 
			
		|||
 *   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 @@ class SearchBlock extends BlockBase {
 | 
			
		|||
   * {@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 @@ class SearchBlockTest extends BrowserTestBase {
 | 
			
		|||
    $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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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']);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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: {  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue