Skip to content

Commit 0f28b61

Browse files
eugene-shabnmalevanec
authored and
nmalevanec
committed
Unable to change attribute type from swatch
1 parent 5084541 commit 0f28b61

File tree

3 files changed

+73
-15
lines changed

3 files changed

+73
-15
lines changed

app/code/Magento/Swatches/Model/Plugin/EavAttribute.php

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Magento\Framework\App\ObjectManager;
1010
use Magento\Framework\Exception\InputException;
1111
use Magento\Framework\Serialize\Serializer\Json;
12+
use Magento\Swatches\Model\ResourceModel\Swatch as SwatchResource;
1213
use Magento\Swatches\Model\Swatch;
1314

1415
/**
@@ -18,6 +19,11 @@ class EavAttribute
1819
{
1920
const DEFAULT_STORE_ID = 0;
2021

22+
/**
23+
* @var SwatchResource
24+
*/
25+
private $swatchResource;
26+
2127
/**
2228
* Base option title used for string operations to detect is option already exists or new
2329
*/
@@ -64,17 +70,20 @@ class EavAttribute
6470
* @param \Magento\Swatches\Model\SwatchFactory $swatchFactory
6571
* @param \Magento\Swatches\Helper\Data $swatchHelper
6672
* @param Json|null $serializer
73+
* @param SwatchResource|null $swatchResource
6774
*/
6875
public function __construct(
6976
\Magento\Swatches\Model\ResourceModel\Swatch\CollectionFactory $collectionFactory,
7077
\Magento\Swatches\Model\SwatchFactory $swatchFactory,
7178
\Magento\Swatches\Helper\Data $swatchHelper,
72-
Json $serializer = null
79+
Json $serializer = null,
80+
SwatchResource $swatchResource = null
7381
) {
7482
$this->swatchCollectionFactory = $collectionFactory;
7583
$this->swatchFactory = $swatchFactory;
7684
$this->swatchHelper = $swatchHelper;
7785
$this->serializer = $serializer ?: ObjectManager::getInstance()->create(Json::class);
86+
$this->swatchResource = $swatchResource ?: ObjectManager::getInstance()->create(SwatchResource::class);
7887
}
7988

8089
/**
@@ -148,6 +157,7 @@ protected function setProperOptionsArray(Attribute $attribute)
148157
* Prepare attribute for conversion from any swatch type to dropdown
149158
*
150159
* @param Attribute $attribute
160+
* @throws \Magento\Framework\Exception\LocalizedException
151161
* @return void
152162
*/
153163
protected function convertSwatchToDropdown(Attribute $attribute)
@@ -157,6 +167,7 @@ protected function convertSwatchToDropdown(Attribute $attribute)
157167
if (!empty($additionalData)) {
158168
$additionalData = $this->serializer->unserialize($additionalData);
159169
if (is_array($additionalData) && isset($additionalData[Swatch::SWATCH_INPUT_TYPE_KEY])) {
170+
$this->cleanEavAttributeOptionSwatchValues($attribute->getOption());
160171
unset($additionalData[Swatch::SWATCH_INPUT_TYPE_KEY]);
161172
$attribute->setData('additional_data', $this->serializer->serialize($additionalData));
162173
}
@@ -235,6 +246,7 @@ protected function saveSwatchParams(Attribute $attribute)
235246
{
236247
if ($this->swatchHelper->isVisualSwatch($attribute)) {
237248
$this->processVisualSwatch($attribute);
249+
$this->cleanTextSwatchValuesAfterSwitch($attribute->getOptiontext());
238250
} elseif ($this->swatchHelper->isTextSwatch($attribute)) {
239251
$this->processTextualSwatch($attribute);
240252
}
@@ -267,6 +279,33 @@ protected function processVisualSwatch(Attribute $attribute)
267279
}
268280
}
269281

282+
/**
283+
* Clean swatch option values after switching to the dropdown type.
284+
*
285+
* @param array $attributeOptions
286+
* @param null $swatchType
287+
* @throws \Magento\Framework\Exception\LocalizedException
288+
*/
289+
private function cleanEavAttributeOptionSwatchValues($attributeOptions, $swatchType = null)
290+
{
291+
if (count($attributeOptions) && isset($attributeOptions['value'])) {
292+
$optionsIDs = array_keys($attributeOptions['value']);
293+
294+
$this->swatchResource->clearSwatchOptionByOptionIdAndType($optionsIDs, $swatchType);
295+
}
296+
}
297+
298+
/**
299+
* Cleaning the text type of swatch option values after switching.
300+
*
301+
* @param array $attributeOptions
302+
* @throws \Magento\Framework\Exception\LocalizedException
303+
*/
304+
private function cleanTextSwatchValuesAfterSwitch($attributeOptions)
305+
{
306+
$this->cleanEavAttributeOptionSwatchValues($attributeOptions, Swatch::SWATCH_TYPE_TEXTUAL);
307+
}
308+
270309
/**
271310
* @param string $value
272311
* @return int
@@ -432,7 +471,7 @@ protected function validateOptions(Attribute $attribute)
432471
$options = $attribute->getData('optiontext');
433472
}
434473
if ($options && !$this->isOptionsValid($options, $attribute)) {
435-
throw new InputException(__('Admin is a required field in the each row'));
474+
throw new InputException(__('Admin is a required field in each row'));
436475
}
437476
return true;
438477
}

app/code/Magento/Swatches/Model/ResourceModel/Swatch.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,24 @@ public function saveDefaultSwatchOption($id, $defaultValue)
3737
$this->getConnection()->update($this->getTable('eav_attribute'), $bind, $where);
3838
}
3939
}
40+
41+
/**
42+
* Cleaned swatch option values when switching to dropdown input type
43+
*
44+
* @param $optionIDs
45+
* @param $type
46+
* @throws \Magento\Framework\Exception\LocalizedException
47+
*/
48+
public function clearSwatchOptionByOptionIdAndType($optionIDs, $type = null)
49+
{
50+
if (count($optionIDs)) {
51+
foreach ($optionIDs as $optionId) {
52+
$where = ['option_id' => $optionId];
53+
if ($type !== null) {
54+
$where['type = ?'] = $type;
55+
}
56+
$this->getConnection()->delete($this->getMainTable(), $where);
57+
}
58+
}
59+
}
4060
}

app/code/Magento/Swatches/Test/Unit/Model/SwatchAttributesProviderTest.php

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\Swatches\Test\Unit\Model;
78

89
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
9-
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
1010
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1111
use Magento\Swatches\Model\SwatchAttributeCodes;
1212
use Magento\Swatches\Model\SwatchAttributesProvider;
@@ -35,26 +35,26 @@ class SwatchAttributesProviderTest extends \PHPUnit\Framework\TestCase
3535
private $productMock;
3636

3737
/**
38-
* @var SwatchAttributeType|\PHPUnit_Framework_MockObject_MockObject
38+
* @var SwatchAttributeType | \PHPUnit_Framework_MockObject_MockObject
3939
*/
40-
private $swatchTypeCheckerMock;
40+
private $swatchTypeChecker;
4141

4242
protected function setUp()
4343
{
4444
$this->typeConfigurable = $this->createPartialMock(
4545
Configurable::class,
46-
['getConfigurableAttributes', 'getCodes']
46+
['getConfigurableAttributes', 'getCodes', 'getProductAttribute']
4747
);
4848

4949
$this->swatchAttributeCodes = $this->createMock(SwatchAttributeCodes::class);
5050

5151
$this->productMock = $this->createPartialMock(\Magento\Catalog\Model\Product::class, ['getId', 'getTypeId']);
52-
$this->swatchTypeCheckerMock = $this->createMock(SwatchAttributeType::class);
52+
$this->swatchTypeChecker = $this->createMock(SwatchAttributeType::class);
5353

5454
$this->swatchAttributeProvider = (new ObjectManager($this))->getObject(SwatchAttributesProvider::class, [
5555
'typeConfigurable' => $this->typeConfigurable,
5656
'swatchAttributeCodes' => $this->swatchAttributeCodes,
57-
'swatchTypeChecker' => $this->swatchTypeCheckerMock,
57+
'swatchTypeChecker' => $this->swatchTypeChecker,
5858
]);
5959
}
6060

@@ -64,8 +64,9 @@ public function testProvide()
6464
$this->productMock->method('getTypeId')
6565
->willReturn(Configurable::TYPE_CODE);
6666

67-
$productAttributeMock = $this->getMockBuilder(Attribute::class)
67+
$attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
6868
->disableOriginalConstructor()
69+
->setMethods(['setStoreId', 'getData', 'setData', 'getSource', 'hasData'])
6970
->getMock();
7071

7172
$configAttributeMock = $this->createPartialMock(
@@ -78,7 +79,7 @@ public function testProvide()
7879

7980
$configAttributeMock
8081
->method('getProductAttribute')
81-
->willReturn($productAttributeMock);
82+
->willReturn($attributeMock);
8283

8384
$this->typeConfigurable
8485
->method('getConfigurableAttributes')
@@ -90,12 +91,10 @@ public function testProvide()
9091
->method('getCodes')
9192
->willReturn($swatchAttributes);
9293

93-
$this->swatchTypeCheckerMock->expects($this->once())->method('isSwatchAttribute')->willReturn(true);
94+
$this->swatchTypeChecker->expects($this->once())->method('isSwatchAttribute')->willReturn(true);
95+
9496
$result = $this->swatchAttributeProvider->provide($this->productMock);
9597

96-
$this->assertEquals(
97-
[1 => $productAttributeMock],
98-
$result
99-
);
98+
$this->assertEquals([1 => $attributeMock], $result);
10099
}
101100
}

0 commit comments

Comments
 (0)