@@ -31,18 +31,27 @@ 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
48+ ProductLinkRepositoryInterface $ productLinkRepository ,
49+ \Magento \Catalog \Model \Product \LinkTypeProvider $ linkTypeProvider
4250 ) {
4351 $ this ->metadataPool = $ metadataPool ;
4452 $ this ->linkResource = $ linkResource ;
4553 $ this ->productLinkRepository = $ productLinkRepository ;
54+ $ this ->linkTypeProvider = $ linkTypeProvider ;
4655 }
4756
4857 /**
@@ -55,17 +64,50 @@ public function execute($entityType, $entity)
5564 {
5665 $ link = $ entity ->getData ($ this ->metadataPool ->getMetadata ($ entityType )->getLinkField ());
5766 if ($ this ->linkResource ->hasProductLinks ($ link )) {
58- /** @var \Magento\Catalog\Api\Data\ProductInterface $entity*/
67+ /** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
5968 foreach ($ this ->productLinkRepository ->getList ($ entity ) as $ link ) {
6069 $ this ->productLinkRepository ->delete ($ link );
6170 }
6271 }
63- $ productLinks = $ entity ->getProductLinks ();
72+
73+ // Build links per type
74+ $ linksByType = [];
75+ foreach ($ entity ->getProductLinks () as $ link ) {
76+ $ linksByType [$ link ->getLinkType ()][] = $ link ;
77+ }
78+
79+ // Set array position as a fallback position if necessary
80+ foreach ($ linksByType as $ linkType => $ links ) {
81+ if (!$ this ->hasPosition ($ links )) {
82+ array_walk ($ linksByType [$ linkType ], function ($ productLink , $ position ) {
83+ $ productLink ->setPosition (++$ position );
84+ });
85+ }
86+ }
87+
88+ // Flatten multi-dimensional linksByType in ProductLinks
89+ $ productLinks = array_reduce ($ linksByType , 'array_merge ' , []);
90+
6491 if (count ($ productLinks ) > 0 ) {
6592 foreach ($ entity ->getProductLinks () as $ link ) {
6693 $ this ->productLinkRepository ->save ($ link );
6794 }
6895 }
6996 return $ entity ;
7097 }
98+
99+ /**
100+ * Check if at least one link without position
101+ * @param array $links
102+ * @return bool
103+ */
104+ private function hasPosition (array $ links )
105+ {
106+ foreach ($ links as $ link ) {
107+ if (!array_key_exists ('position ' , $ link ->getData ())) {
108+ return false ;
109+ }
110+ }
111+ return true ;
112+ }
71113}
0 commit comments