+ // // + Copyright: (c) 2005, CakePHP Authors/Developers + // // + Author(s): Michal Tatarynowicz aka Pies + // // + Larry E. Masters aka PhpNut + // // + Kamil Dzielinski aka Brego + // // +------------------------------------------------------------------+ // // + Licensed under The MIT License + // // + Redistributions of files must retain the above copyright notice. + // // + See: http://www.opensource.org/licenses/mit-license.php + // ////////////////////////////////////////////////////////////////////////// /** * Purpose: Router * Parses the request URL into controller, action, and parameters. * * @filesource * @author CakePHP Authors/Developers * @copyright Copyright (c) 2005, CakePHP Authors/Developers * @link https://trac.cakephp.org/wiki/Authors Authors/Developers * @package cake * @subpackage cake.libs * @since CakePHP v 0.2.9 * @version $Revision$ * @modifiedby $LastChangedBy$ * @lastmodified $Date$ * @license http://www.opensource.org/licenses/mit-license.php The MIT License */ uses('object', 'neat_array'); /** * Parses the request URL into controller, action, and parameters. * * @package cake * @subpackage cake.libs * @since CakePHP v 0.2.9 * */ class Router extends Object { /** * Array of routes * * @var array */ var $routes = array(); /** * TODO: Better description. Returns this object's routes array. Returns false if there are no routes available. * * @param string $route An empty string, or a route string "/" * @param array $default NULL or an array describing the default route * @see routes * @return array Array of routes */ function connect ($route, $default=null) { $parsed = $names = array (); $r = null; if (($route == '') || ($route == '/')) { $regexp = '/^[\/]*$/'; $this->routes[] = array($route, $regexp, array(), $default); } else { $elements = array(); foreach (explode('/', $route) as $element) if (trim($element)) $elements[] = $element; if (!count($elements)) return false; foreach ($elements as $element) { if (preg_match('/^:(.+)$/', $element, $r)) { $parsed[] = '(?:\/([^\/]+))?'; $names[] = $r[1]; } elseif (preg_match('/^\*$/', $element, $r)) { $parsed[] = '(?:\/(.*))?'; } else { $parsed[] = '/'.$element; } } $regexp = '#^'.join('', $parsed).'[\/]*$#'; $this->routes[] = array($route, $regexp, $names, $default); } return $this->routes; } /** * TODO: Better description. Returns an array of routes. * * @param string $url URL to be parsed * @return array */ function parse ($url) { // An URL should start with a '/', mod_rewrite doesn't respect that, but no-mod_rewrite version does. // Here's the fix. if ($url && ('/' != $url[0])) { $url = '/'.$url; } $out = array(); $r = null; $default_route = array ( '/:controller/:action/* (default)', "#^(?:\/(?:([a-z0-9_\-]+)(?:\/([a-z0-9_\-]+)(?:\/(.*))?)?))[\/]*$#", array('controller', 'action'), array() ); $this->routes[] = $default_route; foreach ($this->routes as $route) { list($route, $regexp, $names, $defaults) = $route; if (preg_match($regexp, $url, $r)) { // $this->log($url.' matched '.$regexp, 'note'); // 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; $ii = 0; if (is_array($defaults)) { foreach ($defaults as $name=>$value) { if (preg_match('#[a-z_\-]#i', $name)) $out[$name] = $value; else $out['pass'][] = $value; } } foreach ($r as $found) { // if $found is a named url element (i.e. ':action') if (isset($names[$ii])) { $out[$names[$ii]] = $found; } // unnamed elements go in as 'pass' else { $pass = new NeatArray(explode('/', $found)); $pass->cleanup(); $out['pass'] = $pass->value; } $ii++; } break; } } return $out; } } ?>