Completed
Push — master ( eabfbb...93a568 )
by Milan
01:38
created

Exchange::setDriver()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.2
c 0
b 0
f 0
cc 4
eloc 9
nc 8
nop 2
1
<?php
2
3
namespace h4kuna\Exchange;
4
5
use DateTime;
6
7
/**
8
 * @author Milan Matějček
9
 * @since 2009-06-22 - version 0.5
10
 */
11
class Exchange implements \ArrayAccess, \IteratorAggregate
12
{
13
14
	/** @var Caching\ICache */
15
	private $cache;
16
17
	/** @var Currency\ListRates */
18
	private $listRates;
19
20
	/**
21
	 * Default currency "from" input
22
	 * @var Currency\Property
23
	 */
24
	private $default;
25
26
	/**
27
	 * Display currency "to" output
28
	 * @var Currency\Property
29
	 */
30
	private $output;
31
32
	/** @var Currency\Property[] */
33
	private $tempRates;
34
35
	public function __construct(Caching\ICache $cache)
36
	{
37
		$this->cache = $cache;
38
	}
39
40
	/** @return Currency\Property */
41
	public function getDefault()
42
	{
43
		if ($this->default === NULL) {
44
			$this->default = $this->getListRates()->getFirst();
45
		}
46
		return $this->default;
47
	}
48
49
	/** @return Currency\Property */
50
	public function getOutput()
51
	{
52
		if ($this->output === NULL) {
53
			$this->output = $this->getDefault();
54
		}
55
		return $this->output;
56
	}
57
58
	/**
59
	 * Set default "from" currency.
60
	 * @param string $code
61
	 */
62
	public function setDefault($code)
63
	{
64
		$this->default = $this->offsetGet($code);
65
	}
66
67
	/**
68
	 * @param Driver\ADriver|NULL $driver
69
	 * @param DateTime|NULL $date
70
	 * @return static
71
	 */
72
	public function setDriver(Driver\ADriver $driver = NULL, DateTime $date = NULL)
73
	{
74
		if ($driver === NULL) {
75
			$driver = new Driver\Cnb\Day();
76
		}
77
		$this->listRates = $this->cache->loadListRate($driver, $date);
78
		if ($this->default) {
79
			$this->setDefault($this->default->code);
80
		}
81
		if ($this->output) {
82
			$this->setOutput($this->output->code);
83
		}
84
		return $this;
85
	}
86
87
	/**
88
	 * Set currency "to".
89
	 * @param string $code
90
	 * @return Currency\Property
91
	 */
92
	public function setOutput($code)
93
	{
94
		return $this->output = $this->offsetGet($code);
95
	}
96
97
	/**
98
	 * Transfer number by exchange rate.
99
	 * @param float|int|string $price number
100
	 * @param string|NULL
101
	 * @param string $to
102
	 * @return float|int
103
	 */
104
	public function change($price, $from = NULL, $to = NULL)
105
	{
106
		return $this->transfer($price, $from, $to)[0];
107
	}
108
109
	/**
110
	 * @param int|float $price
111
	 * @param string $from
112
	 * @param string $to
113
	 * @return array
114
	 */
115
	public function transfer($price, $from, $to)
116
	{
117
		$to = $to === NULL ? $this->getOutput() : $this->offsetGet($to);
118
		if (((float) $price) === 0.0) {
119
			return [0, $to];
120
		}
121
122
		$from = $from === NULL ? $this->getDefault() : $this->offsetGet($from);
123
124
		if ($to !== $from) {
125
			$toRate = isset($this->tempRates[$to->code]) ? $this->tempRates[$to->code] : $to->rate;
126
			$fromRate = isset($this->tempRates[$from->code]) ? $this->tempRates[$from->code] : $from->rate;
127
			$price *= $fromRate / $toRate;
128
		}
129
130
		return [$price, $to];
131
	}
132
133
	/**
134
	 * Add history rate for rating
135
	 * @param string $code
136
	 * @param float $rate
137
	 * @return self
138
	 */
139
	public function addRate($code, $rate)
140
	{
141
		$property = $this->offsetGet($code);
142
		$this->tempRates[$property->code] = $rate;
143
		return $this;
144
	}
145
146
	/**
147
	 * Remove history rating
148
	 * @param string $code
149
	 * @return self
150
	 */
151
	public function removeRate($code)
152
	{
153
		$property = $this->offsetGet($code);
154
		unset($this->tempRates[$property->code]);
155
		return $this;
156
	}
157
158
	/**
159
	 * Load currency property.
160
	 * @param string|Currency\Property $index
161
	 * @return Currency\Property
162
	 */
163
	public function offsetGet($index)
164
	{
165
		$index = strtoupper($index);
166
		if ($this->getListRates()->offsetExists($index)) {
167
			return $this->getListRates()->offsetGet($index);
168
		}
169
		throw new UnknownCurrencyException('Undefined currency code: "' . $index . '".');
170
	}
171
172
	public function offsetExists($offset)
173
	{
174
		return $this->getListRates()->offsetExists(strtoupper($offset));
175
	}
176
177
	public function offsetSet($offset, $value)
178
	{
179
		return $this->getListRates()->offsetSet($offset, $value);
180
	}
181
182
	public function offsetUnset($offset)
183
	{
184
		return $this->getListRates()->offsetUnset($offset);
185
	}
186
187
	public function getIterator()
188
	{
189
		return $this->getListRates();
190
	}
191
192
	/**
193
	 * @return Currency\ListRates
194
	 */
195
	protected function getListRates()
196
	{
197
		if ($this->listRates === NULL) {
198
			$this->setDriver();
199
		}
200
		return $this->listRates;
201
	}
202
203
}
204