ContentConverter.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Cms\Setup;
  7. use Magento\Framework\Data\Wysiwyg\Normalizer;
  8. use Magento\Framework\DB\DataConverter\DataConversionException;
  9. use Magento\Framework\DB\DataConverter\SerializedToJson;
  10. use Magento\Framework\Serialize\Serializer\Json;
  11. use Magento\Framework\Serialize\Serializer\Serialize;
  12. use Magento\Framework\Filter\Template\Tokenizer\ParameterFactory;
  13. /**
  14. * Convert conditions_encoded part of cms block content data from serialized to JSON format
  15. */
  16. class ContentConverter extends SerializedToJson
  17. {
  18. /**
  19. * @var ParameterFactory
  20. */
  21. private $parameterFactory;
  22. /**
  23. * @var Normalizer
  24. */
  25. private $normalizer;
  26. /**
  27. * ContentConverter constructor
  28. *
  29. * @param Serialize $serialize
  30. * @param Json $json
  31. * @param ParameterFactory $parameterFactory
  32. * @param Normalizer $normalizer
  33. */
  34. public function __construct(
  35. Serialize $serialize,
  36. Json $json,
  37. ParameterFactory $parameterFactory,
  38. Normalizer $normalizer
  39. ) {
  40. $this->parameterFactory = $parameterFactory;
  41. $this->normalizer = $normalizer;
  42. parent::__construct($serialize, $json);
  43. }
  44. /**
  45. * Convert conditions_encoded part of block content from serialized to JSON format
  46. *
  47. * @param string $value
  48. * @return string
  49. * @throws DataConversionException
  50. */
  51. public function convert($value)
  52. {
  53. preg_match_all('/(.*?){{widget(.*?)}}/si', $value, $matches, PREG_SET_ORDER);
  54. if (empty($matches)) {
  55. return $value;
  56. }
  57. $convertedValue = '';
  58. foreach ($matches as $match) {
  59. $convertedValue .= $match[1] . '{{widget' . $this->convertWidgetParams($match[2]) . '}}';
  60. }
  61. preg_match_all('/(.*?{{widget.*?}})*(?<ending>.*?)$/si', $value, $matchesTwo, PREG_SET_ORDER);
  62. if (isset($matchesTwo[0])) {
  63. $convertedValue .= $matchesTwo[0]['ending'];
  64. }
  65. return $convertedValue;
  66. }
  67. /**
  68. * @inheritdoc
  69. */
  70. protected function isValidJsonValue($value)
  71. {
  72. return parent::isValidJsonValue($this->normalizer->restoreReservedCharacters($value));
  73. }
  74. /**
  75. * Convert widget parameters from serialized format to JSON format
  76. *
  77. * @param string $paramsString
  78. * @return string
  79. */
  80. private function convertWidgetParams($paramsString)
  81. {
  82. /** @var \Magento\Framework\Filter\Template\Tokenizer\Parameter $tokenizer */
  83. $tokenizer = $this->parameterFactory->create();
  84. $tokenizer->setString($paramsString);
  85. $widgetParameters = $tokenizer->tokenize();
  86. if (isset($widgetParameters['conditions_encoded'])) {
  87. if ($this->isValidJsonValue($widgetParameters['conditions_encoded'])) {
  88. return $paramsString;
  89. }
  90. $conditions = $this->restoreReservedCharactersInSerializedContent($widgetParameters['conditions_encoded']);
  91. $widgetParameters['conditions_encoded'] = $this->normalizer->replaceReservedCharacters(
  92. parent::convert($conditions)
  93. );
  94. $newParamsString = '';
  95. foreach ($widgetParameters as $key => $parameter) {
  96. $newParamsString .= ' ' . $key . '="' . $parameter . '"';
  97. }
  98. return $newParamsString;
  99. } else {
  100. return $paramsString;
  101. }
  102. }
  103. /**
  104. * Restore the reserved characters in the existing serialized content
  105. *
  106. * @param string $serializedContent
  107. * @return string
  108. */
  109. private function restoreReservedCharactersInSerializedContent($serializedContent)
  110. {
  111. $map = [
  112. '{' => '[',
  113. '}' => ']',
  114. '"' => '`',
  115. '\\' => '|',
  116. ];
  117. return str_replace(
  118. array_values($map),
  119. array_keys($map),
  120. $serializedContent
  121. );
  122. }
  123. }