diff -u b/core/modules/comment/comment.api.php b/core/modules/comment/comment.api.php --- b/core/modules/comment/comment.api.php +++ b/core/modules/comment/comment.api.php @@ -34,7 +34,7 @@ */ function hook_comment_insert(Drupal\comment\Comment $comment) { // Reindex the node when comments are added. - search_mark_for_reindex('node_search', $comment->nid->target_id); + node_reindex_node_search($comment->nid->target_id); } /** diff -u b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php --- b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php +++ b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php @@ -80,13 +80,13 @@ /** * The list of options and info for advanced search filters. * - * Each entry in the array has the option as key and and info array that - * determines how the value is matched in the databse query. The possible keys - * in the info array are: - * - column: (required) name of the database column to match against. - * - join: (optional) information on a table to join. By default the data - * is matched against the {node_field_data} table. - * - operator: (optional) OR or AND, defaults to OR + * Each entry in the array has the option as the key and and for its value, an + * array that determines how the value is matched in the database query. The + * possible keys in that array are: + * - column: (required) Name of the database column to match against. + * - join: (optional) Information on a table to join. By default the data is + * matched against the {node_field_data} table. + * - operator: (optional) OR or AND, defaults to OR. * * @var array */ @@ -162,47 +162,55 @@ return $results; } $keys = $this->keywords; - // Build matching conditions - $query = $this->database - ->select('search_index', 'i', array('target' => 'slave')) - ->extend('Drupal\search\SearchQuery') - ->extend('Drupal\Core\Database\Query\PagerSelectExtender'); - $query->join('node_field_data', 'n', 'n.nid = i.sid'); - $query->condition('n.status', 1) - ->addTag('node_access') - ->searchExpression($keys, $this->getPluginId()); - - // Handle advanced search filters in the f query string. - $parameters = $this->getParameters(); - if (!empty($parameters['f']) && is_array($parameters['f'])) { - $filters = array(); - // Match any query value that is an expected option and a value - // separated by ':' like 'term:27'. - $pattern = '/(' . implode('|', array_keys($this->advanced)) . '):([^ ]*)/i'; - foreach ($parameters['f'] as $item) { - if (preg_match($pattern, $item, $m)) { - // Use the matched value as the array key to eliminate duplicates. - $filters[$m[1]][$m[2]] = $m[2]; - } - } - foreach ($filters as $option => $matched) { - $info = $this->advanced[$option]; - // Insert additional conditions. By default, all use the OR operator. - $operator = empty($info['operator']) ? 'OR' : $info['operator']; - $where = new Condition($operator); - foreach ($matched as $value) { - $where->condition($info['column'], $value); - } - $query->condition($where); - if (!empty($info['join'])) { - $query->join($info['join']['table'], $info['join']['alias'], $info['join']['condition']); - } - } - } - // Only continue if the first pass query matches. - if (!$query->executeFirstPass()) { - return array(); - } + + // Build matching conditions. + $query = $this->database + ->select('search_index', 'i', array('target' => 'slave')) + ->extend('Drupal\search\SearchQuery') + ->extend('Drupal\Core\Database\Query\PagerSelectExtender'); + $query->join('node_field_data', 'n', 'n.nid = i.sid'); + $query->condition('n.status', 1) + ->addTag('node_access') + ->searchExpression($keys, $this->getPluginId()); + + // Handle advanced search filters in the f query string. + // $_GET['f'] is an array that looks like this in the URL: + // ?f[]=type:page&f[]=term:27&f[]=term:13&f[]=langcode:en + // So $parameters['f'] looks like: + // array('type:page', 'term:27', 'term:13', 'langcode:en'); + // We need to parse this out into query conditions. + $parameters = $this->getParameters(); + if (!empty($parameters['f']) && is_array($parameters['f'])) { + $filters = array(); + // Match any query value that is an expected option and a value + // separated by ':' like 'term:27'. + $pattern = '/(' . implode('|', array_keys($this->advanced)) . '):([^ ]*)/i'; + foreach ($parameters['f'] as $item) { + if (preg_match($pattern, $item, $m)) { + // Use the matched value as the array key to eliminate duplicates. + $filters[$m[1]][$m[2]] = $m[2]; + } + } + // Now turn these into query conditions. This assumes that everything in + // $filters is a known type of advanced search. + foreach ($filters as $option => $matched) { + $info = $this->advanced[$option]; + // Insert additional conditions. By default, all use the OR operator. + $operator = empty($info['operator']) ? 'OR' : $info['operator']; + $where = new Condition($operator); + foreach ($matched as $value) { + $where->condition($info['column'], $value); + } + $query->condition($where); + if (!empty($info['join'])) { + $query->join($info['join']['table'], $info['join']['alias'], $info['join']['condition']); + } + } + } + // Only continue if the first pass query matches. + if (!$query->executeFirstPass()) { + return array(); + } // Add the ranking expressions. $this->addNodeRankings($query); @@ -228,7 +236,7 @@ unset($build['#theme']); $node->rendered = drupal_render($build); - // Fetch comments for snippet. + // Fetch comment count for snippet. $node->rendered .= ' ' . $this->moduleHandler->invoke('comment', 'node_update_index', array($node, $item->langcode)); $extra = $this->moduleHandler->invokeAll('node_search_result', array($node, $item->langcode)); @@ -359,11 +367,11 @@ return array('remaining' => $remaining, 'total' => $total); } - /** + /** * {@inheritdoc} */ public function searchFormAlter(array &$form, array &$form_state) { - // Keyword boxes: + // Add keyword boxes. $form['advanced'] = array( '#type' => 'details', '#title' => t('Advanced search'), @@ -399,7 +407,7 @@ '#maxlength' => 255, ); - // Node types: + // Add node types. $node_types = $this->entityManager->getStorageController('node_type')->loadMultiple(); $types = array_map('check_plain', node_type_get_names()); $form['advanced']['types-fieldset'] = array( @@ -422,7 +430,7 @@ '#weight' => 100, ); - // Languages: + // Add languages. $language_options = array(); foreach (language_list(Language::STATE_ALL) as $langcode => $language) { // Make locked languages appear special in the list. @@ -449,7 +457,7 @@ } /** - * Handle submission of elements added in searchFormAlter(). + * Handles submission of elements added in searchFormAlter(). * * @param array $form * Nested array of form elements that comprise the form. diff -u b/core/modules/node/node.api.php b/core/modules/node/node.api.php --- b/core/modules/node/node.api.php +++ b/core/modules/node/node.api.php @@ -100,12 +100,12 @@ * - Validating a node during editing form submit (calling * node_form_validate()): * - hook_node_validate() (all) - * - Searching (calling node_search_execute()): + * - Searching (using the 'node_search' plugin): * - hook_ranking() (all) * - Query is executed to find matching nodes * - Resulting node is loaded (see Loading section above) * - Resulting node is prepared for viewing (see Viewing a single node above) - * - comment_node_update_index() is called. + * - comment_node_update_index() is called (this adds "N comments" text) * - hook_node_search_result() (all) * - Search indexing (calling updateIndex() on the 'node_search' plugin): * - Node is loaded (see Loading section above) @@ -619,8 +619,8 @@ /** * Act on a node being displayed as a search result. * - * This hook is invoked from node_search_execute(), after node_load() and - * node_view() have been called. + * This hook is invoked from the node search plugin during search execution, + * after loading and rendering the node. * * @param \Drupal\Core\Entity\EntityInterface $node * The node being displayed in a search result. @@ -693,8 +693,8 @@ /** * Act on a node being indexed for searching. * - * This hook is invoked during search indexing, after node_load(), and after the - * result of node_view() is added as $node->rendered to the node object. + * This hook is invoked during search indexing, after loading, and after the + * result of rendering is added as $node->rendered to the node object. * * @param \Drupal\Core\Entity\EntityInterface $node * The node being indexed. diff -u b/core/modules/node/node.module b/core/modules/node/node.module --- b/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -2263,10 +2263,10 @@ } /** - * Mark a node to be re-indexed by the node_search plugin. + * Marks a node to be re-indexed by the node_search plugin. * * @param int $nid - * The Node ID. + * The node ID. */ function node_reindex_node_search($nid) { if (Drupal::moduleHandler()->moduleExists('search')) { diff -u b/core/modules/search/lib/Drupal/search/Plugin/SearchIndexingInterface.php b/core/modules/search/lib/Drupal/search/Plugin/SearchIndexingInterface.php --- b/core/modules/search/lib/Drupal/search/Plugin/SearchIndexingInterface.php +++ b/core/modules/search/lib/Drupal/search/Plugin/SearchIndexingInterface.php @@ -8,13 +8,12 @@ namespace Drupal\search\Plugin; /** - * Defines an optional interface for SearchPlugin objects that will be invoked - * by Search module to report index status and index data via search_cron(). + * Defines an optional interface for SearchPlugin objects using the index. * - * Plugins implementing this interface will have the methods invoked on cron - * and via the search module administration form. Plugins not implementing - * this interface are assumed to use alternate mechanisms for indexing the - * data used to provide search results. + * Plugins implementing this interface will have these methods invoked during + * search_cron() and via the search module administration form. Plugins not + * implementing this interface are assumed to use alternate mechanisms for + * indexing the data used to provide search results. */ interface SearchIndexingInterface { @@ -30,20 +29,18 @@ * When implementing this method, your module should index content items that * were modified or added since the last run. PHP has a time limit * for cron, though, so it is advisable to limit how many items you index - * per run using config('search.settings')->get('index.cron_limit') (see - * example below). Also, since the cron run could time out and abort in the - * middle of your run, you should update your module's internal bookkeeping on - * when items have last been indexed as you go rather than waiting to the end - * of indexing. + * per run using config('search.settings')->get('index.cron_limit'). Also, + * since the cron run could time out and abort in the middle of your run, you + * should update any needed internal bookkeeping on when items have last + * been indexed as you go rather than waiting to the end of indexing. */ public function updateIndex(); /** * Takes action when the search index is going to be rebuilt. * - * Modules that use updateIndex() should update their indexing - * bookkeeping so that it starts from scratch the next time updateIndex() - * is called. + * Modules that use updateIndex() should update their indexing bookkeeping so + * that it starts from scratch the next time updateIndex() is called. */ public function resetIndex(); diff -u b/core/modules/search/lib/Drupal/search/Plugin/SearchInterface.php b/core/modules/search/lib/Drupal/search/Plugin/SearchInterface.php --- b/core/modules/search/lib/Drupal/search/Plugin/SearchInterface.php +++ b/core/modules/search/lib/Drupal/search/Plugin/SearchInterface.php @@ -82,7 +82,7 @@ public function buildResults(); /** - * Alter the search form when being built for a given plugin. + * Alters the search form when being built for a given plugin. * * The core search module only invokes this method on active module plugins * when building a form for them in search_form(). A plugin implementing diff -u b/core/modules/search/lib/Drupal/search/Plugin/SearchPluginBase.php b/core/modules/search/lib/Drupal/search/Plugin/SearchPluginBase.php --- b/core/modules/search/lib/Drupal/search/Plugin/SearchPluginBase.php +++ b/core/modules/search/lib/Drupal/search/Plugin/SearchPluginBase.php @@ -11,7 +11,7 @@ use Drupal\Core\Plugin\ContainerFactoryPluginInterface; /** - * Base class for plugins wishing to support search. + * Defines a base class for plugins wishing to support search. */ abstract class SearchPluginBase extends PluginBase implements ContainerFactoryPluginInterface, SearchInterface { diff -u b/core/modules/search/search.api.php b/core/modules/search/search.api.php --- b/core/modules/search/search.api.php +++ b/core/modules/search/search.api.php @@ -26,7 +26,6 @@ * The text to preprocess. This is a single piece of plain text extracted * from between two HTML tags or from the search query. It will not contain * any HTML entities or HTML tags. - * * @param $langcode * The language code of the entity that has been found. * diff -u b/core/modules/search/search.module b/core/modules/search/search.module --- b/core/modules/search/search.module +++ b/core/modules/search/search.module @@ -267,7 +267,7 @@ * specified, $type must also be given. Omit both $sid and $type to clear * the entire search index. * @param $type - * (optional) The plugin ID other machine-readable type for the item to + * (optional) The plugin ID or other machine-readable type for the item to * remove from the search index. * @param $reindex * (optional) Boolean to specify whether reindexing happens. @@ -660,7 +660,7 @@ } /** - * Extracts a type-specific search option from a search expression. + * Extracts a search-type-specific search option from a search expression. * * Search options are added using search_expression_insert(), and retrieved * using search_expression_extract(). They take the form option:value, and @@ -681,7 +681,7 @@ } /** - * Adds a module-specific search option to a search expression. + * Adds a search-type-specific search option to a search expression. * * Search options are added using search_expression_insert(), and retrieved * using search_expression_extract(). They take the form option:value, and @@ -717,18 +717,21 @@ * data. Most of the system is handled by the Search module, so this must be * enabled for all of the search features to work. * - * To be discovered, the plugins must implement \Drupal\search\Plugin\SearchInterface. + * To be discovered, the plugins must implement + * \Drupal\search\Plugin\SearchInterface and be annotated as + * \Drupal\search\Annotation\SearchPlugin plugins. * * There are three ways to interact with the search system: * - Specifically for searching nodes, you can implement * hook_node_update_index() and hook_node_search_result(). However, note that * the search system already indexes all visible output of a node; i.e., - * everything displayed normally by hook_node_view(). This is + * everything displayed normally during node viewing. This is * usually sufficient. You should only use this mechanism if you want * additional, non-visible data to be indexed. - * - Define a plugin implementing \Drupal\search\Plugin\SearchInterface. This - * will create a search tab for your plugin on the /search page with a simple - * keyword search form. You will also need to implement the execute() method + * - Define a plugin implementing \Drupal\search\Plugin\SearchInterface and + * annotated as \Drupal\search\Annotation\SearchPlugin. This will create a + * search tab for your plugin on the /search page with a simple keyword + * search form. You will also need to implement the execute() method * from the interface to perform the search. A base class is provided in * \Drupal\search\Plugin\SearchPluginBase. * @@ -741,7 +744,7 @@ /** * Form constructor for the search form. * - * @param Drupal\search\Plugin\SearchInterface $plugin + * @param \Drupal\search\Plugin\SearchInterface $plugin * A search plugin instance to render the form for. * @param $action * Form action. Defaults to "search/$path", where $path is the search path @@ -751,11 +754,10 @@ * Label for the keywords field. Defaults to t('Enter your keywords') if * NULL. Supply '' to omit. * - * @return - * A Form API array for the search form. - * * @see search_form_validate() * @see search_form_submit() + * + * @ingroup forms */ function search_form($form, &$form_state, SearchInterface $plugin, $action = '', $prompt = NULL) { diff -u b/core/modules/user/lib/Drupal/user/Plugin/Search/UserSearch.php b/core/modules/user/lib/Drupal/user/Plugin/Search/UserSearch.php --- b/core/modules/user/lib/Drupal/user/Plugin/Search/UserSearch.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Search/UserSearch.php @@ -18,7 +18,7 @@ use Symfony\Component\HttpFoundation\Request; /** - * Executes a keyword search against the search index. + * Executes a keyword search for users against the {users} database table. * * @SearchPlugin( * id = "user_search",