Admin.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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\Sales\Helper;
  8. /**
  9. * Sales admin helper.
  10. */
  11. class Admin extends \Magento\Framework\App\Helper\AbstractHelper
  12. {
  13. /**
  14. * @var \Magento\Sales\Model\Config
  15. */
  16. protected $_salesConfig;
  17. /**
  18. * @var \Magento\Store\Model\StoreManagerInterface
  19. */
  20. protected $_storeManager;
  21. /**
  22. * @var \Magento\Framework\Pricing\PriceCurrencyInterface
  23. */
  24. protected $priceCurrency;
  25. /**
  26. * @var \Magento\Framework\Escaper
  27. */
  28. protected $escaper;
  29. /**
  30. * @param \Magento\Framework\App\Helper\Context $context
  31. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  32. * @param \Magento\Sales\Model\Config $salesConfig
  33. * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
  34. * @param \Magento\Framework\Escaper $escaper
  35. */
  36. public function __construct(
  37. \Magento\Framework\App\Helper\Context $context,
  38. \Magento\Store\Model\StoreManagerInterface $storeManager,
  39. \Magento\Sales\Model\Config $salesConfig,
  40. \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
  41. \Magento\Framework\Escaper $escaper
  42. ) {
  43. $this->priceCurrency = $priceCurrency;
  44. $this->_storeManager = $storeManager;
  45. $this->_salesConfig = $salesConfig;
  46. $this->escaper = $escaper;
  47. parent::__construct($context);
  48. }
  49. /**
  50. * Display price attribute value in base order currency and in place order currency
  51. *
  52. * @param \Magento\Framework\DataObject $dataObject
  53. * @param string $code
  54. * @param bool $strong
  55. * @param string $separator
  56. * @return string
  57. */
  58. public function displayPriceAttribute($dataObject, $code, $strong = false, $separator = '<br/>')
  59. {
  60. // Fix for 'bs_customer_bal_total_refunded' attribute
  61. $baseValue = $dataObject->hasData('bs_' . $code)
  62. ? $dataObject->getData('bs_' . $code)
  63. : $dataObject->getData('base_' . $code);
  64. return $this->displayPrices(
  65. $dataObject,
  66. $baseValue,
  67. $dataObject->getData($code),
  68. $strong,
  69. $separator
  70. );
  71. }
  72. /**
  73. * Get "double" prices html (block with base and place currency)
  74. *
  75. * @param \Magento\Framework\DataObject $dataObject
  76. * @param float $basePrice
  77. * @param float $price
  78. * @param bool $strong
  79. * @param string $separator
  80. * @return string
  81. */
  82. public function displayPrices($dataObject, $basePrice, $price, $strong = false, $separator = '<br/>')
  83. {
  84. if ($dataObject instanceof \Magento\Sales\Model\Order) {
  85. $order = $dataObject;
  86. } else {
  87. $order = $dataObject->getOrder();
  88. }
  89. if ($order && $order->isCurrencyDifferent()) {
  90. $res = '<strong>';
  91. $res .= $order->formatBasePrice($basePrice);
  92. $res .= '</strong>' . $separator;
  93. $res .= '[' . $order->formatPrice($price) . ']';
  94. } elseif ($order) {
  95. $res = $order->formatPrice($price);
  96. if ($strong) {
  97. $res = '<strong>' . $res . '</strong>';
  98. }
  99. } else {
  100. $res = $this->priceCurrency->format($price);
  101. if ($strong) {
  102. $res = '<strong>' . $res . '</strong>';
  103. }
  104. }
  105. return $res;
  106. }
  107. /**
  108. * Filter collection by removing not available product types
  109. *
  110. * @param \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection $collection
  111. * @return \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
  112. */
  113. public function applySalableProductTypesFilter($collection)
  114. {
  115. $productTypes = $this->_salesConfig->getAvailableProductTypes();
  116. foreach ($collection->getItems() as $key => $item) {
  117. if ($item instanceof \Magento\Catalog\Model\Product) {
  118. $type = $item->getTypeId();
  119. } elseif ($item instanceof \Magento\Sales\Model\Order\Item) {
  120. $type = $item->getProductType();
  121. } elseif ($item instanceof \Magento\Quote\Model\Quote\Item) {
  122. $type = $item->getProductType();
  123. } else {
  124. $type = '';
  125. }
  126. if (!in_array($type, $productTypes)) {
  127. $collection->removeItemByKey($key);
  128. }
  129. }
  130. return $collection;
  131. }
  132. /**
  133. * Escape string preserving links
  134. *
  135. * @param string $data
  136. * @param null|array $allowedTags
  137. * @return string
  138. */
  139. public function escapeHtmlWithLinks($data, $allowedTags = null)
  140. {
  141. if (!empty($data) && is_array($allowedTags) && in_array('a', $allowedTags)) {
  142. $links = [];
  143. $i = 1;
  144. $data = str_replace('%', '%%', $data);
  145. $regexp = "#(?J)<a"
  146. ."(?:(?:\s+(?:(?:href\s*=\s*(['\"])(?<link>.*?)\\1\s*)|(?:\S+\s*=\s*(['\"])(.*?)\\3)\s*)*)|>)"
  147. .">?(?:(?:(?<text>.*?)(?:<\/a\s*>?|(?=<\w))|(?<text>.*)))#si";
  148. while (preg_match($regexp, $data, $matches)) {
  149. $text = '';
  150. if (!empty($matches['text'])) {
  151. $text = str_replace('%%', '%', $matches['text']);
  152. }
  153. $url = $this->filterUrl($matches['link'] ?? '');
  154. //Recreate a minimalistic secure a tag
  155. $links[] = sprintf(
  156. '<a href="%s">%s</a>',
  157. htmlspecialchars($url, ENT_QUOTES, 'UTF-8', false),
  158. $this->escaper->escapeHtml($text)
  159. );
  160. $data = str_replace($matches[0], '%' . $i . '$s', $data);
  161. ++$i;
  162. }
  163. $data = $this->escaper->escapeHtml($data, $allowedTags);
  164. return vsprintf($data, $links);
  165. }
  166. return $this->escaper->escapeHtml($data, $allowedTags);
  167. }
  168. /**
  169. * Filter the URL for allowed protocols.
  170. *
  171. * @param string $url
  172. * @return string
  173. */
  174. private function filterUrl(string $url): string
  175. {
  176. if ($url) {
  177. //Revert the sprintf escaping
  178. $url = str_replace('%%', '%', $url);
  179. $urlScheme = parse_url($url, PHP_URL_SCHEME);
  180. $urlScheme = $urlScheme ? strtolower($urlScheme) : '';
  181. if ($urlScheme !== 'http' && $urlScheme !== 'https') {
  182. $url = null;
  183. }
  184. }
  185. if (!$url) {
  186. $url = '#';
  187. }
  188. return $url;
  189. }
  190. }