You are here

class date_api_argument_handler in Date 6

Same name and namespace in other branches
  1. 6.2 includes/date_api_argument_handler.inc \date_api_argument_handler

Date API argument handler.

Hierarchy

Expanded class hierarchy of date_api_argument_handler

1 string reference to 'date_api_argument_handler'
date_api_views_data in ./date_api.views.inc
Implementation of hook_views_data()

File

./date_api.views.inc, line 103
Defines date-related Views data and plugins:

View source
class date_api_argument_handler extends views_handler_argument_formula {
  function construct() {
    parent::construct();
    include_once './' . drupal_get_path('module', 'date_api') . '/date_api_sql.inc';
    $this->date_handler = new date_sql_handler();
    $this->date_handler
      ->construct();
    $this->date_handler->granularity = $this->options['granularity'];
    if (isset($this->definition['content_field'])) {
      $this->date_handler->date_type = $this->definition['content_field']['type'];
      $this->content_field = content_fields($this->definition['content_field_name']);
      $this->additional_fields = $this->definition['additional fields'];
    }
  }

  /**
   * Get granularity and use it to create the formula and a format
   * for the results.
   */
  function init(&$view, $options) {
    parent::init($view, $options);
    $date_handler = $this->date_handler;
    $this->format = $date_handler
      ->views_formats($date_handler->granularity, 'display');
    $this->sql_format = $date_handler
      ->views_formats($date_handler->granularity, 'sql');
  }

  /**
   * Default value for the date_fields option.
   */
  function options(&$options) {
    parent::options($options);
    $options['date_fields'] = array();
    $options['date_method'] = 'OR';
    $options['granularity'] = 'month';
  }

  /**
   * Add a form element to select date_fields for this argument.
   */
  function options_form(&$form, &$form_state) {
    parent::options_form($form, $form_state);
    $options = $this->date_handler
      ->date_parts();
    unset($options['second'], $options['minute']);
    $options += array(
      'week' => t('Week'),
    );
    $form['granularity'] = array(
      '#title' => t('Granularity'),
      '#type' => 'radios',
      '#options' => $options,
      '#default_value' => $this->options['granularity'],
      '#multiple' => TRUE,
      '#description' => t('Select the type of date value to be used in defaults, summaries, and navigation. For example, a granularity of \'month\' will set the default date to the current month, summarize by month in summary views, and link to the next and previous month when using date navigation.'),
    );
    $fields = date_api_fields();
    $options = array();
    foreach ($fields['name'] as $name => $field) {
      $options[$name] = $field['label'];
    }
    $form['date_fields'] = array(
      '#title' => t('Date field(s)'),
      '#type' => 'checkboxes',
      '#options' => $options,
      '#default_value' => $this->options['date_fields'],
      '#multiple' => TRUE,
      '#description' => t('Select one or more date fields to filter with this argument.'),
    );
    $form['date_method'] = array(
      '#title' => t('Method'),
      '#type' => 'radios',
      '#options' => array(
        'OR' => t('OR'),
        'AND' => t('AND'),
      ),
      '#default_value' => $this->options['date_method'],
      '#description' => t('Method of handling multiple date fields in the same query. Return items that have any matching date field (date = field_1 OR field_2), or only those with matches in all selected date fields (date = field_1 AND field_2).'),
    );
  }
  function options_validate($form, &$form_state) {
    if (empty($form_state['values']['options']['date_fields'])) {
      form_error($form, t('You must select at least one date field for this argument.'));
    }
  }
  function options_submit($form, &$form_state) {
    $form_state['values']['options']['date_fields'] = array_filter($form_state['values']['options']['date_fields']);
  }

  // Update the summary values to show selected granularity.
  function admin_summary() {
    if (!empty($this->options['date_fields'])) {
      return ' (' . implode(', ', $this->options['date_fields']) . ')';
    }
    else {
      return parent::admin_summary();
    }
  }

  /**
   * Provide a link to the next level of the view from the summary.
   */
  function summary_name($data) {
    $format = $this->date_handler
      ->views_formats($this->options['granularity'], 'display');
    $created = $data->{$this->name_alias};
    return format_date(strtotime($created), 'custom', $format, 0);
  }

  /**
   * Need to override the basic link since base_alias is now a formula.
   */
  function summary_link($data, $url) {
    $value = $data->{$this->name_alias};
    return url("{$url}/{$value}");
  }

  /**
   * Provide a link to the next level of the view from the argument.
   */
  function title() {
    $format = $this->date_handler
      ->views_formats($this->options['granularity'], 'display');
    return format_date(strtotime($this->argument), 'custom', $format, 0);
  }

  /**
   * Create a summary query that matches the granularity.
   *
   * Needed or Views will do a groupby on the complete date instead
   * of only the part of the date actually used in the argument.
   */
  function summary_query() {
    $this
      ->get_query_fields();

    // No way to do summaries on more than one field at a time.
    if (count($this->query_fields) > 1) {
      return;
    }
    $field = $this->query_fields[0]['field'];
    $date_handler = $this->query_fields[0]['date_handler'];

    // Get the SQL format for this granularity, like Y-m,
    // and use that as the grouping value.
    $format = $date_handler
      ->views_formats($this->options['granularity'], 'sql');
    $this->formula = $date_handler
      ->sql_format($format, $date_handler
      ->sql_field($field['fullname']));
    $this
      ->ensure_my_table();

    // Make sure this field is added to the query so we have all necessary tables.
    $this->query
      ->add_field($field['table_name'], $field['field_name']);

    // Add the computed field.
    $this->base_alias = $this->name_alias = $this->query
      ->add_field(NULL, $this->formula, $field['queryname']);
    $this->query
      ->set_count_field(NULL, $this->formula, $field['queryname']);
    return $this
      ->summary_basics(FALSE);
  }
  function get_query_fields() {
    $fields = date_api_fields();
    $fields = $fields['name'];
    $min_date = isset($this->min_date) ? $this->min_date : NULL;
    $min_utc = isset($this->min_utc) ? $this->min_utc : NULL;
    $max_date = isset($this->max_date) ? $this->max_date : NULL;
    $max_utc = isset($this->max_utc) ? $this->max_utc : NULL;
    foreach ($this->options['date_fields'] as $delta => $name) {
      if ($field = $fields[$name]) {
        $date_handler = new date_sql_handler();
        $date_handler
          ->construct($field['sql_type'], date_default_timezone_name());
        $tz_handling = $field['tz_handling'];
        switch ($tz_handling) {
          case 'date':
            $date_handler->db_timezone = 'UTC';
            $date_handler->local_timezone_field = $field['timezone_field'];
            $date_handler->local_offset_field = $field['offset_field'];
            $date_handler->min_date = $min_date;
            $date_handler->max_date = $max_date;
            break;
          case 'none':
            $date_handler->db_timezone = date_default_timezone_name();
            $date_handler->local_timezone = date_default_timezone_name();
            $date_handler->min_date = $min_date;
            $date_handler->max_date = $max_date;
            break;
          case 'utc':
            $date_handler->db_timezone = 'UTC';
            $date_handler->local_timezone = 'UTC';
            $date_handler->min_date = $min_utc;
            $date_handler->max_date = $max_utc;
            break;
          default:
            $date_handler->db_timezone = 'UTC';
            $date_handler->local_timezone = 'UTC';
            $date_handler->min_date = $min_utc;
            $date_handler->max_date = $max_utc;
            break;
        }
        $this->query_fields[] = array(
          'field' => $field,
          'date_handler' => $date_handler,
        );
      }
    }
  }

  /**
   * Set up the query for this argument.
   *
   * The argument sent may be found at $this->argument.
   */
  function query() {
    $parts = $this->date_handler
      ->arg_parts($this->argument);
    foreach ($parts[0]['date'] as $key => $part) {

      // The last part evaluated is the one that will 'stick'
      // as the date type.
      $this->date_type = $key;
      $this->{$key} = $part;
    }
    $range = $this->date_handler
      ->arg_range($this->argument);
    $min_date = $range[0];
    $max_date = $range[1];

    // Create min and max dates in both local and UTC time.
    // We'll compare fields to the UTC date whenever possible
    // to avoid the need to do timezone conversions. When that
    // isn't possible (the date is not stored in UTC or needs to
    // be converted back to a time that may be different than
    // the local timezone) we will have to do tz conversions in
    // the database.
    $this->min_date = $min_date;
    $this->min_utc = drupal_clone($min_date);
    date_timezone_set($this->min_utc, timezone_open('UTC'));
    $this->max_date = $max_date;
    $this->max_utc = drupal_clone($max_date);
    date_timezone_set($this->max_utc, timezone_open('UTC'));

    // Use set_where_group() with the selected date_method
    // of 'AND' or 'OR' to create the where clause.
    $this->query
      ->set_where_group($this->options['date_method'], 'date');
    $this
      ->ensure_my_table();
    $this
      ->get_query_fields();
    foreach ($this->query_fields as $query_field) {
      $field = $query_field['field'];
      $date_handler = $query_field['date_handler'];

      // Make sure this field is added to the query.
      $this->query
        ->add_field($field['table_name'], $field['field_name']);
      foreach ($field['related_fields'] as $related) {
        $bits = explode('.', $related);
        if ($bits[1] != $field['field_name']) {
          $this->query
            ->add_field($field['table_name'], $bits[1]);
        }
      }
      $from = $date_handler
        ->sql_where_date('DATE', $field['fullname'], '>=', date_format($date_handler->min_date, DATE_FORMAT_DATETIME));
      $to = $date_handler
        ->sql_where_date('DATE', $field['fullname'], '<=', date_format($date_handler->max_date, DATE_FORMAT_DATETIME));
      $sql = str_replace('***table***', $this->table_alias, "({$from} AND {$to})");
      if ($sql) {
        $this->query
          ->add_where('date', $sql);
      }
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
date_api_argument_handler::admin_summary function
date_api_argument_handler::construct function
date_api_argument_handler::get_query_fields function
date_api_argument_handler::init function Get granularity and use it to create the formula and a format for the results.
date_api_argument_handler::options function Default value for the date_fields option.
date_api_argument_handler::options_form function Add a form element to select date_fields for this argument.
date_api_argument_handler::options_submit function
date_api_argument_handler::options_validate function
date_api_argument_handler::query function Set up the query for this argument.
date_api_argument_handler::summary_link function Need to override the basic link since base_alias is now a formula.
date_api_argument_handler::summary_name function Provide a link to the next level of the view from the summary.
date_api_argument_handler::summary_query function Create a summary query that matches the granularity.
date_api_argument_handler::title function Provide a link to the next level of the view from the argument.