Skip to content

Commit bda0636

Browse files
🔃 [Magento Community Engineering] Community Contributions - 2.4-develop daily delivery
Accepted Community Pull Requests: - #27886: Fixed #27874 Vat Validation URL for EU Vat numbers changed. (by @shikhamis11) - #27093: #27089 Fix issue with returning non-available default limit (by @lbajsarowicz) - #27926: Fixes incorrectly nested html in the product items list template. (by @hostep) - #27740: Redirecting users to sales order history page (by @ajithkumar-maragathavel) - #27892: Fixes unstable email integration tests (by @hostep) - #27578: Fix Magento Integrity Dependency test in case to be used not in scope of app/code isntallation. (by @swnsma) - #27323: MFTF: Add `<magentoCron` instruction - CatalogImportExport / CatalogInventory / CatalogRule (by @lbajsarowicz) - #27887: Fix Arabic and Hebrew in invoices (by @ihor-sviziev) - #27966: Correct used in sections image pattern, minor fixes (by @Nazar65) Fixed GitHub Issues: - #27089: BUG: `getDefaultLimitPerPageValue` returns value that is not available (reported by @lbajsarowicz) has been fixed in #27093 by @lbajsarowicz in 2.4-develop branch Related commits: 1. 17236cc 2. 381ab64 3. 778fbfb 4. d3962f2 5. aec01d8
2 parents 63d5896 + 7253d13 commit bda0636

File tree

39 files changed

+448
-192
lines changed

39 files changed

+448
-192
lines changed

app/code/Magento/Catalog/Helper/Product/ProductList.php

Lines changed: 46 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,37 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Catalog\Helper\Product;
89

10+
use Magento\Catalog\Model\Config;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
12+
use Magento\Framework\App\ObjectManager;
13+
use Magento\Framework\Registry;
14+
use Magento\Store\Model\ScopeInterface;
15+
916
/**
10-
* Class ProductList
17+
* Returns data for toolbars of Sorting and Pagination
1118
*
1219
* @api
1320
* @since 100.0.2
1421
*/
1522
class ProductList
1623
{
17-
/**
18-
* List mode configuration path
19-
*/
20-
const XML_PATH_LIST_MODE = 'catalog/frontend/list_mode';
24+
public const XML_PATH_LIST_MODE = 'catalog/frontend/list_mode';
25+
public const DEFAULT_SORT_DIRECTION = 'asc';
2126

2227
const VIEW_MODE_LIST = 'list';
2328
const VIEW_MODE_GRID = 'grid';
2429

25-
const DEFAULT_SORT_DIRECTION = 'asc';
2630
/**
27-
* @var \Magento\Framework\App\Config\ScopeConfigInterface
31+
* @var ScopeConfigInterface
2832
*/
2933
protected $scopeConfig;
3034

3135
/**
32-
* @var \Magento\Framework\Registry
36+
* @var Registry
3337
*/
3438
private $coreRegistry;
3539

@@ -38,20 +42,18 @@ class ProductList
3842
*
3943
* @var array
4044
*/
41-
protected $_defaultAvailableLimit = [10 => 10,20 => 20,50 => 50];
45+
protected $_defaultAvailableLimit = [10 => 10, 20 => 20, 50 => 50];
4246

4347
/**
44-
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
45-
* @param \Magento\Framework\Registry $coreRegistry
48+
* @param ScopeConfigInterface $scopeConfig
49+
* @param Registry $coreRegistry
4650
*/
4751
public function __construct(
48-
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
49-
\Magento\Framework\Registry $coreRegistry = null
52+
ScopeConfigInterface $scopeConfig,
53+
Registry $coreRegistry = null
5054
) {
5155
$this->scopeConfig = $scopeConfig;
52-
$this->coreRegistry = $coreRegistry ?: \Magento\Framework\App\ObjectManager::getInstance()->get(
53-
\Magento\Framework\Registry::class
54-
);
56+
$this->coreRegistry = $coreRegistry ?? ObjectManager::getInstance()->get(Registry::class);
5557
}
5658

5759
/**
@@ -61,31 +63,23 @@ public function __construct(
6163
*/
6264
public function getAvailableViewMode()
6365
{
64-
$value = $this->scopeConfig->getValue(
65-
self::XML_PATH_LIST_MODE,
66-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
67-
);
66+
$value = $this->scopeConfig->getValue(self::XML_PATH_LIST_MODE, ScopeInterface::SCOPE_STORE);
67+
6868
switch ($value) {
6969
case 'grid':
70-
$availableMode = ['grid' => __('Grid')];
71-
break;
70+
return ['grid' => __('Grid')];
7271

7372
case 'list':
74-
$availableMode = ['list' => __('List')];
75-
break;
73+
return ['list' => __('List')];
7674

7775
case 'grid-list':
78-
$availableMode = ['grid' => __('Grid'), 'list' => __('List')];
79-
break;
76+
return ['grid' => __('Grid'), 'list' => __('List')];
8077

8178
case 'list-grid':
82-
$availableMode = ['list' => __('List'), 'grid' => __('Grid')];
83-
break;
84-
default:
85-
$availableMode = null;
86-
break;
79+
return ['list' => __('List'), 'grid' => __('Grid')];
8780
}
88-
return $availableMode;
81+
82+
return null;
8983
}
9084

9185
/**
@@ -99,12 +93,14 @@ public function getDefaultViewMode($options = [])
9993
if (empty($options)) {
10094
$options = $this->getAvailableViewMode();
10195
}
96+
10297
return current(array_keys($options));
10398
}
10499

105100
/**
106101
* Get default sort field
107102
*
103+
* @FIXME Helper should be context-independent
108104
* @return null|string
109105
*/
110106
public function getDefaultSortField()
@@ -114,59 +110,46 @@ public function getDefaultSortField()
114110
return $currentCategory->getDefaultSortBy();
115111
}
116112

117-
return $this->scopeConfig->getValue(
118-
\Magento\Catalog\Model\Config::XML_PATH_LIST_DEFAULT_SORT_BY,
119-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
120-
);
113+
return $this->scopeConfig->getValue(Config::XML_PATH_LIST_DEFAULT_SORT_BY, ScopeInterface::SCOPE_STORE);
121114
}
122115

123116
/**
124117
* Retrieve available limits for specified view mode
125118
*
126-
* @param string $mode
119+
* @param string $viewMode
127120
* @return array
128121
*/
129-
public function getAvailableLimit($mode)
122+
public function getAvailableLimit($viewMode): array
130123
{
131-
if (!in_array($mode, [self::VIEW_MODE_GRID, self::VIEW_MODE_LIST])) {
124+
$availableViewModes = $this->getAvailableViewMode();
125+
126+
if (!isset($availableViewModes[$viewMode])) {
132127
return $this->_defaultAvailableLimit;
133128
}
134-
$perPageConfigKey = 'catalog/frontend/' . $mode . '_per_page_values';
135-
$perPageValues = (string)$this->scopeConfig->getValue(
136-
$perPageConfigKey,
137-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
138-
);
129+
130+
$perPageConfigPath = 'catalog/frontend/' . $viewMode . '_per_page_values';
131+
$perPageValues = (string)$this->scopeConfig->getValue($perPageConfigPath, ScopeInterface::SCOPE_STORE);
139132
$perPageValues = explode(',', $perPageValues);
140133
$perPageValues = array_combine($perPageValues, $perPageValues);
141-
if ($this->scopeConfig->isSetFlag(
142-
'catalog/frontend/list_allow_all',
143-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
144-
)) {
134+
if ($this->scopeConfig->isSetFlag('catalog/frontend/list_allow_all', ScopeInterface::SCOPE_STORE)) {
145135
return ($perPageValues + ['all' => __('All')]);
146136
} else {
147137
return $perPageValues;
148138
}
149139
}
150140

151141
/**
152-
* Retrieve default per page values
142+
* Returns default value of `per_page` for view mode provided
153143
*
154144
* @param string $viewMode
155-
* @return string (comma separated)
145+
* @return int
156146
*/
157-
public function getDefaultLimitPerPageValue($viewMode)
147+
public function getDefaultLimitPerPageValue($viewMode): int
158148
{
159-
if ($viewMode == self::VIEW_MODE_LIST) {
160-
return $this->scopeConfig->getValue(
161-
'catalog/frontend/list_per_page',
162-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
163-
);
164-
} elseif ($viewMode == self::VIEW_MODE_GRID) {
165-
return $this->scopeConfig->getValue(
166-
'catalog/frontend/grid_per_page',
167-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
168-
);
169-
}
170-
return 0;
149+
$xmlConfigPath = sprintf('catalog/frontend/%s_per_page', $viewMode);
150+
$defaultLimit = $this->scopeConfig->getValue($xmlConfigPath, ScopeInterface::SCOPE_STORE);
151+
152+
$availableLimits = $this->getAvailableLimit($viewMode);
153+
return (int)($availableLimits[$defaultLimit] ?? current($availableLimits));
171154
}
172155
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Test\Unit\Helper\Product;
9+
10+
use Magento\Catalog\Helper\Product\ProductList;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
12+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
13+
use PHPUnit\Framework\MockObject\MockObject;
14+
use PHPUnit\Framework\TestCase;
15+
16+
class ProductListTest extends TestCase
17+
{
18+
const STUB_VIEW_MODE = 'grid';
19+
/**
20+
* @var ScopeConfigInterface|MockObject
21+
*/
22+
private $scopeConfigMock;
23+
24+
/**
25+
* @var ProductList
26+
*/
27+
private $productListHelper;
28+
29+
protected function setUp()
30+
{
31+
$objectManager = new ObjectManager($this);
32+
33+
$this->scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class);
34+
$this->productListHelper = $objectManager->getObject(ProductList::class, [
35+
'scopeConfig' => $this->scopeConfigMock
36+
]);
37+
}
38+
39+
/**
40+
* @dataProvider defaultAvailableLimitsDataProvider
41+
*/
42+
public function testGetDefaultLimitPerPageValueReturnsOneOfAvailableLimits(
43+
string $availableValues,
44+
int $defaultValue,
45+
int $expectedReturn
46+
) {
47+
$this->scopeConfigMock->method('getValue')
48+
->willReturnMap([
49+
[sprintf('catalog/frontend/%s_per_page_values', self::STUB_VIEW_MODE), $availableValues],
50+
[sprintf('catalog/frontend/%s_per_page', self::STUB_VIEW_MODE), $defaultValue]
51+
]);
52+
53+
$returnedValue = $this->productListHelper->getDefaultLimitPerPageValue(self::STUB_VIEW_MODE);
54+
55+
$this->assertSame($expectedReturn, $returnedValue);
56+
}
57+
58+
public function defaultAvailableLimitsDataProvider(): array
59+
{
60+
return [
61+
'limit-available' => [
62+
'values' => '10,20,30',
63+
'default' => 10,
64+
'expected' => 10
65+
],
66+
'limit-not-available' => [
67+
'values' => '10,20,30',
68+
'default' => 1,
69+
'expected' => 10
70+
]
71+
];
72+
}
73+
}

app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ $_item = null;
242242
<?php // phpcs:disable ?>
243243
<div class="product actions product-item-actions">
244244
<?php if ($showCart):?>
245+
<div class="actions-primary">
245246
<?php if ($_item->isSaleable()):?>
246-
<div class="actions-primary">
247247
<?php if (!$_item->getTypeInstance()->isPossibleBuyFromList($_item)):?>
248248
<button
249249
class="action tocart primary"

app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportBundleProductTest.xml

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,10 @@
8080
<requiredEntity createDataKey="secondSimpleProductForFixedWithAttribute"/>
8181
</createData>
8282

83-
<!-- Run cron twice -->
84-
<magentoCLI command="cron:run" stepKey="runCron1"/>
85-
<magentoCLI command="cron:run" stepKey="runCron2"/>
86-
87-
<!-- Login as admin -->
83+
<magentoCron stepKey="runCron"/>
8884
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
8985
</before>
9086
<after>
91-
<!-- Delete products creations -->
9287
<deleteData createDataKey="createDynamicBundleProduct" stepKey="deleteDynamicBundleProduct"/>
9388
<deleteData createDataKey="firstSimpleProductForDynamic" stepKey="deleteFirstSimpleProductForDynamic"/>
9489
<deleteData createDataKey="secondSimpleProductForDynamic" stepKey="deleteSecondSimpleProductForDynamic"/>
@@ -100,10 +95,7 @@
10095
<deleteData createDataKey="secondSimpleProductForFixedWithAttribute" stepKey="deleteSecondSimpleProductForFixedWithAttribute"/>
10196
<deleteData createDataKey="createProductAttribute" stepKey="deleteProductAttribute"/>
10297

103-
<!-- Log out -->
10498
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
105-
106-
<!-- Reindex invalidated indices after product attribute has been created/deleted -->
10799
<magentoCron groups="index" stepKey="reindexInvalidatedIndices"/>
108100
</after>
109101

@@ -113,10 +105,6 @@
113105
<!-- Export created below products -->
114106
<actionGroup ref="ExportAllProductsActionGroup" stepKey="exportCreatedProducts"/>
115107

116-
<!-- Run cron -->
117-
<magentoCLI command="cron:run" stepKey="runCron3"/>
118-
<magentoCLI command="cron:run" stepKey="runCron4"/>
119-
120108
<grabTextFrom selector="{{AdminExportAttributeSection.exportFileNameByPosition('0')}}" stepKey="grabNameFile"/>
121109

122110
<!-- Download product -->

app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportGroupedProductWithSpecialPriceTest.xml

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,13 @@
4848
<requiredEntity createDataKey="createSecondSimpleProduct"/>
4949
</updateData>
5050

51-
<!-- Run cron twice -->
52-
<magentoCLI command="cron:run" stepKey="runCron1"/>
53-
<magentoCLI command="cron:run" stepKey="runCron2"/>
54-
55-
<!-- Login as admin -->
51+
<magentoCron stepKey="runCron"/>
5652
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
5753
</before>
5854
<after>
59-
<!-- Deleted created products -->
6055
<deleteData createDataKey="createFirstSimpleProduct" stepKey="deleteFirstSimpleProduct"/>
6156
<deleteData createDataKey="createSecondSimpleProduct" stepKey="deleteSecondSimpleProduct"/>
6257
<deleteData createDataKey="createGroupedProduct" stepKey="deleteGroupedProduct"/>
63-
64-
<!-- Delete category -->
6558
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
6659

6760
<!-- Log out -->
@@ -75,9 +68,7 @@
7568
<!-- Export created below products -->
7669
<actionGroup ref="ExportAllProductsActionGroup" stepKey="exportCreatedProducts"/>
7770

78-
<!-- Run cron -->
79-
<magentoCLI command="cron:run" stepKey="runCron3"/>
80-
<magentoCLI command="cron:run" stepKey="runCron4"/>
71+
<magentoCron stepKey="runCronIndex" groups="index"/>
8172

8273
<grabTextFrom selector="{{AdminExportAttributeSection.exportFileNameByPosition('0')}}" stepKey="grabNameFile"/>
8374

app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportImportConfigurableProductWithImagesTest.xml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@
126126
<requiredEntity createDataKey="createConfigChildProduct"/>
127127
</createData>
128128

129-
<!-- Login as admin -->
129+
<magentoCron stepKey="runCronIndex" groups="index"/>
130+
130131
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
131132
</before>
132133
<after>
@@ -151,8 +152,6 @@
151152
<actionGroup ref="ResetProductGridToDefaultViewActionGroup" stepKey="resetProductGridColumnsInitial"/>
152153
<!-- Admin logout-->
153154
<actionGroup ref="AdminLogoutActionGroup" stepKey="adminLogout"/>
154-
155-
<!-- Reindex invalidated indices after product attribute has been created/deleted -->
156155
<magentoCron groups="index" stepKey="reindexInvalidatedIndices"/>
157156
</after>
158157

0 commit comments

Comments
 (0)