Test Failed
Pull Request — master (#10)
by Alessandro
10:52
created

CurrencyConverterComponent::getRates()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4.0466

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 23
ccs 12
cts 14
cp 0.8571
rs 8.7972
cc 4
eloc 13
nc 6
nop 0
crap 4.0466
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', [
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

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.

Loading history...
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