Skip to content

Commit e0c7edb

Browse files
authored
Merge pull request #456 from magento-nord/NORD-PR-10
- MAGETWO-47698: [Github] Custom options not displayed correctly on a store view level #2908 #5885 - MAGETWO-56411: [GitHub] Shopping cart product options missing #248 - MAGETWO-58242: Issue with an Import Export when Attribute Changes - MAGETWO-58053 [GITHUB] Product image issue with multiple store views Magento 2.1.0 #6259
2 parents 0f1af99 + 6cd9ff7 commit e0c7edb

File tree

23 files changed

+533
-140
lines changed

23 files changed

+533
-140
lines changed

app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php

+12-5
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,16 @@ public function initializeFromData(\Magento\Catalog\Model\Product $product, arra
199199
$customOptions = [];
200200
foreach ($options as $customOptionData) {
201201
if (empty($customOptionData['is_delete'])) {
202+
if (empty($customOptionData['option_id'])) {
203+
$customOptionData['option_id'] = null;
204+
}
202205
if (isset($customOptionData['values'])) {
203206
$customOptionData['values'] = array_filter($customOptionData['values'], function ($valueData) {
204207
return empty($valueData['is_delete']);
205208
});
206209
}
207210
$customOption = $this->getCustomOptionFactory()->create(['data' => $customOptionData]);
208211
$customOption->setProductSku($product->getSku());
209-
$customOption->setOptionId(null);
210212
$customOptions[] = $customOption;
211213
}
212214
}
@@ -255,7 +257,7 @@ protected function setProductLinks(\Magento\Catalog\Model\Product $product)
255257

256258
foreach ($linkTypes as $linkType => $readonly) {
257259
if (isset($links[$linkType]) && !$readonly) {
258-
foreach ((array) $links[$linkType] as $linkData) {
260+
foreach ((array)$links[$linkType] as $linkData) {
259261
if (empty($linkData['id'])) {
260262
continue;
261263
}
@@ -321,9 +323,11 @@ public function mergeProductOptions($productOptions, $overwriteOptions)
321323

322324
if (isset($option['values']) && isset($overwriteOptions[$optionId]['values'])) {
323325
foreach ($option['values'] as $valueIndex => $value) {
324-
$valueId = $value['option_type_id'];
325-
$value = $this->overwriteValue($valueId, $value, $overwriteOptions[$optionId]['values']);
326-
$option['values'][$valueIndex] = $value;
326+
if (isset($value['option_type_id'])) {
327+
$valueId = $value['option_type_id'];
328+
$value = $this->overwriteValue($valueId, $value, $overwriteOptions[$optionId]['values']);
329+
$option['values'][$valueIndex] = $value;
330+
}
327331
}
328332
}
329333

@@ -347,6 +351,9 @@ private function overwriteValue($optionId, $option, $overwriteOptions)
347351
foreach ($overwriteOptions[$optionId] as $fieldName => $overwrite) {
348352
if ($overwrite && isset($option[$fieldName]) && isset($option['default_' . $fieldName])) {
349353
$option[$fieldName] = $option['default_' . $fieldName];
354+
if ('title' == $fieldName) {
355+
$option['is_delete_store_title'] = 1;
356+
}
350357
}
351358
}
352359
}

app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php

+7-6
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,13 @@ public function execute($product, $arguments = [])
160160
if (in_array($attrData, array_keys($existImages))) {
161161
$product->setData($mediaAttrCode . '_label', $existImages[$attrData]['label']);
162162
}
163-
164-
$product->addAttributeUpdate(
165-
$mediaAttrCode,
166-
$product->getData($mediaAttrCode),
167-
$product->getStoreId()
168-
);
163+
if (!empty($product->getData($mediaAttrCode))) {
164+
$product->addAttributeUpdate(
165+
$mediaAttrCode,
166+
$product->getData($mediaAttrCode),
167+
$product->getStoreId()
168+
);
169+
}
169170
}
170171

171172
$product->setData($attrCode, $value);

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

+24-1
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,33 @@ public function save(\Magento\Catalog\Api\Data\ProductCustomOptionInterface $opt
137137
if (!$productSku) {
138138
throw new CouldNotSaveException(__('ProductSku should be specified'));
139139
}
140+
/** @var \Magento\Catalog\Model\Product $product */
140141
$product = $this->productRepository->get($productSku);
141142
$metadata = $this->getMetadataPool()->getMetadata(ProductInterface::class);
142143
$option->setData('product_id', $product->getData($metadata->getLinkField()));
143-
$option->setOptionId(null);
144+
$option->setData('store_id', $product->getStoreId());
145+
146+
if ($option->getOptionId()) {
147+
$options = $product->getOptions();
148+
if (!$options) {
149+
$options = $this->getProductOptions($product);
150+
}
151+
152+
$persistedOption = array_filter($options, function ($iOption) use ($option) {
153+
return $option->getOptionId() == $iOption->getOptionId();
154+
});
155+
$persistedOption = reset($persistedOption);
156+
157+
if (!$persistedOption) {
158+
throw new NoSuchEntityException();
159+
}
160+
$originalValues = $persistedOption->getValues();
161+
$newValues = $option->getData('values');
162+
if ($newValues) {
163+
$newValues = $this->markRemovedValues($newValues, $originalValues);
164+
$option->setData('values', $newValues);
165+
}
166+
}
144167
$option->save();
145168
return $option;
146169
}

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

+16-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ class SaveHandler implements ExtensionInterface
2020

2121
/**
2222
* @param OptionRepository $optionRepository
23-
* @param MetadataPool $metadataPool
2423
*/
2524
public function __construct(
2625
OptionRepository $optionRepository
@@ -36,15 +35,28 @@ public function __construct(
3635
*/
3736
public function execute($entity, $arguments = [])
3837
{
38+
$options = $entity->getOptions();
39+
$optionIds = [];
40+
41+
if ($options) {
42+
$optionIds = array_map(function ($option) {
43+
/** @var \Magento\Catalog\Model\Product\Option $option */
44+
return $option->getOptionId();
45+
}, $options);
46+
}
47+
3948
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
4049
foreach ($this->optionRepository->getProductOptions($entity) as $option) {
41-
$this->optionRepository->delete($option);
50+
if (!in_array($option->getOptionId(), $optionIds)) {
51+
$this->optionRepository->delete($option);
52+
}
4253
}
43-
if ($entity->getOptions()) {
44-
foreach ($entity->getOptions() as $option) {
54+
if ($options) {
55+
foreach ($options as $option) {
4556
$this->optionRepository->save($option);
4657
}
4758
}
59+
4860
return $entity;
4961
}
5062
}

app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php

+3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ protected function validateOptionValue(Option $option)
5151
$storeId = $option->getProduct()->getStoreId();
5252
}
5353
foreach ($values as $value) {
54+
if (isset($value['is_delete']) && (bool)$value['is_delete']) {
55+
continue;
56+
}
5457
$type = isset($value['price_type']) ? $value['price_type'] : null;
5558
$price = isset($value['price']) ? $value['price'] : null;
5659
$title = isset($value['title']) ? $value['title'] : null;

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ public function saveValues()
200200
'store_id',
201201
$this->getOption()->getStoreId()
202202
);
203-
$this->unsetData('option_type_id');
203+
204204
if ($this->getData('is_delete') == '1') {
205205
if ($this->getId()) {
206206
$this->deleteValues($this->getId());

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

+20-8
Original file line numberDiff line numberDiff line change
@@ -247,14 +247,21 @@ protected function _saveValueTitles(\Magento\Framework\Model\AbstractModel $obje
247247
$titleTableName = $this->getTable('catalog_product_option_title');
248248
foreach ([\Magento\Store\Model\Store::DEFAULT_STORE_ID, $object->getStoreId()] as $storeId) {
249249
$existInCurrentStore = $this->getColFromOptionTable($titleTableName, (int)$object->getId(), (int)$storeId);
250-
$existInDefaultStore = $this->getColFromOptionTable(
251-
$titleTableName,
252-
(int)$object->getId(),
253-
\Magento\Store\Model\Store::DEFAULT_STORE_ID
254-
);
250+
$existInDefaultStore = (int)$storeId == \Magento\Store\Model\Store::DEFAULT_STORE_ID ?
251+
$existInCurrentStore :
252+
$this->getColFromOptionTable(
253+
$titleTableName,
254+
(int)$object->getId(),
255+
\Magento\Store\Model\Store::DEFAULT_STORE_ID
256+
);
257+
255258
if ($object->getTitle()) {
259+
$isDeleteStoreTitle = (bool)$object->getData('is_delete_store_title');
256260
if ($existInCurrentStore) {
257-
if ($object->getStoreId() == $storeId) {
261+
if ($isDeleteStoreTitle && (int)$storeId != \Magento\Store\Model\Store::DEFAULT_STORE_ID) {
262+
$connection->delete($titleTableName, ['option_title_id = ?' => $existInCurrentStore]);
263+
264+
} elseif ($object->getStoreId() == $storeId) {
258265
$data = $this->_prepareDataForTable(
259266
new \Magento\Framework\DataObject(['title' => $object->getTitle()]),
260267
$titleTableName
@@ -270,8 +277,13 @@ protected function _saveValueTitles(\Magento\Framework\Model\AbstractModel $obje
270277
}
271278
} else {
272279
// we should insert record into not default store only of if it does not exist in default store
273-
if (($storeId == \Magento\Store\Model\Store::DEFAULT_STORE_ID && !$existInDefaultStore)
274-
|| ($storeId != \Magento\Store\Model\Store::DEFAULT_STORE_ID && !$existInCurrentStore)
280+
if (
281+
($storeId == \Magento\Store\Model\Store::DEFAULT_STORE_ID && !$existInDefaultStore) ||
282+
(
283+
$storeId != \Magento\Store\Model\Store::DEFAULT_STORE_ID &&
284+
!$existInCurrentStore &&
285+
!$isDeleteStoreTitle
286+
)
275287
) {
276288
$data = $this->_prepareDataForTable(
277289
new \Magento\Framework\DataObject(

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

+5
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,11 @@ protected function _saveValueTitles(\Magento\Framework\Model\AbstractModel $obje
237237
);
238238
$optionTypeId = $this->getConnection()->fetchOne($select);
239239
$existInCurrentStore = $this->getOptionIdFromOptionTable($titleTable, (int)$object->getId(), (int)$storeId);
240+
241+
if ($storeId != \Magento\Store\Model\Store::DEFAULT_STORE_ID && $object->getData('is_delete_store_title')) {
242+
$object->unsetData('title');
243+
}
244+
240245
if ($object->getTitle()) {
241246
if ($existInCurrentStore) {
242247
if ($storeId == $object->getStoreId()) {

0 commit comments

Comments
 (0)