Skip to content

Commit d51a4fd

Browse files
author
Stanislav Idolov
authored
ENGCOM-2870: [Forwardport] Unable to change attribute type from swatch #17750
2 parents 941fa8c + eff86e3 commit d51a4fd

File tree

8 files changed

+82
-22
lines changed

8 files changed

+82
-22
lines changed

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

Lines changed: 43 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,8 @@ 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+
$option = $attribute->getOption() ?: [];
171+
$this->cleanEavAttributeOptionSwatchValues($option);
160172
unset($additionalData[Swatch::SWATCH_INPUT_TYPE_KEY]);
161173
$attribute->setData('additional_data', $this->serializer->serialize($additionalData));
162174
}
@@ -235,6 +247,8 @@ protected function saveSwatchParams(Attribute $attribute)
235247
{
236248
if ($this->swatchHelper->isVisualSwatch($attribute)) {
237249
$this->processVisualSwatch($attribute);
250+
$attributeOptions = $attribute->getOptiontext() ?: [];
251+
$this->cleanTextSwatchValuesAfterSwitch($attributeOptions);
238252
} elseif ($this->swatchHelper->isTextSwatch($attribute)) {
239253
$this->processTextualSwatch($attribute);
240254
}
@@ -267,6 +281,33 @@ protected function processVisualSwatch(Attribute $attribute)
267281
}
268282
}
269283

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

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 array $optionIDs
45+
* @param int $type
46+
* @throws \Magento\Framework\Exception\LocalizedException
47+
*/
48+
public function clearSwatchOptionByOptionIdAndType(array $optionIDs, int $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/Plugin/EavAttributeTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public function testBeforeSaveTextSwatch()
191191

192192
/**
193193
* @expectedException \Magento\Framework\Exception\InputException
194-
* @expectedExceptionMessage Admin is a required field in the each row
194+
* @expectedExceptionMessage Admin is a required field in each row
195195
*/
196196
public function testBeforeSaveWithFailedValidation()
197197
{

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
}

app/code/Magento/Swatches/i18n/en_US.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"Admin is a required field in the each row","Admin is a required field in the each row"
1+
"Admin is a required field in each row","Admin is a required field in each row"
22
"Update Product Preview Image","Update Product Preview Image"
33
"Filtering by this attribute will update the product image on catalog page","Filtering by this attribute will update the product image on catalog page"
44
"Use Product Image for Swatch if Possible","Use Product Image for Swatch if Possible"

app/code/Magento/Ui/i18n/en_US.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ CSV,CSV
180180
"Please enter a valid value from list","Please enter a valid value from list"
181181
"Please enter valid SKU key.","Please enter valid SKU key."
182182
"Please enter a valid number.","Please enter a valid number."
183-
"Admin is a required field in the each row.","Admin is a required field in the each row."
183+
"Admin is a required field in each row.","Admin is a required field in each row."
184184
"Please fix this field.","Please fix this field."
185185
"Please enter a valid date (ISO).","Please enter a valid date (ISO)."
186186
"Please enter only digits.","Please enter only digits."

lib/web/i18n/en_US.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ Submit,Submit
9595
"Please enter valid SKU key.","Please enter valid SKU key."
9696
"Please enter a valid number.","Please enter a valid number."
9797
"This is required field","This is required field"
98-
"Admin is a required field in the each row.","Admin is a required field in the each row."
98+
"Admin is a required field in each row.","Admin is a required field in each row."
9999
"Password cannot be the same as email address.","Password cannot be the same as email address."
100100
"Please fix this field.","Please fix this field."
101101
"Please enter a valid email address.","Please enter a valid email address."

lib/web/mage/validation.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,15 +1562,15 @@
15621562
],
15631563
'required-text-swatch-entry': [
15641564
tableSingleValidation,
1565-
$.mage.__('Admin is a required field in the each row.')
1565+
$.mage.__('Admin is a required field in each row.')
15661566
],
15671567
'required-visual-swatch-entry': [
15681568
tableSingleValidation,
1569-
$.mage.__('Admin is a required field in the each row.')
1569+
$.mage.__('Admin is a required field in each row.')
15701570
],
15711571
'required-dropdown-attribute-entry': [
15721572
tableSingleValidation,
1573-
$.mage.__('Admin is a required field in the each row.')
1573+
$.mage.__('Admin is a required field in each row.')
15741574
],
15751575
'validate-item-quantity': [
15761576
function (value, element, params) {

0 commit comments

Comments
 (0)