Skip to content

Commit 2fd7b2d

Browse files
author
Stanislav Idolov
authored
MAGETWO-87851: [Forwardport] #13551 Fix json encoded attribute backend type to not encode attribute value multiple times #13640
2 parents b335359 + 47912b4 commit 2fd7b2d

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,6 @@ public function execute()
202202
}
203203
}
204204

205-
$data = $this->presentation->convertPresentationDataToInputType($data);
206-
207205
if ($attributeId) {
208206
if (!$model->getId()) {
209207
$this->messageManager->addErrorMessage(__('This attribute no longer exists.'));
@@ -218,6 +216,7 @@ public function execute()
218216

219217
$data['attribute_code'] = $model->getAttributeCode();
220218
$data['is_user_defined'] = $model->getIsUserDefined();
219+
$data['frontend_input'] = $model->getFrontendInput();
221220
} else {
222221
/**
223222
* @todo add to helper and specify all relations for properties
@@ -230,6 +229,8 @@ public function execute()
230229
);
231230
}
232231

232+
$data = $this->presentation->convertPresentationDataToInputType($data);
233+
233234
$data += ['is_filterable' => 0, 'is_filterable_in_search' => 0];
234235

235236
if ($model->getIsUserDefined() === null || $model->getIsUserDefined() != 0) {

app/code/Magento/Eav/Model/Entity/Attribute/Backend/JsonEncoded.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function beforeSave($object)
4141
{
4242
// parent::beforeSave() is not called intentionally
4343
$attrCode = $this->getAttribute()->getAttributeCode();
44-
if ($object->hasData($attrCode)) {
44+
if ($object->hasData($attrCode) && !$this->isJsonEncoded($object->getData($attrCode))) {
4545
$object->setData($attrCode, $this->jsonSerializer->serialize($object->getData($attrCode)));
4646
}
4747
return $this;
@@ -61,4 +61,24 @@ public function afterLoad($object)
6161
$object->setData($attrCode, $this->jsonSerializer->unserialize($object->getData($attrCode) ?: '{}'));
6262
return $this;
6363
}
64+
65+
/**
66+
* Returns true if given value is a valid json value, and false otherwise.
67+
*
68+
* @param string|int|float|bool|array|null $value
69+
* @return bool
70+
*/
71+
private function isJsonEncoded($value): bool
72+
{
73+
$result = is_string($value);
74+
if ($result) {
75+
try {
76+
$this->jsonSerializer->unserialize($value);
77+
} catch (\InvalidArgumentException $e) {
78+
$result = false;
79+
}
80+
}
81+
82+
return $result;
83+
}
6484
}

app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Backend/JsonEncodedTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,25 @@ public function testBeforeSave()
8282
$this->assertEquals(json_encode([1, 2, 3]), $product->getData('json_encoded'));
8383
}
8484

85+
/**
86+
* Test before save handler with already encoded attribute value
87+
*/
88+
public function testBeforeSaveWithAlreadyEncodedValue()
89+
{
90+
$product = new \Magento\Framework\DataObject(
91+
[
92+
'json_encoded' => [1, 2, 3]
93+
]
94+
);
95+
96+
// save twice
97+
$this->model->beforeSave($product);
98+
$this->model->beforeSave($product);
99+
100+
// check it is encoded only once
101+
$this->assertEquals(json_encode([1, 2, 3]), $product->getData('json_encoded'));
102+
}
103+
85104
/**
86105
* Test after load handler
87106
*/

0 commit comments

Comments
 (0)