@@ -31,18 +31,27 @@ class SaveHandler
31
31
private $ linkResource ;
32
32
33
33
/**
34
+ * @var linkTypeProvider
35
+ */
36
+ private $ linkTypeProvider ;
37
+
38
+ /**
39
+ * SaveHandler constructor.
34
40
* @param MetadataPool $metadataPool
35
41
* @param Link $linkResource
36
42
* @param ProductLinkRepositoryInterface $productLinkRepository
43
+ * @param \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider
37
44
*/
38
45
public function __construct (
39
46
MetadataPool $ metadataPool ,
40
47
Link $ linkResource ,
41
- ProductLinkRepositoryInterface $ productLinkRepository
48
+ ProductLinkRepositoryInterface $ productLinkRepository ,
49
+ \Magento \Catalog \Model \Product \LinkTypeProvider $ linkTypeProvider
42
50
) {
43
51
$ this ->metadataPool = $ metadataPool ;
44
52
$ this ->linkResource = $ linkResource ;
45
53
$ this ->productLinkRepository = $ productLinkRepository ;
54
+ $ this ->linkTypeProvider = $ linkTypeProvider ;
46
55
}
47
56
48
57
/**
@@ -55,17 +64,50 @@ public function execute($entityType, $entity)
55
64
{
56
65
$ link = $ entity ->getData ($ this ->metadataPool ->getMetadata ($ entityType )->getLinkField ());
57
66
if ($ this ->linkResource ->hasProductLinks ($ link )) {
58
- /** @var \Magento\Catalog\Api\Data\ProductInterface $entity*/
67
+ /** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
59
68
foreach ($ this ->productLinkRepository ->getList ($ entity ) as $ link ) {
60
69
$ this ->productLinkRepository ->delete ($ link );
61
70
}
62
71
}
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
+
64
91
if (count ($ productLinks ) > 0 ) {
65
92
foreach ($ entity ->getProductLinks () as $ link ) {
66
93
$ this ->productLinkRepository ->save ($ link );
67
94
}
68
95
}
69
96
return $ entity ;
70
97
}
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
+ }
71
113
}
0 commit comments