Output.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\Catalog\Helper;
  8. use Magento\Catalog\Model\Category as ModelCategory;
  9. use Magento\Catalog\Model\Product as ModelProduct;
  10. use Magento\Framework\Filter\Template;
  11. class Output extends \Magento\Framework\App\Helper\AbstractHelper
  12. {
  13. /**
  14. * Array of existing handlers
  15. *
  16. * @var array
  17. */
  18. protected $_handlers;
  19. /**
  20. * Template processor instance
  21. *
  22. * @var Template
  23. */
  24. protected $_templateProcessor = null;
  25. /**
  26. * Catalog data
  27. *
  28. * @var Data
  29. */
  30. protected $_catalogData = null;
  31. /**
  32. * Eav config
  33. *
  34. * @var \Magento\Eav\Model\Config
  35. */
  36. protected $_eavConfig;
  37. /**
  38. * @var \Magento\Framework\Escaper
  39. */
  40. protected $_escaper;
  41. /**
  42. * @var array
  43. */
  44. private $directivePatterns;
  45. /**
  46. * Output constructor.
  47. * @param \Magento\Framework\App\Helper\Context $context
  48. * @param \Magento\Eav\Model\Config $eavConfig
  49. * @param Data $catalogData
  50. * @param \Magento\Framework\Escaper $escaper
  51. * @param array $directivePatterns
  52. */
  53. public function __construct(
  54. \Magento\Framework\App\Helper\Context $context,
  55. \Magento\Eav\Model\Config $eavConfig,
  56. Data $catalogData,
  57. \Magento\Framework\Escaper $escaper,
  58. $directivePatterns = []
  59. ) {
  60. $this->_eavConfig = $eavConfig;
  61. $this->_catalogData = $catalogData;
  62. $this->_escaper = $escaper;
  63. $this->directivePatterns = $directivePatterns;
  64. parent::__construct($context);
  65. }
  66. /**
  67. * @return Template
  68. */
  69. protected function _getTemplateProcessor()
  70. {
  71. if (null === $this->_templateProcessor) {
  72. $this->_templateProcessor = $this->_catalogData->getPageTemplateProcessor();
  73. }
  74. return $this->_templateProcessor;
  75. }
  76. /**
  77. * Adding method handler
  78. *
  79. * @param string $method
  80. * @param object $handler
  81. * @return $this
  82. */
  83. public function addHandler($method, $handler)
  84. {
  85. if (!is_object($handler)) {
  86. return $this;
  87. }
  88. $method = strtolower($method);
  89. if (!isset($this->_handlers[$method])) {
  90. $this->_handlers[$method] = [];
  91. }
  92. $this->_handlers[$method][] = $handler;
  93. return $this;
  94. }
  95. /**
  96. * Get all handlers for some method
  97. *
  98. * @param string $method
  99. * @return array
  100. */
  101. public function getHandlers($method)
  102. {
  103. $method = strtolower($method);
  104. return $this->_handlers[$method] ?? [];
  105. }
  106. /**
  107. * Process all method handlers
  108. *
  109. * @param string $method
  110. * @param mixed $result
  111. * @param array $params
  112. * @return mixed
  113. */
  114. public function process($method, $result, $params)
  115. {
  116. foreach ($this->getHandlers($method) as $handler) {
  117. if (method_exists($handler, $method)) {
  118. $result = $handler->{$method}($this, $result, $params);
  119. }
  120. }
  121. return $result;
  122. }
  123. /**
  124. * Prepare product attribute html output
  125. *
  126. * @param ModelProduct $product
  127. * @param string $attributeHtml
  128. * @param string $attributeName
  129. * @return string
  130. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  131. * @throws \Magento\Framework\Exception\LocalizedException
  132. */
  133. public function productAttribute($product, $attributeHtml, $attributeName)
  134. {
  135. $attribute = $this->_eavConfig->getAttribute(ModelProduct::ENTITY, $attributeName);
  136. if ($attribute &&
  137. $attribute->getId() &&
  138. $attribute->getFrontendInput() != 'media_image' &&
  139. (!$attribute->getIsHtmlAllowedOnFront() &&
  140. !$attribute->getIsWysiwygEnabled())
  141. ) {
  142. if ($attribute->getFrontendInput() != 'price') {
  143. $attributeHtml = $this->_escaper->escapeHtml($attributeHtml);
  144. }
  145. if ($attribute->getFrontendInput() == 'textarea') {
  146. $attributeHtml = nl2br($attributeHtml);
  147. }
  148. }
  149. if ($attributeHtml !== null
  150. && $attribute->getIsHtmlAllowedOnFront()
  151. && $attribute->getIsWysiwygEnabled()
  152. && $this->isDirectivesExists($attributeHtml)
  153. ) {
  154. $attributeHtml = $this->_getTemplateProcessor()->filter($attributeHtml);
  155. }
  156. $attributeHtml = $this->process(
  157. 'productAttribute',
  158. $attributeHtml,
  159. ['product' => $product, 'attribute' => $attributeName]
  160. );
  161. return $attributeHtml;
  162. }
  163. /**
  164. * Prepare category attribute html output
  165. *
  166. * @param ModelCategory $category
  167. * @param string $attributeHtml
  168. * @param string $attributeName
  169. * @return string
  170. * @throws \Magento\Framework\Exception\LocalizedException
  171. */
  172. public function categoryAttribute($category, $attributeHtml, $attributeName)
  173. {
  174. $attribute = $this->_eavConfig->getAttribute(ModelCategory::ENTITY, $attributeName);
  175. if ($attribute &&
  176. $attribute->getFrontendInput() != 'image' &&
  177. (!$attribute->getIsHtmlAllowedOnFront() &&
  178. !$attribute->getIsWysiwygEnabled())
  179. ) {
  180. $attributeHtml = $this->_escaper->escapeHtml($attributeHtml);
  181. }
  182. if ($attributeHtml !== null
  183. && $attribute->getIsHtmlAllowedOnFront()
  184. && $attribute->getIsWysiwygEnabled()
  185. && $this->isDirectivesExists($attributeHtml)
  186. ) {
  187. $attributeHtml = $this->_getTemplateProcessor()->filter($attributeHtml);
  188. }
  189. $attributeHtml = $this->process(
  190. 'categoryAttribute',
  191. $attributeHtml,
  192. ['category' => $category, 'attribute' => $attributeName]
  193. );
  194. return $attributeHtml;
  195. }
  196. /**
  197. * Check if string has directives
  198. *
  199. * @param string $attributeHtml
  200. * @return bool
  201. */
  202. public function isDirectivesExists($attributeHtml)
  203. {
  204. $matches = false;
  205. foreach ($this->directivePatterns as $pattern) {
  206. if (preg_match($pattern, $attributeHtml)) {
  207. $matches = true;
  208. break;
  209. }
  210. }
  211. return $matches;
  212. }
  213. }