Skip to content
Merged
48 changes: 45 additions & 3 deletions app/code/Magento/Catalog/Model/Product/Link/SaveHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,27 @@ class SaveHandler
private $linkResource;

/**
* @var linkTypeProvider
*/
private $linkTypeProvider;

/**
* SaveHandler constructor.
* @param MetadataPool $metadataPool
* @param Link $linkResource
* @param ProductLinkRepositoryInterface $productLinkRepository
* @param \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
*/
public function __construct(
MetadataPool $metadataPool,
Link $linkResource,
ProductLinkRepositoryInterface $productLinkRepository
ProductLinkRepositoryInterface $productLinkRepository,
\Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
) {
$this->metadataPool = $metadataPool;
$this->linkResource = $linkResource;
$this->productLinkRepository = $productLinkRepository;
$this->linkTypeProvider = $linkTypeProvider;
}

/**
Expand All @@ -55,17 +64,50 @@ public function execute($entityType, $entity)
{
$link = $entity->getData($this->metadataPool->getMetadata($entityType)->getLinkField());
if ($this->linkResource->hasProductLinks($link)) {
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity*/
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
foreach ($this->productLinkRepository->getList($entity) as $link) {
$this->productLinkRepository->delete($link);
}
}
$productLinks = $entity->getProductLinks();

// Build links per type
$linksByType = [];
foreach ($entity->getProductLinks() as $link) {
$linksByType[$link->getLinkType()][] = $link;
}

// Set array position as a fallback position if necessary
foreach ($linksByType as $linkType => $links) {
if (!$this->hasPosition($links)) {
array_walk($linksByType[$linkType], function ($productLink, $position) {
$productLink->setPosition(++$position);
});
}
}

// Flatten multi-dimensional linksByType in ProductLinks
$productLinks = array_reduce($linksByType, 'array_merge', []);

if (count($productLinks) > 0) {
foreach ($entity->getProductLinks() as $link) {
$this->productLinkRepository->save($link);
}
}
return $entity;
}

/**
* Check if at least one link without position
* @param array $links
* @return bool
*/
private function hasPosition(array $links)
{
foreach ($links as $link) {
if (!array_key_exists('position', $link->getData())) {
return false;
}
}
return true;
}
}