Change record status: 
Project: 
Introduced in branch: 
8.x
Description: 

API changes

  • hook_search_info is replaced by annotation-based plugin discovery using class \Drupal\search\Annotation\SearchPlugin.
  • A new interface \Drupal\search\Plugin\SearchInterface is defined. All search plugins must implement this interface. There is a base class \Drupal\search\Plugin\SearchPluginBase to aid in implementing this interface. Each plugin defines its ID (a string machine name) and a human-readable title in its plugin annotation.
  • Many search plugins will have configuration options. These plugins should implement \Drupal\search\Plugin\ConfigurableSearchInterface (which extends SearchInterface), and there is a base class \Drupal\search\Plugin\ConfigurableSearchPluginBase to aid in implementing this interface, as an alternative to the SearchPluginBase class
  • A search plugin that wants to use the core search index (as Node search does) should also implement \Drupal\search\Plugin\SearchIndexingInterface (user search does not use core indexing, so the indexing-specific methods were separated out).
  • Search plugins that want to have access control should also implement \Drupal\Core\Access\AccessibleInterface
  • All the search module hooks except hook_search_preprocess() are converted to be methods on the plugins that are invoked as appropriate (hook_search_execute(), hook_search_page(), etc.). The node-specific search module hooks still exist as well: hook_ranking(), hook_node_search_result(), and hook_node_update_index().
  • Search plugins can use the plugin methods searchFormAlter() and buildSearchUrlQuery() to alter the search form, for "Advanced" searching or other parameters (previously they would have needed to use hook_form_alter() or hook_form_FORM_ID_alter() to do this).
  • The search plugins are accessed via \Drupal\search\SearchPluginManager which is available as a service 'plugin.manager.search': Drupal::service('plugin.manager.search').
  • Users can define one or more "Search Pages" from the Search configuration page (admin/config/search) based on each plugin; each search page assigns a URL and a tab name to a search plugin and its configuration. Note that this means that a given search plugin cannot expect a fixed URL. Search pages, technically, are each \Drupal\search\Entity\SearchPage configuration entities, and they are managed via the \Drupal\search\SearchPageRepository manager class by default, using the search.search_page_repository service: Drupal::service('search.search_page_repository')
  • Modules providing search plugins can provide a YAML configuration file that will configure a search page. This file would be named search.page.(machine_name).yml -- you should be able to create a page from the Search admin page and find the config in your site's configuration directory. See files search.page.node_search.yml and search.page.user_search.yml in the node and user modules for examples. If your plugin has specific configuration, you will also need to define a configuration schema. See the search.plugin.node_search section of node.schema.yml for an example.
  • Since search implementations are plugins, a single module can now provide multiple search plugins - in contrast to Drupal <= 7 where there was a limit of one search implementation per module.
  • Node and User searches are converted to plugins.
  • Table {search_node_links} and the related functionality are removed since it was causing extra indexing of content and the code addling to this table was broken.
  • Node advanced search filters are now implemented via query sting ?f[]= parameters instead of being embedded into the search keyword string.
  • The SearchExpression class, which was added to Drupal 8, is not needed any more, so it is dropped. It had some functionality for injecting/extracting advanced search parameters into search keyword expressions, but this is done with query arguments now, so it is not needed. Correspondingly, since each search plugin basically sets up its own query, the setOption() method on SearchQuery is not needed, so it is also removed. Also, the functions search_expression_insert() and search_expression_extract() are removed.
  • Functionality specific to the Node module is moved from Search module to Node module or replaced by more generic functionality. For instance, search_touch_node() is replaced by search_mark_for_reindex() and the node module has a new function node_reindex_node_search() that calls this (which can be called from other modules to cause a node to be reindexed for search).
  • In Drupal 6, hook_update_index() was called on all implementing modules. In Drupal 7, this was silently dropped to only being called on active search modules (causing some bugs). In Drupal 8, this is now a method on the SearchIndexingInterface, and thus will explicitly only be called on plugins with active search pages that use indexing.
  • The default backlinks View is removed, since it relied on the {search_node_links} table.

User interface changes

In Drupal 7, users could enable/disable particular modules' search functionality. In Drupal 8, they can add, configure, rearrange, enable, and disable particular "Search Pages", each of which is a configuration of a particular search plugin. The type-specific configuration options are also moved to the individual page configuration instead of being shown on the Search configuration landing page (admin/config/search).

Drupal 7 code example

/**
 * Implements hook_search_info().
 */
function node_search_info() {
  return array(
    'title' => 'Content',
    'path' => 'node',
  );
}

/**
 * Implements hook_search_access().
 */
function node_search_access() {
  return user_access('access content');
}

/**
 * Implements hook_search_reset().
 */
function node_search_reset() {
  db_update('search_dataset')
    ->fields(array('reindex' => REQUEST_TIME))
    ->condition('type', 'node')
    ->execute();
}

/**
 * Implements hook_search_status().
 */
function node_search_status() {
  $total = db_query('SELECT COUNT(*) FROM {node}')->fetchField();
  $remaining = db_query("SELECT COUNT(*) FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE d.sid IS NULL OR d.reindex <> 0")->fetchField();
  return array('remaining' => $remaining, 'total' => $total);
}

/**
 * Implements hook_update_index().
 */
function node_update_index() {
  $limit = (int) variable_get('search_cron_limit', 100);

  $result = db_query_range("SELECT n.nid FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE d.sid IS NULL OR d.reindex <> 0 ORDER BY d.reindex ASC, n.nid ASC", 0, $limit, array(), array('target' => 'slave'));

  foreach ($result as $node) {
    _node_index_node($node);
  }
}

/**
 * Implements hook_search_admin().
 */
function node_search_admin() {
  // Output form for defining rank factor weights.
  ...
}

/**
 * Implements hook_search_execute().
 */
function node_search_execute($keys = NULL, $conditions = NULL) {
  // Build matching conditions
  ...
}

Drupal 8 code example

View the Node search plugin on api.drupal.org

Impacts: 
Site builders, administrators, editors
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done

Comments

waqarit’s picture

how to make a block of custom search including two filters.
These filters should contain taxonomy terms parent and child respectively.
anyone help???

s.abbott’s picture

This change splits hook_search_page() into two places, and removes some potentially used functionality. See this comment for more info.