- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
134 lines
3.2 KiB
PHP
134 lines
3.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Console;
|
|
|
|
use App\Framework\Exception\Core\ConsoleErrorCode;
|
|
use App\Framework\Exception\FrameworkException;
|
|
use ArrayIterator;
|
|
use Countable;
|
|
use IteratorAggregate;
|
|
use Traversable;
|
|
|
|
/**
|
|
* Value Object für die Verwaltung von Console Commands
|
|
* @implements IteratorAggregate<string, ConsoleCommand>
|
|
*/
|
|
final readonly class CommandList implements IteratorAggregate, Countable
|
|
{
|
|
/** @var array<string, ConsoleCommand> */
|
|
private array $commands;
|
|
|
|
public function __construct(ConsoleCommand ...$commands)
|
|
{
|
|
$commandMap = [];
|
|
|
|
foreach ($commands as $command) {
|
|
if (isset($commandMap[$command->name])) {
|
|
throw FrameworkException::create(
|
|
ConsoleErrorCode::INVALID_COMMAND_STRUCTURE,
|
|
"Duplicate command name '{$command->name}'"
|
|
)->withData(['command_name' => $command->name]);
|
|
}
|
|
|
|
$commandMap[$command->name] = $command;
|
|
}
|
|
|
|
$this->commands = $commandMap;
|
|
}
|
|
|
|
public static function empty(): self
|
|
{
|
|
return new self();
|
|
}
|
|
|
|
public function add(ConsoleCommand $command): self
|
|
{
|
|
if ($this->has($command->name)) {
|
|
throw FrameworkException::create(
|
|
ConsoleErrorCode::INVALID_COMMAND_STRUCTURE,
|
|
"Command '{$command->name}' already exists"
|
|
)->withData(['command_name' => $command->name]);
|
|
}
|
|
|
|
$allCommands = array_values($this->commands);
|
|
$allCommands[] = $command;
|
|
|
|
return new self(...$allCommands);
|
|
}
|
|
|
|
public function has(string $name): bool
|
|
{
|
|
return isset($this->commands[$name]);
|
|
}
|
|
|
|
public function get(string $name): ConsoleCommand
|
|
{
|
|
if (! $this->has($name)) {
|
|
throw FrameworkException::create(
|
|
ConsoleErrorCode::COMMAND_NOT_FOUND,
|
|
"Command '{$name}' not found"
|
|
)->withData(['command_name' => $name]);
|
|
}
|
|
|
|
return $this->commands[$name];
|
|
}
|
|
|
|
/**
|
|
* @return array<int, string>
|
|
*/
|
|
public function getNames(): array
|
|
{
|
|
return array_keys($this->commands);
|
|
}
|
|
|
|
/**
|
|
* @return array<int, string>
|
|
*/
|
|
public function findSimilar(string $name, int $maxDistance = 3): array
|
|
{
|
|
$suggestions = [];
|
|
|
|
foreach ($this->getNames() as $commandName) {
|
|
$distance = levenshtein($name, $commandName);
|
|
if ($distance <= $maxDistance && $distance > 0) {
|
|
$suggestions[] = $commandName;
|
|
}
|
|
}
|
|
|
|
return $suggestions;
|
|
}
|
|
|
|
public function count(): int
|
|
{
|
|
return count($this->commands);
|
|
}
|
|
|
|
public function getIterator(): Traversable
|
|
{
|
|
return new ArrayIterator($this->commands);
|
|
}
|
|
|
|
/**
|
|
* @return array<string, ConsoleCommand>
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
return $this->commands;
|
|
}
|
|
|
|
/**
|
|
* @return array<int, ConsoleCommand>
|
|
*/
|
|
public function getAllCommands(): array
|
|
{
|
|
return array_values($this->commands);
|
|
}
|
|
|
|
public function isEmpty(): bool
|
|
{
|
|
return empty($this->commands);
|
|
}
|
|
}
|