diff --git a/app/code/Magento/Catalog/Model/Product/Link/SaveHandler.php b/app/code/Magento/Catalog/Model/Product/Link/SaveHandler.php index 13c6a13a50407..6d053537a659e 100644 --- a/app/code/Magento/Catalog/Model/Product/Link/SaveHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Link/SaveHandler.php @@ -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; } /** @@ -55,12 +64,30 @@ 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); @@ -68,4 +95,19 @@ public function execute($entityType, $entity) } 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; + } }