From 789405db654daf93a51a0a30d1a16a10c7c6b3ad Mon Sep 17 00:00:00 2001 From: Richard BAYET Date: Tue, 22 Jan 2019 18:53:02 +0100 Subject: [PATCH] Fixes #1248 Dropdown attributes values not saved Swatches handling for versions prior to 2.2.6 --- .../Model/Serialize/Serializer/FormData.php | 66 +++++++++++++++ .../Product/Attribute/SavePlugin.php | 81 +++++++++++++++++++ .../Product/Attribute/ValidatePlugin.php | 81 +++++++++++++++++++ .../etc/adminhtml/di.xml | 13 +++ 4 files changed, 241 insertions(+) create mode 100644 src/module-elasticsuite-swatches/Model/Serialize/Serializer/FormData.php create mode 100644 src/module-elasticsuite-swatches/Plugin/Catalog/Controller/Adminhtml/Product/Attribute/SavePlugin.php create mode 100644 src/module-elasticsuite-swatches/Plugin/Catalog/Controller/Adminhtml/Product/Attribute/ValidatePlugin.php diff --git a/src/module-elasticsuite-swatches/Model/Serialize/Serializer/FormData.php b/src/module-elasticsuite-swatches/Model/Serialize/Serializer/FormData.php new file mode 100644 index 000000000..9c889308d --- /dev/null +++ b/src/module-elasticsuite-swatches/Model/Serialize/Serializer/FormData.php @@ -0,0 +1,66 @@ + + * @copyright 2019 Smile + * @license Open Software License ("OSL") v. 3.0 + */ + +namespace Smile\ElasticsuiteSwatches\Model\Serialize\Serializer; + +use Magento\Framework\Serialize\Serializer\Json; + +/** + * Class for processing of serialized form data. + * Copy of \Magento\Framework\Serialize\Serializer\FormData which became available in 2.2.7 + * + * @category Smile + * @package Smile\ElasticsuiteSwatches + */ +class FormData +{ + /** + * @var Json + */ + private $serializer; + + /** + * @param Json $serializer + */ + public function __construct(Json $serializer) + { + $this->serializer = $serializer; + } + + /** + * Provides form data from the serialized data. + * + * @param string $serializedData + * @return array + * @throws \InvalidArgumentException + */ + public function unserialize(string $serializedData): array + { + $encodedFields = $this->serializer->unserialize($serializedData); + + if (!is_array($encodedFields)) { + throw new \InvalidArgumentException('Unable to unserialize value.'); + } + + $formData = []; + foreach ($encodedFields as $item) { + $decodedFieldData = []; + parse_str($item, $decodedFieldData); + $formData = array_replace_recursive($formData, $decodedFieldData); + } + + return $formData; + } +} diff --git a/src/module-elasticsuite-swatches/Plugin/Catalog/Controller/Adminhtml/Product/Attribute/SavePlugin.php b/src/module-elasticsuite-swatches/Plugin/Catalog/Controller/Adminhtml/Product/Attribute/SavePlugin.php new file mode 100644 index 000000000..05fac8da2 --- /dev/null +++ b/src/module-elasticsuite-swatches/Plugin/Catalog/Controller/Adminhtml/Product/Attribute/SavePlugin.php @@ -0,0 +1,81 @@ + + * @copyright 2019 Smile + * @license Open Software License ("OSL") v. 3.0 + */ + +namespace Smile\ElasticsuiteSwatches\Plugin\Catalog\Controller\Adminhtml\Product\Attribute; + +use Smile\ElasticsuiteSwatches\Model\Serialize\Serializer\FormData; +use Magento\Framework\App\ProductMetadataInterface; +use Magento\Catalog\Controller\Adminhtml\Product\Attribute; + +/** + * Plugin to force deserialization of product attribute options if in a version < 2.2.6 where it was introduced. + * + * @category Smile + * @package Smile\ElasticSuiteSwatches + */ +class SavePlugin +{ + /** + * @var FormData + */ + private $formDataSerializer; + + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * SavePlugin constructor. + * + * @param FormData $formDataSerializer Form data serializer/deserializer + * @param ProductMetadataInterface $productMetadata Product metadata interface + */ + public function __construct(FormData $formDataSerializer, ProductMetadataInterface $productMetadata) + { + $this->formDataSerializer = $formDataSerializer; + $this->productMetadata = $productMetadata; + } + + /** + * Before Plugin : if Magento version is < 2.2.6, deserialize attributes options + * before re-inserting them in the request + * + * @param Attribute\Save $subject Controller + * + * @return void + */ + public function beforeExecute(Attribute\Save $subject) + { + if (version_compare($this->productMetadata->getVersion(), '2.2.6', '<')) { + try { + $optionData = $this->formDataSerializer->unserialize( + $subject->getRequest()->getParam('serialized_options', '[]') + ); + } catch (\InvalidArgumentException $e) { + return; + } + + $data = $subject->getRequest()->getPostValue(); + unset($data['serialized_options']); + $data = array_replace_recursive( + $data, + $optionData + ); + + $subject->getRequest()->setPostValue($data); + } + } +} diff --git a/src/module-elasticsuite-swatches/Plugin/Catalog/Controller/Adminhtml/Product/Attribute/ValidatePlugin.php b/src/module-elasticsuite-swatches/Plugin/Catalog/Controller/Adminhtml/Product/Attribute/ValidatePlugin.php new file mode 100644 index 000000000..fca6cde08 --- /dev/null +++ b/src/module-elasticsuite-swatches/Plugin/Catalog/Controller/Adminhtml/Product/Attribute/ValidatePlugin.php @@ -0,0 +1,81 @@ + + * @copyright 2019 Smile + * @license Open Software License ("OSL") v. 3.0 + */ + +namespace Smile\ElasticsuiteSwatches\Plugin\Catalog\Controller\Adminhtml\Product\Attribute; + +use Smile\ElasticsuiteSwatches\Model\Serialize\Serializer\FormData; +use Magento\Framework\App\ProductMetadataInterface; +use Magento\Catalog\Controller\Adminhtml\Product\Attribute; + +/** + * Plugin to force deserialization of product attribute options if in a version < 2.2.6 where it was introduced. + * + * @category Smile + * @package Smile\ElasticsuiteSwatches + */ +class ValidatePlugin +{ + /** + * @var FormData + */ + private $formDataSerializer; + + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * ValidatePlugin constructor. + * + * @param FormData $formDataSerializer Form data serializer/deserializer + * @param ProductMetadataInterface $productMetadata Product metadata interface + */ + public function __construct(FormData $formDataSerializer, ProductMetadataInterface $productMetadata) + { + $this->formDataSerializer = $formDataSerializer; + $this->productMetadata = $productMetadata; + } + + /** + * Before Plugin : if Magento version is < 2.2.6, deserialize attributes options + * before re-inserting them in the request + * + * @param Attribute\Validate $subject Controller + * + * @return void + */ + public function beforeExecute(Attribute\Validate $subject) + { + if (version_compare($this->productMetadata->getVersion(), '2.2.6', '<')) { + try { + $optionData = $this->formDataSerializer->unserialize( + $subject->getRequest()->getParam('serialized_options', '[]') + ); + } catch (\InvalidArgumentException $e) { + return; + } + + $data = $subject->getRequest()->getPostValue(); + unset($data['serialized_options']); + $data = array_replace_recursive( + $data, + $optionData + ); + + $subject->getRequest()->setPostValue($data); + } + } +} diff --git a/src/module-elasticsuite-swatches/etc/adminhtml/di.xml b/src/module-elasticsuite-swatches/etc/adminhtml/di.xml index fe54ee5b0..0e113e75a 100644 --- a/src/module-elasticsuite-swatches/etc/adminhtml/di.xml +++ b/src/module-elasticsuite-swatches/etc/adminhtml/di.xml @@ -25,4 +25,17 @@ /> + + + + + + +