diff --git a/config/currency.php b/config/currency.php index 0f580af..ebe9b3f 100644 --- a/config/currency.php +++ b/config/currency.php @@ -20,12 +20,33 @@ | API Key for OpenExchangeRates.org |-------------------------------------------------------------------------- | - | Only required if you with to use the Open Exchange Rates api. You can - | always just use Yahoo, the current default. + | Only required if you want to use the Open Exchange Rates api. | */ - 'api_key' => '', + 'openexchangerates_api_key' => env('OPENEXCHANGERATES_API_KEY'), + + /* + |-------------------------------------------------------------------------- + | API Key for Exchangeratesapi.io + |-------------------------------------------------------------------------- + | + | Only required if you want to use the Exchange Rates api. + | + */ + + 'exchangerates_api_key' => env('EXCHANGERATES_API_KEY'), + + /* + |-------------------------------------------------------------------------- + | API Key for Fixer.io + |-------------------------------------------------------------------------- + | + | Only required if you want to use the Fixer api. + | + */ + + 'fixer_api_key' => env('FIXER_API_KEY'), /* |-------------------------------------------------------------------------- @@ -113,4 +134,4 @@ ], ], -]; \ No newline at end of file +]; diff --git a/src/Console/Update.php b/src/Console/Update.php index b488408..fe15837 100644 --- a/src/Console/Update.php +++ b/src/Console/Update.php @@ -16,7 +16,7 @@ class Update extends Command protected $signature = 'currency:update {--e|exchangeratesapi : Get rates from ExchangeRatesApi.io} {--o|openexchangerates : Get rates from OpenExchangeRates.org} - {--g|google : Get rates from Google Finance}'; + {--f|fixer : Get rates from Fixer.io}'; /** * The console command description. @@ -65,43 +65,62 @@ public function handle() $defaultCurrency = $this->currency->config('default'); if ($this->input->getOption('exchangeratesapi')) { - // Get rates from exchangeratesapi - return $this->updateFromExchangeRatesApi($defaultCurrency); + if (!$api = $this->currency->config('exchangerates_api_key')) { + $this->error('An API key is needed from Exchangeratesapi.io to continue.'); + + return; + } + // Get rates from Exchangeratesapi + return $this->updateFromExchangeRatesApi($defaultCurrency, $api); } - if ($this->input->getOption('google')) { - // Get rates from google - return $this->updateFromGoogle($defaultCurrency); + if ($this->input->getOption('fixer')) { + if (!$api = $this->currency->config('fixer_api_key')) { + $this->error('An API key is needed from Fixer.io to continue.'); + + return; + } + + // Get rates from Fixer + return $this->updateFromFixerIO($defaultCurrency, $api); } if ($this->input->getOption('openexchangerates')) { - if (! $api = $this->currency->config('api_key')) { + $apiLegacy = $this->currency->config('api_key'); + $api = $this->currency->config('openexchangerates_api_key'); + + if (!$apiLegacy && !$api) { //to stay retro compatible $this->error('An API key is needed from OpenExchangeRates.org to continue.'); return; + } else if ($apiLegacy && !$api) { //to stay retro compatible + $api = $apiLegacy; + $this->warn('Configuration "api_key" is deprecated please use "openexchangerates_api_key" instead'); } // Get rates from OpenExchangeRates return $this->updateFromOpenExchangeRates($defaultCurrency, $api); } + + $this->error('Parameter is missing, please refer to --help to have all the parameter possible'); } /** * Fetch rates from the API * * @param $defaultCurrency + * @param $api */ - private function updateFromExchangeRatesApi($defaultCurrency) + private function updateFromExchangeRatesApi($defaultCurrency, $api) { $this->info('Updating currency exchange rates from ExchangeRatesApi.io...'); // Make request - $content = json_decode($this->request("https://api.exchangeratesapi.io/latest?base={$defaultCurrency}")); + $content = json_decode($this->request("http://api.exchangeratesapi.io/v1/latest?base={$defaultCurrency}&access_key={$api}")); // Error getting content? if (isset($content->error)) { - $this->error($content->description); - + $this->log_error($content); return; } @@ -129,16 +148,43 @@ private function updateFromOpenExchangeRates($defaultCurrency, $api) { $this->info('Updating currency exchange rates from OpenExchangeRates.org...'); + $url = "http://openexchangerates.org/api/latest.json?app_id={$api}&show_alternative=1"; + // Make request $content = json_decode( - $this->request("http://openexchangerates.org/api/latest.json?base={$defaultCurrency}&app_id={$api}&show_alternative=1") + $this->request($url . "&base={$defaultCurrency}") ); - + // logger()->info(json_encode($content)); // Error getting content? if (isset($content->error)) { - $this->error($content->description); - - return; + $strToCompare = 'Changing the API `base` currency is available'; + if (strncmp($content->description, $strToCompare, strlen($strToCompare)) === 0) { + $this->warn($content->description); + $this->warn("Trying to retrieve exchange rates from the default currency then convert to $defaultCurrency, small divergence may appear!"); + $content = json_decode( + $this->request($url) + ); + if (isset($content->error)) { + $this->log_error($content); + return; + } + if (!isset($content->rates->{$defaultCurrency})) { + $this->error("Can't find the default currency '$defaultCurrency'"); + return; + } + $rateCorrection = $content->rates->{$defaultCurrency}; + foreach ($content->rates as $code => $value) { + if ($code === $defaultCurrency) { + $content->rates->{$code} = 1; + } else { + $content->rates->{$code} = round($content->rates->{$code} / $rateCorrection, 6); + } + } + $content->base = $defaultCurrency; + } else { + $this->log_error($content); + return; + } } // Parse timestamp for DB @@ -158,34 +204,83 @@ private function updateFromOpenExchangeRates($defaultCurrency, $api) } /** - * Fetch rates from Google Finance + * Fetch rates from Fixer API * * @param $defaultCurrency + * @param $api */ - private function updateFromGoogle($defaultCurrency) + private function updateFromFixerIO($defaultCurrency, $api) { - $this->info('Updating currency exchange rates from finance.google.com...'); + $this->info('Updating currency exchange rates from fixer.io...'); + $url = "http://data.fixer.io/api/latest?access_key={$api}&format=1"; - foreach ($this->currency->getDriver()->all() as $code => $value) { - // Don't update the default currency, the value is always 1 - if ($code === $defaultCurrency) { - continue; + // Make request + $content = json_decode($this->request($url . "&base={$defaultCurrency}")); + + // Error getting content? + if (isset($content->error)) { + $strToCompare = 'base_currency_access_restricted'; + if (isset($content->error->type) && strncmp($content->error->type, $strToCompare, strlen($strToCompare)) === 0) { + $this->warn($content->error->type); + $this->warn("Trying to retrieve exchange rates from the default currency then convert to $defaultCurrency, small divergence may appear!"); + $content = json_decode( + $this->request($url) + ); + if (isset($content->error)) { + $this->log_error($content); + return; + } + if (!isset($content->rates->{$defaultCurrency})) { + $this->error("Can't find the default currency '$defaultCurrency'"); + return; + } + $rateCorrection = $content->rates->{$defaultCurrency}; + foreach ($content->rates as $code => $value) { + if ($code === $defaultCurrency) { + $content->rates->{$code} = 1; + } else { + $content->rates->{$code} = round($content->rates->{$code} / $rateCorrection, 6); + } + } + $content->base = $defaultCurrency; + } else { + $this->log_error($content); + return; } + } - $response = $this->request('http://finance.google.com/finance/converter?a=1&from=' . $defaultCurrency . '&to=' . $code); + // Parse timestamp for DB + $timestamp = (new DateTime())->setTimestamp($content->timestamp); - if (Str::contains($response, 'bld>')) { - $data = explode('bld>', $response); - $rate = explode($code, $data[1])[0]; + // Update each rate + foreach ($content->rates as $code => $value) { + $this->currency->getDriver()->update($code, [ + 'exchange_rate' => $value, + 'updated_at' => $timestamp, + ]); + } - $this->currency->getDriver()->update($code, [ - 'exchange_rate' => $rate, - ]); - } else { - $this->warn('Can\'t update rate for ' . $code); - continue; - } + $this->currency->clearCache(); + + $this->info('Update!'); + } + + function log_error($content) + { + if (isset($content->description)) { + $this->error($content->description); + } elseif (isset($content->error->message)) { + $this->error($content->error->message); + } elseif (isset($content->description)) { + $this->error($content->description); + } elseif (isset($content->error->info)) { + $this->error($content->error->info); + } elseif (isset($content->error->type)) { + $this->error($content->error->type); + } else { + $this->error('An error occurred please check your configuration.'); } + return; } /**