Skip to content

Commit 8f0601e

Browse files
[Magento Community Engineering] Community Contributions - 2.4-develop-expedited-prs
- merged with '2.4-develop-express-lane-prs' branch
2 parents 516017f + 7b0ec36 commit 8f0601e

File tree

12 files changed

+424
-188
lines changed

12 files changed

+424
-188
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,9 +1180,33 @@ protected function _getSelectCountSql(?Select $select = null, $resetLeftJoins =
11801180
if ($resetLeftJoins) {
11811181
$countSelect->resetJoinLeft();
11821182
}
1183+
1184+
$this->removeEntityIdentifierFromGroupBy($countSelect);
1185+
11831186
return $countSelect;
11841187
}
11851188

1189+
/**
1190+
* Using `entity_id` for `GROUP BY` causes COUNT() return {n} rows of value = 1 instead of 1 row of value {n}
1191+
*
1192+
* @param Select $select
1193+
* @throws \Zend_Db_Select_Exception
1194+
*/
1195+
private function removeEntityIdentifierFromGroupBy(Select $select): void
1196+
{
1197+
$originalGroupBy = $select->getPart(Select::GROUP);
1198+
1199+
if (!is_array($originalGroupBy)) {
1200+
return;
1201+
}
1202+
1203+
$groupBy = array_filter($originalGroupBy, function ($field) {
1204+
return false === strpos($field, $this->getIdFieldName());
1205+
});
1206+
1207+
$select->setPart(Select::GROUP, $groupBy);
1208+
}
1209+
11861210
/**
11871211
* Prepare statistics data
11881212
*
@@ -1770,30 +1794,19 @@ public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC)
17701794
*/
17711795
protected function _prepareProductLimitationFilters()
17721796
{
1773-
if (isset(
1774-
$this->_productLimitationFilters['visibility']
1775-
) && !isset(
1776-
$this->_productLimitationFilters['store_id']
1777-
)
1778-
) {
1797+
if (isset($this->_productLimitationFilters['visibility'])
1798+
&& !isset($this->_productLimitationFilters['store_id'])) {
17791799
$this->_productLimitationFilters['store_id'] = $this->getStoreId();
17801800
}
1781-
if (isset(
1782-
$this->_productLimitationFilters['category_id']
1783-
) && !isset(
1784-
$this->_productLimitationFilters['store_id']
1785-
)
1786-
) {
1801+
1802+
if (isset($this->_productLimitationFilters['category_id'])
1803+
&& !isset($this->_productLimitationFilters['store_id'])) {
17871804
$this->_productLimitationFilters['store_id'] = $this->getStoreId();
17881805
}
1789-
if (isset(
1790-
$this->_productLimitationFilters['store_id']
1791-
) && isset(
1792-
$this->_productLimitationFilters['visibility']
1793-
) && !isset(
1794-
$this->_productLimitationFilters['category_id']
1795-
)
1796-
) {
1806+
1807+
if (isset($this->_productLimitationFilters['store_id'])
1808+
&& isset($this->_productLimitationFilters['visibility'])
1809+
&& !isset($this->_productLimitationFilters['category_id'])) {
17971810
$this->_productLimitationFilters['category_id'] = $this->_storeManager->getStore(
17981811
$this->_productLimitationFilters['store_id']
17991812
)->getRootCategoryId();
@@ -1824,14 +1837,8 @@ protected function _productLimitationJoinWebsite()
18241837
$filters['website_ids'],
18251838
'int'
18261839
);
1827-
} elseif (isset(
1828-
$filters['store_id']
1829-
) && (!isset(
1830-
$filters['visibility']
1831-
) && !isset(
1832-
$filters['category_id']
1833-
)) && !$this->isEnabledFlat()
1834-
) {
1840+
} elseif (isset($filters['store_id']) && !$this->isEnabledFlat()
1841+
&& (!isset($filters['visibility']) && !isset($filters['category_id']))) {
18351842
$joinWebsite = true;
18361843
$websiteId = $this->_storeManager->getStore($filters['store_id'])->getWebsiteId();
18371844
$conditions[] = $this->getConnection()->quoteInto('product_website.website_id = ?', $websiteId, 'int');
@@ -1906,9 +1913,9 @@ protected function _productLimitationJoinPrice()
19061913
/**
19071914
* Join Product Price Table with left-join possibility
19081915
*
1909-
* @see \Magento\Catalog\Model\ResourceModel\Product\Collection::_productLimitationJoinPrice()
19101916
* @param bool $joinLeft
19111917
* @return $this
1918+
* @see \Magento\Catalog\Model\ResourceModel\Product\Collection::_productLimitationJoinPrice()
19121919
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
19131920
*/
19141921
protected function _productLimitationPrice($joinLeft = false)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
10+
<actionGroup name="AssertStorefrontNoProductsFoundActionGroup">
11+
<see userInput="We can't find products matching the selection." stepKey="seeEmptyNotice"/>
12+
</actionGroup>
13+
</actionGroups>

app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,12 @@
6969
<data key="path">catalog/frontend/grid_per_page_values</data>
7070
<data key="value">1,2</data>
7171
</entity>
72+
<entity name="DefaultGridPerPageDefaultConfigData">
73+
<data key="path">catalog/frontend/grid_per_page</data>
74+
<data key="value">12</data>
75+
</entity>
76+
<entity name="CustomGridPerPageDefaultConfigData">
77+
<data key="path">catalog/frontend/grid_per_page</data>
78+
<data key="value">1</data>
79+
</entity>
7280
</entities>

app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@
158158

159159
<!-- # Category should open successfully # <product1> should be absent on the page -->
160160
<see userInput="$$createAnchoredCategory1.name$$" selector="{{StorefrontCategoryMainSection.CategoryTitle}}" stepKey="seeCategory1Name"/>
161-
<see userInput="We can't find products matching the selection." stepKey="seeEmptyNotice"/>
161+
<actionGroup ref="AssertStorefrontNoProductsFoundActionGroup" stepKey="seeEmptyNotice"/>
162162
<dontSee userInput="$$simpleProduct.name$$" selector="{{StorefrontCategoryMainSection.productName}}" stepKey="dontseeProduct"/>
163163

164164
<!-- Log in to the backend: Admin user is logged in-->

app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191

9292
<!-- The category is still empty -->
9393
<see userInput="$$createCategoryA.name$$" selector="{{StorefrontCategoryMainSection.CategoryTitle}}" stepKey="seeCategoryA1Name"/>
94-
<see userInput="We can't find products matching the selection." stepKey="seeEmptyNotice"/>
94+
<actionGroup ref="AssertStorefrontNoProductsFoundActionGroup" stepKey="seeEmptyNotice"/>
9595
<dontSee userInput="$$createProductA1.name$$" selector="{{StorefrontCategoryMainSection.productName}}" stepKey="dontseeProductA1"/>
9696

9797
<!-- 4. Run cron to reindex -->
@@ -132,7 +132,7 @@
132132

133133
<!-- Category A is empty now -->
134134
<see userInput="$$createCategoryA.name$$" selector="{{StorefrontCategoryMainSection.CategoryTitle}}" stepKey="seeOnPageCategoryAName"/>
135-
<see userInput="We can't find products matching the selection." stepKey="seeOnPageEmptyNotice"/>
135+
<actionGroup ref="AssertStorefrontNoProductsFoundActionGroup" stepKey="seeOnPageEmptyNotice"/>
136136
<dontSee userInput="$$createProductA1.name$$" selector="{{StorefrontCategoryMainSection.productName}}" stepKey="dontseeProductA1OnPage"/>
137137

138138
<!-- Case: change product status -->

app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ define([
2323
direction: 'product_list_dir',
2424
order: 'product_list_order',
2525
limit: 'product_list_limit',
26+
page: 'p',
2627
modeDefault: 'grid',
2728
directionDefault: 'asc',
2829
orderDefault: 'position',
@@ -81,24 +82,63 @@ define([
8182
},
8283

8384
/**
84-
* @param {String} paramName
85-
* @param {*} paramValue
86-
* @param {*} defaultValue
85+
* @private
8786
*/
88-
changeUrl: function (paramName, paramValue, defaultValue) {
87+
getUrlParams: function () {
8988
var decode = window.decodeURIComponent,
9089
urlPaths = this.options.url.split('?'),
91-
baseUrl = urlPaths[0],
9290
urlParams = urlPaths[1] ? urlPaths[1].split('&') : [],
93-
paramData = {},
94-
parameters, i, form, params, key, input, formKey;
91+
params = {},
92+
parameters, i;
9593

9694
for (i = 0; i < urlParams.length; i++) {
9795
parameters = urlParams[i].split('=');
98-
paramData[decode(parameters[0])] = parameters[1] !== undefined ?
96+
params[decode(parameters[0])] = parameters[1] !== undefined ?
9997
decode(parameters[1].replace(/\+/g, '%20')) :
10098
'';
10199
}
100+
101+
return params;
102+
},
103+
104+
/**
105+
* @returns {String}
106+
* @private
107+
*/
108+
getCurrentLimit: function () {
109+
return this.getUrlParams()[this.options.limit] || this.options.limitDefault;
110+
},
111+
112+
/**
113+
* @returns {String}
114+
* @private
115+
*/
116+
getCurrentPage: function () {
117+
return this.getUrlParams()[this.options.page] || 1;
118+
},
119+
120+
/**
121+
* @param {String} paramName
122+
* @param {*} paramValue
123+
* @param {*} defaultValue
124+
*/
125+
changeUrl: function (paramName, paramValue, defaultValue) {
126+
var urlPaths = this.options.url.split('?'),
127+
baseUrl = urlPaths[0],
128+
paramData = this.getUrlParams(),
129+
currentPage = this.getCurrentPage(),
130+
form, params, key, input, formKey, newPage;
131+
132+
if (currentPage > 1 && paramName === this.options.limit) {
133+
newPage = Math.floor(this.getCurrentLimit() * (currentPage - 1) / paramValue) + 1;
134+
135+
if (newPage > 1) {
136+
paramData[this.options.page] = newPage;
137+
} else {
138+
delete paramData[this.options.page];
139+
}
140+
}
141+
102142
paramData[paramName] = paramValue;
103143

104144
if (this.options.post) {
@@ -130,6 +170,7 @@ define([
130170
if (paramValue == defaultValue) { //eslint-disable-line eqeqeq
131171
delete paramData[paramName];
132172
}
173+
133174
paramData = $.param(paramData);
134175
location.href = baseUrl + (paramData.length ? '?' + paramData : '');
135176
}

app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ public function resolve(): SearchCriteria
8080
$searchCriteria->setRequestName($this->searchRequestName);
8181
$searchCriteria->setSortOrders($this->orders);
8282
$searchCriteria->setCurrentPage($this->currentPage - 1);
83+
if ($this->size) {
84+
$searchCriteria->setPageSize($this->size);
85+
}
8386

8487
return $searchCriteria;
8588
}

app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,16 @@
3030
<field key="name">Product Simple AAA</field>
3131
</createData>
3232
<magentoCLI command="config:set {{CustomGridPerPageValuesConfigData.path}} {{CustomGridPerPageValuesConfigData.value}}" stepKey="setCustomGridPerPageValues"/>
33+
<magentoCLI command="config:set {{CustomGridPerPageDefaultConfigData.path}} {{CustomGridPerPageDefaultConfigData.value}}" stepKey="setCustomGridPerPageDefaults"/>
34+
<magentoCLI stepKey="flushConfigCache" command="cache:flush config"/>
35+
<magentoCron groups="index" stepKey="runCronIndex"/>
3336
</before>
3437

3538
<after>
3639
<deleteData createDataKey="createFirstProduct" stepKey="deleteFirstProduct"/>
3740
<deleteData createDataKey="createSecondProduct" stepKey="deleteSecondProduct"/>
3841
<magentoCLI command="config:set {{DefaultGridPerPageValuesConfigData.path}} {{DefaultGridPerPageValuesConfigData.value}}" stepKey="setDefaultGridPerPageValues"/>
42+
<magentoCLI command="config:set {{DefaultGridPerPageDefaultConfigData.path}} {{DefaultGridPerPageDefaultConfigData.value}}" stepKey="setDefaultGridPerPageDefaults"/>
3943
</after>
4044

4145
<actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="openStorefrontHomePage"/>
@@ -57,6 +61,9 @@
5761
</actionGroup>
5862
<selectOption selector="{{StorefrontCategoryBottomToolbarSection.perPage}}" userInput="2" stepKey="selectDisplayedProductInGridPerPage"/>
5963
<waitForPageLoad stepKey="waitForPageLoad"/>
64+
65+
<dontSeeInCurrentUrl stepKey="assertRedirectedToFirstPage" url="?p=2"/>
66+
6067
<actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="assertFirstProductDisplayedOnCatalogSearchPage">
6168
<argument name="product" value="$createFirstProduct$"/>
6269
</actionGroup>

app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,11 @@
2525
<remove keyForRemoval="selectDisplayedProductInGridPerPage"/>
2626
<remove keyForRemoval="assertFirstProductDisplayedOnCatalogSearchPage"/>
2727
<remove keyForRemoval="assertSecondProductDisplayedOnCatalogSearchPage"/>
28-
<grabTextFrom selector="{{StorefrontCategoryBottomToolbarSection.currentPage}}" stepKey="grabNumberOfLastPage"/>
29-
<actionGroup ref="StorefrontQuickSearchWithPaginationActionGroup" stepKey="navigateToUnavailableCatalogSearchResultPage">
28+
<remove keyForRemoval="selectDisplayedProductInGridPerPage"/>
29+
<remove keyForRemoval="assertStillOnSecondPage"/>
30+
<actionGroup ref="StorefrontQuickSearchWithPaginationActionGroup" stepKey="navigateToUnavailableCatalogSearchResultPage" before="waitForPageLoad">
3031
<argument name="phrase" value="AAA"/>
3132
<argument name="pageNumber" value="999"/>
3233
</actionGroup>
33-
<scrollTo selector="{{StorefrontCategoryBottomToolbarSection.currentPage}}" stepKey="scrollToBottomToolbarPager"/>
34-
<grabTextFrom selector="{{StorefrontCategoryBottomToolbarSection.currentPage}}" stepKey="grabNumberOfCurrentPage"/>
35-
<assertEquals stepKey="assertCurrentPageIsLastPageOfCatalogSearchResult">
36-
<expectedResult type="variable">grabNumberOfLastPage</expectedResult>
37-
<actualResult type="variable">grabNumberOfCurrentPage</actualResult>
38-
</assertEquals>
39-
<actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="assertProductOnLastCatalogSearchPage">
40-
<argument name="product" value="$createSecondProduct$"/>
41-
</actionGroup>
42-
<actionGroup ref="StorefrontCheckProductIsMissingInCategoryProductsPageActionGroup" stepKey="assertFirstProductIsMissingOnLastCatalogSearchPage">
43-
<argument name="productName" value="$createFirstProduct.name$"/>
44-
</actionGroup>
4534
</test>
4635
</tests>

0 commit comments

Comments
 (0)