DebugEventsCommand::execute()   C
last analyzed

Complexity

Conditions 14
Paths 17

Size

Total Lines 70
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 14
eloc 49
c 1
b 0
f 0
nc 17
nop 2
dl 0
loc 70
rs 6.2666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Debug\Command;
6
7
use Psr\Container\ContainerInterface;
8
use ReflectionClass;
9
use Symfony\Component\Console\Attribute\AsCommand;
10
use Symfony\Component\Console\Command\Command;
11
use Symfony\Component\Console\Helper\Table;
12
use Symfony\Component\Console\Input\InputArgument;
13
use Symfony\Component\Console\Input\InputInterface;
14
use Symfony\Component\Console\Input\InputOption;
15
use Symfony\Component\Console\Output\OutputInterface;
16
use Symfony\Component\Console\Style\SymfonyStyle;
17
use Symfony\Component\VarDumper\VarDumper as SymfonyVarDumper;
18
use Yiisoft\Config\ConfigInterface;
19
use Yiisoft\VarDumper\VarDumper;
20
use Yiisoft\Yii\Console\ExitCode;
21
use Yiisoft\Yii\Debug\Debugger;
22
23
#[AsCommand(
24
    name: 'debug:events',
25
    description: 'Show information about events and listeners',
26
)]
27
final class DebugEventsCommand extends Command
28
{
29
    public function __construct(
30
        private readonly ContainerInterface $container,
31
        private readonly Debugger $debugger,
32
    ) {
33
        parent::__construct();
34
    }
35
36
    protected function configure(): void
37
    {
38
        $this
39
            ->addArgument('id', InputArgument::IS_ARRAY, 'Service ID')
40
            ->addOption('groups', null, InputOption::VALUE_NONE, 'Show groups')
41
            ->addOption('group', 'g', InputOption::VALUE_REQUIRED, 'Show group');
42
    }
43
44
    protected function execute(InputInterface $input, OutputInterface $output): int
45
    {
46
        $this->debugger->stop();
47
        $config = $this->container->get(ConfigInterface::class);
48
49
        $io = new SymfonyStyle($input, $output);
50
51
        if ($input->hasOption('groups') && $input->getOption('groups')) {
52
            $build = $this->getConfigBuild($config);
53
            $groups = array_keys($build);
54
            sort($groups);
55
56
            $io->table(['Groups'], array_map(static fn ($group) => [$group], $groups));
57
58
            return ExitCode::OK;
59
        }
60
        if ($input->hasOption('group') && !empty($group = $input->getOption('group'))) {
61
            $data = $config->get($group);
62
            ksort($data);
63
            $table = new Table($output);
64
65
            foreach ($data as $event => $listeners) {
66
                $io->title($event);
67
                foreach ($listeners as $listener) {
68
                    if (is_callable($listener) && !is_array($listener)) {
69
                        SymfonyVarDumper::dump($this->export($listener));
70
                    } else {
71
                        SymfonyVarDumper::dump($listener);
72
                    }
73
                }
74
                $table->render();
75
                $io->newLine();
76
            }
77
            return ExitCode::OK;
78
        }
79
80
        $data = [];
81
        if ($config->has('events')) {
82
            $data = array_merge($data, $config->get('events'));
83
        }
84
        if ($config->has('events-console')) {
85
            $data = array_merge($data, $config->get('events-console'));
86
        }
87
        $rows = [];
88
        foreach ($data as $event => $listeners) {
89
            $rows[] = [
90
                $event,
91
                is_countable($listeners) ? count($listeners) : 0,
92
                implode(
93
                    "\n",
94
                    array_map(function (mixed $listener) {
95
                        if (is_array($listener)) {
96
                            return sprintf(
97
                                '%s::%s',
98
                                $listener[0],
99
                                $listener[1]
100
                            );
101
                        }
102
                        return $this->export($listener);
103
                    }, $listeners)
104
                ),
105
            ];
106
        }
107
        $table = new Table($output);
108
        $table
109
            ->setHeaders(['Event', 'Count', 'Listeners'])
110
            ->setRows($rows);
111
        $table->render();
112
113
        return ExitCode::OK;
114
    }
115
116
    private function getConfigBuild(mixed $config): array
117
    {
118
        $reflection = new ReflectionClass($config);
119
        $buildReflection = $reflection->getProperty('build');
120
        $buildReflection->setAccessible(true);
121
        return $buildReflection->getValue($config);
122
    }
123
124
    protected function export(mixed $value): string
125
    {
126
        return VarDumper::create($value)->asString();
127
    }
128
}
129