Skip to content

Commit 596e727

Browse files
committed
Merge remote-tracking branch 'mainline/develop' into MAGETWO-59264
2 parents 7f52ffe + 36b07c7 commit 596e727

File tree

93 files changed

+4075
-759
lines changed

Some content is hidden

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

93 files changed

+4075
-759
lines changed

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

Lines changed: 12 additions & 5 deletions
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/Indexer/Product/Flat/FlatTableBuilder.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,11 @@ protected function _fillTemporaryFlatTable(array $tables, $storeId, $valueFieldS
221221

222222
unset($tables[$entityTableName]);
223223

224-
$allColumns = array_merge(['entity_id', 'type_id', 'attribute_set_id'], $columnsList);
224+
$allColumns = array_values(
225+
array_unique(
226+
array_merge(['entity_id', $linkField, 'type_id', 'attribute_set_id'], $columnsList)
227+
)
228+
);
225229

226230
/* @var $status \Magento\Eav\Model\Entity\Attribute */
227231
$status = $this->_productIndexerHelper->getAttribute('status');
@@ -263,7 +267,7 @@ protected function _fillTemporaryFlatTable(array $tables, $storeId, $valueFieldS
263267

264268
$select->joinLeft(
265269
$temporaryTableName,
266-
"e.entity_id = " . $temporaryTableName . ".entity_id",
270+
sprintf('e.%1$s = %2$s.%1$s', $linkField, $temporaryTableName),
267271
$columnsNames
268272
);
269273
$allColumns = array_merge($allColumns, $columnsNames);
@@ -277,7 +281,7 @@ protected function _fillTemporaryFlatTable(array $tables, $storeId, $valueFieldS
277281
if (!empty($columnValueNames)) {
278282
$select->joinLeft(
279283
$temporaryValueTableName,
280-
"e.${linkField} = " . $temporaryValueTableName . ".entity_id",
284+
sprintf('e.%1$s = %2$s.%1$s', $linkField, $temporaryTableName),
281285
$columnValueNames
282286
);
283287
$allColumns = array_merge($allColumns, $columnValueNames);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Model\Indexer\Product\Flat\Table;
7+
8+
/**
9+
* Class Builder
10+
*/
11+
class Builder implements BuilderInterface
12+
{
13+
/**
14+
* @var \Magento\Framework\DB\Ddl\Table
15+
*/
16+
private $tableInstance;
17+
18+
/**
19+
* Builder constructor.
20+
*
21+
* @param \Magento\Framework\DB\Adapter\AdapterInterface $connection
22+
* @param string $tableName
23+
*/
24+
public function __construct(\Magento\Framework\DB\Adapter\AdapterInterface $connection, $tableName)
25+
{
26+
$this->tableInstance = $connection->newTable($tableName);
27+
}
28+
29+
/**
30+
* @inheritdoc
31+
*/
32+
public function addColumn($name, $type, $size = null, $options = [], $comment = null)
33+
{
34+
$this->tableInstance->addColumn($name, $type, $size, $options, $comment);
35+
return $this;
36+
}
37+
38+
/**
39+
* @inheritdoc
40+
*/
41+
public function getTable()
42+
{
43+
return $this->tableInstance;
44+
}
45+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Model\Indexer\Product\Flat\Table;
7+
8+
/**
9+
* Interface BuilderInterface
10+
*/
11+
interface BuilderInterface
12+
{
13+
/**
14+
* Adds column to table.
15+
*
16+
* $options contains additional options for columns. Supported values are:
17+
* - 'unsigned', for number types only. Default: FALSE.
18+
* - 'precision', for numeric and decimal only. Default: taken from $size, if not set there then 0.
19+
* - 'scale', for numeric and decimal only. Default: taken from $size, if not set there then 10.
20+
* - 'default'. Default: not set.
21+
* - 'nullable'. Default: TRUE.
22+
* - 'primary', add column to primary index. Default: do not add.
23+
* - 'primary_position', only for column in primary index. Default: count of primary columns + 1.
24+
* - 'identity' or 'auto_increment'. Default: FALSE.
25+
*
26+
* @param string $name the column name
27+
* @param string $type the column data type
28+
* @param string|int|array $size the column length
29+
* @param array $options array of additional options
30+
* @param string $comment column description
31+
* @return $this
32+
* @throws \Zend_Db_Exception
33+
*/
34+
public function addColumn($name, $type, $size = null, $options = [], $comment = null);
35+
36+
/**
37+
* @return \Magento\Framework\DB\Ddl\Table
38+
*/
39+
public function getTable();
40+
}

app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
namespace Magento\Catalog\Model\Indexer\Product\Flat;
77

8-
use Magento\Framework\App\ResourceConnection;
8+
use Magento\Catalog\Model\Indexer\Product\Flat\Table\BuilderInterfaceFactory;
99

1010
/**
1111
* Class TableBuilder
@@ -32,6 +32,11 @@ class TableBuilder
3232
*/
3333
protected $resource;
3434

35+
/**
36+
* @var BuilderInterfaceFactory
37+
*/
38+
private $tableBuilderFactory;
39+
3540
/**
3641
* Check whether builder was executed
3742
*
@@ -123,17 +128,27 @@ protected function _createTemporaryTable($tableName, array $columns, $valueField
123128
$valueTables = [];
124129
if (!empty($columns)) {
125130
$valueTableName = $tableName . $valueFieldSuffix;
126-
$temporaryTable = $this->_connection->newTable($tableName);
127-
$valueTemporaryTable = $this->_connection->newTable($valueTableName);
131+
$temporaryTableBuilder = $this->getTableBuilderFactory()->create(
132+
[
133+
'connection' => $this->_connection,
134+
'tableName' => $tableName
135+
]
136+
);
137+
$valueTemporaryTableBuilder = $this->getTableBuilderFactory()->create(
138+
[
139+
'connection' => $this->_connection,
140+
'tableName' => $valueTableName
141+
]
142+
);
128143
$flatColumns = $this->_productIndexerHelper->getFlatColumns();
129144

130-
$temporaryTable->addColumn('entity_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
145+
$temporaryTableBuilder->addColumn('entity_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
131146

132-
$temporaryTable->addColumn('type_id', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT);
147+
$temporaryTableBuilder->addColumn('type_id', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT);
133148

134-
$temporaryTable->addColumn('attribute_set_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
149+
$temporaryTableBuilder->addColumn('attribute_set_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
135150

136-
$valueTemporaryTable->addColumn('entity_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
151+
$valueTemporaryTableBuilder->addColumn('entity_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
137152

138153
/** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
139154
foreach ($columns as $columnName => $attribute) {
@@ -145,7 +160,7 @@ protected function _createTemporaryTable($tableName, array $columns, $valueField
145160
$column = $column[$attributeCode];
146161
}
147162

148-
$temporaryTable->addColumn(
163+
$temporaryTableBuilder->addColumn(
149164
$columnName,
150165
$column['type'],
151166
isset($column['length']) ? $column['length'] : null
@@ -154,19 +169,19 @@ protected function _createTemporaryTable($tableName, array $columns, $valueField
154169
$columnValueName = $attributeCode . $valueFieldSuffix;
155170
if (isset($flatColumns[$columnValueName])) {
156171
$columnValue = $flatColumns[$columnValueName];
157-
$valueTemporaryTable->addColumn(
172+
$valueTemporaryTableBuilder->addColumn(
158173
$columnValueName,
159174
$columnValue['type'],
160175
isset($columnValue['length']) ? $columnValue['length'] : null
161176
);
162177
}
163178
}
164179
$this->_connection->dropTemporaryTable($tableName);
165-
$this->_connection->createTemporaryTable($temporaryTable);
180+
$this->_connection->createTemporaryTable($temporaryTableBuilder->getTable());
166181

167-
if (count($valueTemporaryTable->getColumns()) > 1) {
182+
if (count($valueTemporaryTableBuilder->getTable()->getColumns()) > 1) {
168183
$this->_connection->dropTemporaryTable($valueTableName);
169-
$this->_connection->createTemporaryTable($valueTemporaryTable);
184+
$this->_connection->createTemporaryTable($valueTemporaryTableBuilder->getTable());
170185
$valueTables[$valueTableName] = $valueTableName;
171186
}
172187
}
@@ -197,7 +212,8 @@ protected function _fillTemporaryEntityTable($tableName, array $columns, array $
197212
if (!empty($columns)) {
198213
$select = $this->_connection->select();
199214
$temporaryEntityTable = $this->_getTemporaryTableName($tableName);
200-
$idsColumns = ['entity_id', 'type_id', 'attribute_set_id'];
215+
$metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
216+
$idsColumns = array_unique([$metadata->getLinkField(), 'entity_id', 'type_id', 'attribute_set_id']);
201217

202218
$columns = array_merge($idsColumns, array_keys($columns));
203219

@@ -261,7 +277,7 @@ protected function _fillTemporaryTable(
261277
);
262278
$temporaryTableName = $this->_getTemporaryTableName($tableName);
263279
$temporaryValueTableName = $temporaryTableName . $valueFieldSuffix;
264-
$keyColumn = ['entity_id'];
280+
$keyColumn = array_unique([$metadata->getLinkField(), 'entity_id']);
265281
$columns = array_merge($keyColumn, array_keys($columnsList));
266282
$valueColumns = $keyColumn;
267283
$flatColumns = $this->_productIndexerHelper->getFlatColumns();
@@ -333,6 +349,19 @@ protected function _fillTemporaryTable(
333349
}
334350
}
335351

352+
/**
353+
* @return BuilderInterfaceFactory
354+
*/
355+
private function getTableBuilderFactory()
356+
{
357+
if (null === $this->tableBuilderFactory) {
358+
$this->tableBuilderFactory = \Magento\Framework\App\ObjectManager::getInstance()
359+
->get(BuilderInterfaceFactory::class);
360+
}
361+
362+
return $this->tableBuilderFactory;
363+
}
364+
336365
/**
337366
* @return \Magento\Framework\EntityManager\MetadataPool
338367
*/

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

Lines changed: 7 additions & 6 deletions
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

Lines changed: 24 additions & 1 deletion
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

Lines changed: 16 additions & 4 deletions
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
}

0 commit comments

Comments
 (0)