ProductRepositorySave.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\ConfigurableProduct\Model\Plugin;
  7. use Magento\Catalog\Model\ProductFactory;
  8. use Magento\Catalog\Api\Data\ProductInterface;
  9. use Magento\Framework\Exception\InputException;
  10. use Magento\Catalog\Api\ProductRepositoryInterface;
  11. use Magento\Framework\Exception\CouldNotSaveException;
  12. use Magento\ConfigurableProduct\Api\Data\OptionInterface;
  13. use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
  14. use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
  15. class ProductRepositorySave
  16. {
  17. /**
  18. * @var ProductAttributeRepositoryInterface
  19. */
  20. private $productAttributeRepository;
  21. /**
  22. * @var ProductFactory
  23. */
  24. private $productFactory;
  25. /**
  26. * @param ProductAttributeRepositoryInterface $productAttributeRepository
  27. * @param ProductFactory $productFactory
  28. */
  29. public function __construct(
  30. ProductAttributeRepositoryInterface $productAttributeRepository,
  31. ProductFactory $productFactory
  32. ) {
  33. $this->productAttributeRepository = $productAttributeRepository;
  34. $this->productFactory = $productFactory;
  35. }
  36. /**
  37. * Validate product links and reset configurable attributes to configurable product
  38. *
  39. * @param ProductRepositoryInterface $subject
  40. * @param ProductInterface $result
  41. * @param ProductInterface $product
  42. * @param bool $saveOptions
  43. * @return ProductInterface
  44. * @throws CouldNotSaveException
  45. * @throws InputException
  46. *
  47. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  48. */
  49. public function afterSave(
  50. ProductRepositoryInterface $subject,
  51. ProductInterface $result,
  52. ProductInterface $product,
  53. $saveOptions = false
  54. ) {
  55. if ($product->getTypeId() !== Configurable::TYPE_CODE) {
  56. return $result;
  57. }
  58. $extensionAttributes = $result->getExtensionAttributes();
  59. if ($extensionAttributes === null) {
  60. return $result;
  61. }
  62. $configurableLinks = (array) $extensionAttributes->getConfigurableProductLinks();
  63. $configurableOptions = (array) $extensionAttributes->getConfigurableProductOptions();
  64. if (empty($configurableLinks) && empty($configurableOptions)) {
  65. return $result;
  66. }
  67. $attributeCodes = [];
  68. /** @var OptionInterface $configurableOption */
  69. foreach ($configurableOptions as $configurableOption) {
  70. $eavAttribute = $this->productAttributeRepository->get($configurableOption->getAttributeId());
  71. $attributeCode = $eavAttribute->getAttributeCode();
  72. $attributeCodes[] = $attributeCode;
  73. }
  74. $this->validateProductLinks($attributeCodes, $configurableLinks);
  75. $result->getTypeInstance()->resetConfigurableAttributes($product);
  76. return $result;
  77. }
  78. /**
  79. * @param array $attributeCodes
  80. * @param array $linkIds
  81. * @return $this
  82. * @throws InputException
  83. */
  84. private function validateProductLinks(array $attributeCodes, array $linkIds)
  85. {
  86. $valueMap = [];
  87. foreach ($linkIds as $productId) {
  88. $variation = $this->productFactory->create()->load($productId);
  89. $valueKey = '';
  90. foreach ($attributeCodes as $attributeCode) {
  91. if (!$variation->getData($attributeCode)) {
  92. throw new InputException(
  93. __('Product with id "%1" does not contain required attribute "%2".', $productId, $attributeCode)
  94. );
  95. }
  96. $valueKey = $valueKey . $attributeCode . ':' . $variation->getData($attributeCode) . ';';
  97. }
  98. if (isset($valueMap[$valueKey])) {
  99. throw new InputException(
  100. __(
  101. 'Products "%1" and "%2" have the same set of attribute values.',
  102. $productId,
  103. $valueMap[$valueKey]
  104. )
  105. );
  106. }
  107. $valueMap[$valueKey] = $productId;
  108. }
  109. }
  110. }