Hi folks,
While working with Drupal 7/Views 3 recently, I found a necessity to use the MySQL "LIKE" operator in place of the hard-coded "=" in a contextual filter. On researching this, I couldn't find anywhere in Views where this could be set up. To me, it seems insane that this isn't in there already, so if there's any way of doing this in Views UI, please do let me know!
Anyway... What I needed was a contextual filter on the view which would find any node of a certain type which contained a particular string. If the string was static, I could have easily applied it as a filter criterion, however I needed to extract it from the URL. Not finding any simple way of applying a dynamic piece of text to a filter criterion, I decided that the most sensible option would be to try and modify the query. Fortunately, Views 3 provides this as a hook. The Drupal API documentation provides a list of all the Views hooks which are provided for your use.
In Drupal, to implement a hook, you need to write a custom module. I'll go through the whole process here, so no worries if you're not familiar with the process.
First, create a folder called "customviewsquery" under your Drupal installation, in the folder "sites/all/modules". Next, create the following file in the newly created folder.
name = Custom Views Query
description = Modifies a single Views 3 contextual filter to use LIKE instead of =
core = 7.x
package = Custom Code
Now create the following file:
<?php /**
* Implements hook_views_query_alter
*
* Finds the correct view, and calls a relevant callback
*/
function customviewsquery_views_query_alter(&$view, &$query) {
switch($view->name) {
case 'my_view_machine_name':
_customviewsquery_my_view_name_views_query_alter($view, $query);
break;
}
}
/**
* Callback to fix the Views 3 query object before execution
*/
function _customviewsquery_my_view_name_views_query_alter(&$view, &$query) {
// Loop through the conditional parts of the query, and
// * Change = to LIKE
// * Add SQL wildcard characters to both sides of the value
foreach($query->where as $key => $val) {
$field = $val['conditions'][0]['field'];
$operator = $val['conditions'][0]['operator'];
$value = $val['conditions'][0]['value'];
if($field == 'node.title' && $operator == '=') {
$query->where[$key]['conditions'][0]['operator'] = 'LIKE';
$query->where[$key]['conditions'][0]['value'] = '%' . $value . '%';
}
}
}
You should substitute "my_view_machine_name" for Drupal's machine name for the view you want to change, and "node.title" to the contextual filter you want to modify (referenced by its table and column reference in Drupal's database).
That's about it! Any questions or comments, fire away! I'm particularly interested to see if there is a way to do this in the Views UI.
n00b