chore: complete update
This commit is contained in:
168
src/Framework/Console/ConsoleApplication.php
Normal file
168
src/Framework/Console/ConsoleApplication.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Console;
|
||||
|
||||
use App\Framework\Console\Components\InteractiveMenu;
|
||||
use App\Framework\Console\Exceptions\CommandNotFoundException;
|
||||
use App\Framework\DI\Container;
|
||||
use App\Framework\Discovery\Results\DiscoveryResults;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use Throwable;
|
||||
|
||||
final class ConsoleApplication
|
||||
{
|
||||
private array $commands = [];
|
||||
private ConsoleOutputInterface $output;
|
||||
|
||||
public function __construct(
|
||||
private readonly Container $container,
|
||||
private readonly string $scriptName = 'console',
|
||||
private readonly string $title = 'Console Application',
|
||||
?ConsoleOutputInterface $output = null,
|
||||
|
||||
) {
|
||||
$this->output = $output ?? new ConsoleOutput();
|
||||
|
||||
// Setze den Fenstertitel
|
||||
$this->output->writeWindowTitle($this->title);
|
||||
|
||||
$results = $this->container->get(DiscoveryResults::class);
|
||||
|
||||
foreach($results->get(ConsoleCommand::class) as $command) {
|
||||
|
||||
$this->commands[$command['attribute_data']['name']] = [
|
||||
'instance' => $this->container->get($command['class']),
|
||||
'method' => $command['method'],
|
||||
'description' => $command['attribute_data']['description'] ?? ['Keine Beschreibung verfügbar'],
|
||||
'reflection' => new ReflectionMethod($command['class'], $command['method'])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registriert alle Kommandos aus einer Klasse
|
||||
*/
|
||||
|
||||
public function registerCommands(object $commandClass): void
|
||||
{
|
||||
$reflection = new ReflectionClass($commandClass);
|
||||
|
||||
foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
|
||||
$attributes = $method->getAttributes(ConsoleCommand::class);
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
/** @var ConsoleCommand $command */
|
||||
$command = $attribute->newInstance();
|
||||
|
||||
$this->commands[$command->name] = [
|
||||
'instance' => $commandClass,
|
||||
'method' => $method->getName(),
|
||||
'description' => $command->description,
|
||||
'reflection' => $method
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Führt ein Kommando aus
|
||||
*/
|
||||
public function run(array $argv): int
|
||||
{
|
||||
if (count($argv) < 2) {
|
||||
$this->showHelp();
|
||||
return ExitCode::SUCCESS->value;
|
||||
}
|
||||
|
||||
$commandName = $argv[1];
|
||||
$arguments = array_slice($argv, 2);
|
||||
|
||||
if (in_array($commandName, ['help', '--help', '-h'])) {
|
||||
$this->showHelp();
|
||||
return ExitCode::SUCCESS->value;
|
||||
}
|
||||
|
||||
if (!isset($this->commands[$commandName])) {
|
||||
$this->output->writeError("Kommando '{$commandName}' nicht gefunden.");
|
||||
$this->showHelp();
|
||||
return ExitCode::COMMAND_NOT_FOUND->value;
|
||||
}
|
||||
|
||||
return $this->executeCommand($commandName, $arguments)->value;
|
||||
}
|
||||
|
||||
private function executeCommand(string $commandName, array $arguments): ExitCode
|
||||
{
|
||||
$command = $this->commands[$commandName];
|
||||
$instance = $command['instance'];
|
||||
$method = $command['method'];
|
||||
|
||||
try {
|
||||
// Setze den Fenstertitel für das aktuelle Kommando
|
||||
$this->output->writeWindowTitle("{$this->scriptName} - {$commandName}");
|
||||
|
||||
// Erstelle ConsoleInput
|
||||
$input = new ConsoleInput($arguments, $this->output);
|
||||
|
||||
// Führe das Kommando aus
|
||||
$result = $instance->$method($input, $this->output);
|
||||
|
||||
// Behandle verschiedene Rückgabetypen
|
||||
if ($result instanceof ExitCode) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if (is_int($result)) {
|
||||
return ExitCode::from($result);
|
||||
}
|
||||
|
||||
// Standardmäßig Erfolg, wenn nichts anderes zurückgegeben wird
|
||||
return ExitCode::SUCCESS;
|
||||
|
||||
} catch (CommandNotFoundException $e) {
|
||||
$this->output->writeError("Kommando nicht gefunden: " . $e->getMessage());
|
||||
return ExitCode::COMMAND_NOT_FOUND;
|
||||
} catch (Throwable $e) {
|
||||
$this->output->writeError("Fehler beim Ausführen des Kommandos: " . $e->getMessage());
|
||||
|
||||
// Erweiterte Fehlerbehandlung basierend auf Exception-Typ
|
||||
if ($e instanceof \InvalidArgumentException) {
|
||||
return ExitCode::INVALID_INPUT;
|
||||
}
|
||||
|
||||
if ($e instanceof \RuntimeException) {
|
||||
return ExitCode::SOFTWARE_ERROR;
|
||||
}
|
||||
|
||||
return ExitCode::GENERAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
private function showHelp(): void
|
||||
{
|
||||
$this->output->writeLine("Verfügbare Kommandos:", ConsoleColor::BRIGHT_CYAN);
|
||||
$this->output->newLine();
|
||||
|
||||
$menu = new InteractiveMenu($this->output);
|
||||
$menu->setTitle("Kommandos");
|
||||
|
||||
foreach ($this->commands as $name => $command) {
|
||||
|
||||
$description = $command['description'] ?: 'Keine Beschreibung verfügbar';
|
||||
|
||||
$menu->addItem($name, function () use ($name) {
|
||||
return $this->executeCommand($name, [])->value;
|
||||
}, $description);
|
||||
#$this->output->writeLine(sprintf(" %-20s %s", $name, $description));
|
||||
}
|
||||
|
||||
$this->output->writeLine(" " . $menu->showInteractive());
|
||||
|
||||
$this->output->newLine();
|
||||
$this->output->writeLine("Verwendung:", ConsoleColor::BRIGHT_YELLOW);
|
||||
$this->output->writeLine(" php {$this->scriptName} <kommando> [argumente]");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user