Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
FixerIo.php
Go to the documentation of this file.
1 <?php
7 
9 
13 class FixerIo extends AbstractImport
14 {
18  const CURRENCY_CONVERTER_URL = 'http://data.fixer.io/api/latest?access_key={{ACCESS_KEY}}'
19  . '&base={{CURRENCY_FROM}}&symbols={{CURRENCY_TO}}';
20 
26  protected $httpClientFactory;
27 
33  private $scopeConfig;
34 
42  public function __construct(
43  \Magento\Directory\Model\CurrencyFactory $currencyFactory,
44  \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
45  \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory
46  ) {
47  parent::__construct($currencyFactory);
48  $this->scopeConfig = $scopeConfig;
49  $this->httpClientFactory = $httpClientFactory;
50  }
51 
55  public function fetchRates()
56  {
57  $data = [];
58  $currencies = $this->_getCurrencyCodes();
59  $defaultCurrencies = $this->_getDefaultCurrencyCodes();
60 
61  foreach ($defaultCurrencies as $currencyFrom) {
62  if (!isset($data[$currencyFrom])) {
63  $data[$currencyFrom] = [];
64  }
65  $data = $this->convertBatch($data, $currencyFrom, $currencies);
66  ksort($data[$currencyFrom]);
67  }
68  return $data;
69  }
70 
74  protected function _convert($currencyFrom, $currencyTo)
75  {
76  }
77 
86  private function convertBatch(array $data, string $currencyFrom, array $currenciesTo): array
87  {
88  $accessKey = $this->scopeConfig->getValue('currency/fixerio/api_key', ScopeInterface::SCOPE_STORE);
89  if (empty($accessKey)) {
90  $this->_messages[] = __('No API Key was specified or an invalid API Key was specified.');
91  $data[$currencyFrom] = $this->makeEmptyResponse($currenciesTo);
92  return $data;
93  }
94 
95  $currenciesStr = implode(',', $currenciesTo);
96  $url = str_replace(
97  ['{{ACCESS_KEY}}', '{{CURRENCY_FROM}}', '{{CURRENCY_TO}}'],
98  [$accessKey, $currencyFrom, $currenciesStr],
99  self::CURRENCY_CONVERTER_URL
100  );
101 
102  set_time_limit(0);
103  try {
104  $response = $this->getServiceResponse($url);
105  } finally {
106  ini_restore('max_execution_time');
107  }
108 
109  if (!$this->validateResponse($response, $currencyFrom)) {
110  $data[$currencyFrom] = $this->makeEmptyResponse($currenciesTo);
111  return $data;
112  }
113 
114  foreach ($currenciesTo as $currencyTo) {
115  if ($currencyFrom == $currencyTo) {
116  $data[$currencyFrom][$currencyTo] = $this->_numberFormat(1);
117  } else {
118  if (empty($response['rates'][$currencyTo])) {
119  $this->_messages[] = __('We can\'t retrieve a rate from %1 for %2.', $url, $currencyTo);
120  $data[$currencyFrom][$currencyTo] = null;
121  } else {
122  $data[$currencyFrom][$currencyTo] = $this->_numberFormat(
123  (double)$response['rates'][$currencyTo]
124  );
125  }
126  }
127  }
128  return $data;
129  }
130 
138  private function getServiceResponse(string $url, int $retry = 0): array
139  {
141  $httpClient = $this->httpClientFactory->create();
142  $response = [];
143 
144  try {
145  $jsonResponse = $httpClient->setUri($url)
146  ->setConfig(
147  [
148  'timeout' => $this->scopeConfig->getValue(
149  'currency/fixerio/timeout',
150  ScopeInterface::SCOPE_STORE
151  ),
152  ]
153  )
154  ->request('GET')
155  ->getBody();
156 
157  $response = json_decode($jsonResponse, true);
158  } catch (\Exception $e) {
159  if ($retry == 0) {
160  $response = $this->getServiceResponse($url, 1);
161  }
162  }
163  return $response;
164  }
165 
173  private function validateResponse(array $response, string $baseCurrency): bool
174  {
175  if ($response['success']) {
176  return true;
177  }
178 
179  $errorCodes = [
180  101 => __('No API Key was specified or an invalid API Key was specified.'),
181  102 => __('The account this API request is coming from is inactive.'),
182  105 => __('The "%1" is not allowed as base currency for your subscription plan.', $baseCurrency),
183  201 => __('An invalid base currency has been entered.'),
184  ];
185 
186  $this->_messages[] = $errorCodes[$response['error']['code']] ?? __('Currency rates can\'t be retrieved.');
187 
188  return false;
189  }
190 
197  private function makeEmptyResponse(array $currenciesTo): array
198  {
199  return array_fill_keys($currenciesTo, null);
200  }
201 }
$response
Definition: 404.php:11
__construct(\Magento\Directory\Model\CurrencyFactory $currencyFactory, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory)
Definition: FixerIo.php:42
__()
Definition: __.php:13
_convert($currencyFrom, $currencyTo)
Definition: FixerIo.php:74