path = new class () { public function toString(): string { return '/test'; } }; $this->method = new class () { public $value = 'GET'; }; $this->server = new class () { public function getUserAgent() { return new class () { public function toString(): string { return 'Test Agent'; } }; } public function getClientIp() { return new class () { public function __toString(): string { return '127.0.0.1'; } }; } }; } }; $mockResponse = new class () { public $statusCode = 200; public $body = 'Test Response'; public $headers = ['Content-Type' => 'text/html']; }; echo " ✅ Testing BeforeHandleRequest Event:\n"; $beforeEvent = new BeforeHandleRequest( request: $mockRequest, context: [ 'route' => '/test', 'method' => 'GET', 'user_agent' => 'Test Agent', 'client_ip' => '127.0.0.1', ] ); echo " • Timestamp: {$beforeEvent->timestamp->format('H:i:s.u')}\n"; echo " • Context keys: " . implode(', ', array_keys($beforeEvent->context)) . "\n\n"; echo " ✅ Testing AfterHandleRequest Event:\n"; $afterEvent = new AfterHandleRequest( request: $mockRequest, response: $mockResponse, processingTime: Duration::fromMilliseconds(45.7), context: [ 'status_code' => 200, 'content_length' => 13, 'memory_peak' => 1024000, ] ); echo " • Processing time: {$afterEvent->processingTime->toHumanReadable()}\n"; echo " • Timestamp: {$afterEvent->timestamp->format('H:i:s.u')}\n\n"; echo " ✅ Testing BeforeRouteMatching Event:\n"; $routeBeforeEvent = new BeforeRouteMatching( request: $mockRequest, context: ['pattern_count' => 25] ); echo " • Timestamp: {$routeBeforeEvent->timestamp->format('H:i:s.u')}\n"; echo " ✅ Testing AfterRouteMatching Event:\n"; $routeAfterEvent = new AfterRouteMatching( request: $mockRequest, routeName: 'api.users.show', routeParameters: ['id' => '123'], matchingTime: Duration::fromMicroseconds(150), context: ['matched_patterns' => 3] ); echo " • Route name: {$routeAfterEvent->routeName}\n"; echo " • Matching time: {$routeAfterEvent->matchingTime->toHumanReadable()}\n"; echo " • Parameters: " . json_encode($routeAfterEvent->routeParameters) . "\n\n"; echo " ✅ Testing BeforeControllerExecution Event:\n"; $controllerBeforeEvent = new BeforeControllerExecution( request: $mockRequest, controllerClass: ClassName::create('App\\Application\\Api\\UserController'), methodName: MethodName::create('show'), parameters: ['id' => '123'], context: ['auth_user' => 'user_456'] ); echo " • Controller: {$controllerBeforeEvent->controllerClass->getShortName()}\n"; echo " • Method: {$controllerBeforeEvent->methodName->toString()}\n"; echo " • Parameters: " . json_encode($controllerBeforeEvent->parameters) . "\n\n"; echo " ✅ Testing AfterControllerExecution Event:\n"; $controllerAfterEvent = new AfterControllerExecution( request: $mockRequest, response: $mockResponse, controllerClass: ClassName::create('App\\Application\\Api\\UserController'), methodName: MethodName::create('show'), executionTime: Duration::fromMilliseconds(23.4), context: ['db_queries' => 2, 'cache_hits' => 1] ); echo " • Execution time: {$controllerAfterEvent->executionTime->toHumanReadable()}\n"; echo " • DB queries: {$controllerAfterEvent->context['db_queries']}\n\n"; echo " ✅ Testing BeforeMiddlewareExecution Event:\n"; $middlewareBeforeEvent = new BeforeMiddlewareExecution( request: $mockRequest, middlewareClass: ClassName::create('App\\Framework\\Http\\Middlewares\\AuthMiddleware'), priority: 100, context: ['middleware_chain_position' => 2] ); echo " • Middleware: {$middlewareBeforeEvent->middlewareClass->getShortName()}\n"; echo " • Priority: {$middlewareBeforeEvent->priority}\n\n"; echo " ✅ Testing AfterMiddlewareExecution Event:\n"; $middlewareAfterEvent = new AfterMiddlewareExecution( request: $mockRequest, response: $mockResponse, middlewareClass: ClassName::create('App\\Framework\\Http\\Middlewares\\AuthMiddleware'), executionTime: Duration::fromMicroseconds(850), context: ['auth_checks' => 1, 'headers_added' => 2] ); echo " • Execution time: {$middlewareAfterEvent->executionTime->toHumanReadable()}\n"; echo " • Headers added: {$middlewareAfterEvent->context['headers_added']}\n\n"; } catch (\Throwable $e) { echo " ❌ Error: {$e->getMessage()}\n\n"; } echo "2. Testing Timestamp and Duration Value Objects:\n"; try { $start = Timestamp::now(); usleep(1000); // 1ms delay $end = Timestamp::now(); $duration = $start->diff($end); echo " ✅ Timestamp calculations:\n"; echo " • Start: {$start->format('H:i:s.u')}\n"; echo " • End: {$end->format('H:i:s.u')}\n"; echo " • Duration: {$duration->toHumanReadable()}\n"; echo " • Duration (microseconds): {$duration->toMicroseconds()}\n\n"; echo " ✅ Duration factory methods:\n"; $durations = [ 'Microseconds' => Duration::fromMicroseconds(500), 'Milliseconds' => Duration::fromMilliseconds(45.7), 'Seconds' => Duration::fromSeconds(2.5), 'Minutes' => Duration::fromMinutes(1.5), ]; foreach ($durations as $type => $duration) { echo " • {$type}: {$duration->toHumanReadable()}\n"; } echo "\n"; } catch (\Throwable $e) { echo " ❌ Error: {$e->getMessage()}\n\n"; } echo "3. Testing ClassName and MethodName Value Objects:\n"; try { $className = ClassName::create('App\\Framework\\Http\\Middlewares\\AuthenticationMiddleware'); $methodName = MethodName::create('handle'); echo " ✅ ClassName operations:\n"; echo " • Full name: {$className->getFullyQualified()}\n"; echo " • Short name: {$className->getShortName()}\n"; echo " • Namespace: {$className->getNamespace()}\n\n"; echo " ✅ MethodName operations:\n"; echo " • Method name: {$methodName->toString()}\n"; echo " • Is magic method: " . ($methodName->isMagicMethod() ? 'Yes' : 'No') . "\n\n"; $magicMethod = MethodName::construct(); echo " ✅ Magic method example:\n"; echo " • Method: {$magicMethod->toString()}\n"; echo " • Is magic: " . ($magicMethod->isMagicMethod() ? 'Yes' : 'No') . "\n\n"; } catch (\Throwable $e) { echo " ❌ Error: {$e->getMessage()}\n\n"; } echo "=== Request Lifecycle Hooks Test Completed ===\n";