From b75fc4f83aa2fdf093ceae25449fa0b95bbc4020 Mon Sep 17 00:00:00 2001 From: Robert He Date: Mon, 15 Aug 2016 12:20:18 -0500 Subject: [PATCH] MAGETWO-54653: Adding too many configurable product option causes browser to hang. - serialize configurable-matrix and associate_product_ids when editing a configurable product with many variations --- .../Controller/Adminhtml/Product/Save.php | 25 +++++++++++++++++++ .../Helper/Plugin/Configurable.php | 11 ++++++-- .../Helper/Plugin/UpdateConfigurations.php | 6 ++++- .../Helper/Plugin/ConfigurableTest.php | 8 +++--- .../Plugin/UpdateConfigurationsTest.php | 2 +- .../adminhtml/web/js/variations/variations.js | 6 +++++ .../ConfigurableAttributesData.php | 1 - .../Test/Handler/ConfigurableProduct/Curl.php | 5 +++- .../Controller/Adminhtml/ProductTest.php | 3 ++- 9 files changed, 56 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php index d437e467e5daa..4dfd0fdb90155 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php @@ -97,6 +97,7 @@ public function execute() $productTypeId = $this->getRequest()->getParam('type'); if ($data) { try { + $this->unserializeProductData($data); $product = $this->initializationHelper->initialize( $this->productBuilder->build($this->getRequest()) ); @@ -180,6 +181,30 @@ public function execute() return $resultRedirect; } + /** + * Unserialize product data for configurable products + * + * @param array $postData + * @return void + */ + private function unserializeProductData($postData) + { + if (isset($postData["configurable-matrix-serialized"])) { + $configurableMatrixSerialized = $postData["configurable-matrix-serialized"]; + if ($configurableMatrixSerialized != null && !empty($configurableMatrixSerialized)) { + $postData["configurable-matrix"] = json_decode($configurableMatrixSerialized, true); + unset($postData["configurable-matrix-serialized"]); + } + } + if (isset($postData["associated_product_ids_serialized"])) { + $associatedProductIdsSerialized = $postData["associated_product_ids_serialized"]; + if ($associatedProductIdsSerialized != null && !empty($associatedProductIdsSerialized)) { + $postData["associated_product_ids"] = json_decode($associatedProductIdsSerialized, true); + unset($postData["associated_product_ids_serialized"]); + } + } + } + /** * Notify customer when image was not deleted in specific case. * TODO: temporary workaround must be eliminated in MAGETWO-45306 diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php index df7ceda95692d..4602dc5a1dde5 100644 --- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php @@ -127,7 +127,11 @@ public function afterInitialize(Helper $subject, ProductInterface $product) */ private function setLinkedProducts(ProductInterface $product, ProductExtensionInterface $extensionAttributes) { - $associatedProductIds = $this->request->getPost('associated_product_ids', []); + $associatedProductIds = $this->request->getPost('associated_product_ids_serialized', '[]'); + if ($associatedProductIds != null && !empty($associatedProductIds)) { + $associatedProductIds = json_decode($associatedProductIds, true); + } + $variationsMatrix = $this->getVariationMatrix(); if ($associatedProductIds || $variationsMatrix) { @@ -149,7 +153,10 @@ private function setLinkedProducts(ProductInterface $product, ProductExtensionIn protected function getVariationMatrix() { $result = []; - $configurableMatrix = $this->request->getParam('configurable-matrix', []); + $configurableMatrix = $this->request->getParam('configurable-matrix-serialized', '[]'); + if ($configurableMatrix != null && !empty($configurableMatrix)) { + $configurableMatrix = json_decode($configurableMatrix, true); + } foreach ($configurableMatrix as $item) { if ($item['newProduct']) { diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurations.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurations.php index c2f825205875f..ea24235b0fe2e 100644 --- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurations.php +++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurations.php @@ -85,7 +85,11 @@ public function afterInitialize( protected function getConfigurations() { $result = []; - $configurableMatrix = $this->request->getParam('configurable-matrix', []); + $configurableMatrix = $this->request->getParam('configurable-matrix-serialized', '[]'); + if ($configurableMatrix != null && !empty($configurableMatrix)) { + $configurableMatrix = json_decode($configurableMatrix, true); + } + foreach ($configurableMatrix as $item) { if (!$item['newProduct']) { $result[$item['id']] = $this->mapData($item); diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/ConfigurableTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/ConfigurableTest.php index 35afe5fd261a6..05e9938cf522e 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/ConfigurableTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/ConfigurableTest.php @@ -101,7 +101,7 @@ public function testAfterInitializeWithAttributesAndVariations() ]; $valueMap = [ ['new-variations-attribute-set-id', null, 24], - ['associated_product_ids', [], []], + ['associated_product_ids_serialized', '[]', []], ['product', [], ['configurable_attributes_data' => $attributes]], ]; $simpleProductsIds = [1, 2, 3]; @@ -150,7 +150,7 @@ public function testAfterInitializeWithAttributesAndVariations() ] ]; $paramValueMap = [ - ['configurable-matrix', [], $simpleProducts], + ['configurable-matrix-serialized', '[]', json_encode($simpleProducts)], ['attributes', null, $attributes], ]; @@ -212,11 +212,11 @@ public function testAfterInitializeWithAttributesAndWithoutVariations() ]; $valueMap = [ ['new-variations-attribute-set-id', null, 24], - ['associated_product_ids', [], []], + ['associated_product_ids_serialized', '[]', []], ['product', [], ['configurable_attributes_data' => $attributes]], ]; $paramValueMap = [ - ['configurable-matrix', [], []], + ['configurable-matrix-serialized', '[]', []], ['attributes', null, $attributes], ]; diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurationsTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurationsTest.php index 8be77b93282fb..bed5c96b5216e 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurationsTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/UpdateConfigurationsTest.php @@ -127,7 +127,7 @@ public function testAfterInitialize() ->willReturnMap( [ ['store', 0, 0], - ['configurable-matrix', [], $configurableMatrix] + ['configurable-matrix-serialized', '[]', json_encode($configurableMatrix)] ] ); $this->variationHandlerMock->expects(static::once()) diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js index 6b160c7624265..45bd795572d04 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js @@ -301,6 +301,12 @@ define([ * Chose action for the form save button */ saveFormHandler: function() { + this.source.data["configurable-matrix-serialized"] = + JSON.stringify(this.source.data["configurable-matrix"]); + delete this.source.data["configurable-matrix"]; + this.source.data["associated_product_ids_serialized"] = + JSON.stringify(this.source.data["associated_product_ids"]); + delete this.source.data["associated_product_ids"]; if (this.checkForNewAttributes()) { this.formSaveParams = arguments; this.attributeSetHandlerModal().openModal(); diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct/ConfigurableAttributesData.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct/ConfigurableAttributesData.php index 7782216bd7db5..65f80eb714463 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct/ConfigurableAttributesData.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct/ConfigurableAttributesData.php @@ -313,7 +313,6 @@ protected function prepareVariationsMatrix(array $data) $row ); } - } } diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php index c254535579bc2..402aa6ba0d318 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php @@ -55,7 +55,10 @@ public function prepareData(FixtureInterface $fixture) $data['new-variations-attribute-set-id'] = $attributeSetId; $data['associated_product_ids'] = $this->prepareAssociatedProductIds($configurableAttributesData); - return $this->replaceMappingData($data); + $this->replaceMappingData($data); + $data['configurable-matrix-serialized'] = json_encode($data['configurable-matrix']); + $data['associated_product_ids_serialized'] = json_encode($data['associated_product_ids']); + return $data; } /** diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php index fb107aba17f78..f927c78921620 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php @@ -20,10 +20,11 @@ class ProductTest extends \Magento\TestFramework\TestCase\AbstractBackendControl public function testSaveActionAssociatedProductIds() { $associatedProductIds = [3, 14, 15, 92]; + $associatedProductIdsJSON = json_encode($associatedProductIds); $this->getRequest()->setPostValue( [ 'attributes' => [$this->_getConfigurableAttribute()->getId()], - 'associated_product_ids' => $associatedProductIds, + 'associated_product_ids_serialized' => $associatedProductIdsJSON, ] );