Take into consideration the following functional requirements:

Alter the exposed filters values of specific views based on external conditions.

Take into consideration the following code found in views 5.x-1.6:

function views_build_view

function views_build_view($type, &$view, $args = array(), $use_pager = false, $limit = 0, $page = 0, $offset = 0, $filters = NULL) {
  views_load_cache();

  // Fix a number of annoying whines when NULL is passed in..
  if ($args == NULL) {
    $args = array();
  }
  
  // if no filter values are passed in, get them from the $_GET array
  if ($filters == NULL) {
    $filters = views_get_filter_values();
  }

  views_set_current_view($view);

  $view->build_type = $type;
  $view->type = ($type == 'block' ? $view->block_type : $view->page_type);

  if ($view->view_args_php) {
    ob_start();
    $result = eval($view->view_args_php);
    if (is_array($result)) {
      $args = $result;
    }
    ob_end_clean();
  }

  $view->use_pager = $use_pager;
  $view->pager_limit = $limit;
  $view->current_page = $page;
  $view->offset = $offset;

  // Call a hook that'll let modules modify the view query before it is created
  foreach (module_implements('views_pre_query') as $module) {
    $function = $module .'_views_pre_query';
    $output .= $function($view);
  }

  $info = _views_get_query($view, $args, $filters);

Since the $filters variable is only used first on _views_get_query(), I think the code that gets $filters should be called right before calling _views_get_query() so that one can tamper with $_GET in hook_views_pre_query(). The way it is now, one cannot alter $_GET on a per view basis since views_set_current_view($view) is called AFTER views_get_filter_values(). By moving the function the way I suggest, it is possible to tamper/alter the $_GET values by implementing hook_views_pre_query($view) and see what is the current view and alter the $_GET (exposed filter's values) before they get read and used.

The new code would be:

NEW function views_build_view

function views_build_view($type, &$view, $args = array(), $use_pager = false, $limit = 0, $page = 0, $offset = 0, $filters = NULL) {
  views_load_cache();

  // Fix a number of annoying whines when NULL is passed in..
  if ($args == NULL) {
    $args = array();
  }
  
  views_set_current_view($view);

  $view->build_type = $type;
  $view->type = ($type == 'block' ? $view->block_type : $view->page_type);

  if ($view->view_args_php) {
    ob_start();
    $result = eval($view->view_args_php);
    if (is_array($result)) {
      $args = $result;
    }
    ob_end_clean();
  }

  $view->use_pager = $use_pager;
  $view->pager_limit = $limit;
  $view->current_page = $page;
  $view->offset = $offset;

  // Call a hook that'll let modules modify the view query before it is created
  foreach (module_implements('views_pre_query') as $module) {
    $function = $module .'_views_pre_query';
    $output .= $function($view);
  }

  // if no filter values are passed in, get them from the $_GET array
  if ($filters == NULL) {
    $filters = views_get_filter_values();
  }

  $info = _views_get_query($view, $args, $filters);

The patch (also attached) would be:

PATCH

--- sites/all/modules/contrib/views/views.module~       2008-04-04 14:29:44.000000000 -0400
+++ sites/all/modules/contrib/views/views.module        2008-04-04 14:34:38.000000000 -0400
@@ -524,11 +524,6 @@ function views_build_view($type, &$view,
     $args = array();
   }
   
-  // if no filter values are passed in, get them from the $_GET array
-  if ($filters == NULL) {
-    $filters = views_get_filter_values();
-  }
-
   views_set_current_view($view);
 
   $view->build_type = $type;
@@ -554,6 +549,11 @@ function views_build_view($type, &$view,
     $output .= $function($view);
   }
 
+  // if no filter values are passed in, get them from the $_GET array
+  if ($filters == NULL) {
+    $filters = views_get_filter_values();
+  }
+
   $info = _views_get_query($view, $args, $filters);
 
   if ($info['fail']) {

Comments/Suggestions/Questions?

CommentFileSizeAuthor
views_get_filters.patch822 bytesroychri

Comments

merlinofchaos’s picture

The downside to this change is that you would no longer be able to mess with $filters in the PHP arg code, which I am sure people are doing. That's a bad side effect.

roychri’s picture

Status: Needs review » Closed (won't fix)

Make sense. Thanks for the quick reply.

merlinofchaos’s picture

Status: Closed (won't fix) » Needs work

I'd be open to an alternative, though, because your issue is valid.

roychri’s picture

What if $filters and/or $args are passed to hook_views_pre_query() by reference?

views.module

// Call a hook that'll let modules modify the view query before it is created
foreach (module_implements('views_pre_query') as $module) {
  $function = $module .'_views_pre_query';
  $output .= $function($view, $filters, $args);
}

examples.module

function example_views_pre_query(&$view, &$filters, &$args) {
  // Modify the $filters array or the $args array (or the $views object)
}

The comment suggest that this hook allow us to modify the query before it gets run. Since the $filters and $args have a direct effect on the query, it might make sense to be able to modify them in there.

I will make the patch if I am going in the right direction :)

Another alternative would be to create a new hook, but the more hooks we add, the slower this module wil be. Should I be concerned about that?

Let me know your thoughts.

Thanks.

esmerel’s picture

Status: Needs work » Closed (won't fix)

No changes are being made to 1.x at this point.