Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 3.2.1 #128

Merged
merged 21 commits into from Aug 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion config.xml
Expand Up @@ -2,7 +2,7 @@
<module>
<name>ps_facetedsearch</name>
<displayName><![CDATA[Faceted search]]></displayName>
<version><![CDATA[3.2.0]]></version>
<version><![CDATA[3.2.1]]></version>
<description><![CDATA[Displays a block allowing multiple filters.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[front_office_features]]></tab>
Expand Down
6 changes: 3 additions & 3 deletions ps_facetedsearch.php
Expand Up @@ -90,7 +90,7 @@ public function __construct()
{
$this->name = 'ps_facetedsearch';
$this->tab = 'front_office_features';
$this->version = '3.2.0';
$this->version = '3.2.1';
$this->author = 'PrestaShop';
$this->need_instance = 0;
$this->bootstrap = true;
Expand Down Expand Up @@ -528,8 +528,8 @@ public function indexProductPrices($idProduct, $smart = true)
$minPrice[$idCountry][$currency['id_currency']] = $price;
}

if ($minPrice > $maxPrice[$idCountry][$currency['id_currency']]) {
$maxPrice[$idCountry][$currency['id_currency']] = $minPrice;
if ($price > $maxPrice[$idCountry][$currency['id_currency']]) {
$maxPrice[$idCountry][$currency['id_currency']] = $price;
}
}
}
Expand Down
21 changes: 2 additions & 19 deletions src/Adapter/AbstractAdapter.php
Expand Up @@ -98,27 +98,10 @@ public function resetFilter($filterName)
/**
* {@inheritdoc}
*/
public function resetOperationsFilter($filterName, $value = null)
public function resetOperationsFilter($filterName)
{
if (!$this->operationsFilters->offsetExists($filterName)) {
return $this;
}

if ($value === null) {
if ($this->operationsFilters->offsetExists($filterName)) {
$this->operationsFilters->offsetUnset($filterName);

return $this;
}

$operations = $this->operationsFilters->offsetGet($filterName);
if (isset($operations[$value])) {
unset($operations[$value]);
}

if (empty($operations)) {
$this->resetOperationsFilter($filterName);
} else {
$this->addOperationsFilter($filterName, $operations);
}

return $this;
Expand Down
4 changes: 1 addition & 3 deletions src/Adapter/InterfaceAdapter.php
Expand Up @@ -201,14 +201,12 @@ public function resetOperationsFilters();

/**
* Reset the operations filter for the given filterName
* or reset the operations filter with a specific value
*
* @param string $filterName
* @param string|int $value
*
* @return self
*/
public function resetOperationsFilter($filterName, $value = null);
public function resetOperationsFilter($filterName);

/**
* Reset the filter for the given filterName
Expand Down
20 changes: 15 additions & 5 deletions src/Adapter/MySQL.php
Expand Up @@ -392,6 +392,7 @@ private function computeSelectFields(array $filterToTableMapping)
private function computeWhereConditions(array $filterToTableMapping)
{
$whereConditions = [];
$operationIdx = 0;
foreach ($this->getOperationsFilters() as $filterName => $filterOperations) {
$operationsConditions = [];
foreach ($filterOperations as $operations) {
Expand All @@ -403,7 +404,9 @@ private function computeWhereConditions(array $filterToTableMapping)
$joinMapping = $filterToTableMapping[$operation[0]];
// If index is not the first, append to the table alias for
// multi join
$selectAlias = $joinMapping['tableAlias'] . ($idx === 0 ? '' : $idx);
$selectAlias = $joinMapping['tableAlias'] .
($operationIdx === 0 ? '' : '_' . $operationIdx) .
($idx === 0 ? '' : '_' . $idx);
$operation[0] = isset($joinMapping['fieldName']) ? $joinMapping['fieldName'] : $operation[0];
}

Expand All @@ -420,6 +423,7 @@ private function computeWhereConditions(array $filterToTableMapping)
$operationsConditions[] = '(' . implode(' AND ', $conditions) . ')';
}

++$operationIdx;
if (!empty($operationsConditions)) {
$whereConditions[] = '(' . implode(' OR ', $operationsConditions) . ')';
}
Expand Down Expand Up @@ -511,25 +515,31 @@ private function computeJoinConditions(array $filterToTableMapping)
$this->addJoinList($joinList, $this->getSelectFields(), $filterToTableMapping);
$this->addJoinList($joinList, $this->getFilters()->getKeys(), $filterToTableMapping);

$operationIdx = 0;
foreach ($this->getOperationsFilters() as $filterOperations) {
foreach ($filterOperations as $operations) {
foreach ($operations as $idx => $operation) {
if (array_key_exists($operation[0], $filterToTableMapping)) {
$joinMapping = $filterToTableMapping[$operation[0]];
if ($idx !== 0) {
if ($idx !== 0 || $operationIdx !== 0) {
// Index is not the first, append index to tableAlias on joinCondition
$joinMapping['joinCondition'] = preg_replace(
'~([\(\s=]' . $joinMapping['tableAlias'] . ')\.~',
'${1}' . $idx . '.',
'${1}' .
($operationIdx === 0 ? '' : '_' . $operationIdx) .
($idx === 0 ? '' : '_' . $idx) .
'.',
$joinMapping['joinCondition']
);
$joinMapping['tableAlias'] .= $idx;
$joinMapping['tableAlias'] .= ($operationIdx === 0 ? '' : '_' . $operationIdx) .
($idx === 0 ? '' : '_' . $idx);
}

$this->addJoinConditions($joinList, $joinMapping, $filterToTableMapping);
}
}
}
++$operationIdx;
}

$this->addJoinList($joinList, $this->getGroupFields()->getKeys(), $filterToTableMapping);
Expand Down Expand Up @@ -578,7 +588,7 @@ private function addJoinConditions(ArrayCollection $joinList, array $joinMapping
'joinType' => $joinMapping['joinType'],
];

$joinList->set($joinMapping['tableAlias'] . $joinMapping['tableName'], $joinInfos);
$joinList->set($joinMapping['tableAlias'] . '_' . $joinMapping['tableName'], $joinInfos);
}

/**
Expand Down
6 changes: 2 additions & 4 deletions src/Filters/Block.php
Expand Up @@ -689,8 +689,7 @@ private function getAttributesBlock($filter, $selectedFilters, $idLang)
if (!empty($selectedFilters['id_attribute_group'])) {
foreach ($selectedFilters['id_attribute_group'] as $key => $selectedFilter) {
if ($key == $idAttributeGroup) {
$filteredSearchAdapter = $this->searchAdapter->getFilteredSearchAdapter();
$filteredSearchAdapter->getInitialPopulation()->resetOperationsFilter('with_attributes', (int) $idAttributeGroup);
$filteredSearchAdapter = $this->searchAdapter->getFilteredSearchAdapter('with_attributes_' . $idAttributeGroup);
break;
}
}
Expand Down Expand Up @@ -826,8 +825,7 @@ private function getFeaturesBlock($filter, $selectedFilters, $idLang)
if (!empty($selectedFilters['id_feature'])) {
foreach ($selectedFilters['id_feature'] as $key => $selectedFilter) {
if ($key == $idFeature) {
$filteredSearchAdapter = $this->searchAdapter->getFilteredSearchAdapter();
$filteredSearchAdapter->getInitialPopulation()->resetOperationsFilter('with_features', (int) $idFeature);
$filteredSearchAdapter = $this->searchAdapter->getFilteredSearchAdapter('with_features_' . $idFeature);

break;
}
Expand Down
15 changes: 11 additions & 4 deletions src/Filters/Converter.php
Expand Up @@ -136,9 +136,15 @@ public function getFacetsFromFilterBlocks(array $filterBlocks)
$filters[] = $filter;
}

usort($filters, array($this, 'sortFiltersByMagnitude'));
if ((int) $filterBlock['filter_show_limit'] !== 0) {
usort($filters, array($this, 'sortFiltersByMagnitude'));
}

$this->hideZeroValuesAndShowLimit($filters, (int) $filterBlock['filter_show_limit']);
usort($filters, array($this, 'sortFiltersByLabel'));

if ((int) $filterBlock['filter_show_limit'] !== 0 || $filterBlock['type'] !== self::TYPE_ATTRIBUTE_GROUP) {
usort($filters, array($this, 'sortFiltersByLabel'));
}

// No method available to add all filters
foreach ($filters as $filter) {
Expand Down Expand Up @@ -445,7 +451,8 @@ private function sortFiltersByMagnitude(Filter $a, Filter $b)
$aMagnitude = $a->getMagnitude();
$bMagnitude = $b->getMagnitude();
if ($aMagnitude == $bMagnitude) {
return 0;
// Same magnitude, sort by label
return $this->sortFiltersByLabel($a, $b);
}

return $aMagnitude > $bMagnitude ? -1 : +1;
Expand All @@ -461,6 +468,6 @@ private function sortFiltersByMagnitude(Filter $a, Filter $b)
*/
private function sortFiltersByLabel(Filter $a, Filter $b)
{
return strcmp($a->getLabel(), $b->getLabel());
return strnatcmp($a->getLabel(), $b->getLabel());
}
}
20 changes: 9 additions & 11 deletions src/Product/Search.php
Expand Up @@ -107,6 +107,7 @@ public function initSearch($selectedFilters)
$psLayeredFullTree = Configuration::get('PS_LAYERED_FULL_TREE');
if (!$psLayeredFullTree) {
$this->addFilter('id_category_default', [$parent->id]);
$this->addFilter('id_category', [$parent->id]);
}

// Visibility of a product must be in catalog or both (search & catalog)
Expand Down Expand Up @@ -136,25 +137,22 @@ private function addSearchFilters($selectedFilters, $parent, $idShop)
case 'id_feature':
$operationsFilter = [];
foreach ($filterValues as $featureId => $filterValue) {
$operationsFilter[$featureId][] = ['id_feature_value', $filterValue];
$this->getSearchAdapter()->addOperationsFilter(
'with_features_' . $featureId,
[[['id_feature_value', $filterValue]]]
);
}

$this->getSearchAdapter()->addOperationsFilter(
'with_features',
$operationsFilter
);
break;

case 'id_attribute_group':
$operationsFilter = [];
foreach ($filterValues as $attributeId => $filterValue) {
$operationsFilter[$attributeId][] = ['id_attribute', $filterValue];
$this->getSearchAdapter()->addOperationsFilter(
'with_attributes_' . $attributeId,
[[['id_attribute', $filterValue]]]
);
}

$this->getSearchAdapter()->addOperationsFilter(
'with_attributes',
$operationsFilter
);
break;

case 'category':
Expand Down
6 changes: 3 additions & 3 deletions tests/php/FacetedSearch/Adapter/MySQLTest.php
Expand Up @@ -358,7 +358,7 @@ public function getManyOperationsFilters()
['out_of_stock', [1], '='],
],
],
'expected' => 'SELECT p.id_product, sa.out_of_stock, sa.quantity, psi.price_min, psi.price_max, psi.range_start, psi.range_end FROM ps_product p LEFT JOIN ps_stock_available sa ON (p.id_product = sa.id_product AND 0 = sa.id_product_attribute ) INNER JOIN ps_layered_price_index psi ON (psi.id_product = p.id_product AND psi.id_currency = 4 AND psi.id_country = 3) LEFT JOIN ps_stock_available sa1 ON (p.id_product = sa1.id_product AND 0 = sa1.id_product_attribute ) WHERE ((sa.quantity>=0 AND sa1.out_of_stock IN (1, 3, 4)) OR (sa.quantity>0 AND sa1.out_of_stock=1)) ORDER BY p.id_product DESC LIMIT 0, 20',
'expected' => 'SELECT p.id_product, sa.out_of_stock, sa.quantity, psi.price_min, psi.price_max, psi.range_start, psi.range_end FROM ps_product p LEFT JOIN ps_stock_available sa ON (p.id_product = sa.id_product AND 0 = sa.id_product_attribute ) INNER JOIN ps_layered_price_index psi ON (psi.id_product = p.id_product AND psi.id_currency = 4 AND psi.id_country = 3) LEFT JOIN ps_stock_available sa_1 ON (p.id_product = sa_1.id_product AND 0 = sa_1.id_product_attribute ) WHERE ((sa.quantity>=0 AND sa_1.out_of_stock IN (1, 3, 4)) OR (sa.quantity>0 AND sa_1.out_of_stock=1)) ORDER BY p.id_product DESC LIMIT 0, 20',
],
[
'fields' => [
Expand All @@ -375,7 +375,7 @@ public function getManyOperationsFilters()
['out_of_stock', [1], '='],
],
],
'expected' => 'SELECT p.id_product, sa.quantity FROM ps_product p LEFT JOIN ps_stock_available sa ON (p.id_product = sa.id_product AND 0 = sa.id_product_attribute ) STRAIGHT_JOIN ps_product_attribute pa ON (p.id_product = pa.id_product) STRAIGHT_JOIN ps_product_attribute_combination pac ON (pa.id_product_attribute = pac.id_product_attribute) STRAIGHT_JOIN ps_product_attribute_combination pac1 ON (pa.id_product_attribute = pac1.id_product_attribute) LEFT JOIN ps_stock_available sa1 ON (p.id_product = sa1.id_product AND 0 = sa1.id_product_attribute ) WHERE ((pac.id_attribute=2 AND pac1.id_attribute=4) OR (sa.quantity>0 AND sa1.out_of_stock=1)) ORDER BY p.id_product DESC LIMIT 0, 20',
'expected' => 'SELECT p.id_product, sa.quantity FROM ps_product p LEFT JOIN ps_stock_available sa ON (p.id_product = sa.id_product AND 0 = sa.id_product_attribute ) STRAIGHT_JOIN ps_product_attribute pa ON (p.id_product = pa.id_product) STRAIGHT_JOIN ps_product_attribute_combination pac ON (pa.id_product_attribute = pac.id_product_attribute) STRAIGHT_JOIN ps_product_attribute_combination pac_1 ON (pa.id_product_attribute = pac_1.id_product_attribute) LEFT JOIN ps_stock_available sa_1 ON (p.id_product = sa_1.id_product AND 0 = sa_1.id_product_attribute ) WHERE ((pac.id_attribute=2 AND pac_1.id_attribute=4) OR (sa.quantity>0 AND sa_1.out_of_stock=1)) ORDER BY p.id_product DESC LIMIT 0, 20',
],
[
'fields' => [
Expand All @@ -393,7 +393,7 @@ public function getManyOperationsFilters()
['out_of_stock', [0], '='],
],
],
'expected' => 'SELECT p.id_product, sa.quantity FROM ps_product p LEFT JOIN ps_stock_available sa ON (p.id_product = sa.id_product AND 0 = sa.id_product_attribute ) STRAIGHT_JOIN ps_product_attribute pa ON (p.id_product = pa.id_product) STRAIGHT_JOIN ps_product_attribute_combination pac ON (pa.id_product_attribute = pac.id_product_attribute) STRAIGHT_JOIN ps_product_attribute_combination pac1 ON (pa.id_product_attribute = pac1.id_product_attribute) STRAIGHT_JOIN ps_product_attribute_combination pac2 ON (pa.id_product_attribute = pac2.id_product_attribute) LEFT JOIN ps_stock_available sa1 ON (p.id_product = sa1.id_product AND 0 = sa1.id_product_attribute ) WHERE ((pac.id_attribute=2 AND pac1.id_attribute IN (4, 5, 6) AND pac2.id_attribute IN (7, 8, 9)) OR (sa.quantity>0 AND sa1.out_of_stock=0)) ORDER BY p.id_product DESC LIMIT 0, 20',
'expected' => 'SELECT p.id_product, sa.quantity FROM ps_product p LEFT JOIN ps_stock_available sa ON (p.id_product = sa.id_product AND 0 = sa.id_product_attribute ) STRAIGHT_JOIN ps_product_attribute pa ON (p.id_product = pa.id_product) STRAIGHT_JOIN ps_product_attribute_combination pac ON (pa.id_product_attribute = pac.id_product_attribute) STRAIGHT_JOIN ps_product_attribute_combination pac_1 ON (pa.id_product_attribute = pac_1.id_product_attribute) STRAIGHT_JOIN ps_product_attribute_combination pac_2 ON (pa.id_product_attribute = pac_2.id_product_attribute) LEFT JOIN ps_stock_available sa_1 ON (p.id_product = sa_1.id_product AND 0 = sa_1.id_product_attribute ) WHERE ((pac.id_attribute=2 AND pac_1.id_attribute IN (4, 5, 6) AND pac_2.id_attribute IN (7, 8, 9)) OR (sa.quantity>0 AND sa_1.out_of_stock=0)) ORDER BY p.id_product DESC LIMIT 0, 20',
],
];
}
Expand Down
16 changes: 2 additions & 14 deletions tests/php/FacetedSearch/Filters/BlockTest.php
Expand Up @@ -683,14 +683,8 @@ public function testGetFiltersBlockWithoutAttributes()

$this->adapterMock->shouldReceive('getFilteredSearchAdapter')
->once()
->with()
->with('with_attributes_1')
->andReturn($adapterInitialMock);
$adapterInitialMock->shouldReceive('getInitialPopulation')
->once()
->andReturn($adapterInitialMock);
$adapterInitialMock->shouldReceive('resetOperationsFilter')
->once()
->with('with_attributes', 1);

$this->assertEquals(
[
Expand Down Expand Up @@ -892,15 +886,9 @@ public function testGetFiltersBlockWithoutFeatures()
$adapterInitialMock = Mockery::mock(MySQL::class)->makePartial();
$adapterInitialMock->resetAll();
$this->adapterMock->shouldReceive('getFilteredSearchAdapter')
->with()
->with('with_features_1')
->once()
->andReturn($adapterInitialMock);
$adapterInitialMock->shouldReceive('getInitialPopulation')
->once()
->andReturn($adapterInitialMock);
$adapterInitialMock->shouldReceive('resetOperationsFilter')
->once()
->with('with_features', 1);

$featureMock = Mockery::mock(Feature::class);
$featureMock->shouldReceive('getFeatures')
Expand Down