/** * {@inheritdoc} */ public function save(\Magento\Catalog\Api\Data\ProductCustomOptionInterface $option) { $sku = $option->getProductSku(); $product = $this->productRepository->get($sku, true); $optionData = $this->converter->toArray($option); if ($option->getOptionId()) { if (!$product->getOptionById($option->getOptionId())) { throw new NoSuchEntityException(); } $originalValues = $product->getOptionById($option->getOptionId())->getValues(); if (!empty($optionData['values'])) { $optionData['values'] = $this->markRemovedValues($optionData['values'], $originalValues); } } unset($optionData['product_sku']); $product->setProductOptions([$optionData]); $existingOptions = $product->getOptions(); try { $this->productRepository->save($product, true); } catch (\Exception $e) { throw new CouldNotSaveException(__('Could not save product option')); } $product = $this->productRepository->get($sku, true); if (!$option->getOptionId()) { $currentOptions = $product->getOptions(); if ($existingOptions == null) { $newID = array_keys($currentOptions); } else { $newID = array_diff(array_keys($currentOptions), array_keys($existingOptions)); } if (empty($newID)) { throw new CouldNotSaveException(__('Could not save product option')); } $newID = current($newID); } else { $newID = $option->getOptionId(); } $option = $this->get($sku, $newID); return $option; }
/** * 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; }