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
2007-05-26 06:26:06 +00:00
* @ access public
2006-02-18 23:42:21 +00:00
*/
2006-09-06 03:41:38 +00:00
var $routes = array ();
2006-04-29 21:51:30 +00:00
/**
* CAKE_ADMIN route
*
* @ var array
2007-05-26 06:26:06 +00:00
* @ access private
2006-04-29 21:51:30 +00:00
*/
2006-09-06 03:41:38 +00:00
var $__admin = null ;
2007-08-16 05:44:06 +00:00
/**
* List of action prefixes used in connected routes
*
* @ var array
* @ access private
*/
var $__prefixes = array ();
2006-08-12 16:46:42 +00:00
/**
* Directive for Router to parse out file extensions for mapping to Content - types .
*
* @ var boolean
2007-05-26 06:26:06 +00:00
* @ access private
2006-08-12 16:46:42 +00:00
*/
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-05-26 06:26:06 +00:00
* @ access private
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
2007-05-26 06:26:06 +00:00
* @ access private
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}' ,
2007-04-12 07:17:39 +00:00
'Month' => '0[1-9]|1[012]' ,
'Day' => '0[1-9]|[12][0-9]|3[01]' ,
2007-12-08 16:59:57 +00:00
'ID' => '[0-9]+' ,
'UUID' => '[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}'
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
2007-05-26 06:26:06 +00:00
* @ access private
2006-09-22 16:39:15 +00:00
*/
var $__currentRoute = array ();
2007-07-24 13:50:50 +00:00
/**
* HTTP header shortcut map . Used for evaluating header - based route expressions .
*
* @ var array
* @ access private
*/
var $__headerMap = array (
'type' => 'content_type' ,
'method' => 'request_method' ,
'server' => 'server_name'
);
/**
* Default HTTP request method => controller action map .
*
* @ var array
* @ access private
*/
var $__resourceMap = array (
2007-08-14 18:51:34 +00:00
array ( 'action' => 'index' , 'method' => 'GET' , 'id' => false ),
array ( 'action' => 'view' , 'method' => 'GET' , 'id' => true ),
array ( 'action' => 'add' , 'method' => 'POST' , 'id' => false ),
array ( 'action' => 'edit' , 'method' => 'PUT' , 'id' => true ),
array ( 'action' => 'delete' , 'method' => 'DELETE' , 'id' => true ),
array ( 'action' => 'edit' , 'method' => 'POST' , 'id' => true )
2007-07-24 13:50:50 +00:00
);
2007-08-14 18:51:34 +00:00
/**
* List of resource - mapped controllers
*
* @ var array
* @ access private
*/
var $__resourceMapped = array ();
2006-09-28 20:29:52 +00:00
/**
* Maintains the parameter stack for the current request
*
* @ var array
2007-05-26 06:26:06 +00:00
* @ access private
2006-09-28 20:29:52 +00:00
*/
var $__params = array ();
2007-08-16 16:31:50 +00:00
/**
* List of named arguments allowed in routes
*
* @ var array
* @ access private
*/
var $__namedArgs = array ();
/**
* Separator used to join / split / detect named arguments
*
* @ var string
* @ access private
*/
var $__argSeparator = ':' ;
2006-09-28 20:29:52 +00:00
/**
* Maintains the path stack for the current request
*
* @ var array
2007-05-26 06:26:06 +00:00
* @ access private
2006-09-28 20:29:52 +00:00
*/
var $__paths = array ();
2007-08-16 16:31:50 +00:00
/**
* Keeps Router state to determine if default routes have already been connected
*
* @ var boolean
* @ access private
*/
var $__defaultsMapped = false ;
2006-08-12 13:02:51 +00:00
/**
* Gets a reference to the Router object instance
*
2007-05-26 06:26:06 +00:00
* @ return object Object instance
* @ access public
* @ static
2006-08-12 13:02:51 +00:00
*/
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
*
2007-05-26 06:26:06 +00:00
* @ return array Named route elements
* @ access public
* @ static
2006-09-06 03:41:38 +00:00
*/
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
2007-05-26 06:26:06 +00:00
* @ access public
* @ static
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-08-16 16:31:50 +00:00
$admin = Configure :: read ( 'Routing.admin' );
2007-12-08 06:08:03 +00:00
$default = array_merge ( array ( 'plugin' => null , 'controller' => null , 'action' => null ), $default );
2006-08-12 13:02:51 +00:00
2007-02-02 23:55:47 +00:00
if ( ! empty ( $default ) && empty ( $default [ 'action' ])) {
$default [ 'action' ] = 'index' ;
2006-09-28 20:29:52 +00:00
}
2007-08-16 05:44:06 +00:00
if ( isset ( $default [ 'prefix' ])) {
$_this -> __prefixes [] = $default [ 'prefix' ];
$_this -> __prefixes = array_unique ( $_this -> __prefixes );
}
2007-02-26 02:11:30 +00:00
if ( $route = $_this -> writeRoute ( $route , $default , $params )) {
$_this -> routes [] = $route ;
}
return $_this -> routes ;
}
2007-08-16 16:31:50 +00:00
/**
* Connects an array of named arguments ( with optional scoping options )
*
* @ param array $named List of named arguments
* @ param array $options Named argument handling options
* @ access public
* @ static
*/
function connectNamed ( $named , $options = array ()) {
$_this =& Router :: getInstance ();
if ( isset ( $options [ 'argSeparator' ])) {
$_this -> __argSeparator = $options [ 'argSeparator' ];
}
foreach ( $named as $key => $val ) {
if ( is_numeric ( $key )) {
$_this -> __namedArgs [ $val ] = true ;
} else {
$_this -> __namedArgs [ $key ] = $val ;
}
}
}
2007-07-24 13:50:50 +00:00
/**
* Creates REST resource routes for the given controller ( s )
*
* @ param mixed $controller A controller name or array of controller names ( i . e . " Posts " or " ListItems " )
2007-07-27 02:46:30 +00:00
* @ param array $options
2007-07-24 13:50:50 +00:00
* @ access public
* @ static
*/
function mapResources ( $controller , $options = array ()) {
$_this =& Router :: getInstance ();
2007-12-08 16:59:57 +00:00
$options = array_merge ( array ( 'prefix' => '/' ), $options );
2007-07-24 13:50:50 +00:00
$prefix = $options [ 'prefix' ];
2007-09-26 09:49:01 +00:00
foreach (( array ) $controller as $ctlName ) {
2007-07-24 13:50:50 +00:00
$urlName = Inflector :: underscore ( $ctlName );
2007-08-14 18:51:34 +00:00
foreach ( $_this -> __resourceMap as $params ) {
extract ( $params );
$id = ife ( $id , '/:id' , '' );
2007-07-24 13:50:50 +00:00
Router :: connect (
" { $prefix } { $urlName } { $id } " ,
2007-12-08 16:59:57 +00:00
array ( 'controller' => $urlName , 'action' => $action , '[method]' => $params [ 'method' ]),
array ( 'id' => $_this -> __named [ 'ID' ] . '|' . $_this -> __named [ 'UUID' ])
2007-07-24 13:50:50 +00:00
);
}
2007-08-14 18:51:34 +00:00
$this -> __resourceMapped [] = $urlName ;
2007-07-24 13:50:50 +00:00
}
}
2007-02-26 02:11:30 +00:00
/**
2007-03-04 09:12:09 +00:00
* Builds a route regular expression
2007-02-26 02:11:30 +00:00
*
* @ 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
2007-05-26 06:26:06 +00:00
* @ access public
* @ static
2007-02-26 02:11:30 +00:00
*/
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 ();
2007-04-17 07:00:26 +00:00
$elements = Set :: filter ( array_map ( 'trim' , explode ( '/' , $route )));
2006-05-26 05:29:17 +00:00
2007-06-20 06:15:35 +00:00
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 ]])) {
2007-08-16 16:31:50 +00:00
if ( array_key_exists ( $r [ 1 ], $default ) && $r [ 1 ] != 'plugin' ) {
2006-09-22 16:39:15 +00:00
$q = '?' ;
2006-09-10 17:25:44 +00:00
}
2007-10-29 21:33:20 +00:00
$parsed [] = '(?:\/(' . $params [ $r [ 1 ]] . ')' . $q . ')' . $q ;
2006-09-06 03:41:38 +00:00
} else {
$parsed [] = '(?:\/([^\/]+))?' ;
}
2006-08-12 13:02:51 +00:00
$names [] = $r [ 1 ];
2007-06-20 06:15:35 +00:00
} elseif ( preg_match ( '/^\*$/' , $element , $r )) {
2006-05-26 05:29:17 +00:00
$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
}
}
2007-08-16 05:44:06 +00:00
/**
* Returns the list of prefixes used in connected routes
*
* @ return array A list of prefixes used in connected routes
* @ access public
* @ static
*/
function prefixes () {
$_this =& Router :: getInstance ();
return $_this -> __prefixes ;
}
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
2007-05-26 06:26:06 +00:00
* @ return array Parsed elements from URL
* @ access public
* @ static
2006-02-18 23:42:21 +00:00
*/
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 ();
2007-10-31 03:53:41 +00:00
$out = array ( 'pass' => array (), 'named' => array ());
2007-02-26 02:11:30 +00:00
$r = $ext = null ;
2006-05-26 05:29:17 +00:00
2007-10-22 04:31:34 +00:00
if ( ini_get ( 'magic_quotes_gpc' ) == 1 ) {
$url = stripslashes_deep ( $url );
}
2007-03-28 16:42:11 +00:00
if ( $url && strpos ( $url , '/' ) !== 0 ) {
2007-02-26 02:11:30 +00:00
$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
2007-06-20 06:15:35 +00:00
foreach ( $_this -> routes as $route ) {
2007-07-24 13:50:50 +00:00
if (( $r = $_this -> matchRoute ( $route , $url )) !== false ) {
2006-09-22 16:39:15 +00:00
$_this -> __currentRoute [] = $route ;
2007-07-24 13:50:50 +00:00
list ( $route , $regexp , $names , $defaults ) = $route ;
2006-09-22 16:39:15 +00:00
2006-05-26 05:29:17 +00:00
// remove the first element, which is the url
2007-07-24 13:50:50 +00:00
array_shift ( $r );
2006-05-26 05:29:17 +00:00
// hack, pre-fill the default route names
2007-06-20 06:15:35 +00:00
foreach ( $names as $name ) {
2006-05-26 05:29:17 +00:00
$out [ $name ] = null ;
}
if ( is_array ( $defaults )) {
2007-06-20 06:15:35 +00:00
foreach ( $defaults as $name => $value ) {
2006-05-26 05:29:17 +00:00
if ( preg_match ( '#[a-zA-Z_\-]#i' , $name )) {
2007-07-27 17:51:33 +00:00
$out [ $name ] = $value ;
2006-05-26 05:29:17 +00:00
} else {
2007-07-27 17:51:33 +00:00
$out [ 'pass' ][] = $value ;
2006-05-26 05:29:17 +00:00
}
}
}
2007-06-20 06:15:35 +00:00
foreach ( Set :: 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 ])) {
2007-07-27 17:51:33 +00:00
$out [ $names [ $key ]] = $_this -> stripEscape ( $found );
2007-06-20 06:15:35 +00:00
} elseif ( 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 {
2007-10-31 03:53:41 +00:00
extract ( $_this -> getArgs ( $found ));
2007-12-08 06:08:03 +00:00
$out [ 'pass' ] = array_merge ( $out [ 'pass' ], $pass );
2007-10-31 03:53:41 +00:00
$out [ 'named' ] = $named ;
2006-05-26 05:29:17 +00:00
}
}
break ;
}
}
2007-09-26 09:49:01 +00:00
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-07-24 13:50:50 +00:00
/**
* Checks to see if the given URL matches the given route
*
* @ param array $route
* @ param string $url
* @ return mixed Boolean false on failure , otherwise array
* @ access public
*/
function matchRoute ( $route , $url ) {
$_this =& Router :: getInstance ();
list ( $route , $regexp , $names , $defaults ) = $route ;
if ( ! preg_match ( $regexp , $url , $r )) {
return false ;
} else {
foreach ( $defaults as $key => $val ) {
if ( preg_match ( '/^\[(\w+)\]$/' , $key , $header )) {
if ( isset ( $_this -> __headerMap [ $header [ 1 ]])) {
$header = $_this -> __headerMap [ $header [ 1 ]];
} else {
$header = 'http_' . $header [ 1 ];
}
2007-12-25 10:25:42 +00:00
if ( ! is_array ( $val )) {
$val = array ( $val );
}
$h = false ;
foreach ( $val as $v ) {
if ( env ( strtoupper ( $header )) == $v ) {
$h = true ;
}
}
if ( ! $h ) {
2007-07-24 13:50:50 +00:00
return false ;
}
}
}
}
return $r ;
}
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 .
2007-05-26 06:26:06 +00:00
* @ access private
2007-02-26 02:11:30 +00:00
*/
function __parseExtension ( $url ) {
$ext = null ;
$_this =& Router :: getInstance ();
if ( $_this -> __parseExtensions ) {
2007-06-20 06:15:35 +00:00
if ( preg_match ( '/\.[0-9a-zA-Z]*$/' , $url , $match ) == 1 ) {
2007-02-26 02:11:30 +00:00
$match = substr ( $match [ 0 ], 1 );
2007-06-20 06:15:35 +00:00
if ( empty ( $_this -> __validExtensions )) {
2007-02-26 02:11:30 +00:00
$url = substr ( $url , 0 , strpos ( $url , '.' . $match ));
$ext = $match ;
} else {
2007-06-20 06:15:35 +00:00
foreach ( $_this -> __validExtensions as $name ) {
if ( strcasecmp ( $name , $match ) === 0 ) {
2007-02-26 02:11:30 +00:00
$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 .
*
2007-05-26 06:26:06 +00:00
* @ access private
2007-02-26 02:11:30 +00:00
*/
function __connectDefaultRoutes () {
$_this =& Router :: getInstance ();
2007-08-16 16:31:50 +00:00
if ( $_this -> __defaultsMapped ) {
return ;
}
2007-02-26 02:11:30 +00:00
2007-08-16 05:44:06 +00:00
if ( $admin = Configure :: read ( 'Routing.admin' )) {
$params = array ( 'prefix' => $admin , $admin => true );
2007-08-16 16:31:50 +00:00
}
$Inflector =& Inflector :: getInstance ();
$plugins = array_map ( array ( & $Inflector , 'underscore' ), Configure :: listObjects ( 'plugin' ));
if ( ! empty ( $plugins )) {
$match = array ( 'plugin' => implode ( '|' , $plugins ));
$_this -> connect ( '/:plugin/:controller/:action/*' , array (), $match );
if ( $admin ) {
$_this -> connect ( " / { $admin } /:plugin/:controller " , $params , $match );
$_this -> connect ( " / { $admin } /:plugin/:controller/:action/* " , $params , $match );
}
}
if ( $admin ) {
2007-08-16 05:44:06 +00:00
$_this -> connect ( " / { $admin } /:controller " , $params );
$_this -> connect ( " / { $admin } /:controller/:action/* " , $params );
2007-02-26 02:11:30 +00:00
}
2007-08-14 18:51:34 +00:00
$_this -> connect ( '/:controller' , array ( 'action' => 'index' ));
2007-08-16 05:44:06 +00:00
/**
* Deprecated
*
*/
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
2007-08-16 05:44:06 +00:00
if ( Configure :: read ( 'Routing.webservices' ) == 'on' ) {
2007-02-26 02:11:30 +00:00
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' ));
}
2007-08-15 14:18:39 +00:00
$_this -> connect ( '/:controller/:action/*' );
2007-10-24 15:09:40 +00:00
if ( empty ( $_this -> __namedArgs )) {
$_this -> connectNamed ( array ( 'page' , 'fields' , 'order' , 'limit' , 'recursive' , 'sort' , 'direction' , 'step' ));
}
2007-08-16 16:31:50 +00:00
$_this -> __defaultsMapped = true ;
2007-02-26 02:11:30 +00:00
}
2006-09-22 16:39:15 +00:00
/**
* Takes parameter and path information back from the Dispatcher
*
2007-05-26 06:26:06 +00:00
* @ param array $params Parameters and path information
* @ access public
* @ static
2006-09-22 16:39:15 +00:00
*/
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 );
2007-12-08 06:08:03 +00:00
$params [ 0 ] = array_merge ( $defaults , ( array ) $params [ 0 ]);
$params [ 1 ] = array_merge ( $defaults , ( array ) $params [ 1 ]);
2006-09-22 16:39:15 +00:00
list ( $_this -> __params [], $_this -> __paths []) = $params ;
2007-10-22 00:07:39 +00:00
if ( count ( $_this -> __paths )) {
if ( isset ( $_this -> __paths [ 0 ][ 'namedArgs' ])) {
foreach ( $_this -> __paths [ 0 ][ 'namedArgs' ] as $arg => $value ) {
$_this -> __namedArgs [ $arg ] = true ;
}
}
}
2006-09-22 16:39:15 +00:00
}
2006-10-20 17:24:37 +00:00
/**
* Gets parameter information
*
2007-10-22 16:54:36 +00:00
* @ param boolean $current Get current parameter ( true )
2007-05-26 06:26:06 +00:00
* @ return array Parameter information
* @ access public
* @ static
2006-10-20 17:24:37 +00:00
*/
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
*
2007-05-26 06:26:06 +00:00
* @ param string $name Parameter name
2007-10-22 16:54:36 +00:00
* @ param boolean $current Current parameter
2007-05-26 06:26:06 +00:00
* @ return string Parameter value
* @ access public
* @ static
2006-12-31 08:27:02 +00:00
*/
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
*
2007-10-22 16:54:36 +00:00
* @ param boolean $current Current parameter
2006-10-20 17:24:37 +00:00
* @ return array
2007-05-26 06:26:06 +00:00
* @ access public
* @ static
2006-10-20 17:24:37 +00:00
*/
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
}
2007-12-13 07:03:59 +00:00
if ( ! isset ( $_this -> __paths [ 0 ])) {
return array ( 'base' => null );
}
2006-10-20 17:24:37 +00:00
return $_this -> __paths [ 0 ];
}
2006-09-28 20:29:52 +00:00
/**
* Reloads default Router settings
*
2007-05-26 06:26:06 +00:00
* @ access public
* @ static
2006-09-28 20:29:52 +00:00
*/
function reload () {
$_this =& Router :: getInstance ();
foreach ( get_class_vars ( 'Router' ) as $key => $val ) {
$_this -> { $key } = $val ;
}
}
2007-08-16 05:44:06 +00:00
/**
* Promote a route ( by default , the last one added ) to the beginning of the list
*
* @ param $which A zero - based array index representing the route to move . For example ,
* if 3 routes have been added , the last route would be 2.
2007-10-22 16:09:35 +00:00
* @ return boolean Retuns false if no route exists at the position specified by $which .
2007-08-16 05:44:06 +00:00
* @ access public
* @ static
*/
function promote ( $which = null ) {
$_this =& Router :: getInstance ();
if ( $which == null ) {
$which = count ( $_this -> routes ) - 1 ;
}
if ( ! isset ( $_this -> routes [ $which ])) {
return false ;
}
2007-08-16 16:31:50 +00:00
$route = $_this -> routes [ $which ];
2007-08-16 05:44:06 +00:00
unset ( $_this -> routes [ $which ]);
2007-08-16 16:31:50 +00:00
array_unshift ( $_this -> routes , $route );
2007-08-16 05:44:06 +00:00
return true ;
}
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 )
2007-10-22 16:54:36 +00:00
* @ param boolean $full If true , the full base URL will be prepended to the result
2006-09-22 16:39:15 +00:00
* @ return string Full translated URL with base path .
2007-05-26 06:26:06 +00:00
* @ access public
* @ static
2006-09-22 16:39:15 +00:00
*/
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-08-20 13:09:11 +00:00
$admin = Configure :: read ( 'Routing.admin' );
2007-03-04 09:12:09 +00:00
2007-06-20 06:15:35 +00:00
if ( ! empty ( $_this -> __params )) {
2007-06-22 01:25:35 +00:00
if ( isset ( $this ) && ! isset ( $this -> params [ 'requested' ])) {
2007-04-02 19:20:50 +00:00
$params = $_this -> __params [ 0 ];
2007-06-22 01:25:35 +00:00
} else {
2007-04-02 19:20:50 +00:00
$params = end ( $_this -> __params );
}
2007-02-02 23:55:47 +00:00
}
2007-08-16 16:31:50 +00:00
$path = array ( 'base' => null );
2007-04-29 03:46:58 +00:00
2007-06-20 06:15:35 +00:00
if ( ! empty ( $_this -> __paths )) {
2007-06-22 01:25:35 +00:00
if ( isset ( $this ) && ! isset ( $this -> params [ 'requested' ])) {
2007-04-02 19:20:50 +00:00
$path = $_this -> __paths [ 0 ];
2007-06-22 01:25:35 +00:00
} else {
2007-04-02 19:20:50 +00:00
$path = end ( $_this -> __paths );
}
2007-02-02 23:55:47 +00:00
}
2007-08-28 21:16:24 +00:00
$base = $path [ 'base' ]; // dont need this anymore $_this->stripPlugin($path['base'], $params['plugin']);
2007-04-17 07:51:01 +00:00
$extension = $output = $mapped = $q = $frag = 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 [ '?' ]);
}
2007-04-17 07:51:01 +00:00
if ( isset ( $url [ '#' ])) {
$frag = '#' . urlencode ( $url [ '#' ]);
unset ( $url [ '#' ]);
}
2007-08-16 16:31:50 +00:00
if ( empty ( $url [ 'action' ])) {
if ( empty ( $url [ 'controller' ]) || $params [ 'controller' ] == $url [ 'controller' ]) {
2006-09-22 16:39:15 +00:00
$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-08-20 13:09:11 +00:00
if ( $admin ) {
2007-08-28 21:16:24 +00:00
if ( ! isset ( $url [ $admin ]) && ! empty ( $params [ $admin ])) {
2007-08-16 16:31:50 +00:00
$url [ $admin ] = true ;
2007-08-20 13:09:11 +00:00
} elseif ( $admin && array_key_exists ( $admin , $url ) && ! $url [ $admin ]) {
2007-08-16 16:31:50 +00:00
unset ( $url [ $admin ]);
}
2006-09-22 16:39:15 +00:00
}
2007-08-24 12:50:21 +00:00
2007-08-24 13:11:31 +00:00
$plugin = false ;
if ( array_key_exists ( 'plugin' , $url )) {
$plugin = $url [ 'plugin' ];
}
2007-12-08 06:08:03 +00:00
$url = array_merge ( array ( 'controller' => $params [ 'controller' ], 'plugin' => $params [ 'plugin' ]), Set :: filter ( $url , true ));
2007-08-24 12:50:21 +00:00
2007-08-24 13:11:31 +00:00
if ( $plugin !== false ) {
$url [ 'plugin' ] = $plugin ;
}
2007-08-24 12:50:21 +00:00
if ( isset ( $url [ 'ext' ])) {
$extension = '.' . $url [ 'ext' ];
unset ( $url [ 'ext' ]);
}
2007-02-26 02:11:30 +00:00
$match = false ;
2007-04-29 03:46:58 +00:00
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 )) {
2007-08-20 13:09:11 +00:00
$output = trim ( $match , '/' );
$url = array ();
2006-11-10 17:08:31 +00:00
break ;
}
}
2006-09-22 16:39:15 +00:00
$named = $args = array ();
2007-10-22 00:07:39 +00:00
$skip = array ( 'bare' , 'action' , 'controller' , 'plugin' , 'ext' , '?' , '#' , 'prefix' , Configure :: read ( 'Routing.admin' ));
2007-04-29 03:46:58 +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 );
2007-04-29 03:46:58 +00:00
2007-08-20 13:09:11 +00:00
// Remove this once parsed URL parameters can be inserted into 'pass'
2006-09-22 16:39:15 +00:00
for ( $i = 0 ; $i < $count ; $i ++ ) {
2007-03-12 01:52:40 +00:00
if ( $i == 0 && is_numeric ( $keys [ $i ]) && in_array ( 'id' , $keys )) {
$args [ 0 ] = $url [ $keys [ $i ]];
2007-06-20 06:15:35 +00:00
} elseif ( is_numeric ( $keys [ $i ]) || $keys [ $i ] == 'id' ) {
2006-09-22 16:39:15 +00:00
$args [] = $url [ $keys [ $i ]];
2007-10-22 00:07:39 +00:00
} else {
$named [ $keys [ $i ]] = $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-07-22 04:07:06 +00:00
list ( $args , $named ) = array ( Set :: filter ( $args , true ), Set :: filter ( $named , true ));
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-02-03 01:03:33 +00:00
2007-08-28 21:16:24 +00:00
$urlOut = Set :: filter ( array ( $url [ 'controller' ], $url [ 'action' ]));
if ( isset ( $url [ 'plugin' ]) && $url [ 'plugin' ] != $url [ 'controller' ]) {
array_unshift ( $urlOut , $url [ 'plugin' ]);
2006-12-25 10:51:08 +00:00
}
2007-09-21 02:29:36 +00:00
2007-11-02 06:21:41 +00:00
if ( $admin && isset ( $url [ $admin ])) {
2007-09-21 02:29:36 +00:00
array_unshift ( $urlOut , $admin );
}
2007-07-24 13:50:50 +00:00
$output = join ( '/' , $urlOut ) . '/' ;
2006-09-22 16:39:15 +00:00
}
2007-03-04 09:12:09 +00:00
2007-08-20 13:09:11 +00:00
if ( ! empty ( $args )) {
$args = join ( '/' , $args );
if ( $output { strlen ( $output ) - 1 } != '/' ) {
$args = '/' . $args ;
2007-03-04 09:12:09 +00:00
}
2007-08-20 13:09:11 +00:00
$output .= $args ;
2007-03-04 09:12:09 +00:00
}
2007-10-22 00:07:39 +00:00
if ( ! empty ( $named )) {
foreach ( $named as $name => $value ) {
$output .= '/' . $name . $_this -> __argSeparator . $value ;
}
}
2007-03-04 09:12:09 +00:00
$output = str_replace ( '//' , '/' , $base . '/' . $output );
2006-09-22 16:39:15 +00:00
} else {
2007-07-22 04:07:06 +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' ];
2007-08-20 13:09:11 +00:00
} elseif ( substr ( $url , 0 , 1 ) == '/' ) {
2006-09-22 16:39:15 +00:00
$output = $base . $url ;
} else {
2006-12-07 18:59:58 +00:00
$output = $base . '/' ;
2007-08-20 13:09:11 +00:00
if ( $admin && isset ( $params [ $admin ])) {
$output .= $admin . '/' ;
2006-12-07 18:59:58 +00:00
}
2007-10-31 03:53:41 +00:00
if ( ! empty ( $params [ 'plugin' ]) && $params [ 'plugin' ] !== $params [ 'controller' ]) {
2007-05-20 01:40:34 +00:00
$output .= Inflector :: underscore ( $params [ 'plugin' ]) . '/' ;
}
$output .= Inflector :: underscore ( $params [ 'controller' ]) . '/' . $url ;
2006-09-22 16:39:15 +00:00
}
2007-04-30 11:12:11 +00:00
$output = str_replace ( '//' , '/' , $output );
2006-09-22 16:39:15 +00:00
}
if ( $full ) {
$output = FULL_BASE_URL . $output ;
}
2007-07-25 04:38:28 +00:00
if ( ! empty ( $extension ) && substr ( $output , - 1 ) == '/' ) {
2007-07-17 13:45:20 +00:00
$output = substr ( $output , 0 , - 1 );
}
2007-10-31 03:53:41 +00:00
2007-04-17 07:51:01 +00:00
return $output . $extension . $_this -> queryString ( $q ) . $frag ;
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
*
2007-05-26 06:26:06 +00:00
* @ param array $route Route Route
* @ param array $url URL URL to map
* @ return mixed Result ( as string ) or false if no match
* @ access public
* @ static
2006-09-28 20:29:52 +00:00
*/
function mapRouteElements ( $route , $url ) {
2007-02-26 02:11:30 +00:00
$_this =& Router :: getInstance ();
2007-08-20 13:09:11 +00:00
if ( isset ( $route [ 3 ][ 'prefix' ])) {
$prefix = $route [ 3 ][ 'prefix' ];
unset ( $route [ 3 ][ 'prefix' ]);
}
2007-08-16 05:44:06 +00:00
2007-08-16 16:31:50 +00:00
$pass = array ();
2007-08-15 14:18:39 +00:00
$defaults = $route [ 3 ];
2007-08-14 18:51:34 +00:00
$routeParams = $route [ 2 ];
2007-08-20 13:09:11 +00:00
$params = Set :: diff ( $url , $defaults );
2007-10-29 21:33:20 +00:00
$urlInv = array_combine ( array_values ( $url ), array_keys ( $url ));
$i = 0 ;
while ( isset ( $defaults [ $i ])) {
if ( isset ( $urlInv [ $defaults [ $i ]])) {
if ( ! in_array ( $defaults [ $i ], $url ) && is_int ( $urlInv [ $defaults [ $i ]])) {
return false ;
}
unset ( $urlInv [ $defaults [ $i ]], $defaults [ $i ]);
} else {
return false ;
}
$i ++ ;
}
2007-08-14 18:51:34 +00:00
foreach ( $params as $key => $value ) {
2007-08-15 14:18:39 +00:00
if ( is_int ( $key )) {
$pass [] = $value ;
2007-08-14 18:51:34 +00:00
unset ( $params [ $key ]);
}
}
2007-08-16 16:31:50 +00:00
list ( $named , $params ) = $_this -> getNamedElements ( $params );
2007-02-26 02:11:30 +00:00
2007-08-16 16:31:50 +00:00
if ( ! strpos ( $route [ 0 ], '*' ) && ( ! empty ( $pass ) || ! empty ( $named ))) {
2007-02-26 02:11:30 +00:00
return false ;
}
2007-08-20 16:02:11 +00:00
$urlKeys = array_keys ( $url );
$paramsKeys = array_keys ( $params );
$defaultsKeys = array_keys ( $defaults );
2007-08-15 14:18:39 +00:00
if ( ! empty ( $params )) {
2007-08-20 16:02:11 +00:00
if ( array_diff ( $paramsKeys , $routeParams ) != array ()) {
return false ;
}
2007-10-30 22:41:55 +00:00
$required = array_values ( array_diff ( $routeParams , $urlKeys ));
2007-10-29 21:33:20 +00:00
$reqCount = count ( $required );
2007-10-30 22:41:55 +00:00
2007-10-29 21:33:20 +00:00
for ( $i = 0 ; $i < $reqCount ; $i ++ ) {
if ( array_key_exists ( $required [ $i ], $defaults ) && $defaults [ $required [ $i ]] === null ) {
unset ( $required [ $i ]);
}
}
2007-08-20 16:02:11 +00:00
}
$isFilled = true ;
2007-10-29 21:33:20 +00:00
2007-08-20 16:02:11 +00:00
if ( ! empty ( $routeParams )) {
$filled = array_intersect_key ( $url , array_combine ( $routeParams , array_keys ( $routeParams )));
$isFilled = ( array_diff ( $routeParams , array_keys ( $filled )) == array ());
if ( ! $isFilled && empty ( $params )) {
2007-08-20 13:09:11 +00:00
return false ;
}
2007-08-15 14:18:39 +00:00
}
2007-08-20 16:02:11 +00:00
2007-08-14 18:51:34 +00:00
if ( empty ( $params )) {
2007-12-08 06:08:03 +00:00
return Router :: __mapRoute ( $route , array_merge ( $url , compact ( 'pass' , 'named' , 'prefix' )));
2007-08-14 18:51:34 +00:00
} elseif ( ! empty ( $routeParams ) && ! empty ( $route [ 3 ])) {
2007-10-29 21:33:20 +00:00
2007-06-20 06:15:35 +00:00
if ( ! empty ( $required )) {
2006-12-25 10:51:08 +00:00
return false ;
}
2007-08-16 16:31:50 +00:00
foreach ( $params as $key => $val ) {
if (( ! isset ( $url [ $key ]) || $url [ $key ] != $val ) || ( ! isset ( $defaults [ $key ]) || $defaults [ $key ] != $val ) && ! in_array ( $key , $routeParams )) {
2007-10-29 21:33:20 +00:00
if ( array_key_exists ( $key , $defaults ) && $defaults [ $key ] === null ) {
continue ;
}
2007-08-15 14:18:39 +00:00
return false ;
}
2006-12-06 20:38:28 +00:00
}
2006-12-07 05:58:08 +00:00
} else {
2007-06-20 06:15:35 +00:00
if ( empty ( $required ) && $defaults [ 'plugin' ] == $url [ 'plugin' ] && $defaults [ 'controller' ] == $url [ 'controller' ] && $defaults [ 'action' ] == $url [ 'action' ]) {
2007-12-08 06:08:03 +00:00
return Router :: __mapRoute ( $route , array_merge ( $url , compact ( 'pass' , 'named' , 'prefix' )));
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-06-20 06:15:35 +00:00
if ( ! empty ( $route [ 4 ])) {
2006-12-25 10:51:08 +00:00
foreach ( $route [ 4 ] as $key => $reg ) {
2007-08-20 13:09:11 +00:00
if ( array_key_exists ( $key , $url ) && ! preg_match ( '/' . $reg . '/' , $url [ $key ])) {
2006-12-25 10:51:08 +00:00
return false ;
}
2006-11-10 17:08:31 +00:00
}
}
2007-12-08 06:08:03 +00:00
return Router :: __mapRoute ( $route , array_merge ( $filled , compact ( 'pass' , 'named' , 'prefix' )));
2006-12-06 20:38:28 +00:00
}
/**
* Merges URL parameters into a route string
*
2007-05-26 06:26:06 +00:00
* @ param array $route Route
* @ param array $params Parameters
* @ return string Merged URL with parameters
* @ access private
2006-12-06 20:38:28 +00:00
*/
function __mapRoute ( $route , $params = array ()) {
2007-02-26 02:11:30 +00:00
$_this =& Router :: getInstance ();
2007-08-20 13:09:11 +00:00
2007-11-07 00:17:38 +00:00
if ( isset ( $params [ 'plugin' ]) && isset ( $params [ 'controller' ]) && $params [ 'plugin' ] === $params [ 'controller' ]) {
unset ( $params [ 'controller' ]);
}
2007-08-20 13:09:11 +00:00
if ( isset ( $params [ 'prefix' ]) && isset ( $params [ 'action' ])) {
$params [ 'action' ] = str_replace ( $params [ 'prefix' ] . '_' , '' , $params [ 'action' ]);
unset ( $params [ 'prefix' ]);
}
2006-12-06 20:38:28 +00:00
if ( isset ( $params [ 'pass' ]) && is_array ( $params [ 'pass' ])) {
2007-04-17 07:00:26 +00:00
$params [ 'pass' ] = implode ( '/' , Set :: filter ( $params [ 'pass' ], true ));
2006-12-06 20:38:28 +00:00
} elseif ( ! isset ( $params [ 'pass' ])) {
$params [ 'pass' ] = '' ;
}
2007-07-31 05:00:24 +00:00
2007-08-16 16:31:50 +00:00
if ( isset ( $params [ 'named' ])) {
if ( is_array ( $params [ 'named' ])) {
$count = count ( $params [ 'named' ]);
$keys = array_keys ( $params [ 'named' ]);
$named = array ();
for ( $i = 0 ; $i < $count ; $i ++ ) {
$named [] = $keys [ $i ] . $_this -> __argSeparator . $params [ 'named' ][ $keys [ $i ]];
}
$params [ 'named' ] = join ( '/' , $named );
}
$params [ 'pass' ] = str_replace ( '//' , '/' , $params [ 'pass' ] . '/' . $params [ 'named' ]);
}
2007-09-16 18:32:02 +00:00
$out = $route [ 0 ];
2006-12-29 04:16:53 +00:00
2006-11-10 17:08:31 +00:00
foreach ( $route [ 2 ] as $key ) {
2007-07-31 02:01:29 +00:00
$string = null ;
if ( isset ( $params [ $key ])) {
$string = $params [ $key ];
unset ( $params [ $key ]);
}
$out = str_replace ( ':' . $key , $string , $out );
2007-08-16 16:31:50 +00:00
}
2007-09-16 18:32:02 +00:00
if ( strpos ( $route [ 0 ], '*' )) {
$out = str_replace ( '*' , $params [ 'pass' ], $out );
}
2007-03-04 09:12:09 +00:00
return $out ;
2006-11-10 17:08:31 +00:00
}
2007-08-16 16:31:50 +00:00
/**
* Takes an array of URL parameters and separates the ones that can be used as named arguments
*
* @ param array $params Associative array of URL parameters .
* @ param string $controller Name of controller being routed . Used in scoping .
* @ param string $action Name of action being routed . Used in scoping .
* @ return array
* @ access public
* @ static
*/
function getNamedElements ( $params , $controller = null , $action = null ) {
$_this =& Router :: getInstance ();
$named = array ();
foreach ( $params as $key => $val ) {
if ( isset ( $_this -> __namedArgs [ $key ])) {
$match = true ;
if ( is_array ( $_this -> __namedArgs [ $key ])) {
$opts = $_this -> __namedArgs [ $key ];
if ( isset ( $opts [ 'controller' ]) && ! in_array ( $controller , ( array ) $opts [ 'controller' ])) {
$match = false ;
}
if ( isset ( $opts [ 'action' ]) && ! in_array ( $action , ( array ) $opts [ 'action' ])) {
$match = false ;
}
if ( isset ( $opts [ 'match' ]) && ! preg_match ( '/' . $opts [ 'match' ] . '/' , $val )) {
$match = false ;
}
} elseif ( ! $_this -> __namedArgs [ $key ]) {
$match = false ;
}
if ( $match ) {
$named [ $key ] = $val ;
unset ( $params [ $key ]);
}
}
}
return array ( $named , $params );
}
2006-11-10 17:08:31 +00:00
/**
* Generates a well - formed querystring from $q
*
2007-05-26 06:26:06 +00:00
* @ param mixed $q Query string
* @ param array $extra Extra querystring parameters
2006-11-10 17:08:31 +00:00
* @ return array
2007-05-26 06:26:06 +00:00
* @ access public
* @ static
2006-11-10 17:08:31 +00:00
*/
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 )) {
2007-12-08 06:08:03 +00:00
$q = array_merge ( $extra , $q );
2007-02-26 02:11:30 +00:00
} 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
}
2007-12-13 07:03:59 +00:00
/**
* Normalizes a URL for purposes of comparison
*
* @ param mixed $url URL to normalize
* @ return string Normalized URL
* @ access public
*/
function normalize ( $url = '/' ) {
if ( is_array ( $url )) {
$url = Router :: url ( $url );
}
$paths = Router :: getPaths ();
if ( ! empty ( $paths [ 'base' ]) && stristr ( $url , $paths [ 'base' ])) {
$url = str_replace ( $paths [ 'base' ], '' , $url );
}
$url = '/' . $url ;
while ( strpos ( $url , '//' ) !== false ) {
$url = str_replace ( '//' , '/' , $url );
}
2007-12-14 15:09:05 +00:00
$url = preg_replace ( '/(\/$)/' , '' , $url );
if ( empty ( $url )) {
return '/' ;
}
return $url ;
2007-12-13 07:03:59 +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
*
2007-05-26 06:26:06 +00:00
* @ return array Matching route
* @ access public
* @ static
2006-09-22 16:39:15 +00:00
*/
function requestRoute () {
$_this =& Router :: getInstance ();
return $_this -> __currentRoute [ 0 ];
}
/**
* Returns the route matching the current request ( useful for requestAction traces )
*
2007-05-26 06:26:06 +00:00
* @ return array Matching route
* @ access public
* @ static
2006-09-22 16:39:15 +00:00
*/
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
*
2007-05-26 06:26:06 +00:00
* @ param string $base Base URL
* @ param string $plugin Plugin name
2006-11-08 02:07:11 +00:00
* @ return base url with plugin name removed if present
2007-05-26 06:26:06 +00:00
* @ access public
* @ static
2006-11-08 02:07:11 +00:00
*/
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 ;
}
2007-05-26 06:26:06 +00:00
/**
* Strip escape characters from parameter values .
*
* @ param mixed $param Either an array , or a string
* @ return mixed Array or string escaped
* @ access public
* @ static
*/
2007-05-21 03:29:49 +00:00
function stripEscape ( $param ) {
2007-06-07 19:27:42 +00:00
$_this =& Router :: getInstance ();
2007-06-20 06:15:35 +00:00
if ( ! is_array ( $param ) || empty ( $param )) {
if ( is_bool ( $param )) {
2007-05-25 03:33:12 +00:00
return $param ;
}
2007-05-23 20:00:16 +00:00
$return = preg_replace ( '/^[\\t ]*(?:-!)+/' , '' , $param );
2007-05-21 03:29:49 +00:00
return $return ;
}
2007-06-20 06:15:35 +00:00
foreach ( $param as $key => $value ) {
if ( is_string ( $value )) {
2007-05-23 20:00:16 +00:00
$return [ $key ] = preg_replace ( '/^[\\t ]*(?:-!)+/' , '' , $value );
2007-05-21 03:29:49 +00:00
} else {
foreach ( $value as $array => $string ) {
2007-06-07 19:27:42 +00:00
$return [ $key ][ $array ] = $_this -> stripEscape ( $string );
2007-05-21 03:29:49 +00:00
}
}
}
return $return ;
}
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-05-26 06:26:06 +00:00
* @ access public
* @ static
2006-08-12 16:46:42 +00:00
*/
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
}
2007-07-24 13:50:50 +00:00
/**
2007-09-26 09:49:01 +00:00
* Takes an passed params and converts it to args
2007-07-24 13:50:50 +00:00
*
* @ access public
* @ param array $params
* @ static
*/
2007-10-31 03:53:41 +00:00
function getArgs ( $args ) {
2007-08-16 16:31:50 +00:00
$_this =& Router :: getInstance ();
2007-10-31 03:53:41 +00:00
$pass = $named = array ();
$args = array_map (
2007-09-26 09:49:01 +00:00
array ( & $_this , 'stripEscape' ),
2007-10-31 03:53:41 +00:00
Set :: filter ( explode ( '/' , $args ), true )
2007-09-26 09:49:01 +00:00
);
2007-10-31 03:53:41 +00:00
foreach ( $args as $param ) {
2007-09-26 09:49:01 +00:00
if ( strpos ( $param , $_this -> __argSeparator )) {
2007-12-19 01:49:25 +00:00
$param = explode ( $_this -> __argSeparator , $param , 2 );
2007-10-31 03:53:41 +00:00
$named [ $param [ 0 ]] = $param [ 1 ];
2007-09-26 09:49:01 +00:00
} else {
2007-10-31 03:53:41 +00:00
$pass [] = $param ;
2007-07-24 13:50:50 +00:00
}
}
2007-10-31 03:53:41 +00:00
return compact ( 'pass' , 'named' );
2007-07-24 13:50:50 +00:00
}
2005-06-30 02:09:47 +00:00
}
2007-09-26 09:49:01 +00:00
?>