Passed
Push — master ( f13640...7cdd07 )
by Orkhan
01:28
created

CurrencylayerClient::startDate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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