Completed
Push — master ( b26542...bb7d10 )
by Nikola
07:16
created

FetchCommand::execute()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 36
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 36
ccs 0
cts 15
cp 0
rs 8.439
cc 6
eloc 24
nc 6
nop 2
crap 42
1
<?php
2
/*
3
 * This file is part of the Exchange Rate Bundle, 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\Bundle\ExchangeRate\Command;
11
12
use RunOpenCode\ExchangeRate\Contract\ManagerInterface;
13
use RunOpenCode\ExchangeRate\Contract\SourceInterface;
14
use RunOpenCode\ExchangeRate\Contract\SourcesRegistryInterface;
15
use RunOpenCode\ExchangeRate\Log\LoggerAwareTrait;
16
use Symfony\Component\Console\Command\Command;
17
use Symfony\Component\Console\Helper\FormatterHelper;
18
use Symfony\Component\Console\Input\InputInterface;
19
use Symfony\Component\Console\Input\InputOption;
20
use Symfony\Component\Console\Output\OutputInterface;
21
22
/**
23
 * Class FetchCommand
24
 *
25
 * Fetch rates from sources.
26
 *
27
 * @package RunOpenCode\Bundle\ExchangeRate\Command
28
 */
29
class FetchCommand extends Command
30
{
31
    use LoggerAwareTrait;
32
33
    /**
34
     * @var ManagerInterface
35
     */
36
    protected $manager;
37
38
    /**
39
     * @var SourcesRegistryInterface
40
     */
41
    protected $sourcesRegistry;
42
43
    public function __construct(ManagerInterface $manager, SourcesRegistryInterface $sourcesRegistry)
44
    {
45
        parent::__construct();
46
        $this->manager = $manager;
47
        $this->sourcesRegistry = $sourcesRegistry;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    protected function configure()
54
    {
55
        $this
56
            ->setName('roc:exchange-rate:fetch')
57
            ->setDescription('Fetch exchange rates from sources.')
58
            ->addOption('date', 'd', InputOption::VALUE_OPTIONAL, 'State on which date exchange rates should be fetched.')
59
            ->addOption('source', 's', InputOption::VALUE_OPTIONAL, 'State which sources should be contacted only, separated with comma.')
60
        ;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    protected function execute(InputInterface $input, OutputInterface $output)
67
    {
68
        try {
69
            $sources = $this->parseSources($input, $output);
70
            $date = $this->parseDate($input, $output);
71
        } catch (\Exception $e) {
72
            $output->writeln('<error>Unable to continue.</error>');
73
            return;
74
        }
75
76
        $output->writeln($this->getFormatter()->formatSection('Exchange rates', sprintf('Fetching from %s sources for date %s.', ($sources ? implode(', ', $sources) : 'all'),  $date->format('Y-m-d'))));
77
78
        try {
79
80
            $this->manager->fetch($sources, $date);
81
82
            $output->writeln($this->getFormatter()->formatSection('Exchange rates', 'Rates fetched.'));
83
84
            $this->getLogger()->info(sprintf('Rates fetched from %s sources for date %s.', ($sources) ? implode(', ', $sources) : 'all', $date->format('Y-m-d')));
85
86
        } catch (\Exception $e) {
87
            $this->getLogger()->critical('Unable to fetch rates.', array(
88
                'date' => date('Y-m-d H:i:s'),
89
                'sources' => $sources ? 'All' : implode(', ', $sources),
90
                'exception' => array(
91
                    'message' => $e->getMessage(),
92
                    'code' => $e->getCode(),
93
                    'file' => $e->getFile(),
94
                    'line' => $e->getLine(),
95
                    'trace' => $e->getTraceAsString()
96
                )
97
            ));
98
            $output->writeln('<error>Unable to fetch.</error>');
99
            return;
100
        }
101
    }
102
103
    /**
104
     * Parse date from console input.
105
     *
106
     * @param InputInterface $input
107
     * @param OutputInterface $output
108
     *
109
     * @return \DateTime
110
     *
111
     * @throws \Exception
112
     */
113
    protected function parseDate(InputInterface $input, OutputInterface $output)
114
    {
115
        $date = $input->getOption('date');
116
117
        if (!empty($date)) {
118
            $date = \DateTime::createFromFormat('Y-m-d', $date);
119
120
            if ($date === false) {
121
                $output->writeln('<error>Invalid date format provided, expected format is "Y-m-d".</error>');
122
                throw new \Exception;
123
            }
124
        } else {
125
            $date = new \DateTime('now');
126
        }
127
128
        return $date;
129
    }
130
131
    /**
132
     * Parse sources from console input.
133
     *
134
     * @param InputInterface $input
135
     * @param OutputInterface $output
136
     *
137
     * @return array|null
138
     *
139
     * @throws \Exception
140
     */
141
    protected function parseSources(InputInterface $input, OutputInterface $output)
142
    {
143
        $sources = $input->getOption('source');
144
145
        if (!empty($sources)) {
146
            $sources = array_map('trim', explode(',', $sources));
147
148
            foreach ($sources as $source) {
149
150
                if (!$this->sourcesRegistry->has($source)) {
151
                    $output->writeln(sprintf('<error>Invalid source name "%s" provided, available sources are "%s".</error>', $source, implode(', ', array_map(function(SourceInterface $source) {
152
                        return $source->getName();
153
                    }, $this->sourcesRegistry->all()))));
154
                    throw new \Exception;
155
                }
156
            }
157
        }
158
159
        return $sources;
160
    }
161
162
    /**
163
     * Get formatter.
164
     *
165
     * @return FormatterHelper
166
     */
167
    protected function getFormatter()
168
    {
169
        return $this->getHelper('formatter');
170
    }
171
}
172