Skip to content

Commit

Permalink
Add handling for rating filter
Browse files Browse the repository at this point in the history
  • Loading branch information
TobiasGraml11 committed Nov 6, 2023
1 parent d355d47 commit 598a862
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@
propertyName: filter.name
} %}
{% endif %}

{% if filter is instanceof("\\Nosto\\NostoIntegration\\Search\\Response\\GraphQL\\Filter\\RatingFilter") %}
{% sw_include '@Storefront/storefront/component/listing/filter/filter-rating-select.html.twig' ignore missing with {
elements: filter.values,
maxPoints: filter.maxPoints,
sidebar: sidebar,
name: filter.id,
hidden: filter.hidden,
displayName: filter.name,
pluginSelector: 'filter-rating-select',
propertyName: filter.name
} %}
{% endif %}
{% endfor %}
{% endif %}
{% endblock %}
Expand Down
85 changes: 57 additions & 28 deletions src/Search/Request/Handler/FilterHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
namespace Nosto\NostoIntegration\Search\Request\Handler;

use Nosto\NostoIntegration\Search\Request\SearchRequest;
use Nosto\NostoIntegration\Search\Response\GraphQL\Filter\Filter;
use Nosto\NostoIntegration\Search\Response\GraphQL\Filter\RangeSliderFilter;
use Nosto\NostoIntegration\Search\Response\GraphQL\Filter\RatingFilter;
use Nosto\NostoIntegration\Struct\FiltersExtension;
use Nosto\NostoIntegration\Struct\IdToFieldMapping;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
Expand Down Expand Up @@ -69,8 +71,18 @@ protected function handleFilter(
return;
}

if (!$filterField = $filterMapping->getMapping($filterId)) {
return;
}

if ($this->isRatingFilter($filterField)) {
$this->handleRatingFilter($filterField, $filterValue, $searchNavigationRequest);

return;
}

if (in_array($filterId, $availableFilterIds, true)) {
$this->handlePropertyFilter($filterId, $filterValue, $searchNavigationRequest, $filterMapping);
$this->handlePropertyFilter($filterField, $filterValue, $searchNavigationRequest);
}
}

Expand All @@ -82,20 +94,33 @@ protected function handleRangeSliderFilter(
): void {
if (mb_strpos($filterId, self::MIN_PREFIX) === 0) {
$filterId = mb_substr($filterId, mb_strlen(self::MIN_PREFIX));
$filterName = $fieldMapping->getMapping($filterId);
$searchNavigationRequest->addRangeFilter($filterName, $filterValue, null);
$filterField = $fieldMapping->getMapping($filterId);
$searchNavigationRequest->addRangeFilter($filterField, $filterValue, null);
} else {
$filterId = mb_substr($filterId, mb_strlen(self::MAX_PREFIX));
$filterName = $fieldMapping->getMapping($filterId);
$searchNavigationRequest->addRangeFilter($filterName, null, $filterValue);
$filterField = $fieldMapping->getMapping($filterId);
$searchNavigationRequest->addRangeFilter($filterField, null, $filterValue);
}
}

protected function handleRatingFilter(
string $filterField,
mixed $filterValue,
SearchRequest $searchNavigationRequest,
): void {
$searchNavigationRequest->addRangeFilter($filterField, $filterValue);
}

protected function isRangeSliderFilter(string $id): bool
{
return $this->isMinRangeSlider($id) || $this->isMaxRangeSlider($id);
}

protected function isRatingFilter(string $field): bool
{
return $field === Filter::RATING_FILTER_FIELD;
}

/**
* Fetches all available filter names. This is needed to distinguish between standard Shopware query parameters
* like "q", "sort", etc. and real filters.
Expand Down Expand Up @@ -138,13 +163,11 @@ private function isMaxRangeSlider(string $id): bool
}

private function handlePropertyFilter(
string $filterId,
string $filterField,
string $filterValue,
SearchRequest $searchNavigationRequest,
IdToFieldMapping $fieldMapping,
): void {
$filterName = $fieldMapping->getMapping($filterId);
$searchNavigationRequest->addValueFilter($filterName, $filterValue);
$searchNavigationRequest->addValueFilter($filterField, $filterValue);
}

public function handleAvailableFilters(Criteria $criteria): array
Expand All @@ -162,6 +185,7 @@ private function parseNostoFiltersForShopware(
FiltersExtension $allFilters
): array {
$result = [];

foreach ($allFilters->getFilters() as $filterWithAllValues) {
$filterName = $filterWithAllValues->getId();
if (!$filter = $availableFilters->getFilter($filterName)) {
Expand All @@ -170,32 +194,37 @@ private function parseNostoFiltersForShopware(
}

$values = $filter->getValues();
$filterValues = [];

if ($filter instanceof RangeSliderFilter) {
$filterValues[] = [
'min' => $filter->getMin(),
'max' => $filter->getMax(),
];
if ($filter instanceof RatingFilter) {
$result[Filter::RATING_FILTER_FIELD]['max'] = $filter->getMaxPoints();
} else {
foreach ($values as $value) {
$filterValues = [];

if ($filter instanceof RangeSliderFilter) {
$filterValues[] = [
'id' => $value->getTranslated()->getName(),
'translated' => [
'name' => $value->getTranslated()->getName(),
],
'min' => $filter->getMin(),
'max' => $filter->getMax(),
];
} else {
foreach ($values as $value) {
$filterValues[] = [
'id' => $value->getTranslated()->getName(),
'translated' => [
'name' => $value->getTranslated()->getName(),
],
];
}
}
}

$entityValues = [
'translated' => [
'name' => $filter->getName(),
],
'options' => $filterValues,
];
$entityValues = [
'translated' => [
'name' => $filter->getName(),
],
'options' => $filterValues,
];

$result[$filterName]['entities'][] = $entityValues;
$result[$filterName]['entities'][] = $entityValues;
}
}

$actualResult['properties']['entities'] = $result;
Expand Down
22 changes: 11 additions & 11 deletions src/Search/Request/SearchRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,19 @@ public function setSize(int $size): void
$this->size = $size;
}

public function addValueFilter(string $filterName, string $value): void
public function addValueFilter(string $filterField, string $value): void
{
if (array_key_exists($filterName, $this->filters)) {
$this->filters[$filterName]['value'][] = $value;
if (array_key_exists($filterField, $this->filters)) {
$this->filters[$filterField]['value'][] = $value;
} else {
$this->filters[$filterName] = [
'field' => $filterName,
$this->filters[$filterField] = [
'field' => $filterField,
'value' => [$value],
];
}
}

public function addRangeFilter(string $filterName, ?string $min = null, ?string $max = null): void
public function addRangeFilter(string $filterField, ?string $min = null, ?string $max = null): void
{
$range = [];

Expand All @@ -86,14 +86,14 @@ public function addRangeFilter(string $filterName, ?string $min = null, ?string
$range['lt'] = $max;
}

if (array_key_exists($filterName, $this->filters)) {
$this->filters[$filterName]['range'] = array_merge(
$this->filters[$filterName]['range'],
if (array_key_exists($filterField, $this->filters)) {
$this->filters[$filterField]['range'] = array_merge(
$this->filters[$filterField]['range'],
$range
);
} else {
$this->filters[$filterName] = [
'field' => $filterName,
$this->filters[$filterField] = [
'field' => $filterField,
'range' => $range,
];
}
Expand Down
18 changes: 14 additions & 4 deletions src/Search/Response/GraphQL/Filter/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@

abstract class Filter
{
private const FILTER_RANGE_MIN = 'min';

private const FILTER_RANGE_MAX = 'max';
public const RATING_FILTER_FIELD = 'ratingValue';

/**
* @param FilterValue[] $values
Expand All @@ -34,7 +32,9 @@ public function __construct(
public static function getInstance(Facet $facet): ?Filter
{
return match (true) {
$facet instanceof StatsFacet => static::handleRangeSliderFilter($facet),
$facet instanceof StatsFacet => $facet->getField() === self::RATING_FILTER_FIELD
? static::handleRatingSlider($facet)
: static::handleRangeSliderFilter($facet),
$facet instanceof TermsFacet => static::handleLabelTextFilter($facet),
default => throw new InvalidArgumentException('The submitted filter is unknown.'),
};
Expand Down Expand Up @@ -88,4 +88,14 @@ private static function handleRangeSliderFilter(StatsFacet $facet): RangeSliderF
$facet->getMax(),
);
}

private static function handleRatingSlider(StatsFacet $facet): RatingFilter
{
return new RatingFilter(
$facet->getId(),
$facet->getName(),
$facet->getField(),
ceil($facet->getMax()),
);
}
}
28 changes: 28 additions & 0 deletions src/Search/Response/GraphQL/Filter/RatingFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Nosto\NostoIntegration\Search\Response\GraphQL\Filter;

class RatingFilter extends Filter
{
private float $maxPoints = 0;

public function __construct(string $id, string $name, string $field, float $maxPoints)
{
parent::__construct($id, $name, $field);
$this->maxPoints = $maxPoints;
}

public function setMaxPoints(float $maxPoints): RatingFilter
{
$this->maxPoints = $maxPoints;

return $this;
}

public function getMaxPoints(): float
{
return $this->maxPoints;
}
}

0 comments on commit 598a862

Please sign in to comment.