Restricting search results in Drupal 7

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.

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:

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

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.

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

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.

<code>

  1. function mymodule_query_alter(&$query) {
  2. $is_search = FALSE;
  3. foreach ($query->getTables() as $table) {
  4. if ($table['table'] == 'search_index') {
  5. $is_search = TRUE;
  6. }
  7. }
  8.  
  9. if ($is_search) {
  10. $query->condition('n.type', 'article', '<>');
  11. $query->condition('n.type', 'feed', '<>');
  12. }
  13. }

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.

Brad Blake

Brad Blake