Drupal API

hook_search

  • Drupal 5
  • Drupal 6
Познай дзен Друпала — помоги переводчикам! Можешь начать с регистрации.

developer/hooks/core.php, строка 1493

Версии
5 – 6
hook_search($op = 'search', $keys = null)

Определяет пользовательскую функцию поиска.

Этот хук позволяет модулю выполнять поиск по контенту, который он определяет (свои типы нод, пользователи или комментарии, например), когда поиск на сайте выполняется.

Note that you can use form API to extend the search. You will need to use hook_form_alter() to add any additional required form elements. You can process their values on submission using a custom validation function. You will need to merge any custom search values into the search keys using a key:value syntax. This allows all search queries to have a clean and permanent URL. See node_form_alter() for an example.

The example given here is for node.module, which uses the indexed search capabilities. To do this, node module also implements hook_update_index() which is used to create and maintain the index.

We call do_search() with the keys, the module name and extra SQL fragments to use when searching. See hook_update_index() for more information.

Параметры

$op A string defining which operation to perform:

  • 'name': the hook should return a translated name defining the type of items that are searched for with this module ('content', 'users', ...)
  • 'reset': the search index is going to be rebuilt. Modules which use hook_update_index() should update their indexing bookkeeping so that it starts from scratch the next time hook_update_index() is called.
  • 'search': the hook should perform a search using the keywords in $keys
  • 'status': if the module implements hook_update_index(), it should return an array containing the following keys:
    • remaining: the amount of items that still need to be indexed
    • total: the total amount of items (both indexed and unindexed)
$keys The search keywords as entered by the user.

Возвращаемое значение

An array of search results. Each item in the result set array may contain whatever information the module wishes to display as a search result. To use the default search result display, each item should be an array which can have the following keys:

  • link: the URL of the found item
  • type: the type of item
  • title: the name of the item
  • user: the author of the item
  • date: a timestamp when the item was last modified
  • extra: an array of optional extra information items
  • snippet: an excerpt or preview to show with the result (can be generated with search_excerpt())
Only 'link' and 'title' are required, but it is advised to fill in as many of these fields as possible.

Связанные темы

▸ 3 функции вызывают hook_search()

▾ 3 функции вызывают hook_search()

search_admin_settings in modules/search/search.admin.inc
Menu callback; displays the search module settings page. See alsosystem_settings_form()
search_menu in modules/search/search.module
Реализация hook_menu().
search_wipe in modules/search/search.module
Wipes a part of or the entire search index.

Код

<?php
function hook_search($op = 'search', $keys = null) {
  switch ($op) {
    case 'name':
      return t('Content');
    case 'reset':
      db_query("UPDATE {search_dataset} SET reindex = %d WHERE type = 'node'", time());
      return;
    case 'status':
      $total = db_result(db_query('SELECT COUNT(*) FROM {node} WHERE status = 1'));
      $remaining = db_result(db_query("SELECT COUNT(*) FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE n.status = 1 AND (d.sid IS NULL OR d.reindex <> 0)"));
      return array('remaining' => $remaining, 'total' => $total);
    case 'admin':
      $form = array();
      // Output form for defining rank factor weights.
      $form['content_ranking'] = array(
        '#type' => 'fieldset',
        '#title' => t('Content ranking'),
      );
      $form['content_ranking']['#theme'] = 'node_search_admin';
      $form['content_ranking']['info'] = array(
        '#value' => '<em>'. t('The following numbers control which properties the content search should favor when ordering the results. Higher numbers mean more influence, zero means the property is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') .'</em>'
      );
      $ranking = array('node_rank_relevance' => t('Keyword relevance'),
                       'node_rank_recent' => t('Recently posted'));
      if (module_exists('comment')) {
        $ranking['node_rank_comments'] = t('Number of comments');
      }
      if (module_exists('statistics') && variable_get('statistics_count_content_views', 0)) {
        $ranking['node_rank_views'] = t('Number of views');
      }
      // Note: reversed to reflect that higher number = higher ranking.
      $options = drupal_map_assoc(range(0, 10));
      foreach ($ranking as $var => $title) {
        $form['content_ranking']['factors'][$var] = array(
          '#title' => $title,
          '#type' => 'select',
          '#options' => $options,
          '#default_value' => variable_get($var, 5),
        );
      }
      return $form;
    case 'search':
      // Build matching conditions
      list($join1, $where1) = _db_rewrite_sql();
      $arguments1 = array();
      $conditions1 = 'n.status = 1';
      if ($type = search_query_extract($keys, 'type')) {
        $types = array();
        foreach (explode(',', $type) as $t) {
          $types[] = "n.type = '%s'";
          $arguments1[] = $t;
        }
        $conditions1 .= ' AND ('. implode(' OR ', $types) .')';
        $keys = search_query_insert($keys, 'type');
      }
      if ($category = search_query_extract($keys, 'category')) {
        $categories = array();
        foreach (explode(',', $category) as $c) {
          $categories[] = "tn.tid = %d";
          $arguments1[] = $c;
        }
        $conditions1 .= ' AND ('. implode(' OR ', $categories) .')';
        $join1 .= ' INNER JOIN {term_node} tn ON n.vid = tn.vid';
        $keys = search_query_insert($keys, 'category');
      }
      // Build ranking expression (we try to map each parameter to a
      // uniform distribution in the range 0..1).
      $ranking = array();
      $arguments2 = array();
      $join2 = '';
      // Used to avoid joining on node_comment_statistics twice
      $stats_join = FALSE;
      $total = 0;
      if ($weight = (int)variable_get('node_rank_relevance', 5)) {
        // Average relevance values hover around 0.15
        $ranking[] = '%d * i.relevance';
        $arguments2[] = $weight;
        $total += $weight;
      }
      if ($weight = (int)variable_get('node_rank_recent', 5)) {
        // Exponential decay with half-life of 6 months, starting at last indexed node
        $ranking[] = '%d * POW(2, (GREATEST(MAX(n.created), MAX(n.changed), MAX(c.last_comment_timestamp)) - %d) * 6.43e-8)';
        $arguments2[] = $weight;
        $arguments2[] = (int)variable_get('node_cron_last', 0);
        $join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
        $stats_join = TRUE;
        $total += $weight;
      }
      if (module_exists('comment') && $weight = (int)variable_get('node_rank_comments', 5)) {
        // Inverse law that maps the highest reply count on the site to 1 and 0 to 0.
        $scale = variable_get('node_cron_comments_scale', 0.0);
        $ranking[] = '%d * (2.0 - 2.0 / (1.0 + MAX(c.comment_count) * %f))';
        $arguments2[] = $weight;
        $arguments2[] = $scale;
        if (!$stats_join) {
          $join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
        }
        $total += $weight;
      }
      if (module_exists('statistics') && variable_get('statistics_count_content_views', 0) &&
          $weight = (int)variable_get('node_rank_views', 5)) {
        // Inverse law that maps the highest view count on the site to 1 and 0 to 0.
        $scale = variable_get('node_cron_views_scale', 0.0);
        $ranking[] = '%d * (2.0 - 2.0 / (1.0 + MAX(nc.totalcount) * %f))';
        $arguments2[] = $weight;
        $arguments2[] = $scale;
        $join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid';
        $total += $weight;
      }
      // When all search factors are disabled (ie they have a weight of zero),
      // the default score is based only on keyword relevance and there is no need to
      // adjust the score of each item.
      if ($total == 0) {
        $select2 = 'i.relevance AS score';
        $total = 1;
      }
      else {
        $select2 = implode(' + ', $ranking) . ' AS score';
      }
      // Do search.
      $find = do_search($keys, 'node', 'INNER JOIN {node} n ON n.nid = i.sid '. $join1, $conditions1 . (empty($where1) ? '' : ' AND '. $where1), $arguments1, $select2, $join2, $arguments2);
      // Load results.
      $results = array();
      foreach ($find as $item) {
        // Build the node body.
        $node = node_load($item->sid);
        $node->build_mode = NODE_BUILD_SEARCH_RESULT;
        $node = node_build_content($node, FALSE, FALSE);
        $node->body = drupal_render($node->content);
        // Fetch comments for snippet.
        $node->body .= module_invoke('comment', 'nodeapi', $node, 'update index');
        // Fetch terms for snippet.
        $node->body .= module_invoke('taxonomy', 'nodeapi', $node, 'update index');
        $extra = node_invoke_nodeapi($node, 'search result');
        $results[] = array(
          'link' => url('node/'. $item->sid, array('absolute' => TRUE)),
          'type' => check_plain(node_get_types('name', $node)),
          'title' => $node->title,
          'user' => theme('username', $node),
          'date' => $node->changed,
          'node' => $node,
          'extra' => $extra,
          'score' => $item->score / $total,
          'snippet' => search_excerpt($keys, $node->body),
        );
      }
      return $results;
  }
}
?>
Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

Вход в систему

Что такое OpenID?
  • Регистрация
  • Забыли пароль?

Документация

  • Drupal 6
  • Константы
  • Файлы
  • Функции
  • Глобальные переменные
  • Разделы