123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- <?php
- /**
- * @file
- * Term query type plugin for the Apache Solr adapter.
- */
- /**
- * Plugin for "term" query types.
- */
- class SearchApiFacetapiTerm extends FacetapiQueryType implements FacetapiQueryTypeInterface {
- /**
- * Returns the query type associated with the plugin.
- *
- * @return string
- * The query type.
- */
- static public function getType() {
- return 'term';
- }
- /**
- * Adds the filter to the query object.
- *
- * @param SearchApiQueryInterface $query
- * An object containing the query in the backend's native API.
- */
- public function execute($query) {
- // Return terms for this facet.
- $this->adapter->addFacet($this->facet, $query);
- $settings = $this->adapter->getFacet($this->facet)->getSettings()->settings;
- // First check if the facet is enabled for this search.
- $default_true = isset($settings['default_true']) ? $settings['default_true'] : TRUE;
- $facet_search_ids = isset($settings['facet_search_ids']) ? $settings['facet_search_ids'] : array();
- if ($default_true != empty($facet_search_ids[$query->getOption('search id')])) {
- // Facet is not enabled for this search ID.
- return;
- }
- // Retrieve the active facet filters.
- $active = $this->adapter->getActiveItems($this->facet);
- if (empty($active)) {
- return;
- }
- // Create the facet filter, and add a tag to it so that it can be easily
- // identified down the line by services when they need to exclude facets.
- $operator = $settings['operator'];
- if ($operator == FACETAPI_OPERATOR_AND) {
- $conjunction = 'AND';
- }
- elseif ($operator == FACETAPI_OPERATOR_OR) {
- $conjunction = 'OR';
- }
- else {
- throw new SearchApiException(t('Unknown facet operator %operator.', array('%operator' => $operator)));
- }
- $tags = array('facet:' . $this->facet['field']);
- $facet_filter = $query->createFilter($conjunction, $tags);
- foreach ($active as $filter => $filter_array) {
- $field = $this->facet['field'];
- $this->addFacetFilter($facet_filter, $field, $filter);
- }
- // Now add the filter to the query.
- $query->filter($facet_filter);
- }
- /**
- * Helper method for setting a facet filter on a query or query filter object.
- */
- protected function addFacetFilter($query_filter, $field, $filter) {
- // Test if this filter should be negated.
- $settings = $this->adapter->getFacet($this->facet)->getSettings();
- $exclude = !empty($settings->settings['exclude']);
- // Integer (or other nun-string) filters might mess up some of the following
- // comparison expressions.
- $filter = (string) $filter;
- if ($filter == '!') {
- $query_filter->condition($field, NULL, $exclude ? '<>' : '=');
- }
- elseif ($filter[0] == '[' && $filter[strlen($filter) - 1] == ']' && ($pos = strpos($filter, ' TO '))) {
- $lower = trim(substr($filter, 1, $pos));
- $upper = trim(substr($filter, $pos + 4, -1));
- if ($lower == '*' && $upper == '*') {
- $query_filter->condition($field, NULL, $exclude ? '=' : '<>');
- }
- elseif (!$exclude) {
- if ($lower != '*') {
- // Iff we have a range with two finite boundaries, we set two
- // conditions (larger than the lower bound and less than the upper
- // bound) and therefore have to make sure that we have an AND
- // conjunction for those.
- if ($upper != '*' && !($query_filter instanceof SearchApiQueryInterface || $query_filter->getConjunction() === 'AND')) {
- $original_query_filter = $query_filter;
- $query_filter = new SearchApiQueryFilter('AND');
- }
- $query_filter->condition($field, $lower, '>=');
- }
- if ($upper != '*') {
- $query_filter->condition($field, $upper, '<=');
- }
- }
- else {
- // Same as above, but with inverted logic.
- if ($lower != '*') {
- if ($upper != '*' && ($query_filter instanceof SearchApiQueryInterface || $query_filter->getConjunction() === 'AND')) {
- $original_query_filter = $query_filter;
- $query_filter = new SearchApiQueryFilter('OR');
- }
- $query_filter->condition($field, $lower, '<');
- }
- if ($upper != '*') {
- $query_filter->condition($field, $upper, '>');
- }
- }
- }
- else {
- $query_filter->condition($field, $filter, $exclude ? '<>' : '=');
- }
- if (isset($original_query_filter)) {
- $original_query_filter->filter($query_filter);
- }
- }
- /**
- * Initializes the facet's build array.
- *
- * @return array
- * The initialized render array.
- */
- public function build() {
- $facet = $this->adapter->getFacet($this->facet);
- // The current search per facet is stored in a static variable (during
- // initActiveFilters) so that we can retrieve it here and get the correct
- // current search for this facet.
- $search_ids = drupal_static('search_api_facetapi_active_facets', array());
- if (empty($search_ids[$facet['name']]) || !search_api_current_search($search_ids[$facet['name']])) {
- return array();
- }
- $search_id = $search_ids[$facet['name']];
- $search = search_api_current_search($search_id);
- $build = array();
- $results = $search[1];
- if (isset($results['search_api_facets']) && isset($results['search_api_facets'][$this->facet['name']])) {
- $values = $results['search_api_facets'][$this->facet['name']];
- foreach ($values as $value) {
- $filter = $value['filter'];
- // As Facet API isn't really suited for our native facet filter
- // representations, convert the format here. (The missing facet can
- // stay the same.)
- if ($filter[0] == '"') {
- $filter = substr($filter, 1, -1);
- }
- elseif ($filter != '!') {
- // This is a range filter.
- $filter = substr($filter, 1, -1);
- $pos = strpos($filter, ' ');
- if ($pos !== FALSE) {
- $filter = '[' . substr($filter, 0, $pos) . ' TO ' . substr($filter, $pos + 1) . ']';
- }
- }
- $build[$filter] = array(
- '#count' => $value['count'],
- );
- }
- }
- return $build;
- }
- }
|