toString(); if (isset($this->cache[$key])) { $results[$key] = CacheItem::hit($identifier, $this->cache[$key]); } else { $results[$key] = CacheItem::miss($identifier); } } return CacheResult::fromItems(...array_values($results)); } public function set(CacheItem ...$items): bool { foreach ($items as $item) { $this->cache[$item->key->toString()] = $item->value; } return true; } public function forget(CacheIdentifier ...$identifiers): bool { foreach ($identifiers as $identifier) { unset($this->cache[$identifier->toString()]); } return true; } public function clear(): bool { $this->cache = []; return true; } public function remember(CacheKey $key, callable $callback, ?Duration $ttl = null): CacheItem { $keyStr = $key->toString(); if (isset($this->cache[$keyStr])) { return CacheItem::hit($key, $this->cache[$keyStr]); } $value = $callback(); $this->cache[$keyStr] = $value; return CacheItem::hit($key, $value); } public function has(CacheIdentifier ...$identifiers): array { $results = []; foreach ($identifiers as $identifier) { $results[$identifier->toString()] = isset($this->cache[$identifier->toString()]); } return $results; } } use App\Framework\Config\Environment; use App\Framework\Core\PathProvider; use App\Framework\DateTime\Clock; use App\Framework\DateTime\SystemClock; use App\Framework\DI\DefaultContainer; use App\Framework\Discovery\DiscoveryServiceBootstrapper; use App\Framework\Discovery\InitializerProcessor; use App\Framework\Logging\Logger; use App\Framework\Logging\LogLevel; // Simple array logger for testing class TestArrayLogger implements Logger { private array $messages = []; public function getMessages(): array { return $this->messages; } public function debug(string $message, array $context = []): void { $this->messages[] = ['level' => 'debug', 'message' => $message, 'context' => $context]; } public function info(string $message, array $context = []): void { $this->messages[] = ['level' => 'info', 'message' => $message, 'context' => $context]; } public function notice(string $message, array $context = []): void { $this->messages[] = ['level' => 'notice', 'message' => $message, 'context' => $context]; } public function warning(string $message, array $context = []): void { $this->messages[] = ['level' => 'warning', 'message' => $message, 'context' => $context]; } public function error(string $message, array $context = []): void { $this->messages[] = ['level' => 'error', 'message' => $message, 'context' => $context]; } public function critical(string $message, array $context = []): void { $this->messages[] = ['level' => 'critical', 'message' => $message, 'context' => $context]; } public function alert(string $message, array $context = []): void { $this->messages[] = ['level' => 'alert', 'message' => $message, 'context' => $context]; } public function emergency(string $message, array $context = []): void { $this->messages[] = ['level' => 'emergency', 'message' => $message, 'context' => $context]; } public function log(LogLevel $level, string $message, array $context = []): void { $this->messages[] = ['level' => $level->value, 'message' => $message, 'context' => $context]; } } use App\Framework\Context\ExecutionContext; use App\Framework\Reflection\CachedReflectionProvider; use App\Framework\Reflection\ReflectionProvider; echo "=== Discovery System Debug Test ===\n"; // Setup basic services $container = new DefaultContainer(); $logger = new TestArrayLogger(); $cache = new TestCache(); $clock = new SystemClock(); $pathProvider = new PathProvider(__DIR__ . '/../..'); $reflectionProvider = new CachedReflectionProvider(); $environment = new Environment(); $executionContext = ExecutionContext::detect(); // Register required services $container->singleton(TestArrayLogger::class, $logger); $container->singleton(Logger::class, $logger); $container->singleton(TestCache::class, $cache); $container->singleton(Cache::class, $cache); $container->singleton(Clock::class, $clock); $container->singleton(PathProvider::class, $pathProvider); $container->singleton(ReflectionProvider::class, $reflectionProvider); $container->singleton(Environment::class, $environment); $container->singleton(ExecutionContext::class, $executionContext); // Create InitializerProcessor $initializerProcessor = new InitializerProcessor( $container, $reflectionProvider, $executionContext ); $container->singleton(InitializerProcessor::class, $initializerProcessor); echo "Step 1: Creating Discovery Service Bootstrapper...\n"; // Create Discovery Service $discoveryBootstrapper = new DiscoveryServiceBootstrapper($container, $clock); echo "Step 2: Clearing cache to force fresh discovery...\n"; // Clear cache to force fresh discovery $cache->clear(); echo "Step 3: Running Discovery bootstrap...\n"; try { $registry = $discoveryBootstrapper->bootstrap(); echo "Step 4: Discovery completed successfully!\n"; echo "Registry contains " . count($registry) . " items\n"; // Check for Request interface binding echo "\nStep 5: Checking container bindings...\n"; $requestInterface = 'App\Framework\Http\Request'; $hasRequestBinding = $container->has($requestInterface); echo "Request interface binding exists: " . ($hasRequestBinding ? "YES" : "NO") . "\n"; if ($hasRequestBinding) { try { $requestInstance = $container->get($requestInterface); echo "Request instance created: " . get_class($requestInstance) . "\n"; } catch (Throwable $e) { echo "Error creating Request instance: " . $e->getMessage() . "\n"; } } // Show discovered attributes echo "\nStep 6: Discovered attribute types:\n"; if (isset($registry->attributes)) { // Use reflection to access the attribute data $reflection = new \ReflectionObject($registry->attributes); $property = $reflection->getProperty('mappings'); $property->setAccessible(true); $mappings = $property->getValue($registry->attributes); foreach ($mappings as $type => $attributes) { $count = count($attributes); echo "- {$type}: {$count} instances\n"; } } // Show discovered initializers specifically echo "\nStep 7: Discovered Initializers:\n"; if (isset($registry->attributes)) { $initializerResults = $registry->attributes->get(\App\Framework\DI\Initializer::class); echo "Found " . count($initializerResults) . " initializers:\n"; foreach ($initializerResults as $idx => $discoveredAttribute) { echo " {$idx}: {$discoveredAttribute->className}::{$discoveredAttribute->methodName}\n"; // Check additional data if ($discoveredAttribute->additionalData) { $returnType = $discoveredAttribute->additionalData['return'] ?? 'unknown'; echo " -> Returns: {$returnType}\n"; } } } echo "\nStep 8: Discovery log messages:\n"; foreach ($logger->getMessages() as $message) { echo "[{$message['level']}] {$message['message']}\n"; if (! empty($message['context'])) { echo " Context: " . json_encode($message['context'], JSON_PRETTY_PRINT) . "\n"; } } } catch (Throwable $e) { echo "Discovery failed with error: " . $e->getMessage() . "\n"; echo "Stack trace:\n" . $e->getTraceAsString() . "\n"; echo "\nDebug log messages:\n"; foreach ($logger->getMessages() as $message) { echo "[{$message['level']}] {$message['message']}\n"; if (! empty($message['context'])) { echo " Context: " . json_encode($message['context'], JSON_PRETTY_PRINT) . "\n"; } } } echo "\n=== Debug Test Complete ===\n";