1
|
|
|
<?php |
2
|
|
|
namespace CurrencyConverter\Controller\Component; |
3
|
|
|
|
4
|
|
|
use Cake\Controller\Component; |
5
|
|
|
use Cake\Datasource\ConnectionManager; |
6
|
|
|
use Cake\ORM\TableRegistry; |
7
|
|
|
use Cake\I18n\Time; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* CurrencyConverter Component to convert currency. |
11
|
|
|
* |
12
|
|
|
* Convert an amount number from one currency to an other currency |
13
|
|
|
* Return currency rate from one currency to an other |
14
|
|
|
* output type from HTML to JSON format. |
15
|
|
|
*/ |
16
|
|
|
class CurrencyConverterComponent extends Component |
17
|
|
|
{ |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Using database |
21
|
|
|
* |
22
|
|
|
* @var bool |
23
|
|
|
*/ |
24
|
|
|
public $database; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Time interval for refreshing database |
28
|
|
|
* |
29
|
|
|
* @var int |
30
|
|
|
*/ |
31
|
|
|
public $refresh; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Number of decimal to use for formatting converted price |
35
|
|
|
* |
36
|
|
|
* @var int |
37
|
|
|
*/ |
38
|
|
|
public $decimal; |
39
|
8 |
|
|
40
|
|
|
/** |
41
|
|
|
* CurrencyratesTable Class |
42
|
|
|
* @var \Cake\ORM\Table |
43
|
|
|
*/ |
44
|
|
|
private $_currencyratesTable; |
45
|
|
|
|
46
|
|
|
/** |
47
|
8 |
|
* Default CurrencyConverterComponent settings. |
48
|
8 |
|
* |
49
|
8 |
|
* When calling CurrencyConverterComponent() these settings will be merged with the configuration |
50
|
8 |
|
* you provide. |
51
|
8 |
|
* |
52
|
8 |
|
* - `database` - Mention if Component have to store currency rate in database |
53
|
8 |
|
* - `refresh` - Time interval for Component to refresh currency rate in database |
54
|
|
|
* - `decimal` - Number of decimal to use when formatting amount float number |
55
|
8 |
|
* |
56
|
7 |
|
* @var array |
57
|
|
|
*/ |
58
|
7 |
|
protected $_defaultConfig = [ |
59
|
5 |
|
'database' => true, // Mention if Component have to store currency rate in database |
60
|
5 |
|
'refresh' => 24, // Time interval for Component to refresh currency rate in database |
61
|
|
|
'decimal' => 2, // Number of decimal to use when formatting amount float number |
62
|
5 |
|
]; |
63
|
|
|
|
64
|
5 |
|
/** |
65
|
5 |
|
* @param array $config |
66
|
|
|
* @return void |
67
|
5 |
|
*/ |
68
|
|
|
public function initialize(array $config = []) { |
69
|
|
|
|
70
|
2 |
|
$config = $this->getConfig(); |
71
|
|
|
|
72
|
2 |
|
$this->database = $config['database']; |
73
|
|
|
$this->refresh = $config['refresh']; |
74
|
|
|
$this->decimal = $config['decimal']; |
75
|
1 |
|
|
76
|
|
|
$this->_currencyratesTable = TableRegistry::get('CurrencyConverter.Currencyrates'); |
|
|
|
|
77
|
|
|
} |
78
|
7 |
|
|
79
|
|
|
/** |
80
|
7 |
|
* Convert method take an amount as first parameter and convert it using $from currency and $to currency. |
81
|
1 |
|
* |
82
|
1 |
|
* @param float|string $amount the amount to convert. |
83
|
|
|
* @param string $from currency to convert from |
84
|
7 |
|
* @param string $to currency to convert to |
85
|
1 |
|
* @return float $amount converted |
86
|
1 |
|
*/ |
87
|
7 |
|
public function convert($amount, $from, $to) |
88
|
|
|
{ |
89
|
5 |
|
$amount = floatval($amount); |
90
|
|
|
$rate = $this->getRateToUse($from, $to); |
91
|
5 |
|
|
92
|
5 |
|
return $convert = $this->_formatConvert($rate * $amount); |
|
|
|
|
93
|
|
|
} |
94
|
5 |
|
|
95
|
5 |
|
/** |
96
|
|
|
* Rate method return the rate of two currencies |
97
|
5 |
|
* |
98
|
2 |
|
* @param string $from currency to get the rate from |
99
|
|
|
* @param string $to currency to get the rate to |
100
|
2 |
|
* @return float|null $rate |
101
|
2 |
|
*/ |
102
|
2 |
|
public function rate($from, $to) |
103
|
|
|
{ |
104
|
2 |
|
return $this->getRateToUse($from, $to); |
105
|
|
|
} |
106
|
|
|
|
107
|
2 |
|
/** |
108
|
|
|
* getRateToUse return rate to use |
109
|
5 |
|
* Using $from and $to parameters representing currency to deal with and the configuration settings |
110
|
|
|
* This method save or update currencyrates Table if necesseray too. |
111
|
5 |
|
* |
112
|
3 |
|
* @param string $from currency to get the rate from |
113
|
3 |
|
* @param string $to currency to get the rate to |
114
|
5 |
|
* @return float|null $rate |
115
|
|
|
*/ |
116
|
|
|
public function getRateToUse($from, $to) |
117
|
|
|
{ |
118
|
|
|
if ($from == $to) { |
119
|
|
|
return 1; |
120
|
|
|
} else { |
121
|
|
|
if ($this->database) { |
122
|
|
|
// Get a currency rate from table |
123
|
|
|
$result = $this->_currencyratesTable->find('all')->where(['from_currency' => $from, 'to_currency' => $to])->first(); |
124
|
|
|
if ($result) { |
125
|
|
|
// If currency rate is in table and it doesn't have to be updated |
126
|
|
|
if ($result->get('modified')->wasWithinLast($this->refresh . ' hours')) { |
127
|
|
|
return $rate = $result->get('rate'); |
|
|
|
|
128
|
|
|
} else { |
129
|
|
|
$rate = $this->_getRateFromAPI($from, $to); |
|
|
|
|
130
|
|
|
if ($rate) { |
|
|
|
|
131
|
|
|
$result->rate = $rate; |
132
|
3 |
|
$this->_currencyratesTable->save($result); |
133
|
|
|
} |
134
|
3 |
|
return $rate; |
135
|
|
|
} |
136
|
|
|
} |
137
|
3 |
|
// If currency rate isn't in table |
138
|
3 |
|
if (!$result) { |
139
|
3 |
|
$rate = $this->_getRateFromAPI($from, $to); |
|
|
|
|
140
|
3 |
|
if ($rate) { |
|
|
|
|
141
|
3 |
|
$entity = $this->_currencyratesTable->newEntity([ |
142
|
3 |
|
'from_currency' => $from, |
143
|
|
|
'to_currency' => $to, |
144
|
3 |
|
'rate' => $rate |
145
|
3 |
|
]); |
146
|
3 |
|
$this->_currencyratesTable->save($entity); |
147
|
|
|
} |
148
|
2 |
|
return $rate; |
149
|
|
|
} |
150
|
|
|
} |
151
|
2 |
|
} |
152
|
2 |
|
|
153
|
2 |
|
return $this->_getRateFromAPI($from, $to); |
|
|
|
|
154
|
2 |
|
} |
155
|
2 |
|
|
156
|
2 |
|
/** |
157
|
|
|
* Format number using configuration |
158
|
|
|
* |
159
|
5 |
|
* @param float price to format |
|
|
|
|
160
|
|
|
* @return float |
161
|
5 |
|
*/ |
162
|
5 |
|
private function _formatConvert($number) |
163
|
|
|
{ |
164
|
5 |
|
return floatval(number_format($number, $this->decimal)); |
165
|
5 |
|
} |
166
|
5 |
|
|
167
|
5 |
|
/** |
168
|
|
|
* Call free.currencyconverterapi.com API to get a rate for one currency to an other one currency |
169
|
5 |
|
* |
170
|
|
|
* @param string $from the currency |
171
|
|
|
* @param string $to the currency |
172
|
|
|
* @return int|null $rate |
173
|
5 |
|
*/ |
174
|
5 |
|
private function _getRateFromAPI($from, $to) |
175
|
|
|
{ |
176
|
5 |
|
$rate = null; |
177
|
|
|
|
178
|
|
|
$url = 'https://free.currencyconverterapi.com/api/v5/convert?q=' . $from . '_' . $to . '&compact=ultra'; |
179
|
|
|
$request = @fopen($url, 'r'); |
180
|
5 |
|
|
181
|
|
|
if ($request) { |
|
|
|
|
182
|
|
|
$response = fgets($request, 4096); |
183
|
5 |
|
fclose($request); |
184
|
|
|
$response = json_decode($response, true); |
185
|
5 |
|
if (isset($response[$from . '_' . $to])) { |
186
|
|
|
$rate = $response[$from . '_' . $to]; |
187
|
5 |
|
} |
188
|
5 |
|
} |
189
|
|
|
|
190
|
|
|
return $rate; |
191
|
5 |
|
} |
192
|
|
|
} |
193
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.