8
8
use Magento \Bundle \Api \ProductOptionRepositoryInterface as OptionRepository ;
9
9
use Magento \Bundle \Api \ProductLinkManagementInterface ;
10
10
use Magento \Framework \EntityManager \Operation \ExtensionInterface ;
11
+ use Magento \Catalog \Api \Data \ProductInterface ;
11
12
12
13
/**
13
14
* Class SaveHandler
@@ -37,44 +38,51 @@ public function __construct(
37
38
}
38
39
39
40
/**
40
- * @param object $entity
41
+ * @param object|ProductInterface $entity
41
42
* @param array $arguments
42
- * @return \Magento\Catalog\Api\Data\ProductInterface|object
43
+ * @return object|ProductInterface
44
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
45
+ * @throws \Magento\Framework\Exception\InputException
46
+ * @throws \Magento\Framework\Exception\CouldNotSaveException
43
47
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
44
48
*/
45
49
public function execute ($ entity , $ arguments = [])
46
50
{
47
51
$ bundleProductOptions = $ entity ->getExtensionAttributes ()->getBundleProductOptions ();
48
- if ($ entity ->getTypeId () !== ' bundle ' || empty ($ bundleProductOptions )) {
52
+ if ($ entity ->getTypeId () !== Type:: TYPE_CODE || empty ($ bundleProductOptions )) {
49
53
return $ entity ;
50
54
}
51
55
56
+ $ existingBundleProductOptions = $ this ->optionRepository ->getList ($ entity ->getSku ());
57
+
58
+ $ existingOptionsIds = !empty ($ existingBundleProductOptions )
59
+ ? $ this ->getOptionIds ($ existingBundleProductOptions )
60
+ : [];
61
+ $ optionIds = !empty ($ bundleProductOptions )
62
+ ? $ this ->getOptionIds ($ bundleProductOptions )
63
+ : [];
64
+
65
+ $ options = $ bundleProductOptions ?: [];
66
+
52
67
if (!$ entity ->getCopyFromView ()) {
53
- /** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
54
- foreach ($ this ->optionRepository ->getList ($ entity ->getSku ()) as $ option ) {
55
- $ this ->removeOptionLinks ($ entity ->getSku (), $ option );
56
- $ this ->optionRepository ->delete ($ option );
57
- }
68
+ $ this ->processRemovedOptions ($ entity ->getSku (), $ existingOptionsIds , $ optionIds );
69
+ $ this ->processExistingOptions ($ entity ->getSku (), $ existingOptionsIds , $ optionIds );
58
70
59
- $ options = $ bundleProductOptions ?: [];
60
- foreach ($ options as $ option ) {
61
- $ option ->setOptionId (null );
62
- $ this ->optionRepository ->save ($ entity , $ option );
63
- }
71
+ $ newOptionsIds = array_diff ($ optionIds , $ existingOptionsIds );
72
+ $ this ->saveOptions ($ entity , $ options , $ newOptionsIds );
64
73
} else {
65
74
//save only labels and not selections + product links
66
- $ options = $ bundleProductOptions ?: [];
67
- foreach ($ options as $ option ) {
68
- $ this ->optionRepository ->save ($ entity , $ option );
69
- $ entity ->setCopyFromView (false );
70
- }
75
+ $ this ->saveOptions ($ entity , $ options );
76
+ $ entity ->setCopyFromView (false );
71
77
}
72
78
return $ entity ;
73
79
}
74
80
75
81
/**
76
82
* @param string $entitySku
77
83
* @param \Magento\Bundle\Api\Data\OptionInterface $option
84
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
85
+ * @throws \Magento\Framework\Exception\InputException
78
86
* @return void
79
87
*/
80
88
protected function removeOptionLinks ($ entitySku , $ option )
@@ -86,4 +94,85 @@ protected function removeOptionLinks($entitySku, $option)
86
94
}
87
95
}
88
96
}
97
+
98
+ /**
99
+ * Perform save for all options entities
100
+ *
101
+ * @param ProductInterface $entity
102
+ * @param array $options
103
+ * @param array $newOptionsIds
104
+ * @throws \Magento\Framework\Exception\CouldNotSaveException
105
+ * @throws \Magento\Framework\Exception\InputException
106
+ * @return void
107
+ */
108
+ private function saveOptions (ProductInterface $ entity , array $ options , array $ newOptionsIds = [])
109
+ {
110
+ foreach ($ options as $ option ) {
111
+ if (in_array ($ option ->getOptionId (), $ newOptionsIds , true )) {
112
+ $ option ->setOptionId (null );
113
+ }
114
+ $ this ->optionRepository ->save ($ entity , $ option );
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Get options ids from array of the options entities
120
+ *
121
+ * @param array $options
122
+ * @return array
123
+ */
124
+ private function getOptionIds (array $ options )
125
+ {
126
+ $ optionIds = [];
127
+
128
+ if (empty ($ options )) {
129
+ return $ optionIds ;
130
+ }
131
+
132
+ /** @var \Magento\Bundle\Api\Data\OptionInterface $option */
133
+ foreach ($ options as $ option ) {
134
+ if ($ option ->getOptionId ()) {
135
+ $ optionIds [] = $ option ->getOptionId ();
136
+ }
137
+ }
138
+ return $ optionIds ;
139
+ }
140
+
141
+ /**
142
+ * Removes old options that no longer exists
143
+ *
144
+ * @param string $entitySku
145
+ * @param array $existingOptionsIds
146
+ * @param array $optionIds
147
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
148
+ * @throws \Magento\Framework\Exception\InputException
149
+ * @throws \Magento\Framework\Exception\CouldNotSaveException
150
+ * @return void
151
+ */
152
+ private function processRemovedOptions ($ entitySku , array $ existingOptionsIds , array $ optionIds )
153
+ {
154
+ foreach (array_diff ($ existingOptionsIds , $ optionIds ) as $ optionId ) {
155
+ $ option = $ this ->optionRepository ->get ($ entitySku , $ optionId );
156
+ $ this ->removeOptionLinks ($ entitySku , $ option );
157
+ $ this ->optionRepository ->delete ($ option );
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Removes option links for existing options
163
+ *
164
+ * @param string $entitySku
165
+ * @param array $existingOptionsIds
166
+ * @param array $optionIds
167
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
168
+ * @throws \Magento\Framework\Exception\InputException
169
+ * @return void
170
+ */
171
+ private function processExistingOptions ($ entitySku , array $ existingOptionsIds , array $ optionIds )
172
+ {
173
+ foreach (array_intersect ($ optionIds , $ existingOptionsIds ) as $ optionId ) {
174
+ $ option = $ this ->optionRepository ->get ($ entitySku , $ optionId );
175
+ $ this ->removeOptionLinks ($ entitySku , $ option );
176
+ }
177
+ }
89
178
}
0 commit comments