Skip to content

Commit cf10670

Browse files
committed
Merge remote-tracking branch 'origin/MC-30685' into 2.3-develop-com-pr15
2 parents 748b09e + f1593ac commit cf10670

File tree

26 files changed

+974
-256
lines changed

26 files changed

+974
-256
lines changed

app/code/Magento/Catalog/Ui/Component/Listing/Columns/Websites.php

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

98
namespace Magento\Catalog\Ui\Component\Listing\Columns;
@@ -121,31 +120,32 @@ protected function applySorting()
121120
&& !empty($sorting['direction'])
122121
&& $sorting['field'] === $this->getName()
123122
) {
123+
/** @var \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection $collection */
124124
$collection = $this->getContext()->getDataProvider()->getCollection();
125-
$collection
126-
->joinField(
127-
'websites_ids',
128-
'catalog_product_website',
129-
'website_id',
130-
'product_id=entity_id',
131-
null,
132-
'left'
133-
)
134-
->joinTable(
135-
'store_website',
136-
'website_id = websites_ids',
137-
['name'],
138-
null,
139-
'left'
140-
)
141-
->groupByAttribute('entity_id');
142-
$this->resourceHelper->addGroupConcatColumn(
143-
$collection->getSelect(),
144-
$this->websiteNames,
145-
'name'
125+
126+
$select = $collection->getConnection()->select();
127+
$select->from(
128+
['cpw' => $collection->getTable('catalog_product_website')],
129+
['product_id']
130+
)->joinLeft(
131+
['sw' => $collection->getTable('store_website')],
132+
'cpw.website_id = sw.website_id',
133+
[
134+
$this->websiteNames => new \Zend_Db_Expr(
135+
'GROUP_CONCAT(sw.name ORDER BY sw.website_id ASC SEPARATOR \',\')'
136+
)
137+
]
138+
)->group(
139+
'cpw.product_id'
146140
);
147141

148-
$collection->getSelect()->order($this->websiteNames . ' ' . $sorting['direction']);
142+
$collection->getSelect()->joinLeft(
143+
['product_websites' => $select],
144+
'product_websites.product_id = e.entity_id',
145+
[$this->websiteNames]
146+
)->order(
147+
'product_websites.' . $this->websiteNames . ' ' . $sorting['direction']
148+
);
149149
}
150150
}
151151
}

app/code/Magento/Cms/Model/ResourceModel/Block.php

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,9 @@ public function getIsUniqueBlockToStores(AbstractModel $object)
185185
$entityMetadata = $this->metadataPool->getMetadata(BlockInterface::class);
186186
$linkField = $entityMetadata->getLinkField();
187187

188-
$stores = (array)$object->getData('store_id');
189-
$isDefaultStore = $this->_storeManager->isSingleStoreMode()
190-
|| array_search(Store::DEFAULT_STORE_ID, $stores) !== false;
191-
192-
if (!$isDefaultStore) {
193-
$stores[] = Store::DEFAULT_STORE_ID;
194-
}
188+
$stores = $this->_storeManager->isSingleStoreMode()
189+
? [Store::DEFAULT_STORE_ID]
190+
: (array)$object->getData('store_id');
195191

196192
$select = $this->getConnection()->select()
197193
->from(['cb' => $this->getMainTable()])
@@ -200,11 +196,8 @@ public function getIsUniqueBlockToStores(AbstractModel $object)
200196
'cb.' . $linkField . ' = cbs.' . $linkField,
201197
[]
202198
)
203-
->where('cb.identifier = ? ', $object->getData('identifier'));
204-
205-
if (!$isDefaultStore) {
206-
$select->where('cbs.store_id IN (?)', $stores);
207-
}
199+
->where('cb.identifier = ? ', $object->getData('identifier'))
200+
->where('cbs.store_id IN (?)', $stores);
208201

209202
if ($object->getId()) {
210203
$select->where('cb.' . $entityMetadata->getIdentifierField() . ' <> ?', $object->getId());

app/code/Magento/Cms/Test/Mftf/Test/CheckStaticBlocksTest.xml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,23 @@
5656
<seeInCurrentUrl url="cms/block/new" stepKey="VerifyNewBlockPageIsOpened1"/>
5757
<!--Add new BLock with the same data-->
5858
<actionGroup ref="FillOutBlockContent" stepKey="FillOutBlockContent1"/>
59-
<selectOption selector="{{BlockNewPageBasicFieldsSection.storeView}}" userInput="Default Store View" stepKey="selectDefaultStoreView" />
60-
<selectOption selector="{{BlockNewPageBasicFieldsSection.storeView}}" userInput="{{customStore.name}}" stepKey="selectSecondStoreView1" />
6159
<click selector="{{BlockNewPagePageActionsSection.saveBlock}}" stepKey="ClickToSaveBlock1"/>
6260
<waitForPageLoad stepKey="waitForPageLoad6"/>
6361
<!--Verify that corresponding message is displayed-->
6462
<see userInput="A block identifier with the same properties already exists in the selected store." stepKey="VerifyBlockIsSaved1"/>
63+
<!--Click to go back and add new block-->
64+
<click selector="{{BlockNewPagePageActionsSection.back}}" stepKey="ClickToGoBack1"/>
65+
<waitForPageLoad stepKey="waitForPageLoad7"/>
66+
<click selector="{{BlockPageActionsSection.addNewBlock}}" stepKey="ClickToAddNewBlock2"/>
67+
<waitForPageLoad stepKey="waitForPageLoad8"/>
68+
<seeInCurrentUrl url="cms/block/new" stepKey="VerifyNewBlockPageIsOpened2"/>
69+
<!--Add new BLock with the same data for another store view-->
70+
<actionGroup ref="FillOutBlockContent" stepKey="FillOutBlockContent2"/>
71+
<selectOption selector="{{BlockNewPageBasicFieldsSection.storeView}}" userInput="Default Store View" stepKey="selectDefaultStoreView" />
72+
<selectOption selector="{{BlockNewPageBasicFieldsSection.storeView}}" userInput="{{customStore.name}}" stepKey="selectSecondStoreView1" />
73+
<click selector="{{BlockNewPagePageActionsSection.saveBlock}}" stepKey="ClickToSaveBlock2"/>
74+
<waitForPageLoad stepKey="waitForPageLoad9"/>
75+
<see userInput="You saved the block." stepKey="VerifyBlockIsSaved2"/>
6576

6677
<after>
6778
<actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="DeleteWebsite">

app/code/Magento/Config/Model/Config/Importer/SaveProcessor.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,18 +91,21 @@ public function process(array $data)
9191
* @param string $scope The configuration scope (default, website, or store)
9292
* @param string $scopeCode The scope code
9393
* @return void
94+
* @throws \Magento\Framework\Exception\RuntimeException
9495
*/
9596
private function invokeSave(array $scopeData, $scope, $scopeCode = null)
9697
{
9798
$scopeData = array_keys($this->arrayUtils->flatten($scopeData));
9899

99100
foreach ($scopeData as $path) {
100101
$value = $this->scopeConfig->getValue($path, $scope, $scopeCode);
101-
$backendModel = $this->valueFactory->create($path, $value, $scope, $scopeCode);
102+
if ($value !== null) {
103+
$backendModel = $this->valueFactory->create($path, $value, $scope, $scopeCode);
102104

103-
if ($backendModel instanceof Value) {
104-
$backendModel->beforeSave();
105-
$backendModel->afterSave();
105+
if ($backendModel instanceof Value) {
106+
$backendModel->beforeSave();
107+
$backendModel->afterSave();
108+
}
106109
}
107110
}
108111
}

app/code/Magento/Config/Test/Unit/Model/Config/Importer/SaveProcessorTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,37 @@ public function testProcess()
136136

137137
$this->assertSame(null, $this->model->process($data));
138138
}
139+
140+
public function testProcessWithNullValues()
141+
{
142+
$data = [
143+
'default' => [
144+
'advanced' => ['modules_disable_output' => ['Test_Module' => '1']]
145+
],
146+
'websites' => ['test_website' => ['general' => ['locale' => ['timezone' => 'America/Rio_Branco']]]],
147+
];
148+
$this->arrayUtilsMock->expects($this->exactly(2))
149+
->method('flatten')
150+
->willReturnMap([
151+
[
152+
[
153+
'advanced' => ['modules_disable_output' => ['Test_Module' => '1']]
154+
],
155+
'',
156+
'/',
157+
['advanced/modules_disable_output/Test_Module' => '1']
158+
],
159+
[
160+
['general' => ['locale' => ['timezone' => 'America/Rio_Branco']]],
161+
'',
162+
'/',
163+
['general/locale/timezone' => 'America/Rio_Branco']
164+
]
165+
]);
166+
$this->scopeConfigMock->expects($this->exactly(2))
167+
->method('getValue')
168+
->willReturn(null);
169+
170+
$this->assertSame(null, $this->model->process($data));
171+
}
139172
}

app/code/Magento/Customer/CustomerData/SectionConfigConverter.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
namespace Magento\Customer\CustomerData;
77

8+
/**
9+
* Class that receives xml merged source and process it.
10+
*/
811
class SectionConfigConverter implements \Magento\Framework\Config\ConverterInterface
912
{
1013
/**
@@ -13,18 +16,26 @@ class SectionConfigConverter implements \Magento\Framework\Config\ConverterInter
1316
const INVALIDATE_ALL_SECTIONS_MARKER = '*';
1417

1518
/**
16-
* {@inheritdoc}
19+
* @inheritdoc
1720
*/
1821
public function convert($source)
1922
{
2023
$sections = [];
2124
foreach ($source->getElementsByTagName('action') as $action) {
2225
$actionName = strtolower($action->getAttribute('name'));
2326
foreach ($action->getElementsByTagName('section') as $section) {
24-
$sections[$actionName][] = strtolower($section->getAttribute('name'));
27+
$sectionName = strtolower($section->getAttribute('name'));
28+
29+
if ($sectionName === self::INVALIDATE_ALL_SECTIONS_MARKER) {
30+
$sections[$actionName] = [];
31+
$sections[$actionName][] = self::INVALIDATE_ALL_SECTIONS_MARKER;
32+
break;
33+
} else {
34+
$sections[$actionName][] = $sectionName;
35+
}
2536
}
2637
if (!isset($sections[$actionName])) {
27-
$sections[$actionName] = self::INVALIDATE_ALL_SECTIONS_MARKER;
38+
$sections[$actionName][] = self::INVALIDATE_ALL_SECTIONS_MARKER;
2839
}
2940
}
3041
return [

app/code/Magento/Customer/Test/Unit/CustomerData/SectionConfigConverterTest.php

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Magento\Customer\Test\Unit\CustomerData;
88

9+
use Magento\Framework\App\Arguments\ValidationState;
910
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
1011

1112
class SectionConfigConverterTest extends \PHPUnit\Framework\TestCase
@@ -19,27 +20,74 @@ class SectionConfigConverterTest extends \PHPUnit\Framework\TestCase
1920
/** @var \DOMDocument */
2021
protected $source;
2122

23+
/** @var \Magento\Framework\Config\Dom config merger */
24+
private $configMergerClass;
25+
26+
/** @var ValidationState */
27+
private $validationStateMock;
28+
2229
protected function setUp()
2330
{
2431
$this->source = new \DOMDocument();
2532
$this->objectManagerHelper = new ObjectManagerHelper($this);
2633
$this->converter = $this->objectManagerHelper->getObject(
2734
\Magento\Customer\CustomerData\SectionConfigConverter::class
2835
);
36+
$this->validationStateMock = $this->createMock(ValidationState::class);
37+
}
38+
39+
/**
40+
* Return newly created instance of a config merger
41+
*
42+
* @param string $mergerClass
43+
* @param string $initialContents
44+
* @return \Magento\Framework\Config\Dom
45+
* @throws \UnexpectedValueException
46+
*/
47+
private function createConfig($mergerClass, $initialContents)
48+
{
49+
$this->validationStateMock->method('isValidationRequired')->willReturn(\false);
50+
return new $mergerClass(
51+
$initialContents,
52+
$this->validationStateMock,
53+
[
54+
'/config/action' => 'name',
55+
'/config/action/section' => 'name',
56+
],
57+
null,
58+
null
59+
);
2960
}
3061

3162
public function testConvert()
3263
{
3364
$this->source->loadXML(file_get_contents(__DIR__ . '/_files/sections.xml'));
3465

66+
$this->configMergerClass = $this->createConfig(
67+
'Magento\Framework\Config\Dom',
68+
file_get_contents(__DIR__ . '/_files/sections.xml')
69+
);
70+
71+
$this->configMergerClass->merge(file_get_contents(__DIR__ . '/_files/sections2.xml'));
72+
3573
$this->assertEquals(
3674
[
3775
'sections' => [
38-
'customer/account/logout' => '*',
39-
'customer/account/editpost' => ['account'],
76+
'sales/guest/reorder' => ['account'],
77+
'sales/order/reorder' => ['account', 'cart'],
78+
'stores/store/switch' => ['*'],
79+
'directory/currency/switch' => ['*'],
80+
'customer/account/logout' => ['account', 'cart'],
81+
'customer/account/editpost' => ['account', 'acc', 'cart'],
82+
'checkout/cart/delete' => ['*'],
83+
'customer/account/createpost' => ['*'],
84+
'catalog/product_compare/add' => ['*'],
85+
'catalog/product_compare/remove' => ['account', 'acc'],
86+
'catalog/product_compare/clear' => ['*'],
87+
'checkout/cart/add' => ['*'],
4088
],
4189
],
42-
$this->converter->convert($this->source)
90+
$this->converter->convert($this->configMergerClass->getDom())
4391
);
4492
}
4593
}

app/code/Magento/Customer/Test/Unit/CustomerData/_files/sections.xml

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,56 @@
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
99
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
10-
<action name="customer/account/logout"/>
10+
<!-- Actions 1-4 are specified in sections.xml file only -->
11+
<!-- 1 - Action has one Section -->
12+
<action name="sales/guest/reorder">
13+
<section name="account"/>
14+
</action>
15+
<!-- 2 - Action has two Sections -->
16+
<action name="sales/order/reorder">
17+
<section name="account"/>
18+
<section name="cart"/>
19+
</action>
20+
<!-- 3 - Action has two Sections and "*" -->
21+
<action name="stores/store/switch">
22+
<section name="account"/>
23+
<section name="*"/>
24+
<section name="cart"/>
25+
</action>
26+
<!-- 4 - Action has "empty_section" -->
27+
<action name="directory/currency/switch"/>
28+
<!-- Actions 5-12 are specified in files sections.xml and sections2.xml for merging -->
29+
<!-- 5 - Action in both files has unique Section -->
30+
<action name="customer/account/logout">
31+
<section name="account"/>
32+
</action>
33+
<!-- 6 - Action in both files has at least one identical Section -->
1134
<action name="customer/account/editPost">
1235
<section name="account"/>
36+
<section name="acc"/>
37+
</action>
38+
<!-- 7 - Action in both files has at least one identical Section and "*" -->
39+
<action name="checkout/cart/delete">
40+
<section name="account"/>
41+
<section name="acc"/>
42+
</action>
43+
<!-- 8 - Action in both files has Section and "*" -->
44+
<action name="customer/account/createPost">
45+
<section name="account"/>
46+
</action>
47+
<!-- 9 - Action in both files has "*" and "*" -->
48+
<action name="catalog/product_compare/add">
49+
<section name="*"/>
50+
</action>
51+
<!-- 10 - Action in both files has Section and "empty_section" -->
52+
<action name="catalog/product_compare/remove">
53+
<section name="account"/>
54+
<section name="acc"/>
55+
</action>
56+
<!-- 11 - Action in both files has "empty_section" and "empty_section" -->
57+
<action name="catalog/product_compare/clear"/>
58+
<!-- 12 - Action in both files has "*" and "empty_section" -->
59+
<action name="checkout/cart/add">
60+
<section name="*"/>
1361
</action>
1462
</config>

0 commit comments

Comments
 (0)