From b29366ddc08de1ba462e2ffdcd5dbbf6988b3ac3 Mon Sep 17 00:00:00 2001 From: phpnut Date: Wed, 25 Jul 2007 19:42:58 +0000 Subject: [PATCH] Refactoring loading of plugins. git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@5463 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/dispatcher.php | 131 +++++++++++++++-------- cake/libs/controller/components/auth.php | 2 +- cake/tests/cases/dispatcher.test.php | 131 ++++++++++++++++++++++- 3 files changed, 217 insertions(+), 47 deletions(-) diff --git a/cake/dispatcher.php b/cake/dispatcher.php index d4eb39175..99874d296 100644 --- a/cake/dispatcher.php +++ b/cake/dispatcher.php @@ -75,6 +75,14 @@ class Dispatcher extends Object { * @access public */ var $plugin = null; + +/** + * the params for this request + * + * @var string + * @access public + */ + var $params = null; /** * Constructor. */ @@ -98,54 +106,42 @@ class Dispatcher extends Object { * @access public */ function dispatch($url, $additionalParams = array()) { - $params = array_merge($this->parseParams($url), $additionalParams); + $this->params = array_merge($this->parseParams($url), $additionalParams); $missingAction = $missingView = $privateAction = false; $this->base = $this->baseUrl(); + $controller = $this->__getController($this->params); - $pluginPath = null; - if (!empty($params['plugin'])) { - $this->plugin = $params['plugin']; - $pluginPath = Inflector::camelize($this->plugin).'.'; - } + if(!is_object($controller)) { + if (preg_match('/([\\.]+)/', $controller)) { + Router::setRequestInfo(array($this->params, array('base' => $this->base, 'webroot' => $this->webroot))); - if (!empty($params['controller'])) { - $ctrlName = Inflector::camelize($params['controller']); - $ctrlClass = $ctrlName.'Controller'; - } - - if (!loadController($pluginPath . $ctrlName)) { - if (preg_match('/([\\.]+)/', $ctrlName)) { - Router::setRequestInfo(array($params, array('base' => $this->base, 'webroot' => $this->webroot))); - - return $this->cakeError('error404', array(array('url' => strtolower($ctrlName), + return $this->cakeError('error404', array(array('url' => strtolower($controller), 'message' => 'Was not found on this server', 'base' => $this->base))); } else { - Router::setRequestInfo(array($params, array('base' => $this->base, 'webroot' => $this->webroot))); + Router::setRequestInfo(array($this->params, array('base' => $this->base, 'webroot' => $this->webroot))); return $this->cakeError('missingController', array( array( - 'className' => Inflector::camelize($params['controller']."Controller"), + 'className' => $controller.'Controller', 'webroot' => $this->webroot, 'url' => $url, 'base' => $this->base ) )); } - } else { - $controller =& new $ctrlClass(); } - if (empty($params['action'])) { - $params['action'] = 'index'; + if (empty($this->params['action'])) { + $this->params['action'] = 'index'; } if (defined('CAKE_ADMIN')) { - if (isset($params[CAKE_ADMIN])) { + if (isset($this->params[CAKE_ADMIN])) { $this->admin = '/'.CAKE_ADMIN ; $url = preg_replace('/'.CAKE_ADMIN.'(\/|$)/', '', $url); - $params['action'] = CAKE_ADMIN.'_'.$params['action']; - } elseif (strpos($params['action'], CAKE_ADMIN) === 0) { + $this->params['action'] = CAKE_ADMIN.'_'.$this->params['action']; + } elseif (strpos($this->params['action'], CAKE_ADMIN) === 0) { $privateAction = true; } } @@ -160,27 +156,27 @@ class Dispatcher extends Object { $classMethods = array_map("low", get_class_methods($controller)); - if (in_array(low($params['action']), $protected) || strpos($params['action'], '_', 0) === 0) { + if (in_array(low($this->params['action']), $protected) || strpos($this->params['action'], '_', 0) === 0) { $privateAction = true; } - if (!in_array(low($params['action']), $classMethods)) { + if (!in_array(low($this->params['action']), $classMethods)) { $missingAction = true; } - if (in_array('return', array_keys($params)) && $params['return'] == 1) { + if (in_array('return', array_keys($this->params)) && $this->params['return'] == 1) { $controller->autoRender = false; } $controller->base = $this->base; $controller->here = $this->here; $controller->webroot = $this->webroot; - $controller->params = $params; + $controller->params = $this->params; $controller->plugin = $this->plugin; - $controller->action = $params['action']; - $controller->webservices = $params['webservices']; + $controller->action = $this->params['action']; + $controller->webservices = $this->params['webservices']; - list($passedArgs, $namedArgs) = Router::getArgs($params, $controller->namedArgs, $controller->argSeparator); + list($passedArgs, $namedArgs) = Router::getArgs($this->params, $controller->namedArgs, $controller->argSeparator); $controller->passedArgs = $passedArgs; $controller->namedArgs = $namedArgs; @@ -190,25 +186,25 @@ class Dispatcher extends Object { $controller->data = null; } - if (!empty($params['bare'])) { + if (!empty($this->params['bare'])) { $controller->autoLayout = false; } - if (isset($params['layout'])) { - if ($params['layout'] === '') { + if (isset($this->params['layout'])) { + if ($this->params['layout'] === '') { $controller->autoLayout = false; } else { - $controller->layout = $params['layout']; + $controller->layout = $this->params['layout']; } } - if (isset($params['viewPath'])) { - $controller->viewPath = $params['viewPath']; + if (isset($this->params['viewPath'])) { + $controller->viewPath = $this->params['viewPath']; } foreach (array('components', 'helpers') as $var) { - if (isset($params[$var]) && !empty($params[$var]) && is_array($controller->{$var})) { - $diff = array_diff($params[$var], $controller->{$var}); + if (isset($this->params[$var]) && !empty($this->params[$var]) && is_array($controller->{$var})) { + $diff = array_diff($this->params[$var], $controller->{$var}); $controller->{$var} = array_merge($controller->{$var}, $diff); } } @@ -217,16 +213,21 @@ class Dispatcher extends Object { array_push($controller->components, $controller->webservices); array_push($controller->helpers, $controller->webservices); } - Router::setRequestInfo(array($params, array('base' => $this->base, 'here' => $this->here, 'webroot' => $this->webroot, 'passedArgs' => $controller->passedArgs, 'argSeparator' => $controller->argSeparator, 'namedArgs' => $controller->namedArgs, 'webservices' => $controller->webservices))); + Router::setRequestInfo(array($this->params, array('base' => $this->base, 'here' => $this->here, 'webroot' => $this->webroot, 'passedArgs' => $controller->passedArgs, 'argSeparator' => $controller->argSeparator, 'namedArgs' => $controller->namedArgs, 'webservices' => $controller->webservices))); $controller->_initComponents(); + + if(isset($this->plugin)) { + loadPluginModels($this->plugin); + } + $controller->constructClasses(); if ($privateAction) { $this->start($controller); return $this->cakeError('privateAction', array( array( - 'className' => Inflector::camelize($params['controller']."Controller"), - 'action' => $params['action'], + 'className' => Inflector::camelize($this->params['controller']."Controller"), + 'action' => $this->params['action'], 'webroot' => $this->webroot, 'url' => $url, 'base' => $this->base @@ -234,7 +235,7 @@ class Dispatcher extends Object { )); } - return $this->_invoke($controller, $params, $missingAction); + return $this->_invoke($controller, $this->params, $missingAction); } /** * Invokes given controller's render action if autoRender option is set. Otherwise the @@ -448,6 +449,7 @@ class Dispatcher extends Object { * @access protected */ function _restructureParams($params) { + $params['plugin'] = $params['controller']; $params['controller'] = $params['action']; if (isset($params['pass'][0])) { @@ -458,6 +460,47 @@ class Dispatcher extends Object { } return $params; } +/** + * Get controller to use, either plugin controller or application controller + * + * @param array $params Array on where to re-set 'controller', 'action', and 'pass' indexes + * @return mixed name of controller if not loaded, or object if loaded + * @access protected + */ + function __getController($params = null, $continue = true) { + + if(!$params) { + $params = $this->params; + } + + $controller = $pluginPath = null; + + if (!empty($params['controller'])) { + $controller = Inflector::camelize($params['controller']); + $ctrlClass = $controller.'Controller'; + } + + if (!empty($params['plugin'])) { + $this->plugin = $params['plugin']; + $pluginPath = Inflector::camelize($this->plugin).'.'; + + if(!$controller) { + $controller = Inflector::camelize($params['plugin']); + $ctrlClass = $controller.'Controller'; + } + } + if ($pluginPath . $controller && loadController($pluginPath . $controller)) { + $controller =& new $ctrlClass(); + } elseif ($continue){ + $this->params = $this->_restructureParams($params); + $controller = $this->__getController($this->params, false); + } + + if(!isset($ctrlClass)) { + return false; + } + return $controller; + } } ?> \ No newline at end of file diff --git a/cake/libs/controller/components/auth.php b/cake/libs/controller/components/auth.php index 52b831044..6cab3b7ab 100644 --- a/cake/libs/controller/components/auth.php +++ b/cake/libs/controller/components/auth.php @@ -768,7 +768,7 @@ class AuthComponent extends Object { } $paths = Router::getPaths(); - if (stristr($url, $paths['base'])) { + if (!empty($paths['base']) && stristr($url, $paths['base'])) { $url = r($paths['base'], '', $url); } diff --git a/cake/tests/cases/dispatcher.test.php b/cake/tests/cases/dispatcher.test.php index bbd049df3..48c59ee03 100644 --- a/cake/tests/cases/dispatcher.test.php +++ b/cake/tests/cases/dispatcher.test.php @@ -63,6 +63,21 @@ class TestDispatcher extends Dispatcher { class MyPluginAppController extends Controller { } + +class MyPluginController extends MyPluginAppController { + + var $name = 'MyPlugin'; + var $uses = array(); + + function index() { + return true; + } + + function add() { + return true; + } +} + class SomePagesController extends MyPluginAppController { var $name = 'SomePages'; @@ -71,6 +86,10 @@ class SomePagesController extends MyPluginAppController { function display($page = null) { return $page; } + + function index() { + return true; + } } class TestDispatchPagesController extends Controller { @@ -320,7 +339,7 @@ class DispatcherTest extends UnitTestCase { $url = setUrl('/some_controller/home/param:value/param2:value2'); restore_error_handler(); - @$controller = $dispatcher->dispatch($url, array('return'=> 1)); + $controller = $dispatcher->dispatch($url, array('return'=> 1)); set_error_handler('simpleTestErrorHandler'); $expected = 'missingController'; @@ -438,6 +457,9 @@ class DispatcherTest extends UnitTestCase { 'form'=> null, //array('testdata'=> 'My Posted Data'), 'url'=> array('url'=> 'my_plugin/some_pages/home/param:value/param2:value2'), 'bare'=> 0, 'webservices'=> ''); + ksort($expected); + ksort($result); + $this->assertEqual($expected, $result); $expected = 'my_plugin'; @@ -456,8 +478,113 @@ class DispatcherTest extends UnitTestCase { $this->assertIdentical($expected, $controller->base); } + + function testAutomaticPluginDispatch() { + $_POST = array(); + $_SERVER['DOCUMENT_ROOT'] = ''; + $_SERVER['SCRIPT_FILENAME'] = '/cake/repo/branches/1.2.x.x/app/webroot/index.php'; + + Router::reload(); + $dispatcher =& new TestDispatcher(); + $dispatcher->base = false; + + $url = setUrl('/my_plugin/some_pages/index/param:value/param2:value2'); + + restore_error_handler(); + @$controller = $dispatcher->dispatch($url, array('return'=> 1)); + set_error_handler('simpleTestErrorHandler'); + + pr($dispatcher->params); + $expected = 'my_plugin'; + $this->assertIdentical($expected, $controller->plugin); + + $expected = 'SomePages'; + $this->assertIdentical($expected, $controller->name); + + $expected = 'index'; + $this->assertIdentical($expected, $controller->action); + + $expected = array('param'=>'value', 'param2'=>'value2'); + $this->assertIdentical($expected, $controller->namedArgs); + + $expected = '/cake/repo/branches/1.2.x.x/my_plugin/some_pages/index/param:value/param2:value2'; + $this->assertIdentical($expected, $controller->here); + + $expected = '/cake/repo/branches/1.2.x.x'; + $this->assertIdentical($expected, $controller->base); + } + + function testAutomaticPluginControllerDispatch() { + $_POST = array(); + $_SERVER['DOCUMENT_ROOT'] = ''; + $_SERVER['SCRIPT_FILENAME'] = '/cake/repo/branches/1.2.x.x/app/webroot/index.php'; + + Router::reload(); + $dispatcher =& new TestDispatcher(); + $dispatcher->base = false; + + $url = setUrl('/my_plugin/add/param:value/param2:value2'); + + restore_error_handler(); + @$controller = $dispatcher->dispatch($url, array('return'=> 1)); + set_error_handler('simpleTestErrorHandler'); + + $expected = 'my_plugin'; + $this->assertIdentical($expected, $controller->plugin); + + $expected = 'MyPlugin'; + $this->assertIdentical($expected, $controller->name); + + $expected = 'add'; + $this->assertIdentical($expected, $controller->action); + } + + function testAutomaticPluginPluginControllerDispatch() { + $_POST = array(); + $_SERVER['DOCUMENT_ROOT'] = ''; + $_SERVER['SCRIPT_FILENAME'] = '/cake/repo/branches/1.2.x.x/app/webroot/index.php'; + + Router::reload(); + $dispatcher =& new TestDispatcher(); + $dispatcher->base = false; + + $url = setUrl('/my_plugin/param:value/param2:value2'); + restore_error_handler(); + @$controller = $dispatcher->dispatch($url, array('return'=> 1)); + set_error_handler('simpleTestErrorHandler'); + + $expected = 'my_plugin'; + $this->assertIdentical($expected, $controller->plugin); + + $expected = 'MyPlugin'; + $this->assertIdentical($expected, $controller->name); + + $expected = 'index'; + $this->assertIdentical($expected, $controller->action); + } + + function testRouterPluginNullControllerDispatch() { + $_POST = array(); + $_SERVER['DOCUMENT_ROOT'] = ''; + $_SERVER['SCRIPT_FILENAME'] = '/cake/repo/branches/1.2.x.x/app/webroot/index.php'; + + Router::reload(); + Router::connect('/my_plugin/:controller/:action/*', array('plugin'=> 'my_plugin')); + $dispatcher =& new TestDispatcher(); + $dispatcher->base = false; + + $url = setUrl('/my_plugin/param:value/param2:value2'); + restore_error_handler(); + @$controller = $dispatcher->dispatch($url, array('return'=> 1)); + set_error_handler('simpleTestErrorHandler'); + + $expected = 'missingController'; + $this->assertIdentical($expected, $controller); + } + + function tearDown() { $_GET = $this->_get; } } -?> +?> \ No newline at end of file