Skip to content

Commit b33c4b2

Browse files
committed
MAGETWO-94819: Swatch validation breaks the whole attribute form
1 parent d1cbcc0 commit b33c4b2

File tree

6 files changed

+85
-82
lines changed

6 files changed

+85
-82
lines changed

app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Magento\Catalog\Controller\Adminhtml\Product\Attribute;
1515
use Magento\Catalog\Helper\Product;
1616
use Magento\Catalog\Model\Product\Attribute\Frontend\Inputtype\Presentation;
17-
use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer;
17+
use Magento\Framework\Serialize\Serializer\FormData;
1818
use Magento\Catalog\Model\Product\AttributeSet\BuildFactory;
1919
use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory;
2020
use Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\Validator;
@@ -80,9 +80,9 @@ class Save extends Attribute implements HttpPostActionInterface
8080
private $presentation;
8181

8282
/**
83-
* @var OptionsDataSerializer|null
83+
* @var FormData|null
8484
*/
85-
private $optionsDataSerializer;
85+
private $dataSerializer;
8686

8787
/**
8888
* @param Context $context
@@ -97,7 +97,7 @@ class Save extends Attribute implements HttpPostActionInterface
9797
* @param Product $productHelper
9898
* @param LayoutFactory $layoutFactory
9999
* @param Presentation|null $presentation
100-
* @param OptionsDataSerializer|null $optionsDataSerializer
100+
* @param FormData|null $dataSerializer
101101
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
102102
*/
103103
public function __construct(
@@ -113,7 +113,7 @@ public function __construct(
113113
Product $productHelper,
114114
LayoutFactory $layoutFactory,
115115
Presentation $presentation = null,
116-
OptionsDataSerializer $optionsDataSerializer = null
116+
FormData $dataSerializer = null
117117
) {
118118
parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory);
119119
$this->buildFactory = $buildFactory;
@@ -124,8 +124,8 @@ public function __construct(
124124
$this->groupCollectionFactory = $groupCollectionFactory;
125125
$this->layoutFactory = $layoutFactory;
126126
$this->presentation = $presentation ?: ObjectManager::getInstance()->get(Presentation::class);
127-
$this->optionsDataSerializer = $optionsDataSerializer
128-
?: ObjectManager::getInstance()->get(OptionsDataSerializer::class);
127+
$this->dataSerializer = $dataSerializer
128+
?: ObjectManager::getInstance()->get(FormData::class);
129129
}
130130

131131
/**
@@ -140,7 +140,7 @@ public function __construct(
140140
public function execute()
141141
{
142142
try {
143-
$optionData = $this->optionsDataSerializer
143+
$optionData = $this->dataSerializer
144144
->unserialize($this->getRequest()->getParam('serialized_options', '[]'));
145145
} catch (\InvalidArgumentException $e) {
146146
$message = __("The attribute couldn't be saved due to an error. Verify your information and try again. "

app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute;
99

10-
use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer;
10+
use Magento\Framework\Serialize\Serializer\FormData;
1111
use Magento\Framework\App\Action\HttpGetActionInterface;
1212
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
1313
use Magento\Framework\App\ObjectManager;
@@ -39,9 +39,9 @@ class Validate extends AttributeAction implements HttpGetActionInterface, HttpPo
3939
private $multipleAttributeList;
4040

4141
/**
42-
* @var OptionsDataSerializer|null
42+
* @var FormData|null
4343
*/
44-
private $optionsDataSerializer;
44+
private $dataSerializer;
4545

4646
/**
4747
* Constructor
@@ -53,7 +53,7 @@ class Validate extends AttributeAction implements HttpGetActionInterface, HttpPo
5353
* @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
5454
* @param \Magento\Framework\View\LayoutFactory $layoutFactory
5555
* @param array $multipleAttributeList
56-
* @param OptionsDataSerializer|null $optionsDataSerializer
56+
* @param FormData|null $dataSerializer
5757
*/
5858
public function __construct(
5959
\Magento\Backend\App\Action\Context $context,
@@ -63,14 +63,14 @@ public function __construct(
6363
\Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
6464
\Magento\Framework\View\LayoutFactory $layoutFactory,
6565
array $multipleAttributeList = [],
66-
OptionsDataSerializer $optionsDataSerializer = null
66+
FormData $dataSerializer = null
6767
) {
6868
parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory);
6969
$this->resultJsonFactory = $resultJsonFactory;
7070
$this->layoutFactory = $layoutFactory;
7171
$this->multipleAttributeList = $multipleAttributeList;
72-
$this->optionsDataSerializer = $optionsDataSerializer ?: ObjectManager::getInstance()
73-
->get(OptionsDataSerializer::class);
72+
$this->dataSerializer = $dataSerializer ?: ObjectManager::getInstance()
73+
->get(FormData::class);
7474
}
7575

7676
/**
@@ -85,7 +85,7 @@ public function execute()
8585
$response = new DataObject();
8686
$response->setError(false);
8787
try {
88-
$optionsData = $this->optionsDataSerializer
88+
$optionsData = $this->dataSerializer
8989
->unserialize($this->getRequest()->getParam('serialized_options', '[]'));
9090
} catch (\InvalidArgumentException $e) {
9191
$message = __("The attribute couldn't be validated due to an error. Verify your information and try again. "

app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataSerializer.php

Lines changed: 0 additions & 50 deletions
This file was deleted.

app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
use Magento\Catalog\Api\Data\ProductAttributeInterface;
99
use Magento\Catalog\Controller\Adminhtml\Product\Attribute\Save;
10-
use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer;
10+
use Magento\Framework\Serialize\Serializer\FormData;
1111
use Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\AttributeTest;
1212
use Magento\Catalog\Model\Product\AttributeSet\BuildFactory;
1313
use Magento\Catalog\Model\Product\AttributeSet\Build;
@@ -85,9 +85,9 @@ class SaveTest extends AttributeTest
8585
protected $inputTypeValidatorMock;
8686

8787
/**
88-
* @var OptionsDataSerializer|\PHPUnit_Framework_MockObject_MockObject
88+
* @var FormData|\PHPUnit_Framework_MockObject_MockObject
8989
*/
90-
private $optionsDataSerializerMock;
90+
private $dataSerializerMock;
9191

9292
/**
9393
* @var ProductAttributeInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -135,7 +135,7 @@ protected function setUp()
135135
$this->inputTypeValidatorMock = $this->getMockBuilder(InputTypeValidator::class)
136136
->disableOriginalConstructor()
137137
->getMock();
138-
$this->optionsDataSerializerMock = $this->getMockBuilder(OptionsDataSerializer::class)
138+
$this->dataSerializerMock = $this->getMockBuilder(FormData::class)
139139
->disableOriginalConstructor()
140140
->getMock();
141141
$this->productAttributeMock = $this->getMockBuilder(ProductAttributeInterface::class)
@@ -170,7 +170,7 @@ protected function getModel()
170170
'validatorFactory' => $this->validatorFactoryMock,
171171
'groupCollectionFactory' => $this->groupCollectionFactoryMock,
172172
'layoutFactory' => $this->layoutFactoryMock,
173-
'optionsDataSerializer' => $this->optionsDataSerializerMock,
173+
'dataSerializer' => $this->dataSerializerMock,
174174
]);
175175
}
176176

@@ -182,7 +182,7 @@ public function testExecuteWithEmptyData()
182182
['isAjax', null, null],
183183
['serialized_options', '[]', ''],
184184
]);
185-
$this->optionsDataSerializerMock
185+
$this->dataSerializerMock
186186
->expects($this->once())
187187
->method('unserialize')
188188
->with('')
@@ -213,7 +213,7 @@ public function testExecute()
213213
['isAjax', null, null],
214214
['serialized_options', '[]', ''],
215215
]);
216-
$this->optionsDataSerializerMock
216+
$this->dataSerializerMock
217217
->expects($this->once())
218218
->method('unserialize')
219219
->with('')
@@ -273,7 +273,7 @@ public function testExecuteWithOptionsDataError()
273273
['isAjax', null, true],
274274
['serialized_options', '[]', $serializedOptions],
275275
]);
276-
$this->optionsDataSerializerMock
276+
$this->dataSerializerMock
277277
->expects($this->once())
278278
->method('unserialize')
279279
->with($serializedOptions)

app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Attribute;
77

88
use Magento\Catalog\Controller\Adminhtml\Product\Attribute\Validate;
9-
use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer;
9+
use Magento\Framework\Serialize\Serializer\FormData;
1010
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
1111
use Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\AttributeTest;
1212
use Magento\Eav\Model\Entity\Attribute\Set as AttributeSet;
@@ -63,9 +63,9 @@ class ValidateTest extends AttributeTest
6363
protected $layoutMock;
6464

6565
/**
66-
* @var OptionsDataSerializer|\PHPUnit_Framework_MockObject_MockObject
66+
* @var FormData|\PHPUnit_Framework_MockObject_MockObject
6767
*/
68-
private $optionsDataSerializerMock;
68+
private $dataSerializerMock;
6969

7070
protected function setUp()
7171
{
@@ -92,7 +92,7 @@ protected function setUp()
9292
->getMock();
9393
$this->layoutMock = $this->getMockBuilder(LayoutInterface::class)
9494
->getMockForAbstractClass();
95-
$this->optionsDataSerializerMock = $this->getMockBuilder(OptionsDataSerializer::class)
95+
$this->dataSerializerMock = $this->getMockBuilder(FormData::class)
9696
->disableOriginalConstructor()
9797
->getMock();
9898

@@ -116,7 +116,7 @@ protected function getModel()
116116
'resultJsonFactory' => $this->resultJsonFactoryMock,
117117
'layoutFactory' => $this->layoutFactoryMock,
118118
'multipleAttributeList' => ['select' => 'option'],
119-
'optionsDataSerializer' => $this->optionsDataSerializerMock,
119+
'dataSerializer' => $this->dataSerializerMock,
120120
]
121121
);
122122
}
@@ -184,7 +184,7 @@ public function testUniqueValidation(array $options, $isError)
184184
['serialized_options', '[]', $serializedOptions],
185185
]);
186186

187-
$this->optionsDataSerializerMock
187+
$this->dataSerializerMock
188188
->expects($this->once())
189189
->method('unserialize')
190190
->with($serializedOptions)
@@ -319,7 +319,7 @@ public function testEmptyOption(array $options, $result)
319319
['serialized_options', '[]', $serializedOptions],
320320
]);
321321

322-
$this->optionsDataSerializerMock
322+
$this->dataSerializerMock
323323
->expects($this->once())
324324
->method('unserialize')
325325
->with($serializedOptions)
@@ -431,7 +431,7 @@ public function testExecuteWithOptionsDataError()
431431
['serialized_options', '[]', $serializedOptions],
432432
]);
433433

434-
$this->optionsDataSerializerMock
434+
$this->dataSerializerMock
435435
->expects($this->once())
436436
->method('unserialize')
437437
->with($serializedOptions)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Framework\Serialize\Serializer;
10+
11+
/**
12+
* Class for processing of serialized form data.
13+
*/
14+
class FormData
15+
{
16+
/**
17+
* @var Json
18+
*/
19+
private $serializer;
20+
21+
/**
22+
* @param Json $serializer
23+
*/
24+
public function __construct(Json $serializer)
25+
{
26+
$this->serializer = $serializer;
27+
}
28+
29+
/**
30+
* Provides form data from the serialized data.
31+
*
32+
* @param string $serializedData
33+
* @return array
34+
* @throws \InvalidArgumentException
35+
*/
36+
public function unserialize(string $serializedData): array
37+
{
38+
$encodedFields = $this->serializer->unserialize($serializedData);
39+
40+
if (!is_array($encodedFields)) {
41+
throw new \InvalidArgumentException('Unable to unserialize value.');
42+
}
43+
44+
$formData = [];
45+
foreach ($encodedFields as $item) {
46+
$decodedFieldData = [];
47+
parse_str($item, $decodedFieldData);
48+
$formData = array_replace_recursive($formData, $decodedFieldData);
49+
}
50+
51+
return $formData;
52+
}
53+
}

0 commit comments

Comments
 (0)