Passed
Push — master ( 54ce74...0c8925 )
by Alessandro
01:09
created

CurrencyConverterComponent::ensureIfExistTable()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4.1054

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 13
cts 16
cp 0.8125
rs 9.456
c 0
b 0
f 0
cc 4
nc 4
nop 0
crap 4.1054
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 8
    public function convert(
40
        $fromCurrency, 
41
        $toCurrency, 
42
        $amount, 
43
        $saveIntoDb = true, 
44
        $hourDifference = 1, 
45
        $dataSource = 'default'
46
    ) {
47 8
        $this->fromCurrency = $fromCurrency;
48 8
        $this->toCurrency = $toCurrency;
49 8
        $this->amount = $amount;
50 8
        $this->saveIntoDb = (bool)$saveIntoDb;
51 8
        $this->hourDifference = $hourDifference;
52 8
        $this->dataSource = $dataSource;
53 8
        $this->rate = 0;
54
55 8
        if ($this->fromCurrency != $this->toCurrency) {
56 7
            $this->fixFromToCurrency();
57
            
58 7
            if ($this->saveIntoDb === true) {
59 5
                $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 5
                    'className' => 'CurrencyConverter\Model\Table\CurrencyConvertersTable',
61
                    'table' => 'currency_converter'
62 5
                ]);
63
64 5
                $this->ensureIfExistTable();
65 5
                $this->saveIntoDatabase();
66
67 5
                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 7
    private function fixFromToCurrency()
79
    {
80 7
        if ($this->fromCurrency == "PDS"){
81 1
            $this->fromCurrency = "GBP";
82 1
        }
83
84 7
        if ($this->toCurrency == "PDS"){
85 1
            $this->toCurrency = "GBP";
86 1
        }
87 7
    }
88
89 5
    private function saveIntoDatabase()
90
    {
91 5
        $query = $this->currencyTable->find('all')
92 5
            ->where(['fromCurrency' => $this->fromCurrency, 'toCurrency' => $this->toCurrency ]);
93
94 5
        $query->enableHydration(false);
95 5
        $result =  $query->toArray();
96
97 5
        foreach ($result as $row){
98 2
            $lastUpdated = $row['modified'];
99
100 2
            $now = date('Y-m-d H:i:s');
101 2
            $dStart = new \DateTime($now);
102 2
            $diff = $dStart->diff($lastUpdated);
103
104 2
            if ($this->ensureNeedToUpdateDatabase($diff, $row)) {
105
                $this->updateDatabase($row);
106
            } else {
107 2
                $this->rate = $row['rates'];
108
            }
109 5
        }
110
111 5
        if (count($result) <= 0) {
112 3
            $this->insertIntoDatabase();
113 3
        }
114 5
    }
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 3
    private function insertIntoDatabase()
133
    {
134 3
        $this->rate = $this->getRates();
135
136
        $data = [
137 3
            'fromCurrency' => $this->fromCurrency,
138 3
            'toCurrency'   => $this->toCurrency,
139 3
            'rates'        => $this->rate,
140 3
            'created'      => date('Y-m-d H:i:s'),
141 3
            'modified'     => date('Y-m-d H:i:s'),
142 3
        ];
143
144 3
        $entity = $this->currencyTable->newEntity($data);
145 3
        $this->currencyTable->save($entity);
146 3
    }
147
148 2
    private function ensureNeedToUpdateDatabase($diff, $row)
149
    {
150
        return (
151 2
            ((int)$diff->y >= 1) || 
152 2
            ((int)$diff->m >= 1) || 
153 2
            ((int)$diff->d >= 1) || 
154 2
            ((int)$diff->h >= $this->hourDifference) || 
155 2
            ((double)$row['rates'] == 0)
156 2
        );
157
    }
158
159 5
    private function getRates()
160
    {
161 5
        $url = 'https://free.currencyconverterapi.com/api/v5/convert?q=' . $this->fromCurrency . '_' . $this->toCurrency . '&compact=ultra' ;
162 5
        $handle = @fopen($url, 'r');
163
164 5
        if ($handle) {
165 5
            $result = fgets($handle, 4096);
166 5
            fclose($handle);
167 5
        }
168
169 5
        if (!isset($result)) {
170
            return $this->rate = 0;
171
        }
172
173 5
        $conversion = json_decode($result, true);
174 5
        $key = $this->fromCurrency . '_' . $this->toCurrency;
175
176 5
        if (!isset($conversion[$key])) {
177
            return $this->rate = 0;
178
        }
179
180 5
        return $conversion[$this->fromCurrency . '_' . $this->toCurrency];
181
    }
182
183 5
    private function ensureIfExistTable()
184
    {
185 5
        $autoIncrement = 'AUTO_INCREMENT';
186
187 5
        $db = ConnectionManager::get($this->dataSource);
188 5
        $config = $db->config();
189
190
191 5
        if (!isset($config['dsn'])) {
192 5
            if (strpos(strtolower($config['driver']), 'sqlite') !== false) {
193 5
                $autoIncrement = 'AUTOINCREMENT';
194 5
            }
195 5
        } else {
196
            if (strpos($config['dsn'], 'sqlite') !== false) {
197
                $autoIncrement = 'AUTOINCREMENT';
198
            }
199
        }
200
201 5
        $sql = 'CREATE TABLE IF NOT EXISTS `currency_converters` (
202 5
          `id` integer PRIMARY KEY ' . $autoIncrement . ',
203
          `fromCurrency` varchar(5) NOT NULL,
204
          `toCurrency` varchar(5) NOT NULL,
205
          `rates` varchar(10) NOT NULL,
206
          `created` datetime NOT NULL,
207
          `modified` datetime NOT NULL
208 5
        );';
209
210 5
        return $db->query($sql);
211
    }
212
213 7
    private function calculateValue()
214
    {
215 7
        $value = (double)$this->rate * (double)$this->amount;
216 7
        return number_format((double)$value, 2, '.', '');
217
    }
218
}
219