mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API CHANGE #2922: RequestHandler:: now inherit
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@64958 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
cd699e3d89
commit
132957b5c2
@ -77,58 +77,68 @@ class RequestHandler extends ViewableData {
|
|||||||
function handleRequest($request) {
|
function handleRequest($request) {
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
|
|
||||||
foreach($this->stat('url_handlers') as $rule => $action) {
|
// $handlerClass is used to step up the class hierarchy to implement url_handlers inheritance
|
||||||
if(isset($_REQUEST['debug_request'])) Debug::message("Testing '$rule' with '" . $request->remaining() . "' on $this->class");
|
$handlerClass = $this->class;
|
||||||
if($params = $request->match($rule, true)) {
|
// We stop after RequestHandler; in other words, at ViewableData
|
||||||
// FIXME: This unnecessary coupling was added to fix a bug in Image_Uploader.
|
while($handlerClass != 'ViewableData') {
|
||||||
if($this instanceof Controller) $this->urlParams = $request->allParams();
|
// Todo: ajshort's stat rewriting could be useful here.
|
||||||
|
$urlHandlers = eval("return $handlerClass::\$url_handlers;");
|
||||||
|
|
||||||
|
if($urlHandlers) foreach($urlHandlers as $rule => $action) {
|
||||||
|
if(isset($_REQUEST['debug_request'])) Debug::message("Testing '$rule' with '" . $request->remaining() . "' on $this->class");
|
||||||
|
if($params = $request->match($rule, true)) {
|
||||||
|
// FIXME: This unnecessary coupling was added to fix a bug in Image_Uploader.
|
||||||
|
if($this instanceof Controller) $this->urlParams = $request->allParams();
|
||||||
|
|
||||||
if(isset($_REQUEST['debug_request'])) {
|
if(isset($_REQUEST['debug_request'])) {
|
||||||
Debug::message("Rule '$rule' matched to action '$action' on $this->class. Latest request params: " . var_export($request->latestParams(), true));
|
Debug::message("Rule '$rule' matched to action '$action' on $this->class. Latest request params: " . var_export($request->latestParams(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actions can reference URL parameters, eg, '$Action/$ID/$OtherID' => '$Action',
|
// Actions can reference URL parameters, eg, '$Action/$ID/$OtherID' => '$Action',
|
||||||
if($action[0] == '$') $action = $params[substr($action,1)];
|
if($action[0] == '$') $action = $params[substr($action,1)];
|
||||||
|
|
||||||
if($this->checkAccessAction($action)) {
|
if($this->checkAccessAction($action)) {
|
||||||
if(!$action) {
|
if(!$action) {
|
||||||
if(isset($_REQUEST['debug_request'])) Debug::message("Action not set; using default action method name 'index'");
|
if(isset($_REQUEST['debug_request'])) Debug::message("Action not set; using default action method name 'index'");
|
||||||
$action = "index";
|
$action = "index";
|
||||||
} else if(!is_string($action)) {
|
} else if(!is_string($action)) {
|
||||||
user_error("Non-string method name: " . var_export($action, true), E_USER_ERROR);
|
user_error("Non-string method name: " . var_export($action, true), E_USER_ERROR);
|
||||||
}
|
}
|
||||||
$result = $this->$action($request);
|
$result = $this->$action($request);
|
||||||
} else {
|
} else {
|
||||||
return $this->httpError(403, "Action '$action' isn't allowed on class $this->class");
|
return $this->httpError(403, "Action '$action' isn't allowed on class $this->class");
|
||||||
}
|
}
|
||||||
|
|
||||||
if($result instanceof HTTPResponse && $result->isError()) {
|
if($result instanceof HTTPResponse && $result->isError()) {
|
||||||
if(isset($_REQUEST['debug_request'])) Debug::message("Rule resulted in HTTP error; breaking");
|
if(isset($_REQUEST['debug_request'])) Debug::message("Rule resulted in HTTP error; breaking");
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we return a RequestHandler, call handleRequest() on that, even if there is no more URL to parse.
|
// If we return a RequestHandler, call handleRequest() on that, even if there is no more URL to parse.
|
||||||
// It might have its own handler. However, we only do this if we haven't just parsed an empty rule ourselves,
|
// It might have its own handler. However, we only do this if we haven't just parsed an empty rule ourselves,
|
||||||
// to prevent infinite loops
|
// to prevent infinite loops
|
||||||
if(!$request->isEmptyPattern($rule) && is_object($result) && $result instanceof RequestHandler) {
|
if(!$request->isEmptyPattern($rule) && is_object($result) && $result instanceof RequestHandler) {
|
||||||
$returnValue = $result->handleRequest($request);
|
$returnValue = $result->handleRequest($request);
|
||||||
|
|
||||||
// Array results can be used to handle
|
// Array results can be used to handle
|
||||||
if(is_array($returnValue)) $returnValue = $this->customise($returnValue);
|
if(is_array($returnValue)) $returnValue = $this->customise($returnValue);
|
||||||
|
|
||||||
return $returnValue;
|
return $returnValue;
|
||||||
|
|
||||||
// If we return some other data, and all the URL is parsed, then return that
|
// If we return some other data, and all the URL is parsed, then return that
|
||||||
} else if($request->allParsed()) {
|
} else if($request->allParsed()) {
|
||||||
return $result;
|
return $result;
|
||||||
|
|
||||||
// But if we have more content on the URL and we don't know what to do with it, return an error.
|
// But if we have more content on the URL and we don't know what to do with it, return an error.
|
||||||
} else {
|
} else {
|
||||||
return $this->httpError(400, "I can't handle sub-URLs of a $this->class object.");
|
return $this->httpError(400, "I can't handle sub-URLs of a $this->class object.");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$handlerClass = get_parent_class($handlerClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If nothing matches, return this object
|
// If nothing matches, return this object
|
||||||
|
@ -72,6 +72,16 @@ class RequestHandlingTest extends SapphireTest {
|
|||||||
$response = Director::test("testParentBase/testChildBase/method/1/2");
|
$response = Director::test("testParentBase/testChildBase/method/1/2");
|
||||||
$this->assertEquals("This is a method on the controller: 1, 2", $response->getBody());
|
$this->assertEquals("This is a method on the controller: 1, 2", $response->getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testInheritedUrlHandlers() {
|
||||||
|
/* $url_handlers can be defined on any class, and */
|
||||||
|
$response = Director::test("testGoodBase1/TestForm/fields/SubclassedField/something");
|
||||||
|
$this->assertEquals("customSomething", $response->getBody());
|
||||||
|
|
||||||
|
/* However, if the subclass' url_handlers don't match, then the parent class' url_handlers will be used */
|
||||||
|
$response = Director::test("testGoodBase1/TestForm/fields/SubclassedField");
|
||||||
|
$this->assertEquals("SubclassedField requested", $response->getBody());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,7 +137,8 @@ class RequestHandlingTest_Controller extends Controller {
|
|||||||
|
|
||||||
function TestForm() {
|
function TestForm() {
|
||||||
return new RequestHandlingTest_Form($this, "TestForm", new FieldSet(
|
return new RequestHandlingTest_Form($this, "TestForm", new FieldSet(
|
||||||
new RequestHandlingTest_FormField("MyField")
|
new RequestHandlingTest_FormField("MyField"),
|
||||||
|
new RequestHandlingTest_SubclassedFormField("SubclassedField")
|
||||||
), new FieldSet(
|
), new FieldSet(
|
||||||
new FormAction("myAction")
|
new FormAction("myAction")
|
||||||
));
|
));
|
||||||
@ -195,3 +206,19 @@ class RequestHandlingTest_FormField extends FormField {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form field for the test
|
||||||
|
*/
|
||||||
|
class RequestHandlingTest_SubclassedFormField extends RequestHandlingTest_FormField {
|
||||||
|
// We have some url_handlers defined that override RequestHandlingTest_FormField handlers.
|
||||||
|
// We will confirm that the url_handlers inherit.
|
||||||
|
static $url_handlers = array(
|
||||||
|
'something' => 'customSomething',
|
||||||
|
);
|
||||||
|
|
||||||
|
function customSomething() {
|
||||||
|
return "customSomething";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user