Files
michaelschiemer/src/Framework/Console/CommandList.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- 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.
2025-10-25 19:18:37 +02:00

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);
}
}