SymfonyCommandAdapter   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 38
dl 0
loc 76
rs 10
c 1
b 0
f 0
wmc 8

3 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 3 1
A __construct() 0 9 1
B execute() 0 49 6
1
<?php
2
3
/**
4
 * This file is part of byrokrat\giroapp.
5
 *
6
 * byrokrat\giroapp is free software: you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License as published
8
 * by the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * byrokrat\giroapp is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with byrokrat\giroapp. If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * Copyright 2016-21 Hannes Forsgård
20
 */
21
22
declare(strict_types=1);
23
24
namespace byrokrat\giroapp\Console;
25
26
use byrokrat\giroapp\CommandBus\Commit;
27
use byrokrat\giroapp\CommandBus\Rollback;
28
use byrokrat\giroapp\Event;
29
use byrokrat\giroapp\Exception as GiroappException;
30
use byrokrat\giroapp\Event\Listener\OutputtingListener;
31
use byrokrat\giroapp\Plugin\EnvironmentInterface;
32
use Symfony\Component\Console\Command\Command;
33
use Symfony\Component\Console\Input\InputInterface;
34
use Symfony\Component\Console\Output\ConsoleOutputInterface;
35
use Symfony\Component\Console\Output\OutputInterface;
36
use Psr\EventDispatcher\EventDispatcherInterface;
37
38
final class SymfonyCommandAdapter extends Command
39
{
40
    /** @var ConsoleInterface */
41
    private $console;
42
43
    /** @var EnvironmentInterface */
44
    private $environment;
45
46
    /** @var EventDispatcherInterface */
47
    private $dispatcher;
48
49
    public function __construct(
50
        ConsoleInterface $console,
51
        EnvironmentInterface $environment,
52
        EventDispatcherInterface $dispatcher
53
    ) {
54
        $this->console = $console;
55
        $this->environment = $environment;
56
        $this->dispatcher = $dispatcher;
57
        parent::__construct();
58
    }
59
60
    protected function configure(): void
61
    {
62
        $this->console->configure($this);
63
    }
64
65
    protected function execute(InputInterface $input, OutputInterface $output): int
66
    {
67
        if (!$output instanceof ConsoleOutputInterface) {
68
            throw new \InvalidArgumentException('Output must implement ConsoleOutputInterface');
69
        }
70
71
        $this->environment->registerListener(new OutputtingListener($output->getErrorOutput()), 1);
72
73
        $commandBus = $this->environment->getCommandBus();
74
75
        try {
76
            $this->dispatcher->dispatch(new Event\ExecutionStarted());
77
            $this->console->execute($input, $output);
78
            $commandBus->handle(new Commit());
79
            $this->dispatcher->dispatch(new Event\ExecutionStopped());
80
        } catch (GiroappException $e) {
81
            $this->dispatcher->dispatch(
82
                new Event\ErrorEvent(
83
                    $e->getMessage(),
84
                    ['code' => $e->getCode()]
85
                )
86
            );
87
88
            $commandBus->handle(new Rollback());
89
90
            return $e->getCode();
91
        } catch (\Exception $e) {
92
            $this->dispatcher->dispatch(
93
                new Event\ErrorEvent(
94
                    $e->getMessage(),
95
                    [
96
                        'class' => get_class($e),
97
                        'file' => $e->getFile(),
98
                        'line' => (string)$e->getLine(),
99
                        'trace' => $e->getTraceAsString(),
100
                    ]
101
                )
102
            );
103
104
            if ($output->isVerbose()) {
105
                $output->writeln($e->getTraceAsString());
106
            }
107
108
            $commandBus->handle(new Rollback());
109
110
            return $e->getCode() ?: GiroappException::GENERIC_ERROR;
111
        }
112
113
        return 0;
114
    }
115
}
116