Skip to content

Commit 944adbf

Browse files
author
Mohammad HAJ SALEM
committed
🐛 add fallback for Product_links position attribute if position index was not set in API request
1 parent b9ab1ea commit 944adbf

File tree

1 file changed

+70
-3
lines changed

1 file changed

+70
-3
lines changed

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

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,28 @@ class SaveHandler
3131
private $linkResource;
3232

3333
/**
34+
* @var linkTypeProvider
35+
*/
36+
private $linkTypeProvider;
37+
38+
/**
39+
* SaveHandler constructor.
3440
* @param MetadataPool $metadataPool
3541
* @param Link $linkResource
3642
* @param ProductLinkRepositoryInterface $productLinkRepository
43+
* @param \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
3744
*/
3845
public function __construct(
3946
MetadataPool $metadataPool,
4047
Link $linkResource,
41-
ProductLinkRepositoryInterface $productLinkRepository
42-
) {
48+
ProductLinkRepositoryInterface $productLinkRepository,
49+
\Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
50+
)
51+
{
4352
$this->metadataPool = $metadataPool;
4453
$this->linkResource = $linkResource;
4554
$this->productLinkRepository = $productLinkRepository;
55+
$this->linkTypeProvider = $linkTypeProvider;
4656
}
4757

4858
/**
@@ -55,17 +65,74 @@ public function execute($entityType, $entity)
5565
{
5666
$link = $entity->getData($this->metadataPool->getMetadata($entityType)->getLinkField());
5767
if ($this->linkResource->hasProductLinks($link)) {
58-
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity*/
68+
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
5969
foreach ($this->productLinkRepository->getList($entity) as $link) {
6070
$this->productLinkRepository->delete($link);
6171
}
6272
}
6373
$productLinks = $entity->getProductLinks();
74+
75+
// Build links per type
76+
$linksByType = [];
77+
foreach ($productLinks as $link) {
78+
$linksByType[$link->getLinkType()][] = $link;
79+
}
80+
81+
// Do check
82+
$hasPositionLinkType = $this->isPositionsSet($linksByType);
83+
84+
85+
// Bug fix for API if the Position was not set to force set Position attribute in "catalog_product_link_attribute_int"
86+
// set Positions attribute values
87+
foreach ($hasPositionLinkType as $linkType => $hasPosition) {
88+
if (!$hasPosition) {
89+
array_walk($linksByType[$linkType], function ($productLink, $position) {
90+
$productLink->setPosition(++$position);
91+
});
92+
}
93+
}
94+
95+
// Flatten multi-dimensional linksByType in ProductLinks
96+
$productLinks = array_reduce($linksByType, 'array_merge', []);
97+
6498
if (count($productLinks) > 0) {
6599
foreach ($entity->getProductLinks() as $link) {
66100
$this->productLinkRepository->save($link);
67101
}
68102
}
69103
return $entity;
70104
}
105+
106+
/**
107+
* Check if the position is set for all product links per link type.
108+
* array with boolean per type
109+
*
110+
* @param $linksByType
111+
* @return array
112+
*/
113+
private function isPositionsSet($linksByType)
114+
{
115+
$linkTypes = $this->linkTypeProvider->getLinkTypes();
116+
117+
// Initialize isPositionSet for existent link types
118+
$isPositionSet = [];
119+
foreach (array_keys($linkTypes) as $typeName) {
120+
if (array_key_exists($typeName, $linksByType)) {
121+
$isPositionSet[$typeName] = count($linksByType[$typeName]) > 0;
122+
}
123+
}
124+
125+
126+
// Check if at least on link without position exists per Link type
127+
foreach ($linksByType as $type => $links) {
128+
foreach ($links as $link) {
129+
if (!array_key_exists('position', $link->getData())) {
130+
$isPositionSet[$type] = false;
131+
break;
132+
}
133+
}
134+
}
135+
136+
return $isPositionSet;
137+
}
71138
}

0 commit comments

Comments
 (0)