cakephp2-php8/cake/dispatcher.php

349 lines
9.9 KiB
PHP
Raw Normal View History

<?php
/* SVN FILE: $Id$ */
/**
* Dispatcher takes the URL information, parses it for paramters and
* tells the involved controllers what to do.
*
* This is the heart of Cake's operation.
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright (c) 2005, CakePHP Authors/Developers
*
* Author(s): Michal Tatarynowicz aka Pies <tatarynowicz@gmail.com>
* Larry E. Masters aka PhpNut <nut@phpnut.com>
* Kamil Dzielinski aka Brego <brego.dk@gmail.com>
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @author CakePHP Authors/Developers
* @copyright Copyright (c) 2005, CakePHP Authors/Developers
* @link https://trac.cakephp.org/wiki/Authors Authors/Developers
* @package cake
Merging from sandboxes [1079] Merged [1005] committed by nate but not added to core prior to release. Merged [1078] prior to modifying all developers sandboxes. [1081] adding view and template directories [1082] adding base files for view generator [1083] correcting all package and sub package tags for in doc blocks. Making sure every file in the core has doc block in them [1084] renaming working copy of latest release [1093] Added fix for associations using underscores if var $useTable is set in the associated models. This closes ticket #11. [1094] Fix for Ticket #24. The problem was tracked to a variable in View::_render(); $loadedHelpers was being assigned a reference when it when it should not have been. [1096] Initial work on controller components needs testing. Also added a work around for the basics.php uses(). Using the define DS where the files from the original version are now located in deeper libs directories. [1097] committing a few typos in the code I added [1098] reformatting code in component.php [1104] changed the test route and corrected a regex in inflector. [1111] removing the contructor from dispatcher, it is not needed [1112] Changes made for errors when a file is not present in webroot. Fixed the regex used in Router::parse(). Change the error layout template. [1113] Changes to Folder class to allow setting the permissions mode when constructing. This class needs to be refactored and move everything that is in the contructor out. The constructor should set the vars for use in other Folder::"methods"(). Will work on this at a later time. git-svn-id: https://svn.cakephp.org/repo/trunk/cake@1114 3807eeeb-6ff5-0310-8944-8be069107fe0
2005-10-09 01:56:21 +00:00
* @subpackage cake.cake
* @since CakePHP v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Add Description
*/
Merging from sandboxes [1079] Merged [1005] committed by nate but not added to core prior to release. Merged [1078] prior to modifying all developers sandboxes. [1081] adding view and template directories [1082] adding base files for view generator [1083] correcting all package and sub package tags for in doc blocks. Making sure every file in the core has doc block in them [1084] renaming working copy of latest release [1093] Added fix for associations using underscores if var $useTable is set in the associated models. This closes ticket #11. [1094] Fix for Ticket #24. The problem was tracked to a variable in View::_render(); $loadedHelpers was being assigned a reference when it when it should not have been. [1096] Initial work on controller components needs testing. Also added a work around for the basics.php uses(). Using the define DS where the files from the original version are now located in deeper libs directories. [1097] committing a few typos in the code I added [1098] reformatting code in component.php [1104] changed the test route and corrected a regex in inflector. [1111] removing the contructor from dispatcher, it is not needed [1112] Changes made for errors when a file is not present in webroot. Fixed the regex used in Router::parse(). Change the error layout template. [1113] Changes to Folder class to allow setting the permissions mode when constructing. This class needs to be refactored and move everything that is in the contructor out. The constructor should set the vars for use in other Folder::"methods"(). Will work on this at a later time. git-svn-id: https://svn.cakephp.org/repo/trunk/cake@1114 3807eeeb-6ff5-0310-8944-8be069107fe0
2005-10-09 01:56:21 +00:00
uses('error_messages', 'object', 'router', DS.'controller'.DS.'controller', DS.'controller'.DS.'scaffold');
/**
* Short description for class.
*
* Dispatches the request, creating appropriate models and controllers.
*
* @package cake
Merging from sandboxes [1079] Merged [1005] committed by nate but not added to core prior to release. Merged [1078] prior to modifying all developers sandboxes. [1081] adding view and template directories [1082] adding base files for view generator [1083] correcting all package and sub package tags for in doc blocks. Making sure every file in the core has doc block in them [1084] renaming working copy of latest release [1093] Added fix for associations using underscores if var $useTable is set in the associated models. This closes ticket #11. [1094] Fix for Ticket #24. The problem was tracked to a variable in View::_render(); $loadedHelpers was being assigned a reference when it when it should not have been. [1096] Initial work on controller components needs testing. Also added a work around for the basics.php uses(). Using the define DS where the files from the original version are now located in deeper libs directories. [1097] committing a few typos in the code I added [1098] reformatting code in component.php [1104] changed the test route and corrected a regex in inflector. [1111] removing the contructor from dispatcher, it is not needed [1112] Changes made for errors when a file is not present in webroot. Fixed the regex used in Router::parse(). Change the error layout template. [1113] Changes to Folder class to allow setting the permissions mode when constructing. This class needs to be refactored and move everything that is in the contructor out. The constructor should set the vars for use in other Folder::"methods"(). Will work on this at a later time. git-svn-id: https://svn.cakephp.org/repo/trunk/cake@1114 3807eeeb-6ff5-0310-8944-8be069107fe0
2005-10-09 01:56:21 +00:00
* @subpackage cake.cake
* @since CakePHP v 0.2.9
*/
class Dispatcher extends Object
{
/**
* Base URL
* @var string
*/
var $base = false;
/**
* Constructor.
*/
function __construct()
{
parent::__construct();
}
/**
* 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.
* @return boolean Success
*/
function dispatch($url, $additionalParams=array())
{
Merging from sandboxes [1079] Merged [1005] committed by nate but not added to core prior to release. Merged [1078] prior to modifying all developers sandboxes. [1081] adding view and template directories [1082] adding base files for view generator [1083] correcting all package and sub package tags for in doc blocks. Making sure every file in the core has doc block in them [1084] renaming working copy of latest release [1093] Added fix for associations using underscores if var $useTable is set in the associated models. This closes ticket #11. [1094] Fix for Ticket #24. The problem was tracked to a variable in View::_render(); $loadedHelpers was being assigned a reference when it when it should not have been. [1096] Initial work on controller components needs testing. Also added a work around for the basics.php uses(). Using the define DS where the files from the original version are now located in deeper libs directories. [1097] committing a few typos in the code I added [1098] reformatting code in component.php [1104] changed the test route and corrected a regex in inflector. [1111] removing the contructor from dispatcher, it is not needed [1112] Changes made for errors when a file is not present in webroot. Fixed the regex used in Router::parse(). Change the error layout template. [1113] Changes to Folder class to allow setting the permissions mode when constructing. This class needs to be refactored and move everything that is in the contructor out. The constructor should set the vars for use in other Folder::"methods"(). Will work on this at a later time. git-svn-id: https://svn.cakephp.org/repo/trunk/cake@1114 3807eeeb-6ff5-0310-8944-8be069107fe0
2005-10-09 01:56:21 +00:00
$this->base = $this->baseUrl();
$params = array_merge($this->parseParams($url), $additionalParams);
$missingController = false;
$missingAction = false;
$missingView = false;
Merging [920] [922] [929] [920] Small bugfix for after condition in AjaxHelper::remoteFunction [922] Fixed Ticket #224 Added patch from Ticket #221 Added patch from Ticket #222 Renamed renderMethod() to requestAction() the name fits better since we are really requesting another objects response. Added a default setting to turn of autoRender for the class you are requesting the action from, this will allow you to request an action and use the return how you like, instead of letting the object output the content directly to the browser if it would normally do so. [929] Adding fix for Itcket #225. Moved code for beforeFilters to first section of Controller::constructClasses(). Removed current implementaion of beforeFilters. This will be changed to pass a reference of the object to the filters through a core filters class. The core filter class will then load the filters and perform all request on the object in the order the filters are arranged in var $beforeFilters, each beforeFilter needs to be a class that the core filter class will create an instance of. If one of the filters fails, it will return the object, untouched and not try to process other filters, an failed var will be set on the controller. This will be done before data base is initialized for the current object that is being filtered. Modifed the requestAction() changes are noted below Using inside of a controller. Default $this->requestAction('/controller/action/argument/'); Request Object to render output directly $this->requestAction('/controller/action/argument/', a('render')); Using a helper object to make request inside of a view: Default $helpername->requestAction('/controller/action/argument/'); Request Object to render output directly $helpername->requestAction('/controller/action/argument/', a('render')); Using the View object "$this" in a view to make request: $this->requestAction('/controller/action/argument/'); Request Object to render output directly $this->requestAction('/controller/action/argument/', a('render')); git-svn-id: https://svn.cakephp.org/repo/trunk/cake@930 3807eeeb-6ff5-0310-8944-8be069107fe0
2005-09-21 05:48:09 +00:00
if(!in_array('render', array_keys($params)))
{
$params['render'] = 0;
}
if (empty($params['controller']))
{
$missingController = true;
}
else
{
$ctrlName = Inflector::camelize($params['controller']);
$ctrlClass = $ctrlName.'Controller';
if (!loadController($ctrlName) || !class_exists($ctrlClass))
{
Merging from sandboxes [1079] Merged [1005] committed by nate but not added to core prior to release. Merged [1078] prior to modifying all developers sandboxes. [1081] adding view and template directories [1082] adding base files for view generator [1083] correcting all package and sub package tags for in doc blocks. Making sure every file in the core has doc block in them [1084] renaming working copy of latest release [1093] Added fix for associations using underscores if var $useTable is set in the associated models. This closes ticket #11. [1094] Fix for Ticket #24. The problem was tracked to a variable in View::_render(); $loadedHelpers was being assigned a reference when it when it should not have been. [1096] Initial work on controller components needs testing. Also added a work around for the basics.php uses(). Using the define DS where the files from the original version are now located in deeper libs directories. [1097] committing a few typos in the code I added [1098] reformatting code in component.php [1104] changed the test route and corrected a regex in inflector. [1111] removing the contructor from dispatcher, it is not needed [1112] Changes made for errors when a file is not present in webroot. Fixed the regex used in Router::parse(). Change the error layout template. [1113] Changes to Folder class to allow setting the permissions mode when constructing. This class needs to be refactored and move everything that is in the contructor out. The constructor should set the vars for use in other Folder::"methods"(). Will work on this at a later time. git-svn-id: https://svn.cakephp.org/repo/trunk/cake@1114 3807eeeb-6ff5-0310-8944-8be069107fe0
2005-10-09 01:56:21 +00:00
if(preg_match('/([\\.]+)/',$ctrlName))
{
$this->error404(strtolower($ctrlName),'Was not found on this server');
exit();
}
else
{
$missingController = true;
}
}
}
if ($missingController)
{
$controller =& new AppController();
$params['action'] = 'missingController';
$params['controller'] = Inflector::camelize($params['controller']."Controller");
$controller->missingController = $params['controller'];
$controller->webroot = $this->webroot;
return $this->_invoke($controller, $params );
}
else
{
$controller =& new $ctrlClass($this);
}
$classMethods = get_class_methods($controller);
$classVars = get_object_vars($controller);
if (empty($params['action']))
{
$params['action'] = 'index';
}
if(!in_array($params['action'], $classMethods))
{
$missingAction = true;
}
$controller->base = $this->base;
$controller->here = $this->base.'/'.$url;
$controller->webroot = $this->webroot;
$controller->params = $params;
$controller->action = $params['action'];
$controller->data = empty($params['data'])? null: $params['data'];
$controller->passed_args = empty($params['pass'])? null: $params['pass'];
$controller->viewpath = Inflector::underscore($ctrlName);
$controller->autoLayout = !$params['bare'];
Merging [920] [922] [929] [920] Small bugfix for after condition in AjaxHelper::remoteFunction [922] Fixed Ticket #224 Added patch from Ticket #221 Added patch from Ticket #222 Renamed renderMethod() to requestAction() the name fits better since we are really requesting another objects response. Added a default setting to turn of autoRender for the class you are requesting the action from, this will allow you to request an action and use the return how you like, instead of letting the object output the content directly to the browser if it would normally do so. [929] Adding fix for Itcket #225. Moved code for beforeFilters to first section of Controller::constructClasses(). Removed current implementaion of beforeFilters. This will be changed to pass a reference of the object to the filters through a core filters class. The core filter class will then load the filters and perform all request on the object in the order the filters are arranged in var $beforeFilters, each beforeFilter needs to be a class that the core filter class will create an instance of. If one of the filters fails, it will return the object, untouched and not try to process other filters, an failed var will be set on the controller. This will be done before data base is initialized for the current object that is being filtered. Modifed the requestAction() changes are noted below Using inside of a controller. Default $this->requestAction('/controller/action/argument/'); Request Object to render output directly $this->requestAction('/controller/action/argument/', a('render')); Using a helper object to make request inside of a view: Default $helpername->requestAction('/controller/action/argument/'); Request Object to render output directly $helpername->requestAction('/controller/action/argument/', a('render')); Using the View object "$this" in a view to make request: $this->requestAction('/controller/action/argument/'); Request Object to render output directly $this->requestAction('/controller/action/argument/', a('render')); git-svn-id: https://svn.cakephp.org/repo/trunk/cake@930 3807eeeb-6ff5-0310-8944-8be069107fe0
2005-09-21 05:48:09 +00:00
$controller->autoRender = !$params['render'];
if((in_array('scaffold', array_keys($classVars))) && ($missingAction === true))
{
$scaffolding =& new Scaffold($controller, $params);
exit;
}
$controller->constructClasses();
if ($missingAction)
{
$controller->missingAction = $params['action'];
$params['action'] = 'missingAction';
}
return $this->_invoke($controller, $params );
}
/**
* Enter description here...
*
* @param unknown_type $controller
* @param unknown_type $params
* @return unknown
*/
function _invoke (&$controller, $params )
{
$output = call_user_func_array(array(&$controller, $params['action']), empty($params['pass'])? null: $params['pass']);
if ($controller->autoRender)
{
$controller->render();
exit;
}
return $output;
}
/**
* Returns array of GET and POST parameters. GET parameters are taken from given URL.
*
* @param string $from_url URL to mine for parameter information.
* @return array Parameters found in POST and GET.
*/
function parseParams($from_url)
{
// load routes config
$Route = new Router();
include CONFIGS.'routes.php';
$params = $Route->parse ($from_url);
// add submitted form data
$params['form'] = $_POST;
if (isset($_POST['data']))
{
$params['data'] = (ini_get('magic_quotes_gpc') == 1)?
$this->stripslashes_deep($_POST['data']) : $_POST['data'];
}
if (isset($_GET))
{
$params['url'] = $this->urldecode_deep($_GET);
$params['url'] = (ini_get('magic_quotes_gpc') == 1)?
$this->stripslashes_deep($params['url']) : $params['url'];
}
foreach ($_FILES as $name => $data)
{
$params['form'][$name] = $data;
}
$params['bare'] = empty($params['ajax'])? (empty($params['bare'])? 0: 1): 1;
Merging [920] [922] [929] [920] Small bugfix for after condition in AjaxHelper::remoteFunction [922] Fixed Ticket #224 Added patch from Ticket #221 Added patch from Ticket #222 Renamed renderMethod() to requestAction() the name fits better since we are really requesting another objects response. Added a default setting to turn of autoRender for the class you are requesting the action from, this will allow you to request an action and use the return how you like, instead of letting the object output the content directly to the browser if it would normally do so. [929] Adding fix for Itcket #225. Moved code for beforeFilters to first section of Controller::constructClasses(). Removed current implementaion of beforeFilters. This will be changed to pass a reference of the object to the filters through a core filters class. The core filter class will then load the filters and perform all request on the object in the order the filters are arranged in var $beforeFilters, each beforeFilter needs to be a class that the core filter class will create an instance of. If one of the filters fails, it will return the object, untouched and not try to process other filters, an failed var will be set on the controller. This will be done before data base is initialized for the current object that is being filtered. Modifed the requestAction() changes are noted below Using inside of a controller. Default $this->requestAction('/controller/action/argument/'); Request Object to render output directly $this->requestAction('/controller/action/argument/', a('render')); Using a helper object to make request inside of a view: Default $helpername->requestAction('/controller/action/argument/'); Request Object to render output directly $helpername->requestAction('/controller/action/argument/', a('render')); Using the View object "$this" in a view to make request: $this->requestAction('/controller/action/argument/'); Request Object to render output directly $this->requestAction('/controller/action/argument/', a('render')); git-svn-id: https://svn.cakephp.org/repo/trunk/cake@930 3807eeeb-6ff5-0310-8944-8be069107fe0
2005-09-21 05:48:09 +00:00
return $params;
}
/**
* Recursively strips slashes.
*
*/
function stripslashes_deep($val)
{
return (is_array($val)) ?
array_map(array('Dispatcher','stripslashes_deep'), $val) : stripslashes($val);
}
/**
* Recursively performs urldecode.
*
*/
function urldecode_deep($val)
{
return (is_array($val)) ?
array_map(array('Dispatcher','urldecode_deep'), $val) : urldecode($val);
}
/**
* Returns a base URL.
*
* @return string Base URL
*/
function baseUrl()
{
$htaccess = null;
$base = null;
$this->webroot = '';
if (defined('BASE_URL'))
{
$base = BASE_URL;
}
$docRoot = $_SERVER['DOCUMENT_ROOT'];
$scriptName = $_SERVER['PHP_SELF'];
// If document root ends with 'webroot', it's probably correctly set
$r = null;
if (preg_match('/'.APP_DIR.'\\'.DS.WEBROOT_DIR.'/', $docRoot))
{
$this->webroot = '/';
if (preg_match('/^(.*)\/index\.php$/', $scriptName, $r))
{
if(!empty($r[1]))
{
return $r[1];
}
}
}
else
{
if (defined('BASE_URL'))
{
$webroot =setUri();
$htaccess = preg_replace('/(?:'.APP_DIR.'(.*)|index\\.php(.*))/i', '', $webroot).APP_DIR.'/'.WEBROOT_DIR.'/';
}
// Document root is probably not set to Cake 'webroot' dir
if(APP_DIR === 'app')
{
if (preg_match('/^(.*)\\/'.APP_DIR.'\\/'.WEBROOT_DIR.'\\/index\\.php$/', $scriptName, $regs))
{
!empty($htaccess)? $this->webroot = $htaccess : $this->webroot = $regs[1].'/';
return $regs[1];
}
else
{
!empty($htaccess)? $this->webroot = $htaccess : $this->webroot = '/';
return $base;
}
}
else
{
if (preg_match('/^(.*)\\/'.WEBROOT_DIR.'\\/index\\.php$/', $scriptName, $regs))
{
!empty($htaccess)? $this->webroot = $htaccess : $this->webroot = $regs[1].'/';
return $regs[1];
}
else
{
!empty($htaccess)? $this->webroot = $htaccess : $this->webroot = '/';
return $base;
}
}
//Fallback if all others fail
if (preg_match('/^(.*)\\/index\\.php$/', $scriptName, $regs))
{
!empty($htaccess)? $this->webroot = $htaccess : $this->webroot = $regs[1].'/';
return $regs[1];
}
else
{
!empty($htaccess)? $this->webroot = $htaccess : $this->webroot = '/';
return $base;
}
}
return $base;
}
/**
* Displays an error page (e.g. 404 Not found).
*
* @param int $code Error code (e.g. 404)
* @param string $name Name of the error message (e.g. Not found)
* @param string $message
* @return unknown
*/
function error ($code, $name, $message)
{
Merging from sandboxes [1079] Merged [1005] committed by nate but not added to core prior to release. Merged [1078] prior to modifying all developers sandboxes. [1081] adding view and template directories [1082] adding base files for view generator [1083] correcting all package and sub package tags for in doc blocks. Making sure every file in the core has doc block in them [1084] renaming working copy of latest release [1093] Added fix for associations using underscores if var $useTable is set in the associated models. This closes ticket #11. [1094] Fix for Ticket #24. The problem was tracked to a variable in View::_render(); $loadedHelpers was being assigned a reference when it when it should not have been. [1096] Initial work on controller components needs testing. Also added a work around for the basics.php uses(). Using the define DS where the files from the original version are now located in deeper libs directories. [1097] committing a few typos in the code I added [1098] reformatting code in component.php [1104] changed the test route and corrected a regex in inflector. [1111] removing the contructor from dispatcher, it is not needed [1112] Changes made for errors when a file is not present in webroot. Fixed the regex used in Router::parse(). Change the error layout template. [1113] Changes to Folder class to allow setting the permissions mode when constructing. This class needs to be refactored and move everything that is in the contructor out. The constructor should set the vars for use in other Folder::"methods"(). Will work on this at a later time. git-svn-id: https://svn.cakephp.org/repo/trunk/cake@1114 3807eeeb-6ff5-0310-8944-8be069107fe0
2005-10-09 01:56:21 +00:00
$controller =& new Controller ($this);
$controller->base = $this->base;
$controller->autoLayout = false;
$controller->set(array('code'=>$code, 'name'=>$name, 'message'=>$message));
return $controller->render('layouts/error');
}
/**
* Convenience method to display a 404 page.
*
* @param string $url URL that spawned this message, to be included in the output.
* @param string $message Message text for the 404 page.
*/
function error404 ($url, $message)
{
$this->error('404', 'Not found', sprintf(ERROR_404, $url, $message));
}
}
?>