Skip to content

Commit

Permalink
Merge pull request #92 from PrestaShop/dev
Browse files Browse the repository at this point in the history
Release version 3.0.4
  • Loading branch information
PierreRambaud authored Jun 12, 2019
2 parents d5ed634 + 02aa7e0 commit 9712a59
Show file tree
Hide file tree
Showing 21 changed files with 875 additions and 115 deletions.
2 changes: 1 addition & 1 deletion config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<module>
<name>ps_facetedsearch</name>
<displayName><![CDATA[Faceted search]]></displayName>
<version><![CDATA[3.0.3]]></version>
<version><![CDATA[3.0.4]]></version>
<description><![CDATA[Displays a block allowing multiple filters.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[front_office_features]]></tab>
Expand Down
31 changes: 17 additions & 14 deletions ps_facetedsearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function __construct()
{
$this->name = 'ps_facetedsearch';
$this->tab = 'front_office_features';
$this->version = '3.0.3';
$this->version = '3.0.4';
$this->author = 'PrestaShop';
$this->need_instance = 0;
$this->bootstrap = true;
Expand Down Expand Up @@ -354,19 +354,22 @@ public function indexProductPrices($idProduct, $smart = true)
$this->getDatabase()->execute('DELETE FROM `' . _DB_PREFIX_ . 'layered_price_index` WHERE `id_product` = ' . (int) $idProduct . ' AND `id_shop` = ' . (int) $idShop);
}

if (!Configuration::get('PS_LAYERED_FILTER_PRICE_USETAX')) {
$taxRatesByCountry = [['rate' => 0, 'id_country' => 0, 'iso_code' => '']];
} else {
$taxRatesByCountry = $this->getDatabase()->executeS(
'SELECT t.rate rate, tr.id_country, c.iso_code
FROM `' . _DB_PREFIX_ . 'product_shop` p
LEFT JOIN `' . _DB_PREFIX_ . 'tax_rules_group` trg ON (trg.id_tax_rules_group = p.id_tax_rules_group AND p.id_shop = ' . (int) $idShop . ')
LEFT JOIN `' . _DB_PREFIX_ . 'tax_rule` tr ON (tr.id_tax_rules_group = trg.id_tax_rules_group)
LEFT JOIN `' . _DB_PREFIX_ . 'tax` t ON (t.id_tax = tr.id_tax AND t.active = 1)
JOIN `' . _DB_PREFIX_ . 'country` c ON (tr.id_country=c.id_country AND c.active = 1)
WHERE id_product = ' . (int) $idProduct . '
GROUP BY id_product, tr.id_country'
);
$taxRatesByCountry = $this->getDatabase()->executeS(
'SELECT t.rate rate, tr.id_country, c.iso_code ' .
'FROM `' . _DB_PREFIX_ . 'product_shop` p ' .
'LEFT JOIN `' . _DB_PREFIX_ . 'tax_rules_group` trg ON ' .
'(trg.id_tax_rules_group = p.id_tax_rules_group AND p.id_shop = ' . (int) $idShop . ') ' .
'LEFT JOIN `' . _DB_PREFIX_ . 'tax_rule` tr ON (tr.id_tax_rules_group = trg.id_tax_rules_group) ' .
'LEFT JOIN `' . _DB_PREFIX_ . 'tax` t ON (t.id_tax = tr.id_tax AND t.active = 1) ' .
'JOIN `' . _DB_PREFIX_ . 'country` c ON (tr.id_country=c.id_country AND c.active = 1) ' .
'WHERE id_product = ' . (int) $idProduct . ' ' .
'GROUP BY id_product, tr.id_country'
);

if (empty($taxRatesByCountry) || !Configuration::get('PS_LAYERED_FILTER_PRICE_USETAX')) {
$idCountry = (int) Configuration::get('PS_COUNTRY_DEFAULT');
$isoCode = Country::getIsoById($idCountry);
$taxRatesByCountry = [['rate' => 0, 'id_country' => $idCountry, 'iso_code' => $isoCode]];
}

$productMinPrices = $this->getDatabase()->executeS(
Expand Down
16 changes: 15 additions & 1 deletion src/Adapter/AbstractAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,21 @@ public function getInitialPopulation()
*/
public function resetFilter($filterName)
{
unset($this->filters[$filterName]);
if ($this->filters->offsetExists($filterName)) {
$this->filters->offsetUnset($filterName);
}

return $this;
}

/**
* {@inheritdoc}
*/
public function resetOperationsFilter($filterName)
{
if ($this->operationsFilters->offsetExists($filterName)) {
$this->operationsFilters->offsetUnset($filterName);
}

return $this;
}
Expand Down
11 changes: 10 additions & 1 deletion src/Adapter/InterfaceAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,21 @@ public function valueCount($fieldName);
*/
public function resetOperationsFilters();

/**
* Reset the operations filter for the given filterName
*
* @param string $filterName
*
* @return self
*/
public function resetOperationsFilter($filterName);

/**
* Reset the filter for the given filterName
*
* @param string $filterName
*
* @return mixed
* @return self
*/
public function resetFilter($filterName);

Expand Down
9 changes: 3 additions & 6 deletions src/Adapter/MySQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ public function getFilteredSearchAdapter($resetFilter = null, $skipInitialPopula
if ($this->getInitialPopulation() !== null && !$skipInitialPopulation) {
$mysqlAdapter->initialPopulation = clone $this->getInitialPopulation();
if ($resetFilter) {
// Try to reset filter & operations filter
$mysqlAdapter->initialPopulation->resetFilter($resetFilter);
$mysqlAdapter->initialPopulation->resetOperationsFilter($resetFilter);
}
}

Expand Down Expand Up @@ -134,11 +136,6 @@ public function getQuery()
}
}

if ($this->initialPopulation === null) {
// We want to select only activated products
$whereConditions[] = 'p.active = TRUE';
}

if (!empty($whereConditions)) {
$query .= ' WHERE ' . implode(' AND ', $whereConditions);
}
Expand Down Expand Up @@ -203,7 +200,7 @@ protected function getFieldMapping()
'tableName' => 'product_shop',
'tableAlias' => 'ps',
'joinCondition' => '(p.id_product = ps.id_product AND ps.id_shop = ' .
$this->getContext()->shop->id . ')',
$this->getContext()->shop->id . ' AND ps.active = TRUE)',
'joinType' => self::INNER_JOIN,
],
'id_feature_value' => [
Expand Down
9 changes: 5 additions & 4 deletions src/Filters/Block.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,13 @@ public function getFilterBlock(
'id_category',
Tools::getValue('id_category_layered', Configuration::get('PS_HOME_CATEGORY'))
);
$parent = new Category((int) $idParent, $idLang);
$parent = new Category($idParent, $idLang);

/* Get the filters for the current category */
$filters = $this->database->executeS(
'SELECT type, id_value, filter_show_limit, filter_type ' .
'FROM ' . _DB_PREFIX_ . 'layered_category ' .
'WHERE id_category = ' . (int) $idParent . ' ' .
'WHERE id_category = ' . $idParent . ' ' .
'AND id_shop = ' . $idShop . ' ' .
'GROUP BY `type`, id_value ORDER BY position ASC'
);
Expand Down Expand Up @@ -683,7 +683,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('id_attribute');
$filteredSearchAdapter = $this->searchAdapter->getFilteredSearchAdapter('with_attributes');
break;
}
}
Expand Down Expand Up @@ -815,11 +815,12 @@ 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('id_feature_value');
$filteredSearchAdapter = $this->searchAdapter->getFilteredSearchAdapter('with_features');
break;
}
}
}

if (!$filteredSearchAdapter) {
$filteredSearchAdapter = $this->searchAdapter->getFilteredSearchAdapter();
}
Expand Down
11 changes: 10 additions & 1 deletion src/Hook/ProductSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
namespace PrestaShop\Module\FacetedSearch\Hook;

use PrestaShop\Module\FacetedSearch\Product\SearchProvider;
use PrestaShop\Module\FacetedSearch\URLSerializer;
use PrestaShop\Module\FacetedSearch\Filters\Converter;

class ProductSearch extends AbstractHook
{
Expand Down Expand Up @@ -61,7 +63,14 @@ public function productSearchProvider(array $params)
['position' => 'bottom', 'priority' => 100]
);

return new SearchProvider($this->module, $this->module->isAjax());
return new SearchProvider(
$this->module,
new Converter(
$this->module->getContext(),
$this->module->getDatabase()
),
new URLSerializer()
);
}

return null;
Expand Down
10 changes: 9 additions & 1 deletion src/Product/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,15 @@ private function addSearchFilters($selectedFilters, $parent, $idShop)

switch ($key) {
case 'id_feature':
$this->addFilter('id_feature_value', $filterValues);
$operationsFilter = [];
foreach ($filterValues as $filterValue) {
$operationsFilter[] = ['id_feature_value', $filterValue];
}

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

case 'id_attribute_group':
Expand Down
63 changes: 26 additions & 37 deletions src/Product/SearchProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,6 @@

class SearchProvider implements FacetsRendererInterface, ProductSearchProviderInterface
{
/**
* @var bool
*/
private $isAjax;

/**
* @var Ps_Facetedsearch
*/
Expand All @@ -64,15 +59,14 @@ class SearchProvider implements FacetsRendererInterface, ProductSearchProviderIn
*/
private $facetsSerializer;

public function __construct(Ps_Facetedsearch $module, $isAjax)
{
$this->isAjax = $isAjax;
public function __construct(
Ps_Facetedsearch $module,
Filters\Converter $converter,
URLSerializer $serializer
) {
$this->module = $module;
$this->filtersConverter = new Filters\Converter(
$module->getContext(),
$module->getDatabase()
);
$this->facetsSerializer = new URLSerializer();
$this->filtersConverter = $converter;
$this->facetsSerializer = $serializer;
}

/**
Expand Down Expand Up @@ -214,7 +208,7 @@ public function renderFacets(ProductSearchContext $context, ProductSearchResult
[
'show_quantities' => Configuration::get('PS_LAYERED_SHOW_QTIES'),
'facets' => $facetsVar,
'js_enabled' => $this->isAjax,
'js_enabled' => $this->module->isAjax(),
'displayedFacets' => $displayedFacets,
'activeFilters' => $activeFilters,
'sort_order' => $result->getCurrentSortOrder()->toString(),
Expand Down Expand Up @@ -265,6 +259,7 @@ public function renderActiveFilters(ProductSearchContext $context, ProductSearch
private function prepareActiveFiltersForRender(ProductSearchContext $context, ProductSearchResult $result)
{
$facetCollection = $result->getFacetCollection();

// not all search providers generate menus
if (empty($facetCollection)) {
return null;
Expand Down Expand Up @@ -377,10 +372,11 @@ private function labelRangeFilters(array $facets)
private function addEncodedFacetsToFilters(array $facets)
{
// first get the currently active facetFilter in an array
$activeFacetFilters = $this->facetsSerializer->getActiveFacetFiltersFromFacets($facets);
$originalFacetFilters = $this->facetsSerializer->getActiveFacetFiltersFromFacets($facets);
$urlSerializer = new URLFragmentSerializer();

foreach ($facets as $facet) {
$activeFacetFilters = $originalFacetFilters;
// If only one filter can be selected, we keep track of
// the current active filter to disable it before generating the url stub
// and not select two filters in a facet that can have only one active filter.
Expand All @@ -389,7 +385,7 @@ private function addEncodedFacetsToFilters(array $facets)
if ($filter->isActive()) {
// we have a currently active filter is the facet, remove it from the facetFilter array
$activeFacetFilters = $this->facetsSerializer->removeFilterFromFacetFilters(
$activeFacetFilters,
$originalFacetFilters,
$filter,
$facet
);
Expand All @@ -399,18 +395,16 @@ private function addEncodedFacetsToFilters(array $facets)
}

foreach ($facet->getFilters() as $filter) {
$facetFilters = $activeFacetFilters;

// toggle the current filter
if ($filter->isActive() || $facet->getProperty('range')) {
$facetFilters = $this->facetsSerializer->removeFilterFromFacetFilters(
$facetFilters,
$activeFacetFilters,
$filter,
$facet
);
} else {
$facetFilters = $this->facetsSerializer->addFilterToFacetFilters(
$facetFilters,
$activeFacetFilters,
$filter,
$facet
);
Expand Down Expand Up @@ -475,12 +469,10 @@ private function hideUselessFacets(array $facets)
* Generate a URL corresponding to the current page but
* with the query string altered.
*
* If $extraParams is set to NULL, then all query params are stripped.
*
* Otherwise, params from $extraParams that have a null value are stripped,
* Params from $extraParams that have a null value are stripped,
* and other params are added. Params not in $extraParams are unchanged.
*/
private function updateQueryString(array $extraParams = null)
private function updateQueryString(array $extraParams = [])
{
$uriWithoutParams = explode('?', $_SERVER['REQUEST_URI'])[0];
$url = Tools::getCurrentUrlProtocolPrefix() . $_SERVER['HTTP_HOST'] . $uriWithoutParams;
Expand All @@ -491,21 +483,18 @@ private function updateQueryString(array $extraParams = null)
}
parse_str($paramsFromUri, $params);

if (null === $extraParams) {
$params = [];
} else {
foreach ($extraParams as $key => $value) {
if (null === $value) {
unset($params[$key]);
} else {
$params[$key] = $value;
}
foreach ($extraParams as $key => $value) {
if (null === $value) {
// Force clear param if null value is passed
unset($params[$key]);
} else {
$params[$key] = $value;
}
}

foreach ($params as $key => $param) {
if (null === $param || '' === $param) {
unset($params[$key]);
}
foreach ($params as $key => $param) {
if (null === $param || '' === $param) {
unset($params[$key]);
}
}

Expand Down
Loading

0 comments on commit 9712a59

Please sign in to comment.