Skip to content

Commit 4177435

Browse files
authored
Merge branch '2.4-develop' into 2.4-develop-fast-lane-prs
2 parents df7082a + 0d67512 commit 4177435

File tree

137 files changed

+3091
-507
lines changed

Some content is hidden

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

137 files changed

+3091
-507
lines changed

app/code/Magento/AsynchronousOperations/Model/BulkManagement.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,18 @@ public function __construct(
104104
*/
105105
public function scheduleBulk($bulkUuid, array $operations, $description, $userId = null)
106106
{
107-
$metadata = $this->metadataPool->getMetadata(BulkSummaryInterface::class);
108-
$connection = $this->resourceConnection->getConnectionByName($metadata->getEntityConnectionName());
109-
// save bulk summary and related operations
110-
$connection->beginTransaction();
111107
$userType = $this->userContext->getUserType();
112108
if ($userType === null) {
113109
$userType = UserContextInterface::USER_TYPE_ADMIN;
114110
}
111+
if ($userId === null && $userType === UserContextInterface::USER_TYPE_ADMIN) {
112+
$userId = $this->userContext->getUserId();
113+
}
114+
115+
$metadata = $this->metadataPool->getMetadata(BulkSummaryInterface::class);
116+
$connection = $this->resourceConnection->getConnectionByName($metadata->getEntityConnectionName());
117+
// save bulk summary and related operations
118+
$connection->beginTransaction();
115119
try {
116120
/** @var BulkSummaryInterface $bulkSummary */
117121
$bulkSummary = $this->bulkSummaryFactory->create();

app/code/Magento/Backend/view/adminhtml/web/js/dashboard/chart.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* See COPYING.txt for license details.
44
*/
55

6-
/*global define*/
76
/*global FORM_KEY*/
87
define([
98
'jquery',

app/code/Magento/Backend/view/adminhtml/web/js/dashboard/totals.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* See COPYING.txt for license details.
44
*/
55

6-
/*global define*/
76
/*global FORM_KEY*/
87
define([
98
'jquery',

app/code/Magento/Bundle/view/adminhtml/web/js/bundle-product.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
/*global FORM_KEY*/
77
/*global bSelection*/
8-
/*global $H*/
98
/**
109
* @api
1110
*/
@@ -186,7 +185,9 @@ define([
186185
});
187186
bSelection.gridRemoval.each(function (pair) {
188187
$optionBox.find('.col-sku').filter(function () {
189-
return $(this).text().trim() === pair.key; // find row by SKU
188+
let text = $(this).text();
189+
190+
return text.trim() === pair.key; // find row by SKU
190191
}).closest('tr').find('button.delete').trigger('click');
191192
});
192193
widget.refreshSortableElements();

app/code/Magento/Captcha/view/frontend/web/js/model/captcha.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* See COPYING.txt for license details.
44
*/
55

6-
/*global alert*/
76
define([
87
'jquery',
98
'ko',

app/code/Magento/Catalog/Model/Attribute/ScopeOverriddenValue.php

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
namespace Magento\Catalog\Model\Attribute;
88

9+
use Magento\Catalog\Model\AbstractModel;
10+
use Magento\Framework\DataObject;
911
use Magento\Framework\EntityManager\MetadataPool;
1012
use Magento\Eav\Api\AttributeRepositoryInterface as AttributeRepository;
1113
use Magento\Framework\Api\SearchCriteriaBuilder;
@@ -15,7 +17,6 @@
1517
use Magento\Framework\App\ResourceConnection;
1618

1719
/**
18-
* Class ScopeOverriddenValue
1920
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2021
*/
2122
class ScopeOverriddenValue
@@ -76,7 +77,7 @@ public function __construct(
7677
* Whether attribute value is overridden in specific store
7778
*
7879
* @param string $entityType
79-
* @param \Magento\Catalog\Model\AbstractModel $entity
80+
* @param AbstractModel $entity
8081
* @param string $attributeCode
8182
* @param int|string $storeId
8283
* @return bool
@@ -86,39 +87,41 @@ public function containsValue($entityType, $entity, $attributeCode, $storeId)
8687
if ((int)$storeId === Store::DEFAULT_STORE_ID) {
8788
return false;
8889
}
89-
if (!isset($this->attributesValues[$storeId])) {
90+
$values = $this->getAttributesValues($entityType, $entity);
91+
92+
if (!isset($values[$storeId])) {
9093
$this->initAttributeValues($entityType, $entity, (int)$storeId);
94+
$values = $this->getAttributesValues($entityType, $entity);
9195
}
9296

93-
return isset($this->attributesValues[$storeId])
94-
&& array_key_exists($attributeCode, $this->attributesValues[$storeId]);
97+
return isset($values[$storeId]) && array_key_exists($attributeCode, $values[$storeId]);
9598
}
9699

97100
/**
98101
* Get attribute default values
99102
*
100103
* @param string $entityType
101-
* @param \Magento\Catalog\Model\AbstractModel $entity
104+
* @param AbstractModel $entity
102105
* @return array
103106
*
104107
* @deprecated 101.0.0
105108
*/
106109
public function getDefaultValues($entityType, $entity)
107110
{
108-
if ($this->attributesValues === null) {
111+
$values = $this->getAttributesValues($entityType, $entity);
112+
if (!isset($values[Store::DEFAULT_STORE_ID])) {
109113
$this->initAttributeValues($entityType, $entity, (int)$entity->getStoreId());
114+
$values = $this->getAttributesValues($entityType, $entity);
110115
}
111116

112-
return isset($this->attributesValues[Store::DEFAULT_STORE_ID])
113-
? $this->attributesValues[Store::DEFAULT_STORE_ID]
114-
: [];
117+
return $values[Store::DEFAULT_STORE_ID] ?? [];
115118
}
116119

117120
/**
118121
* Init attribute values.
119122
*
120123
* @param string $entityType
121-
* @param \Magento\Catalog\Model\AbstractModel $entity
124+
* @param AbstractModel $entity
122125
* @param int $storeId
123126
* @throws \Magento\Framework\Exception\LocalizedException
124127
* @return void
@@ -129,6 +132,7 @@ private function initAttributeValues($entityType, $entity, $storeId)
129132
/** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */
130133
$attributeTables = [];
131134
if ($metadata->getEavEntityType()) {
135+
$entityId = $entity->getData($metadata->getLinkField());
132136
foreach ($this->getAttributes($entityType) as $attribute) {
133137
if (!$attribute->isStatic()) {
134138
$attributeTables[$attribute->getBackend()->getTable()][] = $attribute->getAttributeId();
@@ -147,7 +151,7 @@ private function initAttributeValues($entityType, $entity, $storeId)
147151
'a.attribute_id = t.attribute_id',
148152
['attribute_code' => 'a.attribute_code']
149153
)
150-
->where($metadata->getLinkField() . ' = ?', $entity->getData($metadata->getLinkField()))
154+
->where($metadata->getLinkField() . ' = ?', $entityId)
151155
->where('t.attribute_id IN (?)', $attributeCodes)
152156
->where('t.store_id IN (?)', $storeIds);
153157
$selects[] = $select;
@@ -158,9 +162,12 @@ private function initAttributeValues($entityType, $entity, $storeId)
158162
\Magento\Framework\DB\Select::SQL_UNION_ALL
159163
);
160164
$attributes = $metadata->getEntityConnection()->fetchAll((string)$unionSelect);
165+
$values = array_fill_keys($storeIds, []);
161166
foreach ($attributes as $attribute) {
162-
$this->attributesValues[$attribute['store_id']][$attribute['attribute_code']] = $attribute['value'];
167+
$values[$attribute['store_id']][$attribute['attribute_code']] = $attribute['value'];
163168
}
169+
$values += $this->getAttributesValues($entityType, $entity);
170+
$this->setAttributesValues($entityType, $entity, $values);
164171
}
165172
}
166173

@@ -187,4 +194,52 @@ private function getAttributes($entityType)
187194
);
188195
return $searchResult->getItems();
189196
}
197+
198+
/**
199+
* Clear entity attributes values cache
200+
*
201+
* @param string $entityType
202+
* @param DataObject $entity
203+
* @return void
204+
* @throws \Exception
205+
*/
206+
public function clearAttributesValues(string $entityType, DataObject $entity): void
207+
{
208+
if (isset($this->attributesValues[$entityType])) {
209+
$metadata = $this->metadataPool->getMetadata($entityType);
210+
$entityId = $entity->getData($metadata->getLinkField());
211+
unset($this->attributesValues[$entityType][$entityId]);
212+
}
213+
}
214+
215+
/**
216+
* Get entity attributes values from cache
217+
*
218+
* @param string $entityType
219+
* @param DataObject $entity
220+
* @return array
221+
* @throws \Exception
222+
*/
223+
private function getAttributesValues(string $entityType, DataObject $entity): array
224+
{
225+
$metadata = $this->metadataPool->getMetadata($entityType);
226+
$entityId = $entity->getData($metadata->getLinkField());
227+
return $this->attributesValues[$entityType][$entityId] ?? [];
228+
}
229+
230+
/**
231+
* Set entity attributes values into cache
232+
*
233+
* @param string $entityType
234+
* @param DataObject $entity
235+
* @param array $values
236+
* @return void
237+
* @throws \Exception
238+
*/
239+
private function setAttributesValues(string $entityType, DataObject $entity, array $values): void
240+
{
241+
$metadata = $this->metadataPool->getMetadata($entityType);
242+
$entityId = $entity->getData($metadata->getLinkField());
243+
$this->attributesValues[$entityType][$entityId] = $values;
244+
}
190245
}

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Catalog\Model\ResourceModel;
77

8+
use Magento\Catalog\Api\Data\ProductInterface;
9+
use Magento\Catalog\Model\Attribute\ScopeOverriddenValue;
810
use Magento\Catalog\Model\ResourceModel\Product\Website\Link as ProductWebsiteLink;
911
use Magento\Eav\Api\AttributeManagementInterface;
1012
use Magento\Framework\App\ObjectManager;
@@ -40,15 +42,11 @@ class Product extends AbstractResource
4042
protected $_productCategoryTable;
4143

4244
/**
43-
* Catalog category
44-
*
4545
* @var Category
4646
*/
4747
protected $_catalogCategory;
4848

4949
/**
50-
* Category collection factory
51-
*
5250
* @var Category\CollectionFactory
5351
*/
5452
protected $_categoryCollectionFactory;
@@ -105,6 +103,11 @@ class Product extends AbstractResource
105103
*/
106104
private $mediaImageDeleteProcessor;
107105

106+
/**
107+
* @var ScopeOverriddenValue
108+
*/
109+
private $scopeOverriddenValue;
110+
108111
/**
109112
* @param \Magento\Eav\Model\Entity\Context $context
110113
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -120,6 +123,7 @@ class Product extends AbstractResource
120123
* @param UniqueValidationInterface|null $uniqueValidator
121124
* @param AttributeManagementInterface|null $eavAttributeManagement
122125
* @param MediaImageDeleteProcessor|null $mediaImageDeleteProcessor
126+
* @param ScopeOverriddenValue|null $scopeOverriddenValue
123127
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
124128
*/
125129
public function __construct(
@@ -136,7 +140,8 @@ public function __construct(
136140
TableMaintainer $tableMaintainer = null,
137141
UniqueValidationInterface $uniqueValidator = null,
138142
AttributeManagementInterface $eavAttributeManagement = null,
139-
?MediaImageDeleteProcessor $mediaImageDeleteProcessor = null
143+
?MediaImageDeleteProcessor $mediaImageDeleteProcessor = null,
144+
?ScopeOverriddenValue $scopeOverriddenValue = null
140145
) {
141146
$this->_categoryCollectionFactory = $categoryCollectionFactory;
142147
$this->_catalogCategory = $catalogCategory;
@@ -157,6 +162,8 @@ public function __construct(
157162
?? ObjectManager::getInstance()->get(AttributeManagementInterface::class);
158163
$this->mediaImageDeleteProcessor = $mediaImageDeleteProcessor
159164
?? ObjectManager::getInstance()->get(MediaImageDeleteProcessor::class);
165+
$this->scopeOverriddenValue = $scopeOverriddenValue
166+
?? ObjectManager::getInstance()->get(ScopeOverriddenValue::class);
160167
}
161168

162169
/**
@@ -316,6 +323,7 @@ protected function _afterSave(DataObject $product)
316323
{
317324
$this->removeNotInSetAttributeValues($product);
318325
$this->_saveWebsiteIds($product)->_saveCategories($product);
326+
$this->scopeOverriddenValue->clearAttributesValues(ProductInterface::class, $product);
319327
return parent::_afterSave($product);
320328
}
321329

app/code/Magento/Catalog/Pricing/Price/TierPrice.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class TierPrice extends AbstractPrice implements TierPriceInterface, BasePricePr
3333
/**
3434
* Price type tier
3535
*/
36-
const PRICE_CODE = 'tier_price';
36+
public const PRICE_CODE = 'tier_price';
3737

3838
/**
3939
* @var Session
@@ -176,10 +176,13 @@ public function getTierPriceList()
176176
function (&$priceData) {
177177
/* convert string value to float */
178178
$priceData['price_qty'] *= 1;
179-
if ($this->getConfigTaxDisplayType() === Config::DISPLAY_TYPE_BOTH) {
180-
$exclTaxPrice = $this->calculator->getAmount($priceData['price'], $this->product);
179+
$exclTaxPrice = $this->calculator->getAmount($priceData['price'], $this->product);
180+
if ($this->getConfigTaxDisplayType() === Config::DISPLAY_TYPE_EXCLUDING_TAX) {
181181
$priceData['excl_tax_price'] = $exclTaxPrice;
182182
}
183+
if ($this->getConfigTaxDisplayType() === Config::DISPLAY_TYPE_BOTH) {
184+
$priceData['incl_excl_tax_price'] = $exclTaxPrice;
185+
}
183186
$priceData['price'] = $this->applyAdjustment($priceData['price']);
184187
}
185188
);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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\Fixture;
9+
10+
use Magento\Framework\DataObject;
11+
12+
class MultiselectAttribute extends SelectAttribute
13+
{
14+
private const DEFAULT_DATA = [
15+
'frontend_input' => 'multiselect',
16+
];
17+
18+
/**
19+
* @inheritdoc
20+
*/
21+
public function apply(array $data = []): ?DataObject
22+
{
23+
$data = $this->prepareData($data);
24+
25+
return parent::apply($data);
26+
}
27+
28+
/**
29+
* Prepare attribute data
30+
*
31+
* @param array $data
32+
* @return array
33+
*/
34+
private function prepareData(array $data): array
35+
{
36+
$data = array_merge(self::DEFAULT_DATA, $data);
37+
38+
return $data;
39+
}
40+
}

0 commit comments

Comments
 (0)