Skip to content

Commit 24376e9

Browse files
author
Lysenko Olexandr
authored
Merge pull request #3146 from magento-tsg-csl3/2.3-develop-pr7
[TSG-CSL3] Upporting 2.3 (pr7)
2 parents b647e9e + 37de3f0 commit 24376e9

File tree

19 files changed

+375
-50
lines changed

19 files changed

+375
-50
lines changed

app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ class Bundle extends \Magento\Catalog\Block\Product\View\AbstractView
5656
*/
5757
private $catalogRuleProcessor;
5858

59+
/**
60+
* @var array
61+
*/
62+
private $optionsPosition = [];
63+
5964
/**
6065
* @param \Magento\Catalog\Block\Product\Context $context
6166
* @param \Magento\Framework\Stdlib\ArrayUtils $arrayUtils
@@ -86,6 +91,8 @@ public function __construct(
8691
}
8792

8893
/**
94+
* Return catalog rule processor or creates processor if it does not exist
95+
*
8996
* @deprecated 100.2.0
9097
* @return \Magento\CatalogRule\Model\ResourceModel\Product\CollectionProcessor
9198
*/
@@ -101,6 +108,7 @@ private function getCatalogRuleProcessor()
101108

102109
/**
103110
* Returns the bundle product options
111+
*
104112
* Will return cached options data if the product options are already initialized
105113
* In a case when $stripSelection parameter is true will reload stored bundle selections collection from DB
106114
*
@@ -135,6 +143,8 @@ public function getOptions($stripSelection = false)
135143
}
136144

137145
/**
146+
* Return true if product has options
147+
*
138148
* @return bool
139149
*/
140150
public function hasOptions()
@@ -150,7 +160,6 @@ public function hasOptions()
150160
* Returns JSON encoded config to be used in JS scripts
151161
*
152162
* @return string
153-
*
154163
*/
155164
public function getJsonConfig()
156165
{
@@ -172,6 +181,7 @@ public function getJsonConfig()
172181
}
173182
$optionId = $optionItem->getId();
174183
$options[$optionId] = $this->getOptionItemData($optionItem, $currentProduct, $position);
184+
$this->optionsPosition[$position] = $optionId;
175185

176186
// Add attribute default value (if set)
177187
if ($preConfiguredFlag) {
@@ -370,6 +380,7 @@ private function getConfigData(Product $product, array $options)
370380
$config = [
371381
'options' => $options,
372382
'selected' => $this->selectedOptions,
383+
'positions' => $this->optionsPosition,
373384
'bundleId' => $product->getId(),
374385
'priceFormat' => $this->localeFormat->getPriceFormat(),
375386
'prices' => [

app/code/Magento/Bundle/Test/Unit/Block/Catalog/Product/View/Type/BundleTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ public function testGetJsonConfigFixedPriceBundle()
280280
$this->assertEquals(110, $jsonConfig['prices']['oldPrice']['amount']);
281281
$this->assertEquals(100, $jsonConfig['prices']['basePrice']['amount']);
282282
$this->assertEquals(100, $jsonConfig['prices']['finalPrice']['amount']);
283+
$this->assertEquals([1], $jsonConfig['positions']);
283284
}
284285

285286
/**

app/code/Magento/Bundle/view/frontend/web/js/product-summary.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ define([
5656

5757
// Clear Summary box
5858
this.element.html('');
59-
60-
$.each(this.cache.currentElement.selected, $.proxy(this._renderOption, this));
59+
this.cache.currentElement.positions.forEach(function (optionId) {
60+
this._renderOption(optionId, this.cache.currentElement.selected[optionId]);
61+
}, this);
6162
this.element
6263
.parents(this.options.bundleSummaryContainer)
6364
.toggleClass('empty', !this.cache.currentElementCount); // Zero elements equal '.empty' container

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

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Product
5454
*/
5555
private $storeManager;
5656

57+
/**
58+
* @var \Magento\Framework\Escaper|null
59+
*/
60+
private $escaper;
61+
62+
/**
63+
* @var null|\Psr\Log\LoggerInterface
64+
*/
65+
private $logger;
66+
5767
/**
5868
* Save constructor.
5969
*
@@ -63,20 +73,26 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Product
6373
* @param \Magento\Catalog\Model\Product\Copier $productCopier
6474
* @param \Magento\Catalog\Model\Product\TypeTransitionManager $productTypeManager
6575
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
76+
* @param \Magento\Framework\Escaper|null $escaper
77+
* @param \Psr\Log\LoggerInterface|null $logger
6678
*/
6779
public function __construct(
6880
\Magento\Backend\App\Action\Context $context,
6981
Product\Builder $productBuilder,
7082
Initialization\Helper $initializationHelper,
7183
\Magento\Catalog\Model\Product\Copier $productCopier,
7284
\Magento\Catalog\Model\Product\TypeTransitionManager $productTypeManager,
73-
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository
85+
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
86+
\Magento\Framework\Escaper $escaper = null,
87+
\Psr\Log\LoggerInterface $logger = null
7488
) {
7589
$this->initializationHelper = $initializationHelper;
7690
$this->productCopier = $productCopier;
7791
$this->productTypeManager = $productTypeManager;
7892
$this->productRepository = $productRepository;
7993
parent::__construct($context, $productBuilder);
94+
$this->escaper = $escaper ?? $this->_objectManager->get(\Magento\Framework\Escaper::class);
95+
$this->logger = $logger ?? $this->_objectManager->get(\Psr\Log\LoggerInterface::class);
8096
}
8197

8298
/**
@@ -103,14 +119,14 @@ public function execute()
103119
$this->productBuilder->build($this->getRequest())
104120
);
105121
$this->productTypeManager->processProduct($product);
106-
107122
if (isset($data['product'][$product->getIdFieldName()])) {
108123
throw new \Magento\Framework\Exception\LocalizedException(
109124
__('The product was unable to be saved. Please try again.')
110125
);
111126
}
112127

113128
$originalSku = $product->getSku();
129+
$canSaveCustomOptions = $product->getCanSaveCustomOptions();
114130
$product->save();
115131
$this->handleImageRemoveError($data, $product->getId());
116132
$this->getCategoryLinkManagement()->assignProductToCategories(
@@ -120,20 +136,17 @@ public function execute()
120136
$productId = $product->getEntityId();
121137
$productAttributeSetId = $product->getAttributeSetId();
122138
$productTypeId = $product->getTypeId();
123-
124-
$this->copyToStores($data, $productId);
139+
$extendedData = $data;
140+
$extendedData['can_save_custom_options'] = $canSaveCustomOptions;
141+
$this->copyToStores($extendedData, $productId);
125142
$this->messageManager->addSuccessMessage(__('You saved the product.'));
126143
$this->getDataPersistor()->clear('catalog_product');
127144
if ($product->getSku() != $originalSku) {
128145
$this->messageManager->addNoticeMessage(
129146
__(
130147
'SKU for product %1 has been changed to %2.',
131-
$this->_objectManager->get(
132-
\Magento\Framework\Escaper::class
133-
)->escapeHtml($product->getName()),
134-
$this->_objectManager->get(
135-
\Magento\Framework\Escaper::class
136-
)->escapeHtml($product->getSku())
148+
$this->escaper->escapeHtml($product->getName()),
149+
$this->escaper->escapeHtml($product->getSku())
137150
)
138151
);
139152
}
@@ -143,17 +156,18 @@ public function execute()
143156
);
144157

145158
if ($redirectBack === 'duplicate') {
159+
$product->unsetData('quantity_and_stock_status');
146160
$newProduct = $this->productCopier->copy($product);
147161
$this->messageManager->addSuccessMessage(__('You duplicated the product.'));
148162
}
149163
} catch (\Magento\Framework\Exception\LocalizedException $e) {
150-
$this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
164+
$this->logger->critical($e);
151165
$this->messageManager->addExceptionMessage($e);
152166
$data = isset($product) ? $this->persistMediaData($product, $data) : $data;
153167
$this->getDataPersistor()->set('catalog_product', $data);
154168
$redirectBack = $productId ? true : 'new';
155169
} catch (\Exception $e) {
156-
$this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
170+
$this->logger->critical($e);
157171
$this->messageManager->addErrorMessage($e->getMessage());
158172
$data = isset($product) ? $this->persistMediaData($product, $data) : $data;
159173
$this->getDataPersistor()->set('catalog_product', $data);
@@ -242,6 +256,7 @@ protected function copyToStores($data, $productId)
242256
->setStoreId($copyFrom)
243257
->load($productId)
244258
->setStoreId($copyTo)
259+
->setCanSaveCustomOptions($data['can_save_custom_options'])
245260
->setCopyFromView(true)
246261
->save();
247262
}

app/code/Magento/CatalogInventory/Observer/ProcessInventoryDataObserver.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
use Magento\Framework\Event\Observer as EventObserver;
1313

1414
/**
15-
* This observer prepares stock data for saving by combining stock data from the stock data property
16-
* and quantity_and_stock_status attribute and setting it to the single point represented by stock data property.
15+
* Prepares stock data for saving
1716
*
1817
* @deprecated 100.2.0 Stock data should be processed using the module API
1918
* @see StockItemInterface when you want to change the stock data
@@ -74,7 +73,6 @@ private function processStockData(Product $product)
7473
$this->setStockDataToProduct($product, $stockItem, $quantityAndStockStatus);
7574
}
7675
}
77-
$product->unsetData('quantity_and_stock_status');
7876
}
7977

8078
/**

app/code/Magento/ConfigurableProduct/Model/ResourceModel/Attribute/OptionSelectBuilder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function __construct(Attribute $attributeResource, OptionProvider $attrib
4040
}
4141

4242
/**
43-
* {@inheritdoc}
43+
* @inheritdoc
4444
*/
4545
public function getSelect(AbstractAttribute $superAttribute, int $productId, ScopeInterface $scope)
4646
{
@@ -91,7 +91,7 @@ public function getSelect(AbstractAttribute $superAttribute, int $productId, Sco
9191
]
9292
),
9393
[]
94-
)->joinInner(
94+
)->joinLeft(
9595
['attribute_option' => $this->attributeResource->getTable('eav_attribute_option')],
9696
'attribute_option.option_id = entity_value.value',
9797
[]

app/code/Magento/ConfigurableProduct/Test/Unit/Model/ResourceModel/Attribute/OptionSelectBuilderTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ public function testGetSelect()
112112
{
113113
$this->select->expects($this->exactly(1))->method('from')->willReturnSelf();
114114
$this->select->expects($this->exactly(1))->method('columns')->willReturnSelf();
115-
$this->select->expects($this->exactly(6))->method('joinInner')->willReturnSelf();
116-
$this->select->expects($this->exactly(3))->method('joinLeft')->willReturnSelf();
115+
$this->select->expects($this->exactly(5))->method('joinInner')->willReturnSelf();
116+
$this->select->expects($this->exactly(4))->method('joinLeft')->willReturnSelf();
117117
$this->select->expects($this->exactly(1))->method('order')->willReturnSelf();
118118
$this->select->expects($this->exactly(2))->method('where')->willReturnSelf();
119119

@@ -156,8 +156,8 @@ public function testGetSelectWithBackendModel()
156156
{
157157
$this->select->expects($this->exactly(1))->method('from')->willReturnSelf();
158158
$this->select->expects($this->exactly(0))->method('columns')->willReturnSelf();
159-
$this->select->expects($this->exactly(6))->method('joinInner')->willReturnSelf();
160-
$this->select->expects($this->exactly(1))->method('joinLeft')->willReturnSelf();
159+
$this->select->expects($this->exactly(5))->method('joinInner')->willReturnSelf();
160+
$this->select->expects($this->exactly(2))->method('joinLeft')->willReturnSelf();
161161
$this->select->expects($this->exactly(1))->method('order')->willReturnSelf();
162162
$this->select->expects($this->exactly(2))->method('where')->willReturnSelf();
163163

app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ public function addAttributeToFilter($attribute, $condition = null, $joinType =
379379

380380
if (!empty($conditionSql)) {
381381
$this->getSelect()->where($conditionSql, null, \Magento\Framework\DB\Select::TYPE_CONDITION);
382+
$this->invalidateSize();
382383
} else {
383384
throw new \Magento\Framework\Exception\LocalizedException(
384385
__('Invalid attribute identifier for filter (%1)', get_class($attribute))
@@ -652,7 +653,7 @@ public function groupByAttribute($attribute)
652653
* @param string $bind attribute of the main entity to link with joined $filter
653654
* @param string $filter primary key for the joined entity (entity_id default)
654655
* @param string $joinType inner|left
655-
* @param null $storeId
656+
* @param int|null $storeId
656657
* @return $this
657658
* @throws LocalizedException
658659
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
@@ -946,8 +947,8 @@ public function load($printQuery = false, $logQuery = false)
946947
/**
947948
* Clone and reset collection
948949
*
949-
* @param null $limit
950-
* @param null $offset
950+
* @param int|null $limit
951+
* @param int|null $offset
951952
* @return Select
952953
*/
953954
protected function _getAllIdsSelect($limit = null, $offset = null)
@@ -1619,6 +1620,7 @@ public function getLoadedIds()
16191620

16201621
/**
16211622
* Clear collection
1623+
*
16221624
* @return $this
16231625
*/
16241626
public function clear()
@@ -1629,6 +1631,7 @@ public function clear()
16291631

16301632
/**
16311633
* Remove all items from collection
1634+
*
16321635
* @return $this
16331636
*/
16341637
public function removeAllItems()
@@ -1652,6 +1655,7 @@ public function removeItemByKey($key)
16521655
}
16531656

16541657
/**
1658+
* Returns main table.
16551659
* Returns main table name - extracted from "module/table" style and
16561660
* validated by db adapter
16571661
*
@@ -1699,4 +1703,16 @@ public function removeAllFieldsFromSelect()
16991703
{
17001704
return $this->removeAttributeToSelect();
17011705
}
1706+
1707+
/**
1708+
* Invalidates "Total Records Count".
1709+
* Invalidates saved "Total Records Count" attribute with last counting,
1710+
* so a next calling of method getSize() will query new total records count.
1711+
*
1712+
* @return void
1713+
*/
1714+
private function invalidateSize(): void
1715+
{
1716+
$this->_totalRecords = null;
1717+
}
17021718
}

app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
<stories value="Adding to wishlist"/>
1414
<title value="Customer should be able to add products to wishlist from different stores"/>
1515
<description value="All products added to wishlist should be visible on any store. Even if product visibility was set to 'Not Visible Individually' for this store"/>
16+
<!-- Skipped because of MAGETWO-93980 -->
17+
<group value="skip"/>
1618
<group value="wishlist"/>
1719
<severity value="AVERAGE"/>
1820
</annotations>

dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,15 @@ public function testJoinTable()
187187

188188
self::assertContains($expected, str_replace(PHP_EOL, '', $sql));
189189
}
190+
191+
/**
192+
* @magentoDataFixture Magento/Catalog/Model/ResourceModel/_files/few_simple_products.php
193+
* @magentoDbIsolation enabled
194+
*/
195+
public function testAddAttributeToFilterAffectsGetSize(): void
196+
{
197+
$this->assertEquals(10, $this->collection->getSize());
198+
$this->collection->addAttributeToFilter('sku', 'Product1');
199+
$this->assertEquals(1, $this->collection->getSize());
200+
}
190201
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
use Magento\TestFramework\Helper\Bootstrap;
9+
use Magento\Catalog\Model\ProductFactory;
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
12+
/** @var Magento\Framework\ObjectManagerInterface $objcetManager */
13+
$objectManager = Bootstrap::getObjectManager();
14+
15+
/** @var ProductFactory $productFactory */
16+
$productFactory = $objectManager->create(ProductFactory::class);
17+
18+
/** @var ProductRepositoryInterface $productRepository */
19+
$productRepository = $objectManager->create(ProductRepositoryInterface::class);
20+
21+
// Create 10 products (with change this variable, don't forget to change the same in rollback)
22+
$productsAmount = 10;
23+
24+
for ($i = 1; $i <= $productsAmount; $i++) {
25+
$productArray = [
26+
'data' => [
27+
'name' => "Product{$i}",
28+
'sku' => "Product{$i}",
29+
'price' => 100,
30+
'attribute_set_id' => 4,
31+
'website_ids' => [1]
32+
]
33+
];
34+
35+
$productRepository->save($productFactory->create($productArray));
36+
}

0 commit comments

Comments
 (0)