You are here

public function date_views_plugin_pager::query in Date 7.2

Same name and namespace in other branches
  1. 8 date_views/includes/date_views_plugin_pager.inc \date_views_plugin_pager::query()
  2. 7.3 date_views/includes/date_views_plugin_pager.inc \date_views_plugin_pager::query()

Modify the query for paging

This is called during the build phase and can directly modify the query.

Overrides views_plugin_pager::query

File

date_views/includes/date_views_plugin_pager.inc, line 151
Date pager.

Class

date_views_plugin_pager
Views pager plugin to page by month.

Code

public function query() {

  // By fetching our data from the exposed input, it is possible to feed
  // pager data through some method other than $_GET.
  $input = $this->view
    ->get_exposed_input();
  $value = NULL;
  if (!empty($input) && !empty($input[$this->options['date_id']])) {
    $value = $input[$this->options['date_id']];
  }

  // Bring the argument information into the view so our theme can access it.
  $i = 0;
  foreach ($this->view->argument as $id => &$argument) {
    if (date_views_handler_is_date($argument, 'argument')) {

      // If the argument is empty, nothing to do. This could be from an
      // argument that does not set a default value.
      if (empty($argument->argument) || empty($argument->date_handler)) {
        continue;
      }

      // Storing this information in the pager so it's available for summary
      // info. The view argument information is not otherwise accessible to
      // the pager. Not working right yet, tho.
      $date_handler = $argument->date_handler;
      $this->options['date_argument'] = $id;
      $this->options['granularity'] = $argument->date_handler->granularity;

      // Reset values set by argument if pager requires it.
      if (!empty($value)) {
        $this
          ->set_argument_value($argument, $value);
      }

      // The pager value might move us into a forbidden range, so test it.
      if ($this
        ->date_forbid($argument)) {
        $this->view->build_info['fail'] = TRUE;
        return;
      }

      // Write date_info to store information to be used in the theming
      // functions.
      if (empty($this->view->date_info)) {
        $this->view->date_info = new stdClass();
      }
      $this->view->date_info->granularity = $argument->date_handler->granularity;
      $format = $this->view->date_info->granularity == 'week' ? DATE_FORMAT_DATETIME : $argument->sql_format;
      $this->view->date_info->placeholders = isset($argument->placeholders) ? $argument->placeholders : $argument->date_handler->placeholders;
      $this->view->date_info->date_arg = $argument->argument;
      $this->view->date_info->date_arg_pos = $i;
      $this->view->date_info->limit = $argument->limit;
      $this->view->date_info->url = $this->view
        ->get_url();
      $this->view->date_info->pager_id = $this->options['date_id'];
      $this->view->date_info->date_pager_position = $this->options['pager_position'];
      $this->view->date_info->date_pager_format = $this->options['link_format'];
      $this->view->date_info->skip_empty_pages = $this->options['skip_empty_pages'] == 1;

      // Execute two additional queries to find the previous and next page
      // with values.
      if ($this->view->date_info->skip_empty_pages) {
        $q = clone $argument->query;
        $field = $argument->table_alias . '.' . $argument->real_field;
        $fieldsql = $date_handler
          ->sql_field($field);
        $fieldsql = $date_handler
          ->sql_format($format, $fieldsql);
        $q
          ->clear_fields();
        $q->orderby = array();
        $q
          ->set_distinct(TRUE, TRUE);

        // Date limits of this argument.
        $datelimits = $argument->date_handler
          ->arg_range($argument->limit[0] . '--' . $argument->limit[1]);

        // Find the first two dates between the minimum date and the upper
        // bound of the current value.
        $q
          ->add_orderby(NULL, $fieldsql, 'DESC', 'date');
        $this
          ->set_argument_placeholders($this->view->date_info->placeholders, $datelimits[0], $argument->max_date, $q, $format);
        $compiledquery = $q
          ->query();
        $compiledquery
          ->range(0, 2);
        $results = $compiledquery
          ->execute()
          ->fetchCol(0);
        $prevdate = array_shift($results);
        $prevdatealt = array_shift($results);

        // Find the first two dates between the lower bound
        // of the current value and the maximum date.
        $q
          ->add_orderby(NULL, $fieldsql, 'ASC', 'date');
        $this
          ->set_argument_placeholders($this->view->date_info->placeholders, $argument->min_date, $datelimits[1], $q, $format);
        $compiledquery = $q
          ->query();
        $compiledquery
          ->range(0, 2);
        $results = $compiledquery
          ->execute()
          ->fetchCol(0);
        $nextdate = array_shift($results);
        $nextdatealt = array_shift($results);

        // Set the default value of the query to $prevfirst or $nextfirst
        // when there is no value and $prevsecond or $nextsecond is set.
        if (empty($value)) {

          // @todo find out which of $prevdate or $nextdate is closest to the
          // default argument date value and choose that one.
          if ($prevdate && $prevdatealt) {
            $this
              ->set_argument_value($argument, $prevdate);
            $value = $prevdate;
            $prevdate = $prevdatealt;

            // If the first next date is the same as the first previous date,
            // move to the following next date.
            if ($value == $nextdate) {
              $nextdate = $nextdatealt;
              $nextdatealt = NULL;
            }
          }
          elseif ($nextdate && $nextdatealt) {
            $this
              ->set_argument_value($argument, $nextdate);
            $value = $nextdate;
            $nextdate = $nextdatealt;

            // If the first previous date is the same as the first next date,
            // move to the following previous date.
            if ($value == $prevdate) {
              $prevdate = $prevdatealt;
              $prevdatealt = NULL;
            }
          }
        }
        else {

          // $prevdate and $nextdate are the same as $value, so move to the
          // next values.
          $prevdate = $prevdatealt;
          $nextdate = $nextdatealt;
        }
        $this->view->date_info->prev_date = $prevdate ? new DateObject($prevdate, NULL, $format) : NULL;
        $this->view->date_info->next_date = $nextdate ? new DateObject($nextdate, NULL, $format) : NULL;
      }
      else {
        $this->view->date_info->prev_date = clone $argument->min_date;
        date_modify($this->view->date_info->prev_date, '-1 ' . $argument->date_handler->granularity);
        $this->view->date_info->next_date = clone $argument->min_date;
        date_modify($this->view->date_info->next_date, '+1 ' . $argument->date_handler->granularity);
      }

      // Write the date_info properties that depend on the current value.
      $this->view->date_info->year = date_format($argument->min_date, 'Y');
      $this->view->date_info->month = date_format($argument->min_date, 'n');
      $this->view->date_info->day = date_format($argument->min_date, 'j');
      $this->view->date_info->week = date_week(date_format($argument->min_date, DATE_FORMAT_DATE));
      $this->view->date_info->date_range = $argument->date_range;
      $this->view->date_info->min_date = $argument->min_date;
      $this->view->date_info->max_date = $argument->max_date;
    }
    $i++;
  }

  // Is this a view that needs to be altered based on a pager value? If there
  // is pager input and the argument has set the placeholders, swap the pager
  // value in for the placeholder set by the argument.
  if (!empty($value) && !empty($this->view->date_info->placeholders)) {
    $this
      ->set_argument_placeholders($this->view->date_info->placeholders, $this->view->date_info->min_date, $this->view->date_info->max_date, $this->view->query, $format);
  }
}