CurrencylayerClient::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 7
rs 10
1
<?php
2
3
namespace Orkhanahmadov\Currencylayer;
4
5
use GuzzleHttp\Client as Guzzle;
6
use Orkhanahmadov\Currencylayer\Data\Change;
7
use Orkhanahmadov\Currencylayer\Data\Conversion;
8
use Orkhanahmadov\Currencylayer\Data\Quotes;
9
use Orkhanahmadov\Currencylayer\Data\Timeframe;
10
11
class CurrencylayerClient implements Client
12
{
13
    /**
14
     * @var Guzzle
15
     */
16
    private $client;
17
    /**
18
     * @var string
19
     */
20
    private $accessKey;
21
    /**
22
     * @var string
23
     */
24
    private $source = 'USD';
25
    /**
26
     * @var string
27
     */
28
    private $currencies;
29
    /**
30
     * @var \DateTimeInterface|null
31
     */
32
    private $date = null;
33
34
    /**
35
     * CurrencylayerClient constructor.
36
     *
37
     * @param string $accessKey
38
     * @param bool   $useHttps
39
     */
40
    public function __construct(string $accessKey, bool $useHttps = false)
41
    {
42
        $this->client = new Guzzle([
43
            'base_uri' => $useHttps ? 'https://apilayer.net/api/' : 'http://apilayer.net/api/',
44
        ]);
45
46
        $this->accessKey = $accessKey;
47
    }
48
49
    /**
50
     * @param string $source
51
     *
52
     * @return $this
53
     */
54
    public function source(string $source): Client
55
    {
56
        $this->source = $source;
57
58
        return $this;
59
    }
60
61
    /**
62
     * @param array<string>|string $currency
63
     *
64
     * @return $this
65
     */
66
    public function currency($currency): Client
67
    {
68
        if (is_array($currency)) {
69
            $this->currencies = implode(',', $currency);
70
        } else {
71
            $this->currencies = implode(',', func_get_args());
72
        }
73
74
        return $this;
75
    }
76
77
    /**
78
     * @param \DateTimeInterface|string $date
79
     *
80
     * @throws \Exception
81
     *
82
     * @return $this
83
     */
84
    public function date($date): Client
85
    {
86
        $this->date = $date instanceof \DateTimeInterface ?
87
            $date :
88
            new \DateTimeImmutable($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
     * @param \DateTimeInterface|string $startDate
142
     * @param \DateTimeInterface|string $endDate
143
     *
144
     * @throws \Exception
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 \DateTimeInterface ?
154
                $startDate->format('Y-m-d') :
155
                $startDate,
156
            'end_date'   => $endDate instanceof \DateTimeInterface ?
157
                $endDate->format('Y-m-d') :
158
                $endDate,
159
        ]);
160
161
        return new Timeframe($data);
162
    }
163
164
    /**
165
     * @param \DateTimeInterface|string $startDate
166
     * @param \DateTimeInterface|string $endDate
167
     *
168
     * @throws \Exception
169
     *
170
     * @return Change
171
     */
172
    public function change($startDate, $endDate): Change
173
    {
174
        $data = $this->request('change', [
175
            'source'     => $this->source,
176
            'currencies' => $this->currencies,
177
            'start_date' => $startDate instanceof \DateTimeInterface ?
178
                $startDate->format('Y-m-d') :
179
                $startDate,
180
            'end_date'   => $endDate instanceof \DateTimeInterface ?
181
                $endDate->format('Y-m-d') :
182
                $endDate,
183
        ]);
184
185
        return new Change($data);
186
    }
187
188
    /**
189
     * @return array
190
     */
191
    public function list(): array
192
    {
193
        $data = $this->request('list', []);
194
195
        return $data['currencies'];
196
    }
197
198
    /**
199
     * @param string $endpoint
200
     * @param array  $query
201
     *
202
     * @return array
203
     */
204
    private function request(string $endpoint, array $query): array
205
    {
206
        $response = $this->client->get($endpoint, [
207
            'query' => array_merge($query, ['access_key' => $this->accessKey]),
208
        ]);
209
210
        $data = \GuzzleHttp\json_decode($response->getBody()->getContents(), true);
211
212
        if (!$data['success']) {
213
            throw new \InvalidArgumentException($data['error']['info']);
214
        }
215
216
        return $data;
217
    }
218
}
219