Skip to content

Instantly share code, notes, and snippets.

@RuZniki
Created December 28, 2016 15:52
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save RuZniki/9ad13ca2ef3dc42eaade2e90f744e79c to your computer and use it in GitHub Desktop.
Оператор между для search_api_solr
<?php
/**
* Implements hook_search_api_solr_query_alter()
*
* В SearchApiSolrService::createFilterQuery Нету оператора "между".
* При использовании facetapi ranges с multivalued полями, возникают проблемы.
* @see https://www.drupal.org/node/1783746#comment-11813009
* Чтобы не хачить сразу кучу модулей, мы добавим костыль сюда.
* Если пользователь в запросе выбрал наш фасет, то мы удаляем значения фильтра,
* которые используют этот же фасет и вставляем наш фильтр вида [40 от 50].
*
*/
function HOOK_search_api_solr_query_alter(array &$call_args, SearchApiQueryInterface $query) {
// Наш фасетик. Вот тут надо изменить. Посмотреть список фасетов dpm($enabled_facets);
$facet_names = array('field_product:commerce_price:amount_decimal');
$index = $query->getIndex();
if ($index->server()->supportsFeature('search_api_facets')) {
$searcher = 'search_api@' . $index->machine_name;
$enabled_facets = facetapi_get_enabled_facets($searcher);
foreach ($facet_names as $facet_name) {
if (isset($enabled_facets[$facet_name])) {
_HOOK_search_query_between($facet_name, $call_args, $query);
}
}
}
}
/**
* @see HOOK_search_api_solr_query_alter
*/
function _HOOK_search_query_between($facet_name, array &$call_args, SearchApiQueryInterface $query) {
// Надо получить facetapi_adapter. @see search_api_facetapi_search_api_query_alter().
$index = $query->getIndex();
if ($index->server()->supportsFeature('search_api_facets')) {
$searcher = 'search_api@' . $index->machine_name;
$enabled_facets = facetapi_get_enabled_facets($searcher);
if (!isset($enabled_facets[$facet_name])) {
// Этот фасет сейчас не работает.
return;
}
$adapter = facetapi_adapter_load($searcher);
if ($adapter) {
// Получаем значение фасета из GET параметра.
$facet_value = $adapter->getActiveItems(array('name' => $facet_name));
if (!empty($facet_value) && is_array($facet_value)) {
// Плевать на всех, берем только первое значение.
$item = current($facet_value);
// @see FacetapiQueryTypeRange::extract.
if (preg_match(FACETAPI_REGEX_RANGE, $item['value'], $matches)) {
$facet_value = array(
'@start' => $matches[1],
'@end' => $matches[2],
);
// Обрабатываем значения. Т.к. нет доступа к $adapter->formatFilterValue,
// а у нас тип decimal, то вручную делаем phrase.
foreach ($facet_value as &$val) {
$val = trim($val);
if ($val === '*') {
$val = '*';
}
else {
$val = SearchApiSolrConnection::phrase($val);
}
}
if (!empty($call_args['params']['fq']) && is_array($call_args['params']['fq'])) {
$fq = &$call_args['params']['fq'];
$prefix = "{!tag=facet:$facet_name}";
foreach ($fq as $fq_key => $fq_val) {
// Если уже существующий фильтр начинается, также как и наш, уберем его.
if (substr($fq_val, 0, strlen($prefix)) == $prefix) {
// Легкий способ получить значение фильтра.
// Найти последнее : и обрезать строку до нее.
$last_colon = strrpos($fq_val, ':');
if ($last_colon === FALSE) {
return;
}
$filter_template = substr($fq_val, 0, $last_colon);
if ($filter_template === FALSE) {
return;
}
unset($call_args['params']['fq'][$fq_key]);
}
}
if (isset($filter_template)) {
$filter_value = $filter_template . strtr(':[@start TO @end]', $facet_value);
$fq[] = $filter_value;
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment