diff --git a/app/code/Magento/Swatches/Model/Plugin/EavAttribute.php b/app/code/Magento/Swatches/Model/Plugin/EavAttribute.php index d3904f058dc2d..76bf5782d3922 100644 --- a/app/code/Magento/Swatches/Model/Plugin/EavAttribute.php +++ b/app/code/Magento/Swatches/Model/Plugin/EavAttribute.php @@ -10,6 +10,7 @@ use Magento\Framework\Exception\InputException; use Magento\Framework\Serialize\Serializer\Json; use Magento\Swatches\Model\Swatch; +use Magento\Swatches\Model\ResourceModel\Swatch as SwatchResource; /** * Plugin model for Catalog Resource Attribute @@ -18,6 +19,11 @@ class EavAttribute { const DEFAULT_STORE_ID = 0; + /** + * @var SwatchResource + */ + private $swatchResource; + /** * Base option title used for string operations to detect is option already exists or new */ @@ -64,17 +70,20 @@ class EavAttribute * @param \Magento\Swatches\Model\SwatchFactory $swatchFactory * @param \Magento\Swatches\Helper\Data $swatchHelper * @param Json|null $serializer + * @param SwatchResource|null $swatchResource */ public function __construct( \Magento\Swatches\Model\ResourceModel\Swatch\CollectionFactory $collectionFactory, \Magento\Swatches\Model\SwatchFactory $swatchFactory, \Magento\Swatches\Helper\Data $swatchHelper, - Json $serializer = null + Json $serializer = null, + SwatchResource $swatchResource = null ) { $this->swatchCollectionFactory = $collectionFactory; $this->swatchFactory = $swatchFactory; $this->swatchHelper = $swatchHelper; $this->serializer = $serializer ?: ObjectManager::getInstance()->create(Json::class); + $this->swatchResource = $swatchResource ?: ObjectManager::getInstance()->create(SwatchResource::class); } /** @@ -148,6 +157,7 @@ protected function setProperOptionsArray(Attribute $attribute) * Prepare attribute for conversion from any swatch type to dropdown * * @param Attribute $attribute + * @throws \Magento\Framework\Exception\LocalizedException * @return void */ protected function convertSwatchToDropdown(Attribute $attribute) @@ -157,6 +167,7 @@ protected function convertSwatchToDropdown(Attribute $attribute) if (!empty($additionalData)) { $additionalData = $this->serializer->unserialize($additionalData); if (is_array($additionalData) && isset($additionalData[Swatch::SWATCH_INPUT_TYPE_KEY])) { + $this->cleanEavAttributeOptionSwatchValues($attribute->getOption()); unset($additionalData[Swatch::SWATCH_INPUT_TYPE_KEY]); $attribute->setData('additional_data', $this->serializer->serialize($additionalData)); } @@ -235,6 +246,7 @@ protected function saveSwatchParams(Attribute $attribute) { if ($this->swatchHelper->isVisualSwatch($attribute)) { $this->processVisualSwatch($attribute); + $this->cleanTextSwatchValuesAfterSwitch($attribute->getOptiontext()); } elseif ($this->swatchHelper->isTextSwatch($attribute)) { $this->processTextualSwatch($attribute); } @@ -267,6 +279,33 @@ protected function processVisualSwatch(Attribute $attribute) } } + /** + * Clean swatch option values after switching to the dropdown type. + * + * @param array $attributeOptions + * @param null $swatchType + * @throws \Magento\Framework\Exception\LocalizedException + */ + private function cleanEavAttributeOptionSwatchValues($attributeOptions, $swatchType = null) + { + if (count($attributeOptions) && isset($attributeOptions['value'])) { + $optionsIDs = array_keys($attributeOptions['value']); + + $this->swatchResource->clearSwatchOptionByOptionIdAndType($optionsIDs, $swatchType); + } + } + + /** + * Cleaning the text type of swatch option values after switching. + * + * @param array $attributeOptions + * @throws \Magento\Framework\Exception\LocalizedException + */ + private function cleanTextSwatchValuesAfterSwitch($attributeOptions) + { + $this->cleanEavAttributeOptionSwatchValues($attributeOptions, Swatch::SWATCH_TYPE_TEXTUAL); + } + /** * @param string $value * @return int diff --git a/app/code/Magento/Swatches/Model/ResourceModel/Swatch.php b/app/code/Magento/Swatches/Model/ResourceModel/Swatch.php index 22eb1d4c7eef9..8ca694725511d 100644 --- a/app/code/Magento/Swatches/Model/ResourceModel/Swatch.php +++ b/app/code/Magento/Swatches/Model/ResourceModel/Swatch.php @@ -37,4 +37,24 @@ public function saveDefaultSwatchOption($id, $defaultValue) $this->getConnection()->update($this->getTable('eav_attribute'), $bind, $where); } } + + /** + * Cleaned swatch option values when switching to dropdown input type + * + * @param $optionIDs + * @param $type + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function clearSwatchOptionByOptionIdAndType($optionIDs, $type = null) + { + if (count($optionIDs)) { + foreach ($optionIDs as $optionId) { + $where = ['option_id' => $optionId]; + if ($type !== null) { + $where['type = ?'] = $type; + } + $this->getConnection()->delete($this->getMainTable(), $where); + } + } + } } diff --git a/app/code/Magento/Swatches/Model/SwatchAttributesProvider.php b/app/code/Magento/Swatches/Model/SwatchAttributesProvider.php index 820d8bf107d5d..2dc00fcf9a428 100644 --- a/app/code/Magento/Swatches/Model/SwatchAttributesProvider.php +++ b/app/code/Magento/Swatches/Model/SwatchAttributesProvider.php @@ -39,6 +39,8 @@ class SwatchAttributesProvider private $swatchTypeChecker; /** + * SwatchAttributesProvider constructor. + * * @param Configurable $typeConfigurable * @param SwatchAttributeCodes $swatchAttributeCodes * @param SwatchAttributeType|null $swatchTypeChecker diff --git a/app/code/Magento/Swatches/Test/Unit/Model/SwatchAttributesProviderTest.php b/app/code/Magento/Swatches/Test/Unit/Model/SwatchAttributesProviderTest.php index 1f69c6d5f2fa3..ec52d759ebafa 100644 --- a/app/code/Magento/Swatches/Test/Unit/Model/SwatchAttributesProviderTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Model/SwatchAttributesProviderTest.php @@ -44,7 +44,7 @@ protected function setUp() { $this->typeConfigurable = $this->createPartialMock( Configurable::class, - ['getConfigurableAttributes', 'getCodes'] + ['getConfigurableAttributes', 'getCodes', 'getProductAttribute'] ); $this->swatchAttributeCodes = $this->createMock(SwatchAttributeCodes::class); @@ -65,8 +65,9 @@ public function testProvide() $this->productMock->method('getTypeId') ->willReturn(Configurable::TYPE_CODE); - $productAttributeMock = $this->getMockBuilder(Attribute::class) + $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) ->disableOriginalConstructor() + ->setMethods(['setStoreId', 'getData', 'setData', 'getSource', 'hasData']) ->getMock(); $configAttributeMock = $this->createPartialMock( @@ -79,7 +80,7 @@ public function testProvide() $configAttributeMock ->method('getProductAttribute') - ->willReturn($productAttributeMock); + ->willReturn($attributeMock); $this->typeConfigurable ->method('getConfigurableAttributes') @@ -92,8 +93,9 @@ public function testProvide() ->willReturn($swatchAttributes); $this->swatchTypeChecker->expects($this->once())->method('isSwatchAttribute')->willReturn(true); + $result = $this->swatchAttributeProvider->provide($this->productMock); - $this->assertEquals([1 => $productAttributeMock], $result); + $this->assertEquals([1 => $attributeMock], $result); } }