1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
|
4
|
|
|
/*** |
5
|
|
|
* the sole purpose of this class is to provide an exchange rate |
6
|
|
|
* from currency 1 to currency 2. |
7
|
|
|
* It can provide number that reads as follows: |
8
|
|
|
* |
9
|
|
|
* If I exchange 1 USD I will get EUR 0.8 |
10
|
|
|
* This is the exchange rate. |
11
|
|
|
* |
12
|
|
|
* So, how many do I get of the "to" currency |
13
|
|
|
* when I have one "from" currency. |
14
|
|
|
* |
15
|
|
|
* |
16
|
|
|
* @authors: Nicolaas [at] Sunny Side Up .co.nz |
17
|
|
|
* @package: ecommerce |
18
|
|
|
* @sub-package: money |
19
|
|
|
**/ |
20
|
|
|
|
21
|
|
|
class ExchangeRateProvider extends Object |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* cache of exchange rates. |
25
|
|
|
* |
26
|
|
|
* @var array |
27
|
|
|
*/ |
28
|
|
|
private static $_memory_cache = array(); |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* adds a bit of additional cost to account for the exchange cost. |
32
|
|
|
* |
33
|
|
|
* @var floatval |
34
|
|
|
*/ |
35
|
|
|
protected $exchangeCostMultiplier = 1.05; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Get the exchange rate. |
39
|
|
|
* |
40
|
|
|
* @param string $fromCode e.g. NZD |
41
|
|
|
* @param string $toCode e.g. USD |
42
|
|
|
* |
43
|
|
|
* @return float |
44
|
|
|
* @return float |
45
|
|
|
*/ |
46
|
|
|
public function ExchangeRate($fromCode, $toCode) |
47
|
|
|
{ |
48
|
|
|
$fromCode = strtoupper($fromCode); |
49
|
|
|
$toCode = strtoupper($toCode); |
50
|
|
|
$cacheCode = $fromCode.'_'.$toCode; |
51
|
|
|
if (isset(self::$_memory_cache[$cacheCode])) { |
52
|
|
|
return self::$_memory_cache[$cacheCode]; |
53
|
|
|
} else { |
54
|
|
|
if ($value = Session::get($cacheCode)) { |
55
|
|
|
self::$_memory_cache[$cacheCode] = $value; |
56
|
|
|
} else { |
57
|
|
|
$value = $this->getRate($fromCode, $toCode); |
58
|
|
|
self::$_memory_cache[$cacheCode] = $value; |
59
|
|
|
Session::set($cacheCode, $value); |
60
|
|
|
} |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
return self::$_memory_cache[$cacheCode]; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* gets a rate from a FROM and a TO currency. |
68
|
|
|
* see https://free.currencyconverterapi.com/ for limitations |
69
|
|
|
* |
70
|
|
|
* @param string $fromCode - UPPERCASE Code, e.g. NZD |
71
|
|
|
* @param string $toCode - UPPERCASE Code, e.g. EUR |
72
|
|
|
* |
73
|
|
|
* @return float - returns exchange rate |
74
|
|
|
*/ |
75
|
|
|
protected function getRate($fromCode, $toCode) |
76
|
|
|
{ |
77
|
|
|
$rate = 0; |
78
|
|
|
$reference = $fromCode.'_'.$toCode; |
79
|
|
|
$url = 'http://free.currencyconverterapi.com/api/v5/convert?q='.$reference.'&compact=y'; |
80
|
|
|
if (($ch = @curl_init())) { |
81
|
|
|
$timeout = 5; // set to zero for no timeout |
82
|
|
|
curl_setopt($ch, CURLOPT_URL, "$url"); |
83
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
84
|
|
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); |
85
|
|
|
$record = curl_exec($ch); |
86
|
|
|
curl_close($ch); |
87
|
|
|
} |
88
|
|
|
if (!$record) { |
|
|
|
|
89
|
|
|
$record = file_get_contents($url); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
if ($record) { |
93
|
|
|
$currencyData = json_decode($record); |
94
|
|
|
$rate = $currencyData->$reference->val; |
95
|
|
|
if (!$rate) { |
96
|
|
|
user_error('There was a problem retrieving the exchange rate.'); |
97
|
|
|
} |
98
|
|
|
} |
99
|
|
|
if ($rate != 1) { |
100
|
|
|
$rate = $rate * $this->exchangeCostMultiplier; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
return $rate; |
104
|
|
|
} |
105
|
|
|
} |
106
|
|
|
|
If you define a variable conditionally, it can happen that it is not defined for all execution paths.
Let’s take a look at an example:
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.
Available Fixes
Check for existence of the variable explicitly:
Define a default value for the variable:
Add a value for the missing path: