Hi there,
I have a weird situation where a request for non-existent page doesn't send the visitor to the 404 Error page but instead to a parent page.
For example, a request is made for:
/understanding/analytes/xyz.
'xyz' is a non-existent (or a unpublished page). Normally the visitor should be sent to the 404 page, but instead is sent to the 'analytes' page, which is an existing page that is, of course, the parent of 'xyz'. I think the reason for this is that the Director rule:
'$URLSegment//$Action/$ID/$OtherID' => 'ModelAsController
in sapphire/_config.php, is matched, where
$URLSegment = /understanding/analytes/
$Action = xyz
$ID = null
$OtherID = null
Instead of redirecting to the 404 page, I think SilverStripe is looking for a method called 'xyz' in the page type for /understanding/analytes. However, /understanding/analytes is a RedirectorPage and since its init() method is the first thing executed, the user is sent to the redirect page.
I need to figure out how to create a subclass of RedirectorPage that when an Action param exists in the url, send the user to the 404 page instead of redirecting to the intended page. If an Action param doesn't exist, execute the normal redirect behavior.
I tried the following subclass code but got the error below:
class Redirector404Page extends RedirectorPage {}
class Redirector404Page_Controller extends RedirectorPage_Controller {
function init() {
$action = $this->request->param('Action');
if ($action) {
Director::redirect('/page-not-found', 404);
}
parent::init();
}
}
Error message:
[User Warning] Already directed to /page-not-found; now trying to direct to /map/aindex/
GET /understanding/analytes/abc/def?debug_request=1
Line 464 in /Users/steve/__projects/lto_ss/us/silverstripe-us/sapphire/core/control/Controller.php
Source
455 }
456 }
457
458 /**
459 * Redirct to the given URL.
460 * It is generally recommended to call Director::redirect() rather than calling this function directly.
461 */
462 function redirect($url, $code=302) {
463 if($this->response->getHeader('Location')) {
464 user_error("Already directed to " . $this->response->getHeader('Location') . "; now trying to direct to $url", E_USER_WARNING);
465 return;
466 }
467
468 // Attach site-root to relative links, if they have a slash in them
469 if($url == "" || $url[0] == '?' || (substr($url,0,4) != "http" && $url[0] != "/" && strpos($url,'/') !== false)){
470 $url = Director::baseURL() . $url;
Trace
Already directed to /page-not-found; now trying to direct to /map/aindex/
Line 464 of Controller.php
Controller->redirect(/map/aindex/,301)
Line 410 of Director.php
Director::redirect(/map/aindex/,301)
Line 159 of RedirectorPage.php
RedirectorPage_Controller->init()
Line 26 of Redirector404Page.php
Redirector404Page_Controller->init()
Line 136 of Controller.php
Controller->handleRequest(SS_HTTPRequest)
Line 199 of ContentController.php
ContentController->handleRequest(SS_HTTPRequest)
Line 184 of ContentController.php
ContentController->handleRequest(SS_HTTPRequest)
Line 67 of ModelAsController.php
ModelAsController->handleRequest(SS_HTTPRequest)
Line 282 of Director.php
Director::handleRequest(SS_HTTPRequest,Session)
Line 125 of Director.php
Director::direct(/understanding/analytes/xyz)
Line 127 of main.php
Can anyone help with advice on what code I can use in this subclass' init() method to send the user to a 404 page if an Action param exists?
Also, if there is a solution, is there away to specify the 404 error page, without hardcoding it with its URLSegment, /page-not-found?
thanks!