Fixer::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\ExchangeRates\Provider;
6
7
use App\ExchangeRates\Exception\ServiceUnavailableException;
8
use GuzzleHttp\ClientInterface;
9
use GuzzleHttp\Exception\GuzzleException;
10
11
class Fixer implements ProviderInterface
12
{
13
    protected const REQUEST_METHOD = 'GET';
14
15
    /**
16
     * @var string
17
     */
18
    protected $baseUri;
19
20
    /**
21
     * @var string
22
     */
23
    protected $token;
24
25
    /**
26
     * @var ClientInterface
27
     */
28
    protected $client;
29
30
    public function __construct(string $baseUri, string $token, ClientInterface $client)
31
    {
32
        $this->baseUri = $baseUri;
33
        $this->token   = $token;
34
        $this->client  = $client;
35
    }
36
37
    /**
38
     * @param string $baseCurrency
39
     * @param string $targetCurrency
40
     *
41
     * @return float
42
     *
43
     * @throws ServiceUnavailableException
44
     */
45
    public function getLatestExchangeRate(string $baseCurrency, string $targetCurrency): float
46
    {
47
        $baseCurrency   = strtoupper($baseCurrency);
48
        $targetCurrency = strtoupper($targetCurrency);
49
50
        if ($baseCurrency === $targetCurrency) {
51
            return 1.0;
52
        }
53
54
        try {
55
            $response = $this->client->request(
56
                static::REQUEST_METHOD,
57
                $this->baseUri,
58
                [
59
                    'query' => [
60
                        'base'       => $baseCurrency,
61
                        'access_key' => $this->token,
62
                    ],
63
                ]
64
            );
65
66
            $responseAsStdObject = \GuzzleHttp\json_decode($response->getBody());
67
        } catch (GuzzleException $e) {
68
            throw new ServiceUnavailableException('', 504, $e);
69
        }
70
71
        if (!property_exists($responseAsStdObject->rates, $targetCurrency)) {
72
            throw new ServiceUnavailableException(
73
                'We\'re currently experiencing some problems, please try again shortly or contact us.'
74
            );
75
        }
76
77
        return (float) $responseAsStdObject->rates->{$targetCurrency};
78
    }
79
80
    /**
81
     * @return array
82
     *
83
     * @throws ServiceUnavailableException
84
     */
85
    public function getSupportedCurrencies(): array
86
    {
87
        try {
88
            $response = $this->client->request(
89
                static::REQUEST_METHOD,
90
                $this->baseUri,
91
                [
92
                    'query' => [
93
                        'access_key' => $this->token,
94
                    ],
95
                ]
96
            );
97
98
            $responseAsArray = \GuzzleHttp\json_decode($response->getBody(), true);
99
        } catch (GuzzleException $e) {
100
            throw new ServiceUnavailableException('', 504, $e);
101
        }
102
103
        if (empty($responseAsArray['rates'])) {
104
            throw new ServiceUnavailableException(
105
                'We\'re currently experiencing some problems, please try again shortly or contact us.'
106
            );
107
        }
108
109
        return array_keys($responseAsArray['rates']);
110
    }
111
}
112