Drupal 6: Passing date ranges into a view as arguments

At some point you might want to pass date ranges as arguments to a view. Unfortunately the built-in functionality of views does not allow you to use a date argument as a range. If you try to specify the date arguments by editing your view, the views module will automatically insert SQL to match the dates exactly, which will not work in this scenario. Assuming that you already have a view and a content type that has two fields for start and date ranges, you can add a hook_db_rewrite_sql() function to add your own SQL to the view’s query.

<?php
// define the db_rewrite_sql hook:
function MYMODULE_db_rewrite_sql($query, $primary_table = 'n', $primary_field = 'nid', $args = array()) {
  // search for the view
  if (is_object($args['view']) && $args['view']->name=='MYVIEWNAME') {
    // if there are no view arguments, don't bother continuing
    if (!is_array($args['view']->args)) return;

    // get the start and end date ranges from the view arguments
    // NOTE: if you don't know which arguments are which,
    // you can use: print_r($args['view']->args)
    $startDate = $args['view']->args[0];
    $endDate = $args['view']->args[1];

    // validate dates. exit function if issue
    if (strlen($startDate) && !checkdate(date('m', strtotime($startDate)), date('d', strtotime($startDate)), date('Y', strtotime($startDate)))) return;
    if (strlen($endDate) && !checkdate(date('m', strtotime($endDate)), date('d', strtotime($endDate)), date('Y', strtotime($endDate)))) return;

    // create var for where clause
    $where = "";

    // define table alias
    $tableAlias = 'MYALIASNAME';

    if ($startDate) {
      $where = " {$tableAlias}.field_start_date_value >= '$startDate' ";
    }

    if ($endDate) {
      if (strlen($where)) $where .= " and ";
        $where .= " {$tableAlias}.field_end_date_value <= '$endDate' ";
    }

    if (strlen($where)) {
      return array('join' => "inner join {content_type_MYCONTENTYPE} $tableAlias on node.vid = $tableAlias.vid and $where");
    }

  }

}
?>

Now you can pass the date ranges in as arguments using the views_embed_view function:

<?php
$viewName = 'MYVIEWNAME';
$arg = array('2008-01-01','2008-12-31');
$viewsHtml = views_embed_view($viewName, 'default', $arg);
?>

Update 2011-02-14:

Seems that you actually don’t need to do a rewrite of the sql with complex code. You can do it like this:

<?php
$view = views_get_view('your_view');
$args[] = '2008-11-12--2010-11-12'; // from - to arguments
$view->set_arguments($args);
$view->build('default');
$view->pre_execute('default');
$view->execute('default');
$output = $view->render();
?>

Since views_embed_view is a wrapper around views_get_view(), this might work too:

<?php
$viewName = 'MYVIEWNAME';
$arg = array('2008-01-01--2008-12-31');
$viewsHtml = views_embed_view($viewName, 'default', $arg);
?>

Updated: