235 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			PHP
		
	
	
			
		
		
	
	
			235 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			PHP
		
	
	
<?php
 | 
						|
 | 
						|
/*
 | 
						|
 * This file is part of the Symfony package.
 | 
						|
 *
 | 
						|
 * (c) Fabien Potencier <fabien@symfony.com>
 | 
						|
 *
 | 
						|
 * For the full copyright and license information, please view the LICENSE
 | 
						|
 * file that was distributed with this source code.
 | 
						|
 */
 | 
						|
 | 
						|
namespace Symfony\Component\Console\DataCollector;
 | 
						|
 | 
						|
use Symfony\Component\Console\Command\Command;
 | 
						|
use Symfony\Component\Console\Debug\CliRequest;
 | 
						|
use Symfony\Component\Console\Output\OutputInterface;
 | 
						|
use Symfony\Component\Console\SignalRegistry\SignalMap;
 | 
						|
use Symfony\Component\HttpFoundation\Request;
 | 
						|
use Symfony\Component\HttpFoundation\Response;
 | 
						|
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
 | 
						|
use Symfony\Component\VarDumper\Cloner\Data;
 | 
						|
 | 
						|
/**
 | 
						|
 * @internal
 | 
						|
 *
 | 
						|
 * @author Jules Pietri <jules@heahprod.com>
 | 
						|
 */
 | 
						|
final class CommandDataCollector extends DataCollector
 | 
						|
{
 | 
						|
    public function collect(Request $request, Response $response, ?\Throwable $exception = null): void
 | 
						|
    {
 | 
						|
        if (!$request instanceof CliRequest) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        $command = $request->command;
 | 
						|
        $application = $command->getApplication();
 | 
						|
 | 
						|
        $this->data = [
 | 
						|
            'command' => $this->cloneVar($command->command),
 | 
						|
            'exit_code' => $command->exitCode,
 | 
						|
            'interrupted_by_signal' => $command->interruptedBySignal,
 | 
						|
            'duration' => $command->duration,
 | 
						|
            'max_memory_usage' => $command->maxMemoryUsage,
 | 
						|
            'verbosity_level' => match ($command->output->getVerbosity()) {
 | 
						|
                OutputInterface::VERBOSITY_QUIET => 'quiet',
 | 
						|
                OutputInterface::VERBOSITY_NORMAL => 'normal',
 | 
						|
                OutputInterface::VERBOSITY_VERBOSE => 'verbose',
 | 
						|
                OutputInterface::VERBOSITY_VERY_VERBOSE => 'very verbose',
 | 
						|
                OutputInterface::VERBOSITY_DEBUG => 'debug',
 | 
						|
            },
 | 
						|
            'interactive' => $command->isInteractive,
 | 
						|
            'validate_input' => !$command->ignoreValidation,
 | 
						|
            'enabled' => $command->isEnabled(),
 | 
						|
            'visible' => !$command->isHidden(),
 | 
						|
            'input' => $this->cloneVar($command->input),
 | 
						|
            'output' => $this->cloneVar($command->output),
 | 
						|
            'interactive_inputs' => array_map($this->cloneVar(...), $command->interactiveInputs),
 | 
						|
            'signalable' => $command->getSubscribedSignals(),
 | 
						|
            'handled_signals' => $command->handledSignals,
 | 
						|
            'helper_set' => array_map($this->cloneVar(...), iterator_to_array($command->getHelperSet())),
 | 
						|
        ];
 | 
						|
 | 
						|
        $baseDefinition = $application->getDefinition();
 | 
						|
 | 
						|
        foreach ($command->arguments as $argName => $argValue) {
 | 
						|
            if ($baseDefinition->hasArgument($argName)) {
 | 
						|
                $this->data['application_inputs'][$argName] = $this->cloneVar($argValue);
 | 
						|
            } else {
 | 
						|
                $this->data['arguments'][$argName] = $this->cloneVar($argValue);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        foreach ($command->options as $optName => $optValue) {
 | 
						|
            if ($baseDefinition->hasOption($optName)) {
 | 
						|
                $this->data['application_inputs']['--'.$optName] = $this->cloneVar($optValue);
 | 
						|
            } else {
 | 
						|
                $this->data['options'][$optName] = $this->cloneVar($optValue);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function getName(): string
 | 
						|
    {
 | 
						|
        return 'command';
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return array{
 | 
						|
     *     class?: class-string,
 | 
						|
     *     executor?: string,
 | 
						|
     *     file: string,
 | 
						|
     *     line: int,
 | 
						|
     * }
 | 
						|
     */
 | 
						|
    public function getCommand(): array
 | 
						|
    {
 | 
						|
        $class = $this->data['command']->getType();
 | 
						|
        $r = new \ReflectionMethod($class, 'execute');
 | 
						|
 | 
						|
        if (Command::class !== $r->getDeclaringClass()) {
 | 
						|
            return [
 | 
						|
                'executor' => $class.'::'.$r->name,
 | 
						|
                'file' => $r->getFileName(),
 | 
						|
                'line' => $r->getStartLine(),
 | 
						|
            ];
 | 
						|
        }
 | 
						|
 | 
						|
        $r = new \ReflectionClass($class);
 | 
						|
 | 
						|
        return [
 | 
						|
            'class' => $class,
 | 
						|
            'file' => $r->getFileName(),
 | 
						|
            'line' => $r->getStartLine(),
 | 
						|
        ];
 | 
						|
    }
 | 
						|
 | 
						|
    public function getInterruptedBySignal(): ?string
 | 
						|
    {
 | 
						|
        if (isset($this->data['interrupted_by_signal'])) {
 | 
						|
            return sprintf('%s (%d)', SignalMap::getSignalName($this->data['interrupted_by_signal']), $this->data['interrupted_by_signal']);
 | 
						|
        }
 | 
						|
 | 
						|
        return null;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getDuration(): string
 | 
						|
    {
 | 
						|
        return $this->data['duration'];
 | 
						|
    }
 | 
						|
 | 
						|
    public function getMaxMemoryUsage(): string
 | 
						|
    {
 | 
						|
        return $this->data['max_memory_usage'];
 | 
						|
    }
 | 
						|
 | 
						|
    public function getVerbosityLevel(): string
 | 
						|
    {
 | 
						|
        return $this->data['verbosity_level'];
 | 
						|
    }
 | 
						|
 | 
						|
    public function getInteractive(): bool
 | 
						|
    {
 | 
						|
        return $this->data['interactive'];
 | 
						|
    }
 | 
						|
 | 
						|
    public function getValidateInput(): bool
 | 
						|
    {
 | 
						|
        return $this->data['validate_input'];
 | 
						|
    }
 | 
						|
 | 
						|
    public function getEnabled(): bool
 | 
						|
    {
 | 
						|
        return $this->data['enabled'];
 | 
						|
    }
 | 
						|
 | 
						|
    public function getVisible(): bool
 | 
						|
    {
 | 
						|
        return $this->data['visible'];
 | 
						|
    }
 | 
						|
 | 
						|
    public function getInput(): Data
 | 
						|
    {
 | 
						|
        return $this->data['input'];
 | 
						|
    }
 | 
						|
 | 
						|
    public function getOutput(): Data
 | 
						|
    {
 | 
						|
        return $this->data['output'];
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return Data[]
 | 
						|
     */
 | 
						|
    public function getArguments(): array
 | 
						|
    {
 | 
						|
        return $this->data['arguments'] ?? [];
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return Data[]
 | 
						|
     */
 | 
						|
    public function getOptions(): array
 | 
						|
    {
 | 
						|
        return $this->data['options'] ?? [];
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return Data[]
 | 
						|
     */
 | 
						|
    public function getApplicationInputs(): array
 | 
						|
    {
 | 
						|
        return $this->data['application_inputs'] ?? [];
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return Data[]
 | 
						|
     */
 | 
						|
    public function getInteractiveInputs(): array
 | 
						|
    {
 | 
						|
        return $this->data['interactive_inputs'] ?? [];
 | 
						|
    }
 | 
						|
 | 
						|
    public function getSignalable(): array
 | 
						|
    {
 | 
						|
        return array_map(
 | 
						|
            static fn (int $signal): string => sprintf('%s (%d)', SignalMap::getSignalName($signal), $signal),
 | 
						|
            $this->data['signalable']
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    public function getHandledSignals(): array
 | 
						|
    {
 | 
						|
        $keys = array_map(
 | 
						|
            static fn (int $signal): string => sprintf('%s (%d)', SignalMap::getSignalName($signal), $signal),
 | 
						|
            array_keys($this->data['handled_signals'])
 | 
						|
        );
 | 
						|
 | 
						|
        return array_combine($keys, array_values($this->data['handled_signals']));
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return Data[]
 | 
						|
     */
 | 
						|
    public function getHelperSet(): array
 | 
						|
    {
 | 
						|
        return $this->data['helper_set'] ?? [];
 | 
						|
    }
 | 
						|
 | 
						|
    public function reset(): void
 | 
						|
    {
 | 
						|
        $this->data = [];
 | 
						|
    }
 | 
						|
}
 |