123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- <?php
- /**
- *
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\ConfigurableProduct\Model;
- use Magento\Catalog\Api\Data\ProductInterface;
- use Magento\Catalog\Model\Product;
- use Magento\Catalog\Model\Product\Type as ProductType;
- use Magento\ConfigurableProduct\Api\Data\OptionInterface;
- use Magento\ConfigurableProduct\Helper\Product\Options\Loader;
- use Magento\ConfigurableProduct\Model\Product\Type\Configurable as ConfigurableType;
- use Magento\Framework\App\ObjectManager;
- use Magento\Framework\Exception\CouldNotSaveException;
- use Magento\Framework\Exception\InputException;
- use Magento\Framework\Exception\NoSuchEntityException;
- use Magento\Framework\Exception\StateException;
- use Magento\Framework\EntityManager\MetadataPool;
- use Magento\Store\Model\Store;
- /**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class OptionRepository implements \Magento\ConfigurableProduct\Api\OptionRepositoryInterface
- {
- /**
- * @var \Magento\Catalog\Api\ProductRepositoryInterface
- */
- protected $productRepository;
- /**
- * @var \Magento\ConfigurableProduct\Api\Data\OptionValueInterfaceFactory
- */
- protected $optionValueFactory;
- /**
- * @var Product\Type\Configurable
- */
- protected $configurableType;
- /**
- * @var \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute
- */
- protected $optionResource;
- /**
- * @var \Magento\Store\Model\StoreManagerInterface
- */
- protected $storeManager;
- /**
- * @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface
- */
- protected $productAttributeRepository;
- /**
- * @var ConfigurableType\AttributeFactory
- */
- protected $configurableAttributeFactory;
- /**
- * @var \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable
- */
- private $configurableTypeResource;
- /**
- * @var MetadataPool
- */
- private $metadataPool;
- /**
- * @var Loader
- */
- private $optionLoader;
- /**
- * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
- * @param \Magento\ConfigurableProduct\Api\Data\OptionValueInterfaceFactory $optionValueFactory
- * @param ConfigurableType $configurableType
- * @param \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute $optionResource
- * @param \Magento\Store\Model\StoreManagerInterface $storeManager
- * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $productAttributeRepository
- * @param ConfigurableType\AttributeFactory $configurableAttributeFactory
- * @param \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $configurableTypeResource
- * @param Loader $optionLoader
- *
- * @SuppressWarnings(PHPMD.ExcessiveParameterList)
- */
- public function __construct(
- \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
- \Magento\ConfigurableProduct\Api\Data\OptionValueInterfaceFactory $optionValueFactory,
- \Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableType,
- \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute $optionResource,
- \Magento\Store\Model\StoreManagerInterface $storeManager,
- \Magento\Catalog\Api\ProductAttributeRepositoryInterface $productAttributeRepository,
- \Magento\ConfigurableProduct\Model\Product\Type\Configurable\AttributeFactory $configurableAttributeFactory,
- \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $configurableTypeResource,
- Loader $optionLoader
- ) {
- $this->productRepository = $productRepository;
- $this->optionValueFactory = $optionValueFactory;
- $this->configurableType = $configurableType;
- $this->optionResource = $optionResource;
- $this->storeManager = $storeManager;
- $this->productAttributeRepository = $productAttributeRepository;
- $this->configurableAttributeFactory = $configurableAttributeFactory;
- $this->configurableTypeResource = $configurableTypeResource;
- $this->optionLoader = $optionLoader;
- }
- /**
- * {@inheritdoc}
- */
- public function get($sku, $id)
- {
- $product = $this->getProduct($sku);
- $options = $this->optionLoader->load($product);
- foreach ($options as $option) {
- if ($option->getId() == $id) {
- return $option;
- }
- }
- throw new NoSuchEntityException(
- __('The "%1" entity that was requested doesn\'t exist. Verify the entity and try again.', $id)
- );
- }
- /**
- * {@inheritdoc}
- */
- public function getList($sku)
- {
- $product = $this->getProduct($sku);
- return (array) $this->optionLoader->load($product);
- }
- /**
- * {@inheritdoc}
- */
- public function delete(OptionInterface $option)
- {
- $entityId = $this->configurableTypeResource->getEntityIdByAttribute($option);
- $product = $this->getProductById($entityId);
- try {
- $this->configurableTypeResource->saveProducts($product, []);
- $this->configurableType->resetConfigurableAttributes($product);
- } catch (\Exception $exception) {
- throw new StateException(
- __('The variations from the "%1" product can\'t be deleted.', $entityId)
- );
- }
- try {
- $this->optionResource->delete($option);
- } catch (\Exception $exception) {
- throw new StateException(
- __('The option with "%1" ID can\'t be deleted.', $option->getId())
- );
- }
- return true;
- }
- /**
- * {@inheritdoc}
- */
- public function deleteById($sku, $id)
- {
- $product = $this->getProduct($sku);
- $attributeCollection = $this->configurableType->getConfigurableAttributeCollection($product);
- /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute $option */
- $option = $attributeCollection->getItemById($id);
- if ($option === null) {
- throw new NoSuchEntityException(
- __("The option that was requested doesn't exist. Verify the entity and try again.")
- );
- }
- return $this->delete($option);
- }
- /**
- * {@inheritdoc}
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- public function save($sku, OptionInterface $option)
- {
- $metadata = $this->getMetadataPool()->getMetadata(ProductInterface::class);
- if ($option->getId()) {
- /** @var Product $product */
- $product = $this->getProduct($sku);
- $data = $option->getData();
- $option->load($option->getId());
- $option->setData(array_replace_recursive($option->getData(), $data));
- if (!$option->getId() || $option->getProductId() != $product->getData($metadata->getLinkField())) {
- throw new NoSuchEntityException(
- __(
- 'Option with id "%1" not found',
- $option->getId()
- )
- );
- }
- } else {
- /** @var Product $product */
- $product = $this->productRepository->get($sku);
- $this->validateNewOptionData($option);
- $allowedTypes = [ProductType::TYPE_SIMPLE, ProductType::TYPE_VIRTUAL, ConfigurableType::TYPE_CODE];
- if (!in_array($product->getTypeId(), $allowedTypes)) {
- throw new \InvalidArgumentException('Incompatible product type');
- }
- $option->setProductId($product->getData($metadata->getLinkField()));
- }
- try {
- $option->save();
- } catch (\Exception $e) {
- throw new CouldNotSaveException(__('An error occurred while saving the option. Please try to save again.'));
- }
- if (!$option->getId()) {
- throw new CouldNotSaveException(__('An error occurred while saving the option. Please try to save again.'));
- }
- return $option->getId();
- }
- /**
- * Retrieve product instance by sku
- *
- * @param string $sku
- * @return ProductInterface
- * @throws InputException
- */
- private function getProduct($sku)
- {
- $product = $this->productRepository->get($sku);
- if (\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE !== $product->getTypeId()) {
- throw new InputException(
- __('This is implemented for the "%1" configurable product only.', $sku)
- );
- }
- return $product;
- }
- /**
- * Retrieve product instance by id
- *
- * @param int $id
- * @return ProductInterface
- * @throws InputException
- */
- private function getProductById($id)
- {
- $product = $this->productRepository->getById($id);
- if (\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE !== $product->getTypeId()) {
- throw new InputException(
- __('This is implemented for the "%1" configurable product only.', $id)
- );
- }
- return $product;
- }
- /**
- * Ensure that all necessary data is available for a new option creation.
- *
- * @param OptionInterface $option
- * @return void
- * @throws InputException
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- public function validateNewOptionData(OptionInterface $option)
- {
- $inputException = new InputException();
- if (!$option->getAttributeId()) {
- $inputException->addError(__('Option attribute ID is not specified.'));
- }
- if (!$option->getLabel()) {
- $inputException->addError(__('Option label is not specified.'));
- }
- if (!$option->getValues()) {
- $inputException->addError(__('Option values are not specified.'));
- } else {
- foreach ($option->getValues() as $optionValue) {
- if (null === $optionValue->getValueIndex()) {
- $inputException->addError(__('Value index is not specified for an option.'));
- }
- }
- }
- if ($inputException->wasErrorAdded()) {
- throw $inputException;
- }
- }
- /**
- * Get MetadataPool instance
- * @return MetadataPool
- */
- private function getMetadataPool()
- {
- if (!$this->metadataPool) {
- $this->metadataPool = ObjectManager::getInstance()->get(MetadataPool::class);
- }
- return $this->metadataPool;
- }
- }
|