Skip to content

Commit ae108ab

Browse files
committed
Merge remote-tracking branch 'remotes/github/2.3-develop' into MC-17251
2 parents 170425c + 6f03dd3 commit ae108ab

File tree

120 files changed

+2772
-718
lines changed

Some content is hidden

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

120 files changed

+2772
-718
lines changed
Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,30 @@
1-
# Admin Notification
1+
# Magento_AdminNotification module
22

3-
**Admin Notification** provides the ability to alert administrators via
4-
system messages and provides a message inbox for surveys and notifications.
3+
The Magento_AdminNotification module provides the ability to alert administrators via system messages and provides a message inbox for surveys and notifications.
4+
5+
## Installation details
6+
7+
Before disabling or uninstalling this module, note that the Magento_Indexer module depends on this module.
8+
9+
For information about module installation in Magento 2, see [Enable or disable modules](https://devdocs.magento.com/guides/v2.3/install-gde/install/cli/install-cli-subcommands-enable.html).
10+
11+
### Events
12+
13+
This module observes the following events:
14+
15+
- `controller_action_predispatch` event in `Magento\AdminNotification\Observer\PredispatchAdminActionControllerObserver`
16+
17+
### Layouts
18+
19+
This module introduces the following layouts and layout handles in the `view/adminhtml/layout` directory:
20+
21+
- `adminhtml_notification_index`
22+
- `adminhtml_notification_block`
23+
24+
For more information about layouts in Magento 2, see the [Layout documentation](https://devdocs.magento.com/guides/v2.3/frontend-dev-guide/layouts/layout-overview.html).
25+
26+
### UI components
27+
28+
You can extend admin notifications using the `view/adminhtml/ui_component/notification_area.xml` configuration file.
29+
30+
For information about UI components in Magento 2, see [Overview of UI components](https://devdocs.magento.com/guides/v2.3/ui_comp_guide/bk-ui_comps.html).
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
The Magento_AdvancedPricingImportExport module handles the import and export of the advanced pricing.
1+
# Magento_AdvancedPricingImportExport module
2+
3+
The Magento_AdvancedPricingImportExport module handles the import and export of the advanced pricing.
4+

app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ $numColumns = $block->getColumns() !== null ? count($block->getColumns()) : 0;
2323
<?php if ($block->canDisplayContainer()) : ?>
2424
<div id="<?= $block->escapeHtml($block->getId()) ?>" data-grid-id="<?= $block->escapeHtml($block->getId()) ?>">
2525
<?php else : ?>
26-
<?= $block->getLayout()->getMessagesBlock()->getGroupedHtml() ?>
26+
<?= $block->getLayout()->getMessagesBlock()->getGroupedHtml() ?>
2727
<?php endif; ?>
2828

2929
<div class="admin__data-grid-header admin__data-grid-toolbar">

app/code/Magento/Bundle/Model/ResourceModel/Option/Collection.php

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

8+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
9+
810
/**
911
* Bundle Options Resource Collection
1012
* @api
@@ -138,12 +140,10 @@ public function setPositionOrder()
138140

139141
/**
140142
* Append selection to options
141-
* stripBefore - indicates to reload
142-
* appendAll - indicates do we need to filter by saleable and required custom options
143143
*
144144
* @param \Magento\Bundle\Model\ResourceModel\Selection\Collection $selectionsCollection
145-
* @param bool $stripBefore
146-
* @param bool $appendAll
145+
* @param bool $stripBefore indicates to reload
146+
* @param bool $appendAll indicates do we need to filter by saleable and required custom options
147147
* @return \Magento\Framework\DataObject[]
148148
*/
149149
public function appendSelections($selectionsCollection, $stripBefore = false, $appendAll = true)
@@ -156,7 +156,9 @@ public function appendSelections($selectionsCollection, $stripBefore = false, $a
156156
foreach ($selectionsCollection->getItems() as $key => $selection) {
157157
$option = $this->getItemById($selection->getOptionId());
158158
if ($option) {
159-
if ($appendAll || $selection->isSalable() && !$selection->getRequiredOptions()) {
159+
if ($appendAll ||
160+
((int) $selection->getStatus()) === Status::STATUS_ENABLED && !$selection->getRequiredOptions()
161+
) {
160162
$selection->setOption($option);
161163
$option->addSelection($selection);
162164
} else {

app/code/Magento/Catalog/Model/Product/Attribute/OptionManagement.php

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,6 @@ public function getItems($attributeCode)
4343
*/
4444
public function add($attributeCode, $option)
4545
{
46-
/** @var \Magento\Eav\Api\Data\AttributeOptionInterface[] $currentOptions */
47-
$currentOptions = $this->getItems($attributeCode);
48-
if (is_array($currentOptions)) {
49-
array_walk($currentOptions, function (&$attributeOption) {
50-
/** @var \Magento\Eav\Api\Data\AttributeOptionInterface $attributeOption */
51-
$attributeOption = $attributeOption->getLabel();
52-
});
53-
if (in_array($option->getLabel(), $currentOptions, true)) {
54-
return false;
55-
}
56-
}
5746
return $this->eavOptionManagement->add(
5847
\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE,
5948
$attributeCode,

app/code/Magento/Catalog/Model/ProductAttributeGroupRepository.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
* Copyright © Magento, Inc. All rights reserved.
55
* See COPYING.txt for license details.
66
*/
7+
declare(strict_types=1);
78

89
namespace Magento\Catalog\Model;
910

1011
use Magento\Framework\Exception\NoSuchEntityException;
1112
use Magento\Framework\Exception\StateException;
1213

14+
/**
15+
* Class \Magento\Catalog\Model\ProductAttributeGroupRepository
16+
*/
1317
class ProductAttributeGroupRepository implements \Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface
1418
{
1519
/**
@@ -43,23 +47,29 @@ public function __construct(
4347
}
4448

4549
/**
46-
* {@inheritdoc}
50+
* @inheritdoc
4751
*/
4852
public function save(\Magento\Eav\Api\Data\AttributeGroupInterface $group)
4953
{
54+
/** @var \Magento\Catalog\Model\Product\Attribute\Group $group */
55+
$extensionAttributes = $group->getExtensionAttributes();
56+
if ($extensionAttributes) {
57+
$group->setSortOrder($extensionAttributes->getSortOrder());
58+
$group->setAttributeGroupCode($extensionAttributes->getAttributeGroupCode());
59+
}
5060
return $this->groupRepository->save($group);
5161
}
5262

5363
/**
54-
* {@inheritdoc}
64+
* @inheritdoc
5565
*/
5666
public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
5767
{
5868
return $this->groupRepository->getList($searchCriteria);
5969
}
6070

6171
/**
62-
* {@inheritdoc}
72+
* @inheritdoc
6373
*/
6474
public function get($groupId)
6575
{
@@ -75,7 +85,7 @@ public function get($groupId)
7585
}
7686

7787
/**
78-
* {@inheritdoc}
88+
* @inheritdoc
7989
*/
8090
public function deleteById($groupId)
8191
{
@@ -86,7 +96,7 @@ public function deleteById($groupId)
8696
}
8797

8898
/**
89-
* {@inheritdoc}
99+
* @inheritdoc
90100
*/
91101
public function delete(\Magento\Eav\Api\Data\AttributeGroupInterface $group)
92102
{

app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ switch ($type = $block->getType()) {
170170
<?php if ($type == 'related' && $canItemsAddToCart) :?>
171171
<div class="block-actions">
172172
<?= $block->escapeHtml(__('Check items to add to the cart or')) ?>
173-
<button type="button" class="action select" role="button"><span><?= $block->escapeHtml(__('select all')) ?></span></button>
173+
<button type="button" class="action select" data-role="select-all"><span><?= $block->escapeHtml(__('select all')) ?></span></button>
174174
</div>
175175
<?php endif; ?>
176176
<div class="products wrapper grid products-grid products-<?= $block->escapeHtmlAttr($type) ?>">

app/code/Magento/Catalog/view/frontend/web/js/related-products.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ define([
1717
relatedProductsField: '#related-products-field', // Hidden input field that stores related products.
1818
selectAllMessage: $.mage.__('select all'),
1919
unselectAllMessage: $.mage.__('unselect all'),
20-
selectAllLink: '[role="button"]',
20+
selectAllLink: '[data-role="select-all"]',
2121
elementsSelector: '.item.product'
2222
},
2323

app/code/Magento/CatalogImportExport/Model/Import/Product/MediaGalleryProcessor.php

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,42 @@ private function initMediaGalleryResources()
284284
}
285285
}
286286

287+
/**
288+
* Get the last media position for each product from the given list
289+
*
290+
* @param int $storeId
291+
* @param array $productIds
292+
* @return array
293+
*/
294+
private function getLastMediaPositionPerProduct(int $storeId, array $productIds): array
295+
{
296+
$result = [];
297+
if ($productIds) {
298+
$productKeyName = $this->getProductEntityLinkField();
299+
// this result could be achieved by using GROUP BY. But there is no index on position column, therefore
300+
// it can be slower than the implementation below
301+
$positions = $this->connection->fetchAll(
302+
$this->connection
303+
->select()
304+
->from($this->mediaGalleryValueTableName, [$productKeyName, 'position'])
305+
->where("$productKeyName IN (?)", $productIds)
306+
->where('value_id is not null')
307+
->where('store_id = ?', $storeId)
308+
);
309+
// Make sure the result contains all product ids even if the product has no media files
310+
$result = array_fill_keys($productIds, 0);
311+
// Find the largest position for each product
312+
foreach ($positions as $record) {
313+
$productId = $record[$productKeyName];
314+
$result[$productId] = $result[$productId] < $record['position']
315+
? $record['position']
316+
: $result[$productId];
317+
}
318+
}
319+
320+
return $result;
321+
}
322+
287323
/**
288324
* Save media gallery data per store.
289325
*
@@ -301,24 +337,30 @@ private function processMediaPerStore(
301337
) {
302338
$multiInsertData = [];
303339
$dataForSkinnyTable = [];
340+
$lastMediaPositionPerProduct = $this->getLastMediaPositionPerProduct(
341+
$storeId,
342+
array_unique(array_merge(...array_values($valueToProductId)))
343+
);
344+
304345
foreach ($mediaGalleryData as $mediaGalleryRows) {
305346
foreach ($mediaGalleryRows as $insertValue) {
306-
foreach ($newMediaValues as $value_id => $values) {
347+
foreach ($newMediaValues as $valueId => $values) {
307348
if ($values['value'] == $insertValue['value']) {
308-
$insertValue['value_id'] = $value_id;
349+
$insertValue['value_id'] = $valueId;
309350
$insertValue[$this->getProductEntityLinkField()]
310351
= array_shift($valueToProductId[$values['value']]);
311-
unset($newMediaValues[$value_id]);
352+
unset($newMediaValues[$valueId]);
312353
break;
313354
}
314355
}
315356
if (isset($insertValue['value_id'])) {
357+
$productId = $insertValue[$this->getProductEntityLinkField()];
316358
$valueArr = [
317359
'value_id' => $insertValue['value_id'],
318360
'store_id' => $storeId,
319-
$this->getProductEntityLinkField() => $insertValue[$this->getProductEntityLinkField()],
361+
$this->getProductEntityLinkField() => $productId,
320362
'label' => $insertValue['label'],
321-
'position' => $insertValue['position'],
363+
'position' => $lastMediaPositionPerProduct[$productId] + $insertValue['position'],
322364
'disabled' => $insertValue['disabled'],
323365
];
324366
$multiInsertData[] = $valueArr;

app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\CatalogSearch\Model\Layer\Filter;
79

810
use Magento\Catalog\Model\Layer\Filter\AbstractFilter;
@@ -62,6 +64,9 @@ public function apply(\Magento\Framework\App\RequestInterface $request)
6264
->getProductCollection();
6365
$productCollection->addFieldToFilter($attribute->getAttributeCode(), $attributeValue);
6466
$label = $this->getOptionText($attributeValue);
67+
if (is_array($label)) {
68+
$label = implode(',', $label);
69+
}
6570
$this->getLayer()
6671
->getState()
6772
->addFilter($this->_createItem($label, $attributeValue));

0 commit comments

Comments
 (0)