Passed
Push — master ( 848875...e54d4a )
by Alessandro
51s queued 10s
created

ensureNeedToUpdateDatabase()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
ccs 7
cts 7
cp 1
rs 8.8571
cc 5
eloc 7
nc 5
nop 2
crap 5
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 5
        if (strpos($config['dsn'], 'sqlite') !== false) {
191 5
            $autoIncrement = 'AUTOINCREMENT';
192 5
        }
193
194
        $sql = 'CREATE TABLE IF NOT EXISTS `currency_converters` (
195 5
          `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 5
        );';
202
203 5
        return $db->query($sql);
204
    }
205
206 7
    private function calculateValue()
207
    {
208 7
        $value = (double)$this->rate * (double)$this->amount;
209 7
        return number_format((double)$value, 2, '.', '');
210
    }
211
}
212