Skip to content

Commit 425d54a

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-96290' into 2.3-develop-pr12
2 parents b842b86 + fe68f5b commit 425d54a

File tree

3 files changed

+163
-21
lines changed

3 files changed

+163
-21
lines changed

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

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
namespace Magento\Catalog\Model\Category\Link;
77

88
use Magento\Catalog\Api\Data\CategoryLinkInterface;
9-
use Magento\Catalog\Model\Indexer\Product\Category;
109
use Magento\Framework\EntityManager\Operation\ExtensionInterface;
1110

1211
/**
@@ -40,6 +39,8 @@ public function __construct(
4039
}
4140

4241
/**
42+
* Execute
43+
*
4344
* @param object $entity
4445
* @param array $arguments
4546
* @return object
@@ -78,6 +79,8 @@ public function execute($entity, $arguments = [])
7879
}
7980

8081
/**
82+
* Get category links positions
83+
*
8184
* @param object $entity
8285
* @return array
8386
*/
@@ -106,27 +109,19 @@ private function getCategoryLinksPositions($entity)
106109
*/
107110
private function mergeCategoryLinks($newCategoryPositions, $oldCategoryPositions)
108111
{
109-
$result = [];
110112
if (empty($newCategoryPositions)) {
111-
return $result;
113+
return [];
112114
}
113115

116+
$categoryPositions = array_combine(array_column($oldCategoryPositions, 'category_id'), $oldCategoryPositions);
114117
foreach ($newCategoryPositions as $newCategoryPosition) {
115-
$key = array_search(
116-
$newCategoryPosition['category_id'],
117-
array_column($oldCategoryPositions, 'category_id')
118-
);
119-
120-
if ($key === false) {
121-
$result[] = $newCategoryPosition;
122-
} elseif (isset($oldCategoryPositions[$key])
123-
&& $oldCategoryPositions[$key]['position'] != $newCategoryPosition['position']
124-
) {
125-
$result[] = $newCategoryPositions[$key];
126-
unset($oldCategoryPositions[$key]);
118+
$categoryId = $newCategoryPosition['category_id'];
119+
if (!isset($categoryPositions[$categoryId])) {
120+
$categoryPositions[$categoryId] = ['category_id' => $categoryId];
127121
}
122+
$categoryPositions[$categoryId]['position'] = $newCategoryPosition['position'];
128123
}
129-
$result = array_merge($result, $oldCategoryPositions);
124+
$result = array_values($categoryPositions);
130125

131126
return $result;
132127
}

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ public function saveCategoryLinks(ProductInterface $product, array $categoryLink
9393
}
9494

9595
/**
96+
* Get category link metadata
97+
*
9698
* @return \Magento\Framework\EntityManager\EntityMetadataInterface
9799
*/
98100
private function getCategoryLinkMetadata()
@@ -114,16 +116,16 @@ private function getCategoryLinkMetadata()
114116
private function processCategoryLinks($newCategoryPositions, &$oldCategoryPositions)
115117
{
116118
$result = ['changed' => [], 'updated' => []];
119+
120+
$oldCategoryPositions = array_values($oldCategoryPositions);
121+
$oldCategoryList = array_column($oldCategoryPositions, 'category_id');
117122
foreach ($newCategoryPositions as $newCategoryPosition) {
118-
$key = array_search(
119-
$newCategoryPosition['category_id'],
120-
array_column($oldCategoryPositions, 'category_id')
121-
);
123+
$key = array_search($newCategoryPosition['category_id'], $oldCategoryList);
122124

123125
if ($key === false) {
124126
$result['changed'][] = $newCategoryPosition;
125127
} elseif ($oldCategoryPositions[$key]['position'] != $newCategoryPosition['position']) {
126-
$result['updated'][] = $newCategoryPositions[$key];
128+
$result['updated'][] = $newCategoryPosition;
127129
unset($oldCategoryPositions[$key]);
128130
}
129131
}
@@ -132,6 +134,8 @@ private function processCategoryLinks($newCategoryPositions, &$oldCategoryPositi
132134
}
133135

134136
/**
137+
* Update category links
138+
*
135139
* @param ProductInterface $product
136140
* @param array $insertLinks
137141
* @param bool $insert
@@ -175,6 +179,8 @@ private function updateCategoryLinks(ProductInterface $product, array $insertLin
175179
}
176180

177181
/**
182+
* Delete category links
183+
*
178184
* @param ProductInterface $product
179185
* @param array $deleteLinks
180186
* @return array
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Model\Category\Link;
9+
10+
use Magento\Catalog\Api\Data\CategoryLinkInterfaceFactory;
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\Catalog\Api\ProductRepositoryInterface;
13+
use Magento\Framework\EntityManager\MetadataPool;
14+
use Magento\TestFramework\Helper\Bootstrap;
15+
use PHPUnit\Framework\TestCase;
16+
17+
/**
18+
* Save handler test
19+
*
20+
* @magentoDataFixture Magento/Catalog/_files/categories_no_products.php
21+
* @magentoDataFixture Magento/Catalog/_files/second_product_simple.php
22+
*/
23+
class SaveHandlerTest extends TestCase
24+
{
25+
/**
26+
* @var ProductRepositoryInterface
27+
*/
28+
private $productRepository;
29+
30+
/**
31+
* @var string
32+
*/
33+
private $productLinkField;
34+
35+
/**
36+
* @var CategoryLinkInterfaceFactory
37+
*/
38+
private $categoryLinkFactory;
39+
40+
/**
41+
* @var SaveHandler
42+
*/
43+
private $saveHandler;
44+
45+
/**
46+
* @inheritdoc
47+
*/
48+
protected function setUp()
49+
{
50+
$objectManager = Bootstrap::getObjectManager();
51+
$this->productRepository = $objectManager->create(ProductRepositoryInterface::class);
52+
$metadataPool = $objectManager->create(MetadataPool::class);
53+
$this->productLinkField = $metadataPool->getMetadata(ProductInterface::class)
54+
->getLinkField();
55+
$this->categoryLinkFactory = $objectManager->create(CategoryLinkInterfaceFactory::class);
56+
$this->saveHandler = $objectManager->create(SaveHandler::class);
57+
}
58+
59+
/**
60+
* Execute test
61+
*
62+
* @return void
63+
*/
64+
public function testExecute(): void
65+
{
66+
$product = $this->productRepository->get('simple2');
67+
$product->setCategoryIds([3, 4, 6]);
68+
$this->productRepository->save($product);
69+
$categoryPositions = [
70+
3 => [
71+
'category_id' => 3,
72+
'position' => 0,
73+
],
74+
4 => [
75+
'category_id' => 4,
76+
'position' => 0,
77+
],
78+
6 => [
79+
'category_id' => 6,
80+
'position' => 0,
81+
],
82+
];
83+
84+
$categoryLinks = $product->getExtensionAttributes()->getCategoryLinks();
85+
$this->assertEmpty($categoryLinks);
86+
87+
$categoryLinks = [];
88+
$categoryPositions[4]['position'] = 1;
89+
$categoryPositions[6]['position'] = 1;
90+
foreach ($categoryPositions as $categoryPosition) {
91+
$categoryLink = $this->categoryLinkFactory->create()
92+
->setCategoryId($categoryPosition['category_id'])
93+
->setPosition($categoryPosition['position']);
94+
$categoryLinks[] = $categoryLink;
95+
}
96+
$categoryLinks = $this->updateCategoryLinks($product, $categoryLinks);
97+
$this->assertPositions($categoryPositions, $categoryLinks);
98+
99+
$categoryPositions[4]['position'] = 2;
100+
$categoryLink = $this->categoryLinkFactory->create()
101+
->setCategoryId(4)
102+
->setPosition($categoryPositions[4]['position']);
103+
$categoryLinks = $this->updateCategoryLinks($product, [$categoryLink]);
104+
$this->assertPositions($categoryPositions, $categoryLinks);
105+
}
106+
107+
/**
108+
* Update category links
109+
*
110+
* @param ProductInterface $product
111+
* @param \Magento\Catalog\Api\Data\CategoryLinkInterface[] $categoryLinks
112+
* @return \Magento\Catalog\Api\Data\CategoryLinkInterface[]
113+
*/
114+
private function updateCategoryLinks(ProductInterface $product, array $categoryLinks): array
115+
{
116+
$product->getExtensionAttributes()->setCategoryLinks($categoryLinks);
117+
$arguments = [$this->productLinkField => $product->getData($this->productLinkField)];
118+
$this->saveHandler->execute($product, $arguments);
119+
$product = $this->productRepository->get($product->getSku(), false, null, true);
120+
$categoryLinks = $product->getExtensionAttributes()
121+
->getCategoryLinks();
122+
123+
return $categoryLinks;
124+
}
125+
126+
/**
127+
* Assert positions
128+
*
129+
* @param array $categoryPositions
130+
* @param array $categoryLinks
131+
* @return void
132+
*/
133+
private function assertPositions(array $categoryPositions, array $categoryLinks): void
134+
{
135+
foreach ($categoryLinks as $categoryLink) {
136+
$categoryPosition = $categoryPositions[$categoryLink->getCategoryId()];
137+
$this->assertEquals($categoryPosition['category_id'], $categoryLink->getCategoryId());
138+
$this->assertEquals($categoryPosition['position'], $categoryLink->getPosition());
139+
}
140+
}
141+
}

0 commit comments

Comments
 (0)