diff --git a/core/control/ContentController.php b/core/control/ContentController.php index 8d50ea5f0..efc96270e 100755 --- a/core/control/ContentController.php +++ b/core/control/ContentController.php @@ -115,6 +115,54 @@ class ContentController extends Controller { } + /** + * This acts the same as {@link Controller::handleRequest()}, but if an action cannot be found this will attempt to + * fall over to a child controller in order to provide functionality for nested URLs. + * + * @return HTTPResponse + */ + public function handleRequest(HTTPRequest $request) { + $child = null; + $action = $request->param('Action'); + + // If nested URLs are enabled, and there is no action handler for the current request then attempt to pass + // control to a child controller. This allows for the creation of chains of controllers which correspond to a + // nested URL. + if($action && SiteTree::nested_urls() && !$this->hasAction($action)) { + Translatable::disable_locale_filter(); + + $child = DataObject::get_one('SiteTree', sprintf ( + "\"ParentID\" = %s AND \"URLSegment\" = '%s'", $this->ID, Convert::raw2sql($action) + )); + + Translatable::enable_locale_filter(); + } + + if($child) { + $request->shiftAllParams(); + $request->shift(); + + $response = ModelAsController::controller_for($child)->handleRequest($request); + } else { + Director::set_current_page($this->data()); + $response = parent::handleRequest($request); + Director::set_current_page(null); + } + + return $response; + } + + /** + * @uses ErrorPage::response_for() + */ + public function httpError($code, $message = null) { + if($this->request->isMedia() || !$response = ErrorPage::response_for($code)) { + parent::httpError($code, $message); + } else { + throw new HTTPResponse_Exception($response); + } + } + /** * Handles widgets attached to a page through one or more {@link WidgetArea} elements. * Iterated through each $has_one relation with a {@link WidgetArea} @@ -160,51 +208,6 @@ class ContentController extends Controller { return new $controllerClass($widget); } - - /** - * This acts the same as {@link Controller::handleRequest()}, but if an action cannot be found this will attempt to - * fall over to a child controller in order to provide functionality for nested URLs. - * - * @return HTTPResponse - */ - public function handleRequest(HTTPRequest $request) { - $child = null; - $action = $request->param('Action'); - - // If nested URLs are enabled, and there is no action handler for the current request then attempt to pass - // control to a child controller. This allows for the creation of chains of controllers which correspond to a - // nested URL. - if($action && SiteTree::nested_urls() && !$this->hasAction($action)) { - Translatable::disable_locale_filter(); - - $child = DataObject::get_one('SiteTree', sprintf ( - "\"ParentID\" = %s AND \"URLSegment\" = '%s'", $this->ID, Convert::raw2sql($action) - )); - - Translatable::enable_locale_filter(); - } - - if($child) { - $request->shiftAllParams(); - $request->shift(); - - $response = ModelAsController::controller_for($child)->handleRequest($request); - } else { - Director::set_current_page($this->data()); - $response = parent::handleRequest($request); - Director::set_current_page(null); - } - - return $response; - } - - /** - * @uses ErrorPage::response_for() - * @return HTTPResponse - */ - public function httpError($code, $message = null) { - return ($resp = ErrorPage::response_for($code, $this->request)) ? $resp : parent::httpError($code, $message); - } /** * Get the project name diff --git a/core/control/ModelAsController.php b/core/control/ModelAsController.php index 415e04bf5..b5adefffc 100755 --- a/core/control/ModelAsController.php +++ b/core/control/ModelAsController.php @@ -88,7 +88,7 @@ class ModelAsController extends Controller implements NestedController { return $this->response; } - if($response = ErrorPage::response_for(404, $this->request)) { + if($response = ErrorPage::response_for(404)) { return $response; } else { $this->httpError(404, 'The requested page could not be found.'); diff --git a/core/model/ErrorPage.php b/core/model/ErrorPage.php index b507921e0..912be55bc 100755 --- a/core/model/ErrorPage.php +++ b/core/model/ErrorPage.php @@ -25,43 +25,28 @@ class ErrorPage extends Page { protected static $static_filepath = ASSETS_PATH; /** - * Get a {@link HTTPResponse} that is suitable for responding to a reques that has thrown a specific error code. + * Get a {@link HTTPResponse} to response to a HTTP error code if an {@link ErrorPage} for that code is present. * - * @param int $statusCode The HTTP error code. - * @param HTTPRequest $request The request object that triggered the error. + * @param int $statusCode * @return HTTPResponse */ - public static function response_for($statusCode, HTTPRequest $request = null) { - $errorPage = null; - - // First attempt to dynamically generate the error page, then fall back on using a cached version. - if ( - (!$request || !$request->isMedia()) && !$errorPage = DataObject::get_one('ErrorPage', "\"ErrorCode\" = $statusCode") - ) { - $cachedPath = self::get_filepath_for_errorcode($statusCode, Translatable::get_current_locale()); - - if(file_exists($cachedPath)) { - $response = new HTTPResponse(); - - $response->setStatusCode($statusCode); - $response->setBody(file_get_contents($cachedPath)); - - return $response; - } + public static function response_for($statusCode) { + // first attempt to dynamically generate the error page + if($errorPage = DataObject::get_one('ErrorPage', "\"ErrorCode\" = $statusCode")) { + return ModelAsController::controller_for($errorPage)->handleRequest(new HTTPRequest('GET', '')); } - // If the request is for a simple media type, or there was no matching dynamic or cached error page just return - // a simple error string to avoid clogging up server resources. - if(!$errorPage) { - $response = new HTTPResponse(); + // then fall back on a cached version + $cachedPath = self::get_filepath_for_errorcode($statusCode, Translatable::get_current_locale()); + + if(file_exists($cachedPath)) { + $response = new HTTPResponse(); $response->setStatusCode($statusCode); - $response->setBody(sprintf('Error %s: %s', $response->getStatusCode(), $response->getStatusDescription())); + $response->setBody(file_get_contents($cachedPath)); return $response; } - - return ModelAsController::controller_for($errorPage)->handleRequest(new HTTPRequest('GET', '')); } /**