Skip to content

Commit c6df629

Browse files
author
Bohdan Korablov
committed
Merge remote-tracking branch 'mainline/2.2-develop' into MAGETWO-49796
2 parents 15c586a + 4d9d6b0 commit c6df629

File tree

116 files changed

+5173
-874
lines changed

Some content is hidden

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

116 files changed

+5173
-874
lines changed

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

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public function getDefaultValues()
142142
*/
143143
protected function _getSelectedOptions()
144144
{
145-
if (is_null($this->_selectedOptions)) {
145+
if ($this->_selectedOptions === null) {
146146
$this->_selectedOptions = [];
147147

148148
/** @var \Magento\Bundle\Model\Option $option */
@@ -152,17 +152,29 @@ protected function _getSelectedOptions()
152152
$selectionId = $this->getProduct()->getPreconfiguredValues()->getData(
153153
'bundle_option/' . $option->getId()
154154
);
155-
if ($selectionId && $option->getSelectionById($selectionId)) {
156-
$this->_selectedOptions = $selectionId;
157-
} elseif (!$option->getRequired()) {
158-
$this->_selectedOptions = 'None';
159-
}
155+
$this->assignSelection($option, $selectionId);
160156
}
161157
}
162158

163159
return $this->_selectedOptions;
164160
}
165161

162+
/**
163+
* Set selected options.
164+
*
165+
* @param \Magento\Bundle\Model\Option $option
166+
* @param mixed $selectionId
167+
* @return void
168+
*/
169+
protected function assignSelection(\Magento\Bundle\Model\Option $option, $selectionId)
170+
{
171+
if ($selectionId && $option->getSelectionById($selectionId)) {
172+
$this->_selectedOptions = $selectionId;
173+
} elseif (!$option->getRequired()) {
174+
$this->_selectedOptions = 'None';
175+
}
176+
}
177+
166178
/**
167179
* Define if selection is selected
168180
*

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,20 @@ class Multi extends \Magento\Bundle\Block\Catalog\Product\View\Type\Bundle\Optio
1717
* @var string
1818
*/
1919
protected $_template = 'catalog/product/view/type/bundle/option/multi.phtml';
20+
21+
/**
22+
* @inheritdoc
23+
*/
24+
protected function assignSelection(\Magento\Bundle\Model\Option $option, $selectionId)
25+
{
26+
if (is_array($selectionId)) {
27+
foreach ($selectionId as $id) {
28+
if ($id && $option->getSelectionById($id)) {
29+
$this->_selectedOptions[] = $id;
30+
}
31+
}
32+
} else {
33+
parent::assignSelection($option, $selectionId);
34+
}
35+
}
2036
}

app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/options.phtml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
<?php
1212
$product = $block->getProduct();
1313
$helper = $this->helper('Magento\Catalog\Helper\Output');
14+
$stripSelection = $product->getConfigureMode() ? true : false;
15+
$options = $block->decorateArray($block->getOptions($stripSelection));
1416
?>
15-
<?php $options = $block->decorateArray($block->getOptions()); ?>
1617
<?php if ($product->isSaleable()):?>
1718
<?php if (count($options)): ?>
1819
<script type="text/x-magento-init">

app/code/Magento/Catalog/Model/Product/Option/Repository.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,9 @@ public function save(\Magento\Catalog\Api\Data\ProductCustomOptionInterface $opt
172172
$originalValues = $persistedOption->getValues();
173173
$newValues = $option->getData('values');
174174
if ($newValues) {
175-
$newValues = $this->markRemovedValues($newValues, $originalValues);
175+
if (isset($originalValues)) {
176+
$newValues = $this->markRemovedValues($newValues, $originalValues);
177+
}
176178
$option->setData('values', $newValues);
177179
}
178180
}

app/code/Magento/Catalog/Test/Unit/Model/Product/Option/RepositoryTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,4 +267,29 @@ public function testSave()
267267
]);
268268
$this->assertEquals($this->optionMock, $this->optionRepository->save($this->optionMock));
269269
}
270+
271+
public function testSaveWhenOptionTypeWasChanged()
272+
{
273+
$productSku = 'simple_product';
274+
$optionId = 1;
275+
$this->optionMock->expects($this->once())->method('getProductSku')->willReturn($productSku);
276+
$this->productRepositoryMock
277+
->expects($this->once())
278+
->method('get')
279+
->with($productSku)
280+
->willReturn($this->productMock);
281+
$this->optionMock->expects($this->any())->method('getOptionId')->willReturn($optionId);
282+
$this->productMock->expects($this->once())->method('getOptions')->willReturn([]);
283+
$this->optionMock->expects($this->once())->method('getData')->with('values')->willReturn([
284+
['option_type_id' => 4],
285+
['option_type_id' => 5]
286+
]);
287+
$optionCollection = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product\Option\Collection::class)
288+
->disableOriginalConstructor()
289+
->getMock();
290+
$optionCollection->expects($this->once())->method('getProductOptions')->willReturn([$this->optionMock]);
291+
$this->optionCollectionFactory->expects($this->once())->method('create')->willReturn($optionCollection);
292+
$this->optionMock->expects($this->once())->method('getValues')->willReturn(null);
293+
$this->assertEquals($this->optionMock, $this->optionRepository->save($this->optionMock));
294+
}
270295
}

app/code/Magento/CatalogImportExport/Model/Export/Product.php

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,15 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
153153
/**
154154
* Items per page for collection limitation
155155
*
156-
* @var null
156+
* @var int|null
157157
*/
158158
protected $_itemsPerPage = null;
159159

160160
/**
161161
* Header columns for export file
162162
*
163163
* @var array
164+
* @deprecated
164165
*/
165166
protected $_headerColumns = [];
166167

@@ -234,17 +235,15 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
234235
protected $_fieldsMap = [
235236
'image' => 'base_image',
236237
'image_label' => "base_image_label",
237-
'image' => 'base_image',
238-
'image_label' => 'base_image_label',
239238
'thumbnail' => 'thumbnail_image',
240239
'thumbnail_label' => 'thumbnail_image_label',
241240
self::COL_MEDIA_IMAGE => 'additional_images',
242241
'_media_image_label' => 'additional_image_labels',
243-
Product::COL_STORE => 'store_view_code',
244-
Product::COL_ATTR_SET => 'attribute_set_code',
245-
Product::COL_TYPE => 'product_type',
246-
Product::COL_CATEGORY => 'categories',
247-
Product::COL_PRODUCT_WEBSITES => 'product_websites',
242+
self::COL_STORE => 'store_view_code',
243+
self::COL_ATTR_SET => 'attribute_set_code',
244+
self::COL_TYPE => 'product_type',
245+
self::COL_CATEGORY => 'categories',
246+
self::COL_PRODUCT_WEBSITES => 'product_websites',
248247
'status' => 'product_online',
249248
'news_from_date' => 'new_from_date',
250249
'news_to_date' => 'new_to_date',
@@ -691,7 +690,7 @@ protected function updateDataWithCategoryColumns(&$dataRow, &$rowCategories, $pr
691690
*/
692691
public function _getHeaderColumns()
693692
{
694-
return $this->_customHeadersMapping($this->_headerColumns);
693+
return $this->_customHeadersMapping($this->rowCustomizer->addHeaderColumns($this->_headerColumns));
695694
}
696695

697696
/**
@@ -700,13 +699,13 @@ public function _getHeaderColumns()
700699
* @param array $customOptionsData
701700
* @param array $stockItemRows
702701
* @return void
702+
* @deprecated Logic will be moved to _getHeaderColumns in future release
703+
*
704+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
703705
*/
704706
protected function setHeaderColumns($customOptionsData, $stockItemRows)
705707
{
706708
if (!$this->_headerColumns) {
707-
$customOptCols = [
708-
'custom_options',
709-
];
710709
$this->_headerColumns = array_merge(
711710
[
712711
self::COL_SKU,
@@ -719,21 +718,19 @@ protected function setHeaderColumns($customOptionsData, $stockItemRows)
719718
$this->_getExportMainAttrCodes(),
720719
[self::COL_ADDITIONAL_ATTRIBUTES],
721720
reset($stockItemRows) ? array_keys(end($stockItemRows)) : [],
722-
[],
723721
[
724722
'related_skus',
725723
'related_position',
726724
'crosssell_skus',
727725
'crosssell_position',
728726
'upsell_skus',
729-
'upsell_position'
730-
],
731-
['additional_images', 'additional_image_labels', 'hide_from_product_page']
727+
'upsell_position',
728+
'additional_images',
729+
'additional_image_labels',
730+
'hide_from_product_page',
731+
'custom_options'
732+
]
732733
);
733-
// have we merge custom options columns
734-
if ($customOptionsData) {
735-
$this->_headerColumns = array_merge($this->_headerColumns, $customOptCols);
736-
}
737734
}
738735
}
739736

@@ -892,10 +889,12 @@ protected function getExportData()
892889
$productIds = array_keys($rawData);
893890
$stockItemRows = $this->prepareCatalogInventory($productIds);
894891

895-
$this->rowCustomizer->prepareData($this->_getEntityCollection(), $productIds);
892+
$this->rowCustomizer->prepareData(
893+
$this->_prepareEntityCollection($this->_entityCollectionFactory->create()),
894+
$productIds
895+
);
896896

897897
$this->setHeaderColumns($multirawData['customOptionsData'], $stockItemRows);
898-
$this->_headerColumns = $this->rowCustomizer->addHeaderColumns($this->_headerColumns);
899898

900899
foreach ($rawData as $productId => $productData) {
901900
foreach ($productData as $storeId => $dataRow) {
@@ -1231,9 +1230,6 @@ private function appendMultirowData(&$dataRow, &$multiRawData)
12311230
return null;
12321231
} elseif ($storeId != Store::DEFAULT_STORE_ID) {
12331232
$dataRow[self::COL_STORE] = $this->_storeIdToCode[$storeId];
1234-
if (isset($productData[Store::DEFAULT_STORE_ID][self::COL_VISIBILITY])) {
1235-
$dataRow[self::COL_VISIBILITY] = $productData[Store::DEFAULT_STORE_ID][self::COL_VISIBILITY];
1236-
}
12371233
}
12381234
$dataRow[self::COL_SKU] = $sku;
12391235
return $dataRow;

app/code/Magento/CatalogImportExport/Test/Unit/Model/Export/ProductTest.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,15 @@ public function testGetHeaderColumns()
270270
$headerColumnsValue = ['headerColumns value'];
271271
$expectedResult = 'result';
272272
$this->setPropertyValue($product, '_headerColumns', $headerColumnsValue);
273-
$product
274-
->expects($this->once())
273+
$this->setPropertyValue($product, 'rowCustomizer', $this->rowCustomizer);
274+
$product->expects($this->once())
275275
->method('_customHeadersMapping')
276276
->with($headerColumnsValue)
277277
->willReturn($expectedResult);
278+
$this->rowCustomizer->expects($this->once())
279+
->method('addHeaderColumns')
280+
->with($headerColumnsValue)
281+
->willReturn($headerColumnsValue);
278282

279283
$result = $product->_getHeaderColumns();
280284

app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class StockItemRepository implements StockItemRepositoryInterface
7777

7878
/**
7979
* @var Processor
80+
* @deprecated
8081
*/
8182
protected $indexProcessor;
8283

@@ -181,8 +182,6 @@ public function save(\Magento\CatalogInventory\Api\Data\StockItemInterface $stoc
181182
$stockItem->setStockId($stockItem->getStockId());
182183

183184
$this->resource->save($stockItem);
184-
185-
$this->indexProcessor->reindexRow($stockItem->getProductId());
186185
} catch (\Exception $exception) {
187186
throw new CouldNotSaveException(__('Unable to save Stock Item'), $exception);
188187
}

app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/StockItemRepositoryTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,6 @@ public function testSave()
304304
->method('save')
305305
->with($this->stockItemMock)
306306
->willReturnSelf();
307-
$this->indexProcessorMock->expects($this->once())->method('reindexRow')->with($productId);
308307

309308
$this->assertEquals($this->stockItemMock, $this->model->save($this->stockItemMock));
310309
}

app/code/Magento/CatalogUrlRewrite/Model/ProductScopeRewriteGenerator.php

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@
55
*/
66
namespace Magento\CatalogUrlRewrite\Model;
77

8+
use Magento\Catalog\Api\CategoryRepositoryInterface;
89
use Magento\Catalog\Model\Category;
910
use Magento\Catalog\Model\Product;
11+
use Magento\CatalogUrlRewrite\Model\Product\AnchorUrlRewriteGenerator;
1012
use Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator;
1113
use Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator;
1214
use Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator;
13-
use Magento\CatalogUrlRewrite\Model\Product\AnchorUrlRewriteGenerator;
1415
use Magento\CatalogUrlRewrite\Service\V1\StoreViewService;
16+
use Magento\Framework\App\ObjectManager;
1517
use Magento\Store\Model\Store;
1618
use Magento\Store\Model\StoreManagerInterface;
1719
use Magento\UrlRewrite\Model\MergeDataProviderFactory;
18-
use Magento\Framework\App\ObjectManager;
1920

2021
/**
2122
* Class ProductScopeRewriteGenerator
@@ -63,6 +64,11 @@ class ProductScopeRewriteGenerator
6364
*/
6465
private $mergeDataProviderPrototype;
6566

67+
/**
68+
* @var CategoryRepositoryInterface
69+
*/
70+
private $categoryRepository;
71+
6672
/**
6773
* @param StoreViewService $storeViewService
6874
* @param StoreManagerInterface $storeManager
@@ -72,6 +78,7 @@ class ProductScopeRewriteGenerator
7278
* @param CurrentUrlRewritesRegenerator $currentUrlRewritesRegenerator
7379
* @param AnchorUrlRewriteGenerator $anchorUrlRewriteGenerator
7480
* @param \Magento\UrlRewrite\Model\MergeDataProviderFactory|null $mergeDataProviderFactory
81+
* @param CategoryRepositoryInterface|null $categoryRepository
7582
*/
7683
public function __construct(
7784
StoreViewService $storeViewService,
@@ -81,7 +88,8 @@ public function __construct(
8188
CategoriesUrlRewriteGenerator $categoriesUrlRewriteGenerator,
8289
CurrentUrlRewritesRegenerator $currentUrlRewritesRegenerator,
8390
AnchorUrlRewriteGenerator $anchorUrlRewriteGenerator,
84-
MergeDataProviderFactory $mergeDataProviderFactory = null
91+
MergeDataProviderFactory $mergeDataProviderFactory = null,
92+
CategoryRepositoryInterface $categoryRepository = null
8593
) {
8694
$this->storeViewService = $storeViewService;
8795
$this->storeManager = $storeManager;
@@ -94,6 +102,8 @@ public function __construct(
94102
$mergeDataProviderFactory = ObjectManager::getInstance()->get(MergeDataProviderFactory::class);
95103
}
96104
$this->mergeDataProviderPrototype = $mergeDataProviderFactory->create();
105+
$this->categoryRepository = $categoryRepository ?:
106+
ObjectManager::getInstance()->get(CategoryRepositoryInterface::class);
97107
}
98108

99109
/**
@@ -150,10 +160,14 @@ public function generateForSpecificStoreView($storeId, $productCategories, Produ
150160
$mergeDataProvider = clone $this->mergeDataProviderPrototype;
151161
$categories = [];
152162
foreach ($productCategories as $category) {
153-
if ($this->isCategoryProperForGenerating($category, $storeId)) {
154-
$categories[] = $category;
163+
if (!$this->isCategoryProperForGenerating($category, $storeId)) {
164+
continue;
155165
}
166+
167+
// category should be loaded per appropriate store if category's URL key has been changed
168+
$categories[] = $this->getCategoryWithOverriddenUrlKey($storeId, $category);
156169
}
170+
157171
$productCategories = $this->objectRegistryFactory->create(['entities' => $categories]);
158172

159173
$mergeDataProvider->merge(
@@ -199,4 +213,26 @@ public function isCategoryProperForGenerating(Category $category, $storeId)
199213
}
200214
return false;
201215
}
216+
217+
/**
218+
* Checks if URL key has been changed for provided category and returns reloaded category,
219+
* in other case - returns provided category.
220+
*
221+
* @param $storeId
222+
* @param Category $category
223+
* @return Category
224+
*/
225+
private function getCategoryWithOverriddenUrlKey($storeId, Category $category)
226+
{
227+
$isUrlKeyOverridden = $this->storeViewService->doesEntityHaveOverriddenUrlKeyForStore(
228+
$storeId,
229+
$category->getEntityId(),
230+
Category::ENTITY
231+
);
232+
233+
if (!$isUrlKeyOverridden) {
234+
return $category;
235+
}
236+
return $this->categoryRepository->get($category->getEntityId(), $storeId);
237+
}
202238
}

0 commit comments

Comments
 (0)