Restricting search results in Drupal 7

Posted Jan 18, 2011 // 0 comments
Brad :

Sites using the built-in search in Drupal 7, as opposed to external options such as SOLR, may need to restrict the types of content in the search or otherwise alter search results. The way this can be accomplished has changed from Drupal 6 to Drupal 7.

In Drupal 6, this could be accomplished using hook_db_rewrite_sql and some form of the code below:

function mymodule_db_rewrite_sql($query, $primary_table, $primary_field, $args) {
  if ($query=='' && $primary_table=='n' && $primary_field=='nid' && empty($args) && arg(0)=='search' && arg(1)=='node') {
    $where = " n.type NOT IN ('article','feed') ";
    return array('where' => $where);
  }
}

However, this hook no longer exists in Drupal 7. Instead, there are hook_query_alter and hook_query_TAG_alter.

hook_query_alter allows you to alter many parts of a query, and hook_query_TAG_alter has the same functionality but allows you to target queries that have certain tags applied, much like how hook_form_alter and hook_form_FORM_ID_alter operate.

If you know the tag of the query you would like to alter, then hook_query_TAG_alter is more specific and the best hook to use. However, if your query does not have a tag or you’re not sure what it is, use hook_query_alter.

Many queries in core and contributed modules have tags applied to them such as ‘node_access’ or ‘pager’. To find what tag(s) a query might have, you can print out the contents of the $query object, and they should be listed.

In the case of the basic search query, there usually are several tags which may include ‘pager’ and ‘node_access’. However, you could apply a patch ( http://drupal.org/node/997976 ) which adds a more specific tag to the query. Assuming the patch has been applied, it is easy to create a hook that replicates the functionality from the Drupal 6 version above.

function mymodule_search_query_search_node_alter(&$query) {
  $query->condition('n.type', 'article', '<>');
  $query->condition('n.type', 'feed', '<>');
}

If you choose not to apply the patch, you can still use other methods to target the specific query, such as looking at the tables used in the query.

function mymodule_query_alter(&$query) {
  $is_search = FALSE;
  foreach ($query->getTables() as $table) {
    if ($table['table'] == 'search_index') {
      $is_search = TRUE;
    }
  }

  if ($is_search) {
    $query->condition('n.type', 'article', '<>');
    $query->condition('n.type', 'feed', '<>');
  }
}

The Drupal 7 query system is very robust and allows for a high level of customization over the queries. For more information, take a look at SelectQueryInterface or SelectQueryExtender.

About Brad

Web Developer Brad Blake brings a wealth of expertise to our team and our clients whenever he creates software tools and websites on the LAMP platform. For more than five years, he has been using PHP to build cutting-edge technologies that ...

more >

Read Brad 's Blog

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
  • Allowed HTML tags: <a> <strong> <code> <p> <img> <ul> <ol> <li> <h2> <h3> <h4> <b> <u> <i>
  • You may insert videos with [video:URL]

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.