Completed
Push — master ( b615a7...036546 )
by Nikola
05:36 queued 20s
created

FetchCommand::notifyFail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
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\Input\InputInterface;
18
use Symfony\Component\Console\Input\InputOption;
19
use Symfony\Component\Console\Output\OutputInterface;
20
use Symfony\Component\Console\Style\SymfonyStyle;
21
use Symfony\Component\Console\Style\OutputStyle;
22
use Symfony\Component\Templating\EngineInterface;
23
24
/**
25
 * Class FetchCommand
26
 *
27
 * Fetch rates from sources.
28
 *
29
 * @package RunOpenCode\Bundle\ExchangeRate\Command
30
 */
31
class FetchCommand extends Command
32
{
33
    use LoggerAwareTrait;
34
35
    /**
36
     * @var ManagerInterface
37
     */
38
    protected $manager;
39
40
    /**
41
     * @var SourcesRegistryInterface
42
     */
43
    protected $sourcesRegistry;
44
45
    /**
46
     * @var \Swift_Mailer
47
     */
48
    protected $mailer;
49
50
    /**
51
     * @var EngineInterface
52
     */
53
    protected $templateEngine;
54
55
    /**
56
     * @var SymfonyStyle
57
     */
58
    protected $outputStyle;
59
60
    public function __construct(ManagerInterface $manager, SourcesRegistryInterface $sourcesRegistry)
61
    {
62
        parent::__construct();
63
        $this->manager = $manager;
64
        $this->sourcesRegistry = $sourcesRegistry;
65
    }
66
67
    public function setMailer(\Swift_Mailer $mailer)
68
    {
69
        $this->mailer = $mailer;
70
        return $this;
71
    }
72
73
    public function setTemplateEngine(EngineInterface $templateEngine)
74
    {
75
        $this->templateEngine = $templateEngine;
76
        return $this;
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    protected function configure()
83
    {
84
        $this
85
            ->setName('roc:exchange-rate:fetch')
86
            ->setDescription('Fetch exchange rates from sources.')
87
            ->addOption('date', 'd', InputOption::VALUE_OPTIONAL, 'State on which date exchange rates should be fetched.')
88
            ->addOption('source', 's', InputOption::VALUE_OPTIONAL, 'State which sources should be contacted only, separated with comma.')
89
        ;
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95
    protected function execute(InputInterface $input, OutputInterface $output)
96
    {
97
        $outputStyle = new SymfonyStyle($input, $output);
98
99
        try {
100
            $this
101
                ->cleanInputDate($input, $outputStyle)
102
                ->cleanInputSources($input, $outputStyle);
103
        } catch (\Exception $e) {
104
            return;
105
        }
106
107
        try {
108
            $this
0 ignored issues
show
Unused Code introduced by
The call to the method RunOpenCode\Bundle\Excha...ommand::notifySuccess() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
109
                ->displayCommandBegin($input, $outputStyle)
110
                ->doFetch($input)
111
                ->displayCommandSuccess($outputStyle)
112
                ->notifySuccess();
113
            ;
114
        } catch (\Exception $e) {
115
            $this
0 ignored issues
show
Unused Code introduced by
The call to the method RunOpenCode\Bundle\Excha...chCommand::notifyFail() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
116
                ->displayCommandFail($outputStyle)
117
                ->notifyFail();
118
        }
119
    }
120
121
122
    /**
123
     * Clean date from console input.
124
     *
125
     * @param InputInterface $input Console input.
126
     * @param OutputStyle $outputStyle Output style to use.
127
     * @return FetchCommand $this Fluent interface.
128
     *
129
     * @throws \Exception
130
     */
131
    protected function cleanInputDate(InputInterface $input, OutputStyle $outputStyle)
132
    {
133
        $date = $input->getOption('date');
134
135
        if (!empty($date)) {
136
            $date = \DateTime::createFromFormat('Y-m-d', $date);
137
138
            if ($date === false) {
139
                $outputStyle->error('Invalid date format provided, expected format is "Y-m-d".');
140
                throw new \Exception;
141
            }
142
        } else {
143
            $date = new \DateTime('now');
144
        }
145
146
        $input->setOption('date', $date);
147
148
        return $this;
149
    }
150
151
    /**
152
     * Clean sources from console input.
153
     *
154
     * @param InputInterface $input Console input.
155
     * @param OutputStyle $outputStyle Output style to use.
156
     * @return FetchCommand $this Fluent interface.
157
     *
158
     * @throws \Exception
159
     */
160
    protected function cleanInputSources(InputInterface $input, OutputStyle $outputStyle)
161
    {
162
        $sources = $input->getOption('source');
163
164
        if (!empty($sources)) {
165
            $sources = array_map('trim', explode(',', $sources));
166
167
            foreach ($sources as $source) {
168
169
                if (!$this->sourcesRegistry->has($source)) {
170
171
                    $outputStyle->error(sprintf('Invalid source name "%s" provided, available sources are "%s".', $source, implode(', ', array_map(function(SourceInterface $source) {
172
                        return $source->getName();
173
                    }, $this->sourcesRegistry->all()))));
174
175
                    throw new \Exception;
176
                }
177
            }
178
        }
179
180
        $input->setOption('source', $sources);
181
182
        return $this;
183
    }
184
185
    /**
186
     * Display command begin note.
187
     *
188
     * @param InputInterface $input Console input.
189
     * @param OutputStyle $outputStyle Console style.
190
     * @return FetchCommand $this Fluent interface.
191
     */
192
    protected function displayCommandBegin(InputInterface $input, OutputStyle $outputStyle)
193
    {
194
        $outputStyle->title('Exchange rates:');
195
        $outputStyle->text(
196
            sprintf(
197
                'Fetching from %s for date %s....',
198
                ($input->getOption('source') ? sprintf('"%s"', implode('", "', $input->getOption('source'))) : 'all sources'),
199
                $input->getOption('date')->format('Y-m-d')
200
            )
201
        );
202
203
        return $this;
204
    }
205
206
    /**
207
     * Do fetch rates.
208
     *
209
     * @param InputInterface $input Console input.
210
     * @return FetchCommand $this Fluent interface.
211
     * @throws \Exception
212
     */
213
    protected function doFetch(InputInterface $input)
214
    {
215
        try {
216
217
            $this->manager->fetch($input->getOption('source'), $input->getOption('date'));
218
219
            $this->getLogger()->info(sprintf('Rates fetched from %s for date %s.', $input->getOption('source') ? sprintf('"%s"', implode('", "', $input->getOption('source'))) : 'all sources', $input->getOption('date')->format('Y-m-d')));
220
221
        } catch (\Exception $e) {
222
223
            $this->getLogger()->critical('Unable to fetch rates.', array(
224
                'date' => $input->getOption('date')->format('Y-m-d'),
225
                'sources' => $input->getOption('source') ? sprintf('"%s"', implode('", "', $input->getOption('source'))) : 'All sources',
226
                'exception' => array(
227
                    'message' => $e->getMessage(),
228
                    'code' => $e->getCode(),
229
                    'file' => $e->getFile(),
230
                    'line' => $e->getLine(),
231
                    'trace' => $e->getTraceAsString()
232
                )
233
            ));
234
235
            throw $e;
236
        }
237
238
        return $this;
239
    }
240
241
    /**
242
     * Display command success note.
243
     *
244
     * @param OutputStyle $outputStyle
245
     * @return FetchCommand $this Fluent interface.
246
     */
247
    protected function displayCommandSuccess(OutputStyle $outputStyle)
248
    {
249
        $outputStyle->success('Exchange rates successfully fetched.');
250
        return $this;
251
    }
252
253
    protected function notifySuccess()
254
    {
255
256
        return $this;
257
    }
258
259
    /**
260
     * Display command fail note.
261
     *
262
     * @param OutputStyle $outputStyle
263
     * @return FetchCommand $this Fluent interface.
264
     */
265
    protected function displayCommandFail(OutputStyle $outputStyle)
266
    {
267
        $outputStyle->error('Unable to fetch data from source(s). See log for details.');
268
269
        return $this;
270
    }
271
272
    protected function notifyFail()
273
    {
274
        return $this;
275
    }
276
}
277