Commit 7be5fc3b authored by Nick_vh's avatar Nick_vh Committed by Nick_vh

Issue #2610764 by Nick_vh: Move Query Types back to Facet APi

parent f5cd4ef8
......@@ -107,8 +107,8 @@ script:
- git clone --branch 8.x-1.x http://git.drupal.org/project/search_api.git
- cd search_api
# Apply patch to Search API module for getting the default query types for a backend.
- wget -q https://www.drupal.org/files/issues/2600442-15--facetapi_support.patch
- git apply 2600442-15--facetapi_support.patch
- wget -q https://www.drupal.org/files/issues/2600442-21.patch
- git apply 2600442-21.patch
- cd -
- drupal-ti script
......
<?php
/**
* @file
* Hooks provided by the Facet API module.
*/
/**
* @addtogroup hooks
* @{
*/
/**
* Alter the Facet API Query Type mapping
*
* Modules may implement this hook to alter the mapping that defines how a
* certain data type should be handled in Search API based Facets.
*
* @param array $query_types
* The Search API backend info array, keyed by backend ID.
*
* @see \Drupal\facetapi\Plugin\facetapi\facet_source\SearchApiBaseFacetSource
*/
function hook_facetapi_search_api_query_type_mapping_alter($backend_plugin_id, array &$query_types) {
if ($backend_plugin_id == 'search_api_solr') {
$query_types['string'] = 'search_api_solr_string';
}
}
......@@ -10,6 +10,7 @@ use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\facetapi\Exception\InvalidQueryTypeException;
use Drupal\facetapi\FacetInterface;
use Drupal\search_api\Backend\BackendInterface;
use Drupal\facetapi\FacetSource\FacetSourceInterface;
use Drupal\facetapi\FacetSource\FacetSourcePluginBase;
use Drupal\search_api\FacetApiQueryTypeMappingInterface;
......@@ -100,15 +101,65 @@ abstract class SearchApiBaseFacetSource extends FacetSourcePluginBase {
// Get the Search API Backend.
$backend = $server->getBackend();
if ($backend instanceof FacetApiQueryTypeMappingInterface) {
$fields = $this->index->getFields(true);
foreach ($fields as $field) {
if ($field->getFieldIdentifier() == $field_id) {
return $backend->getQueryTypesForDataType($field->getType());
}
$fields = $this->index->getFields(true);
foreach ($fields as $field) {
if ($field->getFieldIdentifier() == $field_id) {
return $this->getQueryTypesForDataType($backend, $field->getType());
}
}
throw new InvalidQueryTypeException($this->t("No available query types were found for facet @facet", ['@facet' => $facet->getName()]));
}
/**
* Retrieves the query types for a specified data type.
*
* Backend plugins can use this method to override the default query types
* provided by the Search API with backend-specific ones that better use
* features of that backend.
*
* @param \Drupal\search_api\Backend\BackendInterface $backend
* The backend that we want to get the query types for.
*
* @param string $data_type_plugin_id
* The identifier of the data type.
*
* @return string[]
* An associative array with the plugin IDs of allowed query types, keyed by
* the generic name of the query_type.
*
* @see hook_facetapi_search_api_query_type_mapping_alter()
*/
public function getQueryTypesForDataType(BackendInterface $backend, $data_type_plugin_id) {
$query_types = [];
// @todo Make this flexible for each data type in Search API.
switch($data_type_plugin_id) {
case 'boolean':
case 'date':
case 'decimal':
case 'integer':
case 'string':
case 'text':
$query_types['string'] = 'search_api_string';
break;
}
// Find out if the backend implemented the Interface to retrieve specific
// query types for the supported data_types
if ($backend instanceof FacetApiQueryTypeMappingInterface) {
// If the input arrays have the same string keys, then the later value
// for that key will overwrite the previous one. If, however, the arrays
// contain numeric keys, the later value will not overwrite the original
// value, but will be appended.
$query_types = array_merge($query_types, $backend->getQueryTypesForDataType($data_type_plugin_id));
}
// Add it to a variable so we can pass it by reference. Alter hook complains
// due to the property of the backend object is not passable by reference.
$backend_plugin_id = $backend->getPluginId();
// Let modules alter this mapping.
\Drupal::moduleHandler()->alter('facetapi_search_api_query_type_mapping', $backend_plugin_id, $query_types);
return $query_types;
}
}
<?php
/**
* @file
* Contains \Drupal\facetapi\Plugin\facetapi\query_type\SearchApiString
*/
namespace Drupal\facetapi\Plugin\facetapi\query_type;
use Drupal\facetapi\QueryType\QueryTypePluginBase;
use Drupal\facetapi\Result\Result;
/**
* Provides support for string facets within the Search API scope.
*
* This is the default implementation that works with all backends and data
* types. While you could use this query type for every data type, other query
* types will usually be better suited for their specific data type.
*
* For example, the SearchApiDate query type will handle its input as a DateTime
* value, while this class would only be able to work with it as a string.
*
* @FacetApiQueryType(
* id = "search_api_string",
* label = @Translation("String"),
* )
*/
class SearchApiString extends QueryTypePluginBase {
/**
* Holds the backend's native query object.
*
* @var \Drupal\search_api\Query\QueryInterface
*/
protected $query;
/**
* {@inheritdoc}
*/
public function execute() {
$query = $this->query;
// Alter the query here.
if (!empty($query)) {
$options = &$query->getOptions();
$field_identifier = $this->facet->getFieldIdentifier();
$options['search_api_facets'][$field_identifier] = array(
'field' => $field_identifier,
'limit' => 50,
'operator' => 'and',
'min_count' => 0,
'missing' => FALSE,
);
// Add the filter to the query if there are active values.
$active_items = $this->facet->getActiveItems();
if (count($active_items)) {
foreach ($active_items as $value) {
$filter = $query->createFilter();
$filter->condition($this->facet->getFieldIdentifier(), $value);
$query->filter($filter);
}
}
}
}
/**
* {@inheritdoc}
*/
public function build() {
if (!empty ($this->results)) {
$facet_results = array();
foreach ($this->results as $result) {
if ($result['count']) {
$facet_results[] = new Result(trim($result['filter'], '"'), trim($result['filter'], '"'), $result['count']);
}
}
$this->facet->setResults($facet_results);
}
return $this->facet;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment