productAttributeRepository = $productAttributeRepository; $this->productFactory = $productFactory; } /** * Validate product links and reset configurable attributes to configurable product * * @param ProductRepositoryInterface $subject * @param ProductInterface $result * @param ProductInterface $product * @param bool $saveOptions * @return ProductInterface * @throws CouldNotSaveException * @throws InputException * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function afterSave( ProductRepositoryInterface $subject, ProductInterface $result, ProductInterface $product, $saveOptions = false ) { if ($product->getTypeId() !== Configurable::TYPE_CODE) { return $result; } $extensionAttributes = $result->getExtensionAttributes(); if ($extensionAttributes === null) { return $result; } $configurableLinks = (array) $extensionAttributes->getConfigurableProductLinks(); $configurableOptions = (array) $extensionAttributes->getConfigurableProductOptions(); if (empty($configurableLinks) && empty($configurableOptions)) { return $result; } $attributeCodes = []; /** @var OptionInterface $configurableOption */ foreach ($configurableOptions as $configurableOption) { $eavAttribute = $this->productAttributeRepository->get($configurableOption->getAttributeId()); $attributeCode = $eavAttribute->getAttributeCode(); $attributeCodes[] = $attributeCode; } $this->validateProductLinks($attributeCodes, $configurableLinks); $result->getTypeInstance()->resetConfigurableAttributes($product); return $result; } /** * @param array $attributeCodes * @param array $linkIds * @return $this * @throws InputException */ private function validateProductLinks(array $attributeCodes, array $linkIds) { $valueMap = []; foreach ($linkIds as $productId) { $variation = $this->productFactory->create()->load($productId); $valueKey = ''; foreach ($attributeCodes as $attributeCode) { if (!$variation->getData($attributeCode)) { throw new InputException( __('Product with id "%1" does not contain required attribute "%2".', $productId, $attributeCode) ); } $valueKey = $valueKey . $attributeCode . ':' . $variation->getData($attributeCode) . ';'; } if (isset($valueMap[$valueKey])) { throw new InputException( __( 'Products "%1" and "%2" have the same set of attribute values.', $productId, $valueMap[$valueKey] ) ); } $valueMap[$valueKey] = $productId; } } }