CurrencyConverterApi.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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\Directory\Model\Currency\Import;
  8. class CurrencyConverterApi extends AbstractImport
  9. {
  10. /**
  11. * @var string
  12. */
  13. const CURRENCY_CONVERTER_URL = 'http://free.currencyconverterapi.com/api/v3/convert?q={{CURRENCY_FROM}}_{{CURRENCY_TO}}&compact=ultra'; //@codingStandardsIgnoreLine
  14. /**
  15. * Http Client Factory
  16. *
  17. * @var \Magento\Framework\HTTP\ZendClientFactory
  18. */
  19. private $httpClientFactory;
  20. /**
  21. * Core scope config
  22. *
  23. * @var \Magento\Framework\App\Config\ScopeConfigInterface
  24. */
  25. private $scopeConfig;
  26. /**
  27. * Initialize dependencies
  28. *
  29. * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory
  30. * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
  31. * @param \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory
  32. */
  33. public function __construct(
  34. \Magento\Directory\Model\CurrencyFactory $currencyFactory,
  35. \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
  36. \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory
  37. ) {
  38. parent::__construct($currencyFactory);
  39. $this->scopeConfig = $scopeConfig;
  40. $this->httpClientFactory = $httpClientFactory;
  41. }
  42. /**
  43. * {@inheritdoc}
  44. */
  45. public function fetchRates()
  46. {
  47. $data = [];
  48. $currencies = $this->_getCurrencyCodes();
  49. $defaultCurrencies = $this->_getDefaultCurrencyCodes();
  50. foreach ($defaultCurrencies as $currencyFrom) {
  51. if (!isset($data[$currencyFrom])) {
  52. $data[$currencyFrom] = [];
  53. }
  54. $data = $this->convertBatch($data, $currencyFrom, $currencies);
  55. ksort($data[$currencyFrom]);
  56. }
  57. return $data;
  58. }
  59. /**
  60. * Return currencies convert rates in batch mode
  61. *
  62. * @param array $data
  63. * @param string $currencyFrom
  64. * @param array $currenciesTo
  65. * @return array
  66. */
  67. private function convertBatch($data, $currencyFrom, $currenciesTo)
  68. {
  69. foreach ($currenciesTo as $to) {
  70. set_time_limit(0);
  71. try {
  72. $url = str_replace('{{CURRENCY_FROM}}', $currencyFrom, self::CURRENCY_CONVERTER_URL);
  73. $url = str_replace('{{CURRENCY_TO}}', $to, $url);
  74. $response = $this->getServiceResponse($url);
  75. if ($currencyFrom == $to) {
  76. $data[$currencyFrom][$to] = $this->_numberFormat(1);
  77. } else {
  78. if (empty($response)) {
  79. $this->_messages[] = __('We can\'t retrieve a rate from %1 for %2.', $url, $to);
  80. $data[$currencyFrom][$to] = null;
  81. } else {
  82. $data[$currencyFrom][$to] = $this->_numberFormat(
  83. (double)$response[$currencyFrom . '_' . $to]
  84. );
  85. }
  86. }
  87. } finally {
  88. ini_restore('max_execution_time');
  89. }
  90. }
  91. return $data;
  92. }
  93. /**
  94. * Get Fixer.io service response
  95. *
  96. * @param string $url
  97. * @param int $retry
  98. * @return array
  99. */
  100. private function getServiceResponse($url, $retry = 0)
  101. {
  102. /** @var \Magento\Framework\HTTP\ZendClient $httpClient */
  103. $httpClient = $this->httpClientFactory->create();
  104. $response = [];
  105. try {
  106. $jsonResponse = $httpClient->setUri(
  107. $url
  108. )->setConfig(
  109. [
  110. 'timeout' => $this->scopeConfig->getValue(
  111. 'currency/currencyconverterapi/timeout',
  112. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  113. ),
  114. ]
  115. )->request(
  116. 'GET'
  117. )->getBody();
  118. $response = json_decode($jsonResponse, true);
  119. } catch (\Exception $e) {
  120. if ($retry == 0) {
  121. $response = $this->getServiceResponse($url, 1);
  122. }
  123. }
  124. return $response;
  125. }
  126. /**
  127. * {@inheritdoc}
  128. */
  129. protected function _convert($currencyFrom, $currencyTo)
  130. {
  131. return 1;
  132. }
  133. }