View source
<?php
namespace Drupal\jsonapi_search_api_facets\Plugin\facets\url_processor;
use Drupal\Core\Url;
use Drupal\facets\FacetInterface;
use Drupal\facets\Plugin\facets\url_processor\QueryString;
use Drupal\jsonapi\Query\Filter;
use Drupal\jsonapi\Query\OffsetPage;
use Drupal\jsonapi_search_api_facets\Plugin\facets\facet_source\JsonApiFacets;
class JsonApiQueryString extends QueryString {
protected $filterKey = Filter::KEY_NAME;
protected $originalFilters = [];
protected function initializeActiveFilters() {
$url_parameters = $this->request->query;
$active_params = $url_parameters
->get($this->filterKey, []);
$facet_source_id = $this->configuration['facet']
->getFacetSourceId();
if (!is_array($active_params)) {
return;
}
foreach ($active_params as $param_identifier => $param_value) {
if (is_array($param_value)) {
if (isset($param_value['condition'])) {
$facet_id = $this
->getFacetIdByUrlAlias($param_value['condition']['path'], $facet_source_id);
if ($facet_id === NULL) {
$this->originalFilters[$param_identifier] = $param_value;
continue;
}
$this->activeFilters[$facet_id] = [];
if (isset($param_value['condition']['value'])) {
foreach ($param_value['condition']['value'] as $condition_value) {
$this->activeFilters[$facet_id][] = $condition_value;
}
}
}
else {
$this->originalFilters[$param_identifier] = $param_value;
}
}
else {
$facet_id = $this
->getFacetIdByUrlAlias($param_identifier, $facet_source_id);
if ($facet_id === NULL) {
$this->originalFilters[$param_identifier] = $param_value;
}
else {
$this->activeFilters[$facet_id] = $param_value;
}
}
}
}
public function setActiveItems(FacetInterface $facet) {
if (isset($this->activeFilters[$facet
->id()])) {
$active_filters = $this->activeFilters[$facet
->id()];
if (is_array($active_filters)) {
$facet
->setActiveItems($active_filters);
}
else {
$facet
->setActiveItem($active_filters);
}
}
}
public function buildUrls(FacetInterface $facet, array $results) {
if (empty($results)) {
return [];
}
$facet_source = $facet
->getFacetSource();
if (!$facet_source instanceof JsonApiFacets) {
return [];
}
$get_params = $this->request->query;
if ($get_params
->has(OffsetPage::KEY_NAME)) {
$page_params = $get_params
->get(OffsetPage::KEY_NAME);
unset($page_params[OffsetPage::OFFSET_KEY]);
$get_params
->set(OffsetPage::KEY_NAME, $page_params);
}
$this->urlAlias = $facet
->getUrlAlias();
$facet_source_path = $facet
->getFacetSource()
->getPath();
$request = $this
->getRequestByFacetSourcePath($facet_source_path);
$requestUrl = $this
->getUrlForRequest($facet_source_path, $request);
$original_filter_params = [];
foreach ($this
->getActiveFilters() as $facet_id => $value) {
$facet_url_alias = $this
->getUrlAliasByFacetId($facet_id, $facet
->getFacetSourceId());
$this
->addToFilter($facet_url_alias, $value, $original_filter_params);
}
foreach ($results as &$result) {
$url = clone $requestUrl;
if ($children = $result
->getChildren()) {
$this
->buildUrls($facet, $children);
}
$filter_string = $result
->getRawValue();
$result_get_params = clone $get_params;
$filter_params = $original_filter_params;
if ($filter_string !== NULL) {
$this
->addToFilter($this->urlAlias, $filter_string, $filter_params);
}
if ($result
->isActive()) {
if ($facet
->getEnableParentWhenChildGetsDisabled() && $facet
->getUseHierarchy()) {
$parent_ids = $facet
->getHierarchyInstance()
->getParentIds($result
->getRawValue());
if (isset($parent_ids[0]) && $parent_ids[0]) {
$child_ids = $facet
->getHierarchyInstance()
->getNestedChildIds($parent_ids[0]);
$active_sibling = FALSE;
if ($child_ids) {
foreach ($results as $result2) {
if ($result2
->isActive() && $result2
->getRawValue() != $result
->getRawValue() && in_array($result2
->getRawValue(), $child_ids)) {
$active_sibling = TRUE;
continue;
}
}
}
if (!$active_sibling) {
$this
->addToFilter($this->urlAlias, $parent_ids[0], $filter_params);
}
}
}
}
else {
if ($facet
->getUseHierarchy()) {
$parent_ids = $facet
->getHierarchyInstance()
->getParentIds($result
->getRawValue());
$child_ids = $facet
->getHierarchyInstance()
->getNestedChildIds($result
->getRawValue());
$parents_and_child_ids = array_merge($parent_ids, $child_ids);
foreach ($parents_and_child_ids as $id) {
$filter_params = array_diff($filter_params, [
$id,
]);
}
}
if ($facet
->getShowOnlyOneResult()) {
foreach ($results as $result2) {
if ($result2
->isActive()) {
$active_filter_string = $result2
->getRawValue();
foreach ($filter_params as $filter_key => $filter_values) {
if (in_array($active_filter_string, $filter_values)) {
$filter_params[$filter_key] = array_diff($filter_values, [
$active_filter_string,
]);
}
}
}
}
}
}
$result_get_params
->remove('filter');
$result_get_params
->set('filter', $this->originalFilters);
foreach ($filter_params as $filter_path => $values) {
$existing_params = $result_get_params
->all();
if (count($values) === 1) {
$value = reset($values);
$params = array_merge_recursive($existing_params, [
'filter' => [
$filter_path => $value,
],
]);
}
else {
$filter_key = strtr('!field-facet', [
'!field' => $filter_path,
]);
$params = array_merge_recursive($existing_params, [
'filter' => [
$filter_key => [
'condition' => [
'path' => $filter_path,
'operator' => 'IN',
'value' => [],
],
],
],
]);
foreach ($values as $value) {
$params['filter'][$filter_key]['condition']['value'][] = $value;
}
}
$result_get_params
->add($params);
}
if ($result_get_params
->all() !== [
$this->filterKey => [],
]) {
$new_url_params = $result_get_params
->all();
$url
->setOption('query', $new_url_params);
}
$result
->setUrl($url);
}
return $results;
}
private function addToFilter($key, $values, array &$filter_params) {
if (!isset($filter_params[$key])) {
$filter_params[$key] = [];
}
if (!is_array($values)) {
$values = [
$values,
];
}
foreach ($values as $value) {
if (!in_array($value, $filter_params[$key], TRUE)) {
$filter_params[$key][] = $value;
}
}
}
}