@@ -31,6 +31,7 @@ class SaveHandler
3131 private $ linkResource ;
3232
3333 /**
34+ * SaveHandler constructor.
3435 * @param MetadataPool $metadataPool
3536 * @param Link $linkResource
3637 * @param ProductLinkRepositoryInterface $productLinkRepository
@@ -55,17 +56,50 @@ public function execute($entityType, $entity)
5556 {
5657 $ link = $ entity ->getData ($ this ->metadataPool ->getMetadata ($ entityType )->getLinkField ());
5758 if ($ this ->linkResource ->hasProductLinks ($ link )) {
58- /** @var \Magento\Catalog\Api\Data\ProductInterface $entity*/
59+ /** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
5960 foreach ($ this ->productLinkRepository ->getList ($ entity ) as $ link ) {
6061 $ this ->productLinkRepository ->delete ($ link );
6162 }
6263 }
63- $ productLinks = $ entity ->getProductLinks ();
64+
65+ // Build links per type
66+ $ linksByType = [];
67+ foreach ($ entity ->getProductLinks () as $ link ) {
68+ $ linksByType [$ link ->getLinkType ()][] = $ link ;
69+ }
70+
71+ // Set array position as a fallback position if necessary
72+ foreach ($ linksByType as $ linkType => $ links ) {
73+ if (!$ this ->hasPosition ($ links )) {
74+ array_walk ($ linksByType [$ linkType ], function ($ productLink , $ position ) {
75+ $ productLink ->setPosition (++$ position );
76+ });
77+ }
78+ }
79+
80+ // Flatten multi-dimensional linksByType in ProductLinks
81+ $ productLinks = array_reduce ($ linksByType , 'array_merge ' , []);
82+
6483 if (count ($ productLinks ) > 0 ) {
6584 foreach ($ entity ->getProductLinks () as $ link ) {
6685 $ this ->productLinkRepository ->save ($ link );
6786 }
6887 }
6988 return $ entity ;
7089 }
90+
91+ /**
92+ * Check if at least one link without position
93+ * @param array $links
94+ * @return bool
95+ */
96+ private function hasPosition (array $ links )
97+ {
98+ foreach ($ links as $ link ) {
99+ if (!array_key_exists ('position ' , $ link ->getData ())) {
100+ return false ;
101+ }
102+ }
103+ return true ;
104+ }
71105}
0 commit comments