Completed
Push — master ( 525b4c...5283d1 )
by Mantas
15:03
created

Twig/PriceExtension.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ONGR\CurrencyExchangeBundle\Twig;
13
14
use ONGR\CurrencyExchangeBundle\Exception\UndefinedCurrencyException;
15
use ONGR\CurrencyExchangeBundle\Service\CurrencyExchangeService;
16
use Psr\Log\LoggerAwareInterface;
17
use Psr\Log\LoggerAwareTrait;
18
use Psr\Log\LoggerInterface;
19
20
/**
21
 * Class for displaying changed currencies.
22
 */
23
class PriceExtension extends \Twig_Extension implements LoggerAwareInterface
24
{
25
    use LoggerAwareTrait;
26
27
    /**
28
     * Extension name
29
     */
30
    const NAME = 'price_extension';
31
32
    /**
33
     * @var string Currency sign.
34
     */
35
    private $currencySign;
36
37
    /**
38
     * @var string Decimal point separator.
39
     */
40
    private $decPointSeparator;
41
42
    /**
43
     * @var string Thousands separator.
44
     */
45
    private $thousandsSeparator;
46
47
    /**
48
     * @var null Currency.
49
     */
50
    private $currency = null;
51
52
    /**
53
     * @var CurrencyExchangeService Service which provide currency exchange rates.
54
     */
55
    private $currencyService = null;
56
57
    /**
58
     * @var array Contains formats for each currency.
59
     */
60
    private $formatsMap;
61
62
    /**
63
     * @var array Array of currencies to be listed in twig while using the "list" functions.
64
     */
65
    private $toListMap;
66
67
    /**
68
     * Constructor.
69
     *
70
     * @param string $currencySign
71
     * @param string $decPointSeparator
72
     * @param string $thousandsSeparator
73
     * @param array  $currency
74
     * @param array  $formatsMap
75
     * @param array  $toListMap
76
     */
77
    public function __construct(
78
        $currencySign,
79 27
        $decPointSeparator,
80
        $thousandsSeparator,
81
        $currency = null,
82
        $formatsMap = [],
83
        $toListMap = []
84
    ) {
85
        $this->currencySign = $currencySign;
86
        $this->decPointSeparator = $decPointSeparator;
87 27
        $this->thousandsSeparator = $thousandsSeparator;
88 27
        $this->currency = $currency;
0 ignored issues
show
Documentation Bug introduced by
It seems like $currency can also be of type array. However, the property $currency is declared as type null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
89 27
        $this->formatsMap = $formatsMap;
90 27
        $this->toListMap = $toListMap;
91 27
    }
92 27
93 27
    /**
94
     * @return \Twig_SimpleFilter[]
95
     */
96
    public function getFilters()
97
    {
98 2
        $functions = [];
99
        $functions[] = new \Twig_SimpleFilter(
100 2
            'ongr_price',
101 2
            [$this, 'getFormattedPrice'],
102 2
            ['is_safe' => ['html']]
103 2
        );
104 2
        $functions[] = new \Twig_SimpleFilter(
105 2
            'ongr_price_list',
106 2
            [$this, 'getPriceList'],
107 2
            [
108 2
                'needs_environment' => true,
109
                'is_safe' => ['html'],
110 2
            ]
111 2
        );
112
113 2
        return $functions;
114
    }
115 2
116
    /**
117
     * @return \Twig_SimpleFunction[]
118
     */
119
    public function getFunctions()
120
    {
121 2
        return [
122
            new \Twig_SimpleFunction(
123
                'ongr_currency_list',
124 2
                [$this, 'getCurrencyList'],
125 2
                [
126 2
                    'needs_environment' => true,
127
                    'is_safe' => [
128 2
                        'html',
129
                    ],
130 2
                ]
131 2
            ),
132
        ];
133 2
    }
134 2
135
    /**
136
     * Returns formatted price.
137
     *
138
     * @param float  $price
139
     * @param int    $decimals
140
     * @param string $toCurrency
141
     * @param string $fromCurrency
142
     * @param string $customFormat
143
     *
144
     * @return string
145
     */
146
    public function getFormattedPrice(
147
        $price,
148 21
        $decimals = 0,
149
        $toCurrency = null,
150
        $fromCurrency = null,
151
        $customFormat = null
152
    ) {
153
        $targetCurrency = $toCurrency ? $toCurrency : $this->currency;
154
155 21
        if ($targetCurrency) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $targetCurrency of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
156
            if (isset($this->currencyService)) {
157 21
                try {
158 21
                    $price = $this->currencyService->calculateRate($price, $targetCurrency, $fromCurrency);
0 ignored issues
show
It seems like $fromCurrency defined by parameter $fromCurrency on line 150 can also be of type string; however, ONGR\CurrencyExchangeBun...ervice::calculateRate() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
159
                } catch (UndefinedCurrencyException $ex) {
160 20
                    $this->logger && $this->logger->error(
161 20
                        'Got undefined currency on PriceExtension',
162 1
                        ['message' => $ex->getMessage()]
163 1
                    );
164 1
165 1
                    return '';
166
                }
167 1
            } else {
168
                $this->logger && $this->logger->error('Currency service is undefined on PriceExtension');
169 19
170 1
                return '';
171
            }
172 1
        }
173
174 19
        if (abs($price) > floor(abs($price))) {
175
            $decimals = 2;
176 19
        }
177 12
178 12
        $formattedPrice = number_format($price, $decimals, $this->decPointSeparator, $this->thousandsSeparator);
179
180 19
        $printFormat = null;
181
        if ($customFormat) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $customFormat of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
182 19
            $printFormat = $customFormat;
183 19
        } elseif (isset($this->formatsMap[$targetCurrency])) {
184 1
            $printFormat = $this->formatsMap[$targetCurrency];
185 19
        }
186 11
187 11
        if ($printFormat) {
188
            return sprintf($printFormat, $formattedPrice);
189 19
        } else {
190 12
            return "{$formattedPrice} {$this->currencySign}";
191
        }
192 8
    }
193
194
    /**
195
     * Returns specified prices formatted by a specified template.
196
     *
197
     * @param \Twig_Environment $environment
198
     * @param int               $price
199
     * @param string            $template
200
     * @param null              $fromCurrency
201
     *
202
     * @return string
203
     */
204
    public function getPriceList(
205
        $environment,
206 7
        $price,
207
        $template = 'ONGRCurrencyExchangeBundle::price_list.html.twig',
208
        $fromCurrency = null
209
    ) {
210
        $values = [];
211
        foreach ($this->toListMap as $targetCurrency) {
212 7
            $values[] = [
213 7
                'value' => $this->getFormattedPrice($price, 0, $targetCurrency, $fromCurrency),
214 7
                'currency' => strtolower($targetCurrency),
215 7
            ];
216 7
        }
217
218 7
        return $environment->render(
219
            $template,
220 7
            ['prices' => $values]
221 7
        );
222 7
    }
223 7
224
    /**
225
     * Returns all available currencies.
226
     *
227
     * @param \Twig_Environment $environment
228
     * @param string            $template
229
     *
230
     * @return string
231
     */
232
    public function getCurrencyList($environment, $template = 'ONGRCurrencyExchangeBundle::currency_list.html.twig')
233
    {
234 1
        $values = [];
235
        foreach ($this->toListMap as $targetCurrency) {
236 1
            $values[] = [
237 1
                'value' => $targetCurrency,
238 1
                'code' => strtolower($targetCurrency),
239 1
                'default' => (strcasecmp($targetCurrency, $this->currency) == 0) ? true : false,
240 1
            ];
241 1
        }
242
243 1
        return $environment->render(
244
            $template,
245 1
            ['currencies' => $values]
246 1
        );
247 1
    }
248 1
249
    /**
250
     * Returns name of the extension.
251
     *
252
     * @return string
253
     */
254
    public function getName()
255
    {
256 2
        return self::NAME;
257
    }
258 2
259
    /**
260
     * @param null $currency
261
     */
262
    public function setCurrency($currency)
263
    {
264 9
        $this->currency = $currency;
265
    }
266 9
267 9
    /**
268
     * @return string
269
     */
270
    public function getCurrency()
271
    {
272 2
        return $this->currency;
273
    }
274 2
275
    /**
276
     * @param CurrencyExchangeService $currencyService
277
     */
278
    public function setCurrencyExchangeService($currencyService)
279
    {
280 21
        $this->currencyService = $currencyService;
281
    }
282 21
283 21
    /**
284
     * @param array $toListMap
285
     */
286
    public function setToListMap($toListMap)
287
    {
288 2
        $this->toListMap = $toListMap;
289
    }
290 2
291 2
    /**
292
     * @param array $formatsMap
293
     */
294
    public function setFormatsMap($formatsMap)
295
    {
296 1
        $this->formatsMap = $formatsMap;
297
    }
298
}
299