Skip to content

Commit 0ff8138

Browse files
author
Oleksii Korshenko
authored
Merge pull request #278 from magento-okapis/MAGETWO-57410-config_vars_form_key
Fixed issue: - MAGETWO-57410: Invalid Form key error is thrown while trying to save a configurable product with variations
2 parents d530867 + 59b8dd6 commit 0ff8138

File tree

10 files changed

+161
-20
lines changed

10 files changed

+161
-20
lines changed

app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,9 @@ public function afterInitialize(Helper $subject, ProductInterface $product)
127127
*/
128128
private function setLinkedProducts(ProductInterface $product, ProductExtensionInterface $extensionAttributes)
129129
{
130-
$associatedProductIds = $this->request->getPost('associated_product_ids', []);
131-
$variationsMatrix = $this->getVariationMatrix();
130+
$associatedProductIds = $product->hasData('associated_product_ids') ?
131+
$product->getData('associated_product_ids') : [];
132+
$variationsMatrix = $this->getVariationMatrixFromProduct($product);
132133

133134
if ($associatedProductIds || $variationsMatrix) {
134135
$this->variationHandler->prepareAttributeSet($product);
@@ -141,10 +142,35 @@ private function setLinkedProducts(ProductInterface $product, ProductExtensionIn
141142
$extensionAttributes->setConfigurableProductLinks(array_filter($associatedProductIds));
142143
}
143144

145+
/**
146+
* Get variation-matrix from product
147+
*
148+
* @param ProductInterface $product
149+
* @return array
150+
*/
151+
private function getVariationMatrixFromProduct(ProductInterface $product)
152+
{
153+
$result = [];
154+
155+
$configurableMatrix = $product->hasData('configurable-matrix') ? $product->getData('configurable-matrix') : [];
156+
foreach ($configurableMatrix as $item) {
157+
if ($item['newProduct']) {
158+
$result[$item['variationKey']] = $this->mapData($item);
159+
160+
if (isset($item['qty'])) {
161+
$result[$item['variationKey']]['quantity_and_stock_status']['qty'] = $item['qty'];
162+
}
163+
}
164+
}
165+
166+
return $result;
167+
}
168+
144169
/**
145170
* Get variation-matrix from request
146171
*
147172
* @return array
173+
* @deprecated
148174
*/
149175
protected function getVariationMatrix()
150176
{

app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurations.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public function afterInitialize(
6363
\Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $subject,
6464
\Magento\Catalog\Model\Product $configurableProduct
6565
) {
66-
$configurations = $this->getConfigurations();
66+
$configurations = $this->getConfigurationsFromProduct($configurableProduct);
6767
$configurations = $this->variationHandler->duplicateImagesForVariations($configurations);
6868
foreach ($configurations as $productId => $productData) {
6969
/** @var \Magento\Catalog\Model\Product $product */
@@ -77,10 +77,36 @@ public function afterInitialize(
7777
return $configurableProduct;
7878
}
7979

80+
/**
81+
* Get configurations from product
82+
*
83+
* @param \Magento\Catalog\Model\Product $configurableProduct
84+
* @return array
85+
*/
86+
private function getConfigurationsFromProduct(\Magento\Catalog\Model\Product $configurableProduct)
87+
{
88+
$result = [];
89+
90+
$configurableMatrix = $configurableProduct->hasData('configurable-matrix') ?
91+
$configurableProduct->getData('configurable-matrix') : [];
92+
foreach ($configurableMatrix as $item) {
93+
if (!$item['newProduct']) {
94+
$result[$item['id']] = $this->mapData($item);
95+
96+
if (isset($item['qty'])) {
97+
$result[$item['id']]['quantity_and_stock_status']['qty'] = $item['qty'];
98+
}
99+
}
100+
}
101+
102+
return $result;
103+
}
104+
80105
/**
81106
* Get configurations from request
82107
*
83108
* @return array
109+
* @deprecated
84110
*/
85111
protected function getConfigurations()
86112
{
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
/**
3+
*
4+
* Copyright © 2016 Magento. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
namespace Magento\ConfigurableProduct\Helper\Product\Configuration;
8+
9+
class SaveProductPlugin
10+
{
11+
/**
12+
* Unserialize product data for configurable products
13+
*
14+
* @param \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $subject
15+
* @param \Magento\Catalog\Model\Product $product
16+
* @param array $productData
17+
*
18+
* @return array
19+
*/
20+
public function beforeInitializeFromData(
21+
\Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $subject,
22+
\Magento\Catalog\Model\Product $product,
23+
array $productData
24+
) {
25+
if (isset($productData["configurable-matrix-serialized"])) {
26+
$configurableMatrixSerialized = $productData["configurable-matrix-serialized"];
27+
if (!empty($configurableMatrixSerialized)) {
28+
$productData["configurable-matrix"] = json_decode($configurableMatrixSerialized, true);
29+
unset($productData["configurable-matrix-serialized"]);
30+
}
31+
}
32+
if (isset($productData["associated_product_ids_serialized"])) {
33+
$associatedProductIdsSerialized = $productData["associated_product_ids_serialized"];
34+
if (!empty($associatedProductIdsSerialized)) {
35+
$productData["associated_product_ids"] = json_decode($associatedProductIdsSerialized, true);
36+
unset($productData["associated_product_ids_serialized"]);
37+
}
38+
}
39+
40+
return [$product, $productData];
41+
}
42+
}

app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/ConfigurableTest.php

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ protected function setUp()
7474
->disableOriginalConstructor()
7575
->setMethods([
7676
'getTypeId', 'setAttributeSetId', 'getExtensionAttributes', 'setNewVariationsAttributeSetId',
77-
'setCanSaveConfigurableAttributes', 'setExtensionAttributes'
77+
'setCanSaveConfigurableAttributes', 'setExtensionAttributes', 'hasData', 'getData'
7878
])
7979
->getMock();
8080

@@ -99,11 +99,7 @@ public function testAfterInitializeWithAttributesAndVariations()
9999
['value_index' => 12], ['value_index' => 13]
100100
]]
101101
];
102-
$valueMap = [
103-
['new-variations-attribute-set-id', null, 24],
104-
['associated_product_ids', [], []],
105-
['product', [], ['configurable_attributes_data' => $attributes]],
106-
];
102+
107103
$simpleProductsIds = [1, 2, 3];
108104
$simpleProducts = [
109105
[
@@ -149,15 +145,39 @@ public function testAfterInitializeWithAttributesAndVariations()
149145
'quantity_and_stock_status' => ['qty' => '3']
150146
]
151147
];
148+
149+
$productData = [
150+
'configurable_attributes_data' => $attributes,
151+
'associated_product_ids' => [],
152+
'configurable-matrix' => $simpleProducts
153+
];
154+
$valueMap = [
155+
['new-variations-attribute-set-id', null, 24],
156+
['product', [], $productData]
157+
];
158+
152159
$paramValueMap = [
153-
['configurable-matrix', [], $simpleProducts],
154-
['attributes', null, $attributes],
160+
['attributes', null, $attributes]
155161
];
156162

157163
$this->product->expects(static::once())
158164
->method('getTypeId')
159165
->willReturn(ConfigurableProduct::TYPE_CODE);
160166

167+
$this->product->expects(static::at(4))
168+
->method('hasData')
169+
->with('associated_product_ids')
170+
->willReturn(false);
171+
$this->product->expects(static::at(5))
172+
->method('hasData')
173+
->with('configurable-matrix')
174+
->willReturn(true);
175+
176+
$this->product->expects(static::at(6))
177+
->method('getData')
178+
->with('configurable-matrix')
179+
->willReturn($simpleProducts);
180+
161181
$this->request->expects(static::any())
162182
->method('getPost')
163183
->willReturnMap($valueMap);
@@ -210,19 +230,30 @@ public function testAfterInitializeWithAttributesAndWithoutVariations()
210230
['value_index' => 12], ['value_index' => 13]
211231
]]
212232
];
233+
234+
$productData = [
235+
'configurable_attributes_data' => $attributes,
236+
'associated_product_ids' => [],
237+
'configurable-matrix' => []
238+
];
239+
213240
$valueMap = [
214241
['new-variations-attribute-set-id', null, 24],
215-
['associated_product_ids', [], []],
216-
['product', [], ['configurable_attributes_data' => $attributes]],
242+
['product', [], $productData],
217243
];
218244
$paramValueMap = [
219-
['configurable-matrix', [], []],
220245
['attributes', null, $attributes],
221246
];
222247

223248
$this->product->expects(static::once())
224249
->method('getTypeId')
225250
->willReturn(ConfigurableProduct::TYPE_CODE);
251+
$this->product->expects(static::any())
252+
->method('hasData')
253+
->willReturn(false);
254+
$this->product->expects(static::at(0))
255+
->method('getData')
256+
->willReturn(ConfigurableProduct::TYPE_CODE);
226257

227258
$this->request->expects(static::any())
228259
->method('getPost')

app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurationsTest.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,18 @@ public function testAfterInitialize()
122122
'product3' => $this->getProductMock($configurations['product3'])
123123
];
124124

125+
$productMock->expects(static::any())
126+
->method('hasData')
127+
->willReturn(true);
128+
$productMock->expects(static::any())
129+
->method('getData')
130+
->with('configurable-matrix')
131+
->willReturn($configurableMatrix);
125132
$this->requestMock->expects(static::any())
126133
->method('getParam')
127134
->willReturnMap(
128135
[
129-
['store', 0, 0],
130-
['configurable-matrix', [], $configurableMatrix]
136+
['store', 0, 0]
131137
]
132138
);
133139
$this->variationHandlerMock->expects(static::once())

app/code/Magento/ConfigurableProduct/etc/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
<type name="Magento\Catalog\Helper\Product\Configuration">
2727
<plugin name="configurable_product" type="Magento\ConfigurableProduct\Helper\Product\Configuration\Plugin" sortOrder="50" />
2828
</type>
29+
<type name="Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper">
30+
<plugin name="configurable_product" type="Magento\ConfigurableProduct\Helper\Product\Configuration\SaveProductPlugin" sortOrder="50" />
31+
</type>
2932
<type name="Magento\Catalog\Model\Entity\Product\Attribute\Group\AttributeMapperInterface">
3033
<plugin name="configurable_product" type="Magento\ConfigurableProduct\Model\Entity\Product\Attribute\Group\AttributeMapper\Plugin" sortOrder="50" />
3134
</type>

app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,12 @@ define([
301301
* Chose action for the form save button
302302
*/
303303
saveFormHandler: function() {
304+
this.source.data["product"]["configurable-matrix-serialized"] =
305+
JSON.stringify(this.source.data["configurable-matrix"]);
306+
delete this.source.data["configurable-matrix"];
307+
this.source.data["product"]["associated_product_ids_serialized"] =
308+
JSON.stringify(this.source.data["associated_product_ids"]);
309+
delete this.source.data["associated_product_ids"];
304310
if (this.checkForNewAttributes()) {
305311
this.formSaveParams = arguments;
306312
this.attributeSetHandlerModal().openModal();

dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct/ConfigurableAttributesData.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,6 @@ protected function prepareVariationsMatrix(array $data)
305305
$row
306306
);
307307
}
308-
309308
}
310309
}
311310

dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ public function prepareData(FixtureInterface $fixture)
5050
$attributeSetId = $data['product']['attribute_set_id'];
5151

5252
$data['product']['configurable_attributes_data'] = $this->prepareAttributesData($configurableAttributesData);
53-
$data['configurable-matrix'] = $this->prepareConfigurableMatrix($fixture);
53+
$data['product']['configurable-matrix-serialized'] = json_encode($this->prepareConfigurableMatrix($fixture));
5454
$data['attributes'] = $this->prepareAttributes($configurableAttributesData);
5555
$data['new-variations-attribute-set-id'] = $attributeSetId;
56-
$data['associated_product_ids'] = $this->prepareAssociatedProductIds($configurableAttributesData);
56+
$data['product']['associated_product_ids_serialized'] =
57+
json_encode($this->prepareAssociatedProductIds($configurableAttributesData));
5758

5859
return $this->replaceMappingData($data);
5960
}

dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ class ProductTest extends \Magento\TestFramework\TestCase\AbstractBackendControl
2020
public function testSaveActionAssociatedProductIds()
2121
{
2222
$associatedProductIds = [3, 14, 15, 92];
23+
$associatedProductIdsJSON = json_encode($associatedProductIds);
2324
$this->getRequest()->setPostValue(
2425
[
2526
'attributes' => [$this->_getConfigurableAttribute()->getId()],
26-
'associated_product_ids' => $associatedProductIds,
27+
'product' => ['associated_product_ids_serialized' => $associatedProductIdsJSON]
2728
]
2829
);
2930

0 commit comments

Comments
 (0)