diff --git a/app/code/Magento/Bundle/Test/Unit/Block/Adminhtml/Sales/Order/View/Items/RendererTest.php b/app/code/Magento/Bundle/Test/Unit/Block/Adminhtml/Sales/Order/View/Items/RendererTest.php index c800beb080397..974c46a20dc0d 100644 --- a/app/code/Magento/Bundle/Test/Unit/Block/Adminhtml/Sales/Order/View/Items/RendererTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Block/Adminhtml/Sales/Order/View/Items/RendererTest.php @@ -170,7 +170,7 @@ public function getSelectionAttributesDataProvider() { return [ [[], null], - [['bundle_selection_attributes' => 'a:1:{i:0;i:1;}'], [0 => 1]], + [['bundle_selection_attributes' => 'serialized string'], [0 => 1]], ]; } diff --git a/app/code/Magento/Catalog/Setup/UpgradeData.php b/app/code/Magento/Catalog/Setup/UpgradeData.php index 605607d57abd1..a17f80ae623d8 100644 --- a/app/code/Magento/Catalog/Setup/UpgradeData.php +++ b/app/code/Magento/Catalog/Setup/UpgradeData.php @@ -15,7 +15,7 @@ /** * Upgrade Data script - * @codeCoverageIgnore + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class UpgradeData implements UpgradeDataInterface @@ -35,15 +35,25 @@ class UpgradeData implements UpgradeDataInterface private $eavSetupFactory; /** - * Init + * @var UpgradeWidgetData + */ + private $upgradeWidgetData; + + /** + * Constructor * * @param CategorySetupFactory $categorySetupFactory * @param EavSetupFactory $eavSetupFactory + * @param UpgradeWidgetData $upgradeWidgetData */ - public function __construct(CategorySetupFactory $categorySetupFactory, EavSetupFactory $eavSetupFactory) - { + public function __construct( + CategorySetupFactory $categorySetupFactory, + EavSetupFactory $eavSetupFactory, + UpgradeWidgetData $upgradeWidgetData + ) { $this->categorySetupFactory = $categorySetupFactory; $this->eavSetupFactory = $eavSetupFactory; + $this->upgradeWidgetData = $upgradeWidgetData; } /** @@ -366,6 +376,9 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $this->dissallowUsingHtmlForProductName($setup); } + if ($context->getVersion() && version_compare($context->getVersion(), '2.2.1') < 0) { + $this->upgradeWidgetData->upgrade(); + } $setup->endSetup(); } diff --git a/app/code/Magento/Catalog/Setup/UpgradeWidgetData.php b/app/code/Magento/Catalog/Setup/UpgradeWidgetData.php new file mode 100644 index 0000000000000..f9eba413f5416 --- /dev/null +++ b/app/code/Magento/Catalog/Setup/UpgradeWidgetData.php @@ -0,0 +1,120 @@ +eavSetup = $eavSetup; + $this->queryModifierFactory = $queryModifierFactory; + $this->aggregatedFieldDataConverter = $aggregatedFieldDataConverter; + } + + /** + * Convert category and product layout update + * + * @return void + * @throws \InvalidArgumentException + */ + public function upgrade() + { + $categoryTypeId = $this->eavSetup->getEntityTypeId(\Magento\Catalog\Model\Category::ENTITY); + $categoryLayoutUpdateAttribute = $this->eavSetup->getAttribute($categoryTypeId, 'custom_layout_update'); + $categoryLayoutUpdateAttributeModifier = $this->queryModifierFactory->create( + 'in', + [ + 'values' => [ + 'attribute_id' => $categoryLayoutUpdateAttribute['attribute_id'] + ] + ] + ); + $layoutUpdateValueModifier = $this->queryModifierFactory->create( + 'like', + [ + 'values' => [ + 'value' => '%conditions_encoded%' + ] + ] + ); + $categoryLayoutUpdateModifier = $this->queryModifierFactory->create( + 'composite', + [ + 'queryModifiers' => [ + $categoryLayoutUpdateAttributeModifier, + $layoutUpdateValueModifier + ] + ] + ); + $productTypeId = $this->eavSetup->getEntityTypeId(\Magento\Catalog\Model\Product::ENTITY); + $productLayoutUpdateAttribute = $this->eavSetup->getAttribute($productTypeId, 'custom_layout_update'); + $productLayoutUpdateAttributeModifier = $this->queryModifierFactory->create( + 'in', + [ + 'values' => [ + 'attribute_id' => $productLayoutUpdateAttribute['attribute_id'] + ] + ] + ); + $productLayoutUpdateModifier = $this->queryModifierFactory->create( + 'composite', + [ + 'queryModifiers' => [ + $productLayoutUpdateAttributeModifier, + $layoutUpdateValueModifier + ] + ] + ); + $this->aggregatedFieldDataConverter->convert( + [ + new FieldToConvert( + LayoutUpdateConverter::class, + $this->eavSetup->getSetup()->getTable('catalog_category_entity_text'), + 'value_id', + 'value', + $categoryLayoutUpdateModifier + ), + new FieldToConvert( + LayoutUpdateConverter::class, + $this->eavSetup->getSetup()->getTable('catalog_product_entity_text'), + 'value_id', + 'value', + $productLayoutUpdateModifier + ), + ], + $this->eavSetup->getSetup()->getConnection() + ); + } +} diff --git a/app/code/Magento/Catalog/etc/module.xml b/app/code/Magento/Catalog/etc/module.xml index 2434f74cf7961..91bf0075d4e20 100644 --- a/app/code/Magento/Catalog/etc/module.xml +++ b/app/code/Magento/Catalog/etc/module.xml @@ -6,7 +6,7 @@ */ --> - + diff --git a/app/code/Magento/CatalogRule/Setup/UpgradeData.php b/app/code/Magento/CatalogRule/Setup/UpgradeData.php index e1d732f2a115b..7f75b7e41dfac 100644 --- a/app/code/Magento/CatalogRule/Setup/UpgradeData.php +++ b/app/code/Magento/CatalogRule/Setup/UpgradeData.php @@ -6,8 +6,9 @@ namespace Magento\CatalogRule\Setup; -use Magento\Framework\DB\FieldDataConverterFactory; +use Magento\Framework\DB\AggregatedFieldDataConverter; use Magento\Framework\DB\DataConverter\SerializedToJson; +use Magento\Framework\DB\FieldToConvert; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\UpgradeDataInterface; @@ -17,26 +18,26 @@ class UpgradeData implements UpgradeDataInterface { /** - * @var FieldDataConverterFactory + * @var MetadataPool */ - private $fieldDataConverterFactory; + private $metadataPool; /** - * @var MetadataPool + * @var AggregatedFieldDataConverter */ - private $metadataPool; + private $aggregatedFieldConverter; /** * UpgradeData constructor. * - * @param FieldDataConverterFactory $fieldDataConverterFactory + * @param AggregatedFieldDataConverter $aggregatedFieldConverter * @param MetadataPool $metadataPool */ public function __construct( - FieldDataConverterFactory $fieldDataConverterFactory, + AggregatedFieldDataConverter $aggregatedFieldConverter, MetadataPool $metadataPool ) { - $this->fieldDataConverterFactory = $fieldDataConverterFactory; + $this->aggregatedFieldConverter = $aggregatedFieldConverter; $this->metadataPool = $metadataPool; } @@ -63,20 +64,23 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface */ public function convertSerializedDataToJson($setup) { - $fieldDataConverter = $this->fieldDataConverterFactory->create(SerializedToJson::class); $metadata = $this->metadataPool->getMetadata(RuleInterface::class); - - $fieldDataConverter->convert( - $setup->getConnection(), - $setup->getTable('catalogrule'), - $metadata->getLinkField(), - 'conditions_serialized' - ); - $fieldDataConverter->convert( - $setup->getConnection(), - $setup->getTable('catalogrule'), - $metadata->getLinkField(), - 'actions_serialized' + $this->aggregatedFieldConverter->convert( + [ + new FieldToConvert( + SerializedToJson::class, + $setup->getTable('catalogrule'), + $metadata->getLinkField(), + 'conditions_serialized' + ), + new FieldToConvert( + SerializedToJson::class, + $setup->getTable('catalogrule'), + $metadata->getLinkField(), + 'actions_serialized' + ), + ], + $setup->getConnection() ); } } diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/_files/categoryUrlRewritesDataProvider.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/_files/categoryUrlRewritesDataProvider.php deleted file mode 100644 index 77ac90b3bb884..0000000000000 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/_files/categoryUrlRewritesDataProvider.php +++ /dev/null @@ -1,98 +0,0 @@ - CategoryUrlRewriteGenerator::ENTITY_TYPE, - 'entity_id' => 1, - 'store_id' => 1, - 'request_path' => 'test-category.html', - 'target_path' => 'catalog/category/view/id/1', - 'redirect_type' => 0, - 'is_autogenerated' => true, - 'metadata' => null, - ] - ]], - [1, 1, 'test-category.html', [ - [ - UrlRewrite::REQUEST_PATH => 'generate-for-autogenerated.html', - UrlRewrite::TARGET_PATH => 'some-path.html', - UrlRewrite::STORE_ID => 2, - UrlRewrite::IS_AUTOGENERATED => 1, - ], - [ - UrlRewrite::REQUEST_PATH => 'test-category.html', - UrlRewrite::TARGET_PATH => 'skip-generation-due-to-equals-request-and-generated-target-path.html', - UrlRewrite::IS_AUTOGENERATED => 1, - ], - [ - UrlRewrite::REQUEST_PATH => 'generate-for-custom-by-user.html', - UrlRewrite::TARGET_PATH => 'custom-target-path.html', - UrlRewrite::REDIRECT_TYPE => 'some-type', - UrlRewrite::IS_AUTOGENERATED => 0, - UrlRewrite::METADATA => ['is_user_generated' => 1], - ], - [ - UrlRewrite::REQUEST_PATH => 'generate-for-custom-without-redirect-type.html', - UrlRewrite::TARGET_PATH => 'custom-target-path2.html', - UrlRewrite::REDIRECT_TYPE => 0, - UrlRewrite::IS_AUTOGENERATED => 0, - UrlRewrite::METADATA => ['is_user_generated' => false], - ], - [ - UrlRewrite::REQUEST_PATH => 'skip-equals-paths.html', - UrlRewrite::TARGET_PATH => 'skip-equals-paths.html', - UrlRewrite::REDIRECT_TYPE => 0, - UrlRewrite::IS_AUTOGENERATED => 0, - ], - ], [ - [ - 'entity_type' => CategoryUrlRewriteGenerator::ENTITY_TYPE, - 'entity_id' => 1, - 'store_id' => 1, - 'request_path' => 'test-category.html', - 'target_path' => 'catalog/category/view/id/1', - 'redirect_type' => 0, - 'is_autogenerated' => true, - 'metadata' => null, - ], - [ - 'entity_type' => CategoryUrlRewriteGenerator::ENTITY_TYPE, - 'entity_id' => 1, - 'store_id' => 2, - 'request_path' => 'generate-for-autogenerated.html', - 'target_path' => 'test-category.html', - 'redirect_type' => OptionProvider::PERMANENT, - 'is_autogenerated' => false, - 'metadata' => null - ], - [ - 'entity_type' => CategoryUrlRewriteGenerator::ENTITY_TYPE, - 'entity_id' => 1, - 'store_id' => 1, - 'request_path' => 'generate-for-custom-by-user.html', - 'target_path' => 'custom-target-path.html', - 'redirect_type' => 'some-type', - 'is_autogenerated' => false, - 'metadata' => serialize(['is_user_generated' => 1]), - ], - [ - 'entity_type' => CategoryUrlRewriteGenerator::ENTITY_TYPE, - 'entity_id' => 1, - 'store_id' => 1, - 'request_path' => 'generate-for-custom-without-redirect-type.html', - 'target_path' => 'custom-target-path2.html', - 'redirect_type' => 0, - 'is_autogenerated' => false, - 'metadata' => serialize(['is_user_generated' => false]), - ], - ]], -]; diff --git a/app/code/Magento/Cms/Setup/ContentConverter.php b/app/code/Magento/Cms/Setup/ContentConverter.php index 9754108c33f48..705771dea64ff 100644 --- a/app/code/Magento/Cms/Setup/ContentConverter.php +++ b/app/code/Magento/Cms/Setup/ContentConverter.php @@ -5,11 +5,12 @@ */ namespace Magento\Cms\Setup; -use Magento\Widget\Model\Widget\Wysiwyg\Normalizer; +use Magento\Framework\Data\Wysiwyg\Normalizer; use Magento\Framework\DB\DataConverter\DataConversionException; use Magento\Framework\DB\DataConverter\SerializedToJson; use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\Serialize\Serializer\Serialize; +use Magento\Framework\Filter\Template\Tokenizer\ParameterFactory; /** * Convert conditions_encoded part of cms block content data from serialized to JSON format @@ -17,7 +18,7 @@ class ContentConverter extends SerializedToJson { /** - * @var \Magento\Framework\Filter\Template\Tokenizer\ParameterFactory + * @var ParameterFactory */ private $parameterFactory; @@ -31,13 +32,13 @@ class ContentConverter extends SerializedToJson * * @param Serialize $serialize * @param Json $json - * @param \Magento\Framework\Filter\Template\Tokenizer\ParameterFactory $parameterFactory + * @param ParameterFactory $parameterFactory * @param Normalizer $normalizer */ public function __construct( Serialize $serialize, Json $json, - \Magento\Framework\Filter\Template\Tokenizer\ParameterFactory $parameterFactory, + ParameterFactory $parameterFactory, Normalizer $normalizer ) { $this->parameterFactory = $parameterFactory; @@ -70,6 +71,14 @@ public function convert($value) return $convertedValue; } + /** + * @inheritdoc + */ + protected function isValidJsonValue($value) + { + return parent::isValidJsonValue($this->normalizer->restoreReservedCharacters($value)); + } + /** * Convert widget parameters from serialized format to JSON format * @@ -83,11 +92,11 @@ private function convertWidgetParams($paramsString) $tokenizer->setString($paramsString); $widgetParameters = $tokenizer->tokenize(); if (isset($widgetParameters['conditions_encoded'])) { - $conditions = $this->normalizer->restoreReservedCharaters($widgetParameters['conditions_encoded']); - if ($this->isValidJsonValue($conditions)) { + if ($this->isValidJsonValue($widgetParameters['conditions_encoded'])) { return $paramsString; } - $widgetParameters['conditions_encoded'] = $this->normalizer->replaceReservedCharaters( + $conditions = $this->restoreReservedCharactersInSerializedContent($widgetParameters['conditions_encoded']); + $widgetParameters['conditions_encoded'] = $this->normalizer->replaceReservedCharacters( parent::convert($conditions) ); $newParamsString = ''; @@ -99,4 +108,25 @@ private function convertWidgetParams($paramsString) return $paramsString; } } + + /** + * Restore the reserved characters in the existing serialized content + * + * @param string $serializedContent + * @return string + */ + private function restoreReservedCharactersInSerializedContent($serializedContent) + { + $map = [ + '{' => '[', + '}' => ']', + '"' => '`', + '\\' => '|', + ]; + return str_replace( + array_values($map), + array_keys($map), + $serializedContent + ); + } } diff --git a/app/code/Magento/Cms/Setup/UpgradeData.php b/app/code/Magento/Cms/Setup/UpgradeData.php index 3731eb1b3b49f..91bda43d2e0e7 100644 --- a/app/code/Magento/Cms/Setup/UpgradeData.php +++ b/app/code/Magento/Cms/Setup/UpgradeData.php @@ -5,12 +5,17 @@ */ namespace Magento\Cms\Setup; +use Magento\Cms\Api\Data\BlockInterface; +use Magento\Cms\Api\Data\PageInterface; use Magento\Cms\Model\Page; use Magento\Cms\Model\PageFactory; +use Magento\Framework\DB\AggregatedFieldDataConverter; +use Magento\Framework\DB\FieldToConvert; use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\UpgradeDataInterface; +use Magento\Widget\Setup\LayoutUpdateConverter; class UpgradeData implements UpgradeDataInterface { @@ -24,11 +29,6 @@ class UpgradeData implements UpgradeDataInterface */ private $pageFactory; - /** - * @var \Magento\Framework\DB\FieldDataConverterFactory - */ - private $fieldDataConverterFactory; - /** * @var \Magento\Framework\DB\Select\QueryModifierFactory */ @@ -39,22 +39,27 @@ class UpgradeData implements UpgradeDataInterface */ private $metadataPool; + /** + * @var AggregatedFieldDataConverter + */ + private $aggregatedFieldConverter; + /** * UpgradeData constructor. * * @param PageFactory $pageFactory - * @param \Magento\Framework\DB\FieldDataConverterFactory $fieldDataConverterFactory + * @param AggregatedFieldDataConverter $aggregatedFieldConverter * @param \Magento\Framework\DB\Select\QueryModifierFactory $queryModifierFactory * @param MetadataPool $metadataPool */ public function __construct( PageFactory $pageFactory, - \Magento\Framework\DB\FieldDataConverterFactory $fieldDataConverterFactory, + AggregatedFieldDataConverter $aggregatedFieldConverter, \Magento\Framework\DB\Select\QueryModifierFactory $queryModifierFactory, MetadataPool $metadataPool ) { $this->pageFactory = $pageFactory; - $this->fieldDataConverterFactory = $fieldDataConverterFactory; + $this->aggregatedFieldConverter = $aggregatedFieldConverter; $this->queryModifierFactory = $queryModifierFactory; $this->metadataPool = $metadataPool; } @@ -84,10 +89,6 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface */ private function convertWidgetConditionsToJson(ModuleDataSetupInterface $setup) { - $fieldDataConverter = $this->fieldDataConverterFactory->create( - \Magento\Cms\Setup\ContentConverter::class - ); - $queryModifier = $this->queryModifierFactory->create( 'like', [ @@ -96,23 +97,56 @@ private function convertWidgetConditionsToJson(ModuleDataSetupInterface $setup) ] ] ); - - $blockMetadata = $this->metadataPool->getMetadata(\Magento\Cms\Api\Data\BlockInterface::class); - $fieldDataConverter->convert( - $setup->getConnection(), - $setup->getTable('cms_block'), - $blockMetadata->getIdentifierField(), - 'content', - $queryModifier + $layoutUpdateXmlFieldQueryModifier = $this->queryModifierFactory->create( + 'like', + [ + 'values' => [ + 'layout_update_xml' => '%conditions_encoded%' + ] + ] ); - - $pageMetadata = $this->metadataPool->getMetadata(\Magento\Cms\Api\Data\PageInterface::class); - $fieldDataConverter->convert( - $setup->getConnection(), - $setup->getTable('cms_page'), - $pageMetadata->getIdentifierField(), - 'content', - $queryModifier + $customLayoutUpdateXmlFieldQueryModifier = $this->queryModifierFactory->create( + 'like', + [ + 'values' => [ + 'custom_layout_update_xml' => '%conditions_encoded%' + ] + ] + ); + $blockMetadata = $this->metadataPool->getMetadata(BlockInterface::class); + $pageMetadata = $this->metadataPool->getMetadata(PageInterface::class); + $this->aggregatedFieldConverter->convert( + [ + new FieldToConvert( + ContentConverter::class, + $setup->getTable('cms_block'), + $blockMetadata->getIdentifierField(), + 'content', + $queryModifier + ), + new FieldToConvert( + ContentConverter::class, + $setup->getTable('cms_page'), + $pageMetadata->getIdentifierField(), + 'content', + $queryModifier + ), + new FieldToConvert( + LayoutUpdateConverter::class, + $setup->getTable('cms_page'), + $pageMetadata->getIdentifierField(), + 'layout_update_xml', + $layoutUpdateXmlFieldQueryModifier + ), + new FieldToConvert( + LayoutUpdateConverter::class, + $setup->getTable('cms_page'), + $pageMetadata->getIdentifierField(), + 'custom_layout_update_xml', + $customLayoutUpdateXmlFieldQueryModifier + ), + ], + $setup->getConnection() ); } diff --git a/app/code/Magento/Customer/Setup/CustomerSetup.php b/app/code/Magento/Customer/Setup/CustomerSetup.php index 085b2e1ab4f49..b1f07e4872fd8 100644 --- a/app/code/Magento/Customer/Setup/CustomerSetup.php +++ b/app/code/Magento/Customer/Setup/CustomerSetup.php @@ -179,7 +179,7 @@ public function getDefaultEntities() 'label' => 'First Name', 'input' => 'text', 'sort_order' => 40, - 'validate_rules' => 'a:2:{s:15:"max_text_length";i:255;s:15:"min_text_length";i:1;}', + 'validate_rules' => '{"max_text_length":255,"min_text_length":1}', 'position' => 40, ], 'middlename' => [ @@ -197,7 +197,7 @@ public function getDefaultEntities() 'label' => 'Last Name', 'input' => 'text', 'sort_order' => 60, - 'validate_rules' => 'a:2:{s:15:"max_text_length";i:255;s:15:"min_text_length";i:1;}', + 'validate_rules' => '{"max_text_length":255,"min_text_length":1}', 'position' => 60, ], 'suffix' => [ @@ -215,7 +215,7 @@ public function getDefaultEntities() 'label' => 'Email', 'input' => 'text', 'sort_order' => 80, - 'validate_rules' => 'a:1:{s:16:"input_validation";s:5:"email";}', + 'validate_rules' => '{"input_validation":"email"}', 'position' => 80, 'admin_checkout' => 1, ], @@ -240,7 +240,7 @@ public function getDefaultEntities() 'visible' => false, 'system' => false, 'input_filter' => 'date', - 'validate_rules' => 'a:1:{s:16:"input_validation";s:4:"date";}', + 'validate_rules' => '{"input_validation":"date"}', 'position' => 90, 'admin_checkout' => 1, ], @@ -262,7 +262,7 @@ public function getDefaultEntities() 'rp_token_created_at' => [ 'type' => 'static', 'input' => 'date', - 'validate_rules' => 'a:1:{s:16:"input_validation";s:4:"date";}', + 'validate_rules' => '{"input_validation":"date"}', 'required' => false, 'sort_order' => 120, 'visible' => false, @@ -293,7 +293,7 @@ public function getDefaultEntities() 'sort_order' => 100, 'visible' => false, 'system' => false, - 'validate_rules' => 'a:1:{s:15:"max_text_length";i:255;}', + 'validate_rules' => '{"max_text_length":255}', 'position' => 100, 'admin_checkout' => 1, ], @@ -323,7 +323,7 @@ public function getDefaultEntities() 'sort_order' => 110, 'visible' => false, 'system' => false, - 'validate_rules' => 'a:0:{}', + 'validate_rules' => '[]', 'position' => 110, 'admin_checkout' => 1, 'option' => ['values' => ['Male', 'Female']], @@ -363,7 +363,7 @@ public function getDefaultEntities() 'label' => 'First Name', 'input' => 'text', 'sort_order' => 20, - 'validate_rules' => 'a:2:{s:15:"max_text_length";i:255;s:15:"min_text_length";i:1;}', + 'validate_rules' => '{"max_text_length":255,"min_text_length":1}', 'position' => 20, ], 'middlename' => [ @@ -381,7 +381,7 @@ public function getDefaultEntities() 'label' => 'Last Name', 'input' => 'text', 'sort_order' => 40, - 'validate_rules' => 'a:2:{s:15:"max_text_length";i:255;s:15:"min_text_length";i:1;}', + 'validate_rules' => '{"max_text_length":255,"min_text_length":1}', 'position' => 40, ], 'suffix' => [ @@ -400,7 +400,7 @@ public function getDefaultEntities() 'input' => 'text', 'required' => false, 'sort_order' => 60, - 'validate_rules' => 'a:2:{s:15:"max_text_length";i:255;s:15:"min_text_length";i:1;}', + 'validate_rules' => '{"max_text_length":255,"min_text_length":1}', 'position' => 60, ], 'street' => [ @@ -410,7 +410,7 @@ public function getDefaultEntities() 'backend' => \Magento\Eav\Model\Entity\Attribute\Backend\DefaultBackend::class, 'sort_order' => 70, 'multiline_count' => 2, - 'validate_rules' => 'a:2:{s:15:"max_text_length";i:255;s:15:"min_text_length";i:1;}', + 'validate_rules' => '{"max_text_length":255,"min_text_length":1}', 'position' => 70, ], 'city' => [ @@ -418,7 +418,7 @@ public function getDefaultEntities() 'label' => 'City', 'input' => 'text', 'sort_order' => 80, - 'validate_rules' => 'a:2:{s:15:"max_text_length";i:255;s:15:"min_text_length";i:1;}', + 'validate_rules' => '{"max_text_length":255,"min_text_length":1}', 'position' => 80, ], 'country_id' => [ @@ -452,7 +452,7 @@ public function getDefaultEntities() 'label' => 'Zip/Postal Code', 'input' => 'text', 'sort_order' => 110, - 'validate_rules' => 'a:0:{}', + 'validate_rules' => '[]', 'data' => \Magento\Customer\Model\Attribute\Data\Postcode::class, 'position' => 110, 'required' => false, @@ -462,7 +462,7 @@ public function getDefaultEntities() 'label' => 'Phone Number', 'input' => 'text', 'sort_order' => 120, - 'validate_rules' => 'a:2:{s:15:"max_text_length";i:255;s:15:"min_text_length";i:1;}', + 'validate_rules' => '{"max_text_length":255,"min_text_length":1}', 'position' => 120, ], 'fax' => [ @@ -471,7 +471,7 @@ public function getDefaultEntities() 'input' => 'text', 'required' => false, 'sort_order' => 130, - 'validate_rules' => 'a:2:{s:15:"max_text_length";i:255;s:15:"min_text_length";i:1;}', + 'validate_rules' => '{"max_text_length":255,"min_text_length":1}', 'position' => 130, ], ], diff --git a/app/code/Magento/Quote/Setup/ConvertSerializedDataToJson.php b/app/code/Magento/Quote/Setup/ConvertSerializedDataToJson.php index ae733a79a581b..8627a8012f2ed 100644 --- a/app/code/Magento/Quote/Setup/ConvertSerializedDataToJson.php +++ b/app/code/Magento/Quote/Setup/ConvertSerializedDataToJson.php @@ -5,7 +5,9 @@ */ namespace Magento\Quote\Setup; -use Magento\Framework\DB\FieldDataConverterFactory; +use Magento\Framework\DB\AggregatedFieldDataConverter; +use Magento\Framework\DB\DataConverter\SerializedToJson; +use Magento\Framework\DB\FieldToConvert; use Magento\Framework\DB\Select\QueryModifierFactory; use Magento\Framework\DB\Query\Generator; @@ -19,11 +21,6 @@ class ConvertSerializedDataToJson */ private $quoteSetup; - /** - * @var FieldDataConverterFactory - */ - private $fieldDataConverterFactory; - /** * @var QueryModifierFactory */ @@ -34,22 +31,27 @@ class ConvertSerializedDataToJson */ private $queryGenerator; + /** + * @var AggregatedFieldDataConverter + */ + private $aggregatedFieldConverter; + /** * Constructor * * @param QuoteSetup $quoteSetup - * @param FieldDataConverterFactory $fieldDataConverterFactory + * @param AggregatedFieldDataConverter $aggregatedFieldConverter * @param QueryModifierFactory $queryModifierFactory * @param Generator $queryGenerator */ public function __construct( QuoteSetup $quoteSetup, - FieldDataConverterFactory $fieldDataConverterFactory, + AggregatedFieldDataConverter $aggregatedFieldConverter, QueryModifierFactory $queryModifierFactory, Generator $queryGenerator ) { $this->quoteSetup = $quoteSetup; - $this->fieldDataConverterFactory = $fieldDataConverterFactory; + $this->aggregatedFieldConverter = $aggregatedFieldConverter; $this->queryModifierFactory = $queryModifierFactory; $this->queryGenerator = $queryGenerator; } @@ -63,27 +65,6 @@ public function __construct( */ public function convert() { - $fieldDataConverter = $this->fieldDataConverterFactory->create( - \Magento\Framework\DB\DataConverter\SerializedToJson::class - ); - $fieldDataConverter->convert( - $this->quoteSetup->getConnection(), - $this->quoteSetup->getTable('quote_payment'), - 'payment_id', - 'additional_information' - ); - $fieldDataConverter->convert( - $this->quoteSetup->getConnection(), - $this->quoteSetup->getTable('quote_payment'), - 'payment_id', - 'additional_data' - ); - $fieldDataConverter->convert( - $this->quoteSetup->getConnection(), - $this->quoteSetup->getTable('quote_address'), - 'address_id', - 'applied_taxes' - ); $queryModifier = $this->queryModifierFactory->create( 'in', [ @@ -99,13 +80,37 @@ public function convert() ] ] ); - $fieldDataConverter->convert( - $this->quoteSetup->getConnection(), - $this->quoteSetup->getTable('quote_item_option'), - 'option_id', - 'value', - $queryModifier + $this->aggregatedFieldConverter->convert( + [ + new FieldToConvert( + SerializedToJson::class, + $this->quoteSetup->getTable('quote_payment'), + 'payment_id', + 'additional_information' + ), + new FieldToConvert( + SerializedToJson::class, + $this->quoteSetup->getTable('quote_payment'), + 'payment_id', + 'additional_data' + ), + new FieldToConvert( + SerializedToJson::class, + $this->quoteSetup->getTable('quote_address'), + 'address_id', + 'applied_taxes' + ), + new FieldToConvert( + SerializedToJson::class, + $this->quoteSetup->getTable('quote_item_option'), + 'option_id', + 'value', + $queryModifier + ), + ], + $this->quoteSetup->getConnection() ); + $select = $this->quoteSetup->getSetup() ->getConnection() ->select() @@ -134,12 +139,17 @@ function ($id) { ] ] ); - $fieldDataConverter->convert( - $this->quoteSetup->getConnection(), - $this->quoteSetup->getTable('quote_item_option'), - 'option_id', - 'value', - $queryModifier + $this->aggregatedFieldConverter->convert( + [ + new FieldToConvert( + SerializedToJson::class, + $this->quoteSetup->getTable('quote_item_option'), + 'option_id', + 'value', + $queryModifier + ), + ], + $this->quoteSetup->getConnection() ); } } diff --git a/app/code/Magento/Sales/Setup/ConvertSerializedDataToJson.php b/app/code/Magento/Sales/Setup/ConvertSerializedDataToJson.php deleted file mode 100644 index 36f6443b0a81d..0000000000000 --- a/app/code/Magento/Sales/Setup/ConvertSerializedDataToJson.php +++ /dev/null @@ -1,113 +0,0 @@ - 'sales_order_item', - 'identifier' => 'item_id', - 'title' => 'product_options', - 'data_converter' => SerializedDataConverter::class - ], - [ - 'table' => 'sales_shipment', - 'identifier' => 'entity_id', - 'title' => 'packages', - 'data_converter' => SerializedToJson::class - ], - [ - 'table' => 'sales_order_payment', - 'identifier' => 'entity_id', - 'title' => 'additional_information', - 'data_converter' => SalesOrderPaymentDataConverter::class - ], - [ - 'table' => 'sales_payment_transaction', - 'identifier' => 'transaction_id', - 'title' => 'additional_information', - 'data_converter' => SerializedToJson::class - ] - ]; - - /** - * Constructor - * - * @param SalesSetup $salesSetup - * @param FieldDataConverterFactory $fieldDataConverterFactory - */ - public function __construct( - SalesSetup $salesSetup, - FieldDataConverterFactory $fieldDataConverterFactory - ) { - $this->salesSetup = $salesSetup; - $this->fieldDataConverterFactory = $fieldDataConverterFactory; - } - - /** - * Convert data for the following fields from serialized to JSON format: - * sales_order_item.product_options - * sales_shipment.packages - * sales_order_payment.additional_information - * sales_payment_transaction.additional_information - * - * @return void - */ - public function convert() - { - foreach ($this->fieldsToUpdate as $field) { - $fieldDataConverter = $this->getFieldDataConverter($field['data_converter']); - $fieldDataConverter->convert( - $this->salesSetup->getConnection(), - $this->salesSetup->getTable($field['table']), - $field['identifier'], - $field['title'] - ); - } - } - - /** - * Get field data converter - * - * @param string $dataConverterClassName - * @return FieldDataConverter - */ - private function getFieldDataConverter($dataConverterClassName) - { - if (!isset($this->fieldDataConverters[$dataConverterClassName])) { - $this->fieldDataConverters[$dataConverterClassName] = $this->fieldDataConverterFactory->create( - $dataConverterClassName - ); - } - return $this->fieldDataConverters[$dataConverterClassName]; - } -} diff --git a/app/code/Magento/Sales/Setup/SalesSetup.php b/app/code/Magento/Sales/Setup/SalesSetup.php index 1c0040b37b316..ec8f7ce0f14d2 100644 --- a/app/code/Magento/Sales/Setup/SalesSetup.php +++ b/app/code/Magento/Sales/Setup/SalesSetup.php @@ -322,4 +322,53 @@ public function getTable($table) { return $this->getSetup()->getTable($table, self::$connectionName); } + + /** + * Update entity types + * + * @return void + */ + public function updateEntityTypes() + { + $this->updateEntityType( + \Magento\Sales\Model\Order::ENTITY, + 'entity_model', + \Magento\Sales\Model\ResourceModel\Order::class + ); + $this->updateEntityType( + \Magento\Sales\Model\Order::ENTITY, + 'increment_model', + \Magento\Eav\Model\Entity\Increment\NumericValue::class + ); + $this->updateEntityType( + 'invoice', + 'entity_model', + \Magento\Sales\Model\ResourceModel\Order::class + ); + $this->updateEntityType( + 'invoice', + 'increment_model', + \Magento\Eav\Model\Entity\Increment\NumericValue::class + ); + $this->updateEntityType( + 'creditmemo', + 'entity_model', + \Magento\Sales\Model\ResourceModel\Order\Creditmemo::class + ); + $this->updateEntityType( + 'creditmemo', + 'increment_model', + \Magento\Eav\Model\Entity\Increment\NumericValue::class + ); + $this->updateEntityType( + 'shipment', + 'entity_model', + \Magento\Sales\Model\ResourceModel\Order\Shipment::class + ); + $this->updateEntityType( + 'shipment', + 'increment_model', + \Magento\Eav\Model\Entity\Increment\NumericValue::class + ); + } } diff --git a/app/code/Magento/Sales/Setup/UpgradeData.php b/app/code/Magento/Sales/Setup/UpgradeData.php index 4346a86b68ca5..8b104b0b35590 100644 --- a/app/code/Magento/Sales/Setup/UpgradeData.php +++ b/app/code/Magento/Sales/Setup/UpgradeData.php @@ -5,138 +5,117 @@ */ namespace Magento\Sales\Setup; -use Magento\Framework\App\ObjectManager; -use Magento\Framework\DB\FieldDataConverterFactory; +use Magento\Eav\Model\Config; +use Magento\Framework\DB\AggregatedFieldDataConverter; use Magento\Framework\DB\DataConverter\SerializedToJson; +use Magento\Framework\DB\FieldToConvert; +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Framework\Setup\UpgradeDataInterface; /** * Data upgrade script */ -class UpgradeData implements \Magento\Framework\Setup\UpgradeDataInterface +class UpgradeData implements UpgradeDataInterface { /** * Sales setup factory * - * @var \Magento\Sales\Setup\SalesSetupFactory + * @var SalesSetupFactory */ private $salesSetupFactory; /** - * @var \Magento\Eav\Model\Config + * @var Config */ private $eavConfig; /** - * @var \Magento\Sales\Setup\ConvertSerializedDataToJsonFactory + * @var AggregatedFieldDataConverter */ - private $convertSerializedDataToJsonFactory; - - /** - * @var FieldDataConverterFactory - */ - private $fieldDataConverterFactory; + private $aggregatedFieldConverter; /** * Constructor * - * @param \Magento\Sales\Setup\SalesSetupFactory $salesSetupFactory - * @param \Magento\Sales\Setup\ConvertSerializedDataToJsonFactory $convertSerializedDataToJsonFactory - * @param \Magento\Eav\Model\Config $eavConfig - * @param FieldDataConverterFactory $fieldDataConverterFactory + * @param SalesSetupFactory $salesSetupFactory + * @param Config $eavConfig + * @param AggregatedFieldDataConverter $aggregatedFieldConverter */ public function __construct( - \Magento\Sales\Setup\SalesSetupFactory $salesSetupFactory, - \Magento\Sales\Setup\ConvertSerializedDataToJsonFactory $convertSerializedDataToJsonFactory, - \Magento\Eav\Model\Config $eavConfig, - FieldDataConverterFactory $fieldDataConverterFactory = null + SalesSetupFactory $salesSetupFactory, + Config $eavConfig, + AggregatedFieldDataConverter $aggregatedFieldConverter ) { $this->salesSetupFactory = $salesSetupFactory; - $this->convertSerializedDataToJsonFactory = $convertSerializedDataToJsonFactory; $this->eavConfig = $eavConfig; - $this->fieldDataConverterFactory = $fieldDataConverterFactory ?: ObjectManager::getInstance() - ->get(FieldDataConverterFactory::class); + $this->aggregatedFieldConverter = $aggregatedFieldConverter; } /** * {@inheritdoc} */ - public function upgrade( - \Magento\Framework\Setup\ModuleDataSetupInterface $setup, - \Magento\Framework\Setup\ModuleContextInterface $context - ) { + public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context) + { $salesSetup = $this->salesSetupFactory->create(['setup' => $setup]); if (version_compare($context->getVersion(), '2.0.1', '<')) { - $this->upgradeToTwoZeroOne($salesSetup); - } - if (version_compare($context->getVersion(), '2.0.5', '<')) { - $this->convertSerializedDataToJsonFactory->create(['salesSetup' => $salesSetup]) - ->convert(); + $salesSetup->updateEntityTypes(); } if (version_compare($context->getVersion(), '2.0.6', '<')) { - $fieldDataConverter = $this->fieldDataConverterFactory->create(SerializedToJson::class); - $fieldDataConverter->convert( - $salesSetup->getConnection(), - $salesSetup->getTable('sales_invoice_item'), - 'entity_id', - 'tax_ratio' - ); - $fieldDataConverter->convert( - $salesSetup->getConnection(), - $salesSetup->getTable('sales_creditmemo_item'), - 'entity_id', - 'tax_ratio' - ); + $this->convertSerializedDataToJson($context->getVersion(), $salesSetup); } $this->eavConfig->clear(); } /** - * Upgrade to version 2.0.1 + * Convert data from serialized to JSON encoded * - * @param \Magento\Sales\Setup\SalesSetup $setup + * @param string $setupVersion + * @param SalesSetup $salesSetup * @return void */ - private function upgradeToTwoZeroOne(\Magento\Sales\Setup\SalesSetup $setup) + private function convertSerializedDataToJson($setupVersion, SalesSetup $salesSetup) { - $setup->updateEntityType( - \Magento\Sales\Model\Order::ENTITY, - 'entity_model', - \Magento\Sales\Model\ResourceModel\Order::class - ); - $setup->updateEntityType( - \Magento\Sales\Model\Order::ENTITY, - 'increment_model', - \Magento\Eav\Model\Entity\Increment\NumericValue::class - ); - $setup->updateEntityType( - 'invoice', - 'entity_model', - \Magento\Sales\Model\ResourceModel\Order::class - ); - $setup->updateEntityType( - 'invoice', - 'increment_model', - \Magento\Eav\Model\Entity\Increment\NumericValue::class - ); - $setup->updateEntityType( - 'creditmemo', - 'entity_model', - \Magento\Sales\Model\ResourceModel\Order\Creditmemo::class - ); - $setup->updateEntityType( - 'creditmemo', - 'increment_model', - \Magento\Eav\Model\Entity\Increment\NumericValue::class - ); - $setup->updateEntityType( - 'shipment', - 'entity_model', - \Magento\Sales\Model\ResourceModel\Order\Shipment::class - ); - $setup->updateEntityType( - 'shipment', - 'increment_model', - \Magento\Eav\Model\Entity\Increment\NumericValue::class - ); + $fieldsToUpdate = [ + new FieldToConvert( + SerializedToJson::class, + $salesSetup->getTable('sales_invoice_item'), + 'entity_id', + 'tax_ratio' + ), + new FieldToConvert( + SerializedToJson::class, + $salesSetup->getTable('sales_creditmemo_item'), + 'entity_id', + 'tax_ratio' + ), + ]; + if (version_compare($setupVersion, '2.0.5', '<')) { + $fieldsToUpdate[] = new FieldToConvert( + SerializedDataConverter::class, + $salesSetup->getTable('sales_order_item'), + 'item_id', + 'product_options' + ); + $fieldsToUpdate[] = new FieldToConvert( + SerializedToJson::class, + $salesSetup->getTable('sales_shipment'), + 'entity_id', + 'packages' + ); + $fieldsToUpdate[] = new FieldToConvert( + SalesOrderPaymentDataConverter::class, + $salesSetup->getTable('sales_order_payment'), + 'entity_id', + 'additional_information' + ); + $fieldsToUpdate[] = new FieldToConvert( + SerializedToJson::class, + $salesSetup->getTable('sales_payment_transaction'), + 'transaction_id', + 'additional_information' + ); + } + $this->aggregatedFieldConverter->convert($fieldsToUpdate, $salesSetup->getConnection()); } } diff --git a/app/code/Magento/SalesRule/Setup/UpgradeData.php b/app/code/Magento/SalesRule/Setup/UpgradeData.php index 1f458451753cb..609f5ff5a6845 100644 --- a/app/code/Magento/SalesRule/Setup/UpgradeData.php +++ b/app/code/Magento/SalesRule/Setup/UpgradeData.php @@ -5,8 +5,9 @@ */ namespace Magento\SalesRule\Setup; -use Magento\Framework\DB\FieldDataConverterFactory; +use Magento\Framework\DB\AggregatedFieldDataConverter; use Magento\Framework\DB\DataConverter\SerializedToJson; +use Magento\Framework\DB\FieldToConvert; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\UpgradeDataInterface; @@ -16,26 +17,26 @@ class UpgradeData implements UpgradeDataInterface { /** - * @var FieldDataConverterFactory + * @var MetadataPool */ - private $fieldDataConverterFactory; + private $metadataPool; /** - * @var MetadataPool + * @var AggregatedFieldDataConverter */ - private $metadataPool; + private $aggregatedFieldConverter; /** * UpgradeData constructor. * - * @param FieldDataConverterFactory $fieldDataConverterFactory + * @param AggregatedFieldDataConverter $aggregatedFieldConverter * @param MetadataPool $metadataPool */ public function __construct( - FieldDataConverterFactory $fieldDataConverterFactory, + AggregatedFieldDataConverter $aggregatedFieldConverter, MetadataPool $metadataPool ) { - $this->fieldDataConverterFactory = $fieldDataConverterFactory; + $this->aggregatedFieldConverter = $aggregatedFieldConverter; $this->metadataPool = $metadataPool; } @@ -62,20 +63,23 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface */ public function convertSerializedDataToJson($setup) { - $fieldDataConverter = $this->fieldDataConverterFactory->create(SerializedToJson::class); $metadata = $this->metadataPool->getMetadata(RuleInterface::class); - - $fieldDataConverter->convert( - $setup->getConnection(), - $setup->getTable('salesrule'), - $metadata->getLinkField(), - 'conditions_serialized' - ); - $fieldDataConverter->convert( - $setup->getConnection(), - $setup->getTable('salesrule'), - $metadata->getLinkField(), - 'actions_serialized' + $this->aggregatedFieldConverter->convert( + [ + new FieldToConvert( + SerializedToJson::class, + $setup->getTable('salesrule'), + $metadata->getLinkField(), + 'conditions_serialized' + ), + new FieldToConvert( + SerializedToJson::class, + $setup->getTable('salesrule'), + $metadata->getLinkField(), + 'actions_serialized' + ), + ], + $setup->getConnection() ); } } diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/_files/quote_item_downloadable.php b/app/code/Magento/SalesRule/Test/Unit/Model/_files/quote_item_downloadable.php index 7a8c88cd426cd..004bd2675da1a 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/_files/quote_item_downloadable.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/_files/quote_item_downloadable.php @@ -54,7 +54,7 @@ 'weee_tax_row_disposition' => '0.0000', 'base_weee_tax_disposition' => '0.0000', 'base_weee_tax_row_disposition' => '0.0000', - 'weee_tax_applied' => 'a:0:{}', + 'weee_tax_applied' => '[]', 'weee_tax_applied_amount' => '0.0000', 'weee_tax_applied_row_amount' => '0.0000', 'base_weee_tax_applied_amount' => '0.0000', diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/_files/quote_item_simple.php b/app/code/Magento/SalesRule/Test/Unit/Model/_files/quote_item_simple.php index f752449235de2..17056716385e4 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/_files/quote_item_simple.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/_files/quote_item_simple.php @@ -54,7 +54,7 @@ 'weee_tax_row_disposition' => '0.0000', 'base_weee_tax_disposition' => '0.0000', 'base_weee_tax_row_disposition' => '0.0000', - 'weee_tax_applied' => 'a:0:{}', + 'weee_tax_applied' => '[]', 'weee_tax_applied_amount' => '0.0000', 'weee_tax_applied_row_amount' => '0.0000', 'base_weee_tax_applied_amount' => '0.0000', diff --git a/app/code/Magento/Widget/Helper/Conditions.php b/app/code/Magento/Widget/Helper/Conditions.php index 730aa925d1c23..33cc353358020 100644 --- a/app/code/Magento/Widget/Helper/Conditions.php +++ b/app/code/Magento/Widget/Helper/Conditions.php @@ -5,7 +5,7 @@ */ namespace Magento\Widget\Helper; -use Magento\Widget\Model\Widget\Wysiwyg\Normalizer; +use Magento\Framework\Data\Wysiwyg\Normalizer; use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\Serializer\Json; @@ -44,7 +44,7 @@ public function __construct( */ public function encode(array $value) { - return $this->normalizer->replaceReservedCharaters($this->serializer->serialize($value)); + return $this->normalizer->replaceReservedCharacters($this->serializer->serialize($value)); } /** @@ -56,7 +56,7 @@ public function encode(array $value) public function decode($value) { return $this->serializer->unserialize( - $this->normalizer->restoreReservedCharaters($value) + $this->normalizer->restoreReservedCharacters($value) ); } } diff --git a/app/code/Magento/Widget/Setup/LayoutUpdateConverter.php b/app/code/Magento/Widget/Setup/LayoutUpdateConverter.php index 1fd5a8edda4b6..54c364dcc49a4 100644 --- a/app/code/Magento/Widget/Setup/LayoutUpdateConverter.php +++ b/app/code/Magento/Widget/Setup/LayoutUpdateConverter.php @@ -7,7 +7,7 @@ use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\Serialize\Serializer\Serialize; -use Magento\Widget\Model\Widget\Wysiwyg\Normalizer; +use Magento\Framework\Data\Wysiwyg\Normalizer; use Magento\Framework\DB\DataConverter\DataConversionException; use Magento\Framework\DB\DataConverter\SerializedToJson; @@ -22,7 +22,7 @@ class LayoutUpdateConverter extends SerializedToJson private $normalizer; /** - * LayoutUpdateConverter constructor. + * Constructor * * @param Serialize $serialize * @param Json $json @@ -54,12 +54,60 @@ public function convert($value) ); if (isset($matches[0])) { $matchSegments = $matches[0]; - $matchSegments[2] = $this->normalizer->replaceReservedCharaters( - parent::convert($this->normalizer->restoreReservedCharaters($matchSegments[2])) - ); + $matchSegments[2] = parent::convert($matchSegments[2]); return $matchSegments[1] . $matchSegments[2] . $matchSegments[3]; } else { return $value; } } + + /** + * @inheritdoc + */ + protected function isValidJsonValue($value) + { + $value = $this->normalizer->restoreReservedCharacters($value); + return parent::isValidJsonValue($value); + } + + /** + * @inheritdoc + */ + protected function unserializeValue($value) + { + $value = htmlspecialchars_decode($value); + $value = $this->restoreReservedCharactersInSerializedContent($value); + return parent::unserializeValue($value); + } + + /** + * @inheritdoc + */ + protected function encodeJson($value) + { + return htmlspecialchars( + $this->normalizer->replaceReservedCharacters(parent::encodeJson($value)) + ); + } + + /** + * Restore the reserved characters in the existing serialized content + * + * @param string $serializedContent + * @return string + */ + private function restoreReservedCharactersInSerializedContent($serializedContent) + { + $map = [ + '{' => '[', + '}' => ']', + '"' => '`', + '\\' => '|', + ]; + return str_replace( + array_values($map), + array_keys($map), + $serializedContent + ); + } } diff --git a/app/code/Magento/Widget/Setup/UpgradeData.php b/app/code/Magento/Widget/Setup/UpgradeData.php index 38659a923b94a..de3928d1fb5b8 100644 --- a/app/code/Magento/Widget/Setup/UpgradeData.php +++ b/app/code/Magento/Widget/Setup/UpgradeData.php @@ -3,13 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Widget\Setup; +use Magento\Framework\DB\AggregatedFieldDataConverter; +use Magento\Framework\DB\FieldToConvert; use Magento\Framework\Setup\UpgradeDataInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; -use Magento\Framework\DB\FieldDataConverterFactory; use Magento\Framework\DB\DataConverter\SerializedToJson; /** @@ -18,26 +18,26 @@ class UpgradeData implements UpgradeDataInterface { /** - * @var FieldDataConverterFactory + * @var \Magento\Framework\DB\Select\QueryModifierFactory */ - private $fieldDataConverterFactory; + private $queryModifierFactory; /** - * @var \Magento\Framework\DB\Select\QueryModifierFactory + * @var AggregatedFieldDataConverter */ - private $queryModifierFactory; - + private $aggregatedFieldConverter; + /** * UpgradeData constructor - * - * @param FieldDataConverterFactory $fieldDataConverterFactory + * + * @param AggregatedFieldDataConverter $aggregatedFieldConverter * @param \Magento\Framework\DB\Select\QueryModifierFactory $queryModifierFactory */ public function __construct( - FieldDataConverterFactory $fieldDataConverterFactory, + AggregatedFieldDataConverter $aggregatedFieldConverter, \Magento\Framework\DB\Select\QueryModifierFactory $queryModifierFactory ) { - $this->fieldDataConverterFactory = $fieldDataConverterFactory; + $this->aggregatedFieldConverter = $aggregatedFieldConverter; $this->queryModifierFactory = $queryModifierFactory; } @@ -59,17 +59,7 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface */ private function upgradeVersionTwoZeroOne(ModuleDataSetupInterface $setup) { - // upgrade widget_parameters field in widget_instance table - $fieldDataConverter = $this->fieldDataConverterFactory->create(SerializedToJson::class); - $fieldDataConverter->convert( - $setup->getConnection(), - $setup->getTable('widget_instance'), - 'instance_id', - 'widget_parameters' - ); - - // upgrade xml field in layout_update table if there is conditions in a widget instance - $queryModifier = $this->queryModifierFactory->create( + $layoutUpdateQueryModifier = $this->queryModifierFactory->create( 'like', [ 'values' => [ @@ -77,14 +67,23 @@ private function upgradeVersionTwoZeroOne(ModuleDataSetupInterface $setup) ] ] ); - - $xmlFieldDataConverter = $this->fieldDataConverterFactory->create(LayoutUpdateConverter::class); - $xmlFieldDataConverter->convert( - $setup->getConnection(), - $setup->getTable('layout_update'), - 'layout_update_id', - 'xml', - $queryModifier + $this->aggregatedFieldConverter->convert( + [ + new FieldToConvert( + SerializedToJson::class, + $setup->getTable('widget_instance'), + 'instance_id', + 'widget_parameters' + ), + new FieldToConvert( + LayoutUpdateConverter::class, + $setup->getTable('layout_update'), + 'layout_update_id', + 'xml', + $layoutUpdateQueryModifier + ), + ], + $setup->getConnection() ); } } diff --git a/app/code/Magento/Widget/Test/Unit/Controller/Adminhtml/Widget/LoadOptionsTest.php b/app/code/Magento/Widget/Test/Unit/Controller/Adminhtml/Widget/LoadOptionsTest.php index 2dd23d90f2189..d7c7c4d3afd32 100644 --- a/app/code/Magento/Widget/Test/Unit/Controller/Adminhtml/Widget/LoadOptionsTest.php +++ b/app/code/Magento/Widget/Test/Unit/Controller/Adminhtml/Widget/LoadOptionsTest.php @@ -140,7 +140,7 @@ public function dtestExecuteWithException() public function testExecute() { $widgetType = 'Magento\SomeWidget'; - $conditionsEncoded = 'a:3:{s:5:"value";i:1;s:8:"operator";s:2:"==";s:9:"attribute";s:2:"id";}'; + $conditionsEncoded = 'encoded conditions'; $conditionsDecoded = [ 'value' => 1, 'operator' => '==', diff --git a/app/code/Magento/Widget/Test/Unit/Helper/ConditionsTest.php b/app/code/Magento/Widget/Test/Unit/Helper/ConditionsTest.php index 38e16c8869c4c..544f88b21996d 100644 --- a/app/code/Magento/Widget/Test/Unit/Helper/ConditionsTest.php +++ b/app/code/Magento/Widget/Test/Unit/Helper/ConditionsTest.php @@ -7,7 +7,7 @@ namespace Magento\Widget\Test\Unit\Helper; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use Magento\Widget\Model\Widget\Wysiwyg\Normalizer; +use Magento\Framework\Data\Wysiwyg\Normalizer; /** * Class ConditionsTest @@ -59,11 +59,11 @@ public function testEncodeDecode() ->with($serializedValue) ->willReturn($value); $this->normalizer->expects($this->once()) - ->method('replaceReservedCharaters') + ->method('replaceReservedCharacters') ->with($serializedValue) ->willReturn($normalizedValue); $this->normalizer->expects($this->once()) - ->method('restoreReservedCharaters') + ->method('restoreReservedCharacters') ->with($normalizedValue) ->willReturn($serializedValue); $encoded = $this->conditions->encode($value); diff --git a/app/etc/di.xml b/app/etc/di.xml index 4eb4f74ba4c25..f29d1fe22a497 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -1253,6 +1253,7 @@ Magento\Framework\DB\Select\InQueryModifier Magento\Framework\DB\Select\LikeQueryModifier + Magento\Framework\DB\Select\CompositeQueryModifier diff --git a/dev/tests/integration/testsuite/Magento/Cms/Setup/ContentConverterTest.php b/dev/tests/integration/testsuite/Magento/Cms/Setup/ContentConverterTest.php index 0fa1778732cfc..b3bbd64b83e7e 100644 --- a/dev/tests/integration/testsuite/Magento/Cms/Setup/ContentConverterTest.php +++ b/dev/tests/integration/testsuite/Magento/Cms/Setup/ContentConverterTest.php @@ -34,8 +34,8 @@ public function convertDataProvider()

Hot Sellers

Here is what`s trending on Luma right now

'; - $serializedWidgetContent = '{{widget type="Magento\\CatalogWidget\\Block\\Product\\ProductsList" products_per_page="8" products_count="8" template="product/widget/content/grid.phtml" conditions_encoded="a:2:[i:1;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Combine`;s:10:`aggregator`;s:3:`all`;s:5:`value`;s:1:`1`;s:9:`new_child`;s:0:``;]s:4:`1--1`;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Product`;s:9:`attribute`;s:3:`sku`;s:8:`operator`;s:2:`()`;s:5:`value`;s:60:`WS12, WT09, MT07, MH07, 24-MB02, 24-WB04, 241-MB08, 240-LV05`;]]"}}'; - $jsonEncodedWidgetContent = '{{widget type="Magento\\CatalogWidget\\Block\\Product\\ProductsList" products_per_page="8" products_count="8" template="product/widget/content/grid.phtml" conditions_encoded="[`1`:[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,`aggregator`:`all`,`value`:`1`,`new_child`:``],`1--1`:[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`sku`,`operator`:`()`,`value`:`WS12, WT09, MT07, MH07, 24-MB02, 24-WB04, 241-MB08, 240-LV05`]]"}}'; + $serializedWidgetContent = '{{widget type="Magento\\CatalogWidget\\Block\\Product\\ProductsList" products_per_page="8" products_count="8" template="product/widget/content/grid.phtml" conditions_encoded="a:2:[i:1;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Combine`;s:10:`aggregator`;s:3:`all`;s:5:`value`;s:1:`1`;s:9:`new_child`;s:0:``;]s:4:`1--1`;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Product`;s:9:`attribute`;s:3:`sku`;s:8:`operator`;s:2:`()`;s:5:`value`;a:8:[i:0;s:4:`WS12`;i:1;s:4:`WT09`;i:2;s:4:`MT07`;i:3;s:4:`MH07`;i:4;s:7:`24-MB02`;i:5;s:7:`24-WB04`;i:6;s:8:`241-MB08`;i:7;s:8:`240-LV05`;]]]"}}'; + $jsonEncodedWidgetContent = '{{widget type="Magento\\CatalogWidget\\Block\\Product\\ProductsList" products_per_page="8" products_count="8" template="product/widget/content/grid.phtml" conditions_encoded="^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,`aggregator`:`all`,`value`:`1`,`new_child`:``^],`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`sku`,`operator`:`()`,`value`:[`WS12`,`WT09`,`MT07`,`MH07`,`24-MB02`,`24-WB04`,`241-MB08`,`240-LV05`]^]^]"}}'; // @codingStandardsIgnoreEnd return [ 'no widget' => [ diff --git a/dev/tests/integration/testsuite/Magento/Framework/Data/Wysiwyg/NormalizerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Data/Wysiwyg/NormalizerTest.php new file mode 100644 index 0000000000000..57676d8df62de --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Data/Wysiwyg/NormalizerTest.php @@ -0,0 +1,49 @@ +normalizer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Framework\Data\Wysiwyg\Normalizer::class + ); + } + + public function testReplaceReservedCharacters() + { + $content = '{}\\""[]'; + $expected = '^[^]|``[]'; + $this->assertEquals($expected, $this->normalizer->replaceReservedCharacters($content)); + } + + public function testRestoreReservedCharacters() + { + $content = '^[^]|``[]'; + $expected = '{}\\""[]'; + $this->assertEquals($expected, $this->normalizer->restoreReservedCharacters($content)); + } + + public function testReplaceAndRestoreReservedCharacters() + { + $value = '{"1":{"type":"Magento\\CatalogWidget\\Model\\Rule\\Condition\\Combine",' + . '"aggregator":"all","value":"1","new_child":""},"1--1":{"type":' + . '"Magento\\CatalogWidget\\Model\\Rule\\Condition\\Product","attribute":"pattern",' + . '"operator":"{}","value":["212,213"]}}'; + $this->assertEquals( + $value, + $this->normalizer->restoreReservedCharacters( + $this->normalizer->replaceReservedCharacters($value) + ) + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Widget/Model/Widget/Wysiwyg/NormalizerTest.php b/dev/tests/integration/testsuite/Magento/Widget/Model/Widget/Wysiwyg/NormalizerTest.php deleted file mode 100644 index aa22a669a8cc3..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Widget/Model/Widget/Wysiwyg/NormalizerTest.php +++ /dev/null @@ -1,35 +0,0 @@ -normalizer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Widget\Model\Widget\Wysiwyg\Normalizer::class - ); - } - - public function testReplaceReservedCharaters() - { - $content = '{}\\""'; - $expected = '[]|``'; - $this->assertEquals($expected, $this->normalizer->replaceReservedCharaters($content)); - } - - public function testRestoreReservedCharaters() - { - $content = '[]|``'; - $expected = '{}\\""'; - $this->assertEquals($expected, $this->normalizer->restoreReservedCharaters($content)); - } -} diff --git a/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php b/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php index ac276bcb59083..68ab560dff82f 100644 --- a/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php +++ b/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php @@ -5,9 +5,11 @@ */ namespace Magento\Widget\Setup; -class LayoutUpdateConverterTest extends \Magento\TestFramework\TestCase\AbstractController +class LayoutUpdateConverterTest extends \PHPUnit_Framework_TestCase { - /** @var LayoutUpdateConverter */ + /** + * @var LayoutUpdateConverter + */ private $converter; protected function setUp() @@ -31,8 +33,8 @@ public function convertDataProvider() { // @codingStandardsIgnoreStart $beginning = 'show_pager0products_count10'; - $serializedWidgetXml = 'conditions_encodeda:2:[i:1;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Combine`;s:10:`aggregator`;s:3:`all`;s:5:`value`;s:1:`1`;s:9:`new_child`;s:0:``;]s:4:`1--1`;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Product`;s:9:`attribute`;s:3:`sku`;s:8:`operator`;s:2:`==`;s:5:`value`;s:10:`sku321-341`;]]'; - $jsonEncodedWidgetXml = 'conditions_encoded[`1`:[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,`aggregator`:`all`,`value`:`1`,`new_child`:``],`1--1`:[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`sku`,`operator`:`==`,`value`:`sku321-341`]]'; + $serializedWidgetXml = 'conditions_encodeda:3:[i:1;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Combine`;s:10:`aggregator`;s:3:`all`;s:5:`value`;s:1:`1`;s:9:`new_child`;s:0:``;]s:4:`1--1`;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Product`;s:9:`attribute`;s:3:`sku`;s:8:`operator`;s:2:`()`;s:5:`value`;s:15:`simple, simple1`;]s:4:`1--2`;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Product`;s:9:`attribute`;s:5:`price`;s:8:`operator`;s:2:`<=`;s:5:`value`;s:2:`10`;]]'; + $jsonEncodedWidgetXml = 'conditions_encoded^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,`aggregator`:`all`,`value`:`1`,`new_child`:``^],`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`sku`,`operator`:`()`,`value`:`simple, simple1`^],`1--2`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`price`,`operator`:`<=`,`value`:`10`^]^]'; $ending = 'page_var_namepobqks'; // @codingStandardsIgnoreEnd return [ diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/restricted_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/restricted_classes.php index e9564c57d11ed..a8127cb3f9678 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/restricted_classes.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/restricted_classes.php @@ -138,6 +138,11 @@ 'name' => 'Magento_Cms', 'path' => 'Setup/ContentConverter.php' ], + [ + 'type' => 'library', + 'name' => 'magento/framework', + 'path' => 'Unserialize/Test/Unit/UnserializeTest.php' + ], ] ], 'ArrayObject' => [ diff --git a/lib/internal/Magento/Framework/App/Cache/Manager.php b/lib/internal/Magento/Framework/App/Cache/Manager.php index ac30b0d70953f..7ac53d5d6e070 100644 --- a/lib/internal/Magento/Framework/App/Cache/Manager.php +++ b/lib/internal/Magento/Framework/App/Cache/Manager.php @@ -10,6 +10,8 @@ /** * Cache status manager + * + * @api */ class Manager { diff --git a/lib/internal/Magento/Framework/App/Cache/Tag/StrategyInterface.php b/lib/internal/Magento/Framework/App/Cache/Tag/StrategyInterface.php index 74550b572a250..8247f50488468 100644 --- a/lib/internal/Magento/Framework/App/Cache/Tag/StrategyInterface.php +++ b/lib/internal/Magento/Framework/App/Cache/Tag/StrategyInterface.php @@ -7,6 +7,8 @@ /** * Invalidation tags generator + * + * @api */ interface StrategyInterface { diff --git a/lib/internal/Magento/Framework/App/Cache/Type/Config.php b/lib/internal/Magento/Framework/App/Cache/Type/Config.php index ab53726543e3b..7c5547f936105 100644 --- a/lib/internal/Magento/Framework/App/Cache/Type/Config.php +++ b/lib/internal/Magento/Framework/App/Cache/Type/Config.php @@ -4,14 +4,14 @@ * See COPYING.txt for license details. */ -/** - * System / Cache Management / Cache type "Configuration" - */ namespace Magento\Framework\App\Cache\Type; use Magento\Framework\Cache\Frontend\Decorator\TagScope; use Magento\Framework\Config\CacheInterface; +/** + * System / Cache Management / Cache type "Configuration" + */ class Config extends TagScope implements CacheInterface { /** diff --git a/lib/internal/Magento/Framework/App/Cache/Type/FrontendPool.php b/lib/internal/Magento/Framework/App/Cache/Type/FrontendPool.php index 96c8fa89f49ef..596fd833ab1ed 100644 --- a/lib/internal/Magento/Framework/App/Cache/Type/FrontendPool.php +++ b/lib/internal/Magento/Framework/App/Cache/Type/FrontendPool.php @@ -10,6 +10,8 @@ /** * In-memory readonly pool of cache front-ends with enforced access control, specific to cache types + * + * @api */ class FrontendPool { diff --git a/lib/internal/Magento/Framework/Cache/Backend/Decorator/AbstractDecorator.php b/lib/internal/Magento/Framework/Cache/Backend/Decorator/AbstractDecorator.php index 8029ee338836e..89068c10d498f 100644 --- a/lib/internal/Magento/Framework/Cache/Backend/Decorator/AbstractDecorator.php +++ b/lib/internal/Magento/Framework/Cache/Backend/Decorator/AbstractDecorator.php @@ -4,11 +4,11 @@ * See COPYING.txt for license details. */ +namespace Magento\Framework\Cache\Backend\Decorator; + /** * Abstract decorator class for \Zend_Cache_Backend class and its descendants */ -namespace Magento\Framework\Cache\Backend\Decorator; - abstract class AbstractDecorator extends \Zend_Cache_Backend implements \Zend_Cache_Backend_ExtendedInterface { /** diff --git a/lib/internal/Magento/Framework/Cache/Backend/Decorator/Compression.php b/lib/internal/Magento/Framework/Cache/Backend/Decorator/Compression.php index 5e2dc46ba1d5b..57f97e9cbac7f 100644 --- a/lib/internal/Magento/Framework/Cache/Backend/Decorator/Compression.php +++ b/lib/internal/Magento/Framework/Cache/Backend/Decorator/Compression.php @@ -4,13 +4,13 @@ * See COPYING.txt for license details. */ +namespace Magento\Framework\Cache\Backend\Decorator; + /** * Decorator class for compressing data before storing in cache * * @todo re-implement as a cache frontend decorator similarly to \Magento\Framework\Cache\Frontend\Decorator\* */ -namespace Magento\Framework\Cache\Backend\Decorator; - class Compression extends \Magento\Framework\Cache\Backend\Decorator\AbstractDecorator { /** diff --git a/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Logger.php b/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Logger.php index 4d654dc559f01..d57946a07f1f4 100644 --- a/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Logger.php +++ b/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Logger.php @@ -4,14 +4,14 @@ * See COPYING.txt for license details. */ -/** - * Cache frontend decorator that logger of cache invalidate - */ namespace Magento\Framework\Cache\Frontend\Decorator; use Magento\Framework\Cache\FrontendInterface; use Magento\Framework\Cache\InvalidateLogger as LoggerHandler; +/** + * Cache frontend decorator that logs cache invalidation actions + */ class Logger extends Bare { /** diff --git a/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Profiler.php b/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Profiler.php index 6da4a93dcfd9a..2bb1bc0d2dc20 100644 --- a/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Profiler.php +++ b/lib/internal/Magento/Framework/Cache/Frontend/Decorator/Profiler.php @@ -4,11 +4,11 @@ * See COPYING.txt for license details. */ +namespace Magento\Framework\Cache\Frontend\Decorator; + /** * Cache frontend decorator that performs profiling of cache operations */ -namespace Magento\Framework\Cache\Frontend\Decorator; - class Profiler extends \Magento\Framework\Cache\Frontend\Decorator\Bare { /** diff --git a/lib/internal/Magento/Framework/Cache/Frontend/Decorator/TagScope.php b/lib/internal/Magento/Framework/Cache/Frontend/Decorator/TagScope.php index 2fedba4ea853d..c837544a75f0f 100644 --- a/lib/internal/Magento/Framework/Cache/Frontend/Decorator/TagScope.php +++ b/lib/internal/Magento/Framework/Cache/Frontend/Decorator/TagScope.php @@ -4,11 +4,13 @@ * See COPYING.txt for license details. */ +namespace Magento\Framework\Cache\Frontend\Decorator; + /** * Cache frontend decorator that limits the cleaning scope within a tag + * + * @api */ -namespace Magento\Framework\Cache\Frontend\Decorator; - class TagScope extends \Magento\Framework\Cache\Frontend\Decorator\Bare { /** diff --git a/lib/internal/Magento/Framework/Cache/FrontendInterface.php b/lib/internal/Magento/Framework/Cache/FrontendInterface.php index 7633a88ea164f..2960d98de453f 100644 --- a/lib/internal/Magento/Framework/Cache/FrontendInterface.php +++ b/lib/internal/Magento/Framework/Cache/FrontendInterface.php @@ -4,11 +4,13 @@ * See COPYING.txt for license details. */ +namespace Magento\Framework\Cache; + /** * Interface of a cache frontend - an ultimate publicly available interface to an actual cache storage + * + * @api */ -namespace Magento\Framework\Cache; - interface FrontendInterface { /** diff --git a/lib/internal/Magento/Framework/DB/AggregatedFieldDataConverter.php b/lib/internal/Magento/Framework/DB/AggregatedFieldDataConverter.php new file mode 100644 index 0000000000000..8b60b10e1e45c --- /dev/null +++ b/lib/internal/Magento/Framework/DB/AggregatedFieldDataConverter.php @@ -0,0 +1,74 @@ +fieldDataConverterFactory = $fieldDataConverterFactory; + } + + /** + * Convert data for the specified fields using specified field converters + * + * @param FieldToConvert[] $fieldsToUpdate + * @param AdapterInterface $connection + * @throws FieldDataConversionException + * @return void + */ + public function convert(array $fieldsToUpdate, AdapterInterface $connection) + { + foreach ($fieldsToUpdate as $field) { + $fieldDataConverter = $this->getFieldDataConverter($field->getDataConverterClass()); + $fieldDataConverter->convert( + $connection, + $field->getTableName(), + $field->getIdentifierField(), + $field->getFieldName(), + $field->getQueryModifier() + ); + } + } + + /** + * Get field data converter + * + * @param string $dataConverterClassName + * @return FieldDataConverter + */ + private function getFieldDataConverter($dataConverterClassName) + { + if (!isset($this->fieldDataConverters[$dataConverterClassName])) { + $this->fieldDataConverters[$dataConverterClassName] = $this->fieldDataConverterFactory->create( + $dataConverterClassName + ); + } + return $this->fieldDataConverters[$dataConverterClassName]; + } +} diff --git a/lib/internal/Magento/Framework/DB/DataConverter/DataConversionException.php b/lib/internal/Magento/Framework/DB/DataConverter/DataConversionException.php index 84169a33cfd86..36921535e3757 100644 --- a/lib/internal/Magento/Framework/DB/DataConverter/DataConversionException.php +++ b/lib/internal/Magento/Framework/DB/DataConverter/DataConversionException.php @@ -6,10 +6,6 @@ namespace Magento\Framework\DB\DataConverter; -/** - * Class DataConversionException. - * @package Magento\Framework\DB\DataConverter - */ class DataConversionException extends \Exception { } diff --git a/lib/internal/Magento/Framework/DB/FieldToConvert.php b/lib/internal/Magento/Framework/DB/FieldToConvert.php new file mode 100644 index 0000000000000..7097321054ca0 --- /dev/null +++ b/lib/internal/Magento/Framework/DB/FieldToConvert.php @@ -0,0 +1,113 @@ +dataConverterClass = $dataConverter; + $this->tableName = $table; + $this->fieldName = $fieldName; + $this->identifierField = $identifierField; + $this->queryModifier = $queryModifier; + } + + /** + * Get data converter class name + * + * @return string + */ + public function getDataConverterClass() + { + return $this->dataConverterClass; + } + + /** + * Get table name + * + * @return string + */ + public function getTableName() + { + return $this->tableName; + } + + /** + * Get ID field name + * + * @return string + */ + public function getIdentifierField() + { + return $this->identifierField; + } + + /** + * Get field name + * + * @return string + */ + public function getFieldName() + { + return $this->fieldName; + } + + /** + * Get query modifier + * + * @return QueryModifierInterface|null + */ + public function getQueryModifier() + { + return $this->queryModifier; + } +} diff --git a/lib/internal/Magento/Framework/DB/Select/CompositeQueryModifier.php b/lib/internal/Magento/Framework/DB/Select/CompositeQueryModifier.php new file mode 100644 index 0000000000000..5e87617e0d0c1 --- /dev/null +++ b/lib/internal/Magento/Framework/DB/Select/CompositeQueryModifier.php @@ -0,0 +1,40 @@ +queryModifiers = $queryModifiers; + } + + /** + * {@inheritdoc} + */ + public function modify(Select $select) + { + foreach ($this->queryModifiers as $modifier) { + $modifier->modify($select); + } + } +} diff --git a/lib/internal/Magento/Framework/DB/Test/Unit/Select/CompositeQueryModifierTest.php b/lib/internal/Magento/Framework/DB/Test/Unit/Select/CompositeQueryModifierTest.php new file mode 100644 index 0000000000000..ee305964007c5 --- /dev/null +++ b/lib/internal/Magento/Framework/DB/Test/Unit/Select/CompositeQueryModifierTest.php @@ -0,0 +1,47 @@ +objectManager = new ObjectManager($this); + } + + public function testModify() + { + $queryModifierMockOne = $this->getMock(QueryModifierInterface::class); + $queryModifierMockTwo = $this->getMock(QueryModifierInterface::class); + $selectMock = $this->getMock(Select::class, [], [], '', false); + $queryModifierMockOne->expects($this->once()) + ->method('modify') + ->with($selectMock); + $queryModifierMockTwo->expects($this->once()) + ->method('modify') + ->with($selectMock); + $compositeQueryModifier = $this->objectManager->getObject( + CompositeQueryModifier::class, + [ + 'queryModifiers' => [ + $queryModifierMockOne, + $queryModifierMockTwo + ] + ] + ); + $compositeQueryModifier->modify($selectMock); + } +} diff --git a/app/code/Magento/Widget/Model/Widget/Wysiwyg/Normalizer.php b/lib/internal/Magento/Framework/Data/Wysiwyg/Normalizer.php similarity index 52% rename from app/code/Magento/Widget/Model/Widget/Wysiwyg/Normalizer.php rename to lib/internal/Magento/Framework/Data/Wysiwyg/Normalizer.php index 9aae9aeb80ec6..62e7500a302a6 100644 --- a/app/code/Magento/Widget/Model/Widget/Wysiwyg/Normalizer.php +++ b/lib/internal/Magento/Framework/Data/Wysiwyg/Normalizer.php @@ -3,7 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Widget\Model\Widget\Wysiwyg; +namespace Magento\Framework\Data\Wysiwyg; /** * Normalize widget content in Wysiwyg editor @@ -11,9 +11,9 @@ class Normalizer { - const WYSIWYG_RESERVED_CHARCTERS_REPLACEMENT_MAP = [ - '{' => '[', - '}' => ']', + const WYSIWYG_RESERVED_CHARACTERS_REPLACEMENT_MAP = [ + '{' => '^[', + '}' => '^]', '"' => '`', '\\' => '|', ]; @@ -24,11 +24,11 @@ class Normalizer * @param string $content * @return string */ - public function replaceReservedCharaters($content) + public function replaceReservedCharacters($content) { return str_replace( - array_keys(Normalizer::WYSIWYG_RESERVED_CHARCTERS_REPLACEMENT_MAP), - array_values(Normalizer::WYSIWYG_RESERVED_CHARCTERS_REPLACEMENT_MAP), + array_keys(Normalizer::WYSIWYG_RESERVED_CHARACTERS_REPLACEMENT_MAP), + array_values(Normalizer::WYSIWYG_RESERVED_CHARACTERS_REPLACEMENT_MAP), $content ); } @@ -39,11 +39,11 @@ public function replaceReservedCharaters($content) * @param string $content * @return string */ - public function restoreReservedCharaters($content) + public function restoreReservedCharacters($content) { return str_replace( - array_values(Normalizer::WYSIWYG_RESERVED_CHARCTERS_REPLACEMENT_MAP), - array_keys(Normalizer::WYSIWYG_RESERVED_CHARCTERS_REPLACEMENT_MAP), + array_values(Normalizer::WYSIWYG_RESERVED_CHARACTERS_REPLACEMENT_MAP), + array_keys(Normalizer::WYSIWYG_RESERVED_CHARACTERS_REPLACEMENT_MAP), $content ); } diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index 02373bd9f30de..60914851c8aac 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -9,11 +9,13 @@ namespace Magento\Framework\Mail\Template; use Magento\Framework\App\TemplateTypesInterface; -use Magento\Framework\Mail\Message; use Magento\Framework\Mail\MessageInterface; use Magento\Framework\Mail\TransportInterfaceFactory; use Magento\Framework\ObjectManagerInterface; +/** + * @api + */ class TransportBuilder { /** diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/Setup/_files/data_content_serialized.php b/lib/internal/Magento/Framework/Module/Test/Unit/Setup/_files/data_content_serialized.php index 5f10e3ac11d6e..f784418331323 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/Setup/_files/data_content_serialized.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/Setup/_files/data_content_serialized.php @@ -14,21 +14,21 @@ ], ], '$tableData' => [ - ['field' => 'a:1:{s:5:"model";s:34:"catalogrule/rule_condition_combine";}'], - ['field' => 'a:1:{s:5:"model";s:16:"some random text";}'], + ['field' => '{"max_text_length":255,"min_text_length":1}'], + ['field' => '{"model":"some random text"}'], ], '$expected' => [ 'updates' => [ [ 'table' => 'table', 'field' => 'field', - 'to' => 'a:1:{s:5:"model";s:48:"Magento\CatalogRule\Model\Rule\Condition\Combine";}', - 'from' => ['`field` = ?' => 'a:1:{s:5:"model";s:34:"catalogrule/rule_condition_combine";}'], + 'to' => '{"model":"Magento\\CatalogRule\\Model\\Rule\\Condition\\Combine"}', + 'from' => ['`field` = ?' => '{"model":"catalogrule\/rule_condition_combine"}'], ], ], 'aliases_map' => [ \Magento\Framework\Module\Setup\Migration::ENTITY_TYPE_MODEL => [ - 'catalogrule/rule_condition_combine' => \Magento\CatalogRule\Model\Rule\Condition\Combine::class, + 'catalogrule/rule_condition_combine' => 'Magento\CatalogRule\Model\Rule\Condition\Combine', ], ], ] diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/_files/empty_definition_file b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/_files/empty_definition_file deleted file mode 100644 index 67d0259b72264..0000000000000 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/_files/empty_definition_file +++ /dev/null @@ -1 +0,0 @@ -a:0:{} diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/_files/test_definition_file b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/_files/test_definition_file deleted file mode 100644 index 2571d680f77ed..0000000000000 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/_files/test_definition_file +++ /dev/null @@ -1 +0,0 @@ -a:1:{i:0;s:10:"Magento_Di";} \ No newline at end of file diff --git a/lib/internal/Magento/Framework/Pricing/Adjustment/Collection.php b/lib/internal/Magento/Framework/Pricing/Adjustment/Collection.php index 74eac8d677107..c7ab4b6e796c2 100644 --- a/lib/internal/Magento/Framework/Pricing/Adjustment/Collection.php +++ b/lib/internal/Magento/Framework/Pricing/Adjustment/Collection.php @@ -8,6 +8,8 @@ /** * Adjustment collection model + * + * @api */ class Collection { diff --git a/lib/internal/Magento/Framework/Pricing/Adjustment/Pool.php b/lib/internal/Magento/Framework/Pricing/Adjustment/Pool.php index 465be0f787af8..d064e05b0b671 100644 --- a/lib/internal/Magento/Framework/Pricing/Adjustment/Pool.php +++ b/lib/internal/Magento/Framework/Pricing/Adjustment/Pool.php @@ -10,6 +10,8 @@ /** * Global adjustment pool model + * + * @api */ class Pool { diff --git a/lib/internal/Magento/Framework/Pricing/Amount/AmountFactory.php b/lib/internal/Magento/Framework/Pricing/Amount/AmountFactory.php index 45ac44167757b..a8340ee097f58 100644 --- a/lib/internal/Magento/Framework/Pricing/Amount/AmountFactory.php +++ b/lib/internal/Magento/Framework/Pricing/Amount/AmountFactory.php @@ -8,6 +8,8 @@ /** * Class AmountFactory + * + * @api */ class AmountFactory { diff --git a/lib/internal/Magento/Framework/Pricing/Helper/Data.php b/lib/internal/Magento/Framework/Pricing/Helper/Data.php index ba6beb6265df9..ecaa94d3a2d4f 100644 --- a/lib/internal/Magento/Framework/Pricing/Helper/Data.php +++ b/lib/internal/Magento/Framework/Pricing/Helper/Data.php @@ -9,6 +9,8 @@ /** * Pricing data helper + * + * @api */ class Data extends \Magento\Framework\App\Helper\AbstractHelper { diff --git a/lib/internal/Magento/Framework/Pricing/Price/AbstractPrice.php b/lib/internal/Magento/Framework/Pricing/Price/AbstractPrice.php index 07ef2d965d18e..fe8fcbb6f430f 100644 --- a/lib/internal/Magento/Framework/Pricing/Price/AbstractPrice.php +++ b/lib/internal/Magento/Framework/Pricing/Price/AbstractPrice.php @@ -14,6 +14,8 @@ /** * Class AbstractPrice * Should be the base for creating any Price type class + * + * @api */ abstract class AbstractPrice implements PriceInterface { diff --git a/lib/internal/Magento/Framework/Pricing/Price/Collection.php b/lib/internal/Magento/Framework/Pricing/Price/Collection.php index 9becc10669288..200c3a50aff89 100644 --- a/lib/internal/Magento/Framework/Pricing/Price/Collection.php +++ b/lib/internal/Magento/Framework/Pricing/Price/Collection.php @@ -10,6 +10,8 @@ /** * Class Collection + * + * @api */ class Collection implements \Iterator { diff --git a/lib/internal/Magento/Framework/Pricing/Price/Pool.php b/lib/internal/Magento/Framework/Pricing/Price/Pool.php index 3a4c64d1d535f..b460113fc32c8 100644 --- a/lib/internal/Magento/Framework/Pricing/Price/Pool.php +++ b/lib/internal/Magento/Framework/Pricing/Price/Pool.php @@ -8,6 +8,8 @@ /** * Class Pool + * + * @api */ class Pool implements \Iterator, \ArrayAccess { diff --git a/lib/internal/Magento/Framework/Pricing/PriceComposite.php b/lib/internal/Magento/Framework/Pricing/PriceComposite.php index 09ec6f27f2ea6..620480a89c2b8 100644 --- a/lib/internal/Magento/Framework/Pricing/PriceComposite.php +++ b/lib/internal/Magento/Framework/Pricing/PriceComposite.php @@ -6,7 +6,6 @@ namespace Magento\Framework\Pricing; -use Magento\Framework\Pricing\SaleableInterface; use Magento\Framework\Pricing\Price\Factory as PriceFactory; use Magento\Framework\Pricing\Price\PriceInterface; diff --git a/lib/internal/Magento/Framework/Pricing/PriceInfo/Base.php b/lib/internal/Magento/Framework/Pricing/PriceInfo/Base.php index f1b4cd126cea7..ac8c301e24a5c 100644 --- a/lib/internal/Magento/Framework/Pricing/PriceInfo/Base.php +++ b/lib/internal/Magento/Framework/Pricing/PriceInfo/Base.php @@ -15,6 +15,8 @@ /** * Class Base * Price info base model + * + * @api */ class Base implements PriceInfoInterface { diff --git a/lib/internal/Magento/Framework/Pricing/PriceInfo/Factory.php b/lib/internal/Magento/Framework/Pricing/PriceInfo/Factory.php index 583fd7fa60f6a..e3e4af56f6095 100644 --- a/lib/internal/Magento/Framework/Pricing/PriceInfo/Factory.php +++ b/lib/internal/Magento/Framework/Pricing/PriceInfo/Factory.php @@ -14,6 +14,8 @@ /** * Price info model factory + * + * @api */ class Factory { diff --git a/lib/internal/Magento/Framework/Pricing/Render.php b/lib/internal/Magento/Framework/Pricing/Render.php index ea560b6ef5f32..a866095ce4216 100644 --- a/lib/internal/Magento/Framework/Pricing/Render.php +++ b/lib/internal/Magento/Framework/Pricing/Render.php @@ -7,7 +7,6 @@ namespace Magento\Framework\Pricing; use Magento\Framework\Pricing\Amount\AmountInterface; -use Magento\Framework\Pricing\SaleableInterface; use Magento\Framework\Pricing\Price\PriceInterface; use Magento\Framework\Pricing\Render\Layout; use Magento\Framework\View\Element\AbstractBlock; @@ -17,6 +16,8 @@ * Base price render * * @method string getPriceRenderHandle() + * + * @api */ class Render extends AbstractBlock { diff --git a/lib/internal/Magento/Framework/Pricing/Render/RendererPool.php b/lib/internal/Magento/Framework/Pricing/Render/RendererPool.php index b193f72897e34..4659e9d43ed3e 100644 --- a/lib/internal/Magento/Framework/Pricing/Render/RendererPool.php +++ b/lib/internal/Magento/Framework/Pricing/Render/RendererPool.php @@ -13,6 +13,8 @@ /** * RenderPool + * + * @api */ class RendererPool extends AbstractBlock { @@ -77,9 +79,8 @@ public function createPriceRender( $renderBlock = $this->getLayout()->createBlock($renderClassName, '', $arguments); if (!$renderBlock instanceof PriceBoxRenderInterface) { throw new \InvalidArgumentException( - 'Block "' . - $renderClassName . - '" must implement \Magento\Framework\Pricing\Render\PriceBoxRenderInterface' + 'Block "' . $renderClassName + . '" must implement \Magento\Framework\Pricing\Render\PriceBoxRenderInterface' ); } $renderBlock->setTemplate($this->getRenderBlockTemplate($type, $priceCode)); @@ -142,9 +143,8 @@ public function createAmountRender( $amountBlock = $this->getLayout()->createBlock($renderClassName, '', $arguments); if (!$amountBlock instanceof AmountRenderInterface) { throw new \InvalidArgumentException( - 'Block "' . - $renderClassName . - '" must implement \Magento\Framework\Pricing\Render\AmountRenderInterface' + 'Block "' . $renderClassName + . '" must implement \Magento\Framework\Pricing\Render\AmountRenderInterface' ); } $amountBlock->setTemplate($this->getAmountRenderBlockTemplate($type, $priceCode)); @@ -158,8 +158,8 @@ public function createAmountRender( */ public function getAdjustmentRenders(SaleableInterface $saleableItem = null, PriceInterface $price = null) { - $itemType = $saleableItem === null ? 'default' : $saleableItem->getTypeId(); - $priceType = $price === null ? 'default' : $price->getPriceCode(); + $itemType = null === $saleableItem ? 'default' : $saleableItem->getTypeId(); + $priceType = null === $price ? 'default' : $price->getPriceCode(); $fallbackPattern = [ "{$itemType}/adjustments/{$priceType}", diff --git a/lib/internal/Magento/Framework/Test/Unit/DB/AggregatedFieldDataConverterTest.php b/lib/internal/Magento/Framework/Test/Unit/DB/AggregatedFieldDataConverterTest.php new file mode 100644 index 0000000000000..d0a10b99e3782 --- /dev/null +++ b/lib/internal/Magento/Framework/Test/Unit/DB/AggregatedFieldDataConverterTest.php @@ -0,0 +1,89 @@ +getMockBuilder(AdapterInterface::class)->getMock(); + $queryModifier = $this->getMockBuilder(QueryModifierInterface::class)->getMock(); + $fields = [ + new FieldToConvert( + 'ClassOne', + 'table_1', + 'id_1', + 'field_1' + ), + new FieldToConvert( + 'ClassTwo', + 'table_2', + 'id_2', + 'field_2', + $queryModifier + ), + ]; + $fieldConverterOne = $this->getMockBuilder(FieldDataConverter::class) + ->disableOriginalConstructor() + ->getMock(); + $fieldConverterTwo = clone $fieldConverterOne; + $fieldConverterFactory = $this->createFieldConverterFactory( + [ + ['ClassOne', $fieldConverterOne], + ['ClassTwo', $fieldConverterTwo], + ] + ); + + $this->assertCallsDelegation($connection, $fieldConverterOne, $fieldConverterTwo, $queryModifier); + $object = new AggregatedFieldDataConverter($fieldConverterFactory); + $object->convert($fields, $connection); + } + + /** + * @param array $returnValuesMap + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function createFieldConverterFactory(array $returnValuesMap) + { + $fieldConverterFactory = $this->getMockBuilder(FieldDataConverterFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $fieldConverterFactory->expects($this->any()) + ->method('create') + ->willReturnMap($returnValuesMap); + return $fieldConverterFactory; + } + + /** + * Assert that correct methods with correct arguments are called during delegation of the action + * + * @param $connection + * @param \PHPUnit_Framework_MockObject_MockObject $fieldConverterOne + * @param \PHPUnit_Framework_MockObject_MockObject $fieldConverterTwo + * @param $queryModifier + */ + private function assertCallsDelegation( + $connection, + \PHPUnit_Framework_MockObject_MockObject $fieldConverterOne, + \PHPUnit_Framework_MockObject_MockObject $fieldConverterTwo, + $queryModifier + ) { + $fieldConverterOne->expects($this->once()) + ->method('convert') + ->with($connection, 'table_1', 'id_1', 'field_1', null); + $fieldConverterTwo->expects($this->once()) + ->method('convert') + ->with($connection, 'table_2', 'id_2', 'field_2', $queryModifier); + } +} diff --git a/lib/internal/Magento/Framework/Test/Unit/FlagTest.php b/lib/internal/Magento/Framework/Test/Unit/FlagTest.php index 5757327039083..cb77c25bf28c3 100644 --- a/lib/internal/Magento/Framework/Test/Unit/FlagTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/FlagTest.php @@ -5,145 +5,49 @@ */ namespace Magento\Framework\Test\Unit; -/** - * Class FlagTest - * - * @package Magento\Framework - */ class FlagTest extends \PHPUnit_Framework_TestCase { - /** - * @var \Magento\Framework\Flag - */ - protected $flag; - - /** - * @var \Magento\Framework\Serialize\Serializer\Json - */ - private $json; - - /** - * @var \Magento\Framework\Serialize\Serializer\Serialize - */ - private $serialize; - - protected function setUp() - { - $data = ['flag_code' => 'synchronize']; - $this->createInstance($data); - } - - protected function createInstance(array $data = []) - { - $eventManager = $this->getMock(\Magento\Framework\Event\Manager::class, ['dispatch'], [], '', false, false); - $context = $this->getMock(\Magento\Framework\Model\Context::class, [], [], '', false, false); - $context->expects($this->once()) - ->method('getEventDispatcher') - ->will($this->returnValue($eventManager)); - $registry = $this->getMock(\Magento\Framework\Registry::class, [], [], '', false, false); - - $connection = $this->getMock( - \Magento\Framework\DB\Adapter\Adapter::class, - ['beginTransaction'], - [], - '', - false, - false - ); - $connection->expects($this->any()) - ->method('beginTransaction') - ->will($this->returnSelf()); - $appResource = $this->getMock( - \Magento\Framework\App\ResourceConnection::class, - [], - [], - '', - false, - false - ); - $appResource->expects($this->any()) - ->method('getConnection') - ->will($this->returnValue($connection)); - - $dbContextMock = $this->getMock(\Magento\Framework\Model\ResourceModel\Db\Context::class, [], [], '', false); - $dbContextMock->expects($this->once())->method('getResources')->willReturn($appResource); - $resource = $this->getMock( - \Magento\Framework\Flag\FlagResource::class, - ['__wakeup', 'load', 'save', 'addCommitCallback', 'commit', 'rollBack'], - ['context' => $dbContextMock], - '', - true - ); - $resource->expects($this->any()) - ->method('addCommitCallback') - ->will($this->returnSelf()); - - $resourceCollection = $this->getMockBuilder(\Magento\Framework\Data\Collection\AbstractDb::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $this->json = $this->getMockBuilder(\Magento\Framework\Serialize\Serializer\Json::class) - ->setMethods(null) - ->getMock(); - - $this->serialize = $this->getMockBuilder(\Magento\Framework\Serialize\Serializer\Serialize::class) - ->setMethods(null) - ->getMock(); - - $this->flag = new \Magento\Framework\Flag( - $context, - $registry, - $resource, - $resourceCollection, - $data, - $this->json, - $this->serialize - ); - } - - public function tearDown() - { - unset($this->flag); - } - public function testConstruct() { $flagCode = 'synchronize'; - $this->createInstance(); - $this->flag->setFlagCode('synchronize'); - $this->assertEquals($flagCode, $this->flag->getFlagCode()); + $flag = $this->createFlagInstance(); + $flag->setFlagCode($flagCode); + $this->assertEquals($flagCode, $flag->getFlagCode()); } public function testGetFlagDataJson() { - $result = $this->flag->getFlagData(); - $this->assertNull($result); - $flagData = json_encode('data'); - $this->flag->setData('flag_data', $flagData); - $result = $this->flag->getFlagData(); - $this->assertEquals(json_decode($flagData), $result); + $data = ['foo' => 'bar']; + $serializedData = '{"foo":"bar"}'; + $flag = $this->createFlagInstance(['flag_code' => 'synchronize']); + $this->assertNull($flag->getFlagData()); + $flag->setData('flag_data', $serializedData); + $this->assertEquals($data, $flag->getFlagData()); } public function testGetFlagDataSerialized() { - $result = $this->flag->getFlagData(); - $this->assertNull($result); - $flagData = serialize('data'); - $this->flag->setData('flag_data', $flagData); - $result = $this->flag->getFlagData(); - $this->assertEquals(unserialize($flagData), $result); + $data = 'foo'; + $serializedData = 's:3:"foo";'; + $flag = $this->createFlagInstance(['flag_code' => 'synchronize']); + $this->assertNull($flag->getFlagData()); + $flag->setData('flag_data', $serializedData); + $this->assertEquals($data, $flag->getFlagData()); } public function testSetFlagData() { - $flagData = 'data'; - $this->flag->setFlagData($flagData); - $result = json_decode($this->flag->getData('flag_data')); - $this->assertEquals($flagData, $result); + $data = ['foo' => 'bar']; + $serializedData = '{"foo":"bar"}'; + $flag = $this->createFlagInstance(['flag_code' => 'synchronize']); + $flag->setFlagData($data); + $this->assertEquals($serializedData, $flag->getData('flag_data')); } public function testLoadSelf() { - $this->assertInstanceOf(\Magento\Framework\Flag::class, $this->flag->loadSelf()); + $flag = $this->createFlagInstance(['flag_code' => 'synchronize']); + $this->assertInstanceOf(\Magento\Framework\Flag::class, $flag->loadSelf()); } /** @@ -152,16 +56,17 @@ public function testLoadSelf() */ public function testLoadSelfException() { - $this->createInstance(); - $this->flag->loadSelf(); + $flag = $this->createFlagInstance(); + $flag->loadSelf(); } public function testBeforeSave() { - $this->flag->setData('block', 'blockNmae'); - $result = $this->flag->save(); - $this->assertSame($this->flag, $result); - $this->assertEquals('synchronize', $this->flag->getFlagCode()); + $flagCode = 'synchronize'; + $flag = $this->createFlagInstance(['flag_code' => $flagCode]); + $flag->setData('block', 'blockNmae'); + $this->assertSame($flag, $flag->save()); + $this->assertEquals($flagCode, $flag->getFlagCode()); } /** @@ -170,8 +75,61 @@ public function testBeforeSave() */ public function testBeforeSaveException() { - $this->createInstance(); - $this->flag->setData('block', 'blockNmae'); - $this->flag->beforeSave(); + $flag = $this->createFlagInstance(); + $flag->setData('block', 'blockNmae'); + $flag->beforeSave(); + } + + /** + * @param array $data + * @return \Magento\Framework\Flag + */ + private function createFlagInstance(array $data = []) + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $eventManagerMock = $this->getMock(\Magento\Framework\Event\Manager::class, ['dispatch'], [], '', false); + /** @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject $contextMock */ + $contextMock = $this->getMock(\Magento\Framework\Model\Context::class, [], [], '', false); + $contextMock->expects($this->once()) + ->method('getEventDispatcher') + ->willReturn($eventManagerMock); + $connectionMock = $this->getMock(\Magento\Framework\DB\Adapter\AdapterInterface::class); + $connectionMock->expects($this->any()) + ->method('beginTransaction') + ->willReturnSelf(); + $appResource = $this->getMock( + \Magento\Framework\App\ResourceConnection::class, + [], + [], + '', + false + ); + $appResource->expects($this->any()) + ->method('getConnection') + ->willReturn($connectionMock); + $dbContextMock = $this->getMock(\Magento\Framework\Model\ResourceModel\Db\Context::class, [], [], '', false); + $dbContextMock->expects($this->once()) + ->method('getResources') + ->willReturn($appResource); + $resourceMock = $this->getMock( + \Magento\Framework\Flag\FlagResource::class, + ['__wakeup', 'load', 'save', 'addCommitCallback', 'commit', 'rollBack'], + ['context' => $dbContextMock], + '', + true + ); + $resourceMock->expects($this->any()) + ->method('addCommitCallback') + ->willReturnSelf(); + return $objectManager->getObject( + \Magento\Framework\Flag::class, + [ + 'context' => $contextMock, + 'resource' => $resourceMock, + 'data' => $data, + 'json' => new \Magento\Framework\Serialize\Serializer\Json(), + 'serialize' => new \Magento\Framework\Serialize\Serializer\Serialize() + ] + ); } } diff --git a/lib/internal/Magento/Framework/Unserialize/Test/Unit/UnserializeTest.php b/lib/internal/Magento/Framework/Unserialize/Test/Unit/UnserializeTest.php index 7535078205b2d..571bab0a2471e 100644 --- a/lib/internal/Magento/Framework/Unserialize/Test/Unit/UnserializeTest.php +++ b/lib/internal/Magento/Framework/Unserialize/Test/Unit/UnserializeTest.php @@ -6,54 +6,56 @@ namespace Magento\Framework\Unserialize\Test\Unit; use Magento\Framework\Serialize\Serializer\Serialize; +use Magento\Framework\Unserialize\Unserialize; -/** - * @package Magento\Framework - */ class UnserializeTest extends \PHPUnit_Framework_TestCase { - /** @var \Magento\Framework\Unserialize\Unserialize */ - protected $unserialize; + /** + * @var Serialize|\PHPUnit_Framework_MockObject_MockObject + */ + private $serializerMock; + + /** + * @var Unserialize + */ + private $unserialize; protected function setUp() { - $serializer = $this->getMockBuilder(Serialize::class) - ->setMethods(['serialize', 'unserialize']) + $this->serializerMock = $this->getMockBuilder(Serialize::class) + ->setMethods( + ['serialize', 'unserialize'] + ) ->getMock(); - $serializer->expects($this->any()) - ->method('serialize') - ->willReturnCallback(function ($parameter) { - return serialize($parameter); - }); - $serializer->expects($this->any()) - ->method('unserialize') - ->willReturnCallback(function ($parameter) { - return unserialize($parameter); - }); - $this->unserialize = new \Magento\Framework\Unserialize\Unserialize( - $serializer - ); + $this->unserialize = new Unserialize($this->serializerMock); } public function testUnserializeArray() { - $array = ['foo' => 'bar', 1, 4]; - $this->assertEquals($array, $this->unserialize->unserialize(serialize($array))); + $data = ['foo' => 'bar', 1, 4]; + $serializedData = 'serialzied data'; + $this->serializerMock->expects($this->any()) + ->method('unserialize') + ->with($serializedData) + ->willReturn($data); + $this->assertEquals( + $data, + $this->unserialize->unserialize($serializedData) + ); } /** * @param string $serialized The string containing serialized object - * * @expectedException \Exception * @expectedExceptionMessage String contains serialized object - * @dataProvider serializedObjectDataProvider + * @dataProvider unserializeObjectDataProvider */ public function testUnserializeObject($serialized) { $this->assertFalse($this->unserialize->unserialize($serialized)); } - public function serializedObjectDataProvider() + public function unserializeObjectDataProvider() { return [ // Upper and lower case serialized object indicators, nested in array diff --git a/setup/src/Magento/Setup/Fixtures/_files/orders_fixture_data.json b/setup/src/Magento/Setup/Fixtures/_files/orders_fixture_data.json index 59760c4e5e276..864ad45533afe 100644 --- a/setup/src/Magento/Setup/Fixtures/_files/orders_fixture_data.json +++ b/setup/src/Magento/Setup/Fixtures/_files/orders_fixture_data.json @@ -328,7 +328,7 @@ "cc_number_enc": "NULL", "cc_trans_id": "NULL", "address_status": "NULL", - "additional_information": "'a:1:{s:53:\"a:1:{s:12:\"method_title\";s:19:\"Check \/ Money order\";}\";N;}'" + "additional_information": "'{\"method_title\":\"Check \/ Money order\"}'" }, "sales_order_status_history": { "entity_id": "'%entityId%'", diff --git a/setup/src/Magento/Setup/Module/I18n/Dictionary/Writer/Csv.php b/setup/src/Magento/Setup/Module/I18n/Dictionary/Writer/Csv.php index c1f2d6642debb..4399144b536e1 100644 --- a/setup/src/Magento/Setup/Module/I18n/Dictionary/Writer/Csv.php +++ b/setup/src/Magento/Setup/Module/I18n/Dictionary/Writer/Csv.php @@ -51,21 +51,9 @@ public function write(Phrase $phrase) } /** - * Close file handler + * Destructor for closing resource * * @return void - * - * @deprecated - */ - public function __destructor() - { - if (is_resource($this->_fileHandler)) { - fclose($this->_fileHandler); - } - } - - /** - * Destructor for closing file handler */ public function __destruct() { diff --git a/setup/src/Magento/Setup/Module/I18n/Dictionary/Writer/Csv/Stdo.php b/setup/src/Magento/Setup/Module/I18n/Dictionary/Writer/Csv/Stdo.php index befa0ec81ee8b..1b606f8cf015e 100644 --- a/setup/src/Magento/Setup/Module/I18n/Dictionary/Writer/Csv/Stdo.php +++ b/setup/src/Magento/Setup/Module/I18n/Dictionary/Writer/Csv/Stdo.php @@ -21,4 +21,13 @@ public function __construct() { $this->_fileHandler = STDOUT; } + + /** + * Overriding parent as we can not close globally used resource + * + * @return void + */ + public function __destruct() + { + } } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Dictionary/Writer/Csv/StdoTest.php b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Dictionary/Writer/Csv/StdoTest.php index 554fe7f0c9004..c306838670aeb 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Dictionary/Writer/Csv/StdoTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Dictionary/Writer/Csv/StdoTest.php @@ -11,9 +11,7 @@ class StdoTest extends \PHPUnit_Framework_TestCase { public function testThatHandlerIsRight() { - $handler = STDOUT; - // Mocking object's under test destructor here is perfectly valid as there is no way to reopen STDOUT - $writer = $this->getMock(Stdo::class, ['__destruct']); - $this->assertAttributeEquals($handler, '_fileHandler', $writer); + $writer = new Stdo(); + $this->assertAttributeEquals(STDOUT, '_fileHandler', $writer); } }