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