Data.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Payment\Helper;
  7. use Magento\Quote\Model\Quote;
  8. use Magento\Store\Model\Store;
  9. use Magento\Payment\Block\Form;
  10. use Magento\Payment\Model\InfoInterface;
  11. use Magento\Framework\View\Element\Template;
  12. use Magento\Framework\View\LayoutInterface;
  13. use Magento\Framework\View\LayoutFactory;
  14. use Magento\Payment\Model\Method\AbstractMethod;
  15. use Magento\Payment\Model\MethodInterface;
  16. /**
  17. * Payment module base helper
  18. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  19. *
  20. * @api
  21. * @since 100.0.2
  22. */
  23. class Data extends \Magento\Framework\App\Helper\AbstractHelper
  24. {
  25. const XML_PATH_PAYMENT_METHODS = 'payment';
  26. /**
  27. * @var \Magento\Payment\Model\Config
  28. */
  29. protected $_paymentConfig;
  30. /**
  31. * Layout
  32. *
  33. * @var \Magento\Framework\View\LayoutInterface
  34. */
  35. protected $_layout;
  36. /**
  37. * Factory for payment method models
  38. *
  39. * @var \Magento\Payment\Model\Method\Factory
  40. */
  41. protected $_methodFactory;
  42. /**
  43. * App emulation model
  44. *
  45. * @var \Magento\Store\Model\App\Emulation
  46. */
  47. protected $_appEmulation;
  48. /**
  49. * @var \Magento\Framework\App\Config\Initial
  50. */
  51. protected $_initialConfig;
  52. /**
  53. * Construct
  54. *
  55. * @param \Magento\Framework\App\Helper\Context $context
  56. * @param LayoutFactory $layoutFactory
  57. * @param \Magento\Payment\Model\Method\Factory $paymentMethodFactory
  58. * @param \Magento\Store\Model\App\Emulation $appEmulation
  59. * @param \Magento\Payment\Model\Config $paymentConfig
  60. * @param \Magento\Framework\App\Config\Initial $initialConfig
  61. */
  62. public function __construct(
  63. \Magento\Framework\App\Helper\Context $context,
  64. LayoutFactory $layoutFactory,
  65. \Magento\Payment\Model\Method\Factory $paymentMethodFactory,
  66. \Magento\Store\Model\App\Emulation $appEmulation,
  67. \Magento\Payment\Model\Config $paymentConfig,
  68. \Magento\Framework\App\Config\Initial $initialConfig
  69. ) {
  70. parent::__construct($context);
  71. $this->_layout = $layoutFactory->create();
  72. $this->_methodFactory = $paymentMethodFactory;
  73. $this->_appEmulation = $appEmulation;
  74. $this->_paymentConfig = $paymentConfig;
  75. $this->_initialConfig = $initialConfig;
  76. }
  77. /**
  78. * Get config name of method model
  79. *
  80. * @param string $code
  81. * @return string
  82. */
  83. protected function getMethodModelConfigName($code)
  84. {
  85. return sprintf('%s/%s/model', self::XML_PATH_PAYMENT_METHODS, $code);
  86. }
  87. /**
  88. * Retrieve method model object
  89. *
  90. * @param string $code
  91. *
  92. * @throws \Magento\Framework\Exception\LocalizedException
  93. * @return MethodInterface
  94. */
  95. public function getMethodInstance($code)
  96. {
  97. $class = $this->scopeConfig->getValue(
  98. $this->getMethodModelConfigName($code),
  99. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  100. );
  101. if (!$class) {
  102. throw new \UnexpectedValueException('Payment model name is not provided in config!');
  103. }
  104. return $this->_methodFactory->create($class);
  105. }
  106. /**
  107. * Get and sort available payment methods for specified or current store
  108. *
  109. * @param null|string|bool|int $store
  110. * @param Quote|null $quote
  111. * @return AbstractMethod[]
  112. * @deprecated 100.1.3
  113. * @see \Magento\Payment\Api\PaymentMethodListInterface
  114. */
  115. public function getStoreMethods($store = null, $quote = null)
  116. {
  117. $res = [];
  118. $methods = $this->getPaymentMethods();
  119. foreach (array_keys($methods) as $code) {
  120. $model = $this->scopeConfig->getValue(
  121. $this->getMethodModelConfigName($code),
  122. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  123. $store
  124. );
  125. if (!$model) {
  126. continue;
  127. }
  128. /** @var AbstractMethod $methodInstance */
  129. $methodInstance = $this->_methodFactory->create($model);
  130. $methodInstance->setStore($store);
  131. if (!$methodInstance->isAvailable($quote)) {
  132. /* if the payment method cannot be used at this time */
  133. continue;
  134. }
  135. $res[] = $methodInstance;
  136. }
  137. @uasort(
  138. $res,
  139. function (MethodInterface $a, MethodInterface $b) {
  140. return (int)$a->getConfigData('sort_order') <=> (int)$b->getConfigData('sort_order');
  141. }
  142. );
  143. return $res;
  144. }
  145. /**
  146. * Retrieve payment method form html
  147. *
  148. * @param MethodInterface $method
  149. * @param LayoutInterface $layout
  150. * @return Form
  151. */
  152. public function getMethodFormBlock(MethodInterface $method, LayoutInterface $layout)
  153. {
  154. $block = $layout->createBlock($method->getFormBlockType(), $method->getCode());
  155. $block->setMethod($method);
  156. return $block;
  157. }
  158. /**
  159. * Retrieve payment information block
  160. *
  161. * @param InfoInterface $info
  162. * @param \Magento\Framework\View\LayoutInterface $layout
  163. * @return Template
  164. */
  165. public function getInfoBlock(InfoInterface $info, LayoutInterface $layout = null)
  166. {
  167. $layout = $layout ?: $this->_layout;
  168. $blockType = $info->getMethodInstance()->getInfoBlockType();
  169. $block = $layout->createBlock($blockType);
  170. $block->setInfo($info);
  171. return $block;
  172. }
  173. /**
  174. * Render payment information block
  175. *
  176. * @param InfoInterface $info
  177. * @param int $storeId
  178. * @return string
  179. * @throws \Exception
  180. */
  181. public function getInfoBlockHtml(InfoInterface $info, $storeId)
  182. {
  183. $this->_appEmulation->startEnvironmentEmulation($storeId);
  184. try {
  185. // Retrieve specified view block from appropriate design package (depends on emulated store)
  186. $paymentBlock = $this->getInfoBlock($info);
  187. $paymentBlock->setArea(\Magento\Framework\App\Area::AREA_FRONTEND)
  188. ->setIsSecureMode(true);
  189. $paymentBlock->getMethod()
  190. ->setStore($storeId);
  191. $paymentBlockHtml = $paymentBlock->toHtml();
  192. } catch (\Exception $exception) {
  193. $this->_appEmulation->stopEnvironmentEmulation();
  194. throw $exception;
  195. }
  196. $this->_appEmulation->stopEnvironmentEmulation();
  197. return $paymentBlockHtml;
  198. }
  199. /**
  200. * Retrieve all payment methods
  201. *
  202. * @return array
  203. */
  204. public function getPaymentMethods()
  205. {
  206. return $this->_initialConfig->getData('default')[self::XML_PATH_PAYMENT_METHODS];
  207. }
  208. /**
  209. * Retrieve all payment methods list as an array
  210. *
  211. * Possible output:
  212. * 1) assoc array as <code> => <title>
  213. * 2) array of array('label' => <title>, 'value' => <code>)
  214. * 3) array of array(
  215. * array('value' => <code>, 'label' => <title>),
  216. * array('value' => array(
  217. * 'value' => array(array(<code1> => <title1>, <code2> =>...),
  218. * 'label' => <group name>
  219. * )),
  220. * array('value' => <code>, 'label' => <title>),
  221. * ...
  222. * )
  223. *
  224. * @param bool $sorted
  225. * @param bool $asLabelValue
  226. * @param bool $withGroups
  227. * @param Store|null $store
  228. * @return array
  229. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  230. * @SuppressWarnings(PHPMD.NPathComplexity)
  231. */
  232. public function getPaymentMethodList($sorted = true, $asLabelValue = false, $withGroups = false, $store = null)
  233. {
  234. $methods = [];
  235. $groups = [];
  236. $groupRelations = [];
  237. foreach ($this->getPaymentMethods() as $code => $data) {
  238. if (!empty($data['active'])) {
  239. $storedTitle = $this->getMethodInstance($code)->getConfigData('title', $store);
  240. if (isset($storedTitle)) {
  241. $methods[$code] = $storedTitle;
  242. } elseif (isset($data['title'])) {
  243. $methods[$code] = $data['title'];
  244. }
  245. }
  246. if ($asLabelValue && $withGroups && isset($data['group'])) {
  247. $groupRelations[$code] = $data['group'];
  248. }
  249. }
  250. if ($asLabelValue && $withGroups) {
  251. $groups = $this->_paymentConfig->getGroups();
  252. foreach ($groups as $code => $title) {
  253. $methods[$code] = $title;
  254. }
  255. }
  256. if ($sorted) {
  257. asort($methods);
  258. }
  259. if ($asLabelValue) {
  260. $labelValues = [];
  261. foreach ($methods as $code => $title) {
  262. $labelValues[$code] = [];
  263. }
  264. foreach ($methods as $code => $title) {
  265. if (isset($groups[$code])) {
  266. $labelValues[$code]['label'] = $title;
  267. if (!isset($labelValues[$code]['value'])) {
  268. $labelValues[$code]['value'] = null;
  269. }
  270. } elseif (isset($groupRelations[$code])) {
  271. unset($labelValues[$code]);
  272. $labelValues[$groupRelations[$code]]['value'][$code] = ['value' => $code, 'label' => $title];
  273. } else {
  274. $labelValues[$code] = ['value' => $code, 'label' => $title];
  275. }
  276. }
  277. return $labelValues;
  278. }
  279. return $methods;
  280. }
  281. /**
  282. * Returns value of Zero Subtotal Checkout / Enabled
  283. *
  284. * @param null|string|bool|int|Store $store
  285. * @return bool
  286. */
  287. public function isZeroSubTotal($store = null)
  288. {
  289. return $this->scopeConfig->getValue(
  290. \Magento\Payment\Model\Method\Free::XML_PATH_PAYMENT_FREE_ACTIVE,
  291. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  292. $store
  293. );
  294. }
  295. /**
  296. * Returns value of Zero Subtotal Checkout / New Order Status
  297. *
  298. * @param null|string|bool|int|Store $store
  299. * @return string
  300. */
  301. public function getZeroSubTotalOrderStatus($store = null)
  302. {
  303. return $this->scopeConfig->getValue(
  304. \Magento\Payment\Model\Method\Free::XML_PATH_PAYMENT_FREE_ORDER_STATUS,
  305. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  306. $store
  307. );
  308. }
  309. /**
  310. * Returns value of Zero Subtotal Checkout / Automatically Invoice All Items
  311. *
  312. * @param null|string|bool|int|Store $store
  313. * @return string
  314. */
  315. public function getZeroSubTotalPaymentAutomaticInvoice($store = null)
  316. {
  317. return $this->scopeConfig->getValue(
  318. \Magento\Payment\Model\Method\Free::XML_PATH_PAYMENT_FREE_PAYMENT_ACTION,
  319. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  320. $store
  321. );
  322. }
  323. }