Search code examples
phpdrupaldrupal-views

Custom logic for exposed filters in a Drupal view


I'm working on a Drupal site and would love some advice on this. Currently, a user enters his level for a number of different skills. This is stored in a CCK integer field and exposed to the user as a drop-down widget containing the key/value pairs 1|Beginner, 2|Intermediate, 3|Advanced.

In a view, I expose the allowed values for each skill, which are presented to the user as checkboxes (using the Better Exposed Filters module) and then listed in a sortable table. In practice, users generally search for people who have "at least knowledge level X in skill Y". Is there a module or straightforward way to display the allowed values as a drop-down and use a "greater than" operator in the query instead of a "one of"?

Any sample code or advice on how to dynamically change the filter logic or the WHERE clause of the query would be very appreciated.


Solution

  • You want to use hook_views_query_alter(), while I haven't specifically altered the WHERE clause, I have altered the SORTBY clause and the idea behind both should be relatively similar.

    Here's a quick piece of code:

    function my_module_views_query_alter(&$view, &$query) {
      switch ($view->name) {
        case 'view1':
          $args = _my_module_get_querystring();
          switch ($args['condition']) {
            case 'condition1':
              $query->where[0]['args'][0] = 1;
              break;
    
            case 'condition2':
              $query->where[0]['args'][0] = 2;
              break;
          }
          break;
      }
    }
    
    /**
     * Returns querystring as an array.
     */
    function _my_module_get_querystring() {
      $string = drupal_query_string_encode($_REQUEST, array_merge(array('q'), array_keys($_COOKIE)));
      $args = explode('&', $string);
      foreach ($args as $id => $string) {
        unset($args[$id]);
        $string = explode('=', $string);
        $args[$string[0]] = str_replace(' ', '-', $string[1]);
      }
      return $args;
    }
    

    This particular piece would allow you to alter the WHERE clause using a querystring (?condition=condition1), but you could alter it to get the arguments however you wish.

    Hope this helps.