Mercurial > hg > MPIWG-drupal-modules
comparison sites/all/modules/custom/solrsearch/plugins/facetapi/query_type_date.inc @ 0:015d06b10d37 default tip
initial
author | dwinter |
---|---|
date | Wed, 31 Jul 2013 13:49:13 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:015d06b10d37 |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * @file | |
5 * Date query type plugin for the Apache Solr adapter. | |
6 */ | |
7 | |
8 /** | |
9 * Plugin for "date" query types. | |
10 */ | |
11 class solrsearchFacetapiDate extends FacetapiQueryTypeDate implements FacetapiQueryTypeInterface { | |
12 | |
13 /** | |
14 * Returns the query type associated with the plugin. | |
15 * | |
16 * @return string | |
17 * The query type. | |
18 */ | |
19 static public function getType() { | |
20 return 'date'; | |
21 } | |
22 | |
23 /** | |
24 * Adds the filter to the query object. | |
25 * | |
26 * @param DrupalSolrQueryInterface $query | |
27 * An object containing the query in the backend's native API. | |
28 */ | |
29 public function execute($query) { | |
30 // Gets the data range in formats that Solr understands. | |
31 $date_range = $this->getDateRange($query); | |
32 if (empty($date_range)) { | |
33 return NULL; | |
34 } | |
35 list($start, $end, $gap) = $date_range; | |
36 $query->addParam('facet.date', $this->facet['field']); | |
37 $query->addParam('f.' . $this->facet['field'] . '.facet.date.start', $start); | |
38 $query->addParam('f.' . $this->facet['field'] . '.facet.date.end', $end); | |
39 $query->addParam('f.' . $this->facet['field'] . '.facet.date.gap', $gap); | |
40 | |
41 // Adds "hard limit" parameter to prevent too many return values. | |
42 $settings = $this->adapter->getFacet($this->facet)->getSettings(); | |
43 $limit = empty($settings->settings['hard_limit']) ? 20 : (int) $settings->settings['hard_limit']; | |
44 $query->addParam('f.' . $this->facet['field'] . '.facet.limit', $limit); | |
45 | |
46 $active = $this->adapter->getActiveItems($this->facet); | |
47 // Date filters don't support OR operator. | |
48 foreach ($active as $value => $item) { | |
49 $query->addFilter($this->facet['field'], $value); | |
50 } | |
51 } | |
52 | |
53 /** | |
54 * Gets the range of dates we are using. | |
55 * | |
56 * @param DrupalSolrQueryInterface $query | |
57 * A SolrBaseQuery object. | |
58 * | |
59 * @return bool|array | |
60 * An array containing the gap and range information or false if not present | |
61 */ | |
62 function getDateRange(DrupalSolrQueryInterface $query) { | |
63 $return = NULL; | |
64 $gap = NULL; | |
65 | |
66 // Attempts to get next gap from passed date filters. | |
67 foreach ($this->adapter->getActiveItems($this->facet) as $item) { | |
68 if ($gap = facetapi_get_date_gap($item['start'], $item['end'])) { | |
69 $next_gap = facetapi_get_next_date_gap($gap, FACETAPI_DATE_SECOND); | |
70 if ($next_gap == $gap) { | |
71 $next_gap = NULL; | |
72 return NULL; | |
73 } | |
74 $return = array( | |
75 "{$item['start']}/$next_gap", | |
76 "{$item['end']}+1$next_gap/$next_gap", | |
77 "+1$next_gap", | |
78 ); | |
79 } | |
80 } | |
81 | |
82 // If no filters were passed, get default range. | |
83 if (NULL === $return) { | |
84 | |
85 // Builds SQL that gets minimum and maximum values from node table. | |
86 $minimum = $maximum = FALSE; | |
87 if ($this->facet['min callback'] && is_callable($this->facet['min callback'])) { | |
88 $minimum = $this->facet['min callback']($this->facet); | |
89 } | |
90 if ($this->facet['max callback'] && is_callable($this->facet['max callback'])) { | |
91 $maximum = $this->facet['max callback']($this->facet); | |
92 } | |
93 | |
94 // Gets the default gap. | |
95 //$gap = FACETAPI_DATE_YEAR; | |
96 if ($minimum && $maximum) { | |
97 $gap = facetapi_get_timestamp_gap($minimum, $maximum); | |
98 $minimum = facetapi_isodate($minimum, $gap); | |
99 $maximum = facetapi_isodate($maximum, $gap); | |
100 $return = array( | |
101 "$minimum/$gap", | |
102 "$maximum+1$gap/$gap", | |
103 "+1$gap", | |
104 ); | |
105 } | |
106 } | |
107 // Returns the range information. | |
108 return $return; | |
109 } | |
110 | |
111 /** | |
112 * Initializes the facet's build array. | |
113 * | |
114 * @return array | |
115 * The initialized render array. | |
116 */ | |
117 public function build() { | |
118 | |
119 // Initializes build and gets static response. | |
120 if (!$response = solrsearch_static_response_cache($this->adapter->getSearcher())) { | |
121 return array(); | |
122 } | |
123 $build = array(); | |
124 | |
125 // Gets total number of documents matched in search. | |
126 $total = $response->response->numFound; | |
127 | |
128 // Gets the active date facets, starts to builds the "parent - child" | |
129 // relationships. | |
130 $parent = NULL; | |
131 foreach ($this->adapter->getActiveItems($this->facet) as $value => $item) { | |
132 // Builds the raw facet "value", the count for selected items will be the | |
133 // total number of rows returned in the query. | |
134 $build[$value] = array('#count' => $total); | |
135 | |
136 // If there is a previous item, there is a parent, uses a reference so the | |
137 // arrays are populated when they are updated. | |
138 if (NULL !== $parent) { | |
139 $build[$parent]['#item_children'][$value] = &$build[$value]; | |
140 $build[$value]['#item_parents'][$parent] = $parent; | |
141 } | |
142 | |
143 // Stores the last value iterated over. | |
144 $parent = $value; | |
145 } | |
146 | |
147 // Gets raw facet data from the Solr server. | |
148 if (isset($response->facet_counts->facet_dates) && isset($response->facet_counts->facet_dates->{$this->facet['field']})) { | |
149 $raw_data = (array) $response->facet_counts->facet_dates->{$this->facet['field']}; | |
150 } | |
151 else { | |
152 $raw_data = array(); | |
153 } | |
154 //$end = (!empty($raw_data['end'])) ? $raw_data['end'] : ''; | |
155 //$start = (!empty($raw_data['start'])) ? $raw_data['start'] : ''; | |
156 $gap = (!empty($raw_data['gap'])) ? $raw_data['gap'] : ''; | |
157 | |
158 // We cannot list anything below a minute (range of 00 seconds till 59 | |
159 // seconds. Milliseconds are not possible) | |
160 if ($gap != "+1SECOND") { | |
161 unset($raw_data['start']); | |
162 unset($raw_data['end']); | |
163 unset($raw_data['gap']); | |
164 | |
165 // Treat each date facet as a range start, and use the next date facet | |
166 // as range end. Use 'end' for the final end. | |
167 $previous = NULL; | |
168 | |
169 // Builds facet counts object used by the server. | |
170 foreach ($raw_data as $value => $count) { | |
171 if ($count) { | |
172 $from = $value; | |
173 $to = facetapi_isodate(strtotime($value . $gap)); | |
174 $new_value = '[' . $from . ' TO ' . $to . ']'; | |
175 $build[$new_value] = array('#count' => $count, '#active' => 0); | |
176 if (NULL !== $parent) { | |
177 $build[$parent]['#item_children'][$new_value] = &$build[$new_value]; | |
178 $build[$new_value]['#item_parents'][$parent] = $parent; | |
179 } | |
180 } | |
181 } | |
182 } | |
183 return $build; | |
184 } | |
185 } |