/** * Handle Exception * By default this function will just print the error. Override this function to change the behaviour * @return string */ public function handleException(HTTPResponseException $exception) { if (isset($this->_application)) { return $this->_application->handleException($exception); } return $exception->getMessage(); }
/** * Route * @param HTTPRequest | string $request * @param HTTPResponse $response * @return VOID */ public static function route($request, HTTPResponse &$response = null) { //GET / POST etc. $requestMethod = isset($_SERVER['X-HTTP-Method-Override']) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD']; // IIS will sometimes generate this. if (!empty($_SERVER['HTTP_X_ORIGINAL_URL'])) { $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_ORIGINAL_URL']; } $url = is_string($request) ? $request : preg_replace("/^\\/" . str_replace("/", "\\/?", WORKING_DIR) . "/", '', $_SERVER["REQUEST_URI"]); if (strpos($url, '?') !== false) { list($url, $query) = explode('?', $url, 2); parse_str($query, $_GET); if ($_GET) { $_REQUEST = array_merge((array) $_REQUEST, (array) $_GET); } } // Pass back to the webserver for files that exist if (php_sapi_name() == 'cli-server') { $realFile = File::create([BASE_PATH, 'public_html', $url]); if ($realFile->isFile() && $realFile->exists()) { //Can't return false this far up, read file instead. readfile($realFile->path); exit; } } //Remove base folders from the URL if webroot is hosted in a subfolder if (substr(strtolower($url), 0, strlen(BASE_PATH)) == strtolower(BASE_PATH)) { $url = substr($url, strlen(BASE_PATH)); } $response = $response ?: HTTPResponse::create(); if (!$request instanceof HTTPRequest) { $request = HTTPRequest::create($requestMethod, $url)->setMainRequest(true); } SessionStore::ageFlash(); if (!static::handleRequest($request, $response)) { try { //Get Dispatchable if (!static::$dispatch) { $dispatchNamespace = static::config()->get("project")->get("namespace", ""); $dispatch = $dispatchNamespace . '\\' . $dispatchNamespace . 'App'; if (substr($dispatch, 0, 1) != '\\') { $dispatch = '\\' . $dispatch; } if (class_exists($dispatch)) { if (!static::$dispatch) { static::$dispatch = $dispatch::create(); static::$dispatch->setConfig(static::config())->init(); } } else { $e = new HTTPResponseException("Could not load project", 404); //Error responses should be considered plain text for security reasons. $e->response()->setHeader('Content-Type', 'text/plain'); throw $e; } } static::$dispatch->handleRequest($request, $response); } catch (HTTPResponseException $e) { $response->setStatusCode($e->getCode(), $e->getMessage()); $response->setBody(static::$dispatch ? static::$dispatch->handleException($e) : $e->getMessage()); } } //TODO: It would be good for this to reside in $response->render() - But would need access to $request. if ((!$response->isError() && !$response->hasFinished() || $response->statusCode() === 401) && $request->isMainRequest() && !$request->isAjax()) { if (strpos($response->getHeader("Content-Type"), "text/html") === 0) { static::setRouteHistory(static::buildParams($request->url(), $_GET)); } } if (static::isDev()) { error_log(sprintf("%s [%d]: %s - %s", $requestMethod, $response->statusCode(), $url, $response->statusDescription()), 4); } return $response; }