Files
michaelschiemer/src/Framework/Console/CommandList.php
Michael Schiemer 9b74ade5b0 feat: Fix discovery system critical issues
Resolved multiple critical discovery system issues:

## Discovery System Fixes
- Fixed console commands not being discovered on first run
- Implemented fallback discovery for empty caches
- Added context-aware caching with separate cache keys
- Fixed object serialization preventing __PHP_Incomplete_Class

## Cache System Improvements
- Smart caching that only caches meaningful results
- Separate caches for different execution contexts (console, web, test)
- Proper array serialization/deserialization for cache compatibility
- Cache hit logging for debugging and monitoring

## Object Serialization Fixes
- Fixed DiscoveredAttribute serialization with proper string conversion
- Sanitized additional data to prevent object reference issues
- Added fallback for corrupted cache entries

## Performance & Reliability
- All 69 console commands properly discovered and cached
- 534 total discovery items successfully cached and restored
- No more __PHP_Incomplete_Class cache corruption
- Improved error handling and graceful fallbacks

## Testing & Quality
- Fixed code style issues across discovery components
- Enhanced logging for better debugging capabilities
- Improved cache validation and error recovery

Ready for production deployment with stable discovery system.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-13 12:04:17 +02:00

116 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Console;
use App\Framework\Exception\ErrorCode;
use App\Framework\Exception\FrameworkException;
use ArrayIterator;
use Countable;
use IteratorAggregate;
use Traversable;
/**
* Value Object für die Verwaltung von Console Commands
*/
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(
ErrorCode::CON_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(
ErrorCode::CON_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(
ErrorCode::CON_COMMAND_NOT_FOUND,
"Command '{$name}' not found"
)->withData(['command_name' => $name]);
}
return $this->commands[$name];
}
public function getNames(): array
{
return array_keys($this->commands);
}
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);
}
public function toArray(): array
{
return $this->commands;
}
public function isEmpty(): bool
{
return empty($this->commands);
}
}