Drupal - Add FILTER CRITERIA in Views Programmatically

Use the Devel module and dpm($view) and dpm($query) after you put like "[email protected]" into the "value" field found in your pic. See the object/array structure of the view and query from the devel output.

Then use the function hook_views_query_alter(&$view, &$query) in your module to target the WHERE condition filter condition and set it to the value you want.

Something like:

function MYMODULE_views_query_alter(&$view, &$query) {
  global $user;
  dpm($view, __FUNCTION__);
  dpm($query, __FUNCTION__);
  if ($view->name === 'your_view_machine_name') {
    // This will only work as-is if you always have something in the filter by
    // default, I guess. This hook runs always so you could just put
    // '[email protected]' as the email to filter by in views and this
    // will always override it. I'm sure there is a cleaner way to put
    // the filter dynamically at runtime. But i think thats more complex
    // php that customizes a view.
    //
    // The index 2 below is the index of the condition for the email filter.
    // Your $query structure may be different in your dpm() of the View $query.
    $query->where[1]['conditions'][2]['field']['value'] = $user->email;
  }
}

Here's an alternative:

$view = views_get_view('view_machine_name');
$view->init_display('default');
$view->display_handler->display->display_options['filters']['your_filter_name']['default_value'] = 'your_value';
$view->is_cacheable = FALSE;  
$view->execute();
print $view->render();

I know you should probably set this using some esoteric, convoluted method, but if you just want quick and dirty access without messing around this will get you there.


It would be preferable to alter these in hooks rather than at render time so that you are not undermining site performance and caching. Took me age to figure out that hook_views_pre_build() fires too late, you need hook_views_pre_view().

I found reference to using $view->add_item() but struggled for examples, below was my solution for filtering a set of taxonomy terms to only include certain vocabs:

function MODULENAME_views_pre_view(&$view, &$display_id, &$args) {

  if ($view->name == 'VIEWNAME' && $display_id == 'DISPLAYID') {
    // Add all the terms of a vocabulary to the terms listing widget select field
    $vids = array();
    $vocab = taxonomy_vocabulary_machine_name_load('vocab_name');
    $vids[ $vocab->vid ] = $vocab->vid;

    // Get the existing filters
    $filters = $view->display_handler->get_option('filters');

    if (empty($filters['vid'])) {
      // There is no vid filter so we have to add it
      $view->add_item(
        $view->current_display,
        'filter',
        'taxonomy_term_data',
        'vid',
        array(
          'operator' => 'in',
          'value' => $vids,
          'group' => 1
        )
      );
    }
    else {
      // Add to pre-existing filter
      foreach($vids as $vid) {
        $filters['vid']['value'][ $vid ] = $vid;
      }
      $view->display_handler->override_option('filters', $filters);
    }
  }
}

Edit note: This comment on d.o group helped me figure out how to get the views filters using $view->display_handler->get_option('filters') and to then override them using $view->display_handler->override_option('filters', $filters);.

Tags:

Views

7