Example #1
0
 /**
  * Dispatch a HTTP request to a front controller.
  * @return void
  */
 public function run()
 {
     $httpRequest = $this->getHttpRequest();
     $httpResponse = $this->getHttpResponse();
     $httpRequest->setEncoding('UTF-8');
     // autostarts session
     $session = $this->getSession();
     if (!$session->isStarted() && $session->exists()) {
         $session->start();
     }
     // check HTTP method
     if ($this->allowedMethods) {
         $method = $httpRequest->getMethod();
         if (!in_array($method, $this->allowedMethods, TRUE)) {
             $httpResponse->setCode(Nette\Web\IHttpResponse::S501_NOT_IMPLEMENTED);
             $httpResponse->setHeader('Allow', implode(',', $this->allowedMethods));
             echo '<h1>Method ' . htmlSpecialChars($method) . ' is not implemented</h1>';
             return;
         }
     }
     // dispatching
     $request = NULL;
     $repeatedError = FALSE;
     do {
         try {
             if (count($this->requests) > self::$maxLoop) {
                 throw new ApplicationException('Too many loops detected in application life cycle.');
             }
             if (!$request) {
                 $this->onStartup($this);
                 // default router
                 if ($this->context->hasService('Nette\\Application\\IRouter', TRUE)) {
                     $router = $this->getRouter();
                 } else {
                     $this->setRouter($router = $this->context->getService('defaultRouter'));
                 }
                 // enable routing debuggger
                 Nette\Debug::addPanel(new RoutingDebugger($router, $httpRequest));
                 // routing
                 $request = $router->match($httpRequest);
                 if (!$request instanceof PresenterRequest) {
                     $request = NULL;
                     throw new BadRequestException('No route for HTTP request.');
                 }
                 if (strcasecmp($request->getPresenterName(), $this->errorPresenter) === 0) {
                     throw new BadRequestException('Invalid request.');
                 }
             }
             $this->requests[] = $request;
             $this->onRequest($this, $request);
             // Instantiate presenter
             $presenter = $request->getPresenterName();
             try {
                 $class = $this->getPresenterLoader()->getPresenterClass($presenter);
                 $request->setPresenterName($presenter);
             } catch (InvalidPresenterException $e) {
                 throw new BadRequestException($e->getMessage(), 404, $e);
             }
             $request->freeze();
             // Execute presenter
             $this->presenter = new $class();
             $response = $this->presenter->run($request);
             // Send response
             if ($response instanceof ForwardingResponse) {
                 $request = $response->getRequest();
                 continue;
             } elseif ($response instanceof IPresenterResponse) {
                 $response->send();
             }
             break;
         } catch (\Exception $e) {
             // fault barrier
             $this->onError($this, $e);
             if (!$this->catchExceptions) {
                 $this->onShutdown($this, $e);
                 throw $e;
             }
             if ($repeatedError) {
                 $e = new ApplicationException('An error occured while executing error-presenter', 0, $e);
             }
             if (!$httpResponse->isSent()) {
                 $httpResponse->setCode($e instanceof BadRequestException ? $e->getCode() : 500);
             }
             if (!$repeatedError && $this->errorPresenter) {
                 $repeatedError = TRUE;
                 if ($this->presenter) {
                     try {
                         $this->presenter->forward(":{$this->errorPresenter}:", array('exception' => $e));
                     } catch (AbortException $foo) {
                         $request = $this->presenter->getLastCreatedRequest();
                     }
                 } else {
                     $request = new PresenterRequest($this->errorPresenter, PresenterRequest::FORWARD, array('exception' => $e));
                 }
                 // continue
             } else {
                 // default error handler
                 if ($e instanceof BadRequestException) {
                     $code = $e->getCode();
                 } else {
                     $code = 500;
                     Nette\Debug::log($e);
                 }
                 echo "<!DOCTYPE html><meta name=robots content=noindex><meta name=generator content='Nette Framework'>\n\n";
                 echo "<style>body{color:#333;background:white;width:500px;margin:100px auto}h1{font:bold 47px/1.5 sans-serif;margin:.6em 0}p{font:21px/1.5 Georgia,serif;margin:1.5em 0}small{font-size:70%;color:gray}</style>\n\n";
                 static $messages = array(0 => array('Oops...', 'Your browser sent a request that this server could not understand or process.'), 403 => array('Access Denied', 'You do not have permission to view this page. Please try contact the web site administrator if you believe you should be able to view this page.'), 404 => array('Page Not Found', 'The page you requested could not be found. It is possible that the address is incorrect, or that the page no longer exists. Please use a search engine to find what you are looking for.'), 405 => array('Method Not Allowed', 'The requested method is not allowed for the URL.'), 410 => array('Page Not Found', 'The page you requested has been taken off the site. We apologize for the inconvenience.'), 500 => array('Server Error', 'We\'re sorry! The server encountered an internal error and was unable to complete your request. Please try again later.'));
                 $message = isset($messages[$code]) ? $messages[$code] : $messages[0];
                 echo "<title>{$message['0']}</title>\n\n<h1>{$message['0']}</h1>\n\n<p>{$message['1']}</p>\n\n";
                 if ($code) {
                     echo "<p><small>error {$code}</small></p>";
                 }
                 break;
             }
         }
     } while (1);
     $this->onShutdown($this, isset($e) ? $e : NULL);
 }