/** * {@inheritdoc} */ public function getProducts(ProductInterface $product) { if (!isset($this->products[$product->getId()])) { if ($this->requestSafety->isSafeMethod()) { $productIds = $this->resource->getConnection()->fetchCol('(' . implode(') UNION (', $this->linkedProductSelectBuilder->build($product->getId())) . ')'); $this->products[$product->getId()] = $this->collectionFactory->create()->addAttributeToSelect(['price', 'special_price'])->addIdFilter($productIds); } else { $this->products[$product->getId()] = $this->configurable->getUsedProducts($product); } } return $this->products[$product->getId()]; }
/** * Get linked to configurable simple products * * @param ProductInterface $product * @return int[] */ private function getLinkedProducts(ProductInterface $product) { /** @var Configurable $typeInstance */ $typeInstance = $product->getTypeInstance(); $childrenIds = $typeInstance->getChildrenIds($product->getId()); if (isset($childrenIds[0])) { return $childrenIds[0]; } else { return []; } }
/** * Add Product Filter to Collection * * @param int|array|ProductInterface $product * @return $this */ public function addProductFilter($product) { $id = -1; if ($product instanceof ProductInterface) { $id = $product->getId(); } else { if (is_numeric($product)) { $id = $product; } } $this->addFieldToFilter('product', $id); return $this; }
/** * Return the stock item that needs to be updated. * If the stock item does not need to be updated, return null. * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null */ protected function getStockItemToBeUpdated($product) { // from the API, all the data we care about will exist as extension attributes of the original product $extendedAttributes = $product->getExtensionAttributes(); if ($extendedAttributes !== null) { $stockItem = $extendedAttributes->getStockItem(); if ($stockItem != null) { return $stockItem; } } // we have no new stock item information to update, however we need to ensure that the product does have some // stock item information present. On a newly created product, it will not have any stock item info. $stockItem = $this->stockRegistry->getStockItem($product->getId()); if ($stockItem->getItemId() != null) { // we already have stock item info, so we return null since nothing more needs to be updated return null; } return $stockItem; }
/** * {@inheritdoc} * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ 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->setProductIdFilter($product->getId())->joinValues($this->storeManager->getStore()->getId()); $isNewOption = true; /** @var \Magento\Bundle\Model\Option $option */ foreach ($options as $option) { if ($option->getOptionId() == $optionId) { $isNewOption = false; break; } } if ($isNewOption) { throw new InputException(__('Product with specified sku: "%1" does not contain option: "%2"', [$product->getSku(), $optionId])); } /* @var $resource \Magento\Bundle\Model\Resource\Bundle */ $resource = $this->bundleFactory->create(); $selections = $resource->getSelectionsData($product->getId()); /** @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->getId()) { throw new CouldNotSaveException(__('Child with specified sku: "%1" already assigned to product: "%2"', [$linkedProduct->getSku(), $product->getSku()])); } } } $selectionModel = $this->bundleSelection->create(); $selectionModel->setOptionId($optionId)->setPosition($linkedProduct->getPosition())->setSelectionQty($linkedProduct->getQty())->setSelectionPriceType($linkedProduct->getPriceType())->setSelectionPriceValue($linkedProduct->getPrice())->setSelectionCanChangeQty($linkedProduct->getCanChangeQuantity())->setProductId($linkProductModel->getId())->setParentProductId($product->getId())->setIsDefault($linkedProduct->getIsDefault())->setWebsiteId($this->storeManager->getStore()->getWebsiteId()); try { $selectionModel->save(); } catch (\Exception $e) { throw new CouldNotSaveException(__('Could not save child: "%1"', $e->getMessage()), $e); } return $selectionModel->getId(); }
/** * @param ProductInterface $product * @param StockItemInterface $stockItem * @throws LocalizedException * @return void */ private function validateStockItem(ProductInterface $product, StockItemInterface $stockItem) { $defaultScopeId = $this->stockConfiguration->getDefaultScopeId(); $defaultStockId = $this->stockRegistry->getStock($defaultScopeId)->getStockId(); $stockId = $stockItem->getStockId(); if ($stockId !== null && $stockId != $defaultStockId) { throw new LocalizedException(__('Invalid stock id: %1. Only default stock with id %2 allowed', $stockId, $defaultStockId)); } $stockItemId = $stockItem->getItemId(); if ($stockItemId !== null && (!is_numeric($stockItemId) || $stockItemId <= 0)) { throw new LocalizedException(__('Invalid stock item id: %1. Should be null or numeric value greater than 0', $stockItemId)); } $defaultStockItemId = $this->stockRegistry->getStockItem($product->getId())->getItemId(); if ($defaultStockItemId && $stockItemId !== null && $defaultStockItemId != $stockItemId) { throw new LocalizedException(__('Invalid stock item id: %1. Assigned stock item id is %2', $stockItemId, $defaultStockItemId)); } }
/** * {@inheritdoc} */ public function delete(\Magento\Catalog\Api\Data\ProductInterface $product) { $sku = $product->getSku(); $productId = $product->getId(); try { $this->resourceModel->delete($product); } catch (\Exception $e) { throw new \Magento\Framework\Exception\StateException(__('Unable to remove product %1', $sku)); } unset($this->instances[$sku]); unset($this->instancesById[$productId]); return true; }
/** * Set the project associated with this text8 * @param \Magento\Catalog\Api\Data\ProductInterface $productInterface * @return \Tudock\HelloWorld\Api\Data\HelloTextInterface */ public function setProduct(\Magento\Catalog\Api\Data\ProductInterface $productInterface) { $this->setData('product', $productInterface->getId()); return $this; }
/** * @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.')); } if ($existingLink->getProductId() != $product->getId()) { 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) { $option->setStoreId($this->storeManager->getStore()->getId()); $option->setParentId($product->getId()); $optionId = $option->getOptionId(); $linksToAdd = []; if (!$optionId) { $option->setDefaultTitle($option->getTitle()); if (is_array($option->getProductLinks())) { $linksToAdd = $option->getProductLinks(); } } else { $optionCollection = $this->type->getOptionsCollection($product); /** @var \Magento\Bundle\Model\Option $existingOption */ $existingOption = $optionCollection->getItemById($option->getOptionId()); if (!isset($existingOption) || !$existingOption->getOptionId()) { throw new NoSuchEntityException(__('Requested option doesn\'t exist')); } $option->setData(array_merge($existingOption->getData(), $option->getData())); $this->updateOptionSelection($product, $option); } 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); } return $option->getOptionId(); }
/** * Fill data column * * @param ProductInterface $linkedProduct * @param ProductLinkInterface $linkItem * @return array */ protected function fillData(ProductInterface $linkedProduct, ProductLinkInterface $linkItem) { /** @var \Magento\Framework\Currency $currency */ $currency = $this->localeCurrency->getCurrency($this->locator->getBaseCurrencyCode()); return ['id' => $linkedProduct->getId(), 'name' => $linkedProduct->getName(), 'sku' => $linkItem->getLinkedProductSku(), 'price' => $currency->toCurrency(sprintf("%f", $linkedProduct->getPrice())), 'qty' => $linkItem->getExtensionAttributes()->getQty(), 'position' => $linkItem->getPosition(), 'thumbnail' => $this->imageHelper->init($linkedProduct, 'product_listing_thumbnail')->getUrl(), 'type_id' => $linkedProduct->getTypeId(), 'status' => $this->status->getOptionText($linkedProduct->getStatus()), 'attribute_set' => $this->attributeSetRepository->get($linkedProduct->getAttributeSetId())->getAttributeSetName()]; }
/** * Prepare data column * * @param ProductInterface $linkedProduct * @param ProductLinkInterface $linkItem * @return array */ protected function fillData(ProductInterface $linkedProduct, ProductLinkInterface $linkItem) { return ['id' => $linkedProduct->getId(), 'thumbnail' => $this->imageHelper->init($linkedProduct, 'product_listing_thumbnail')->getUrl(), 'name' => $linkedProduct->getName(), 'status' => $this->status->getOptionText($linkedProduct->getStatus()), 'attribute_set' => $this->attributeSetRepository->get($linkedProduct->getAttributeSetId())->getAttributeSetName(), 'sku' => $linkItem->getLinkedProductSku(), 'price' => $linkedProduct->getPrice(), 'position' => $linkItem->getPosition()]; }
/** * {@inheritdoc} * @SuppressWarnings(PHPMD.NPathComplexity) */ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, \Magento\Bundle\Api\Data\OptionInterface $option) { $option->setStoreId($this->storeManager->getStore()->getId()); $option->setParentId($product->getId()); if (!$option->getOptionId()) { $option->setDefaultTitle($option->getTitle()); $linksToAdd = is_array($option->getProductLinks()) ? $option->getProductLinks() : []; } else { $optionCollection = $this->type->getOptionsCollection($product); $optionCollection->setIdFilter($option->getOptionId()); /** @var \Magento\Bundle\Model\Option $existingOption */ $existingOption = $optionCollection->getFirstItem(); if (!$existingOption->getOptionId()) { throw new NoSuchEntityException(__('Requested option doesn\'t exist')); } $option->setData(array_merge($existingOption->getData(), $option->getData())); /** @var \Magento\Bundle\Api\Data\LinkInterface[] $existingLinks */ $existingLinks = is_array($existingOption->getProductLinks()) ? $existingOption->getProductLinks() : []; /** @var \Magento\Bundle\Api\Data\LinkInterface[] $newProductLinks */ $newProductLinks = is_array($option->getProductLinks()) ? $option->getProductLinks() : []; /** @var \Magento\Bundle\Api\Data\LinkInterface[] $linksToDelete */ $linksToDelete = array_udiff($existingLinks, $newProductLinks, [$this, 'compareLinks']); foreach ($linksToDelete as $link) { $this->linkManagement->removeChild($product->getSku(), $option->getOptionId(), $link->getSku()); } /** @var \Magento\Bundle\Api\Data\LinkInterface[] $linksToAdd */ $linksToAdd = array_udiff($newProductLinks, $existingLinks, [$this, 'compareLinks']); } 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); } return $option->getOptionId(); }
/** * {@inheritdoc} */ 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])); } /* @var $resource \Magento\Bundle\Model\ResourceModel\Bundle */ $resource = $this->bundleFactory->create(); $selections = $resource->getSelectionsData($product->getId()); /** @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->getId()) { throw new CouldNotSaveException(__('Child with specified sku: "%1" already assigned to product: "%2"', [$linkedProduct->getSku(), $product->getSku()])); } } } $selectionModel = $this->bundleSelection->create(); $selectionModel = $this->mapProductLinkToSelectionModel($selectionModel, $linkedProduct, $linkProductModel->getId(), $product->getId()); $selectionModel->setOptionId($optionId); try { $selectionModel->save(); $resource->addProductRelation($product->getId(), $linkProductModel->getId()); } catch (\Exception $e) { throw new CouldNotSaveException(__('Could not save child: "%1"', $e->getMessage()), $e); } return $selectionModel->getId(); }
/** * @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.')); } if ($existingSample->getProductId() != $product->getId()) { 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(); }
/** * {@inheritdoc} */ public function duplicate(\Magento\Catalog\Api\Data\ProductInterface $product, \Magento\Catalog\Api\Data\ProductInterface $duplicate) { return $this->optionResource->duplicate($this->getOptionFactory()->create([]), $product->getId(), $duplicate->getId()); }
/** * Item data. * * @return array */ public function getData() { $productItemData = ['id' => $this->product->getId(), 'name' => $this->product->getName(), 'price' => $this->getProductPrice(), 'image' => $this->productHelper->getSmallImageUrl($this->product), 'score' => $this->product->getDocumentScore(), 'is_in_stock' => $this->isInStockProduct()]; return $productItemData; }
/** * @deprecated * * @param Product $parentProduct * @param array $attributes * @return bool|ProductCollection * @throws InputException */ protected function prepareVariationCollection(Product $parentProduct, array $attributes) { $productCollection = $this->productCollectionFactory->create(); $this->addFilterByParent($productCollection, $parentProduct->getId()); $configurableAttributes = $this->getAttributesFromConfigurable($parentProduct); foreach ($configurableAttributes as $attribute) { $productCollection->addAttributeToSelect($attribute['attribute_code']); } $this->addFilterByAttributes($productCollection, $attributes); return $productCollection; }