Passed
Push — master ( 31e5bc...a79a25 )
by Orkhan
01:45
created

CurrencylayerClient::change()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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