2005-08-21 06:49:02 +00:00
< ? php
/* SVN FILE: $Id$ */
2005-06-30 02:09:47 +00:00
/**
2005-10-18 22:27:39 +00:00
* Parses the request URL into controller , action , and parameters .
2005-12-27 03:33:44 +00:00
*
2005-08-21 06:49:02 +00:00
* Long description for file
*
* PHP versions 4 and 5
*
2007-02-02 10:39:45 +00:00
* CakePHP ( tm ) : Rapid Development Framework < http :// www . cakephp . org />
* Copyright 2005 - 2007 , Cake Software Foundation , Inc .
2006-05-26 05:29:17 +00:00
* 1785 E . Sahara Avenue , Suite 490 - 204
* Las Vegas , Nevada 89104
2005-08-21 06:49:02 +00:00
*
2005-12-23 21:57:26 +00:00
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice .
2005-08-21 06:49:02 +00:00
*
2005-12-27 03:33:44 +00:00
* @ filesource
2007-02-02 10:39:45 +00:00
* @ copyright Copyright 2005 - 2007 , Cake Software Foundation , Inc .
* @ link http :// www . cakefoundation . org / projects / info / cakephp CakePHP ( tm ) Project
2006-05-26 05:29:17 +00:00
* @ package cake
* @ subpackage cake . cake . libs
2007-02-02 10:39:45 +00:00
* @ since CakePHP ( tm ) v 0.2 . 9
2006-05-26 05:29:17 +00:00
* @ version $Revision $
* @ modifiedby $LastChangedBy $
* @ lastmodified $Date $
* @ license http :// www . opensource . org / licenses / mit - license . php The MIT License
2005-08-21 06:49:02 +00:00
*/
/**
2006-02-18 23:42:21 +00:00
* Included libraries .
*
*/
2006-11-22 16:33:50 +00:00
if ( ! class_exists ( 'Object' )) {
2007-02-26 02:11:30 +00:00
uses ( 'object' );
2006-11-22 16:33:50 +00:00
}
2005-06-30 02:09:47 +00:00
/**
2006-02-18 23:42:21 +00:00
* Parses the request URL into controller , action , and parameters .
*
2006-05-26 05:29:17 +00:00
* @ package cake
* @ subpackage cake . cake . libs
2006-02-18 23:42:21 +00:00
*/
2007-02-26 02:11:30 +00:00
class Router extends Object {
2006-09-16 02:10:02 +00:00
2005-06-30 02:09:47 +00:00
/**
2006-02-18 23:42:21 +00:00
* Array of routes
*
* @ var array
*/
2006-09-06 03:41:38 +00:00
var $routes = array ();
2006-04-29 21:51:30 +00:00
/**
* CAKE_ADMIN route
*
* @ var array
*/
2006-09-06 03:41:38 +00:00
var $__admin = null ;
2006-08-12 16:46:42 +00:00
/**
* Directive for Router to parse out file extensions for mapping to Content - types .
*
* @ var boolean
*/
2006-09-06 03:41:38 +00:00
var $__parseExtensions = false ;
2007-02-03 02:32:42 +00:00
/**
2007-02-03 23:10:03 +00:00
* List of valid extensions to parse from a URL . If null , any extension is allowed .
2007-02-03 02:32:42 +00:00
*
2007-02-03 23:10:03 +00:00
* @ var array
2007-02-03 02:32:42 +00:00
*/
2007-02-03 23:10:03 +00:00
var $__validExtensions = null ;
2006-05-26 05:29:17 +00:00
/**
2006-09-06 03:41:38 +00:00
* 'Constant' regular expression definitions for named route elements
2006-05-26 05:29:17 +00:00
*
2006-09-06 03:41:38 +00:00
* @ var array
2006-05-26 05:29:17 +00:00
*/
2006-09-06 03:41:38 +00:00
var $__named = array (
2006-09-10 17:25:44 +00:00
'Action' => 'index|show|list|add|create|edit|update|remove|del|delete|new|view|item' ,
'Year' => '[12][0-9]{3}' ,
'Month' => '(0[1-9]|1[012])' ,
'Day' => '(0[1-9]|[12][0-9]|3[01])' ,
'ID' => '[0-9]+'
2006-09-06 03:41:38 +00:00
);
2006-09-22 16:39:15 +00:00
/**
* The route matching the URL of the current request
*
* @ var array
*/
var $__currentRoute = array ();
2006-09-28 20:29:52 +00:00
/**
* Maintains the parameter stack for the current request
*
* @ var array
*/
var $__params = array ();
/**
* Maintains the path stack for the current request
*
* @ var array
*/
var $__paths = array ();
/**
2007-02-26 02:11:30 +00:00
* Initialize the Router object
*
*/
2006-05-26 05:29:17 +00:00
function __construct () {
if ( defined ( 'CAKE_ADMIN' )) {
$admin = CAKE_ADMIN ;
if ( ! empty ( $admin )) {
2006-12-06 20:38:28 +00:00
$this -> __admin = array (
'/:' . $admin . '/:controller/:action/*' ,
'/^(?:\/(?:(' . $admin . ')(?:\\/([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:\\/([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:[\\/\\?](.*))?)?)?))[\/]*$/' ,
array ( $admin , 'controller' , 'action' ), array ()
);
2006-05-26 05:29:17 +00:00
}
}
}
2006-08-12 13:02:51 +00:00
/**
* Gets a reference to the Router object instance
*
* @ return object
*/
function & getInstance () {
static $instance = array ();
if ( ! isset ( $instance [ 0 ]) || ! $instance [ 0 ]) {
$instance [ 0 ] =& new Router ();
}
return $instance [ 0 ];
}
2006-09-06 03:41:38 +00:00
/**
* Gets the named route elements for use in app / config / routes . php
*
* @ return array
*/
2006-09-10 17:25:44 +00:00
function getNamedExpressions () {
2006-09-06 03:41:38 +00:00
$_this =& Router :: getInstance ();
return $_this -> __named ;
}
2005-06-30 02:09:47 +00:00
/**
2007-02-26 02:11:30 +00:00
* Returns this object ' s routes array . Returns false if there are no routes available .
2006-02-18 23:42:21 +00:00
*
2006-09-06 03:41:38 +00:00
* @ param string $route An empty string , or a route string " / "
* @ param array $default NULL or an array describing the default route
2006-09-10 17:25:44 +00:00
* @ param array $params An array matching the named elements in the route to regular expressions which that element should match .
2006-02-18 23:42:21 +00:00
* @ see routes
2006-05-26 05:29:17 +00:00
* @ return array Array of routes
2006-02-18 23:42:21 +00:00
*/
2006-09-22 16:39:15 +00:00
function connect ( $route , $default = array (), $params = array ()) {
2006-08-12 16:46:42 +00:00
$_this =& Router :: getInstance ();
2007-02-26 02:11:30 +00:00
$parsed = array ();
2006-05-26 05:29:17 +00:00
if ( defined ( 'CAKE_ADMIN' ) && $default == null ) {
if ( $route == CAKE_ADMIN ) {
2006-08-12 13:02:51 +00:00
$_this -> routes [] = $_this -> __admin ;
$_this -> __admin = null ;
2006-05-26 05:29:17 +00:00
}
}
2006-08-12 13:02:51 +00:00
2007-02-02 23:55:47 +00:00
if ( empty ( $default [ 'plugin' ])) {
$default [ 'plugin' ] = null ;
2006-08-31 19:23:11 +00:00
}
2007-02-02 23:55:47 +00:00
if ( empty ( $default [ 'controller' ])) {
$default [ 'controller' ] = null ;
}
if ( ! empty ( $default ) && empty ( $default [ 'action' ])) {
$default [ 'action' ] = 'index' ;
2006-09-28 20:29:52 +00:00
}
2007-02-26 02:11:30 +00:00
if ( $route = $_this -> writeRoute ( $route , $default , $params )) {
$_this -> routes [] = $route ;
}
return $_this -> routes ;
}
/**
2007-03-04 09:12:09 +00:00
* Builds a route regular expression
2007-02-26 02:11:30 +00:00
*
* @ access public
* @ param string $route An empty string , or a route string " / "
* @ param array $default NULL or an array describing the default route
* @ param array $params An array matching the named elements in the route to regular expressions which that element should match .
* @ return string
* @ see routes
*/
function writeRoute ( $route , $default , $params ) {
if ( empty ( $route ) || ( $route == '/' )) {
return array ( $route , '/^[\/]*$/' , array (), $default , array ());
2006-05-26 05:29:17 +00:00
} else {
2007-02-26 02:11:30 +00:00
$names = array ();
$elements = $this -> __filter ( array_map ( 'trim' , explode ( '/' , $route )));
2006-05-26 05:29:17 +00:00
if ( ! count ( $elements )) {
return false ;
}
foreach ( $elements as $element ) {
2006-09-22 16:39:15 +00:00
$q = null ;
2006-05-26 05:29:17 +00:00
if ( preg_match ( '/^:(.+)$/' , $element , $r )) {
2006-09-10 17:25:44 +00:00
if ( isset ( $params [ $r [ 1 ]])) {
2006-12-06 20:38:28 +00:00
if ( array_key_exists ( $r [ 1 ], $default )) {
2006-09-22 16:39:15 +00:00
$q = '?' ;
2006-09-10 17:25:44 +00:00
}
$parsed [] = '(?:\/(' . $params [ $r [ 1 ]] . '))' . $q ;
2006-09-06 03:41:38 +00:00
} else {
$parsed [] = '(?:\/([^\/]+))?' ;
}
2006-08-12 13:02:51 +00:00
$names [] = $r [ 1 ];
2006-05-26 05:29:17 +00:00
} elseif ( preg_match ( '/^\*$/' , $element , $r )) {
$parsed [] = '(?:\/(.*))?' ;
} else {
$parsed [] = '/' . $element ;
}
}
2007-02-26 02:11:30 +00:00
return array ( $route , '#^' . join ( '' , $parsed ) . '[\/]*$#' , $names , $default , $params );
2006-05-26 05:29:17 +00:00
}
}
2005-06-30 02:09:47 +00:00
/**
2006-02-18 23:42:21 +00:00
* Parses given URL and returns an array of controllers , action and parameters
* taken from that URL .
*
* @ param string $url URL to be parsed
* @ return array
*/
2006-05-26 05:29:17 +00:00
function parse ( $url ) {
2006-08-12 16:46:42 +00:00
$_this =& Router :: getInstance ();
2007-02-26 02:11:30 +00:00
$_this -> __connectDefaultRoutes ();
2006-05-26 05:29:17 +00:00
$out = array ();
2007-02-26 02:11:30 +00:00
$r = $ext = null ;
2006-05-26 05:29:17 +00:00
2007-02-26 02:11:30 +00:00
if ( $url && strpos ( $url , '/' ) !== 0 && ! defined ( 'SERVER_IIS' )) {
$url = '/' . $url ;
2006-05-26 05:29:17 +00:00
}
if ( strpos ( $url , '?' ) !== false ) {
$url = substr ( $url , 0 , strpos ( $url , '?' ));
}
2007-02-26 02:11:30 +00:00
extract ( $_this -> __parseExtension ( $url ));
2006-05-26 05:29:17 +00:00
2006-08-12 13:02:51 +00:00
foreach ( $_this -> routes as $route ) {
2006-05-26 05:29:17 +00:00
list ( $route , $regexp , $names , $defaults ) = $route ;
if ( preg_match ( $regexp , $url , $r )) {
2006-09-22 16:39:15 +00:00
$_this -> __currentRoute [] = $route ;
2006-05-26 05:29:17 +00:00
// remove the first element, which is the url
array_shift ( $r );
// hack, pre-fill the default route names
foreach ( $names as $name ) {
$out [ $name ] = null ;
}
if ( is_array ( $defaults )) {
foreach ( $defaults as $name => $value ) {
if ( preg_match ( '#[a-zA-Z_\-]#i' , $name )) {
$out [ $name ] = $value ;
} else {
$out [ 'pass' ][] = $value ;
}
}
}
2007-02-26 02:11:30 +00:00
foreach ( $_this -> __filter ( $r , true ) as $key => $found ) {
2006-05-26 05:29:17 +00:00
// if $found is a named url element (i.e. ':action')
2007-02-26 02:11:30 +00:00
if ( isset ( $names [ $key ])) {
2006-12-26 18:06:42 +00:00
$out [ $names [ $key ]] = $found ;
2007-02-26 02:11:30 +00:00
} else if ( isset ( $names [ $key ]) && empty ( $names [ $key ]) && empty ( $out [ $names [ $key ]])) {
2006-12-26 18:06:42 +00:00
break ; //leave the default values;
2006-05-26 05:29:17 +00:00
} else {
// unnamed elements go in as 'pass'
2007-02-02 23:55:47 +00:00
$out [ 'pass' ] = explode ( '/' , $found );
2006-05-26 05:29:17 +00:00
}
}
break ;
}
}
2006-08-12 16:46:42 +00:00
if ( ! empty ( $ext )) {
2006-08-22 12:08:44 +00:00
$out [ 'url' ][ 'ext' ] = $ext ;
2006-08-12 16:46:42 +00:00
}
2006-05-26 05:29:17 +00:00
return $out ;
}
2007-02-26 02:11:30 +00:00
/**
* Parses a file extension out of a URL , if Router :: parseExtensions () is enabled .
*
* @ param string $url
* @ return array Returns an array containing the altered URL and the parsed extension .
*/
function __parseExtension ( $url ) {
$ext = null ;
$_this =& Router :: getInstance ();
if ( $_this -> __parseExtensions ) {
if ( preg_match ( '/\.[0-9a-zA-Z]*$/' , $url , $match ) == 1 ) {
$match = substr ( $match [ 0 ], 1 );
if ( empty ( $_this -> __validExtensions )) {
$url = substr ( $url , 0 , strpos ( $url , '.' . $match ));
$ext = $match ;
} else {
foreach ( $_this -> __validExtensions as $name ) {
if ( strcasecmp ( $name , $match ) === 0 ) {
$url = substr ( $url , 0 , strpos ( $url , '.' . $name ));
$ext = $match ;
}
}
}
}
}
return compact ( 'ext' , 'url' );
}
/**
* Connects the default , built - in routes , including admin routes , and ( deprecated ) web services
* routes .
*
* @ return void
*/
function __connectDefaultRoutes () {
$_this =& Router :: getInstance ();
$default_route = array (
'/:controller/:action/*' ,
'/^(?:\/(?:([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:\\/([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:[\\/\\?](.*))?)?))[\\/]*$/' ,
array ( 'controller' , 'action' ), array ()
);
if ( defined ( 'CAKE_ADMIN' ) && $_this -> __admin != null ) {
$_this -> routes [] = $_this -> __admin ;
$_this -> __admin = null ;
}
2007-03-06 23:48:25 +00:00
$_this -> connect ( '/bare/:controller/:action/*' , array ( 'bare' => '1' ));
$_this -> connect ( '/ajax/:controller/:action/*' , array ( 'bare' => '1' ));
2007-02-26 02:11:30 +00:00
if ( defined ( 'WEBSERVICES' ) && WEBSERVICES == 'on' ) {
trigger_error ( 'Deprecated: webservices routes are deprecated and will not be supported in future versions. Use Router::parseExtensions() instead.' , E_USER_WARNING );
$_this -> connect ( '/rest/:controller/:action/*' , array ( 'webservices' => 'Rest' ));
$_this -> connect ( '/rss/:controller/:action/*' , array ( 'webservices' => 'Rss' ));
$_this -> connect ( '/soap/:controller/:action/*' , array ( 'webservices' => 'Soap' ));
$_this -> connect ( '/xml/:controller/:action/*' , array ( 'webservices' => 'Xml' ));
$_this -> connect ( '/xmlrpc/:controller/:action/*' , array ( 'webservices' => 'XmlRpc' ));
}
$_this -> routes [] = $default_route ;
}
2006-09-22 16:39:15 +00:00
/**
* Takes parameter and path information back from the Dispatcher
*
* @ param array
* @ return void
*/
2007-02-23 00:14:51 +00:00
function setRequestInfo ( $params ) {
2006-09-22 16:39:15 +00:00
$_this =& Router :: getInstance ();
2006-12-15 16:10:57 +00:00
$defaults = array ( 'plugin' => null , 'controller' => null , 'action' => null );
$params [ 0 ] = am ( $defaults , $params [ 0 ]);
$params [ 1 ] = am ( $defaults , $params [ 1 ]);
2006-09-22 16:39:15 +00:00
list ( $_this -> __params [], $_this -> __paths []) = $params ;
}
2006-10-20 17:24:37 +00:00
/**
* Gets parameter information
*
* @ param boolean $current
* @ return array
*/
function getParams ( $current = false ) {
$_this =& Router :: getInstance ();
2006-12-31 08:27:02 +00:00
if ( $current ) {
return $_this -> __params [ count ( $_this -> __params ) - 1 ];
}
return $_this -> __params [ 0 ];
}
/**
* Gets URL parameter by name
*
* @ param string $name
2007-02-23 00:14:51 +00:00
* @ param boolean $current
2006-12-31 08:27:02 +00:00
* @ return string
*/
2007-02-23 00:14:51 +00:00
function getParam ( $name = 'controller' , $current = false ) {
2006-12-31 08:27:02 +00:00
$_this =& Router :: getInstance ();
2007-02-23 00:14:51 +00:00
$params = Router :: getParams ( $current );
2007-01-20 20:50:57 +00:00
if ( isset ( $params [ $name ])) {
return $params [ $name ];
2006-10-20 17:24:37 +00:00
}
2007-01-20 20:50:57 +00:00
return null ;
2006-10-20 17:24:37 +00:00
}
/**
* Gets path information
*
* @ param boolean $current
* @ return array
*/
function getPaths ( $current = false ) {
$_this =& Router :: getInstance ();
if ( $current ) {
2006-10-26 16:29:10 +00:00
return $_this -> __paths [ count ( $_this -> __paths ) - 1 ];
2006-10-20 17:24:37 +00:00
}
return $_this -> __paths [ 0 ];
}
2006-09-28 20:29:52 +00:00
/**
* Reloads default Router settings
*
* @ return void
*/
function reload () {
$_this =& Router :: getInstance ();
foreach ( get_class_vars ( 'Router' ) as $key => $val ) {
$_this -> { $key } = $val ;
}
}
2007-02-26 02:11:30 +00:00
/**
* Filters empty elements out of a route array , excluding '0' .
*
* @ return mixed
*/
function __filter ( $var , $isArray = false ) {
if ( is_array ( $var ) && ( ! empty ( $var ) || $isArray )) {
$_this =& Router :: getInstance ();
return array_filter ( $var , array ( & $_this , '__filter' ));
2007-02-03 01:03:33 +00:00
} else {
2007-02-26 02:11:30 +00:00
if ( $var === '0' || ! empty ( $var )) {
return true ;
} else {
return false ;
}
2007-02-03 01:03:33 +00:00
}
}
2006-09-22 16:39:15 +00:00
/**
* Finds URL for specified action .
*
* Returns an URL pointing to a combination of controller and action . Param
* $url can be :
* + Empty - the method will find adress to actuall controller / action .
* + '/' - the method will find base URL of application .
* + A combination of controller / action - the method will find url for it .
*
* @ param mixed $url Cake - relative URL , like " /products/edit/92 " or " /presidents/elect/4 "
* or an array specifying any of the following : 'controller' , 'action' ,
* and / or 'plugin' , in addition to named arguments ( keyed array elements ),
* and standard URL arguments ( indexed array elements )
* @ param boolean $full If true , the full base URL will be prepended to the result
* @ return string Full translated URL with base path .
*/
function url ( $url = null , $full = false ) {
$_this =& Router :: getInstance ();
2007-02-26 02:11:30 +00:00
$defaults = $params = array ( 'plugin' => null , 'controller' => null , 'action' => 'index' );
2007-03-04 09:12:09 +00:00
if ( ! empty ( $_this -> __params )) {
$params = end ( $_this -> __params );
2007-02-02 23:55:47 +00:00
}
2007-02-26 02:11:30 +00:00
$path = array ( 'base' => null );
2007-03-04 09:12:09 +00:00
if ( ! empty ( $_this -> __paths )) {
$path = end ( $_this -> __paths );
2007-02-02 23:55:47 +00:00
}
2006-11-08 02:07:11 +00:00
$base = $_this -> stripPlugin ( $path [ 'base' ], $params [ 'plugin' ]);
2006-12-06 20:38:28 +00:00
$extension = $output = $mapped = $q = null ;
2006-09-22 16:39:15 +00:00
if ( is_array ( $url ) && ! empty ( $url )) {
2006-11-03 19:38:54 +00:00
if ( isset ( $url [ 'full_base' ]) && $url [ 'full_base' ] == true ) {
$full = true ;
unset ( $url [ 'full_base' ]);
}
2006-11-10 17:08:31 +00:00
if ( isset ( $url [ '?' ])) {
$q = $url [ '?' ];
unset ( $url [ '?' ]);
}
2006-09-22 16:39:15 +00:00
if ( ! isset ( $url [ 'action' ])) {
if ( ! isset ( $url [ 'controller' ]) || $params [ 'controller' ] == $url [ 'controller' ]) {
$url [ 'action' ] = $params [ 'action' ];
2007-02-26 02:11:30 +00:00
} else {
$url [ 'action' ] = 'index' ;
2006-09-22 16:39:15 +00:00
}
}
2007-02-26 02:11:30 +00:00
$url = am ( array ( 'controller' => $params [ 'controller' ], 'plugin' => $params [ 'plugin' ]), $url );
2006-12-24 04:32:22 +00:00
2006-09-22 16:39:15 +00:00
if ( isset ( $url [ 'ext' ])) {
$extension = '.' . $url [ 'ext' ];
}
2006-12-07 05:58:08 +00:00
if ( defined ( 'CAKE_ADMIN' ) && ! isset ( $url [ CAKE_ADMIN ]) && isset ( $params [ CAKE_ADMIN ])) {
2006-12-25 10:51:08 +00:00
$url [ CAKE_ADMIN ] = CAKE_ADMIN ;
$url [ 'action' ] = str_replace ( CAKE_ADMIN . '_' , '' , $url [ 'action' ]);
2006-12-07 22:41:20 +00:00
} elseif ( defined ( 'CAKE_ADMIN' ) && isset ( $url [ CAKE_ADMIN ]) && $url [ CAKE_ADMIN ] == false ) {
2006-12-07 05:58:08 +00:00
unset ( $url [ CAKE_ADMIN ]);
2006-09-22 16:39:15 +00:00
}
2007-03-04 09:12:09 +00:00
$_this -> __mapped = array ();
2007-02-26 02:11:30 +00:00
$match = false ;
2006-11-10 17:08:31 +00:00
foreach ( $_this -> routes as $route ) {
2007-02-26 02:11:30 +00:00
if ( $match = $_this -> mapRouteElements ( $route , $url )) {
2006-11-10 17:08:31 +00:00
list ( $output , $url ) = $match ;
2007-02-26 02:11:30 +00:00
if ( strpos ( $output , '/' ) === 0 ) {
2006-11-10 17:08:31 +00:00
$output = substr ( $output , 1 );
}
break ;
}
}
2006-09-22 16:39:15 +00:00
$named = $args = array ();
2007-03-04 09:12:09 +00:00
$skip = am ( array_keys ( $_this -> __mapped ), array ( 'bare' , 'action' , 'controller' , 'plugin' , 'ext' , '?' ));
2006-12-25 10:51:08 +00:00
if ( defined ( 'CAKE_ADMIN' )) {
$skip [] = CAKE_ADMIN ;
2006-12-26 13:46:22 +00:00
}
2007-02-26 02:11:30 +00:00
2006-12-25 10:51:08 +00:00
$keys = array_values ( array_diff ( array_keys ( $url ), $skip ));
2006-09-22 16:39:15 +00:00
$count = count ( $keys );
for ( $i = 0 ; $i < $count ; $i ++ ) {
2007-03-04 09:12:09 +00:00
if ( is_numeric ( $keys [ $i ])) {
2006-09-22 16:39:15 +00:00
$args [] = $url [ $keys [ $i ]];
2007-03-04 09:12:09 +00:00
} else if ( ! empty ( $path [ 'namedArgs' ]) && in_array ( $keys [ $i ], array_keys ( $path [ 'namedArgs' ])) && ! empty ( $url [ $keys [ $i ]])) {
$named [] = $keys [ $i ] . $path [ 'argSeparator' ] . $url [ $keys [ $i ]];
} else if ( ! empty ( $url [ $keys [ $i ]])){
$named [] = $keys [ $i ] . $path [ 'argSeparator' ] . $url [ $keys [ $i ]];
2006-09-28 20:29:52 +00:00
}
}
2007-03-04 09:12:09 +00:00
2006-11-10 17:08:31 +00:00
if ( $match === false ) {
2007-02-05 23:45:26 +00:00
if ( empty ( $named ) && empty ( $args ) && ( ! isset ( $url [ 'action' ]) || $url [ 'action' ] == 'index' )) {
2006-11-10 17:08:31 +00:00
$url [ 'action' ] = null ;
2006-09-22 16:39:15 +00:00
}
2007-03-04 09:12:09 +00:00
$urlOut = $_this -> __filter ( array ( $url [ 'plugin' ], $url [ 'controller' ], $url [ 'action' ]));
2007-02-03 01:03:33 +00:00
2006-12-25 10:51:08 +00:00
if ( $url [ 'plugin' ] == $url [ 'controller' ]) {
array_shift ( $urlOut );
}
2006-11-10 17:08:31 +00:00
if ( defined ( 'CAKE_ADMIN' ) && isset ( $url [ CAKE_ADMIN ]) && $url [ CAKE_ADMIN ]) {
array_unshift ( $urlOut , CAKE_ADMIN );
}
$output = join ( '/' , $urlOut );
2006-09-22 16:39:15 +00:00
}
2007-03-04 09:12:09 +00:00
if ( ! empty ( $args )) {
if ( $output { strlen ( $output ) - 1 } == '/' ) {
$output .= join ( '/' , $_this -> __filter ( $args , true ));
} else {
$output .= '/' . join ( '/' , $_this -> __filter ( $args , true ));
}
}
if ( ! empty ( $named )) {
if ( $output { strlen ( $output ) - 1 } == '/' ) {
$output .= join ( '/' , $_this -> __filter ( $named , true ));
} else {
$output .= '/' . join ( '/' , $_this -> __filter ( $named , true ));
}
}
$output = str_replace ( '//' , '/' , $base . '/' . $output );
2006-09-22 16:39:15 +00:00
} else {
2007-02-18 15:25:56 +00:00
if ((( strpos ( $url , '://' )) || ( strpos ( $url , 'javascript:' ) === 0 ) || ( strpos ( $url , 'mailto:' ) === 0 )) || ( substr ( $url , 0 , 1 ) == '#' )) {
2006-09-22 16:39:15 +00:00
return $url ;
}
if ( empty ( $url )) {
2006-09-28 20:29:52 +00:00
return $path [ 'here' ];
2006-09-22 16:39:15 +00:00
} elseif ( $url { 0 } == '/' ) {
$output = $base . $url ;
} else {
2006-12-07 18:59:58 +00:00
$output = $base . '/' ;
2006-12-07 22:41:20 +00:00
if ( defined ( 'CAKE_ADMIN' ) && isset ( $params [ CAKE_ADMIN ])) {
2006-12-07 18:59:58 +00:00
$output .= CAKE_ADMIN . '/' ;
}
$output .= strtolower ( $params [ 'controller' ]) . '/' . $url ;
2006-09-22 16:39:15 +00:00
}
}
if ( $full ) {
$output = FULL_BASE_URL . $output ;
}
2006-11-10 17:08:31 +00:00
return $output . $extension . $_this -> queryString ( $q );
2006-09-22 16:39:15 +00:00
}
2006-09-28 20:29:52 +00:00
/**
2006-11-08 02:07:11 +00:00
* Maps a URL array onto a route and returns the string result , or false if no match
2006-09-28 20:29:52 +00:00
*
* @ param array Route
* @ param array URL
* @ return mixed
*/
function mapRouteElements ( $route , $url ) {
2007-02-26 02:11:30 +00:00
$_this =& Router :: getInstance ();
2006-12-06 20:38:28 +00:00
$params = $route [ 2 ];
2007-03-04 09:12:09 +00:00
$defaults = am ( array ( 'plugin' => null , 'controller' => null , 'action' => null ), $route [ 3 ]);
2007-02-26 02:11:30 +00:00
2007-03-04 09:12:09 +00:00
$pass = Set :: diff ( $url , $defaults );
foreach ( $pass as $key => $value ) {
2007-03-07 07:53:43 +00:00
if ( ! is_numeric ( $key )) {
2007-03-04 09:12:09 +00:00
unset ( $pass [ $key ]);
2007-02-26 02:11:30 +00:00
}
}
if ( ! strpos ( $route [ 0 ], '*' ) && ! empty ( $pass )) {
return false ;
}
2007-03-07 07:53:43 +00:00
/* removing this for now
2007-02-26 02:11:30 +00:00
foreach ( $defaults as $key => $default ) {
if ( ! array_key_exists ( $key , $url ) && ( ! is_numeric ( $key ) || ! isset ( $pass [ $key ]))) {
2007-02-02 23:55:47 +00:00
$url [ $key ] = $default ;
}
}
2007-03-07 07:53:43 +00:00
*/
2007-02-02 23:55:47 +00:00
krsort ( $defaults );
krsort ( $url );
2007-02-26 02:11:30 +00:00
if ( Set :: diff ( $defaults , $url ) == array ()) {
return array ( Router :: __mapRoute ( $route , am ( $url , array ( 'pass' => $pass ))), array ());
} elseif ( ! empty ( $params ) && ! empty ( $route [ 3 ])) {
2007-02-02 23:55:47 +00:00
$required = array_diff ( array_keys ( $defaults ), array_keys ( $url ));
2006-12-25 10:51:08 +00:00
if ( ! empty ( $required )) {
return false ;
}
2007-02-02 23:55:47 +00:00
2006-12-06 20:38:28 +00:00
$filled = array_intersect_key ( $url , array_combine ( $params , array_keys ( $params )));
$keysFilled = array_keys ( $filled );
sort ( $params );
sort ( $keysFilled );
2007-02-26 02:11:30 +00:00
2006-12-06 20:38:28 +00:00
if ( $keysFilled != $params ) {
return false ;
}
2007-02-26 02:11:30 +00:00
if ( Set :: diff ( $keysFilled , $params ) != array ()) {
2006-12-25 10:51:08 +00:00
return false ;
}
2006-12-07 05:58:08 +00:00
} else {
2007-02-02 23:55:47 +00:00
$required = array_diff ( array_keys ( $defaults ), array_keys ( $url ));
if ( empty ( $required ) && $defaults [ 'plugin' ] == $url [ 'plugin' ] && $defaults [ 'controller' ] == $url [ 'controller' ] && $defaults [ 'action' ] == $url [ 'action' ]) {
2007-03-04 09:12:09 +00:00
return array ( Router :: __mapRoute ( $route , am ( $url , array ( 'pass' => $pass ))), $url );
2007-02-02 23:55:47 +00:00
}
2006-12-07 05:58:08 +00:00
return false ;
2006-12-06 20:38:28 +00:00
}
2007-02-02 23:55:47 +00:00
2007-02-26 02:11:30 +00:00
if ( isset ( $route [ 3 ][ 'controller' ]) && ! empty ( $route [ 3 ][ 'controller' ]) && $url [ 'controller' ] != $route [ 3 ][ 'controller' ]) {
2007-02-02 23:55:47 +00:00
return false ;
}
2007-02-26 02:11:30 +00:00
if ( ! empty ( $route [ 4 ])) {
2006-12-25 10:51:08 +00:00
foreach ( $route [ 4 ] as $key => $reg ) {
if ( isset ( $url [ $key ]) && ! preg_match ( '/' . $reg . '/' , $url [ $key ])) {
return false ;
}
2006-11-10 17:08:31 +00:00
}
}
2007-02-26 02:11:30 +00:00
return array ( Router :: __mapRoute ( $route , am ( $url , array ( 'pass' => $pass ))), $url );
2006-12-06 20:38:28 +00:00
}
/**
* Merges URL parameters into a route string
*
* @ param array Route
* @ param array $params
* @ return string
*/
function __mapRoute ( $route , $params = array ()) {
2007-02-26 02:11:30 +00:00
$_this =& Router :: getInstance ();
2006-12-06 20:38:28 +00:00
if ( isset ( $params [ 'pass' ]) && is_array ( $params [ 'pass' ])) {
2007-03-07 07:53:43 +00:00
$_this -> __mapped = $params [ 'pass' ];
2007-03-04 09:12:09 +00:00
$params [ 'pass' ] = implode ( '/' , $_this -> __filter ( $params [ 'pass' ], true ));
2006-12-06 20:38:28 +00:00
} elseif ( ! isset ( $params [ 'pass' ])) {
$params [ 'pass' ] = '' ;
}
if ( strpos ( $route [ 0 ], '*' )) {
$out = str_replace ( '*' , $params [ 'pass' ], $route [ 0 ]);
} else {
2007-02-26 02:11:30 +00:00
$out = $route [ 0 ];
2006-12-06 20:38:28 +00:00
}
2006-12-29 04:16:53 +00:00
2006-11-10 17:08:31 +00:00
foreach ( $route [ 2 ] as $key ) {
2006-12-06 20:38:28 +00:00
$out = str_replace ( ':' . $key , $params [ $key ], $out );
2007-03-04 09:12:09 +00:00
$_this -> __mapped [ $key ] = $params [ $key ];
2006-12-06 20:38:28 +00:00
unset ( $params [ $key ]);
2006-11-10 17:08:31 +00:00
}
2007-02-26 02:11:30 +00:00
2007-03-04 09:12:09 +00:00
return $out ;
2006-11-10 17:08:31 +00:00
}
/**
* Generates a well - formed querystring from $q
*
* @ param mixed Querystring
* @ param array Extra querystring parameters
* @ return array
*/
function queryString ( $q , $extra = array ()) {
2007-02-26 02:11:30 +00:00
if ( empty ( $q ) && empty ( $extra )) {
2006-11-10 17:08:31 +00:00
return null ;
2006-11-08 02:07:11 +00:00
}
2007-02-26 02:11:30 +00:00
$out = '' ;
if ( is_array ( $q )) {
$q = am ( $extra , $q );
} else {
$out = $q ;
$q = $extra ;
}
$out .= http_build_query ( $q );
if ( strpos ( $out , '?' ) !== 0 ) {
$out = '?' . $out ;
}
return $out ;
2006-09-28 20:29:52 +00:00
}
2006-09-22 16:39:15 +00:00
/**
2007-02-26 02:11:30 +00:00
* Returns the route matching the current request URL .
2006-09-22 16:39:15 +00:00
*
* @ return array
*/
function requestRoute () {
$_this =& Router :: getInstance ();
return $_this -> __currentRoute [ 0 ];
}
/**
* Returns the route matching the current request ( useful for requestAction traces )
*
* @ return array
*/
function currentRoute () {
$_this =& Router :: getInstance ();
return $_this -> __currentRoute [ count ( $_this -> __currentRoute ) - 1 ];
}
2006-11-08 02:07:11 +00:00
/**
2007-02-26 02:11:30 +00:00
* Removes the plugin name from the base URL .
2006-11-08 02:07:11 +00:00
*
* @ param string $base
* @ param string $plugin
* @ return base url with plugin name removed if present
*/
function stripPlugin ( $base , $plugin ) {
if ( $plugin != null ) {
$base = preg_replace ( '/' . $plugin . '/' , '' , $base );
$base = str_replace ( '//' , '' , $base );
$pos1 = strrpos ( $base , '/' );
$char = strlen ( $base ) - 1 ;
if ( $pos1 == $char ) {
$base = substr ( $base , 0 , $char );
}
}
return $base ;
}
2006-08-12 16:46:42 +00:00
/**
2006-11-03 19:38:54 +00:00
* Instructs the router to parse out file extensions from the URL . For example ,
2006-11-14 16:20:52 +00:00
* http :// example . com / posts . rss would yield an file extension of " rss " .
2006-11-03 19:38:54 +00:00
* The file extension itself is made available in the controller as
* $this -> params [ 'url' ][ 'ext' ], and is used by the RequestHandler component to
* automatically switch to alternate layouts and templates , and load helpers
* corresponding to the given content , i . e . RssHelper .
2006-08-12 16:46:42 +00:00
*
2007-02-26 02:11:30 +00:00
* A list of valid extension can be passed to this method , i . e . Router :: parseExtensions ( 'rss' , 'xml' );
* If no parameters are given , anything after the first . ( dot ) after the last / in the URL will be
* parsed , excluding querystring parameters ( i . e . ? q =... ) .
2007-02-03 02:32:42 +00:00
*
2007-02-03 21:47:38 +00:00
* @ param string $ext
* @ param string $ext
* @ param string $ext
* @ param string ...
2006-08-12 16:46:42 +00:00
* @ return void
*/
2007-02-03 21:47:38 +00:00
function parseExtensions () {
2006-08-12 16:46:42 +00:00
$_this =& Router :: getInstance ();
$_this -> __parseExtensions = true ;
2007-02-03 21:47:38 +00:00
if ( func_num_args () > 0 ) {
$_this -> __validExtensions = func_get_args ();
}
2006-08-12 16:46:42 +00:00
}
2005-06-30 02:09:47 +00:00
}
2007-02-26 02:11:30 +00:00
/**
* Implements http_build_query for PHP4 .
*
* @ param string $data
* @ param string $prefix
* @ param string $argSep
* @ param string $baseKey
* @ return string
* @ see http :// php . net / http_build_query
*/
if ( ! function_exists ( 'http_build_query' )) {
function http_build_query ( $data , $prefix = null , $argSep = null , $baseKey = null ) {
if ( empty ( $argSep )) {
$argSep = ini_get ( 'arg_separator.output' );
}
if ( is_object ( $data )) {
$data = get_object_vars ( $data );
}
$out = array ();
foreach (( array ) $data as $key => $val ) {
if ( is_numeric ( $key ) && ! empty ( $prefix )) {
$key = $prefix . $key ;
}
$key = urlencode ( $key );
if ( ! empty ( $baseKey )) {
$key = $baseKey . '[' . $key . ']' ;
}
if ( is_array ( $v ) || is_object ( $v )) {
$out [] = http_build_query ( $v , $prefix , $argSep , $key );
} else {
$out [] = $k . '=' . urlencode ( $v );
}
}
return implode ( $argSep , $out );
}
}
2006-08-12 13:02:51 +00:00
2007-03-04 09:12:09 +00:00
?>