RendererPool.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Pricing\Render;
  7. use Magento\Framework\Pricing\Amount\AmountInterface;
  8. use Magento\Framework\Pricing\SaleableInterface;
  9. use Magento\Framework\Pricing\Price\PriceInterface;
  10. use Magento\Framework\View\Element\AbstractBlock;
  11. /**
  12. * @api
  13. * @since 100.0.2
  14. */
  15. class RendererPool extends AbstractBlock
  16. {
  17. /**
  18. * Default price group type
  19. */
  20. const DEFAULT_PRICE_GROUP_TYPE = 'default';
  21. /**
  22. * Default price renderer
  23. */
  24. const PRICE_RENDERER_DEFAULT = \Magento\Framework\Pricing\Render\PriceBox::class;
  25. /**
  26. * Default amount renderer
  27. */
  28. const AMOUNT_RENDERER_DEFAULT = \Magento\Framework\Pricing\Render\Amount::class;
  29. /**
  30. * Create amount renderer
  31. *
  32. * @param string $priceCode
  33. * @param SaleableInterface $saleableItem
  34. * @param array $data
  35. * @throws \InvalidArgumentException
  36. * @return PriceBoxRenderInterface
  37. */
  38. public function createPriceRender(
  39. $priceCode,
  40. SaleableInterface $saleableItem,
  41. array $data = []
  42. ) {
  43. $type = $saleableItem->getTypeId();
  44. // implement class resolving fallback
  45. $pattern = [
  46. $type . '/prices/' . $priceCode . '/render_class',
  47. $type . '/default_render_class',
  48. 'default/prices/' . $priceCode . '/render_class',
  49. 'default/default_render_class',
  50. ];
  51. $renderClassName = $this->findDataByPattern($pattern);
  52. if (!$renderClassName) {
  53. throw new \InvalidArgumentException(
  54. 'Class name for price code "' . $priceCode . '" not registered'
  55. );
  56. }
  57. $price = $saleableItem->getPriceInfo()->getPrice($priceCode);
  58. if (!$price) {
  59. throw new \InvalidArgumentException(
  60. 'Price model for price code "' . $priceCode . '" not registered'
  61. );
  62. }
  63. $arguments['data'] = $data;
  64. $arguments['rendererPool'] = $this;
  65. $arguments['price'] = $price;
  66. $arguments['saleableItem'] = $saleableItem;
  67. /** @var \Magento\Framework\View\Element\Template $renderBlock */
  68. $renderBlock = $this->getLayout()->createBlock($renderClassName, '', $arguments);
  69. if (!$renderBlock instanceof PriceBoxRenderInterface) {
  70. throw new \InvalidArgumentException(
  71. 'Block "' . $renderClassName
  72. . '" must implement \Magento\Framework\Pricing\Render\PriceBoxRenderInterface'
  73. );
  74. }
  75. $renderBlock->setTemplate($this->getRenderBlockTemplate($type, $priceCode));
  76. return $renderBlock;
  77. }
  78. /**
  79. * Create amount renderer
  80. *
  81. * @param AmountInterface $amount
  82. * @param SaleableInterface $saleableItem
  83. * @param PriceInterface $price
  84. * @param array $data
  85. * @return AmountRenderInterface
  86. * @throws \InvalidArgumentException
  87. */
  88. public function createAmountRender(
  89. AmountInterface $amount,
  90. SaleableInterface $saleableItem = null,
  91. PriceInterface $price = null,
  92. array $data = []
  93. ) {
  94. $type = self::DEFAULT_PRICE_GROUP_TYPE;
  95. if ($saleableItem) {
  96. $type = $saleableItem->getTypeId();
  97. }
  98. $priceCode = null;
  99. $renderClassName = self::AMOUNT_RENDERER_DEFAULT;
  100. if ($price) {
  101. $priceCode = $price->getPriceCode();
  102. // implement class resolving fallback
  103. $pattern = [
  104. $type . '/prices/' . $priceCode . '/amount_render_class',
  105. $type . '/default_amount_render_class',
  106. 'default/prices/' . $priceCode . '/amount_render_class',
  107. 'default/default_amount_render_class',
  108. ];
  109. $renderClassName = $this->findDataByPattern($pattern);
  110. if (!$renderClassName) {
  111. throw new \InvalidArgumentException(
  112. 'There is no amount render class for price code "' . $priceCode . '"'
  113. );
  114. }
  115. }
  116. $arguments['data'] = $data;
  117. $arguments['rendererPool'] = $this;
  118. $arguments['amount'] = $amount;
  119. if ($saleableItem) {
  120. $arguments['saleableItem'] = $saleableItem;
  121. if ($price) {
  122. $arguments['price'] = $price;
  123. }
  124. }
  125. /** @var \Magento\Framework\View\Element\Template $amountBlock */
  126. $amountBlock = $this->getLayout()->createBlock($renderClassName, '', $arguments);
  127. if (!$amountBlock instanceof AmountRenderInterface) {
  128. throw new \InvalidArgumentException(
  129. 'Block "' . $renderClassName
  130. . '" must implement \Magento\Framework\Pricing\Render\AmountRenderInterface'
  131. );
  132. }
  133. $amountBlock->setTemplate($this->getAmountRenderBlockTemplate($type, $priceCode));
  134. return $amountBlock;
  135. }
  136. /**
  137. * @param SaleableInterface $saleableItem
  138. * @param PriceInterface $price
  139. * @return array
  140. */
  141. public function getAdjustmentRenders(SaleableInterface $saleableItem = null, PriceInterface $price = null)
  142. {
  143. $itemType = null === $saleableItem ? 'default' : $saleableItem->getTypeId();
  144. $priceType = null === $price ? 'default' : $price->getPriceCode();
  145. $fallbackPattern = [
  146. "{$itemType}/adjustments/{$priceType}",
  147. "{$itemType}/adjustments/default",
  148. "default/adjustments/{$priceType}",
  149. "default/adjustments/default",
  150. ];
  151. $renders = $this->findDataByPattern($fallbackPattern);
  152. if ($renders) {
  153. foreach ($renders as $code => $configuration) {
  154. /** @var \Magento\Framework\View\Element\Template $render */
  155. $render = $this->getLayout()->createBlock($configuration['adjustment_render_class']);
  156. $render->setTemplate($configuration['adjustment_render_template']);
  157. $renders[$code] = $render;
  158. }
  159. }
  160. return $renders;
  161. }
  162. /**
  163. * @param string $type
  164. * @param string $priceCode
  165. * @return string
  166. * @throws \InvalidArgumentException
  167. */
  168. protected function getAmountRenderBlockTemplate($type, $priceCode)
  169. {
  170. $pattern = [
  171. $type . '/prices/' . $priceCode . '/amount_render_template',
  172. $type . '/default_amount_render_template',
  173. 'default/prices/' . $priceCode . '/amount_render_template',
  174. 'default/default_amount_render_template',
  175. ];
  176. $template = $this->findDataByPattern($pattern);
  177. if (!$template) {
  178. throw new \InvalidArgumentException(
  179. 'For type "' . $type . '" amount render block not configured'
  180. );
  181. }
  182. return $template;
  183. }
  184. /**
  185. * @param string $type
  186. * @param string $priceCode
  187. * @return string
  188. * @throws \InvalidArgumentException
  189. */
  190. protected function getRenderBlockTemplate($type, $priceCode)
  191. {
  192. $pattern = [
  193. $type . '/prices/' . $priceCode . '/render_template',
  194. $type . '/default_render_template',
  195. 'default/prices/' . $priceCode . '/render_template',
  196. 'default/default_render_template',
  197. ];
  198. $template = $this->findDataByPattern($pattern);
  199. if (!$template) {
  200. throw new \InvalidArgumentException(
  201. 'Price code "' . $priceCode . '" render block not configured'
  202. );
  203. }
  204. return $template;
  205. }
  206. /**
  207. * @param array $pattern
  208. * @return null|string
  209. */
  210. protected function findDataByPattern(array $pattern)
  211. {
  212. $data = null;
  213. foreach ($pattern as $key) {
  214. $data = $this->getData($key);
  215. if ($data) {
  216. break;
  217. }
  218. }
  219. return $data;
  220. }
  221. }