Skip to content

Commit 0887683

Browse files
authored
Merge pull request #5194 from magento-tsg/2.3-develop-pr97
[TSG] Fixes for 2.3 (pr97) (2.3-develop)
2 parents e4d4947 + ea0dff0 commit 0887683

File tree

16 files changed

+471
-56
lines changed

16 files changed

+471
-56
lines changed

app/code/Magento/Backend/view/adminhtml/web/js/translate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ define([
3535
* @return {String}
3636
*/
3737
this.translate = function (text) {
38-
return _data[text] ? _data[text] : text;
38+
return typeof _data[text] === 'string' ? _data[text] : text;
3939
};
4040

4141
return this;

app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
use Magento\Eav\Api\Data\AttributeGroupInterfaceFactory;
1818
use Magento\Eav\Api\Data\AttributeInterface;
1919
use Magento\Eav\Api\Data\AttributeSetInterface;
20+
use Magento\Eav\Model\Cache\Type as CacheType;
2021
use Magento\Framework\Api\ExtensionAttributesFactory;
2122
use Magento\Framework\Api\SearchCriteriaBuilder;
2223
use Magento\Framework\App\Action\HttpPostActionInterface;
24+
use Magento\Framework\App\CacheInterface;
2325
use Magento\Framework\App\ObjectManager;
2426
use Magento\Framework\Controller\Result\Json;
2527
use Magento\Framework\Controller\Result\JsonFactory;
@@ -29,7 +31,7 @@
2931
use Psr\Log\LoggerInterface;
3032

3133
/**
32-
* Class AddAttributeToTemplate
34+
* Assign attribute to attribute set.
3335
*
3436
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
3537
*/
@@ -80,6 +82,11 @@ class AddAttributeToTemplate extends Product implements HttpPostActionInterface
8082
*/
8183
protected $extensionAttributesFactory;
8284

85+
/**
86+
* @var CacheInterface
87+
*/
88+
private $cache;
89+
8390
/**
8491
* Constructor
8592
*
@@ -94,8 +101,8 @@ class AddAttributeToTemplate extends Product implements HttpPostActionInterface
94101
* @param AttributeManagementInterface $attributeManagement
95102
* @param LoggerInterface $logger
96103
* @param ExtensionAttributesFactory $extensionAttributesFactory
104+
* @param CacheInterface|null $cache
97105
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
98-
* @SuppressWarnings(PHPMD.LongVariable)
99106
* @SuppressWarnings(PHPMD.NPathComplexity)
100107
*/
101108
public function __construct(
@@ -109,7 +116,8 @@ public function __construct(
109116
SearchCriteriaBuilder $searchCriteriaBuilder = null,
110117
AttributeManagementInterface $attributeManagement = null,
111118
LoggerInterface $logger = null,
112-
ExtensionAttributesFactory $extensionAttributesFactory = null
119+
ExtensionAttributesFactory $extensionAttributesFactory = null,
120+
CacheInterface $cache = null
113121
) {
114122
parent::__construct($context, $productBuilder);
115123
$this->resultJsonFactory = $resultJsonFactory;
@@ -129,6 +137,7 @@ public function __construct(
129137
->get(LoggerInterface::class);
130138
$this->extensionAttributesFactory = $extensionAttributesFactory ?: ObjectManager::getInstance()
131139
->get(ExtensionAttributesFactory::class);
140+
$this->cache = $cache ?? ObjectManager::getInstance()->get(CacheInterface::class);
132141
}
133142

134143
/**
@@ -203,6 +212,7 @@ function (AttributeInterface $attribute) use ($attributeSet, $attributeGroup) {
203212
);
204213
}
205214
);
215+
$this->cache->clean([CacheType::CACHE_TAG]);
206216
} catch (LocalizedException $e) {
207217
$response->setError(true);
208218
$response->setMessage($e->getMessage());
@@ -223,7 +233,7 @@ function (AttributeInterface $attribute) use ($attributeSet, $attributeGroup) {
223233
*/
224234
private function getBasicAttributeSearchCriteriaBuilder()
225235
{
226-
$attributeIds = (array) $this->getRequest()->getParam('attributeIds', []);
236+
$attributeIds = (array)$this->getRequest()->getParam('attributeIds', []);
227237

228238
if (empty($attributeIds['selected'])) {
229239
throw new LocalizedException(__('Attributes were missing and must be specified.'));

app/code/Magento/Catalog/Model/Product/ProductFrontendAction/Synchronizer.php

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,16 @@ private function filterNewestActions(array $productsData, $typeId)
125125
$lifetime = $this->getLifeTimeByNamespace($typeId);
126126
$actionsNumber = $lifetime * self::TIME_TO_DO_ONE_ACTION;
127127

128-
uasort($productsData, function (array $firstProduct, array $secondProduct) {
129-
return $firstProduct['added_at'] > $secondProduct['added_at'];
130-
});
128+
uasort(
129+
$productsData,
130+
function (array $firstProduct, array $secondProduct) {
131+
if (isset($firstProduct['added_at'], $secondProduct['added_at'])) {
132+
return $firstProduct['added_at'] > $secondProduct['added_at'];
133+
}
134+
135+
return false;
136+
}
137+
);
131138

132139
return array_slice($productsData, 0, $actionsNumber, true);
133140
}
@@ -185,15 +192,17 @@ public function syncActions(array $productsData, $typeId)
185192

186193
foreach ($productsData as $productId => $productData) {
187194
/** @var ProductFrontendActionInterface $action */
188-
$action = $this->productFrontendActionFactory->create([
189-
'data' => [
190-
'visitor_id' => $customerId ? null : $visitorId,
191-
'customer_id' => $this->session->getCustomerId(),
192-
'added_at' => $productData['added_at'],
193-
'product_id' => $productId,
194-
'type_id' => $typeId
195+
$action = $this->productFrontendActionFactory->create(
196+
[
197+
'data' => [
198+
'visitor_id' => $customerId ? null : $visitorId,
199+
'customer_id' => $this->session->getCustomerId(),
200+
'added_at' => $productData['added_at'],
201+
'product_id' => $productId,
202+
'type_id' => $typeId
203+
]
195204
]
196-
]);
205+
);
197206

198207
$this->entityManager->save($action);
199208
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminExpandProductAttributesTabActionGroup">
12+
<annotations>
13+
<description>Expands the 'Attributes' tab on the Admin Product page.</description>
14+
</annotations>
15+
16+
<scrollTo selector="{{AdminProductAttributeSection.attributeSectionHeader}}" stepKey="scrollToAttributesTab"/>
17+
<conditionalClick selector="{{AdminProductAttributeSection.attributeSectionHeader}}" dependentSelector="{{AdminProductAttributeSection.attributeSection}}" visible="false" stepKey="expandAttributesTab"/>
18+
</actionGroup>
19+
</actionGroups>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AssertStorefrontAttributeOptionPresentInLayeredNavigationActionGroup">
12+
<annotations>
13+
<description>Clicks on the attribute label. Checks for attribute option presence.</description>
14+
</annotations>
15+
<arguments>
16+
<argument name="attributeLabel" type="string" defaultValue="{{ProductAttributeFrontendLabel.label}}"/>
17+
<argument name="attributeOptionLabel" type="string" defaultValue="{{Option1Store0.label}}"/>
18+
<argument name="attributeOptionPosition" type="string" defaultValue="1"/>
19+
</arguments>
20+
21+
<waitForElementVisible selector="{{StorefrontCategorySidebarSection.filterOptionsTitle(attributeLabel)}}" stepKey="waitForAttributeVisible"/>
22+
<conditionalClick selector="{{StorefrontCategorySidebarSection.filterOptionsTitle(attributeLabel)}}" dependentSelector="{{StorefrontCategorySidebarSection.activeFilterOptions}}" visible="false" stepKey="clickToExpandAttribute"/>
23+
<waitForElementVisible selector="{{StorefrontCategorySidebarSection.activeFilterOptions}}" stepKey="waitForAttributeOptionsVisible"/>
24+
<see selector="{{StorefrontCategorySidebarSection.activeFilterOptionItemByPosition(attributeOptionPosition)}}" userInput="{{attributeOptionLabel}}" stepKey="assertAttributeOptionInLayeredNavigation"/>
25+
</actionGroup>
26+
</actionGroups>

app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
<element name="optionQty" type="text" selector=".filter-options-content .item .count"/>
1616
<element name="filterOptionByLabel" type="button" selector=" div.filter-options-item div[option-label='{{optionLabel}}']" parameterized="true"/>
1717
<element name="removeFilter" type="button" selector="div.filter-current .remove"/>
18+
<element name="activeFilterOptions" type="text" selector=".filter-options-item.active .items"/>
19+
<element name="activeFilterOptionItemByPosition" type="text" selector=".filter-options-item.active .items li:nth-child({{itemPosition}}) a" parameterized="true"/>
1820
</section>
1921
<section name="StorefrontCategorySidebarMobileSection">
2022
<element name="shopByButton" type="button" selector="//div[contains(@class, 'filter-title')]/strong[contains(text(), 'Shop By')]"/>
2123
</section>
22-
</sections>
24+
</sections>
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
10+
<test name="AdminCheckCustomAttributeValuesAfterProductSaveTest">
11+
<annotations>
12+
<features value="Catalog"/>
13+
<stories value="Product attributes"/>
14+
<title value="Saving custom attribute values using UI"/>
15+
<description value="Checks that saved custom attribute values are reflected on the product's edit page"/>
16+
<severity value="MAJOR"/>
17+
<testCaseId value="MC-17516"/>
18+
<useCaseId value="MC-29022"/>
19+
<group value="catalog"/>
20+
</annotations>
21+
<before>
22+
<!-- Create multi select product attribute -->
23+
<createData entity="productAttributeMultiselectTwoOptions" stepKey="createMultiSelectProductAttribute"/>
24+
<!-- Add options to created product attribute -->
25+
<createData entity="productAttributeOption1" stepKey="addFirstOptionToAttribute">
26+
<requiredEntity createDataKey="createMultiSelectProductAttribute"/>
27+
</createData>
28+
<createData entity="productAttributeOption2" stepKey="addSecondOptionToAttribute">
29+
<requiredEntity createDataKey="createMultiSelectProductAttribute"/>
30+
</createData>
31+
<createData entity="productAttributeOption3" stepKey="addThirdOptionToAttribute">
32+
<requiredEntity createDataKey="createMultiSelectProductAttribute"/>
33+
</createData>
34+
<!-- Create simple product -->
35+
<createData entity="SimpleProduct2" stepKey="createSimpleProduct"/>
36+
<magentoCLI command="indexer:reindex" arguments="catalogsearch_fulltext" stepKey="reindexCatalogSearch"/>
37+
<!-- Login to Admin page -->
38+
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
39+
</before>
40+
<after>
41+
<!-- Delete created entities -->
42+
<deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/>
43+
<deleteData createDataKey="createMultiSelectProductAttribute" stepKey="deleteMultiSelectProductAttribute"/>
44+
<!-- Logout from Admin page -->
45+
<actionGroup ref="logout" stepKey="logoutFromAdmin"/>
46+
</after>
47+
48+
<!-- Open created product for edit -->
49+
<amOnPage url="{{AdminProductEditPage.url($createSimpleProduct.id$)}}" stepKey="goToProductEditPage"/>
50+
<waitForPageLoad stepKey="waitForProductPageLoad"/>
51+
52+
<!-- Add created attribute to the product -->
53+
<actionGroup ref="addProductAttributeInProductModal" stepKey="addAttributeToProduct">
54+
<argument name="attributeCode" value="$createMultiSelectProductAttribute.attribute_code$"/>
55+
</actionGroup>
56+
<waitForPageLoad stepKey="waitForAttributeAdded"/>
57+
58+
<!-- Expand 'Attributes' tab -->
59+
<actionGroup ref="AdminExpandProductAttributesTabActionGroup" stepKey="expandAttributesTab"/>
60+
<!-- Check created attribute presents in the 'Attributes' tab -->
61+
<seeElement selector="{{AdminProductAttributesSection.attributeDropdownByCode($createMultiSelectProductAttribute.attribute_code$)}}" stepKey="assertAttributeIsPresentInTab"/>
62+
<!-- Select attribute options -->
63+
<selectOption selector="{{AdminProductAttributesSection.attributeDropdownByCode($createMultiSelectProductAttribute.attribute_code$)}}" parameterArray="[$addFirstOptionToAttribute.option[store_labels][0][label]$, $addThirdOptionToAttribute.option[store_labels][0][label]$]" stepKey="selectAttributeOptions"/>
64+
<!-- Save product -->
65+
<actionGroup ref="saveProductForm" stepKey="saveProductForm"/>
66+
67+
<!-- Check attribute options are selected -->
68+
<actionGroup ref="AdminExpandProductAttributesTabActionGroup" stepKey="expandAttributesTabAfterProductSave"/>
69+
<seeOptionIsSelected selector="{{AdminProductAttributesSection.attributeDropdownByCode($createMultiSelectProductAttribute.attribute_code$)}}" userInput="$addFirstOptionToAttribute.option[store_labels][0][label]$" stepKey="assertFirstOptionIsSelected"/>
70+
<seeOptionIsSelected selector="{{AdminProductAttributesSection.attributeDropdownByCode($createMultiSelectProductAttribute.attribute_code$)}}" userInput="$addThirdOptionToAttribute.option[store_labels][0][label]$" stepKey="assertThirdOptionIsSelected"/>
71+
72+
<!-- Search for the product on Storefront -->
73+
<amOnPage url="{{StorefrontHomePage.url}}" stepKey="goToHomePage"/>
74+
<waitForPageLoad stepKey="waitForHomePageLoad"/>
75+
<actionGroup ref="StorefrontCheckQuickSearchActionGroup" stepKey="searchProductOnStorefront">
76+
<argument name="phrase" value="$createSimpleProduct.name$"/>
77+
</actionGroup>
78+
79+
<!-- Assert that attribute values present in layered navigation -->
80+
<actionGroup ref="AssertStorefrontAttributeOptionPresentInLayeredNavigationActionGroup" stepKey="assertFirstAttributeOptionPresence">
81+
<argument name="attributeLabel" value="$createMultiSelectProductAttribute.attribute[frontend_labels][0][label]$"/>
82+
<argument name="attributeOptionLabel" value="$addFirstOptionToAttribute.option[store_labels][0][label]$"/>
83+
<argument name="attributeOptionPosition" value="1"/>
84+
</actionGroup>
85+
<actionGroup ref="AssertStorefrontAttributeOptionPresentInLayeredNavigationActionGroup" stepKey="assertThirdAttributeOptionPresence">
86+
<argument name="attributeLabel" value="$createMultiSelectProductAttribute.attribute[frontend_labels][0][label]$"/>
87+
<argument name="attributeOptionLabel" value="$addThirdOptionToAttribute.option[store_labels][0][label]$"/>
88+
<argument name="attributeOptionPosition" value="2"/>
89+
</actionGroup>
90+
</test>
91+
</tests>

app/code/Magento/Catalog/view/frontend/layout/default.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
<item name="updateRequestConfig" xsi:type="array">
2727
<item name="url" xsi:type="serviceUrl" path="/products-render-info"/>
2828
</item>
29+
<item name="requestConfig" xsi:type="array">
30+
<item name="syncUrl" xsi:type="url" path="catalog/product/frontend_action_synchronize"/>
31+
</item>
2932
</item>
3033
</argument>
3134
</arguments>

app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,8 @@ public function addFieldToFilter($field, $condition = null)
385385
public function clear()
386386
{
387387
$this->searchResult = null;
388+
$this->setFlag('has_category_filter', false);
389+
388390
return parent::clear();
389391
}
390392

@@ -394,6 +396,8 @@ public function clear()
394396
protected function _reset()
395397
{
396398
$this->searchResult = null;
399+
$this->setFlag('has_category_filter', false);
400+
397401
return parent::_reset();
398402
}
399403

@@ -423,7 +427,11 @@ public function _loadEntities($printQuery = false, $logQuery = false)
423427
throw $e;
424428
}
425429

430+
$position = 0;
426431
foreach ($rows as $value) {
432+
if ($this->getFlag('has_category_filter')) {
433+
$value['cat_index_position'] = $position++;
434+
}
427435
$object = $this->getNewEmptyItem()->setData($value);
428436
$this->addItem($object);
429437
if (isset($this->_itemsById[$object->getId()])) {
@@ -432,6 +440,9 @@ public function _loadEntities($printQuery = false, $logQuery = false)
432440
$this->_itemsById[$object->getId()] = [$object];
433441
}
434442
}
443+
if ($this->getFlag('has_category_filter')) {
444+
$this->setFlag('has_category_filter', false);
445+
}
435446

436447
return $this;
437448
}
@@ -669,6 +680,7 @@ public function addCategoryFilter(\Magento\Catalog\Model\Category $category)
669680
if ($this->defaultFilterStrategyApplyChecker->isApplicable()) {
670681
parent::addCategoryFilter($category);
671682
} else {
683+
$this->setFlag('has_category_filter', true);
672684
$this->_productLimitationPrice();
673685
}
674686

app/code/Magento/Theme/view/adminhtml/page_layout/admin-2columns-left.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
</container>
3232
<container name="page.main.container" as="page_main_container" htmlId="page:main-container" htmlTag="div" htmlClass="page-columns">
3333
<container name="main.col" as="main-col" htmlId="container" htmlTag="div" htmlClass="main-col">
34-
<container name="admin.scope.col.wrap" as="admin-scope-col-wrap" htmlTag="div" htmlClass="form-inline"> <!-- ToDo UI: remove this wrapper remove with old styles removal -->
34+
<container name="admin.scope.col.wrap" as="admin-scope-col-wrap" htmlTag="div" htmlClass="admin__scope-old"> <!-- ToDo UI: remove this wrapper remove with old styles removal -->
3535
<container name="content" as="content"/>
3636
</container>
3737
</container>

0 commit comments

Comments
 (0)