Passed
Push — master ( 3b0aef...c252a4 )
by Orkhan
01:34
created

CurrencylayerClient::list()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Orkhanahmadov\Currencylayer;
4
5
use Carbon\CarbonImmutable;
6
use GuzzleHttp\Client as Guzzle;
7
use Orkhanahmadov\Currencylayer\Data\Change;
8
use Orkhanahmadov\Currencylayer\Data\Conversion;
9
use Orkhanahmadov\Currencylayer\Data\Quotes;
10
use Orkhanahmadov\Currencylayer\Data\Timeframe;
11
12
class CurrencylayerClient implements Client
13
{
14
    /**
15
     * @var Guzzle
16
     */
17
    private $client;
18
    /**
19
     * @var string
20
     */
21
    private $accessKey;
22
    /**
23
     * @var string
24
     */
25
    private $source = 'USD';
26
    /**
27
     * @var string
28
     */
29
    private $currencies;
30
    /**
31
     * @var \DateTimeInterface|null
32
     */
33
    private $date = null;
34
35
    /**
36
     * CurrencylayerClient constructor.
37
     *
38
     * @param string $accessKey
39
     * @param bool   $useHttps
40
     */
41
    public function __construct(string $accessKey, bool $useHttps = false)
42
    {
43
        $this->client = new Guzzle([
44
            'base_uri' => $useHttps ? 'https://apilayer.net/api/' : 'http://apilayer.net/api/',
45
        ]);
46
47
        $this->accessKey = $accessKey;
48
    }
49
50
    /**
51
     * @param string $source
52
     *
53
     * @return $this
54
     */
55
    public function source(string $source): Client
56
    {
57
        $this->source = $source;
58
59
        return $this;
60
    }
61
62
    /**
63
     * @param array<string>|string $currency
64
     *
65
     * @return $this
66
     */
67
    public function currency($currency): Client
68
    {
69
        if (is_array($currency)) {
70
            $this->currencies = implode(',', $currency);
71
        } else {
72
            $this->currencies = implode(',', func_get_args());
73
        }
74
75
        return $this;
76
    }
77
78
    /**
79
     * @param \DateTimeInterface|string $date
80
     *
81
     * @throws \Exception
82
     *
83
     * @return $this
84
     */
85
    public function date($date): Client
86
    {
87
        $this->date = $date instanceof \DateTimeInterface ? $date : new CarbonImmutable($date);
88
89
        return $this;
90
    }
91
92
    /**
93
     * @throws \Exception
94
     *
95
     * @return Quotes
96
     */
97
    public function quotes(): Quotes
98
    {
99
        $query = [
100
            'currencies' => $this->currencies,
101
            'source'     => $this->source,
102
        ];
103
104
        if ($this->date) {
105
            $query['date'] = $this->date->format('Y-m-d');
106
107
            return new Quotes($this->request('historical', $query));
108
        }
109
110
        return new Quotes($this->request('live', $query));
111
    }
112
113
    /**
114
     * @param int|float $amount
115
     *
116
     * @throws \Exception
117
     *
118
     * @return Conversion
119
     */
120
    public function convert($amount): Conversion
121
    {
122
        if (!$this->source || !$this->currencies) {
123
            throw new \InvalidArgumentException('Conversion "from" and "to" currencies were not set.');
124
        }
125
126
        $query = [
127
            'from'   => $this->source,
128
            'to'     => $this->currencies,
129
            'amount' => $amount,
130
        ];
131
132
        if ($this->date) {
133
            $query['date'] = $this->date->format('Y-m-d');
134
        }
135
136
        return new Conversion($this->request('convert', $query));
137
    }
138
139
    /**
140
     * @param \DateTimeInterface|string $startDate
141
     * @param \DateTimeInterface|string $endDate
142
     *
143
     * @throws \Exception
144
     *
145
     * @return Timeframe
146
     */
147
    public function timeframe($startDate, $endDate): Timeframe
148
    {
149
        $data = $this->request('timeframe', [
150
            'source'     => $this->source,
151
            'currencies' => $this->currencies,
152
            'start_date' => $startDate instanceof \DateTimeInterface ? $startDate->format('Y-m-d') : $startDate,
153
            'end_date'   => $endDate instanceof \DateTimeInterface ? $endDate->format('Y-m-d') : $endDate,
154
        ]);
155
156
        return new Timeframe($data);
157
    }
158
159
    /**
160
     * @param \DateTimeInterface|string $startDate
161
     * @param \DateTimeInterface|string $endDate
162
     *
163
     * @throws \Exception
164
     *
165
     * @return Change
166
     */
167
    public function change($startDate, $endDate): Change
168
    {
169
        $data = $this->request('change', [
170
            'source'     => $this->source,
171
            'currencies' => $this->currencies,
172
            'start_date' => $startDate instanceof \DateTimeInterface ? $startDate->format('Y-m-d') : $startDate,
173
            'end_date'   => $endDate instanceof \DateTimeInterface ? $endDate->format('Y-m-d') : $endDate,
174
        ]);
175
176
        return new Change($data);
177
    }
178
179
    /**
180
     * @return array
181
     */
182
    public function list(): array
183
    {
184
        $data = $this->request('list', []);
185
186
        return $data['currencies'];
187
    }
188
189
    /**
190
     * @param string $endpoint
191
     * @param array  $query
192
     *
193
     * @return array
194
     */
195
    private function request(string $endpoint, array $query): array
196
    {
197
        $response = $this->client->get($endpoint, [
198
            'query' => array_merge($query, ['access_key' => $this->accessKey]),
199
        ]);
200
201
        $data = \GuzzleHttp\json_decode($response->getBody()->getContents(), true);
202
203
        if (!$data['success']) {
204
            throw new \InvalidArgumentException($data['error']['info']);
205
        }
206
207
        return $data;
208
    }
209
210
    /**
211
     * @param Guzzle $client
212
     */
213
    public function setClient(Guzzle $client): void
214
    {
215
        $this->client = $client;
216
    }
217
}
218