mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-03-18 23:49:55 +00:00
Moving private method detection into Controller.
This fixes an issue where potected methods would not be called, and no exception would be raised.
This commit is contained in:
parent
8bfc0a859d
commit
177cd39abb
3 changed files with 62 additions and 50 deletions
|
@ -442,6 +442,61 @@ class Controller extends Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches the controller action. Checks that the action
|
||||||
|
* exists and isn't private.
|
||||||
|
*
|
||||||
|
* @param CakeRequest $request
|
||||||
|
* @return The resulting response.
|
||||||
|
*/
|
||||||
|
public function invokeAction(CakeRequest $request) {
|
||||||
|
$reflection = new ReflectionClass($this);
|
||||||
|
try {
|
||||||
|
$method = $reflection->getMethod($request->params['action']);
|
||||||
|
|
||||||
|
if ($this->_isPrivateAction($method, $request)) {
|
||||||
|
throw new PrivateActionException(array(
|
||||||
|
'controller' => $this->name . "Controller",
|
||||||
|
'action' => $request->params['action']
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return $method->invokeArgs($this, $request->params['pass']);
|
||||||
|
|
||||||
|
} catch (ReflectionException $e) {
|
||||||
|
if ($this->scaffold !== false) {
|
||||||
|
return new Scaffold($this, $request);
|
||||||
|
}
|
||||||
|
throw new MissingActionException(array(
|
||||||
|
'controller' => $this->name . "Controller",
|
||||||
|
'action' => $request->params['action']
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the request's action is marked as private, with an underscore, of if the request is attempting to
|
||||||
|
* directly accessing a prefixed action.
|
||||||
|
*
|
||||||
|
* @param ReflectionMethod $method The method to be invoked.
|
||||||
|
* @param CakeRequest $request The request to check.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
protected function _isPrivateAction(ReflectionMethod $method, CakeRequest $request) {
|
||||||
|
$privateAction = (
|
||||||
|
$method->name[0] === '_' ||
|
||||||
|
!$method->isPublic() ||
|
||||||
|
!in_array($method->name, $this->methods)
|
||||||
|
);
|
||||||
|
$prefixes = Router::prefixes();
|
||||||
|
|
||||||
|
if (!$privateAction && !empty($prefixes)) {
|
||||||
|
if (empty($request->params['prefix']) && strpos($request->params['action'], '_') > 0) {
|
||||||
|
list($prefix, $action) = explode('_', $request->params['action']);
|
||||||
|
$privateAction = in_array($prefix, $prefixes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $privateAction;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Merge components, helpers, and uses vars from Controller::$_mergeParent and PluginAppController.
|
* Merge components, helpers, and uses vars from Controller::$_mergeParent and PluginAppController.
|
||||||
*
|
*
|
||||||
|
|
|
@ -93,37 +93,9 @@ class Dispatcher {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->_isPrivateAction($request)) {
|
|
||||||
throw new PrivateActionException(array(
|
|
||||||
'controller' => Inflector::camelize($request->params['controller']) . "Controller",
|
|
||||||
'action' => $request->params['action']
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->_invoke($controller, $request, $response);
|
return $this->_invoke($controller, $request, $response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the request's action is marked as private, with an underscore, of if the request is attempting to
|
|
||||||
* directly accessing a prefixed action.
|
|
||||||
*
|
|
||||||
* @param CakeRequest $request The request to check
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
protected function _isPrivateAction($request) {
|
|
||||||
$privateAction = $request->params['action'][0] === '_';
|
|
||||||
$prefixes = Router::prefixes();
|
|
||||||
|
|
||||||
if (!$privateAction && !empty($prefixes)) {
|
|
||||||
if (empty($request->params['prefix']) && strpos($request->params['action'], '_') > 0) {
|
|
||||||
list($prefix, $action) = explode('_', $request->params['action']);
|
|
||||||
$privateAction = in_array($prefix, $prefixes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $privateAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the components and models a controller will be using.
|
* Initializes the components and models a controller will be using.
|
||||||
* Triggers the controller action, and invokes the rendering if Controller::$autoRender is true and echo's the output.
|
* Triggers the controller action, and invokes the rendering if Controller::$autoRender is true and echo's the output.
|
||||||
|
@ -138,22 +110,11 @@ class Dispatcher {
|
||||||
$controller->constructClasses();
|
$controller->constructClasses();
|
||||||
$controller->startupProcess();
|
$controller->startupProcess();
|
||||||
|
|
||||||
$methods = array_flip($controller->methods);
|
$result = $controller->invokeAction($request);
|
||||||
|
|
||||||
if (!isset($methods[$request->params['action']])) {
|
|
||||||
if ($controller->scaffold !== false) {
|
|
||||||
return new Scaffold($controller, $request);
|
|
||||||
}
|
|
||||||
throw new MissingActionException(array(
|
|
||||||
'controller' => Inflector::camelize($request->params['controller']) . "Controller",
|
|
||||||
'action' => $request->params['action']
|
|
||||||
));
|
|
||||||
}
|
|
||||||
$result = call_user_func_array(array(&$controller, $request->params['action']), $request->params['pass']);
|
|
||||||
|
|
||||||
if ($result instanceof CakeResponse) {
|
if ($result instanceof CakeResponse) {
|
||||||
$response = $result;
|
$response = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($controller->autoRender) {
|
if ($controller->autoRender) {
|
||||||
$response = $controller->render();
|
$response = $controller->render();
|
||||||
} elseif ($response->body() === null) {
|
} elseif ($response->body() === null) {
|
||||||
|
|
|
@ -50,11 +50,7 @@ class TestDispatcher extends Dispatcher {
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function _invoke(Controller $controller, CakeRequest $request, CakeResponse $response) {
|
protected function _invoke(Controller $controller, CakeRequest $request, CakeResponse $response) {
|
||||||
if ($result = parent::_invoke($controller, $request, $response)) {
|
$result = parent::_invoke($controller, $request, $response);
|
||||||
if ($result[0] === 'missingAction') {
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $controller;
|
return $controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -733,13 +729,13 @@ class DispatcherTest extends CakeTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test that methods declared in Controller are treated as missing methods.
|
* test that methods declared in Controller are treated as private methods.
|
||||||
*
|
*
|
||||||
* @expectedException MissingActionException
|
* @expectedException PrivateActionException
|
||||||
* @expectedExceptionMessage Action SomePagesController::redirect() could not be found.
|
* @expectedExceptionMessage Private Action SomePagesController::redirect() is not directly accessible.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testMissingActionFromBaseClassMethods() {
|
public function testPrivateActionFromBaseClassMethods() {
|
||||||
$Dispatcher = new TestDispatcher();
|
$Dispatcher = new TestDispatcher();
|
||||||
Configure::write('App.baseUrl','/index.php');
|
Configure::write('App.baseUrl','/index.php');
|
||||||
$url = new CakeRequest('some_pages/redirect/param:value/param2:value2');
|
$url = new CakeRequest('some_pages/redirect/param:value/param2:value2');
|
||||||
|
|
Loading…
Add table
Reference in a new issue