Skip to content

Commit 29c6609

Browse files
author
Oleksandr Gorkun
committed
Merge branch '2.2-develop' of https://github.com/magento-qwerty/magento2ce into MAGETWO-81431
2 parents 490a4de + 6d5cf58 commit 29c6609

File tree

45 files changed

+9257
-8818
lines changed

Some content is hidden

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

45 files changed

+9257
-8818
lines changed

app/code/Magento/Braintree/view/adminhtml/web/js/braintree.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ define([
145145
_initBraintree: function () {
146146
var self = this;
147147

148+
this.disableEventListeners();
149+
148150
self.braintree.setup(self.clientToken, 'custom', {
149151
id: self.selector,
150152
hostedFields: self.getHostedFields(),
@@ -154,6 +156,7 @@ define([
154156
*/
155157
onReady: function () {
156158
$('body').trigger('processStop');
159+
self.enableEventListeners();
157160
},
158161

159162
/**

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,13 @@ protected function processNewAndExistingImages($product, array &$images)
241241
if (empty($image['removed'])) {
242242
$data = $this->processNewImage($product, $image);
243243

244-
$this->resourceModel->deleteGalleryValueInStore(
245-
$image['value_id'],
246-
$product->getData($this->metadata->getLinkField()),
247-
$product->getStoreId()
248-
);
249-
244+
if (!$product->isObjectNew()) {
245+
$this->resourceModel->deleteGalleryValueInStore(
246+
$image['value_id'],
247+
$product->getData($this->metadata->getLinkField()),
248+
$product->getStoreId()
249+
);
250+
}
250251
// Add per store labels, position, disabled
251252
$data['value_id'] = $image['value_id'];
252253
$data['label'] = isset($image['label']) ? $image['label'] : '';

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,20 @@ class SaveHandler
3030
*/
3131
private $linkResource;
3232

33-
/**
34-
* @var linkTypeProvider
35-
*/
36-
private $linkTypeProvider;
37-
3833
/**
3934
* SaveHandler constructor.
4035
* @param MetadataPool $metadataPool
4136
* @param Link $linkResource
4237
* @param ProductLinkRepositoryInterface $productLinkRepository
43-
* @param \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
4438
*/
4539
public function __construct(
4640
MetadataPool $metadataPool,
4741
Link $linkResource,
48-
ProductLinkRepositoryInterface $productLinkRepository,
49-
\Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
42+
ProductLinkRepositoryInterface $productLinkRepository
5043
) {
5144
$this->metadataPool = $metadataPool;
5245
$this->linkResource = $linkResource;
5346
$this->productLinkRepository = $productLinkRepository;
54-
$this->linkTypeProvider = $linkTypeProvider;
5547
}
5648

5749
/**

app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,10 @@ protected function _prepareLoadSelect(array $selects)
177177
protected function _saveAttributeValue($object, $attribute, $value)
178178
{
179179
$connection = $this->getConnection();
180-
$storeId = (int) $this->_storeManager->getStore($object->getStoreId())->getId();
180+
$hasSingleStore = $this->_storeManager->hasSingleStore();
181+
$storeId = $hasSingleStore
182+
? $this->getDefaultStoreId()
183+
: (int) $this->_storeManager->getStore($object->getStoreId())->getId();
181184
$table = $attribute->getBackend()->getTable();
182185

183186
/**
@@ -186,15 +189,18 @@ protected function _saveAttributeValue($object, $attribute, $value)
186189
* In this case we clear all not default values
187190
*/
188191
$entityIdField = $this->getLinkField();
189-
if ($this->_storeManager->hasSingleStore()) {
190-
$storeId = $this->getDefaultStoreId();
192+
$conditions = [
193+
'attribute_id = ?' => $attribute->getAttributeId(),
194+
"{$entityIdField} = ?" => $object->getData($entityIdField),
195+
'store_id <> ?' => $storeId
196+
];
197+
if ($hasSingleStore
198+
&& !$object->isObjectNew()
199+
&& $this->isAttributePresentForNonDefaultStore($attribute, $conditions)
200+
) {
191201
$connection->delete(
192202
$table,
193-
[
194-
'attribute_id = ?' => $attribute->getAttributeId(),
195-
"{$entityIdField} = ?" => $object->getData($entityIdField),
196-
'store_id <> ?' => $storeId
197-
]
203+
$conditions
198204
);
199205
}
200206

@@ -233,6 +239,27 @@ protected function _saveAttributeValue($object, $attribute, $value)
233239
return $this;
234240
}
235241

242+
/**
243+
* Check if attribute present for non default Store View.
244+
* Prevent "delete" query locking in a case when nothing to delete
245+
*
246+
* @param AbstractAttribute $attribute
247+
* @param array $conditions
248+
*
249+
* @return boolean
250+
*/
251+
private function isAttributePresentForNonDefaultStore($attribute, $conditions)
252+
{
253+
$connection = $this->getConnection();
254+
$select = $connection->select()->from($attribute->getBackend()->getTable());
255+
foreach ($conditions as $condition => $conditionValue) {
256+
$select->where($condition, $conditionValue);
257+
}
258+
$select->limit(1);
259+
260+
return !empty($connection->fetchRow($select));
261+
}
262+
236263
/**
237264
* Insert entity attribute value
238265
*
@@ -568,8 +595,7 @@ public function getAttributeRawValue($entityId, $attribute, $store)
568595
}
569596

570597
if (is_array($attributesData) && sizeof($attributesData) == 1) {
571-
$_data = each($attributesData);
572-
$attributesData = $_data[1];
598+
$attributesData = array_shift($attributesData);
573599
}
574600

575601
return $attributesData === false ? false : $attributesData;

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

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,12 @@ public function saveCategoryLinks(ProductInterface $product, array $categoryLink
8383
$insertUpdate = $this->processCategoryLinks($categoryLinks, $oldCategoryLinks);
8484
$deleteUpdate = $this->processCategoryLinks($oldCategoryLinks, $categoryLinks);
8585

86-
list($delete, $insert) = $this->analyseUpdatedLinks($deleteUpdate, $insertUpdate);
86+
list($delete, $insert, $update) = $this->analyseUpdatedLinks($deleteUpdate, $insertUpdate);
8787

8888
return array_merge(
89-
$this->updateCategoryLinks($product, $insert),
90-
$this->deleteCategoryLinks($product, $delete)
89+
$this->deleteCategoryLinks($product, $delete),
90+
$this->updateCategoryLinks($product, $insert, true),
91+
$this->updateCategoryLinks($product, $update)
9192
);
9293
}
9394

@@ -133,16 +134,15 @@ private function processCategoryLinks($newCategoryPositions, &$oldCategoryPositi
133134
/**
134135
* @param ProductInterface $product
135136
* @param array $insertLinks
137+
* @param bool $insert
136138
* @return array
137139
*/
138-
private function updateCategoryLinks(ProductInterface $product, array $insertLinks)
140+
private function updateCategoryLinks(ProductInterface $product, array $insertLinks, $insert = false)
139141
{
140142
if (empty($insertLinks)) {
141143
return [];
142144
}
143145

144-
$connection = $this->resourceConnection->getConnection();
145-
146146
$data = [];
147147
foreach ($insertLinks as $categoryLink) {
148148
$data[] = [
@@ -153,11 +153,22 @@ private function updateCategoryLinks(ProductInterface $product, array $insertLin
153153
}
154154

155155
if ($data) {
156-
$connection->insertOnDuplicate(
157-
$this->getCategoryLinkMetadata()->getEntityTable(),
158-
$data,
159-
['position']
160-
);
156+
$connection = $this->resourceConnection->getConnection();
157+
if ($insert) {
158+
$connection->insertArray(
159+
$this->getCategoryLinkMetadata()->getEntityTable(),
160+
array_keys($data[0]),
161+
$data,
162+
\Magento\Framework\DB\Adapter\AdapterInterface::INSERT_IGNORE
163+
);
164+
} else {
165+
// for mass update category links with constraint by unique key use insert on duplicate statement
166+
$connection->insertOnDuplicate(
167+
$this->getCategoryLinkMetadata()->getEntityTable(),
168+
$data,
169+
['position']
170+
);
171+
}
161172
}
162173

163174
return array_column($insertLinks, 'category_id');
@@ -215,7 +226,7 @@ private function verifyCategoryLinks(array $links)
215226
}
216227

217228
/**
218-
* Analyse category links for update or/and delete
229+
* Analyse category links for update or/and delete. Return array of links for delete, insert and update
219230
*
220231
* @param array $deleteUpdate
221232
* @param array $insertUpdate
@@ -226,8 +237,7 @@ private function analyseUpdatedLinks($deleteUpdate, $insertUpdate)
226237
$delete = $deleteUpdate['changed'] ?: [];
227238
$insert = $insertUpdate['changed'] ?: [];
228239
$insert = array_merge_recursive($insert, $deleteUpdate['updated']);
229-
$insert = array_merge_recursive($insert, $insertUpdate['updated']);
230240

231-
return [$delete, $insert];
241+
return [$delete, $insert, $insertUpdate['updated']];
232242
}
233243
}

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

Lines changed: 98 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Catalog\Model\ResourceModel\Product;
77

8+
use Magento\Framework\DB\Adapter\AdapterInterface;
9+
810
/**
911
* Catalog product link resource model
1012
*
@@ -136,7 +138,6 @@ public function saveProductLinks($parentId, $data, $typeId)
136138
$data = [];
137139
}
138140

139-
$attributes = $this->getAttributesByType($typeId);
140141
$connection = $this->getConnection();
141142

142143
$bind = [':product_id' => (int)$parentId, ':link_type_id' => (int)$typeId];
@@ -151,42 +152,38 @@ public function saveProductLinks($parentId, $data, $typeId)
151152

152153
$links = $connection->fetchPairs($select, $bind);
153154

154-
foreach ($data as $linkedProductId => $linkInfo) {
155-
$linkId = null;
156-
if (isset($links[$linkedProductId])) {
157-
$linkId = $links[$linkedProductId];
158-
unset($links[$linkedProductId]);
159-
} else {
160-
$bind = [
161-
'product_id' => $parentId,
162-
'linked_product_id' => $linkedProductId,
163-
'link_type_id' => $typeId,
164-
];
165-
$connection->insert($this->getMainTable(), $bind);
166-
$linkId = $connection->lastInsertId($this->getMainTable());
167-
}
155+
list($insertData, $updateData, $deleteConditions) = $this->prepareProductLinksData(
156+
$parentId,
157+
$data,
158+
$typeId,
159+
$links
160+
);
168161

169-
foreach ($attributes as $attributeInfo) {
170-
$attributeTable = $this->getAttributeTypeTable($attributeInfo['type']);
171-
if ($attributeTable) {
172-
if (isset($linkInfo[$attributeInfo['code']])) {
173-
$value = $this->_prepareAttributeValue(
174-
$attributeInfo['type'],
175-
$linkInfo[$attributeInfo['code']]
176-
);
177-
$bind = [
178-
'product_link_attribute_id' => $attributeInfo['id'],
179-
'link_id' => $linkId,
180-
'value' => $value,
181-
];
182-
$connection->insertOnDuplicate($attributeTable, $bind, ['value']);
183-
} else {
184-
$connection->delete(
185-
$attributeTable,
186-
['link_id = ?' => $linkId, 'product_link_attribute_id = ?' => $attributeInfo['id']]
187-
);
188-
}
189-
}
162+
if ($insertData) {
163+
$insertColumns = [
164+
'product_link_attribute_id',
165+
'link_id',
166+
'value',
167+
];
168+
foreach ($insertData as $table => $values) {
169+
$connection->insertArray($table, $insertColumns, $values, AdapterInterface::INSERT_IGNORE);
170+
}
171+
}
172+
if ($updateData) {
173+
// for mass update product links with constraint by unique key use insert on duplicate statement
174+
foreach ($updateData as $table => $values) {
175+
$connection->insertOnDuplicate($table, $values, ['value']);
176+
}
177+
}
178+
if ($deleteConditions) {
179+
foreach ($deleteConditions as $table => $deleteCondition) {
180+
$connection->delete(
181+
$table,
182+
[
183+
'link_id = ?' => $deleteCondition['link_id'],
184+
'product_link_attribute_id = ?' => $deleteCondition['product_link_attribute_id']
185+
]
186+
);
190187
}
191188
}
192189

@@ -302,4 +299,69 @@ public function getParentIdsByChild($childId, $typeId)
302299

303300
return $parentIds;
304301
}
302+
303+
/**
304+
* Prepare data for insert, update or delete product link attributes
305+
*
306+
* @param int $parentId
307+
* @param array $data
308+
* @param int $typeId
309+
* @param array $links
310+
* @return array
311+
*/
312+
private function prepareProductLinksData($parentId, $data, $typeId, $links)
313+
{
314+
$connection = $this->getConnection();
315+
$attributes = $this->getAttributesByType($typeId);
316+
317+
$insertData = [];
318+
$updateData = [];
319+
$deleteConditions = [];
320+
321+
foreach ($data as $linkedProductId => $linkInfo) {
322+
$linkId = null;
323+
if (isset($links[$linkedProductId])) {
324+
$linkId = $links[$linkedProductId];
325+
} else {
326+
$bind = [
327+
'product_id' => $parentId,
328+
'linked_product_id' => $linkedProductId,
329+
'link_type_id' => $typeId,
330+
];
331+
$connection->insert($this->getMainTable(), $bind);
332+
$linkId = $connection->lastInsertId($this->getMainTable());
333+
}
334+
335+
foreach ($attributes as $attributeInfo) {
336+
$attributeTable = $this->getAttributeTypeTable($attributeInfo['type']);
337+
if (!$attributeTable) {
338+
continue;
339+
}
340+
if (isset($linkInfo[$attributeInfo['code']])) {
341+
$value = $this->_prepareAttributeValue(
342+
$attributeInfo['type'],
343+
$linkInfo[$attributeInfo['code']]
344+
);
345+
if (isset($links[$linkedProductId])) {
346+
$updateData[$attributeTable][] = [
347+
'product_link_attribute_id' => $attributeInfo['id'],
348+
'link_id' => $linkId,
349+
'value' => $value,
350+
];
351+
} else {
352+
$insertData[$attributeTable][] = [
353+
'product_link_attribute_id' => $attributeInfo['id'],
354+
'link_id' => $linkId,
355+
'value' => $value,
356+
];
357+
}
358+
} else {
359+
$deleteConditions[$attributeTable]['link_id'][] = $linkId;
360+
$deleteConditions[$attributeTable]['product_link_attribute_id'][] = $attributeInfo['id'];
361+
}
362+
}
363+
}
364+
365+
return [$insertData, $updateData, $deleteConditions];
366+
}
305367
}

0 commit comments

Comments
 (0)