/** * Process product options, creating new options, updating and deleting existing options * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param array $newOptions * @return $this * @throws NoSuchEntityException * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ private function processOptions(\Magento\Catalog\Api\Data\ProductInterface $product, $newOptions) { //existing options by option_id /** @var \Magento\Catalog\Api\Data\ProductCustomOptionInterface[] $existingOptions */ $existingOptions = $product->getOptions(); if ($existingOptions === null) { $existingOptions = []; } $newOptionIds = []; foreach ($newOptions as $key => $option) { if (isset($option['option_id'])) { //updating existing option $optionId = $option['option_id']; if (!isset($existingOptions[$optionId])) { throw new NoSuchEntityException(__('Product option with id %1 does not exist', $optionId)); } $existingOption = $existingOptions[$optionId]; $newOptionIds[] = $option['option_id']; if (isset($option['values'])) { //updating option values $optionValues = $option['values']; $valueIds = []; foreach ($optionValues as $optionValue) { if (isset($optionValue['option_type_id'])) { $valueIds[] = $optionValue['option_type_id']; } } $originalValues = $existingOption->getValues(); foreach ($originalValues as $originalValue) { if (!in_array($originalValue->getOptionTypeId(), $valueIds)) { $originalValue->setData('is_delete', 1); $optionValues[] = $originalValue->getData(); } } $newOptions[$key]['values'] = $optionValues; } else { $existingOptionData = $this->optionConverter->toArray($existingOption); if (isset($existingOptionData['values'])) { $newOptions[$key]['values'] = $existingOptionData['values']; } } } } $optionIdsToDelete = array_diff(array_keys($existingOptions), $newOptionIds); foreach ($optionIdsToDelete as $optionId) { $optionToDelete = $existingOptions[$optionId]; $optionDataArray = $this->optionConverter->toArray($optionToDelete); $optionDataArray['is_delete'] = 1; $newOptions[] = $optionDataArray; } $product->setProductOptions($newOptions); return $this; }