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

Service/CurrencyRatesService.php (3 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\Service;
13
14
use Elasticsearch\Common\Exceptions\Missing404Exception;
15
use ONGR\CurrencyExchangeBundle\Currency\CurrencyDriverInterface;
16
use ONGR\CurrencyExchangeBundle\Document\CurrencyDocument;
17
use ONGR\CurrencyExchangeBundle\Document\RatesObject;
18
use ONGR\CurrencyExchangeBundle\Exception\RatesNotLoadedException;
19
use ONGR\ElasticsearchDSL\Query\MatchAllQuery;
20
use ONGR\ElasticsearchDSL\Sort\FieldSort;
21
use ONGR\ElasticsearchBundle\Service\Manager;
22
use ONGR\ElasticsearchBundle\Service\Repository;
23
use Psr\Log\LoggerAwareInterface;
24
use Psr\Log\LoggerAwareTrait;
25
use Stash\Interfaces\ItemInterface;
26
use Stash\Interfaces\PoolInterface;
27
28
/**
29
 * This class provides currency rates.
30
 */
31
class CurrencyRatesService implements LoggerAwareInterface
32
{
33
    use LoggerAwareTrait;
34
35
    /**
36
     * @var null|array
37
     */
38
    public $rates = null;
39
40
    /**
41
     * @var CurrencyDriverInterface
42
     */
43
    private $driver;
44
45
    /**
46
     * @var PoolInterface
47
     */
48
    private $pool;
49
50
    /**
51
     * @var Manager
52
     */
53
    private $manager;
54
55
    /**
56
     * @param CurrencyDriverInterface $driver  Currency exchange driver.
57
     * @param Manager                 $manager ES Manager.
58
     * @param PoolInterface           $pool    Cache pool.
59
     */
60 5
    public function __construct(
61
        CurrencyDriverInterface $driver,
62
        Manager $manager,
63
        PoolInterface $pool
64
    ) {
65 5
        $this->driver = $driver;
66 5
        $this->manager = $manager;
67 5
        $this->pool = $pool;
68 5
    }
69
70
    /**
71
     * This method returns exchange rates.
72
     *
73
     * @throws RatesNotLoadedException
74
     * @return array
75
     */
76 4
    public function getRates()
77
    {
78 4
        if (isset($this->rates)) {
79 3
            return $this->rates;
80
        }
81
82 4
        $item = $this->getCachedRates();
83 4
        $this->rates = $item->get();
84 4
        if (isset($this->rates)) {
85 1
            return $this->rates;
86
        }
87
88 3
        $this->rates = $this->getRatesFromBackup();
89 3
        if (isset($this->rates)) {
90
            return $this->rates;
91
        }
92
93 3
        $this->rates = $this->reloadRates();
94 3
        if (isset($this->rates)) {
95 2
            return $this->rates;
96
        }
97 1
        throw new RatesNotLoadedException('Currency rates are not loaded and could not be loaded on demand');
98
    }
99
100
    /**
101
     * Returns currency rates from ES.
102
     *
103
     * @return array
104
     */
105 3
    private function getRatesFromBackup()
106
    {
107 3
        $rates = [];
108 3
        $repository = $this->manager->getRepository('ONGRCurrencyExchangeBundle:CurrencyDocument');
109 3
        $search = $repository->createSearch();
110 3
        $search->addSort(new FieldSort('created_at', FieldSort::DESC));
111 3
        $query = new MatchAllQuery();
112 3
        $search->addQuery($query);
113 3
        $search->setSize(1);
114
        try {
115 3
            $results = $repository->execute($search, Repository::RESULTS_ARRAY);
116 3
        } catch (Missing404Exception $e) {
117 1
            $this->logger && $this->logger->notice('Failed to execute query. Please check ES configuration');
118
119 1
            return null;
120
        }
121
122 2
        if (count($results)) {
123
            foreach ($results[0]['rates'] as $data) {
124
                $rates[$data['name']] = $data['value'];
125
            }
126
            $this->logger && $this->logger->notice('Rates returned from ES. Cache updated.');
127
            $this->updateRatesCache($rates);
128
129
            return $rates;
130
        }
131
132 2
        return null;
133
    }
134
135
    /**
136
     * Update rates in cache.
137
     *
138
     * @param array $rates
139
     */
140 2
    private function updateRatesCache($rates)
141
    {
142 2
        $this->getCachedRates()->set($rates);
143 2
    }
144
145
    /**
146
     * @return ItemInterface
147
     */
148 4
    private function getCachedRates()
149
    {
150 4
        return $this->pool->getItem('ongr_currency');
0 ignored issues
show
The call to PoolInterface::getItem() has too many arguments starting with 'ongr_currency'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
151
    }
152
153
    /**
154
     * Reloads rates using given driver.
155
     *
156
     * @return array
157
     */
158 3
    public function reloadRates()
159
    {
160 3
        $esRates = [];
161 3
        $this->rates = $this->driver->getRates();
162
163
        /** @var CurrencyDocument $document */
164 3
        $document = new CurrencyDocument();
165 3
        $document->setCreatedAt(new \DateTime());
166
167 3
        if ($this->rates) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->rates of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
168 2
            foreach ($this->rates as $name => $value) {
169 2
                $ratesObject = new RatesObject();
170 2
                $ratesObject->setName($name);
171 2
                $ratesObject->setValue($value);
172 2
                $esRates[] = $ratesObject;
173 2
            }
174 2
            $document->rates = $esRates;
0 ignored issues
show
Documentation Bug introduced by
It seems like $esRates of type array is incompatible with the declared type object<ONGR\CurrencyExch...e\Document\RatesObject> of property $rates.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
175 2
            $this->manager->persist($document);
176 2
            $this->manager->commit();
177 2
            $this->updateRatesCache($this->rates);
178
179 2
            return $this->rates;
180
        }
181 1
        $this->logger && $this->logger->notice('Failed to retrieve currency rates from provider.');
182
183 1
        return null;
184
    }
185
186
    /**
187
     * Returns actual base currency name.
188
     *
189
     * @return string
190
     */
191 2
    public function getBaseCurrency()
192
    {
193 2
        return $this->driver->getDefaultCurrencyName();
194
    }
195
}
196