You are here

class ApacheSolrFacetapiDate in Apache Solr Search 7

Same name and namespace in other branches
  1. 8 plugins/facetapi/query_type_date.inc \ApacheSolrFacetapiDate
  2. 6.3 plugins/facetapi/query_type_date.inc \ApacheSolrFacetapiDate

Plugin for "date" query types.

Hierarchy

Expanded class hierarchy of ApacheSolrFacetapiDate

1 string reference to 'ApacheSolrFacetapiDate'
apachesolr_facetapi_query_types in ./apachesolr.module
Implements hook_facetapi_query_types().

File

plugins/facetapi/query_type_date.inc, line 11
Date query type plugin for the Apache Solr adapter.

View source
class ApacheSolrFacetapiDate extends FacetapiQueryTypeDate implements FacetapiQueryTypeInterface {

  /**
   * Returns the query type associated with the plugin.
   *
   * @return string
   *   The query type.
   */
  public static function getType() {
    return 'date';
  }

  /**
   * Adds the filter to the query object.
   *
   * @param DrupalSolrQueryInterface $query
   *   An object containing the query in the backend's native API.
   */
  public function execute($query) {

    // Gets the data range in formats that Solr understands.
    $date_range = $this
      ->getDateRange($query);
    if (empty($date_range)) {
      return NULL;
    }
    list($start, $end, $gap) = $date_range;
    $facet_name = $query
      ->getSolrVersion() >= 6 ? 'facet.range' : 'facet.date';
    $query
      ->addParam($facet_name, $this->facet['field']);
    $query
      ->addParam('f.' . $this->facet['field'] . '.' . $facet_name . '.start', $start);
    $query
      ->addParam('f.' . $this->facet['field'] . '.' . $facet_name . '.end', $end);
    $query
      ->addParam('f.' . $this->facet['field'] . '.' . $facet_name . '.gap', $gap);

    // Adds "hard limit" parameter to prevent too many return values.
    $settings = $this->adapter
      ->getFacet($this->facet)
      ->getSettings();
    $limit = empty($settings->settings['hard_limit']) ? 20 : (int) $settings->settings['hard_limit'];
    $query
      ->addParam('f.' . $this->facet['field'] . '.facet.limit', $limit);
    $active = $this->adapter
      ->getActiveItems($this->facet);

    // Date filters don't support OR operator.
    foreach ($active as $value => $item) {
      $query
        ->addFilter($this->facet['field'], $value);
    }
  }

  /**
   * Gets the range of dates we are using.
   *
   * @param DrupalSolrQueryInterface $query
   *   A SolrBaseQuery object.
   *
   * @return bool|array
   *   An array containing the gap and range information or false if not present
   */
  function getDateRange(DrupalSolrQueryInterface $query) {
    $return = NULL;
    $gap = NULL;

    // Attempts to get next gap from passed date filters.
    foreach ($this->adapter
      ->getActiveItems($this->facet) as $item) {
      if ($gap = facetapi_get_date_gap($item['start'], $item['end'])) {
        $next_gap = facetapi_get_next_date_gap($gap, FACETAPI_DATE_SECOND);
        if ($next_gap == $gap) {
          $next_gap = NULL;
          return NULL;
        }
        $return = array(
          "{$item['start']}/{$next_gap}",
          "{$item['end']}+1{$next_gap}/{$next_gap}",
          "+1{$next_gap}",
        );
      }
    }

    // If no filters were passed, get default range.
    if (NULL === $return) {

      // Builds SQL that gets minimum and maximum values from node table.
      $minimum = $maximum = FALSE;
      if ($this->facet['min callback'] && is_callable($this->facet['min callback'])) {
        $minimum = $this->facet['min callback']($this->facet);
      }
      if ($this->facet['max callback'] && is_callable($this->facet['max callback'])) {
        $maximum = $this->facet['max callback']($this->facet);
      }

      // Gets the default gap.

      //$gap = FACETAPI_DATE_YEAR;
      if ($minimum && $maximum) {
        $gap = facetapi_get_timestamp_gap($minimum, $maximum);
        $minimum = facetapi_isodate($minimum, $gap);
        $maximum = facetapi_isodate($maximum, $gap);
        $return = array(
          "{$minimum}/{$gap}",
          "{$maximum}+1{$gap}/{$gap}",
          "+1{$gap}",
        );
      }
    }

    // Returns the range information.
    return $return;
  }

  /**
   * Initializes the facet's build array.
   *
   * @return array
   *   The initialized render array.
   */
  public function build() {

    // Initializes build and gets static response.
    if (!($response = apachesolr_static_response_cache($this->adapter
      ->getSearcher()))) {
      return array();
    }
    $build = array();

    // Gets total number of documents matched in search.
    $total = $response->response->numFound;

    // Gets the active date facets, starts to builds the "parent - child"
    // relationships.
    $parent = NULL;
    foreach ($this->adapter
      ->getActiveItems($this->facet) as $value => $item) {

      // Builds the raw facet "value", the count for selected items will be the
      // total number of rows returned in the query.
      $build[$value] = array(
        '#count' => $total,
      );

      // If there is a previous item, there is a parent, uses a reference so the
      // arrays are populated when they are updated.
      if (NULL !== $parent) {
        $build[$parent]['#item_children'][$value] =& $build[$value];
        $build[$value]['#item_parents'][$parent] = $parent;
      }

      // Stores the last value iterated over.
      $parent = $value;
    }

    // Gets raw facet data from the Solr server.
    // Check older versions first, then newer ones.
    if (isset($response->facet_counts->facet_dates) && isset($response->facet_counts->facet_dates->{$this->facet['field']})) {
      $raw_data = (array) $response->facet_counts->facet_dates->{$this->facet['field']};
      $raw_data['gap'] = FACETAPI_DATE_MINUTE;
      if (isset($response->facet_counts->facet_dates->{$this->facet['field']}->gap)) {
        $raw_data['gap'] = $response->facet_counts->facet_dates->{$this->facet['field']}->gap;
      }
    }
    elseif (isset($response->facet_counts->facet_ranges) && isset($response->facet_counts->facet_ranges->{$this->facet['field']}->counts)) {
      $raw_data = (array) $response->facet_counts->facet_ranges->{$this->facet['field']}->counts;
      $raw_data['gap'] = FACETAPI_DATE_MINUTE;
      if (isset($response->facet_counts->facet_ranges->{$this->facet['field']}->gap)) {
        $raw_data['gap'] = $response->facet_counts->facet_ranges->{$this->facet['field']}->gap;
      }
    }
    else {
      $raw_data = array();
    }

    //$end = (!empty($raw_data['end'])) ? $raw_data['end'] : '';

    //$start = (!empty($raw_data['start'])) ? $raw_data['start'] : '';
    $gap = !empty($raw_data['gap']) ? $raw_data['gap'] : '';
    $settings = $this
      ->getSettings()->settings;
    $granularity = isset($settings['date_granularity']) ? $settings['date_granularity'] : FACETAPI_DATE_MINUTE;

    // We cannot list anything below a minute (range of 00 seconds till 59
    // seconds). Milliseconds are not possible. Also, anything below the set
    // granularity should not be shown either.
    if ($gap != "+1" . FACETAPI_DATE_SECOND && (!$gap || strtotime($gap, 0) >= strtotime("+1" . $granularity, 0))) {
      unset($raw_data['start']);
      unset($raw_data['end']);
      unset($raw_data['gap']);

      // Treat each date facet as a range start, and use the next date facet
      // as range end.  Use 'end' for the final end.
      $previous = NULL;

      // Builds facet counts object used by the server.
      foreach ($raw_data as $value => $count) {
        if ($count) {
          $from = $value;
          $to = facetapi_isodate(strtotime($value . $gap));
          $new_value = '[' . $from . ' TO ' . $to . ']';
          $build[$new_value] = array(
            '#count' => $count,
            '#active' => 0,
          );
          if (NULL !== $parent) {
            $build[$parent]['#item_children'][$new_value] =& $build[$new_value];
            $build[$new_value]['#item_parents'][$parent] = $parent;
          }
        }
      }
    }
    return $build;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ApacheSolrFacetapiDate::build public function Initializes the facet's build array.
ApacheSolrFacetapiDate::execute public function Adds the filter to the query object.
ApacheSolrFacetapiDate::getDateRange function Gets the range of dates we are using.
ApacheSolrFacetapiDate::getType public static function Returns the query type associated with the plugin.