Passed
Pull Request — master (#14)
by
unknown
02:33
created

CurrencyConverterComponent::getRateToUse()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 38
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 12.8474

Importance

Changes 0
Metric Value
cc 8
eloc 24
nc 8
nop 2
dl 0
loc 38
ccs 15
cts 26
cp 0.5769
crap 12.8474
rs 8.4444
c 0
b 0
f 0
1
<?php
2
namespace CurrencyConverter\Controller\Component;
3
4
use Cake\Controller\Component;
5
use Cake\Datasource\ConnectionManager;
6
use Cake\ORM\TableRegistry;
7
use Cake\I18n\Time;
8
9
/**
10
 * CurrencyConverter Component to convert currency.
11
 *
12
 * Convert an amount number from one currency to an other currency
13
 * Return currency rate from one currency to an other
14
 * output type from HTML to JSON format.
15
 */
16
class CurrencyConverterComponent extends Component
17
{
18
    
19
    /**
20
     * Using database
21
     *
22
     * @var bool
23
     */
24
    public $database;
25
26
    /**
27
     * Time interval for refreshing database
28
     *
29
     * @var int
30
     */
31
    public $refresh;
32
33
    /**
34
     * Number of decimal to use for formatting converted price
35
     *
36
     * @var int
37
     */
38
    public $decimal;
39 8
40
    /**
41
     * CurrencyratesTable Class
42
     * @var \Cake\ORM\Table
43
     */
44
    private $_currencyratesTable;
45
46
    /**
47 8
     * Default CurrencyConverterComponent settings.
48 8
     *
49 8
     * When calling CurrencyConverterComponent() these settings will be merged with the configuration
50 8
     * you provide.
51 8
     *
52 8
     * - `database` - Mention if Component have to store currency rate in database
53 8
     * - `refresh` - Time interval for Component to refresh currency rate in database
54
     * - `decimal` - Number of decimal to use when formatting amount float number
55 8
     *
56 7
     * @var array
57
     */
58 7
    protected $_defaultConfig = [
59 5
        'database' => true, // Mention if Component have to store currency rate in database
60 5
        'refresh' => 24, // Time interval for Component to refresh currency rate in database
61
        'decimal' => 2, // Number of decimal to use when formatting amount float number
62 5
    ];
63
64 5
    /**
65 5
     * @param array $config
66
     * @return void
67 5
     */
68
    public function initialize(array $config = []) {
69
70 2
        $config = $this->getConfig();
71
72 2
        $this->database = $config['database'];
73
        $this->refresh = $config['refresh'];
74
        $this->decimal = $config['decimal'];
75 1
76
        $this->_currencyratesTable = TableRegistry::get('CurrencyConverter.Currencyrates');
0 ignored issues
show
Deprecated Code introduced by
The function Cake\ORM\TableRegistry::get() has been deprecated: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

76
        $this->_currencyratesTable = /** @scrutinizer ignore-deprecated */ TableRegistry::get('CurrencyConverter.Currencyrates');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
77
    }
78 7
79
    /**
80 7
     * Convert method take an amount as first parameter and convert it using $from currency and $to currency.
81 1
     *
82 1
     * @param float|string $amount the amount to convert.
83
     * @param string $from currency to convert from
84 7
     * @param string $to currency to convert to
85 1
     * @return float $amount converted
86 1
     */
87 7
    public function convert($amount, $from, $to)
88
    {
89 5
        $amount = floatval($amount);
90
        $rate = $this->getRateToUse($from, $to);
91 5
92 5
        return $convert = $this->_formatConvert($rate * $amount);
0 ignored issues
show
Unused Code introduced by
The assignment to $convert is dead and can be removed.
Loading history...
93
    }
94 5
95 5
    /**
96
     * Rate method return the rate of two currencies
97 5
     *
98 2
     * @param string $from currency to get the rate from
99
     * @param string $to currency to get the rate to
100 2
     * @return float|null $rate
101 2
     */
102 2
    public function rate($from, $to)
103
    {
104 2
        return $this->getRateToUse($from, $to);
105
    }
106
107 2
    /**
108
     * getRateToUse return rate to use
109 5
     * Using $from and $to parameters representing currency to deal with and the configuration settings
110
     * This method save or update currencyrates Table if necesseray too.
111 5
     *
112 3
     * @param string $from currency to get the rate from
113 3
     * @param string $to currency to get the rate to
114 5
     * @return float|null $rate
115
     */
116
    public function getRateToUse($from, $to)
117
    {
118
        if ($from == $to) {
119
            return 1;
120
        } else {
121
            if ($this->database) {
122
                // Get a currency rate from table
123
                $result = $this->_currencyratesTable->find('all')->where(['from_currency' => $from, 'to_currency' => $to])->first();
124
                if ($result) {
125
                    // If currency rate is in table and it doesn't have to be updated
126
                    if ($result->get('modified')->wasWithinLast($this->refresh . ' hours')) {
127
                        return $rate = $result->get('rate');
0 ignored issues
show
Unused Code introduced by
The assignment to $rate is dead and can be removed.
Loading history...
128
                    } else {
129
                        $rate = $this->_getRateFromAPI($from, $to);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $rate is correct as $this->_getRateFromAPI($from, $to) targeting CurrencyConverter\Contro...nent::_getRateFromAPI() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
130
                        if ($rate) {
0 ignored issues
show
introduced by
$rate is of type null, thus it always evaluated to false.
Loading history...
131
                            $result->rate = $rate;
132 3
                            $this->_currencyratesTable->save($result);
133
                        }
134 3
                        return $rate;
135
                    }
136
                }
137 3
                // If currency rate isn't in table
138 3
                if (!$result) {
139 3
                    $rate = $this->_getRateFromAPI($from, $to);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $rate is correct as $this->_getRateFromAPI($from, $to) targeting CurrencyConverter\Contro...nent::_getRateFromAPI() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
140 3
                    if ($rate) {
0 ignored issues
show
introduced by
$rate is of type null, thus it always evaluated to false.
Loading history...
141 3
                        $entity = $this->_currencyratesTable->newEntity([
142 3
                            'from_currency' => $from,
143
                            'to_currency' => $to,
144 3
                            'rate' => $rate
145 3
                        ]);
146 3
                        $this->_currencyratesTable->save($entity);
147
                    }
148 2
                    return $rate;
149
                }
150
            }
151 2
        }
152 2
        
153 2
        return $this->_getRateFromAPI($from, $to);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->_getRateFromAPI($from, $to) targeting CurrencyConverter\Contro...nent::_getRateFromAPI() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
154 2
    }
155 2
156 2
    /**
157
     * Format number using configuration
158
     *
159 5
     * @param float price to format
0 ignored issues
show
Bug introduced by
The type CurrencyConverter\Controller\Component\price was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
160
     * @return float
161 5
     */
162 5
    private function _formatConvert($number)
163
    {
164 5
        return floatval(number_format($number, $this->decimal));
165 5
    }
166 5
167 5
    /**
168
     * Call free.currencyconverterapi.com API to get a rate for one currency to an other one currency
169 5
     *
170
     * @param string $from the currency
171
     * @param string $to the currency
172
     * @return int|null $rate
173 5
     */
174 5
    private function _getRateFromAPI($from, $to)
175
    {
176 5
        $rate = null;
177
178
        $url = 'https://free.currencyconverterapi.com/api/v5/convert?q=' . $from . '_' . $to . '&compact=ultra';
179
        $request = @fopen($url, 'r');
180 5
181
        if ($request) {
0 ignored issues
show
introduced by
$request is of type false|resource, thus it always evaluated to false.
Loading history...
182
            $response = fgets($request, 4096);
183 5
            fclose($request);
184
            $response = json_decode($response, true);
185 5
            if (isset($response[$from . '_' . $to])) {
186
                $rate = $response[$from . '_' . $to];
187 5
            }
188 5
        }
189
        
190
        return $rate;
191 5
    }
192
}
193