Building a website I recently ran into an issue where I had HTML search facets interacting with Drupal views. The user would click on the facet and it would filter the view depending on the argument. I ended up implementing hook_views_query_alter. To make sure the values I wanted to filter on were in the view, I added the search facets into the view as fields. This automatically joins the necessary tables so that you don’t have to. Implementing hook_views_query_alter requires two parameters, view and query, both are passed by reference. Since this hook is called for every view the first thing I did was check that I was altering the right query by adding an if statement that checks the view name. After that you're free to modify the query as you wish. In my example, I looped through the search facets and added them as where statements and arguments to the query.


function search_views_query_alter(&$view, &$query) {
  if($view->name == 'example_view_name'){
    foreach($parsed_url AS $key => $value){ 
      where[0]['clauses'][] = 'profile_values_profile_' . $key . '.value IN ("%s")'; 
      where[0]['args'][] = $value; 
    }
  }
} 

One of the search facets was a taxonomy filter which the user was allowed to multi select. In order to get the view to grab the correct values, I had to add join clauses to dynamically create term_node table aliases. This is done by adding a join clause to the table_queue and tables array elements within the query object. I was able to just copy the existing term_node table_queue and tables array elements because I only wanted to create different aliases. Then I incremented the existing term_node table count within the tables array. If you wanted to create a new table join dynamically, the same approach is used but the table_queue and tables definitions need to be created by hand.

foreach($parsed_url AS $key => $value) { 
  $vid = _search_get_vocabulary_id(str_replace('_', ' ', $key)); 
  $tid = _search_get_term_by_vocabulary($vid, $value); 
  $table_term_node_join = $query->table_queue['term_node']; 
  $query->table_queue['term_node_' . $count] = $table_term_node_join; 
  $query->table_queue['term_node_' . $count]['alias'] = 'term_node_' . $count; $query->tables['term_node']['count']++; 
  $query->where[0]['args'][] = $tid->tid; 
  $query->where[0]['clauses'][] .= 'term_node_' . $count . '.tid = %d'; $count++; 
} 

 The query table_queue and tables array elements looks like so:

 

Table Queue:
'table_queue' => array (
  'term_node' => array (
    'table' => 'term_node',
    'num' => 1,
    'alias' => 'term_node',
    'join' => views_join::__set_state(array(
      'definition' => array (
      'left_field' => 'vid',
      'field' => 'vid',
      'table' => 'term_node',
      'left_table' => 'node',
    ),
    'extra_type' => 'AND',
    'table' => 'term_node',
    'left_table' => 'node',
    'left_field' => 'vid',
    'field' => 'vid',
    'type' => 'LEFT',
    'adjusted' => true,
    )
  )

Tables:
'tables' => array (
    'node' => array (
      'node' => array (
      'count' => 1,
      'alias' => 'node',
      ),
    'term_node' => array (
      'count' => 1,
      'alias' => 'term_node',
    )
  ),
);

 

In my book this makes views more comfortable to use because it gives me more control over them. This along with a view preprocessor allows me to style and output pretty much anything I want within a view.

Building Rich Internet Apps with Drupal & HTML5
Learn the power of combining Drupal + HTML5 + CSS3 + JS
Read Next

Create an XSD from XML

29 October, 2010|2 min
Get in touch and let’s get started.

We are a full service digital consultancy with experience and capacity to meet the needs of even the largest most complex of organizations in the world. Our services portfolio enables us to offer clients the best of experiences when working with our teams so as to make sure we keep the focus on their needs, customers and delivering tangible value to the business. End to end services; endless ideas. 

Three easy ways to get in touch. Complete the form to request a consultation, email us your inquiry, specs and/or RFP to contact@appnovation.com OR call one of our many, global office locations and tell us how we can help.