Skip to content

Commit 5da4020

Browse files
committed
Merge branch '2.1-develop' of https://github.com/magento/magento2ce into MAGETWO-85781-2
2 parents da1c45b + 70d7ca4 commit 5da4020

File tree

89 files changed

+2337
-776
lines changed

Some content is hidden

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

89 files changed

+2337
-776
lines changed

app/code/Magento/Bundle/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Bundle.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,13 @@ public function afterInitialize(
105105
if ($result['bundle_options'] && !$compositeReadonly) {
106106
$product->setBundleOptionsData($result['bundle_options']);
107107
}
108+
108109
$this->processBundleOptionsData($product);
109110
$this->processDynamicOptionsData($product);
111+
} elseif (!$compositeReadonly) {
112+
$extension = $product->getExtensionAttributes();
113+
$extension->setBundleProductOptions([]);
114+
$product->setExtensionAttributes($extension);
110115
}
111116

112117
$affectProductSelections = (bool)$this->request->getPost('affect_bundle_product_selections');
@@ -127,13 +132,11 @@ protected function processBundleOptionsData(\Magento\Catalog\Model\Product $prod
127132
}
128133
$options = [];
129134
foreach ($bundleOptionsData as $key => $optionData) {
130-
if ((bool)$optionData['delete']) {
131-
continue;
132-
}
133-
134135
$option = $this->optionFactory->create(['data' => $optionData]);
135136
$option->setSku($product->getSku());
136-
$option->setOptionId(null);
137+
if (!$option->getOptionId()) {
138+
$option->setOptionId(null);
139+
}
137140

138141
$links = [];
139142
$bundleLinks = $product->getBundleSelectionsData();

app/code/Magento/Bundle/Model/OptionRepository.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,11 @@ protected function updateOptionSelection(
246246
* @param string $sku
247247
* @return \Magento\Catalog\Api\Data\ProductInterface
248248
* @throws \Magento\Framework\Exception\InputException
249+
* @throws \Magento\Framework\Exception\NoSuchEntityException
249250
*/
250251
private function getProduct($sku)
251252
{
252-
$product = $this->productRepository->get($sku, true);
253+
$product = $this->productRepository->get($sku, true, null, true);
253254
if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) {
254255
throw new InputException(__('Only implemented for bundle product'));
255256
}

app/code/Magento/Bundle/Model/Product/SaveHandler.php

Lines changed: 107 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Magento\Bundle\Api\ProductOptionRepositoryInterface as OptionRepository;
99
use Magento\Bundle\Api\ProductLinkManagementInterface;
1010
use Magento\Framework\EntityManager\Operation\ExtensionInterface;
11+
use Magento\Catalog\Api\Data\ProductInterface;
1112

1213
/**
1314
* Class SaveHandler
@@ -37,44 +38,51 @@ public function __construct(
3738
}
3839

3940
/**
40-
* @param object $entity
41+
* @param object|ProductInterface $entity
4142
* @param array $arguments
42-
* @return \Magento\Catalog\Api\Data\ProductInterface|object
43+
* @return object|ProductInterface
44+
* @throws \Magento\Framework\Exception\NoSuchEntityException
45+
* @throws \Magento\Framework\Exception\InputException
46+
* @throws \Magento\Framework\Exception\CouldNotSaveException
4347
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
4448
*/
4549
public function execute($entity, $arguments = [])
4650
{
4751
$bundleProductOptions = $entity->getExtensionAttributes()->getBundleProductOptions();
48-
if ($entity->getTypeId() !== 'bundle' || empty($bundleProductOptions)) {
52+
if ($entity->getTypeId() !== Type::TYPE_CODE || empty($bundleProductOptions)) {
4953
return $entity;
5054
}
5155

56+
$existingBundleProductOptions = $this->optionRepository->getList($entity->getSku());
57+
58+
$existingOptionsIds = !empty($existingBundleProductOptions)
59+
? $this->getOptionIds($existingBundleProductOptions)
60+
: [];
61+
$optionIds = !empty($bundleProductOptions)
62+
? $this->getOptionIds($bundleProductOptions)
63+
: [];
64+
65+
$options = $bundleProductOptions ?: [];
66+
5267
if (!$entity->getCopyFromView()) {
53-
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
54-
foreach ($this->optionRepository->getList($entity->getSku()) as $option) {
55-
$this->removeOptionLinks($entity->getSku(), $option);
56-
$this->optionRepository->delete($option);
57-
}
68+
$this->processRemovedOptions($entity->getSku(), $existingOptionsIds, $optionIds);
69+
$this->processExistingOptions($entity->getSku(), $existingOptionsIds, $optionIds);
5870

59-
$options = $bundleProductOptions ?: [];
60-
foreach ($options as $option) {
61-
$option->setOptionId(null);
62-
$this->optionRepository->save($entity, $option);
63-
}
71+
$newOptionsIds = array_diff($optionIds, $existingOptionsIds);
72+
$this->saveOptions($entity, $options, $newOptionsIds);
6473
} else {
6574
//save only labels and not selections + product links
66-
$options = $bundleProductOptions ?: [];
67-
foreach ($options as $option) {
68-
$this->optionRepository->save($entity, $option);
69-
$entity->setCopyFromView(false);
70-
}
75+
$this->saveOptions($entity, $options);
76+
$entity->setCopyFromView(false);
7177
}
7278
return $entity;
7379
}
7480

7581
/**
7682
* @param string $entitySku
7783
* @param \Magento\Bundle\Api\Data\OptionInterface $option
84+
* @throws \Magento\Framework\Exception\NoSuchEntityException
85+
* @throws \Magento\Framework\Exception\InputException
7886
* @return void
7987
*/
8088
protected function removeOptionLinks($entitySku, $option)
@@ -86,4 +94,85 @@ protected function removeOptionLinks($entitySku, $option)
8694
}
8795
}
8896
}
97+
98+
/**
99+
* Perform save for all options entities
100+
*
101+
* @param ProductInterface $entity
102+
* @param array $options
103+
* @param array $newOptionsIds
104+
* @throws \Magento\Framework\Exception\CouldNotSaveException
105+
* @throws \Magento\Framework\Exception\InputException
106+
* @return void
107+
*/
108+
private function saveOptions(ProductInterface $entity, array $options, array $newOptionsIds = [])
109+
{
110+
foreach ($options as $option) {
111+
if (in_array($option->getOptionId(), $newOptionsIds, true)) {
112+
$option->setOptionId(null);
113+
}
114+
$this->optionRepository->save($entity, $option);
115+
}
116+
}
117+
118+
/**
119+
* Get options ids from array of the options entities
120+
*
121+
* @param array $options
122+
* @return array
123+
*/
124+
private function getOptionIds(array $options)
125+
{
126+
$optionIds = [];
127+
128+
if (empty($options)) {
129+
return $optionIds;
130+
}
131+
132+
/** @var \Magento\Bundle\Api\Data\OptionInterface $option */
133+
foreach ($options as $option) {
134+
if ($option->getOptionId()) {
135+
$optionIds[] = $option->getOptionId();
136+
}
137+
}
138+
return $optionIds;
139+
}
140+
141+
/**
142+
* Removes old options that no longer exists
143+
*
144+
* @param string $entitySku
145+
* @param array $existingOptionsIds
146+
* @param array $optionIds
147+
* @throws \Magento\Framework\Exception\NoSuchEntityException
148+
* @throws \Magento\Framework\Exception\InputException
149+
* @throws \Magento\Framework\Exception\CouldNotSaveException
150+
* @return void
151+
*/
152+
private function processRemovedOptions($entitySku, array $existingOptionsIds, array $optionIds)
153+
{
154+
foreach (array_diff($existingOptionsIds, $optionIds) as $optionId) {
155+
$option = $this->optionRepository->get($entitySku, $optionId);
156+
$this->removeOptionLinks($entitySku, $option);
157+
$this->optionRepository->delete($option);
158+
}
159+
}
160+
161+
/**
162+
* Removes option links for existing options
163+
*
164+
* @param string $entitySku
165+
* @param array $existingOptionsIds
166+
* @param array $optionIds
167+
* @throws \Magento\Framework\Exception\NoSuchEntityException
168+
* @throws \Magento\Framework\Exception\InputException
169+
* @return void
170+
*/
171+
private function processExistingOptions($entitySku, array $existingOptionsIds, array $optionIds)
172+
{
173+
foreach (array_intersect($optionIds, $existingOptionsIds) as $optionId) {
174+
$option = $this->optionRepository->get($entitySku, $optionId);
175+
$this->removeOptionLinks($entitySku, $option);
176+
}
177+
}
89178
}

app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ protected function _prepareTierPriceIndex($entityIds = null)
491491
null
492492
)->join(
493493
['e' => $this->getTable('catalog_product_entity')],
494-
"i.entity_id=e.$linkField",
494+
"i.entity_id=e.entity_id",
495495
[]
496496
)->where(
497497
'e.type_id=?',
@@ -502,7 +502,7 @@ protected function _prepareTierPriceIndex($entityIds = null)
502502

503503
$select = $connection->select()->from(
504504
['tp' => $this->getTable('catalog_product_entity_tier_price')],
505-
[$linkField]
505+
['e.entity_id']
506506
)->join(
507507
['e' => $this->getTable('catalog_product_entity')],
508508
"tp.{$linkField} = e.{$linkField}",
@@ -523,11 +523,11 @@ protected function _prepareTierPriceIndex($entityIds = null)
523523
)->columns(
524524
new \Zend_Db_Expr('MIN(tp.value)')
525525
)->group(
526-
["tp.{$linkField}", 'cg.customer_group_id', 'cw.website_id']
526+
['e.entity_id', 'cg.customer_group_id', 'cw.website_id']
527527
);
528528

529529
if (!empty($entityIds)) {
530-
$select->where("tp.{$linkField} IN(?)", $entityIds);
530+
$select->where('e.entity_id IN(?)', $entityIds);
531531
}
532532

533533
$query = $select->insertFromSelect($this->_getTierPriceIndexTable());

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ public function execute()
129129
$isNewCategory = !isset($categoryPostData['entity_id']);
130130
$categoryPostData = $this->stringToBoolConverting($categoryPostData);
131131
$categoryPostData = $this->imagePreprocessing($categoryPostData);
132-
$categoryPostData = $this->dateTimePreprocessing($category, $categoryPostData);
133132
$storeId = isset($categoryPostData['store_id']) ? $categoryPostData['store_id'] : null;
134133
$store = $this->storeManager->getStore($storeId);
135134
$this->storeManager->setCurrentStore($store->getCode());

app/code/Magento/Catalog/Model/Product/Option/Type/Date.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public function prepareForCart()
142142

143143
if ($this->_dateExists()) {
144144
if ($this->useCalendar()) {
145-
$timestamp += $this->_localeDate->date($value['date'], null, true, false)->getTimestamp();
145+
$timestamp += $this->_localeDate->date($value['date'], null, true)->getTimestamp();
146146
} else {
147147
$timestamp += mktime(0, 0, 0, $value['month'], $value['day'], $value['year']);
148148
}

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

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -292,27 +292,34 @@ protected function initializeProductData(array $productData, $createNew)
292292
foreach ($productData as $key => $value) {
293293
$product->setData($key, $value);
294294
}
295-
$this->assignProductToWebsites($product);
295+
$this->assignProductToWebsites($product, $createNew);
296296

297297
return $product;
298298
}
299299

300300
/**
301301
* @param \Magento\Catalog\Model\Product $product
302+
* @param bool $createNew
302303
* @return void
303304
*/
304-
private function assignProductToWebsites(\Magento\Catalog\Model\Product $product)
305+
private function assignProductToWebsites(\Magento\Catalog\Model\Product $product, $createNew)
305306
{
306-
if (!$this->storeManager->hasSingleStore()) {
307-
308-
if ($this->storeManager->getStore()->getCode() == \Magento\Store\Model\Store::ADMIN_CODE) {
309-
$websiteIds = array_keys($this->storeManager->getWebsites());
310-
} else {
311-
$websiteIds = [$this->storeManager->getStore()->getWebsiteId()];
312-
}
307+
$websiteIds = $product->getWebsiteIds();
308+
309+
if ($createNew && !$this->storeManager->hasSingleStore()) {
310+
$websiteIds = array_unique(
311+
array_merge(
312+
$websiteIds,
313+
[$this->storeManager->getStore()->getWebsiteId()]
314+
)
315+
);
316+
}
313317

314-
$product->setWebsiteIds(array_unique(array_merge($product->getWebsiteIds(), $websiteIds)));
318+
if ($createNew && $this->storeManager->getStore(true)->getCode() == \Magento\Store\Model\Store::ADMIN_CODE) {
319+
$websiteIds = array_keys($this->storeManager->getWebsites());
315320
}
321+
322+
$product->setWebsiteIds($websiteIds);
316323
}
317324

318325
/**
@@ -401,7 +408,7 @@ private function processLinks(\Magento\Catalog\Api\Data\ProductInterface $produc
401408
$linksToInitialize = [];
402409
foreach ($linksByType as $link) {
403410
$linkDataArray = $this->extensibleDataObjectConverter
404-
->toNestedArray($link, [], 'Magento\Catalog\Api\Data\ProductLinkInterface');
411+
->toNestedArray($link, [], \Magento\Catalog\Api\Data\ProductLinkInterface::class);
405412
$linkedSku = $link->getLinkedProductSku();
406413
if (!isset($linkedProductIds[$linkedSku])) {
407414
throw new NoSuchEntityException(
@@ -518,7 +525,7 @@ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveO
518525
}
519526

520527
$productDataArray = $this->extensibleDataObjectConverter
521-
->toNestedArray($product, [], 'Magento\Catalog\Api\Data\ProductInterface');
528+
->toNestedArray($product, [], \Magento\Catalog\Api\Data\ProductInterface::class);
522529
$productDataArray = array_replace($productDataArray, $product->getData());
523530
$ignoreLinksFlag = $product->getData('ignore_links_flag');
524531
$productLinks = null;
@@ -631,6 +638,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
631638
$collection->setCurPage($searchCriteria->getCurrentPage());
632639
$collection->setPageSize($searchCriteria->getPageSize());
633640
$collection->load();
641+
$collection->addCategoryIds();
634642

635643
$searchResult = $this->searchResultsFactory->create();
636644
$searchResult->setSearchCriteria($searchCriteria);
@@ -717,7 +725,7 @@ private function getMediaGalleryProcessor()
717725
{
718726
if (null === $this->mediaGalleryProcessor) {
719727
$this->mediaGalleryProcessor = \Magento\Framework\App\ObjectManager::getInstance()
720-
->get('Magento\Catalog\Model\Product\Gallery\Processor');
728+
->get(\Magento\Catalog\Model\Product\Gallery\Processor::class);
721729
}
722730
return $this->mediaGalleryProcessor;
723731
}

app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Category/SaveTest.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,6 @@ public function testExecute($categoryId, $storeId, $parentId)
279279
'setParentId',
280280
'setData',
281281
'addData',
282-
'getAttributes',
283282
'setAttributeSetId',
284283
'getDefaultAttributeSetId',
285284
'getProductsReadonly',
@@ -470,9 +469,6 @@ public function testExecute($categoryId, $storeId, $parentId)
470469
$categoryMock->expects($this->any())
471470
->method('getId')
472471
->will($this->returnValue($categoryId));
473-
$categoryMock->expects($this->once())
474-
->method('getAttributes')
475-
->willReturn([]);
476472
if (!$parentId) {
477473
if ($storeId) {
478474
$storeManagerMock->expects($this->once())

app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ public function testGetCustomAttributes()
550550
$this->assertEquals("description", $this->category->getCustomAttribute($descriptionAttributeCode)->getValue());
551551

552552
//Change the attribute value, should reflect in getCustomAttribute
553-
$this->category->setData($descriptionAttributeCode, "new description");
553+
$this->category->setCustomAttribute($descriptionAttributeCode, "new description");
554554
$this->assertEquals(1, count($this->category->getCustomAttributes()));
555555
$this->assertNotNull($this->category->getCustomAttribute($descriptionAttributeCode));
556556
$this->assertEquals(

0 commit comments

Comments
 (0)