Passed
Push — master ( dd77b6...0c7091 )
by Sergei
06:24 queued 03:57
created

Application   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Test Coverage

Coverage 94.34%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
wmc 24
eloc 48
c 5
b 0
f 0
dl 0
loc 117
ccs 50
cts 53
cp 0.9434
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A extractNamespace() 0 5 2
A setDispatcher() 0 4 1
A renderThrowable() 0 5 1
A shutdown() 0 4 2
A doRenderThrowable() 0 22 5
A getNamespaces() 0 17 4
A start() 0 4 3
A extractAllNamespaces() 0 18 4
A addOptions() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Console;
6
7
use Symfony\Component\Console\Input\ArgvInput;
8
use Symfony\Component\Console\Input\InputOption;
9
use Symfony\Component\Console\Output\OutputInterface;
10
use Symfony\Component\Console\Style\StyleInterface;
11
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
12
use Throwable;
13
use Yiisoft\FriendlyException\FriendlyExceptionInterface;
14
use Yiisoft\Yii\Console\Event\ApplicationShutdown;
15
use Yiisoft\Yii\Console\Event\ApplicationStartup;
16
17
use function array_slice;
18
use function count;
19
use function explode;
20
use function implode;
21
22
final class Application extends \Symfony\Component\Console\Application
23
{
24
    public const NAME = 'Yii Console';
25
    public const VERSION = '1.0';
26
27
    private ?EventDispatcherInterface $dispatcher = null;
28
29 48
    public function __construct(string $name = self::NAME, string $version = self::VERSION)
30
    {
31 48
        parent::__construct($name, $version);
32
    }
33
34 48
    public function setDispatcher(EventDispatcherInterface $dispatcher): void
35
    {
36 48
        $this->dispatcher = $dispatcher;
37 48
        parent::setDispatcher($dispatcher);
38
    }
39
40 3
    public function start(?ArgvInput $input = null): void
41
    {
42 3
        if ($this->dispatcher !== null && $input !== null) {
43
            $this->dispatcher->dispatch(new ApplicationStartup($input->getFirstArgument()));
44
        }
45
    }
46
47 3
    public function shutdown(int $exitCode): void
48
    {
49 3
        if ($this->dispatcher !== null) {
50 3
            $this->dispatcher->dispatch(new ApplicationShutdown($exitCode));
51
        }
52
    }
53
54 3
    public function renderThrowable(Throwable $e, OutputInterface $output): void
55
    {
56 3
        $output->writeln('', OutputInterface::VERBOSITY_QUIET);
57
58 3
        $this->doRenderThrowable($e, $output);
59
    }
60
61 3
    protected function doRenderThrowable(Throwable $e, OutputInterface $output): void
62
    {
63 3
        parent::doRenderThrowable($e, $output);
64
65
        // Friendly Exception support
66 3
        if ($e instanceof FriendlyExceptionInterface) {
67 3
            if ($output instanceof StyleInterface) {
68 1
                $output->title($e->getName());
69 1
                if (($solution = $e->getSolution()) !== null) {
70 1
                    $output->note($solution);
71
                }
72 1
                $output->newLine();
73
            } else {
74 2
                $output->writeln('<fg=red>' . $e->getName() . '</>');
75 2
                if (($solution = $e->getSolution()) !== null) {
76 2
                    $output->writeln('<fg=yellow>' . $solution . '</>');
77
                }
78 2
                $output->writeln('');
79
            }
80
        }
81
82 3
        $output->writeln($e->getTraceAsString());
83
    }
84
85 48
    public function addOptions(InputOption $options): void
86
    {
87 48
        $this
88 48
            ->getDefinition()
89 48
            ->addOption($options);
90
    }
91
92 7
    public function extractNamespace(string $name, int $limit = null): string
93
    {
94 7
        $parts = explode('/', $name, -1);
95
96 7
        return implode('/', null === $limit ? $parts : array_slice($parts, 0, $limit));
97
    }
98
99 1
    public function getNamespaces(): array
100
    {
101 1
        $namespaces = [];
102 1
        foreach ($this->all() as $command) {
103 1
            if ($command->isHidden()) {
104 1
                continue;
105
            }
106
107 1
            $namespaces[] = $this->extractAllNamespaces($command->getName());
108
109
            /** @var string $alias */
110 1
            foreach ($command->getAliases() as $alias) {
111 1
                $namespaces[] = $this->extractAllNamespaces($alias);
112
            }
113
        }
114
115 1
        return array_values(array_unique(array_filter(array_merge([], ...$namespaces))));
116
    }
117
118
    /**
119
     * @return string[]
120
     */
121 1
    private function extractAllNamespaces(?string $name): array
122
    {
123 1
        if ($name === null) {
124
            return [];
125
        }
126
127 1
        $parts = explode('/', $name, -1);
128 1
        $namespaces = [];
129
130 1
        foreach ($parts as $part) {
131 1
            if (count($namespaces)) {
132
                $namespaces[] = end($namespaces) . '/' . $part;
133
            } else {
134 1
                $namespaces[] = $part;
135
            }
136
        }
137
138 1
        return $namespaces;
139
    }
140
}
141