/** * Populate product with variation of attributes * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param array $attributes * @return \Magento\Catalog\Api\Data\ProductInterface[] */ public function create(\Magento\Catalog\Api\Data\ProductInterface $product, $attributes) { $variations = $this->variationMatrix->getVariations($attributes); $products = []; foreach ($variations as $variation) { $price = $product->getPrice(); /** @var \Magento\Catalog\Model\Product $item */ $item = $this->productFactory->create(); $item->setData($product->getData()); $suffix = ''; foreach ($variation as $attributeId => $valueInfo) { $suffix .= '-' . $valueInfo['value']; $customAttribute = $this->customAttributeFactory->create()->setAttributeCode($attributes[$attributeId]['attribute_code'])->setValue($valueInfo['value']); $customAttributes = array_merge($item->getCustomAttributes(), [$attributes[$attributeId]['attribute_code'] => $customAttribute]); $item->setData('custom_attributes', $customAttributes); $priceInfo = $valueInfo['price']; $price += (!empty($priceInfo['is_percent']) ? $product->getPrice() / 100.0 : 1.0) * $priceInfo['pricing_value']; } $item->setPrice($price); $item->setName($product->getName() . $suffix); $item->setSku($product->getSku() . $suffix); $item->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE); $products[] = $item; } return $products; }
/** * {@inheritdoc} * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false) { if ($saveOptions) { $productOptions = $product->getProductOptions(); } $isDeleteOptions = $product->getIsDeleteOptions(); $tierPrices = $product->getData('tier_price'); $productId = $this->resourceModel->getIdBySku($product->getSku()); $ignoreLinksFlag = $product->getData('ignore_links_flag'); $productDataArray = $this->extensibleDataObjectConverter->toNestedArray($product, [], 'Magento\\Catalog\\Api\\Data\\ProductInterface'); $productLinks = null; if (!$ignoreLinksFlag && $ignoreLinksFlag !== null) { $productLinks = $product->getProductLinks(); } $product = $this->initializeProductData($productDataArray, empty($productId)); if (isset($productDataArray['options'])) { if (!empty($productDataArray['options']) || $isDeleteOptions) { $this->processOptions($product, $productDataArray['options']); $product->setCanSaveCustomOptions(true); } } $this->processLinks($product, $productLinks); if (isset($productDataArray['media_gallery_entries'])) { $this->processMediaGallery($product, $productDataArray['media_gallery_entries']); } $validationResult = $this->resourceModel->validate($product); if (true !== $validationResult) { throw new \Magento\Framework\Exception\CouldNotSaveException(__('Invalid product data: %1', implode(',', $validationResult))); } try { if ($saveOptions) { $product->setProductOptions($productOptions); $product->setCanSaveCustomOptions(true); } if ($tierPrices !== null) { $product->setData('tier_price', $tierPrices); } $this->resourceModel->save($product); } catch (\Magento\Eav\Model\Entity\Attribute\Exception $exception) { throw \Magento\Framework\Exception\InputException::invalidFieldValue($exception->getAttributeCode(), $product->getData($exception->getAttributeCode()), $exception); } catch (\Exception $e) { throw new \Magento\Framework\Exception\CouldNotSaveException(__('Unable to save product')); } unset($this->instances[$product->getSku()]); unset($this->instancesById[$product->getId()]); return $this->get($product->getSku()); }
/** * {@inheritdoc} * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function addChild(\Magento\Catalog\Api\Data\ProductInterface $product, $optionId, \Magento\Bundle\Api\Data\LinkInterface $linkedProduct) { if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) { throw new InputException(__('Product with specified sku: "%1" is not a bundle product', $product->getSku())); } $options = $this->optionCollection->create(); $options->setIdFilter($optionId); $existingOption = $options->getFirstItem(); if (!$existingOption->getId()) { throw new InputException(__('Product with specified sku: "%1" does not contain option: "%2"', [$product->getSku(), $optionId])); } $linkField = $this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField(); /* @var $resource \Magento\Bundle\Model\ResourceModel\Bundle */ $resource = $this->bundleFactory->create(); $selections = $resource->getSelectionsData($product->getData($linkField)); /** @var \Magento\Catalog\Model\Product $linkProductModel */ $linkProductModel = $this->productRepository->get($linkedProduct->getSku()); if ($linkProductModel->isComposite()) { throw new InputException(__('Bundle product could not contain another composite product')); } if ($selections) { foreach ($selections as $selection) { if ($selection['option_id'] == $optionId && $selection['product_id'] == $linkProductModel->getEntityId()) { if (!$product->getCopyFromView()) { throw new CouldNotSaveException(__('Child with specified sku: "%1" already assigned to product: "%2"', [$linkedProduct->getSku(), $product->getSku()])); } else { return $this->bundleSelection->create()->load($linkProductModel->getEntityId()); } } } } $selectionModel = $this->bundleSelection->create(); $selectionModel = $this->mapProductLinkToSelectionModel($selectionModel, $linkedProduct, $linkProductModel->getEntityId(), $product->getData($linkField)); $selectionModel->setOptionId($optionId); try { $selectionModel->save(); $resource->addProductRelation($product->getData($linkField), $linkProductModel->getEntityId()); } catch (\Exception $e) { throw new CouldNotSaveException(__('Could not save child: "%1"', $e->getMessage()), $e); } return $selectionModel->getId(); }
/** * Get variation-matrix from product * * @param ProductInterface $product * @return array */ private function getVariationMatrixFromProduct(ProductInterface $product) { $result = []; $configurableMatrix = $product->hasData('configurable-matrix') ? $product->getData('configurable-matrix') : []; foreach ($configurableMatrix as $item) { if ($item['newProduct']) { $result[$item['variationKey']] = $this->mapData($item); if (isset($item['qty'])) { $result[$item['variationKey']]['quantity_and_stock_status']['qty'] = $item['qty']; } } } return $result; }
/** * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param LinkInterface $link * @param bool $isGlobalScopeContent * @return mixed * @throws InputException * @throws NoSuchEntityException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function updateLink(\Magento\Catalog\Api\Data\ProductInterface $product, LinkInterface $link, $isGlobalScopeContent) { /** @var $existingLink \Magento\Downloadable\Model\Link */ $existingLink = $this->linkFactory->create()->load($link->getId()); if (!$existingLink->getId()) { throw new NoSuchEntityException(__('There is no downloadable link with provided ID.')); } $linkFieldValue = $product->getData($this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField()); if ($existingLink->getProductId() != $linkFieldValue) { throw new InputException(__('Provided downloadable link is not related to given product.')); } $validateLinkContent = $link->getLinkFileContent() === null ? false : true; $validateSampleContent = $link->getSampleFileContent() === null ? false : true; if (!$this->contentValidator->isValid($link, $validateLinkContent, $validateSampleContent)) { throw new InputException(__('Provided link information is invalid.')); } if ($isGlobalScopeContent) { $product->setStoreId(0); } $title = $link->getTitle(); if (empty($title)) { if ($isGlobalScopeContent) { throw new InputException(__('Link title cannot be empty.')); } } if ($link->getLinkType() == 'file' && $link->getLinkFileContent() === null) { $link->setLinkFile($existingLink->getLinkFile()); } if ($link->getSampleType() == 'file' && $link->getSampleFileContent() === null) { $link->setSampleFile($existingLink->getSampleFile()); } $this->saveLink($product, $link, $isGlobalScopeContent); return $existingLink->getId(); }
/** * {@inheritdoc} */ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, \Magento\Bundle\Api\Data\OptionInterface $option) { $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); $option->setStoreId($product->getStoreId()); $option->setParentId($product->getData($metadata->getLinkField())); $linksToAdd = []; $option->setDefaultTitle($option->getDefaultTitle() ?: $option->getTitle()); if (is_array($option->getProductLinks())) { $linksToAdd = $option->getProductLinks(); } try { $this->optionResource->save($option); } catch (\Exception $e) { throw new CouldNotSaveException(__('Could not save option'), $e); } /** @var \Magento\Bundle\Api\Data\LinkInterface $linkedProduct */ foreach ($linksToAdd as $linkedProduct) { $this->linkManagement->addChild($product, $option->getOptionId(), $linkedProduct); } $product->setIsRelationsChanged(true); return $option->getOptionId(); }
/** * Method getting full media gallery for current Product * Array structure: [ * ['image'] => 'http://url/pub/media/catalog/product/2/0/blabla.jpg', * ['mediaGallery'] => [ * galleryImageId1 => simpleProductImage1.jpg, * galleryImageId2 => simpleProductImage2.jpg, * ..., * ] * ] * @param Product $product * @return array */ public function getProductMediaGallery(Product $product) { if (!in_array($product->getData('image'), [null, 'no_selection'], true)) { $baseImage = $product->getData('image'); } else { $productMediaAttributes = array_filter($product->getMediaAttributeValues(), function ($value) { return $value !== 'no_selection' && $value !== null; }); foreach ($productMediaAttributes as $attributeCode => $value) { if ($attributeCode !== 'swatch_image') { $baseImage = (string) $value; break; } } } if (empty($baseImage)) { return []; } $resultGallery = $this->getAllSizeImages($product, $baseImage); $resultGallery['gallery'] = $this->getGalleryImages($product); return $resultGallery; }
/** * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param SampleInterface $sample * @param bool $isGlobalScopeContent * @return int * @throws InputException * @throws NoSuchEntityException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function updateSample(\Magento\Catalog\Api\Data\ProductInterface $product, SampleInterface $sample, $isGlobalScopeContent) { $sampleId = $sample->getId(); /** @var $existingSample \Magento\Downloadable\Model\Sample */ $existingSample = $this->sampleFactory->create()->load($sampleId); if (!$existingSample->getId()) { throw new NoSuchEntityException(__('There is no downloadable sample with provided ID.')); } $linkFieldValue = $product->getData($this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField()); if ($existingSample->getProductId() != $linkFieldValue) { throw new InputException(__('Provided downloadable sample is not related to given product.')); } $validateFileContent = $sample->getSampleFileContent() === null ? false : true; if (!$this->contentValidator->isValid($sample, $validateFileContent)) { throw new InputException(__('Provided sample information is invalid.')); } if ($isGlobalScopeContent) { $product->setStoreId(0); } $title = $sample->getTitle(); if (empty($title)) { if ($isGlobalScopeContent) { throw new InputException(__('Sample title cannot be empty.')); } // use title from GLOBAL scope $existingSample->setTitle(null); } else { $existingSample->setTitle($sample->getTitle()); } if ($sample->getSampleType() === 'file' && $sample->getSampleFileContent() === null) { $sample->setSampleFile($existingSample->getSampleFile()); } $this->saveSample($product, $sample, $isGlobalScopeContent); return $existingSample->getId(); }
/** * Retrieve assoc array that contains media attribute values of the given product * * @param Product $product * @return array */ protected function getMediaAttributeValues(Product $product) { $mediaAttributeCodes = array_keys($product->getMediaAttributes()); $mediaAttributeValues = []; foreach ($mediaAttributeCodes as $attributeCode) { $mediaAttributeValues[$attributeCode] = $product->getData($attributeCode); } return $mediaAttributeValues; }
/** * {@inheritdoc} */ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false) { if ($saveOptions) { $productOptions = $product->getProductOptions(); } $groupPrices = $product->getData('group_price'); $tierPrices = $product->getData('tier_price'); $productId = $this->resourceModel->getIdBySku($product->getSku()); $productDataArray = $this->extensibleDataObjectConverter->toNestedArray($product, [], 'Magento\\Catalog\\Api\\Data\\ProductInterface'); $product = $this->initializeProductData($productDataArray, empty($productId)); $validationResult = $this->resourceModel->validate($product); if (true !== $validationResult) { throw new \Magento\Framework\Exception\CouldNotSaveException(__('Invalid product data: %1', implode(',', $validationResult))); } try { if ($saveOptions) { $product->setProductOptions($productOptions); $product->setCanSaveCustomOptions(true); } $product->setData('group_price', $groupPrices); $product->setData('tier_price', $tierPrices); $this->resourceModel->save($product); } catch (\Magento\Eav\Model\Entity\Attribute\Exception $exception) { throw \Magento\Framework\Exception\InputException::invalidFieldValue($exception->getAttributeCode(), $product->getData($exception->getAttributeCode()), $exception); } catch (\Exception $e) { throw new \Magento\Framework\Exception\CouldNotSaveException(__('Unable to save product')); } unset($this->instances[$product->getSku()]); unset($this->instancesById[$product->getId()]); return $product; }