Completed
Push — master ( 794160...5bca01 )
by Nikola
03:58
created

MemoryRepository::getRateKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 8
Ratio 100 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 8
loc 8
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 4
crap 1
1
<?php
2
/*
3
 * This file is part of the Exchange Rate package, an RunOpenCode project.
4
 *
5
 * (c) 2017 RunOpenCode
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace RunOpenCode\ExchangeRate\Repository;
11
12
use RunOpenCode\ExchangeRate\Contract\RateInterface;
13
use RunOpenCode\ExchangeRate\Contract\RepositoryInterface;
14
use RunOpenCode\ExchangeRate\Enum\RateType;
15
use RunOpenCode\ExchangeRate\Exception\ExchangeRateException;
16
use RunOpenCode\ExchangeRate\Utils\RateFilterUtil;
17
18
/**
19
 * Class MemoryRepository
20
 *
21
 * Memory repository is useful for unit testing only.
22
 *
23
 * @package RunOpenCode\ExchangeRate\Repository
24
 */
25
class MemoryRepository implements RepositoryInterface
26
{
27
    /**
28
     * @var RateInterface[]
29
     */
30
    private $rates;
31
32 8
    public function __construct()
33
    {
34 8
        $this->rates = [];
35 8
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40 7
    public function save(array $rates)
41
    {
42
        /**
43
         * @var RateInterface $rate
44
         */
45 7
        foreach ($rates as $rate) {
46 7
            $this->rates[$this->getRateKey($rate->getCurrencyCode(), $rate->getDate(), $rate->getRateType(), $rate->getSourceName())] = $rate;
47
        }
48
49 7
        uasort($this->rates, function (RateInterface $rate1, RateInterface $rate2) {
50 5
            return ($rate1->getDate() > $rate2->getDate()) ? -1 : 1;
51 7
        });
52 7
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57 1 View Code Duplication
    public function delete(array $rates)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
58
    {
59
        /**
60
         * @var RateInterface $rate
61
         */
62 1
        foreach ($rates as $rate) {
63 1
            unset($this->rates[$this->getRateKey($rate->getCurrencyCode(), $rate->getDate(), $rate->getRateType(), $rate->getSourceName())]);
64
        }
65 1
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70 3 View Code Duplication
    public function has($sourceName, $currencyCode, \DateTime $date = null, $rateType = RateType::MEDIAN)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
71
    {
72 3
        if ($date === null) {
73 2
            $date = new \DateTime('now');
74
        }
75
76 3
        return array_key_exists($this->getRateKey($currencyCode, $date, $rateType, $sourceName), $this->rates);
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82 3 View Code Duplication
    public function get($sourceName, $currencyCode, \DateTime $date = null, $rateType = RateType::MEDIAN)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83
    {
84 3
        if ($date === null) {
85 3
            $date = new \DateTime('now');
86
        }
87
88 3
        if ($this->has($sourceName, $currencyCode, $date, $rateType)) {
89 2
            return $this->rates[$this->getRateKey($currencyCode, $date, $rateType, $sourceName)];
90
        }
91
92 1
        throw new ExchangeRateException(sprintf('Could not fetch rate for rate currency code "%s" and rate type "%s" on date "%s".', $currencyCode, $rateType, $date->format('Y-m-d')));
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98 2 View Code Duplication
    public function latest($sourceName, $currencyCode, $rateType = RateType::MEDIAN)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
99
    {
100
        /**
101
         * @var RateInterface $rate
102
         */
103 2
        foreach ($this->rates as $rate) {
104
105
            if (
106 1
                $rate->getSourceName() === $sourceName
107
                &&
108 1
                $rate->getCurrencyCode() === $currencyCode
109
                &&
110 1
                $rate->getRateType() === $rateType
111
            ) {
112 1
                return $rate;
113
            }
114
        }
115
116 1
        throw new ExchangeRateException(sprintf('Could not fetch latest rate for rate currency code "%s" and rate type "%s" from source "%s".', $currencyCode, $rateType, $sourceName));
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122 3 View Code Duplication
    public function all(array $criteria = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
123
    {
124 3
        if (count($criteria) == 0) {
125 1
            return $this->rates;
126
        }
127
128 2
        $result = array();
129
130
        /**
131
         * @var RateInterface $rate
132
         */
133 2
        foreach ($this->rates as $rate) {
134
135 2
            if (RateFilterUtil::matches($rate, $criteria)) {
136 2
                $result[] = $rate;
137
            }
138
        }
139
140 2
        return $this->paginate($result, $criteria);
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146 1
    public function count()
147
    {
148 1
        return count($this->rates);
149
    }
150
151
    /**
152
     * Builds rate key to speed up search.
153
     *
154
     * @param string $currencyCode
155
     * @param \DateTime $date
156
     * @param string $rateType
157
     * @param string $sourceName
158
     * @return string
159
     */
160 7 View Code Duplication
    protected function getRateKey($currencyCode, $date, $rateType, $sourceName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
161
    {
162 7
        return str_replace(
163 7
            array('%currency_code%', '%date%', '%rate_type%', '%source_name%'),
164 7
            array($currencyCode, $date->format('Y-m-d'), $rateType, $sourceName),
165 7
            '%currency_code%_%date%_%rate_type%_%source_name%'
166
        );
167
    }
168
169
    /**
170
     * Extract requested page from filter criteria.
171
     *
172
     * @param array $rates Rates to filter for pagination.
173
     * @param array $criteria Filter criteria.
174
     * @return RateInterface[] Paginated rates.
175
     */
176 2 View Code Duplication
    protected function paginate(array $rates, $criteria)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
177
    {
178 2
        if (!array_key_exists('offset', $criteria) && !array_key_exists('limit', $criteria)) {
179 1
            return $rates;
180
        }
181
182 1
        $range = array();
183 1
        $offset = array_key_exists('offset', $criteria) ? $criteria['offset'] : 0;
184 1
        $limit = min((array_key_exists('limit', $criteria) ? $criteria['limit'] : count($rates)) + $offset, count($rates));
185
186 1
        for ($i = $offset; $i < $limit; $i++) {
187 1
            $range[] = $rates[$i];
188
        }
189
190 1
        return $range;
191
    }
192
}
193