diff --git a/core/modules/node/config/search.search.node_search.yml b/core/modules/node/config/search.search.node_search.yml
index 5c73892..7e9ac7e 100644
--- a/core/modules/node/config/search.search.node_search.yml
+++ b/core/modules/node/config/search.search.node_search.yml
@@ -1,7 +1,9 @@
id: node_search
-label: Node
+label: 'Node search'
uuid: 25687eeb-4bb5-469c-ad05-5eb24cd7012c
status: '1'
langcode: en
+path: node
+title: Content
plugin: node_search
configuration: { }
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index ae14496..87481e6 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1562,8 +1562,7 @@ function node_page_view(EntityInterface $node) {
* @see node_search_validate()
*/
function node_form_search_form_alter(&$form, $form_state) {
-
- if (isset($form['module']) && $form['module']['#value'] == 'node' && user_access('use advanced search')) {
+ if ($form_state['search_plugin'] == 'node_search' && user_access('use advanced search')) {
// Keyword boxes:
$form['advanced'] = array(
'#type' => 'details',
diff --git a/core/modules/search/config/search.settings.yml b/core/modules/search/config/search.settings.yml
index ff32f97..f6fa8fc 100644
--- a/core/modules/search/config/search.settings.yml
+++ b/core/modules/search/config/search.settings.yml
@@ -1,5 +1,5 @@
and_or_limit: '7'
-default_entity: node_search
+default_type: node_search
index:
cron_limit: '100'
overlap_cjk: '1'
diff --git a/core/modules/search/lib/Drupal/search/Controller/SearchController.php b/core/modules/search/lib/Drupal/search/Controller/SearchController.php
index 7c7f54f..71d1a65 100644
--- a/core/modules/search/lib/Drupal/search/Controller/SearchController.php
+++ b/core/modules/search/lib/Drupal/search/Controller/SearchController.php
@@ -74,7 +74,7 @@ public static function create(ContainerInterface $container) {
* @return array
* A list of search plugins that can be configured.
*/
- public function addSearchConfig() {
+ public function addSearchType() {
// @todo Remove this when https://drupal.org/node/2032535 is in.
drupal_set_title(t('Add new search configuration'));
diff --git a/core/modules/search/lib/Drupal/search/Form/SearchAddForm.php b/core/modules/search/lib/Drupal/search/Form/SearchAddForm.php
index 6e11b77..a3afa35 100644
--- a/core/modules/search/lib/Drupal/search/Form/SearchAddForm.php
+++ b/core/modules/search/lib/Drupal/search/Form/SearchAddForm.php
@@ -26,7 +26,9 @@ protected function init(array &$form_state) {
public function buildForm(array $form, array &$form_state, $search_plugin_id = NULL) {
$this->entity->setPlugin($search_plugin_id);
$definition = $this->entity->getPluginDefinition();
+ $this->entity->set('path', $definition['path']);
$this->entity->set('label', $definition['title']);
+ $this->entity->set('title', $definition['title']);
return parent::buildForm($form, $form_state);
}
diff --git a/core/modules/search/lib/Drupal/search/Form/SearchFormBase.php b/core/modules/search/lib/Drupal/search/Form/SearchFormBase.php
index f310210..bd1083d 100644
--- a/core/modules/search/lib/Drupal/search/Form/SearchFormBase.php
+++ b/core/modules/search/lib/Drupal/search/Form/SearchFormBase.php
@@ -10,6 +10,7 @@
use Drupal\Core\Entity\EntityControllerInterface;
use Drupal\Core\Entity\EntityFormController;
use Drupal\Core\Entity\EntityStorageControllerInterface;
+use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\ConfigurablePluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -34,24 +35,24 @@
protected $plugin;
/**
- * The search storage controller.
+ * The entity query factory.
*
- * @var \Drupal\Core\Entity\EntityStorageControllerInterface
+ * @var \Drupal\Core\Entity\Query\QueryFactory
*/
- protected $storageController;
+ protected $entityQuery;
/**
* Constructs a new search form.
*
- * @param \Drupal\Core\Extension\ModuleHandlerInterface
+ * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
- * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage_controller
- * The search storage controller.
+ * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query
+ * The entity query.
*/
- public function __construct(ModuleHandlerInterface $module_handler, EntityStorageControllerInterface $storage_controller) {
+ public function __construct(ModuleHandlerInterface $module_handler, QueryFactory $entity_query) {
parent::__construct($module_handler);
- $this->storageController = $storage_controller;
+ $this->entityQuery = $entity_query;
}
/**
@@ -60,13 +61,20 @@ public function __construct(ModuleHandlerInterface $module_handler, EntityStorag
public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
return new static(
$container->get('module_handler'),
- $container->get('plugin.manager.entity')->getStorageController($entity_type)
+ $container->get('entity.query')
);
}
/**
* {@inheritdoc}
*/
+ public function getBaseFormID() {
+ return 'search_entity_form';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function buildForm(array $form, array &$form_state) {
$this->plugin = $this->entity->getPlugin();
return parent::buildForm($form, $form_state);
@@ -79,6 +87,7 @@ public function form(array $form, array &$form_state) {
$form['label'] = array(
'#type' => 'textfield',
'#title' => t('Label'),
+ '#description' => t('The administrative label for this search'),
'#default_value' => $this->entity->label(),
'#maxlength' => '255',
);
@@ -92,6 +101,20 @@ public function form(array $form, array &$form_state) {
'exists' => array($this, 'exists'),
),
);
+ $form['title'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Menu title'),
+ '#description' => t('The title used by the local tab on the search page'),
+ '#default_value' => $this->entity->getTitle(),
+ '#maxlength' => '255',
+ );
+ $form['path'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Path'),
+ '#field_prefix' => 'search/',
+ '#default_value' => $this->entity->getPath(),
+ '#maxlength' => '255',
+ );
$form['plugin'] = array(
'#type' => 'value',
'#value' => $this->entity->get('plugin'),
@@ -118,8 +141,10 @@ public function form(array $form, array &$form_state) {
* TRUE if the search configuration exists, FALSE otherwise.
*/
public function exists($id) {
- $search = $this->storageController->load($id);
- return !empty($search);
+ $entity = $this->entityQuery->get('search')
+ ->condition('id', $id)
+ ->execute();
+ return (bool) $entity;
}
/**
@@ -137,6 +162,15 @@ protected function actions(array $form, array &$form_state) {
public function validate(array $form, array &$form_state) {
parent::validate($form, $form_state);
+ // Ensure each path is unique.
+ $path = $this->entityQuery->get('search')
+ ->condition('path', $form_state['values']['path'])
+ ->condition('id', $form_state['values']['id'], '<>')
+ ->execute();
+ if ($path) {
+ form_set_error('path', t('The search path must be unique'));
+ }
+
if ($this->plugin instanceof ConfigurablePluginInterface) {
$this->plugin->validate($form, $form_state);
}
diff --git a/core/modules/search/lib/Drupal/search/Plugin/Core/Entity/Search.php b/core/modules/search/lib/Drupal/search/Plugin/Core/Entity/Search.php
index 42d2f9e..3d5357e 100644
--- a/core/modules/search/lib/Drupal/search/Plugin/Core/Entity/Search.php
+++ b/core/modules/search/lib/Drupal/search/Plugin/Core/Entity/Search.php
@@ -78,6 +78,16 @@ class Search extends ConfigEntityBase implements SearchInterface {
protected $plugin;
/**
+ * @var string
+ */
+ protected $path;
+
+ /**
+ * @var string
+ */
+ protected $title;
+
+ /**
* The plugin bag that stores search plugins.
*
* @var \Drupal\Core\Plugin\DefaultPluginBag
@@ -126,7 +136,29 @@ public function isConfigurable() {
* {@inheritdoc}
*/
public function isDefaultSearch() {
- return \Drupal::service('config.factory')->get('search.settings')->get('default_entity') == $this->id();
+ return \Drupal::service('config.factory')->get('search.settings')->get('default_type') == $this->id();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTitle() {
+ return $this->title;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPath() {
+ return $this->path;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getProvider() {
+ $definition = $this->getPluginDefinition();
+ return $definition['provider'];
}
/**
@@ -148,6 +180,8 @@ public function uri() {
public function getExportProperties() {
$properties = parent::getExportProperties();
$names = array(
+ 'path',
+ 'title',
'plugin',
'configuration',
);
diff --git a/core/modules/search/lib/Drupal/search/SearchInterface.php b/core/modules/search/lib/Drupal/search/SearchInterface.php
index 853d552..19618e1 100644
--- a/core/modules/search/lib/Drupal/search/SearchInterface.php
+++ b/core/modules/search/lib/Drupal/search/SearchInterface.php
@@ -54,4 +54,19 @@ public function getPluginDefinition();
*/
public function isDefaultSearch();
+ /**
+ * @return string
+ */
+ public function getPath();
+
+ /**
+ * @return string
+ */
+ public function getProvider();
+
+ /**
+ * @return string
+ */
+ public function getTitle();
+
}
diff --git a/core/modules/search/lib/Drupal/search/SearchListController.php b/core/modules/search/lib/Drupal/search/SearchListController.php
index 592e07d..7bff6ae 100644
--- a/core/modules/search/lib/Drupal/search/SearchListController.php
+++ b/core/modules/search/lib/Drupal/search/SearchListController.php
@@ -93,10 +93,20 @@ public function render() {
* {@inheritdoc}
*/
public function buildHeader() {
- $header['label'] = t('Label');
- $header['plugin'] = t('Plugin');
- $header['status'] = t('Status');
- $header['operations'] = t('Operations');
+ $header['label'] = array(
+ 'data' => t('Label'),
+ );
+ $header['plugin'] = array(
+ 'data' => t('Plugin'),
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ );
+ $header['status'] = array(
+ 'data' => t('Status'),
+ 'class' => array(RESPONSIVE_PRIORITY_LOW),
+ );
+ $header['operations'] = array(
+ 'data' => t('Operations'),
+ );
return $header;
}
@@ -180,18 +190,18 @@ public function buildForm(array $form, array &$form_state) {
'#description' => t('Whether to apply a simple Chinese/Japanese/Korean tokenizer based on overlapping sequences. Turn this off if you want to use an external preprocessor for this instead. Does not affect other languages.')
);
- $form['search_plugins'] = array(
+ $form['search_types'] = array(
'#type' => 'details',
- '#title' => t('Search plugins'),
+ '#title' => t('Search types'),
);
- $form['search_plugins']['inline_actions'] = array(
+ $form['search_types']['inline_actions'] = array(
'#prefix' => '
',
);
- $form['search_plugins']['inline_actions']['add'] = array(
+ $form['search_types']['inline_actions']['add'] = array(
'#theme' => 'menu_local_action',
'#link' => array(
- 'title' => t('Add new search settings'),
+ 'title' => t('Add new search type'),
'href' => 'admin/config/search/settings/add',
),
);
@@ -199,13 +209,13 @@ public function buildForm(array $form, array &$form_state) {
foreach ($entities as $entity) {
$rows[$entity->id()] = $this->buildRow($entity);
}
- $form['search_plugins']['default_entity'] = array(
+ $form['search_types']['default_type'] = array(
'#type' => 'tableselect',
'#header' => $this->buildHeader(),
'#options' => $rows,
'#required' => TRUE,
'#multiple' => FALSE,
- '#default_value' => $search_settings->get('default_entity'),
+ '#default_value' => $search_settings->get('default_type'),
);
$form['actions']['#type'] = 'actions';
@@ -252,14 +262,14 @@ public function submitForm(array &$form, array &$form_state) {
}
// If the default search is disabled, enable it.
- $entity = $this->storage->load($form_state['values']['default_entity']);
+ $entity = $this->storage->load($form_state['values']['default_type']);
if (!$entity->status()) {
$entity->enable()->save();
}
$search_settings
->set('index.cron_limit', $form_state['values']['cron_limit'])
- ->set('default_entity', $form_state['values']['default_entity'])
+ ->set('default_type', $form_state['values']['default_type'])
->save();
drupal_set_message(t('The configuration options have been saved.'));
diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchConfigSettingsFormTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchConfigSettingsFormTest.php
index 118a8e7..3086c21 100644
--- a/core/modules/search/lib/Drupal/search/Tests/SearchConfigSettingsFormTest.php
+++ b/core/modules/search/lib/Drupal/search/Tests/SearchConfigSettingsFormTest.php
@@ -105,7 +105,7 @@ function testSearchModuleSettingsPage() {
// Enable search for the test module
$edit = array(
- 'default_entity' => 'dummy_search_type',
+ 'default_type' => 'dummy_search_type',
'minimum_word_size' => 5,
);
$this->drupalPost('admin/config/search/settings', $edit, t('Save configuration'));
@@ -162,7 +162,7 @@ function testSearchModuleDisabling() {
// Test each module if it's enabled as the only search module.
foreach ($modules as $module) {
// Enable the one module and disable other ones.
- $edit = array('default_entity' => $module);
+ $edit = array('default_type' => $module);
$this->drupalPost('admin/config/search/settings', $edit, t('Save configuration'));
foreach ($modules as $other) {
@@ -208,7 +208,7 @@ function testSearchModuleDisabling() {
$search->enable()->save();
}
- $edit = array('default_entity' => 'node_search');
+ $edit = array('default_type' => 'node_search');
$this->drupalPost('admin/config/search/settings', $edit, t('Save configuration'));
foreach (array('search/node/pizza', 'search/node') as $path) {
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index ffe969b..c0004c4 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -162,7 +162,7 @@ function search_menu() {
'route_name' => 'search.add',
);
$items['admin/config/search/settings/add/%'] = array(
- 'route_name' => 'search.add_settings',
+ 'route_name' => 'search.add_type',
);
$items['admin/config/search/settings'] = array(
'title' => 'Search settings',
@@ -193,39 +193,36 @@ function search_menu() {
// system appears to be having two sets of tabs. See discussion on issue
// http://drupal.org/node/245103 for details.
- $default_info = search_get_default_entity_info();
- if ($default_info) {
- foreach (entity_load_multiple_by_properties('search', array('status' => '1')) as $search_id => $entity) {
- $search_info = $entity->getPluginDefinition();
- $path = 'search/' . $search_info['path'];
- $items[$path] = array(
- 'title' => $search_info['title'],
- 'page callback' => 'search_view',
- 'page arguments' => array($search_id, ''),
- 'access callback' => '_search_menu_access',
- 'access arguments' => array($search_info['provider']),
- 'type' => MENU_LOCAL_TASK,
- 'file' => 'search.pages.inc',
- 'weight' => $search_info['provider'] == $default_info['provider'] ? -10 : 0,
- );
- $items["$path/%menu_tail"] = array(
- 'title' => $search_info['title'],
- 'load arguments' => array('%map', '%index'),
- 'page callback' => 'search_view',
- 'page arguments' => array($search_id, 2),
- 'access callback' => '_search_menu_access',
- 'access arguments' => array($search_info['provider']),
- // The default local task points to its parent, but this item points to
- // where it should so it should not be changed.
- 'type' => MENU_LOCAL_TASK,
- 'file' => 'search.pages.inc',
- 'weight' => 0,
- // These tabs are not subtabs.
- 'tab_root' => 'search/' . $default_info['path'] . '/%',
- // These tabs need to display at the same level.
- 'tab_parent' => 'search/' . $default_info['path'],
- );
- }
+ $default_type = search_get_default_type();
+ foreach (entity_load_multiple_by_properties('search', array('status' => '1')) as $search_id => $entity) {
+ $path = 'search/' . $entity->getPath();
+ $items[$path] = array(
+ 'title' => $entity->getTitle(),
+ 'page callback' => 'search_view',
+ 'page arguments' => array($search_id, ''),
+ 'access callback' => '_search_menu_access',
+ 'access arguments' => array($entity->getProvider()),
+ 'type' => MENU_LOCAL_TASK,
+ 'file' => 'search.pages.inc',
+ 'weight' => $entity->isDefaultSearch() ? -10 : 0,
+ );
+ $items["$path/%menu_tail"] = array(
+ 'title' => $entity->getTitle(),
+ 'load arguments' => array('%map', '%index'),
+ 'page callback' => 'search_view',
+ 'page arguments' => array($search_id, 2),
+ 'access callback' => '_search_menu_access',
+ 'access arguments' => array($entity->getProvider()),
+ // The default local task points to its parent, but this item points to
+ // where it should so it should not be changed.
+ 'type' => MENU_LOCAL_TASK,
+ 'file' => 'search.pages.inc',
+ 'weight' => 0,
+ // These tabs are not subtabs.
+ 'tab_root' => 'search/' . $default_type->getPath() . '/%',
+ // These tabs need to display at the same level.
+ 'tab_parent' => 'search/' . $default_type->getPath(),
+ );
}
return $items;
}
@@ -258,14 +255,13 @@ function search_is_active() {
}
/**
- * Returns information about the default search module.
+ * Returns the default search entity.
*
- * @return array
- * The search plugin definition for the default search module, if any.
+ * @return \Drupal\search\SearchInterface
+ * The search entity.
*/
-function search_get_default_entity_info() {
- $definition = array();
- $default = config('search.settings')->get('default_entity');
+function search_get_default_type() {
+ $default = config('search.settings')->get('default_type');
if (!$default || !$entity = search_load($default, TRUE)) {
// The variable setting does not match any active plugin, so just return
// the info for the first active plugin (if any).
@@ -273,9 +269,9 @@ function search_get_default_entity_info() {
->condition('status', 1)
->range(0, 1)
->execute();
- $definition = entity_load('search', reset($id))->getPluginDefinition();
+ $entity = entity_load('search', reset($id));
}
- return $definition;
+ return $entity;
}
/**
@@ -954,17 +950,11 @@ function search_expression_insert($expression, $option, $value = NULL) {
* @see search_form_validate()
* @see search_form_submit()
*/
-function search_form($form, &$form_state, $action = '', $keys = '', $plugin_id = NULL, $prompt = NULL) {
- if (!$plugin_id) {
- $module_info = search_get_default_entity_info();
- }
- else {
- $entity = entity_load('search', $plugin_id);
- $module_info = $entity->getPluginDefinition();
- }
+function search_form($form, &$form_state, $action = '', $keys = '', $entity_id = NULL, $prompt = NULL) {
+ $entity = $entity_id ? entity_load('search', $entity_id) : search_get_default_type();
if (!$action) {
- $action = 'search/' . $module_info['path'];
+ $action = 'search/' . $entity->getPath();
}
if (!isset($prompt)) {
$prompt = t('Enter your keywords');
@@ -972,8 +962,8 @@ function search_form($form, &$form_state, $action = '', $keys = '', $plugin_id =
$form['#action'] = url($action);
// Record the $action for later use in redirecting.
+ $form_state['search_plugin'] = $entity->getPlugin()->getPluginId();
$form_state['action'] = $action;
- $form['module'] = array('#type' => 'value', '#value' => $module_info['provider']);
$form['basic'] = array('#type' => 'container', '#attributes' => array('class' => array('container-inline')));
$form['basic']['keys'] = array(
'#type' => 'search',
@@ -1038,9 +1028,8 @@ function search_box_form_submit($form, &$form_state) {
}
$form_id = $form['form_id']['#value'];
- $info = search_get_default_entity_info();
- if ($info) {
- $form_state['redirect'] = 'search/' . $info['path'] . '/' . trim($form_state['values'][$form_id]);
+ if ($entity = search_get_default_type()) {
+ $form_state['redirect'] = 'search/' . $entity->getPath() . '/' . trim($form_state['values'][$form_id]);
}
else {
form_set_error(NULL, t('Search is currently disabled.'), 'error');
diff --git a/core/modules/search/search.pages.inc b/core/modules/search/search.pages.inc
index ed9449c..15d3e7b 100644
--- a/core/modules/search/search.pages.inc
+++ b/core/modules/search/search.pages.inc
@@ -27,19 +27,18 @@ function search_view($entity_id = NULL, $keys = '') {
// No path or invalid path: find the default module. Note that if there
// are no enabled search modules, this function should never be called,
// since hook_menu() would not have defined any search paths.
- $info = search_get_default_entity_info();
+ $entity = search_get_default_type();
// Redirect from bare /search or an invalid path to the default search path.
- $path = 'search/' . $info['path'];
+ $path = 'search/' . $entity->getPath();
if ($keys) {
$path .= '/' . $keys;
}
return new RedirectResponse(url($path, array('absolute' => TRUE)));
}
- $plugin = $entity->getPlugin();
$request = Drupal::request();
+ $plugin = $entity->getPlugin();
$plugin->setSearch($keys, $request->query->all(), $request->attributes->all());
- $info = $plugin->getPluginDefinition();
// Default results output is an empty string.
$results = array('#markup' => '');
// Process the search form. Note that if there is $_POST data,
@@ -51,7 +50,7 @@ function search_view($entity_id = NULL, $keys = '') {
// Only search if there are keywords or non-empty conditions.
if ($plugin->isSearchExecutable()) {
// Log the search keys.
- watchdog('search', 'Searched %type for %keys.', array('%keys' => $keys, '%type' => $info['title']), WATCHDOG_NOTICE, l(t('results'), 'search/' . $info['path'] . '/' . $keys));
+ watchdog('search', 'Searched %type for %keys.', array('%keys' => $keys, '%type' => $entity->getTitle()), WATCHDOG_NOTICE, l(t('results'), 'search/' . $entity->getPath() . '/' . $keys));
// Collect the search results.
$results = $plugin->buildResults();
diff --git a/core/modules/search/search.routing.yml b/core/modules/search/search.routing.yml
index fac9ba2..833573c 100644
--- a/core/modules/search/search.routing.yml
+++ b/core/modules/search/search.routing.yml
@@ -15,11 +15,11 @@ search_reindex_confirm:
search.add:
pattern: '/admin/config/search/settings/add'
defaults:
- _content: '\Drupal\search\Controller\SearchController::addSearchConfig'
+ _content: '\Drupal\search\Controller\SearchController::addSearchType'
requirements:
_permission: 'administer search'
-search.add_settings:
+search.add_type:
pattern: '/admin/config/search/settings/add/{search_plugin_id}'
defaults:
_entity_form: 'search.add'
diff --git a/core/modules/search/tests/modules/search_extra_type/config/search.search.dummy_search_type.yml b/core/modules/search/tests/modules/search_extra_type/config/search.search.dummy_search_type.yml
index b6e4996..cfebc79 100644
--- a/core/modules/search/tests/modules/search_extra_type/config/search.search.dummy_search_type.yml
+++ b/core/modules/search/tests/modules/search_extra_type/config/search.search.dummy_search_type.yml
@@ -3,5 +3,7 @@ label: 'Dummy search type'
uuid: b55858d4-f428-474c-8200-ef47a4597aef
status: '1'
langcode: en
+path: dummy_path
+title: 'Dummy search type'
plugin: search_extra_type_search
configuration: { }
diff --git a/core/modules/user/config/search.search.user_search.yml b/core/modules/user/config/search.search.user_search.yml
index 5134b69..94c43ce 100644
--- a/core/modules/user/config/search.search.user_search.yml
+++ b/core/modules/user/config/search.search.user_search.yml
@@ -1,7 +1,9 @@
id: user_search
-label: User
+label: 'User search'
uuid: c0d6b9a7-09a7-415f-b71a-26957bef635c
status: '1'
langcode: en
+path: user
+title: Users
plugin: user_search
configuration: { }