i18n: Automatically filtering search by current language with Druapl 7

05 Mar 2013
Posted by jcfiala

The problem I was handled at work was pretty simple - we're putting together a multi-language site, with English and Spanish data. However, if you search on something that's part of a proper name which shows on both English and Spanish data, then you were getting a mix of English and Spanish nodes. What we wanted was a way to automatically filter the search by the current language, something that I couldn't find anywhere. So, I rolled up my sleeves and created this:

<?php
/**
* Implements hook_query_TAG_alter().
*
* Attempts to insure the query is a select query going across the search_index and node tables.
*/
function i18n_search_query_node_access_alter(QueryAlterableInterface $query) {
  global
$language;

 
$tables = $query->getTables();
 
$match_count = 0;
  foreach (
$tables as $table) {
    if (
$table['table'] == 'search_index' || $table['table'] == 'node') {
     
$match_count++;
    }
  }
  if (
$match_count < 2) {
    return;
  }
 
 
$option = 'language';
 
$column = 'n.language';
 
$exists = FALSE;
  foreach (
$query->conditions() as $condition) {
    if (
is_array($condition) && is_string($condition['field']) && $condition['field'] == $column) {
     
$exists = TRUE;
    }
  }
  if (!
$exists) {
   
$query->condition($column, $language->language);
  }
}
?>

The first half of the function is trying to solve the problem of only affecting queries for search. Unfortunately, the only tag applied to search queries is 'node_access', and although that tag makes sense, there's nothing more specific. So, we check to see if this node_access query includes both node and search_index - if it doesn't, then we stop.

The second half is testing to see if there's already a language filter on the query - if there is, then we don't want to add another one that could screw things up. Only if we don't find a language condition do we finally add a filter to only show nodes with the language in the global $language variable.

As you can see, this is part of a module - but this is also all of the module, other than a tiny info file that requires the search and locale modules. I suppose it could get added to drupal.org, but it seems pretty slight to create a module just for this.

Tags:

Also note the discussion at

Also note the discussion at http://drupal.stackexchange.com/questions/11290/search-only-for-the-curr..., which has the same fix for the +250 answer.