Completed
Push — master ( 26f700...5afdab )
by Nikola
02:10
created

Manager::historical()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 8.7414

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
ccs 4
cts 12
cp 0.3333
rs 9.2
cc 4
eloc 11
nc 4
nop 4
crap 8.7414
1
<?php
2
/*
3
 * This file is part of the Exchange Rate package, an RunOpenCode project.
4
 *
5
 * (c) 2016 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;
11
12
use RunOpenCode\ExchangeRate\Contract\ManagerInterface;
13
use RunOpenCode\ExchangeRate\Contract\ProcessorInterface;
14
use RunOpenCode\ExchangeRate\Contract\ProcessorsRegistryInterface;
15
use RunOpenCode\ExchangeRate\Contract\RatesConfigurationRegistryInterface;
16
use RunOpenCode\ExchangeRate\Contract\RepositoryInterface;
17
use RunOpenCode\ExchangeRate\Contract\SourceInterface;
18
use RunOpenCode\ExchangeRate\Contract\SourcesRegistryInterface;
19
use RunOpenCode\ExchangeRate\Exception\ExchangeRateException;
20
use RunOpenCode\ExchangeRate\Log\LoggerAwareTrait;
21
use RunOpenCode\ExchangeRate\Registry\SourcesRegistry;
22
use RunOpenCode\ExchangeRate\Utils\CurrencyCodeUtil;
23
24
/**
25
 * Class Manager
26
 *
27
 * Default implementation of manager.
28
 *
29
 * @package RunOpenCode\ExchangeRate
30
 */
31
class Manager implements ManagerInterface
32
{
33
    use LoggerAwareTrait;
34
35
    /**
36
     * @var string
37
     */
38
    protected $baseCurrency;
39
40
    /**
41
     * @var RepositoryInterface
42
     */
43
    protected $repository;
44
45
    /**
46
     * @var SourcesRegistryInterface
47
     */
48
    protected $sources;
49
50
    /**
51
     * @var ProcessorsRegistryInterface
52
     */
53
    protected $processors;
54
55
    /**
56
     * @var RatesConfigurationRegistryInterface
57
     */
58
    protected $configurations;
59
60 10
    public function __construct($baseCurrency, RepositoryInterface $repository, SourcesRegistryInterface $sources, ProcessorsRegistryInterface $processors, RatesConfigurationRegistryInterface $configurations)
61
    {
62 10
        $this->baseCurrency = CurrencyCodeUtil::clean($baseCurrency);
63 10
        $this->repository = $repository;
64 10
        $this->configurations = $configurations;
65 10
        $this->sources = $sources;
66 10
        $this->processors = $processors;
67 10
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 8
    public function has($sourceName, $currencyCode, \DateTime $date = null, $rateType = 'default')
73
    {
74 8
        return $this->repository->has($sourceName, CurrencyCodeUtil::clean($currencyCode), $date, $rateType);
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80 6
    public function get($sourceName, $currencyCode, \DateTime $date = null, $rateType = 'default')
81
    {
82 6
        return $this->repository->get($sourceName, CurrencyCodeUtil::clean($currencyCode), $date, $rateType);
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88 2
    public function latest($sourceName, $currencyCode, $rateType = 'default')
89
    {
90 2
        return $this->repository->latest($sourceName, CurrencyCodeUtil::clean($currencyCode), $rateType);
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96 4
    public function today($sourceName, $currencyCode, $rateType = 'default')
97
    {
98 4
        $currencyCode = CurrencyCodeUtil::clean($currencyCode);
99 4
        $today = new \DateTime('now');
100
101 4
        if ($this->has($sourceName, $currencyCode, $today, $rateType)) {
102 2
            return $this->get($sourceName, $currencyCode, $today, $rateType);
103
        }
104
105 2
        if ((int)$today->format('N') >= 6) {
106
            return $this->get($sourceName, $currencyCode, new \DateTime('last Friday'), $rateType);
107
        }
108
109 2
        $message = sprintf('Rate for currency code "%s" of type "%s" from source "%s" is not available for today "%s".', $currencyCode, $rateType, $sourceName, date('Y-m-d'));
110 2
        $this->getLogger()->critical($message);
111 2
        throw new ExchangeRateException($message);
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117 2
    public function historical($sourceName, $currencyCode, \DateTime $date, $rateType = 'default')
118
    {
119 2
        $currencyCode = CurrencyCodeUtil::clean($currencyCode);
120
121 2
        if ($this->has($sourceName, $currencyCode, $date, $rateType)) {
122 2
            return $this->get($sourceName, $currencyCode, $date, $rateType);
123
        }
124
125
        if ((int)$date->format('N') === 6) {
126
            $this->get($sourceName, $currencyCode, $date->sub(new \DateInterval('PT1D')), $rateType);
127
        } elseif ((int)$date->format('N') === 7) {
128
            $this->get($sourceName, $currencyCode, $date->sub(new \DateInterval('PT2D')), $rateType);
129
        }
130
131
        $message = sprintf('Rate for currency code "%s" of type "%s" from source "%s" is not available for historical date "%s".', $currencyCode, $rateType, $sourceName, $date->format('Y-m-d'));
132
        $this->getLogger()->critical($message);
133
        throw new ExchangeRateException($message);
134
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139 2
    public function fetch($sourceName = null, \DateTime $date = null)
140
    {
141 2
        $rates = array();
142
143 2
        $sourceNames = ($sourceName === null) ? array_map(function(SourceInterface $source) {
144
            return $source->getName();
145 2
        }, $this->sources->all()) : (array) $sourceName;
146
147 2
        foreach ($sourceNames as $sourceName) {
148
149 2
            $source = $this->sources->get($sourceName);
150
151 2
            $configurations = $this->configurations->all(array(
152
                'sourceName' => $sourceName
153 2
            ));
154
155
            /**
156
             * @var Configuration $configuration
157
             */
158 2
            foreach ($configurations as $configuration) {
159 2
                $rates[] = $source->fetch($configuration->getCurrencyCode(), $configuration->getRateType(), $date);
160 2
            }
161 2
        }
162
163
        /**
164
         * @var ProcessorInterface $processor
165
         */
166 2
        foreach ($this->processors->all() as $processor) {
167 2
            $rates = $processor->process($this->baseCurrency, $this->configurations, $rates);
168 2
        }
169
170 2
        $this->repository->save($rates);
171
172 2
        return $rates;
173
    }
174
}
175