app = $app; $this->setRunner(new Runner()); } /** * Run the request/response through the Application and its middleware. * * This will invoke the following methods: * * - App->bootstrap() - Perform any bootstrapping logic for your application here. * - App->middleware() - Attach any application middleware here. * - Trigger the 'Server.buildMiddleware' event. You can use this to modify the * from event listeners. * - Run the middleware queue including the application. * * @param \Psr\Http\Message\ServerRequestInterface|null $request The request to use or null. * @param \Psr\Http\Message\ResponseInterface|null $response The response to use or null. * @return \Psr\Http\Message\ResponseInterface * @throws \RuntimeException When the application does not make a response. */ public function run(ServerRequestInterface $request = null, ResponseInterface $response = null) { $this->bootstrap(); $response = $response ?: new Response(); $request = $request ?: ServerRequestFactory::fromGlobals(); $middleware = $this->app->middleware(new MiddlewareQueue()); if ($this->app instanceof PluginApplicationInterface) { $middleware = $this->app->pluginMiddleware($middleware); } if (!($middleware instanceof MiddlewareQueue)) { throw new RuntimeException('The application `middleware` method did not return a middleware queue.'); } $this->dispatchEvent('Server.buildMiddleware', ['middleware' => $middleware]); $middleware->add($this->app); $response = $this->runner->run($middleware, $request, $response); if (!($response instanceof ResponseInterface)) { throw new RuntimeException(sprintf( 'Application did not create a response. Got "%s" instead.', is_object($response) ? get_class($response) : $response )); } return $response; } /** * Application bootstrap wrapper. * * Calls `bootstrap()` and `events()` if application implements `EventApplicationInterface`. * After the application is bootstrapped and events are attached, plugins are bootstrapped * and have their events attached. * * @return void */ protected function bootstrap() { $this->app->bootstrap(); if ($this->app instanceof PluginApplicationInterface) { $this->app->pluginBootstrap(); } } /** * Emit the response using the PHP SAPI. * * @param \Psr\Http\Message\ResponseInterface $response The response to emit * @param \Zend\Diactoros\Response\EmitterInterface|null $emitter The emitter to use. * When null, a SAPI Stream Emitter will be used. * @return void */ public function emit(ResponseInterface $response, EmitterInterface $emitter = null) { if (!$emitter) { $emitter = new ResponseEmitter(); } $emitter->emit($response); } /** * Get the current application. * * @return \Cake\Core\HttpApplicationInterface The application that will be run. */ public function getApp() { return $this->app; } /** * Set the runner * * @param \Cake\Http\Runner $runner The runner to use. * @return $this */ public function setRunner(Runner $runner) { $this->runner = $runner; return $this; } /** * Get the application's event manager or the global one. * * @return \Cake\Event\EventManager */ public function getEventManager() { if ($this->app instanceof PluginApplicationInterface) { return $this->app->getEventManager(); } return EventManager::instance(); } /** * Get/set the application's event manager. * * If the application does not support events and this method is used as * a setter, an exception will be raised. * * @param \Cake\Event\EventManager|null $events The event manager to set. * @return \Cake\Event\EventManager|$this * @deprecated 3.6.0 Will be removed in 4.0 */ public function eventManager(EventManager $events = null) { deprecationWarning('eventManager() is deprecated. Use getEventManager()/setEventManager() instead.'); if ($events === null) { return $this->getEventManager(); } return $this->setEventManager($events); } /** * Get/set the application's event manager. * * If the application does not support events and this method is used as * a setter, an exception will be raised. * * @param \Cake\Event\EventManager $events The event manager to set. * @return $this */ public function setEventManager(EventManager $events) { if ($this->app instanceof PluginApplicationInterface) { $this->app->setEventManager($events); return $this; } throw new InvalidArgumentException('Cannot set the event manager, the application does not support events.'); } }