Skip to content

Commit de5a558

Browse files
committed
Merge branch '2.4-develop' of https://github.com/magento/magento2ce into MC-41801
2 parents 2a27505 + 9a68d68 commit de5a558

File tree

93 files changed

+3156
-826
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+3156
-826
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@
4343
- [ ] Pull request has a meaningful description of its purpose
4444
- [ ] All commits are accompanied by meaningful commit messages
4545
- [ ] All new or changed code is covered with unit/integration tests (if applicable)
46+
- [ ] README.md files for modified modules are updated and included in the pull request if any [README.md predefined sections](https://github.com/magento/devdocs/wiki/Magento-module-README.md) require an update
4647
- [ ] All automated tests passed successfully (all builds are green)

app/code/Magento/Backend/Block/Store/Switcher.php

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

78
namespace Magento\Backend\Block\Store;
89

@@ -114,7 +115,8 @@ protected function _construct()
114115
{
115116
parent::_construct();
116117

117-
$this->setUseConfirm(true);
118+
$this->setUseConfirm($this->hasData('use_confirm') ? (bool)$this->getData('use_confirm') : true);
119+
118120
$this->setUseAjax(true);
119121

120122
$this->setShowManageStoresLink(0);

app/code/Magento/Backend/view/adminhtml/templates/store/switcher.phtml

Lines changed: 117 additions & 207 deletions
Large diffs are not rendered by default.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
define([
7+
'jquery'
8+
], function ($) {
9+
'use strict';
10+
11+
/**
12+
* @param {Object} storeSwitchConfig
13+
*/
14+
return function (storeSwitchConfig) {
15+
var scopeSwitcherHandler;
16+
17+
(function () {
18+
var storesList = $('[data-role=stores-list]');
19+
20+
storesList.on('click', '[data-value]', function (event) {
21+
var val = $(event.target).data('value'),
22+
role = $(event.target).data('role'),
23+
switcher = $('[data-role=' + role + ']');
24+
25+
event.preventDefault();
26+
27+
if (!switcher.val() || val !== switcher.val()) {
28+
29+
/* Set the value & trigger event */
30+
switcher.val(val).trigger('change');
31+
}
32+
});
33+
})($);
34+
35+
/**
36+
* Switch store scope
37+
*
38+
* @param {Object} obj
39+
* @return void
40+
*/
41+
function switchScope(obj) {
42+
var switcher = $(obj),
43+
scopeId = switcher.val(),
44+
scopeParams = '',
45+
switcherParams = {};
46+
47+
if (scopeId) {
48+
scopeParams = switcher.data('param') + '/' + scopeId + '/';
49+
}
50+
51+
if (obj.switchParams) {
52+
scopeParams += obj.switchParams;
53+
}
54+
55+
/**
56+
* Reload function for switcher
57+
*/
58+
function reload() {
59+
var url;
60+
61+
if (!storeSwitchConfig.isUsingIframe) {
62+
63+
if (storeSwitchConfig.switchUrl && storeSwitchConfig.switchUrl.length > 0) {
64+
url = storeSwitchConfig.switchUrl + scopeParams;
65+
66+
/* eslint-disable no-undef */
67+
setLocation(url);
68+
}
69+
70+
} else {
71+
$('#preview_selected_store').val(scopeId);
72+
$('#preview_form').submit();
73+
74+
$('.store-switcher .dropdown-menu li a').each(function () {
75+
var $this = $(this);
76+
77+
if ($this.data('role') === 'store-view-id' && $this.data('value') === scopeId) {
78+
$('#store-change-button').html($this.text());
79+
}
80+
});
81+
82+
$('#store-change-button').click();
83+
}
84+
}
85+
86+
if (typeof scopeSwitcherHandler !== 'undefined') {
87+
switcherParams = {
88+
scopeId: scopeId,
89+
scopeParams: scopeParams,
90+
useConfirm: storeSwitchConfig.useConfirm
91+
};
92+
93+
scopeSwitcherHandler(switcherParams);
94+
} else if (storeSwitchConfig.useConfirm) {
95+
require([
96+
'Magento_Ui/js/modal/confirm',
97+
'mage/translate'
98+
], function (confirm, $t) {
99+
confirm({
100+
content: $t('Please confirm scope switching. All data that hasn\'t been saved will be lost.'),
101+
actions: {
102+
103+
/**
104+
* Confirm action
105+
*/
106+
confirm: function () {
107+
reload();
108+
},
109+
110+
/**
111+
* Cancel action
112+
*/
113+
cancel: function () {
114+
obj.value = storeSwitchConfig.storeId ? storeSwitchConfig.storeId : '';
115+
}
116+
}
117+
});
118+
});
119+
} else {
120+
reload();
121+
}
122+
}
123+
124+
window.scopeSwitcherHandler = scopeSwitcherHandler;
125+
window.switchScope = switchScope;
126+
};
127+
});

app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price.php

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,21 @@ class Price implements DimensionalIndexerInterface
9191
*/
9292
private $moduleManager;
9393

94+
/**
95+
* @var string
96+
*/
97+
private $tmpBundlePriceTable;
98+
99+
/**
100+
* @var string
101+
*/
102+
private $tmpBundleSelectionTable;
103+
104+
/**
105+
* @var string
106+
*/
107+
private $tmpBundleOptionTable;
108+
94109
/**
95110
* @param IndexTableStructureFactory $indexTableStructureFactory
96111
* @param TableMaintainer $tableMaintainer
@@ -184,7 +199,16 @@ public function executeByDimensions(array $dimensions, \Traversable $entityIds)
184199
*/
185200
private function getBundlePriceTable()
186201
{
187-
return $this->getTable('catalog_product_index_price_bundle_tmp');
202+
if ($this->tmpBundlePriceTable === null) {
203+
$this->tmpBundlePriceTable = $this->getTable('catalog_product_index_price_bundle_temp');
204+
$this->getConnection()->createTemporaryTableLike(
205+
$this->tmpBundlePriceTable,
206+
$this->getTable('catalog_product_index_price_bundle_tmp'),
207+
true
208+
);
209+
}
210+
211+
return $this->tmpBundlePriceTable;
188212
}
189213

190214
/**
@@ -194,7 +218,16 @@ private function getBundlePriceTable()
194218
*/
195219
private function getBundleSelectionTable()
196220
{
197-
return $this->getTable('catalog_product_index_price_bundle_sel_tmp');
221+
if ($this->tmpBundleSelectionTable === null) {
222+
$this->tmpBundleSelectionTable = $this->getTable('catalog_product_index_price_bundle_sel_temp');
223+
$this->getConnection()->createTemporaryTableLike(
224+
$this->tmpBundleSelectionTable,
225+
$this->getTable('catalog_product_index_price_bundle_sel_tmp'),
226+
true
227+
);
228+
}
229+
230+
return $this->tmpBundleSelectionTable;
198231
}
199232

200233
/**
@@ -204,7 +237,16 @@ private function getBundleSelectionTable()
204237
*/
205238
private function getBundleOptionTable()
206239
{
207-
return $this->getTable('catalog_product_index_price_bundle_opt_tmp');
240+
if ($this->tmpBundleOptionTable === null) {
241+
$this->tmpBundleOptionTable = $this->getTable('catalog_product_index_price_bundle_opt_temp');
242+
$this->getConnection()->createTemporaryTableLike(
243+
$this->tmpBundleOptionTable,
244+
$this->getTable('catalog_product_index_price_bundle_opt_tmp'),
245+
true
246+
);
247+
}
248+
249+
return $this->tmpBundleOptionTable;
208250
}
209251

210252
/**
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
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\Bundle\Test\Unit\Model\ResourceModel\Indexer;
9+
10+
use Magento\Bundle\Model\ResourceModel\Indexer\Price;
11+
use Magento\Catalog\Model\Indexer\Product\Price\TableMaintainer;
12+
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\BasePriceModifier;
13+
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructureFactory;
14+
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\Query\JoinAttributeProcessor;
15+
use Magento\Framework\App\ResourceConnection;
16+
use Magento\Framework\DB\Adapter\AdapterInterface;
17+
use Magento\Framework\EntityManager\MetadataPool;
18+
use Magento\Framework\Event\ManagerInterface;
19+
use Magento\Framework\Module\Manager;
20+
use PHPUnit\Framework\MockObject\MockObject;
21+
use PHPUnit\Framework\TestCase;
22+
23+
/**
24+
* Class to test Bundle products Price indexer resource model
25+
*/
26+
class PriceTest extends TestCase
27+
{
28+
/**
29+
* @var string
30+
*/
31+
private $connectionName = 'test_connection';
32+
33+
/**
34+
* @var ResourceConnection|MockObject
35+
*/
36+
private $resourceMock;
37+
38+
/**
39+
* @var AdapterInterface|MockObject
40+
*/
41+
private $connectionMock;
42+
43+
/**
44+
* @var Price
45+
*/
46+
private $priceModel;
47+
48+
/**
49+
* @inheritdoc
50+
*/
51+
protected function setUp(): void
52+
{
53+
parent::setUp();
54+
55+
$this->connectionMock = $this->createMock(AdapterInterface::class);
56+
$this->resourceMock = $this->createMock(ResourceConnection::class);
57+
$this->resourceMock->method('getConnection')
58+
->with($this->connectionName)
59+
->willReturn($this->connectionMock);
60+
$this->resourceMock->method('getTableName')->willReturnArgument(0);
61+
62+
/** @var IndexTableStructureFactory|MockObject $indexTableStructureFactory */
63+
$indexTableStructureFactory = $this->createMock(IndexTableStructureFactory::class);
64+
/** @var TableMaintainer|MockObject $tableMaintainer */
65+
$tableMaintainer = $this->createMock(TableMaintainer::class);
66+
/** @var MetadataPool|MockObject $metadataPool */
67+
$metadataPool = $this->createMock(MetadataPool::class);
68+
/** @var BasePriceModifier|MockObject $basePriceModifier */
69+
$basePriceModifier = $this->createMock(BasePriceModifier::class);
70+
/** @var JoinAttributeProcessor|MockObject $joinAttributeProcessor */
71+
$joinAttributeProcessor = $this->createMock(JoinAttributeProcessor::class);
72+
/** @var ManagerInterface|MockObject $eventManager */
73+
$eventManager = $this->createMock(ManagerInterface::class);
74+
/** @var Manager|MockObject $moduleManager */
75+
$moduleManager = $this->createMock(Manager::class);
76+
$fullReindexAction = false;
77+
78+
$this->priceModel = new Price(
79+
$indexTableStructureFactory,
80+
$tableMaintainer,
81+
$metadataPool,
82+
$this->resourceMock,
83+
$basePriceModifier,
84+
$joinAttributeProcessor,
85+
$eventManager,
86+
$moduleManager,
87+
$fullReindexAction,
88+
$this->connectionName
89+
);
90+
}
91+
92+
/**
93+
* Tests create Bundle Price temporary table
94+
*/
95+
public function testGetBundlePriceTable(): void
96+
{
97+
$expectedTmpTableName = 'catalog_product_index_price_bundle_temp';
98+
$expectedTableName = 'catalog_product_index_price_bundle_tmp';
99+
100+
$this->connectionMock->expects($this->once())
101+
->method('createTemporaryTableLike')
102+
->with($expectedTmpTableName, $expectedTableName, true);
103+
104+
$this->assertEquals(
105+
$expectedTmpTableName,
106+
$this->invokeMethodViaReflection('getBundlePriceTable')
107+
);
108+
}
109+
110+
/**
111+
* Tests create Bundle Selection Prices Index temporary table
112+
*/
113+
public function testGetBundleSelectionTable(): void
114+
{
115+
$expectedTmpTableName = 'catalog_product_index_price_bundle_sel_temp';
116+
$expectedTableName = 'catalog_product_index_price_bundle_sel_tmp';
117+
118+
$this->connectionMock->expects($this->once())
119+
->method('createTemporaryTableLike')
120+
->with($expectedTmpTableName, $expectedTableName, true);
121+
122+
$this->assertEquals(
123+
$expectedTmpTableName,
124+
$this->invokeMethodViaReflection('getBundleSelectionTable')
125+
);
126+
}
127+
128+
/**
129+
* Tests create Bundle Option Prices Index temporary table
130+
*/
131+
public function testGetBundleOptionTable(): void
132+
{
133+
$expectedTmpTableName = 'catalog_product_index_price_bundle_opt_temp';
134+
$expectedTableName = 'catalog_product_index_price_bundle_opt_tmp';
135+
136+
$this->connectionMock->expects($this->once())
137+
->method('createTemporaryTableLike')
138+
->with($expectedTmpTableName, $expectedTableName, true);
139+
140+
$this->assertEquals(
141+
$expectedTmpTableName,
142+
$this->invokeMethodViaReflection('getBundleOptionTable')
143+
);
144+
}
145+
146+
/**
147+
* Invoke private method via reflection
148+
*
149+
* @param string $methodName
150+
* @return string
151+
*/
152+
private function invokeMethodViaReflection(string $methodName): string
153+
{
154+
$method = new \ReflectionMethod(
155+
Price::class,
156+
$methodName
157+
);
158+
$method->setAccessible(true);
159+
160+
return (string)$method->invoke($this->priceModel);
161+
}
162+
}

0 commit comments

Comments
 (0)