Passed
Push — master ( 376d34...7bf0e1 )
by Alexander
04:51 queued 02:18
created

DebugEventsCommand::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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