Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/Product/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,12 @@ public function addFilter($filterName, array $filterValues)
*/
private function addPriceFilter($minPrice, $maxPrice)
{
$this->getSearchAdapter()->addFilter('price_min', [$maxPrice], '<=');
$this->getSearchAdapter()->addFilter('price_max', [$minPrice], '>=');
// The slider is built from floor() of the lowest indexed price and ceil() of the highest,
// so a product indexed at 5995.000001 is offered as spanning 5995 to 5996. Comparing the
// raw column against those bounds then rejects it at both ends of its own range.
// `price_min < floor(max) + 1` is the same condition as `floor(price_min) <= max`, and
// keeps the column alone on its side of the comparison so the index is still usable.
$this->getSearchAdapter()->addFilter('price_min', [floor($maxPrice) + 1], '<');
$this->getSearchAdapter()->addFilter('price_max', [ceil($minPrice) - 1], '>');
}
}
29 changes: 25 additions & 4 deletions tests/php/FacetedSearch/Product/SearchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -334,16 +334,18 @@ public function testInitSearchWithAllFilters()
],
],
'price_min' => [
'<=' => [
// The bounds are widened by one unit so a product matches the range the slider
// displayed for it, which is floor(price_min) to ceil(price_max).
'<' => [
[
200.0,
201.0,
],
],
],
'price_max' => [
'>=' => [
'>' => [
[
50.0,
49.0,
],
],
],
Expand Down Expand Up @@ -441,6 +443,25 @@ public function testInitSearchWithAllFilters()
);
}

/**
* The slider is built from floor() of the lowest indexed price and ceil() of the highest, so a
* product indexed at 5995.000001 is offered to the shopper as spanning 5995 to 5996. Comparing
* the raw column against those bounds rejected it at both ends of its own range, which emptied
* the listing as soon as either handle was dragged.
*
* @see https://github.com/PrestaShop/PrestaShop/issues/37604
*/
public function testInitSearchWidensPriceBoundsToTheDisplayedRange()
{
$this->search->initSearch(['price' => [5995, 5995]]);

$filters = $this->search->getSearchAdapter()->getInitialPopulation()->getFilters()->toArray();

// 5995.000001 satisfies both: it is below 5996 and above 5994.
$this->assertEquals(['<' => [[5996.0]]], $filters['price_min']);
$this->assertEquals(['>' => [[5994.0]]], $filters['price_max']);
}

public function testInitSearchWithManyFeatures()
{
$this->search->initSearch(
Expand Down
Loading