/** * Dispatches and invokes given URL, handing over control to the involved controllers, and then renders the results (if autoRender is set). * * If no controller of given name can be found, invoke() shows error messages in * the form of Missing Controllers information. It does the same with Actions (methods of Controllers are called * Actions). * * @param string $url URL information to work on. * @param array $additionalParams Settings array ("bare", "return"), * which is melded with the GET and POST params. * @return boolean Success */ function dispatch($url, $additionalParams = array()) { $params = array_merge($this->parseParams($url), $additionalParams); $missingController = false; $missingAction = false; $missingView = false; $privateAction = false; $this->base = $this->baseUrl(); if (empty($params['controller'])) { $missingController = true; } else { $ctrlName = Inflector::camelize($params['controller']); $ctrlClass = $ctrlName . 'Controller'; if (!loadController($ctrlName)) { $pluginName = Inflector::camelize($params['action']); if (!loadPluginController(Inflector::underscore($ctrlName), $pluginName)) { if (preg_match('/([\\.]+)/', $ctrlName)) { return $this->cakeError('error404', array(array('url' => strtolower($ctrlName), 'message' => 'Was not found on this server', 'base' => $this->base))); } elseif (!class_exists($ctrlClass)) { $missingController = true; } else { $params['plugin'] = null; $this->plugin = null; } } else { $params['plugin'] = Inflector::underscore($ctrlName); } } else { $params['plugin'] = null; $this->plugin = null; } } if (isset($params['plugin'])) { $plugin = $params['plugin']; $pluginName = Inflector::camelize($params['action']); $pluginClass = $pluginName . 'Controller'; $ctrlClass = $pluginClass; $oldAction = $params['action']; $params = $this->_restructureParams($params); $this->plugin = $plugin; loadPluginModels($plugin); $this->base = $this->base . '/' . Inflector::underscore($ctrlName); if (empty($params['controller']) || !class_exists($pluginClass)) { $params['controller'] = Inflector::underscore($ctrlName); $ctrlClass = $ctrlName . 'Controller'; if (!is_null($params['action'])) { array_unshift($params['pass'], $params['action']); } $params['action'] = $oldAction; } } if (empty($params['action'])) { $params['action'] = 'index'; } if (defined('CAKE_ADMIN')) { if (isset($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) { $privateAction = true; } } if ($missingController) { return $this->cakeError('missingController', array(array('className' => Inflector::camelize($params['controller'] . "Controller"), 'webroot' => $this->webroot, 'url' => $url, 'base' => $this->base))); } else { $controller =& new $ctrlClass(); } $classMethods = get_class_methods($controller); $classVars = get_object_vars($controller); if ((in_array($params['action'], $classMethods) || in_array(strtolower($params['action']), $classMethods)) && strpos($params['action'], '_', 0) === 0) { $privateAction = true; } if (!in_array($params['action'], $classMethods) && !in_array(strtolower($params['action']), $classMethods)) { $missingAction = true; } if (in_array(strtolower($params['action']), array('object', 'tostring', 'requestaction', 'log', 'cakeerror', 'constructclasses', 'redirect', 'set', 'setaction', 'validate', 'validateerrors', 'render', 'referer', 'flash', 'flashout', 'generatefieldnames', 'postconditions', 'cleanupfields', 'beforefilter', 'beforerender', 'afterfilter'))) { $missingAction = true; } if (in_array('return', array_keys($params)) && $params['return'] == 1) { $controller->autoRender = false; } $controller->base = $this->base; $base = strip_plugin($this->base, $this->plugin); if (defined("BASE_URL")) { $controller->here = $base . $this->admin . $url; } else { $controller->here = $base . $this->admin . '/' . $url; } $controller->webroot = $this->webroot; $controller->params = $params; $controller->action = $params['action']; if (!empty($controller->params['data'])) { $controller->data =& $controller->params['data']; } else { $controller->data = null; } if (!empty($controller->params['pass'])) { $controller->passed_args =& $controller->params['pass']; $controller->passedArgs =& $controller->params['pass']; } else { $controller->passed_args = null; $controller->passedArgs = null; } if (!empty($params['bare'])) { $controller->autoLayout = !$params['bare']; } else { $controller->autoLayout = $controller->autoLayout; } $controller->webservices = $params['webservices']; $controller->plugin = $this->plugin; if (!is_null($controller->webservices)) { array_push($controller->components, $controller->webservices); array_push($controller->helpers, $controller->webservices); $component =& new Component($controller); } $controller->_initComponents(); $controller->constructClasses(); if ($missingAction && !in_array('scaffold', array_keys($classVars))) { $this->start($controller); return $this->cakeError('missingAction', array(array('className' => Inflector::camelize($params['controller'] . "Controller"), 'action' => $params['action'], 'webroot' => $this->webroot, 'url' => $url, 'base' => $this->base))); } if ($privateAction) { $this->start($controller); return $this->cakeError('privateAction', array(array('className' => Inflector::camelize($params['controller'] . "Controller"), 'action' => $params['action'], 'webroot' => $this->webroot, 'url' => $url, 'base' => $this->base))); } return $this->_invoke($controller, $params, $missingAction); }
/** * Dispatches and invokes given URL, handing over control to the involved controllers, and then renders the results (if autoRender is set). * * If no controller of given name can be found, invoke() shows error messages in * the form of Missing Controllers information. It does the same with Actions (methods of Controllers are called * Actions). * * @param string $url URL information to work on * @param array $additionalParams Settings array ("bare", "return") which is melded with the GET and POST params * @return boolean Success * @access public */ function dispatch($url = null, $additionalParams = array()) { if ($this->base === false) { $this->base = $this->baseUrl(); } if ($url !== null) { $_GET['url'] = $url; } $url = $this->getUrl(); $this->here = $this->base . '/' . $url; $this->cached($url); $this->params = array_merge($this->parseParams($url), $additionalParams); $controller = $this->__getController(); if (!is_object($controller)) { if (preg_match('/([\\.]+)/', $controller)) { Router::setRequestInfo(array($this->params, array('base' => $this->base, 'webroot' => $this->webroot))); return $this->cakeError('error404', array(array('url' => strtolower($controller), 'message' => __('Was not found on this server', true), 'base' => $this->base))); } else { Router::setRequestInfo(array($this->params, array('base' => $this->base, 'webroot' => $this->webroot))); return $this->cakeError('missingController', array(array('className' => Inflector::camelize($this->params['controller']) . 'Controller', 'webroot' => $this->webroot, 'url' => $url, 'base' => $this->base))); } } $missingAction = $missingView = $privateAction = false; if (empty($this->params['action'])) { $this->params['action'] = 'index'; } $prefixes = Router::prefixes(); if (!empty($prefixes)) { if (isset($this->params['prefix'])) { $this->params['action'] = $this->params['prefix'] . '_' . $this->params['action']; } elseif (strpos($this->params['action'], '_') !== false) { list($prefix, $action) = explode('_', $this->params['action']); $privateAction = in_array($prefix, $prefixes); } } $protected = array_map('strtolower', get_class_methods('controller')); $classMethods = array_map('strtolower', get_class_methods($controller)); if (in_array(low($this->params['action']), $protected) || strpos($this->params['action'], '_', 0) === 0) { $privateAction = true; } if (!in_array(low($this->params['action']), $classMethods)) { $missingAction = true; } 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->plugin = $this->plugin; $controller->params =& $this->params; $controller->action =& $this->params['action']; $controller->webservices =& $this->params['webservices']; $controller->passedArgs =& $this->params['pass']; if (!empty($this->params['data'])) { $controller->data =& $this->params['data']; } else { $controller->data = null; } if (!empty($this->params['bare'])) { $controller->autoLayout = false; } if (isset($this->params['layout'])) { if ($this->params['layout'] === '') { $controller->autoLayout = false; } else { $controller->layout = $this->params['layout']; } } if (isset($this->params['viewPath'])) { $controller->viewPath = $this->params['viewPath']; } foreach (array('components', 'helpers') as $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); } } if (!is_null($controller->webservices)) { array_push($controller->components, $controller->webservices); array_push($controller->helpers, $controller->webservices); } Router::setRequestInfo(array($this->params, array('base' => $this->base, 'here' => $this->here, 'webroot' => $this->webroot))); $controller->_initComponents(); if (isset($this->plugin)) { loadPluginModels($this->plugin); } $controller->constructClasses(); $this->start($controller); if ($privateAction) { return $this->cakeError('privateAction', array(array('className' => Inflector::camelize($this->params['controller'] . "Controller"), 'action' => $this->params['action'], 'webroot' => $this->webroot, 'url' => $url, 'base' => $this->base))); } return $this->_invoke($controller, $this->params, $missingAction); }