1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace CurrencyConverter\Controller\Component; |
4
|
|
|
|
5
|
|
|
use Cake\Controller\Component; |
6
|
|
|
use Cake\Datasource\ConnectionManager; |
7
|
|
|
use Cake\ORM\TableRegistry; |
8
|
|
|
use Cake\Database\Schema\TableSchema; |
9
|
|
|
|
10
|
|
|
class CurrencyConverterComponent extends Component |
11
|
|
|
{ |
12
|
|
|
private $fromCurrency; |
13
|
|
|
|
14
|
|
|
private $toCurrency; |
15
|
|
|
|
16
|
|
|
private $amount; |
17
|
|
|
|
18
|
|
|
private $hourDifference; |
19
|
|
|
|
20
|
|
|
private $saveIntoDb; |
21
|
|
|
|
22
|
|
|
private $dataSource; |
23
|
|
|
|
24
|
|
|
private $rate; |
25
|
|
|
|
26
|
|
|
private $currencyTable; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Convertion function |
30
|
|
|
* |
31
|
|
|
* @param string $fromCurrency the starting currency that user wants to convert to. |
32
|
|
|
* @param string $toCurrency the ending currency that user wants to convert to. |
33
|
|
|
* @param float $amount the amount to convert. |
34
|
|
|
* @param boolean $saveIntoDb if develop wants to store convertion rate for use it without resending data to yahoo service. |
35
|
|
|
* @param int $hourDifference the hour difference to check if the last convertion is passed, if yes make a new call to yahoo finance api. |
36
|
|
|
* @param string $dataSource which dataSOurce need to use |
37
|
|
|
* @return float the total amount converted into the new currency |
38
|
|
|
*/ |
39
|
7 |
|
public function convert( |
40
|
|
|
$fromCurrency, |
41
|
|
|
$toCurrency, |
42
|
|
|
$amount, |
43
|
|
|
$saveIntoDb = true, |
44
|
|
|
$hourDifference = 1, |
45
|
|
|
$dataSource = 'default' |
46
|
|
|
) { |
47
|
7 |
|
$this->fromCurrency = $fromCurrency; |
48
|
7 |
|
$this->toCurrency = $toCurrency; |
49
|
7 |
|
$this->amount = $amount; |
50
|
7 |
|
$this->saveIntoDb = (bool)$saveIntoDb; |
51
|
7 |
|
$this->hourDifference = $hourDifference; |
52
|
7 |
|
$this->dataSource = $dataSource; |
53
|
7 |
|
$this->rate = 0; |
54
|
|
|
|
55
|
7 |
|
if ($this->fromCurrency != $this->toCurrency) { |
56
|
6 |
|
$this->fixFromToCurrency(); |
57
|
|
|
|
58
|
6 |
|
if ($this->saveIntoDb === true) { |
59
|
4 |
|
$this->currencyTable = TableRegistry::get('CurrencyConverter', [ |
|
|
|
|
60
|
4 |
|
'className' => 'CurrencyConverter\Model\Table\CurrencyConvertersTable', |
61
|
|
|
'table' => 'currency_converter' |
62
|
4 |
|
]); |
63
|
|
|
|
64
|
|
|
$this->ensureIfExistTable(); |
65
|
|
|
$this->saveIntoDatabase(); |
66
|
|
|
|
67
|
|
|
return $this->calculateValue(); |
68
|
|
|
} |
69
|
|
|
|
70
|
2 |
|
$this->rate = $this->getRates(); |
71
|
|
|
|
72
|
2 |
|
return $this->calculateValue(); |
73
|
|
|
} |
74
|
|
|
|
75
|
1 |
|
return number_format((double)$this->amount, 2, '.', ''); |
76
|
|
|
} |
77
|
|
|
|
78
|
6 |
|
private function fixFromToCurrency() |
79
|
|
|
{ |
80
|
6 |
|
if ($this->fromCurrency == "PDS"){ |
81
|
1 |
|
$this->fromCurrency = "GBP"; |
82
|
1 |
|
} |
83
|
|
|
|
84
|
6 |
|
if ($this->toCurrency == "PDS"){ |
85
|
1 |
|
$this->toCurrency = "GBP"; |
86
|
1 |
|
} |
87
|
6 |
|
} |
88
|
|
|
|
89
|
|
|
private function saveIntoDatabase() |
90
|
|
|
{ |
91
|
|
|
$query = $this->currencyTable->find('all') |
92
|
|
|
->where(['fromCurrency' => $this->fromCurrency, 'toCurrency' => $this->toCurrency ]); |
93
|
|
|
|
94
|
|
|
$query->enableHydration(false); |
95
|
|
|
$result = $query->toArray(); |
96
|
|
|
|
97
|
|
|
foreach ($result as $row){ |
98
|
|
|
$lastUpdated = $row['modified']; |
99
|
|
|
|
100
|
|
|
$now = date('Y-m-d H:i:s'); |
101
|
|
|
$dStart = new \DateTime($now); |
102
|
|
|
$diff = $dStart->diff($lastUpdated); |
103
|
|
|
|
104
|
|
|
if ($this->ensureNeedToUpdateDatabase($diff, $row)) { |
105
|
|
|
$this->updateDatabase($row); |
106
|
|
|
} else { |
107
|
|
|
$this->rate = $row['rates']; |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
if (count($result) <= 0) { |
112
|
|
|
$this->insertIntoDatabase(); |
113
|
|
|
} |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
private function updateDatabase($row) |
117
|
|
|
{ |
118
|
|
|
$this->rate = $this->getRates(); |
119
|
|
|
|
120
|
|
|
$data = [ |
121
|
|
|
'fromCurrency'=> $this->fromCurrency, |
122
|
|
|
'toCurrency' => $this->toCurrency, |
123
|
|
|
'rates' => $this->rate, |
124
|
|
|
'modified' => date('Y-m-d H:i:s'), |
125
|
|
|
]; |
126
|
|
|
|
127
|
|
|
$entity = $this->currencyTable->get($row['id']); |
128
|
|
|
$this->currencyTable->patchEntity($entity, $data); |
129
|
|
|
$this->currencyTable->save($entity); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
private function insertIntoDatabase() |
133
|
|
|
{ |
134
|
|
|
$this->rate = $this->getRates(); |
135
|
|
|
|
136
|
|
|
$data = [ |
137
|
|
|
'fromCurrency' => $this->fromCurrency, |
138
|
|
|
'toCurrency' => $this->toCurrency, |
139
|
|
|
'rates' => $this->rate, |
140
|
|
|
'created' => date('Y-m-d H:i:s'), |
141
|
|
|
'modified' => date('Y-m-d H:i:s'), |
142
|
|
|
]; |
143
|
|
|
|
144
|
|
|
$entity = $this->currencyTable->newEntity($data); |
145
|
|
|
$this->currencyTable->save($entity); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
private function ensureNeedToUpdateDatabase($diff, $row) |
149
|
|
|
{ |
150
|
|
|
return ( |
151
|
|
|
((int)$diff->y >= 1) || |
152
|
|
|
((int)$diff->m >= 1) || |
153
|
|
|
((int)$diff->d >= 1) || |
154
|
|
|
((int)$diff->h >= $this->hourDifference) || |
155
|
|
|
((double)$row['rates'] == 0) |
156
|
|
|
); |
157
|
|
|
} |
158
|
|
|
|
159
|
2 |
|
private function getRates() |
160
|
|
|
{ |
161
|
2 |
|
$url = 'https://free.currencyconverterapi.com/api/v5/convert?q=' . $this->fromCurrency . '_' . $this->toCurrency . '&compact=ultra' ; |
162
|
2 |
|
$handle = @fopen($url, 'r'); |
163
|
|
|
|
164
|
2 |
|
if ($handle) { |
165
|
2 |
|
$result = fgets($handle, 4096); |
166
|
2 |
|
fclose($handle); |
167
|
2 |
|
} |
168
|
|
|
|
169
|
2 |
|
if (!isset($result)) { |
170
|
|
|
return $this->rate = 0; |
171
|
|
|
} |
172
|
|
|
|
173
|
2 |
|
$conversion = json_decode($result, true); |
174
|
2 |
|
$key = $this->fromCurrency . '_' . $this->toCurrency; |
175
|
|
|
|
176
|
2 |
|
if (!isset($conversion[$key])) { |
177
|
|
|
return $this->rate = 0; |
178
|
|
|
} |
179
|
|
|
|
180
|
2 |
|
return $conversion[$this->fromCurrency . '_' . $this->toCurrency]; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
private function ensureIfExistTable() |
184
|
|
|
{ |
185
|
|
|
$autoIncrement = 'AUTO_INCREMENT'; |
186
|
|
|
|
187
|
|
|
$db = ConnectionManager::get($this->dataSource); |
188
|
|
|
$config = $db->config(); |
189
|
|
|
|
190
|
|
|
if (strpos($config['dsn'], 'sqlite') !== false) { |
191
|
|
|
$autoIncrement = 'AUTOINCREMENT'; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
$sql = 'CREATE TABLE IF NOT EXISTS `currency_converters` ( |
195
|
|
|
`id` integer PRIMARY KEY ' . $autoIncrement . ', |
196
|
|
|
`fromCurrency` varchar(5) NOT NULL, |
197
|
|
|
`toCurrency` varchar(5) NOT NULL, |
198
|
|
|
`rates` varchar(10) NOT NULL, |
199
|
|
|
`created` datetime NOT NULL, |
200
|
|
|
`modified` datetime NOT NULL |
201
|
|
|
);'; |
202
|
|
|
|
203
|
|
|
return $db->query($sql); |
204
|
|
|
} |
205
|
|
|
|
206
|
2 |
|
private function calculateValue() |
207
|
|
|
{ |
208
|
2 |
|
$value = (double)$this->rate * (double)$this->amount; |
209
|
2 |
|
return number_format((double)$value, 2, '.', ''); |
210
|
|
|
} |
211
|
|
|
} |
212
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.