123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- <?php
- /**
- *
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Bundle\Model;
- use Magento\Bundle\Model\Option\SaveAction;
- use Magento\Catalog\Api\Data\ProductInterface;
- use Magento\Framework\Exception\InputException;
- use Magento\Framework\Exception\NoSuchEntityException;
- /**
- * Repository for performing CRUD operations for a bundle product's options.
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class OptionRepository implements \Magento\Bundle\Api\ProductOptionRepositoryInterface
- {
- /**
- * @var \Magento\Catalog\Api\ProductRepositoryInterface
- */
- protected $productRepository;
- /**
- * @var Product\Type
- */
- protected $type;
- /**
- * @var \Magento\Bundle\Api\Data\OptionInterfaceFactory
- */
- protected $optionFactory;
- /**
- * @var \Magento\Bundle\Model\ResourceModel\Option
- */
- protected $optionResource;
- /**
- * @var \Magento\Bundle\Api\ProductLinkManagementInterface
- */
- protected $linkManagement;
- /**
- * @var Product\OptionList
- */
- protected $productOptionList;
- /**
- * @var \Magento\Framework\Api\DataObjectHelper
- */
- protected $dataObjectHelper;
- /**
- * @var SaveAction
- */
- private $optionSave;
- /**
- * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
- * @param Product\Type $type
- * @param \Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory
- * @param \Magento\Bundle\Model\ResourceModel\Option $optionResource
- * @param \Magento\Bundle\Api\ProductLinkManagementInterface $linkManagement
- * @param Product\OptionList $productOptionList
- * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
- * @param SaveAction $optionSave
- */
- public function __construct(
- \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
- \Magento\Bundle\Model\Product\Type $type,
- \Magento\Bundle\Api\Data\OptionInterfaceFactory $optionFactory,
- \Magento\Bundle\Model\ResourceModel\Option $optionResource,
- \Magento\Bundle\Api\ProductLinkManagementInterface $linkManagement,
- \Magento\Bundle\Model\Product\OptionList $productOptionList,
- \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
- SaveAction $optionSave
- ) {
- $this->productRepository = $productRepository;
- $this->type = $type;
- $this->optionFactory = $optionFactory;
- $this->optionResource = $optionResource;
- $this->linkManagement = $linkManagement;
- $this->productOptionList = $productOptionList;
- $this->dataObjectHelper = $dataObjectHelper;
- $this->optionSave = $optionSave;
- }
- /**
- * @inheritdoc
- */
- public function get($sku, $optionId)
- {
- $product = $this->getProduct($sku);
- /** @var \Magento\Bundle\Model\Option $option */
- $option = $this->type->getOptionsCollection($product)->getItemById($optionId);
- if (!$option || !$option->getId()) {
- throw new NoSuchEntityException(
- __("The option that was requested doesn't exist. Verify the entity and try again.")
- );
- }
- $productLinks = $this->linkManagement->getChildren($product->getSku(), $optionId);
- /** @var \Magento\Bundle\Api\Data\OptionInterface $optionDataObject */
- $optionDataObject = $this->optionFactory->create();
- $this->dataObjectHelper->populateWithArray(
- $optionDataObject,
- $option->getData(),
- \Magento\Bundle\Api\Data\OptionInterface::class
- );
- $optionDataObject->setOptionId($option->getId());
- $optionDataObject->setTitle($option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle());
- $optionDataObject->setSku($product->getSku());
- $optionDataObject->setProductLinks($productLinks);
- return $optionDataObject;
- }
- /**
- * @inheritdoc
- */
- public function getList($sku)
- {
- $product = $this->getProduct($sku);
- return $this->getListByProduct($product);
- }
- /**
- * Return list of product options
- *
- * @param ProductInterface $product
- * @return \Magento\Bundle\Api\Data\OptionInterface[]
- */
- public function getListByProduct(ProductInterface $product)
- {
- return $this->productOptionList->getItems($product);
- }
- /**
- * @inheritdoc
- */
- public function delete(\Magento\Bundle\Api\Data\OptionInterface $option)
- {
- try {
- $this->optionResource->delete($option);
- } catch (\Exception $exception) {
- throw new \Magento\Framework\Exception\StateException(
- __('The option with "%1" ID can\'t be deleted.', $option->getOptionId()),
- $exception
- );
- }
- return true;
- }
- /**
- * @inheritdoc
- */
- public function deleteById($sku, $optionId)
- {
- /** @var \Magento\Bundle\Api\Data\OptionInterface $option */
- $option = $this->get($sku, $optionId);
- $hasBeenDeleted = $this->delete($option);
- return $hasBeenDeleted;
- }
- /**
- * @inheritdoc
- */
- public function save(
- \Magento\Catalog\Api\Data\ProductInterface $product,
- \Magento\Bundle\Api\Data\OptionInterface $option
- ) {
- $savedOption = $this->optionSave->save($product, $option);
- $productToSave = $this->productRepository->get($product->getSku());
- $this->productRepository->save($productToSave);
- return $savedOption->getOptionId();
- }
- /**
- * Update option selections
- *
- * @param \Magento\Catalog\Api\Data\ProductInterface $product
- * @param \Magento\Bundle\Api\Data\OptionInterface $option
- * @return $this
- * @throws InputException
- * @throws NoSuchEntityException
- * @throws \Magento\Framework\Exception\CouldNotSaveException
- */
- protected function updateOptionSelection(
- \Magento\Catalog\Api\Data\ProductInterface $product,
- \Magento\Bundle\Api\Data\OptionInterface $option
- ) {
- $optionId = $option->getOptionId();
- $existingLinks = $this->linkManagement->getChildren($product->getSku(), $optionId);
- $linksToAdd = [];
- $linksToUpdate = [];
- $linksToDelete = [];
- if (is_array($option->getProductLinks())) {
- $productLinks = $option->getProductLinks();
- foreach ($productLinks as $productLink) {
- if (!$productLink->getId() && !$productLink->getSelectionId()) {
- $linksToAdd[] = $productLink;
- } else {
- $linksToUpdate[] = $productLink;
- }
- }
- /** @var \Magento\Bundle\Api\Data\LinkInterface[] $linksToDelete */
- $linksToDelete = $this->compareLinks($existingLinks, $linksToUpdate);
- }
- foreach ($linksToUpdate as $linkedProduct) {
- $this->linkManagement->saveChild($product->getSku(), $linkedProduct);
- }
- foreach ($linksToDelete as $linkedProduct) {
- $this->linkManagement->removeChild(
- $product->getSku(),
- $option->getOptionId(),
- $linkedProduct->getSku()
- );
- }
- foreach ($linksToAdd as $linkedProduct) {
- $this->linkManagement->addChild($product, $option->getOptionId(), $linkedProduct);
- }
- return $this;
- }
- /**
- * Retrieve product by SKU
- *
- * @param string $sku
- * @return \Magento\Catalog\Api\Data\ProductInterface
- * @throws InputException
- * @throws NoSuchEntityException
- */
- private function getProduct($sku)
- {
- $product = $this->productRepository->get($sku, true, null, true);
- if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) {
- throw new InputException(__('This is implemented for bundle products only.'));
- }
- return $product;
- }
- /**
- * Computes the difference between given arrays.
- *
- * @param \Magento\Bundle\Api\Data\LinkInterface[] $firstArray
- * @param \Magento\Bundle\Api\Data\LinkInterface[] $secondArray
- *
- * @return array
- */
- private function compareLinks(array $firstArray, array $secondArray)
- {
- $result = [];
- $firstArrayIds = [];
- $firstArrayMap = [];
- $secondArrayIds = [];
- foreach ($firstArray as $item) {
- $firstArrayIds[] = $item->getId();
- $firstArrayMap[$item->getId()] = $item;
- }
- foreach ($secondArray as $item) {
- $secondArrayIds[] = $item->getId();
- }
- foreach (array_diff($firstArrayIds, $secondArrayIds) as $id) {
- $result[] = $firstArrayMap[$id];
- }
- return $result;
- }
- }
|