Skip to content

Commit c6728de

Browse files
committed
MAGETWO-70287: [Backport] - Category edit performance issue - for 2.1
- Update logic for url rewrites;
1 parent 92b0911 commit c6728de

File tree

5 files changed

+46
-36
lines changed

5 files changed

+46
-36
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
* @method Category setUrlPath(string $urlPath)
2828
* @method Category getSkipDeleteChildren()
2929
* @method Category setSkipDeleteChildren(boolean $value)
30+
* @method Category setChangedProductIds(array $categoryIds) Set products ids that inserted or deleted for category
31+
* @method array getChangedProductIds() Get products ids that inserted or deleted for category
3032
*
3133
* @SuppressWarnings(PHPMD.LongVariable)
3234
* @SuppressWarnings(PHPMD.ExcessivePublicCount)

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,9 +409,18 @@ protected function _saveCategoryProducts($category)
409409
* Update product positions in category
410410
*/
411411
if (!empty($update)) {
412+
$newPositions = [];
412413
foreach ($update as $productId => $position) {
413-
$where = ['category_id = ?' => (int)$id, 'product_id = ?' => (int)$productId];
414-
$bind = ['position' => (int)$position];
414+
$delta = $position - $oldProducts[$productId];
415+
if (!isset($newPositions[$delta])) {
416+
$newPositions[$delta] = [];
417+
}
418+
$newPositions[$delta][] = $productId;
419+
}
420+
421+
foreach ($newPositions as $delta => $productIds) {
422+
$bind = ['position' => new \Zend_Db_Expr("position + ({$delta})")];
423+
$where = ['category_id = ?' => (int)$id, 'product_id IN (?)' => $productIds];
415424
$connection->update($this->getCategoryProductTable(), $bind, $where);
416425
}
417426
}
@@ -422,6 +431,8 @@ protected function _saveCategoryProducts($category)
422431
'catalog_category_change_products',
423432
['category' => $category, 'product_ids' => $productIds]
424433
);
434+
435+
$category->setChangedProductIds($productIds);
425436
}
426437

427438
if (!empty($insert) || !empty($update) || !empty($delete)) {

app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,12 @@ public function execute(\Magento\Framework\Event\Observer $observer)
9191
}
9292
if ($category->dataHasChangedFor('url_key')
9393
|| $category->dataHasChangedFor('is_anchor')
94-
|| $category->getIsChangedProductList()
94+
|| $category->getChangedProductIds()
9595
) {
96-
$categoryUrlRewriteResult = $this->categoryUrlRewriteGenerator->generate($category);
97-
$this->urlRewriteBunchReplacer->doBunchReplace($categoryUrlRewriteResult);
96+
if ($category->dataHasChangedFor('url_key')) {
97+
$categoryUrlRewriteResult = $this->categoryUrlRewriteGenerator->generate($category);
98+
$this->urlRewriteBunchReplacer->doBunchReplace($categoryUrlRewriteResult);
99+
}
98100

99101
$productUrlRewriteResult = $this->urlRewriteHandler->generateProductUrlRewrites($category);
100102
$this->urlRewriteBunchReplacer->doBunchReplace($productUrlRewriteResult);

app/code/Magento/CatalogUrlRewrite/Observer/UrlRewriteHandler.php

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -87,36 +87,31 @@ public function generateProductUrlRewrites(Category $category)
8787
$this->isSkippedProduct = [];
8888
$saveRewriteHistory = $category->getData('save_rewrites_history');
8989
$storeId = $category->getStoreId();
90-
if ($category->dataHasChangedFor('name')
91-
|| $category->dataHasChangedFor('url_key')
92-
|| $category->dataHasChangedFor('url_path')
93-
) {
94-
if ($category->getAffectedProductIds()) {
95-
$this->isSkippedProduct = $category->getAffectedProductIds();
96-
$collection = $this->productCollectionFactory->create()
97-
->setStoreId($storeId)
98-
->addIdFilter($category->getAffectedProductIds())
99-
->addAttributeToSelect('visibility')
100-
->addAttributeToSelect('name')
101-
->addAttributeToSelect('url_key')
102-
->addAttributeToSelect('url_path');
103-
foreach ($collection as $product) {
104-
$product->setStoreId($storeId);
105-
$product->setData('save_rewrites_history', $saveRewriteHistory);
106-
$mergeDataProvider->merge(
107-
$this->productUrlRewriteGenerator->generate($product, $category->getEntityId())
108-
);
109-
}
110-
} else {
90+
if ($category->getChangedProductIds()) {
91+
$this->isSkippedProduct = $category->getAffectedProductIds();
92+
$collection = $this->productCollectionFactory->create()
93+
->setStoreId($storeId)
94+
->addIdFilter($category->getAffectedProductIds())
95+
->addAttributeToSelect('visibility')
96+
->addAttributeToSelect('name')
97+
->addAttributeToSelect('url_key')
98+
->addAttributeToSelect('url_path');
99+
foreach ($collection as $product) {
100+
$product->setStoreId($storeId);
101+
$product->setData('save_rewrites_history', $saveRewriteHistory);
111102
$mergeDataProvider->merge(
112-
$this->getCategoryProductsUrlRewrites(
113-
$category,
114-
$storeId,
115-
$saveRewriteHistory,
116-
$category->getEntityId()
117-
)
103+
$this->productUrlRewriteGenerator->generate($product, $category->getEntityId())
118104
);
119105
}
106+
} else {
107+
$mergeDataProvider->merge(
108+
$this->getCategoryProductsUrlRewrites(
109+
$category,
110+
$storeId,
111+
$saveRewriteHistory,
112+
$category->getEntityId()
113+
)
114+
);
120115
}
121116
foreach ($this->childrenCategoriesProvider->getChildren($category, true) as $childCategory) {
122117
$mergeDataProvider->merge(

app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/UrlRewriteHandlerTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,12 @@ protected function setUp()
9292
->setMethods(
9393
[
9494
'getAffectedProductIds',
95+
'getChangedProductIds',
9596
'getData',
9697
'getStoreId',
9798
'getEntityId',
9899
'getId',
99100
'getProductCollection',
100-
'dataHasChangedFor'
101101
]
102102
)
103103
->disableOriginalConstructor()
@@ -196,12 +196,12 @@ public function testGenerateProductUrlRewrites($affectedProductIds)
196196
$this->categoryMock->expects($this->once())
197197
->method('getStoreId')
198198
->willReturn($storeId);
199-
$this->categoryMock->expects($this->atLeastOnce())
200-
->method('dataHasChangedFor')
201-
->willReturn('true');
202199
$this->categoryMock->expects($this->any())
203200
->method('getAffectedProductIds')
204201
->willReturn($affectedProductIds);
202+
$this->categoryMock->expects($this->any())
203+
->method('getChangedProductIds')
204+
->willReturn($affectedProductIds);
205205
$this->categoryMock->expects($this->once())
206206
->method('getEntityId')
207207
->willReturn($categoryId);

0 commit comments

Comments
 (0)