Passed
Push — master ( 96eedf...95a867 )
by Orkhan
01:50
created

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