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.14.0 #939

Merged
merged 38 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
394fdff
Bump @babel/cli from 7.22.10 to 7.22.15
dependabot[bot] Sep 18, 2023
d93666f
Bump eslint from 8.48.0 to 8.49.0
dependabot[bot] Sep 18, 2023
76fbb86
Bump @babel/register from 7.22.5 to 7.22.15
dependabot[bot] Sep 18, 2023
1696594
Add sorting by reference
LameuleFR Sep 20, 2023
71c88e9
Merge pull request #917 from PrestaShop/dependabot/npm_and_yarn/dev/e…
matthieu-rolland Sep 21, 2023
828a0aa
Merge pull request #915 from PrestaShop/dependabot/npm_and_yarn/dev/b…
kpodemski Sep 25, 2023
cdd0c7c
Merge pull request #911 from PrestaShop/dependabot/npm_and_yarn/dev/b…
kpodemski Sep 25, 2023
569a72e
Bump @babel/eslint-parser from 7.22.11 to 7.22.15
dependabot[bot] Sep 25, 2023
6520282
Merge pull request #910 from PrestaShop/dependabot/npm_and_yarn/dev/b…
kpodemski Sep 25, 2023
94d8085
Bump eslint from 8.49.0 to 8.50.0
dependabot[bot] Sep 25, 2023
9dc59e3
Bump @babel/core from 7.22.20 to 7.23.0
dependabot[bot] Sep 26, 2023
43a4b14
Merge pull request #925 from LameuleFR/dev
kpodemski Sep 26, 2023
c6a1455
Add selections feature
Hlavtox Jul 17, 2023
c2dab98
Merge pull request #926 from PrestaShop/dependabot/npm_and_yarn/dev/e…
kpodemski Sep 27, 2023
14d9b43
Merge pull request #927 from PrestaShop/dependabot/npm_and_yarn/dev/b…
kpodemski Sep 27, 2023
80039eb
Bump @babel/node from 7.22.10 to 7.22.19
dependabot[bot] Sep 27, 2023
68d2c39
Merge pull request #920 from PrestaShop/dependabot/npm_and_yarn/dev/b…
kpodemski Sep 27, 2023
a1485a1
Bump @babel/cli from 7.22.15 to 7.23.0
dependabot[bot] Sep 27, 2023
5e32a15
Merge pull request #928 from PrestaShop/dependabot/npm_and_yarn/dev/b…
matthieu-rolland Sep 27, 2023
d430eb4
rm with --user root
leemyongpakvn Sep 28, 2023
8a6adcc
Bump chai from 4.3.8 to 4.3.10
dependabot[bot] Sep 29, 2023
58440cb
Merge pull request #931 from PrestaShop/dependabot/npm_and_yarn/dev/c…
kpodemski Sep 29, 2023
0601442
Merge pull request #929 from leemyongpakvn/dev
kpodemski Sep 29, 2023
d8c8f50
Merge pull request #880 from Hlavtox/extras
kpodemski Oct 4, 2023
e553220
Bump postcss from 8.4.23 to 8.4.31
dependabot[bot] Oct 7, 2023
e802cc1
Merge pull request #932 from PrestaShop/dependabot/npm_and_yarn/postc…
mflasquin Oct 9, 2023
4fb03e2
Bump @babel/preset-env from 7.22.20 to 7.23.2
dependabot[bot] Oct 12, 2023
b293982
Bump @babel/core from 7.23.0 to 7.23.2
dependabot[bot] Oct 12, 2023
9181266
Merge pull request #934 from PrestaShop/dependabot/npm_and_yarn/dev/b…
nicosomb Oct 12, 2023
167be20
Merge pull request #935 from PrestaShop/dependabot/npm_and_yarn/dev/b…
nicosomb Oct 12, 2023
5115ff9
Bump eslint from 8.50.0 to 8.51.0
dependabot[bot] Oct 12, 2023
d6fc121
Merge pull request #933 from PrestaShop/dependabot/npm_and_yarn/dev/e…
nicosomb Oct 12, 2023
99e6ead
Bump webpack from 5.88.2 to 5.89.0
dependabot[bot] Oct 16, 2023
7a3e705
Merge pull request #936 from PrestaShop/dependabot/npm_and_yarn/dev/w…
matthieu-rolland Oct 16, 2023
1789c87
Bump eslint from 8.51.0 to 8.52.0
dependabot[bot] Oct 23, 2023
df8cdae
Merge pull request #937 from PrestaShop/dependabot/npm_and_yarn/dev/e…
mflasquin Oct 23, 2023
386626c
Bump eslint-plugin-import from 2.28.1 to 2.29.0
dependabot[bot] Oct 24, 2023
f1a63a0
Merge pull request #938 from PrestaShop/dependabot/npm_and_yarn/dev/e…
nicosomb Oct 25, 2023
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
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.13.2]]></version>
<version><![CDATA[3.14.0]]></version>
<description><![CDATA[Displays a block allowing multiple filters.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[front_office_features]]></tab>
Expand Down
1,126 changes: 582 additions & 544 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,26 @@
},
"homepage": "https://github.com/PrestaShop/ps_facetedsearch#readme",
"devDependencies": {
"@babel/eslint-parser": "^7.22.11",
"@babel/cli": "^7.22.10",
"@babel/core": "^7.22.20",
"@babel/node": "^7.22.10",
"@babel/preset-env": "^7.22.20",
"@babel/register": "^7.22.5",
"@babel/eslint-parser": "^7.22.15",
"@babel/cli": "^7.23.0",
"@babel/core": "^7.23.2",
"@babel/node": "^7.22.19",
"@babel/preset-env": "^7.23.2",
"@babel/register": "^7.22.15",
"babel-loader": "^9.1.3",
"chai": "^4.3.8",
"chai": "^4.3.10",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^6.8.1",
"eslint": "^8.48.0",
"eslint": "^8.52.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prestashop": "^0.2.1",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-import": "^2.29.0",
"mini-css-extract-plugin": "^1.0.0",
"mocha": "^10.2.0",
"node-sass": "^9.0.0",
"sass-loader": "^13.3.2",
"style-loader": "^2.0.0",
"webpack": "^5.88.2",
"webpack": "^5.89.0",
"webpack-cli": "^4.10.0"
},
"dependencies": {
Expand Down
104 changes: 66 additions & 38 deletions ps_facetedsearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public function __construct()
{
$this->name = 'ps_facetedsearch';
$this->tab = 'front_office_features';
$this->version = '3.13.2';
$this->version = '3.14.0';
$this->author = 'PrestaShop';
$this->need_instance = 0;
$this->bootstrap = true;
Expand Down Expand Up @@ -172,6 +172,9 @@ protected function getDefaultFilters()
'label' => 'Product price filter (slider)',
'slider' => true,
],
'layered_selection_extras' => [
'label' => 'Product extras filter',
],
];
}

Expand Down Expand Up @@ -216,7 +219,7 @@ public function install()
$productsCount = $this->getDatabase()->getValue('SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'product`');

if ($productsCount < static::LOCK_TEMPLATE_CREATION) {
$this->rebuildLayeredCache();
$this->createDefaultTemplate();
}

$this->rebuildPriceIndexTable();
Expand Down Expand Up @@ -591,7 +594,6 @@ public function indexProductPrices($idProduct, $smart = true)
*/
public function getContent()
{
global $cookie;
$message = '';

if (Tools::isSubmit('SubmitFilter')) {
Expand Down Expand Up @@ -990,7 +992,7 @@ public function rebuildLayeredStructure()
`controller` VARCHAR(64) NOT NULL,
`id_category` INT(10) UNSIGNED NOT NULL,
`id_value` INT(10) UNSIGNED NULL DEFAULT \'0\',
`type` ENUM(\'category\',\'id_feature\',\'id_attribute_group\',\'availability\',\'condition\',\'manufacturer\',\'weight\',\'price\') NOT NULL,
`type` ENUM(\'category\',\'id_feature\',\'id_attribute_group\',\'availability\',\'condition\',\'manufacturer\',\'weight\',\'price\',\'extras\') NOT NULL,
`position` INT(10) UNSIGNED NOT NULL,
`filter_type` int(10) UNSIGNED NOT NULL DEFAULT 0,
`filter_show_limit` int(10) UNSIGNED NOT NULL DEFAULT 0,
Expand Down Expand Up @@ -1027,17 +1029,25 @@ public function rebuildLayeredStructure()
}

/**
* Build layered cache
*
* @param array $productsIds
* @param array $categoriesIds
* @param bool $rebuildLayeredCategories
* This method creates the first initial filter after installing the module,
* from all available features and attributes.
*/
public function rebuildLayeredCache($productsIds = [], $categoriesIds = [], $rebuildLayeredCategories = true)
public function createDefaultTemplate()
{
@set_time_limit(0);

$filterData = ['categories' => [], 'controllers' => ['category']];
// Default filter data
$filterData = [
'categories' => [],
'controllers' => [],
];

// Add all stable controllers (except search)
foreach ($this->getSupportedControllers() as $controller_name => $data) {
if ($controller_name != 'search') {
$filterData['controllers'][] = $controller_name;
}
}

/* Set memory limit to 128M only if current is lower */
$memoryLimit = Tools::getMemoryLimit();
Expand All @@ -1053,6 +1063,7 @@ public function rebuildLayeredCache($productsIds = [], $categoriesIds = [], $reb
$joinProduct = Shop::addSqlAssociation('product', 'p');
$joinProductAttribute = Shop::addSqlAssociation('product_attribute', 'pa');

// Fetch all available attributes and their values
$attributeGroups = $this->query(
'SELECT a.id_attribute, a.id_attribute_group
FROM ' . _DB_PREFIX_ . 'attribute a
Expand All @@ -1062,17 +1073,16 @@ public function rebuildLayeredCache($productsIds = [], $categoriesIds = [], $reb
' . $joinProduct . $joinProductAttribute . '
LEFT JOIN ' . _DB_PREFIX_ . 'category_product cp ON (cp.id_product = p.id_product)
LEFT JOIN ' . _DB_PREFIX_ . 'category c ON (c.id_category = cp.id_category)
WHERE c.active = 1' .
(count($categoriesIds) ? ' AND cp.id_category IN (' . implode(',', array_map('intval', $categoriesIds)) . ')' : '') . '
AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")
' . (count($productsIds) ? 'AND p.id_product IN (' . implode(',', array_map('intval', $productsIds)) . ')' : '')
WHERE c.active = 1
AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")'
);

$attributeGroupsById = [];
while ($row = $db->nextRow($attributeGroups)) {
$attributeGroupsById[(int) $row['id_attribute']] = (int) $row['id_attribute_group'];
}

// Fetch all available features and their values
$features = $this->query(
'SELECT fv.id_feature_value, fv.id_feature
FROM ' . _DB_PREFIX_ . 'feature_value fv
Expand All @@ -1081,9 +1091,8 @@ public function rebuildLayeredCache($productsIds = [], $categoriesIds = [], $reb
' . $joinProduct . '
LEFT JOIN ' . _DB_PREFIX_ . 'category_product cp ON (cp.id_product = p.id_product)
LEFT JOIN ' . _DB_PREFIX_ . 'category c ON (c.id_category = cp.id_category)
WHERE (fv.custom IS NULL OR fv.custom = 0) AND c.active = 1' . (count($categoriesIds) ? ' AND cp.id_category IN (' . implode(',', array_map('intval', $categoriesIds)) . ')' : '') . '
AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog") ' .
(count($productsIds) ? 'AND p.id_product IN (' . implode(',', array_map('intval', $productsIds)) . ')' : '')
WHERE (fv.custom IS NULL OR fv.custom = 0) AND c.active = 1
AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog") '
);

$featuresById = [];
Expand All @@ -1104,10 +1113,9 @@ public function rebuildLayeredCache($productsIds = [], $categoriesIds = [], $reb
LEFT JOIN ' . _DB_PREFIX_ . 'product_attribute pa ON (pa.id_product = p.id_product)
' . $joinProduct . $joinProductAttribute . '
LEFT JOIN ' . _DB_PREFIX_ . 'product_attribute_combination pac ON (pac.id_product_attribute = pa.id_product_attribute)
WHERE c.active = 1' . (count($categoriesIds) ? ' AND cp.id_category IN (' . implode(',', array_map('intval', $categoriesIds)) . ')' : '') . '
WHERE c.active = 1
AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")
' . (count($productsIds) ? 'AND p.id_product IN (' . implode(',', array_map('intval', $productsIds)) . ')' : '') .
' AND (fv.custom IS NULL OR fv.custom = 0)
AND (fv.custom IS NULL OR fv.custom = 0)
GROUP BY p.id_product'
);

Expand Down Expand Up @@ -1138,11 +1146,36 @@ public function rebuildLayeredCache($productsIds = [], $categoriesIds = [], $reb
if (!isset($nCategories[(int) $idCategory])) {
$nCategories[(int) $idCategory] = 1;
}

// Stock filter
if (!isset($doneCategories[(int) $idCategory]['q'])) {
$filterData['layered_selection_stock'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0];
$doneCategories[(int) $idCategory]['q'] = true;
$toInsert = true;
}

// Add extras filter
if (!isset($doneCategories[(int) $idCategory]['e'])) {
$filterData['layered_selection_extras'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0];
$doneCategories[(int) $idCategory]['e'] = true;
$toInsert = true;
}

// Price filter
if (!isset($doneCategories[(int) $idCategory]['p'])) {
$filterData['layered_selection_price_slider'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0];
$doneCategories[(int) $idCategory]['p'] = true;
$toInsert = true;
}

// Category filter
if (!isset($doneCategories[(int) $idCategory]['cat'])) {
$filterData['layered_selection_subcategories'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0];
$doneCategories[(int) $idCategory]['cat'] = true;
$toInsert = true;
}

// Attribute filter
if (is_array($attributeGroupsById) && count($attributeGroupsById) > 0) {
foreach ($a as $kAttribute => $attribute) {
if (!isset($doneCategories[(int) $idCategory]['a' . (int) $attributeGroupsById[(int) $kAttribute]])) {
Expand All @@ -1152,7 +1185,9 @@ public function rebuildLayeredCache($productsIds = [], $categoriesIds = [], $reb
}
}
}
if (is_array($attributeGroupsById) && count($attributeGroupsById) > 0) {

// Features filter
if (is_array($featuresById) && count($featuresById) > 0) {
foreach ($f as $kFeature => $feature) {
if (!isset($doneCategories[(int) $idCategory]['f' . (int) $featuresById[(int) $kFeature]])) {
$filterData['layered_selection_feat_' . (int) $featuresById[(int) $kFeature]] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0];
Expand All @@ -1162,38 +1197,30 @@ public function rebuildLayeredCache($productsIds = [], $categoriesIds = [], $reb
}
}

if (!isset($doneCategories[(int) $idCategory]['q'])) {
$filterData['layered_selection_stock'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0];
$doneCategories[(int) $idCategory]['q'] = true;
$toInsert = true;
}

// Manufacturer filter
if (!isset($doneCategories[(int) $idCategory]['m'])) {
$filterData['layered_selection_manufacturer'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0];
$doneCategories[(int) $idCategory]['m'] = true;
$toInsert = true;
}

// Condition filter
if (!isset($doneCategories[(int) $idCategory]['c'])) {
$filterData['layered_selection_condition'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0];
$doneCategories[(int) $idCategory]['c'] = true;
$toInsert = true;
}

// Weight filter
if (!isset($doneCategories[(int) $idCategory]['w'])) {
$filterData['layered_selection_weight_slider'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0];
$doneCategories[(int) $idCategory]['w'] = true;
$toInsert = true;
}

if (!isset($doneCategories[(int) $idCategory]['p'])) {
$filterData['layered_selection_price_slider'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0];
$doneCategories[(int) $idCategory]['p'] = true;
$toInsert = true;
}
}
}

// If there are any filters available to setup, we will create the filter template
if ($toInsert) {
$this->getDatabase()->execute('INSERT INTO ' . _DB_PREFIX_ . 'layered_filter(name, filters, n_categories, date_add)
VALUES (\'' . sprintf($this->trans('My template %s', [], 'Modules.Facetedsearch.Admin'), date('Y-m-d')) . '\', \'' . pSQL(serialize($filterData)) . '\', ' . count($filterData['categories']) . ', NOW())');
Expand All @@ -1204,11 +1231,10 @@ public function rebuildLayeredCache($productsIds = [], $categoriesIds = [], $reb
$this->getDatabase()->execute('INSERT INTO ' . _DB_PREFIX_ . 'layered_filter_shop (`id_layered_filter`, `id_shop`)
VALUES(' . $last_id . ', ' . (int) $idShop . ')');
}

if ($rebuildLayeredCategories) {
$this->buildLayeredCategories();
}
}

// Now we need to build layered_category table from this template
$this->buildLayeredCategories();
}

/**
Expand Down Expand Up @@ -1295,6 +1321,8 @@ public function buildLayeredCategories()
} elseif (substr($key, 0, 23) == 'layered_selection_feat_') {
$sqlInsert .= '(' . (int) $idCategory . ', \'' . $controller . '\', ' . (int) $idShop . ', ' . (int) str_replace('layered_selection_feat_', '', $key) . ',
\'id_feature\',' . (int) $n . ', ' . (int) $limit . ', ' . (int) $type . '),';
} elseif ($key == 'layered_selection_extras') {
$sqlInsert .= '(' . (int) $idCategory . ', \'' . $controller . '\', ' . (int) $idShop . ', NULL,\'extras\',' . (int) $n . ', ' . (int) $limit . ', ' . (int) $type . '),';
}

++$nbSqlValuesToInsert;
Expand Down
14 changes: 8 additions & 6 deletions src/Adapter/MySQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,20 @@ public function getQuery()

// Process and generate all fields for the SQL query below
$orderField = $this->computeOrderByField($filterToTableMapping);
$selectFields = $this->computeSelectFields($filterToTableMapping);
$whereConditions = $this->computeWhereConditions($filterToTableMapping);
$joinConditions = $this->computeJoinConditions($filterToTableMapping);
$groupFields = $this->computeGroupByFields($filterToTableMapping);

// Now, let's build the query...
// If this query IS the initial population (the base table), we are selecting from product table
if ($this->getInitialPopulation() === null) {
$referenceTable = _DB_PREFIX_ . 'product';
// If not, we will call this function again but for the initial population
} else {
$referenceTable = '(' . $this->getInitialPopulation()->getQuery() . ')';
}

$selectFields = $this->computeSelectFields($filterToTableMapping);
$whereConditions = $this->computeWhereConditions($filterToTableMapping);
$joinConditions = $this->computeJoinConditions($filterToTableMapping);
$groupFields = $this->computeGroupByFields($filterToTableMapping);

$query = 'SELECT ' . implode(', ', $selectFields) . ' FROM ' . $referenceTable . ' p';

foreach ($joinConditions as $joinAliasInfos) {
Expand Down Expand Up @@ -327,7 +327,7 @@ protected function getFieldMapping()
(sp.from = \'0000-00-00 00:00:00\' OR \'' . date('Y-m-d H:i:s') . '\' >= sp.from) AND
(sp.to = \'0000-00-00 00:00:00\' OR \'' . date('Y-m-d H:i:s') . '\' <= sp.to)
)',
'joinType' => self::INNER_JOIN,
'joinType' => self::LEFT_JOIN,
],
];

Expand Down Expand Up @@ -805,6 +805,8 @@ public function useFiltersAsInitialPopulation()
'weight',
'price',
'sales',
'on_sale',
'date_add',
]
);

Expand Down
Loading