Skip to content

Commit bec9025

Browse files
authored
Merge pull request #4998 from magento-tsg-csl3/2.3-develop-pr36
[TSG-CSL3] For 2.3 (pr36)
2 parents 0c39cdb + 070abe4 commit bec9025

File tree

19 files changed

+472
-31
lines changed

19 files changed

+472
-31
lines changed

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

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
namespace Magento\Catalog\Model\ResourceModel;
77

88
use Magento\Catalog\Model\ResourceModel\Product\Website\Link as ProductWebsiteLink;
9+
use Magento\Eav\Api\AttributeManagementInterface;
910
use Magento\Framework\App\ObjectManager;
1011
use Magento\Catalog\Model\Indexer\Category\Product\TableMaintainer;
1112
use Magento\Catalog\Model\Product as ProductEntity;
1213
use Magento\Eav\Model\Entity\Attribute\UniqueValidationInterface;
14+
use Magento\Framework\DataObject;
1315
use Magento\Framework\EntityManager\EntityManager;
1416
use Magento\Framework\Model\AbstractModel;
1517

@@ -93,6 +95,11 @@ class Product extends AbstractResource
9395
*/
9496
private $tableMaintainer;
9597

98+
/**
99+
* @var AttributeManagementInterface
100+
*/
101+
private $eavAttributeManagement;
102+
96103
/**
97104
* @param \Magento\Eav\Model\Entity\Context $context
98105
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -106,7 +113,7 @@ class Product extends AbstractResource
106113
* @param array $data
107114
* @param TableMaintainer|null $tableMaintainer
108115
* @param UniqueValidationInterface|null $uniqueValidator
109-
*
116+
* @param AttributeManagementInterface|null $eavAttributeManagement
110117
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
111118
*/
112119
public function __construct(
@@ -121,7 +128,8 @@ public function __construct(
121128
\Magento\Catalog\Model\Product\Attribute\DefaultAttributes $defaultAttributes,
122129
$data = [],
123130
TableMaintainer $tableMaintainer = null,
124-
UniqueValidationInterface $uniqueValidator = null
131+
UniqueValidationInterface $uniqueValidator = null,
132+
AttributeManagementInterface $eavAttributeManagement = null
125133
) {
126134
$this->_categoryCollectionFactory = $categoryCollectionFactory;
127135
$this->_catalogCategory = $catalogCategory;
@@ -138,6 +146,8 @@ public function __construct(
138146
);
139147
$this->connectionName = 'catalog';
140148
$this->tableMaintainer = $tableMaintainer ?: ObjectManager::getInstance()->get(TableMaintainer::class);
149+
$this->eavAttributeManagement = $eavAttributeManagement
150+
?? ObjectManager::getInstance()->get(AttributeManagementInterface::class);
141151
}
142152

143153
/**
@@ -268,10 +278,10 @@ public function getIdBySku($sku)
268278
/**
269279
* Process product data before save
270280
*
271-
* @param \Magento\Framework\DataObject $object
281+
* @param DataObject $object
272282
* @return $this
273283
*/
274-
protected function _beforeSave(\Magento\Framework\DataObject $object)
284+
protected function _beforeSave(DataObject $object)
275285
{
276286
$self = parent::_beforeSave($object);
277287
/**
@@ -286,15 +296,73 @@ protected function _beforeSave(\Magento\Framework\DataObject $object)
286296
/**
287297
* Save data related with product
288298
*
289-
* @param \Magento\Framework\DataObject $product
299+
* @param DataObject $product
290300
* @return $this
291301
*/
292-
protected function _afterSave(\Magento\Framework\DataObject $product)
302+
protected function _afterSave(DataObject $product)
293303
{
304+
$this->removeNotInSetAttributeValues($product);
294305
$this->_saveWebsiteIds($product)->_saveCategories($product);
295306
return parent::_afterSave($product);
296307
}
297308

309+
/**
310+
* Remove attribute values that absent in product attribute set
311+
*
312+
* @param DataObject $product
313+
* @return DataObject
314+
*/
315+
private function removeNotInSetAttributeValues(DataObject $product): DataObject
316+
{
317+
$oldAttributeSetId = $product->getOrigData(ProductEntity::ATTRIBUTE_SET_ID);
318+
if ($oldAttributeSetId && $product->dataHasChangedFor(ProductEntity::ATTRIBUTE_SET_ID)) {
319+
$newAttributes = $product->getAttributes();
320+
$newAttributesCodes = array_keys($newAttributes);
321+
$oldAttributes = $this->eavAttributeManagement->getAttributes(
322+
ProductEntity::ENTITY,
323+
$oldAttributeSetId
324+
);
325+
$oldAttributesCodes = [];
326+
foreach ($oldAttributes as $oldAttribute) {
327+
$oldAttributesCodes[] = $oldAttribute->getAttributecode();
328+
}
329+
$notInSetAttributeCodes = array_diff($oldAttributesCodes, $newAttributesCodes);
330+
if (!empty($notInSetAttributeCodes)) {
331+
$this->deleteSelectedEntityAttributeRows($product, $notInSetAttributeCodes);
332+
}
333+
}
334+
335+
return $product;
336+
}
337+
338+
/**
339+
* Clear selected entity attribute rows
340+
*
341+
* @param DataObject $product
342+
* @param array $attributeCodes
343+
* @return void
344+
*/
345+
private function deleteSelectedEntityAttributeRows(DataObject $product, array $attributeCodes): void
346+
{
347+
$backendTables = [];
348+
foreach ($attributeCodes as $attributeCode) {
349+
$attribute = $this->getAttribute($attributeCode);
350+
$backendTable = $attribute->getBackendTable();
351+
if (!$attribute->isStatic() && $backendTable) {
352+
$backendTables[$backendTable][] = $attribute->getId();
353+
}
354+
}
355+
356+
$entityIdField = $this->getLinkField();
357+
$entityId = $product->getData($entityIdField);
358+
foreach ($backendTables as $backendTable => $attributes) {
359+
$connection = $this->getConnection();
360+
$where = $connection->quoteInto('attribute_id IN (?)', $attributes);
361+
$where .= $connection->quoteInto(" AND {$entityIdField} = ?", $entityId);
362+
$connection->delete($backendTable, $where);
363+
}
364+
}
365+
298366
/**
299367
* @inheritdoc
300368
*/
@@ -337,12 +405,12 @@ protected function _saveWebsiteIds($product)
337405
/**
338406
* Save product category relations
339407
*
340-
* @param \Magento\Framework\DataObject $object
408+
* @param DataObject $object
341409
* @return $this
342410
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
343411
* @deprecated 101.1.0
344412
*/
345-
protected function _saveCategories(\Magento\Framework\DataObject $object)
413+
protected function _saveCategories(DataObject $object)
346414
{
347415
return $this;
348416
}

app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ private function limitShippingCarrier(Quote $quote) : void
193193
$shippingAddress = $quote->getShippingAddress();
194194
if ($shippingAddress && $shippingAddress->getShippingMethod()) {
195195
$shippingRate = $shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod());
196-
$shippingAddress->setLimitCarrier($shippingRate->getCarrier());
196+
if ($shippingRate) {
197+
$shippingAddress->setLimitCarrier($shippingRate->getCarrier());
198+
}
197199
}
198200
}
199201
}

app/code/Magento/Checkout/Model/PaymentInformationManagement.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ public function savePaymentInformation(
124124
$shippingAddress = $quote->getShippingAddress();
125125
if ($shippingAddress && $shippingAddress->getShippingMethod()) {
126126
$shippingRate = $shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod());
127-
$shippingAddress->setLimitCarrier(
128-
$shippingRate ? $shippingRate->getCarrier() : $shippingAddress->getShippingMethod()
129-
);
127+
if ($shippingRate) {
128+
$shippingAddress->setLimitCarrier($shippingRate->getCarrier());
129+
}
130130
}
131131
}
132132
$this->paymentMethodManagement->set($cartId, $paymentMethod);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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="AssertStorefrontNotCalculatedValueInShippingTotalInOrderSummaryActionGroup">
12+
<annotations>
13+
<description>Validates value of the Shipping total is not calculated.</description>
14+
</annotations>
15+
16+
<arguments>
17+
<argument name="value" defaultValue="Not yet calculated" type="string"/>
18+
</arguments>
19+
<waitForElementVisible selector="{{CheckoutOrderSummarySection.shippingTotalNotYetCalculated}}" time="30" stepKey="waitForShippingTotalToBeVisible"/>
20+
<see selector="{{CheckoutOrderSummarySection.shippingTotalNotYetCalculated}}" userInput="{{value}}" stepKey="assertShippingTotalIsNotYetCalculated"/>
21+
</actionGroup>
22+
</actionGroups>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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="AssertStorefrontOrderCannotBePlacedActionGroup">
12+
<annotations>
13+
<description>Validates order cannot be placed and checks error message.</description>
14+
</annotations>
15+
16+
<arguments>
17+
<argument name="error" type="string"/>
18+
</arguments>
19+
<waitForElement selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/>
20+
<click selector="{{CheckoutPaymentSection.placeOrderWithoutTimeout}}" stepKey="clickPlaceOrder"/>
21+
<waitForElement selector="{{CheckoutCartMessageSection.errorMessage}}" time="30" stepKey="waitForErrorMessage"/>
22+
<see selector="{{CheckoutCartMessageSection.errorMessage}}" userInput="{{error}}" stepKey="assertErrorMessage"/>
23+
</actionGroup>
24+
</actionGroups>

app/code/Magento/Checkout/Test/Mftf/Section/CheckoutOrderSummarySection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@
2020
<element name="miniCartTabClosed" type="button" selector=".title[aria-expanded='false']" timeout="30"/>
2121
<element name="itemsQtyInCart" type="text" selector=".items-in-cart > .title > strong > span"/>
2222
<element name="orderSummaryShippingTotalLabelDescription" type="text" selector=".shipping.totals .label.description"/>
23+
<element name="shippingTotalNotYetCalculated" type="text" selector=".shipping.totals .not-calculated"/>
2324
</section>
2425
</sections>

app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<element name="cartItemsAreaActive" type="textarea" selector="div.block.items-in-cart.active" timeout="30"/>
3232
<element name="checkMoneyOrderPayment" type="radio" selector="input#checkmo.radio" timeout="30"/>
3333
<element name="placeOrder" type="button" selector=".payment-method._active button.action.primary.checkout" timeout="30"/>
34+
<element name="placeOrderWithoutTimeout" type="button" selector=".payment-method._active button.action.primary.checkout"/>
3435
<element name="paymentSectionTitle" type="text" selector="//*[@id='checkout-payment-method-load']//div[@data-role='title']" />
3536
<element name="orderSummarySubtotal" type="text" selector="//tr[@class='totals sub']//span[@class='price']" />
3637
<element name="orderSummaryShippingTotal" type="text" selector="//tr[@class='totals shipping excl']//span[@class='price']" />

0 commit comments

Comments
 (0)