Created
March 4, 2013 12:22
-
-
Save kinglozzer/5081915 to your computer and use it in GitHub Desktop.
Lines 66 - 74 amended. Causes "[User Warning] popCurrent called on ModelAsController controller, but it wasn't at the top of the stack" and "[User Warning] Couldn't set response type to 404 because of output on line 101 of /Users/lawrence/Devsites/abelhomes/framework/dev/DebugView.php" on sites that are in dev mode.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Handles URL requests. | |
* | |
* - ViewableData::handleRequest() iterates through each rule in {@link self::$url_handlers}. | |
* - If the rule matches, the named method will be called. | |
* - If there is still more URL to be processed, then handleRequest() | |
* is called on the object that that method returns. | |
* | |
* Once all of the URL has been processed, the final result is returned. | |
* However, if the final result is an array, this | |
* array is interpreted as being additional template data to customise the | |
* 2nd to last result with, rather than an object | |
* in its own right. This is most frequently used when a Controller's | |
* action will return an array of data with which to | |
* customise the controller. | |
* | |
* @param $request The {@link SS_HTTPRequest} object that is reponsible for distributing URL parsing | |
* @uses SS_HTTPRequest | |
* @uses SS_HTTPRequest->match() | |
* @return SS_HTTPResponse|RequestHandler|string|array | |
*/ | |
public function handleRequest(SS_HTTPRequest $request, DataModel $model) { | |
// $handlerClass is used to step up the class hierarchy to implement url_handlers inheritance | |
$handlerClass = ($this->class) ? $this->class : get_class($this); | |
if($this->brokenOnConstruct) { | |
user_error("parent::__construct() needs to be called on {$handlerClass}::__construct()", E_USER_WARNING); | |
} | |
$this->request = $request; | |
$this->setDataModel($model); | |
$match = $this->findAction($request); | |
// If nothing matches, return this object | |
if (!$match) return $this; | |
// Start to find what action to call. Start by using what findAction returned | |
$action = $match['action']; | |
// We used to put "handleAction" as the action on controllers, but (a) this could only be called when | |
// you had $Action in your rule, and (b) RequestHandler didn't have one. $Action is better | |
if ($action == 'handleAction') { | |
Deprecation::notice('3.2.0', 'Calling handleAction directly is deprecated - use $Action instead'); | |
$action = '$Action'; | |
} | |
// Actions can reference URL parameters, eg, '$Action/$ID/$OtherID' => '$Action', | |
if($action[0] == '$') { | |
$action = str_replace("-", "_", $request->latestParam(substr($action,1))); | |
} | |
if(!$action) { | |
if(isset($_REQUEST['debug_request'])) { | |
Debug::message("Action not set; using default action method name 'index'"); | |
} | |
$action = "index"; | |
} else if(!is_string($action)) { | |
user_error("Non-string method name: " . var_export($action, true), E_USER_ERROR); | |
} | |
$className = get_class($this); | |
if(!$this->hasAction($action)) { | |
// return new SS_HTTPResponse("Action '$action' isn't available on class $className.", 404); | |
return $this->httpError(404, "Action '$action' isn't available on class $classname."); | |
} | |
if(!$this->checkAccessAction($action) || in_array(strtolower($action), array('run', 'init'))) { | |
// return new SS_HTTPResponse("Action '$action' isn't allowed on class $className.", 403); | |
return $this->httpError(403, "Action '$action' isn't allowed on class $classname."); | |
} | |
try { | |
$result = $this->handleAction($request, $action); | |
} | |
catch (SS_HTTPResponse_Exception $e) { | |
return $e->getResponse(); | |
} | |
catch(PermissionFailureException $e) { | |
$result = Security::permissionFailure(null, $e->getMessage()); | |
} | |
if($result instanceof SS_HTTPResponse && $result->isError()) { | |
if(isset($_REQUEST['debug_request'])) Debug::message("Rule resulted in HTTP error; breaking"); | |
return $result; | |
} | |
// 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, to prevent infinite loops. Also prevent further handling of controller | |
// actions which return themselves to avoid infinite loops. | |
$matchedRuleWasEmpty = $request->isEmptyPattern($match['rule']); | |
$resultIsRequestHandler = is_object($result) && $result instanceof RequestHandler; | |
if($this !== $result && !$matchedRuleWasEmpty && $resultIsRequestHandler) { | |
$returnValue = $result->handleRequest($request, $model); | |
// Array results can be used to handle | |
if(is_array($returnValue)) $returnValue = $this->customise($returnValue); | |
return $returnValue; | |
// If we return some other data, and all the URL is parsed, then return that | |
} else if($request->allParsed()) { | |
return $result; | |
// But if we have more content on the URL and we don't know what to do with it, return an error. | |
} else { | |
return $this->httpError(404, "I can't handle sub-URLs of a $this->class object."); | |
} | |
return $this; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment