Currency.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Directory\Model\ResourceModel;
  7. /**
  8. * Currency Resource Model
  9. *
  10. * @api
  11. * @since 100.0.2
  12. */
  13. class Currency extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
  14. {
  15. /**
  16. * Currency rate table
  17. *
  18. * @var string
  19. */
  20. protected $_currencyRateTable;
  21. /**
  22. * Currency rate cache array
  23. *
  24. * @var array
  25. */
  26. protected static $_rateCache;
  27. /**
  28. * Define main and currency rate tables
  29. *
  30. * @return void
  31. */
  32. protected function _construct()
  33. {
  34. $this->_init('directory_currency', 'currency_code');
  35. $this->_currencyRateTable = $this->getTable('directory_currency_rate');
  36. }
  37. /**
  38. * Retrieve currency rate (only base=>allowed)
  39. *
  40. * @param \Magento\Directory\Model\Currency|string $currencyFrom
  41. * @param \Magento\Directory\Model\Currency|string $currencyTo
  42. * @return float
  43. */
  44. public function getRate($currencyFrom, $currencyTo)
  45. {
  46. if ($currencyFrom instanceof \Magento\Directory\Model\Currency) {
  47. $currencyFrom = $currencyFrom->getCode();
  48. }
  49. if ($currencyTo instanceof \Magento\Directory\Model\Currency) {
  50. $currencyTo = $currencyTo->getCode();
  51. }
  52. if ($currencyFrom == $currencyTo) {
  53. return 1;
  54. }
  55. if (!isset(self::$_rateCache[$currencyFrom][$currencyTo])) {
  56. $connection = $this->getConnection();
  57. $bind = [':currency_from' => strtoupper($currencyFrom), ':currency_to' => strtoupper($currencyTo)];
  58. $select = $connection->select()->from(
  59. $this->_currencyRateTable,
  60. 'rate'
  61. )->where(
  62. 'currency_from = :currency_from'
  63. )->where(
  64. 'currency_to = :currency_to'
  65. );
  66. self::$_rateCache[$currencyFrom][$currencyTo] = $connection->fetchOne($select, $bind);
  67. }
  68. return self::$_rateCache[$currencyFrom][$currencyTo];
  69. }
  70. /**
  71. * Retrieve currency rate (base=>allowed or allowed=>base)
  72. *
  73. * @param \Magento\Directory\Model\Currency|string $currencyFrom
  74. * @param \Magento\Directory\Model\Currency|string $currencyTo
  75. * @return float
  76. */
  77. public function getAnyRate($currencyFrom, $currencyTo)
  78. {
  79. if ($currencyFrom instanceof \Magento\Directory\Model\Currency) {
  80. $currencyFrom = $currencyFrom->getCode();
  81. }
  82. if ($currencyTo instanceof \Magento\Directory\Model\Currency) {
  83. $currencyTo = $currencyTo->getCode();
  84. }
  85. if ($currencyFrom == $currencyTo) {
  86. return 1;
  87. }
  88. if (!isset(self::$_rateCache[$currencyFrom][$currencyTo])) {
  89. $connection = $this->getConnection();
  90. $bind = [':currency_from' => strtoupper($currencyFrom), ':currency_to' => strtoupper($currencyTo)];
  91. $select = $connection->select()->from(
  92. $this->_currencyRateTable,
  93. 'rate'
  94. )->where(
  95. 'currency_from = :currency_from'
  96. )->where(
  97. 'currency_to = :currency_to'
  98. );
  99. $rate = $connection->fetchOne($select, $bind);
  100. if ($rate === false) {
  101. $select = $connection->select()->from(
  102. $this->_currencyRateTable,
  103. new \Zend_Db_Expr('1/rate')
  104. )->where(
  105. 'currency_to = :currency_from'
  106. )->where(
  107. 'currency_from = :currency_to'
  108. );
  109. $rate = $connection->fetchOne($select, $bind);
  110. }
  111. self::$_rateCache[$currencyFrom][$currencyTo] = $rate;
  112. }
  113. return self::$_rateCache[$currencyFrom][$currencyTo];
  114. }
  115. /**
  116. * Saving currency rates
  117. *
  118. * @param array $rates
  119. * @return void
  120. * @throws \Magento\Framework\Exception\LocalizedException
  121. */
  122. public function saveRates($rates)
  123. {
  124. if (is_array($rates) && sizeof($rates) > 0) {
  125. $connection = $this->getConnection();
  126. $data = [];
  127. foreach ($rates as $currencyCode => $rate) {
  128. foreach ($rate as $currencyTo => $value) {
  129. $value = abs($value);
  130. if ($value == 0) {
  131. continue;
  132. }
  133. $data[] = ['currency_from' => $currencyCode, 'currency_to' => $currencyTo, 'rate' => $value];
  134. }
  135. }
  136. if ($data) {
  137. $connection->insertOnDuplicate($this->_currencyRateTable, $data, ['rate']);
  138. }
  139. } else {
  140. throw new \Magento\Framework\Exception\LocalizedException(__('Please correct the rates received'));
  141. }
  142. }
  143. /**
  144. * Retrieve config currency data by config path
  145. *
  146. * @param \Magento\Directory\Model\Currency $model
  147. * @param string $path
  148. * @return array
  149. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  150. * @deprecated 100.2.3 because doesn't take into consideration scopes and system config values.
  151. * @see \Magento\Directory\Model\CurrencyConfig::getConfigCurrencies()
  152. */
  153. public function getConfigCurrencies($model, $path)
  154. {
  155. $connection = $this->getConnection();
  156. $bind = [':config_path' => $path];
  157. $select = $connection->select()->from($this->getTable('core_config_data'))->where('path = :config_path');
  158. $result = [];
  159. $rowSet = $connection->fetchAll($select, $bind);
  160. foreach ($rowSet as $row) {
  161. $result = array_merge($result, explode(',', $row['value']));
  162. }
  163. sort($result);
  164. return array_unique($result);
  165. }
  166. /**
  167. * Return currency rates
  168. *
  169. * @param string|array $currency
  170. * @param array $toCurrencies
  171. * @return array
  172. */
  173. public function getCurrencyRates($currency, $toCurrencies = null)
  174. {
  175. $rates = [];
  176. if (is_array($currency)) {
  177. foreach ($currency as $code) {
  178. $rates[$code] = $this->_getRatesByCode($code, $toCurrencies);
  179. }
  180. } else {
  181. $rates = $this->_getRatesByCode($currency, $toCurrencies);
  182. }
  183. return $rates;
  184. }
  185. /**
  186. * Protected method used by getCurrencyRates() method
  187. *
  188. * @param string $code
  189. * @param array $toCurrencies
  190. * @return array
  191. */
  192. protected function _getRatesByCode($code, $toCurrencies = null)
  193. {
  194. $connection = $this->getConnection();
  195. $bind = [':currency_from' => $code];
  196. $select = $connection->select()->from(
  197. $this->getTable('directory_currency_rate'),
  198. ['currency_to', 'rate']
  199. )->where(
  200. 'currency_from = :currency_from'
  201. )->where(
  202. 'currency_to IN(?)',
  203. $toCurrencies
  204. );
  205. $rowSet = $connection->fetchAll($select, $bind);
  206. $result = [];
  207. foreach ($rowSet as $row) {
  208. $result[$row['currency_to']] = $row['rate'];
  209. }
  210. return $result;
  211. }
  212. }