Passed
Push — master ( 775805...67d0f2 )
by Sergei
02:43
created

src/Collector/Console/CommandCollector.php (2 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Debug\Collector\Console;
6
7
use RuntimeException;
8
use Symfony\Component\Console\Command\Command;
9
use Symfony\Component\Console\Event\ConsoleCommandEvent;
10
use Symfony\Component\Console\Event\ConsoleErrorEvent;
11
use Symfony\Component\Console\Event\ConsoleEvent;
12
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
13
use Yiisoft\Yii\Debug\Collector\CollectorInterface;
14
use Yiisoft\Yii\Debug\Collector\CollectorTrait;
15
use Yiisoft\Yii\Debug\Collector\IndexCollectorInterface;
16
17
use function is_object;
18
19
final class CommandCollector implements CollectorInterface, IndexCollectorInterface
20
{
21
    use CollectorTrait;
22
23
    /**
24
     * Let -1 mean that it was not set during the process.
25
     */
26
    private const UNDEFINED_EXIT_CODE = -1;
27
    private array $commands = [];
28
29
    public function getCollected(): array
30
    {
31
        return $this->commands;
32
    }
33
34
    public function collect(ConsoleEvent|ConsoleErrorEvent|ConsoleTerminateEvent $event): void
35
    {
36
        if (!is_object($event) || !$this->isActive()) {
37
            return;
38
        }
39
40
        $command = $event->getCommand();
41
42
        if ($event instanceof ConsoleErrorEvent) {
43
            $this->commands[$event::class] = [
44
                'name' => $event->getInput()->getFirstArgument() ?? '',
45
                'command' => $command,
46
                'input' => $event->getInput()->__toString(),
0 ignored issues
show
The method __toString() does not exist on Symfony\Component\Console\Input\InputInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Symfony\Component\Consol...treamableInputInterface or Symfony\Component\Console\Input\Input or Symfony\Component\Console\Input\Input. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

46
                'input' => $event->getInput()->/** @scrutinizer ignore-call */ __toString(),
Loading history...
47
                'output' => $event->getOutput()->fetch(),
0 ignored issues
show
The method fetch() does not exist on Symfony\Component\Console\Output\OutputInterface. It seems like you code against a sub-type of Symfony\Component\Console\Output\OutputInterface such as Symfony\Component\Console\Output\BufferedOutput or Symfony\Component\Consol...put\TrimmedBufferOutput or Yiisoft\Yii\Console\Output\ConsoleBufferedOutput or Yiisoft\Yii\Console\Output\ConsoleBufferedOutput. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

47
                'output' => $event->getOutput()->/** @scrutinizer ignore-call */ fetch(),
Loading history...
48
                'error' => $event->getError()->getMessage(),
49
                'exitCode' => $event->getExitCode(),
50
            ];
51
52
            return;
53
        }
54
55
        if ($event instanceof ConsoleTerminateEvent) {
56
            $this->commands[$event::class] = [
57
                'name' => $command->getName(),
58
                'command' => $command,
59
                'input' => $event->getInput()->__toString(),
60
                'output' => $event->getOutput()->fetch(),
61
                'exitCode' => $event->getExitCode(),
62
            ];
63
            return;
64
        }
65
66
        if ($event instanceof ConsoleEvent) {
67
            $this->commands[$event::class] = [
68
                'name' => $command->getName(),
69
                'command' => $command,
70
                'input' => $event->getInput()->__toString(),
71
                'output' => $event->getOutput()->fetch(),
72
                'arguments' => $command->getDefinition()->getArguments(),
73
                'options' => $command->getDefinition()->getOptions(),
74
            ];
75
        }
76
    }
77
78
    public function getIndexData(): array
79
    {
80
        $eventTypes = [
81
            ConsoleErrorEvent::class,
82
            ConsoleTerminateEvent::class,
83
            ConsoleCommandEvent::class,
84
        ];
85
86
        $commandEvent = null;
87
        foreach ($eventTypes as $eventType) {
88
            if (!array_key_exists($eventType, $this->commands)) {
89
                continue;
90
            }
91
92
            $commandEvent = $this->commands[$eventType];
93
            break;
94
        }
95
96
        if ($commandEvent === null) {
97
            $types = array_keys($this->commands);
98
            throw new RuntimeException(
99
                sprintf(
100
                    'Unsupported event type encountered among "%s". Supported only "%s"',
101
                    implode('", "', $types),
102
                    implode('", "', $eventTypes),
103
                )
104
            );
105
        }
106
107
        return [
108
            'command' => [
109
                'name' => $commandEvent['name'],
110
                'class' => $commandEvent['command'] instanceof Command ? $commandEvent['command']::class : null,
111
                'input' => $commandEvent['input'],
112
                'exitCode' => $commandEvent['exitCode'] ?? self::UNDEFINED_EXIT_CODE,
113
            ],
114
        ];
115
    }
116
117
    private function reset(): void
118
    {
119
        $this->commands = [];
120
    }
121
}
122