mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 11:28:25 +00:00
Moving matching and parsing methods into RouterRoute.
This commit is contained in:
parent
fec83abd90
commit
6da1ab9c30
2 changed files with 204 additions and 24 deletions
|
@ -457,7 +457,7 @@ class Router {
|
||||||
if (count($route) === 3) {
|
if (count($route) === 3) {
|
||||||
$route = $_this->compile($i);
|
$route = $_this->compile($i);
|
||||||
}
|
}
|
||||||
|
//switches to parse() in RouterRoute
|
||||||
if (($r = $_this->__matchRoute($route, $url)) !== false) {
|
if (($r = $_this->__matchRoute($route, $url)) !== false) {
|
||||||
$_this->__currentRoute[] = $route;
|
$_this->__currentRoute[] = $route;
|
||||||
list($route, $regexp, $names, $defaults, $params) = $route;
|
list($route, $regexp, $names, $defaults, $params) = $route;
|
||||||
|
@ -881,6 +881,7 @@ class Router {
|
||||||
if (isset($route[4]['persist'], $_this->__params[0])) {
|
if (isset($route[4]['persist'], $_this->__params[0])) {
|
||||||
$url = array_merge(array_intersect_key($params, Set::combine($route[4]['persist'], '/')), $url);
|
$url = array_merge(array_intersect_key($params, Set::combine($route[4]['persist'], '/')), $url);
|
||||||
}
|
}
|
||||||
|
// replace with RouterRoute::match
|
||||||
if ($match = $_this->mapRouteElements($route, $url)) {
|
if ($match = $_this->mapRouteElements($route, $url)) {
|
||||||
$output = trim($match, '/');
|
$output = trim($match, '/');
|
||||||
$url = array();
|
$url = array();
|
||||||
|
@ -1447,7 +1448,7 @@ class RouterRoute {
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
**/
|
**/
|
||||||
var $names = array();
|
var $keys = array();
|
||||||
/**
|
/**
|
||||||
* An array of additional parameters for the Route.
|
* An array of additional parameters for the Route.
|
||||||
*
|
*
|
||||||
|
@ -1461,11 +1462,18 @@ class RouterRoute {
|
||||||
*/
|
*/
|
||||||
var $defaults = array();
|
var $defaults = array();
|
||||||
/**
|
/**
|
||||||
* The routes pattern string.
|
* The routes template string.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
**/
|
**/
|
||||||
var $pattern = null;
|
var $template = null;
|
||||||
|
/**
|
||||||
|
* Is this route a greedy route? Greedy routes have a `/*` in their
|
||||||
|
* template
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
**/
|
||||||
|
var $_greedy = false;
|
||||||
/**
|
/**
|
||||||
* The compiled route regular expresssion
|
* The compiled route regular expresssion
|
||||||
*
|
*
|
||||||
|
@ -1486,13 +1494,13 @@ class RouterRoute {
|
||||||
/**
|
/**
|
||||||
* Constructor for a Route
|
* Constructor for a Route
|
||||||
*
|
*
|
||||||
* @param string $pattern Pattern string with parameter placeholders
|
* @param string $template Template string with parameter placeholders
|
||||||
* @param array $defaults Array of defaults for the route.
|
* @param array $defaults Array of defaults for the route.
|
||||||
* @param string $params Array of parameters and additional options for the Route
|
* @param string $params Array of parameters and additional options for the Route
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function RouterRoute($pattern, $defaults = array(), $params = array()) {
|
function RouterRoute($template, $defaults = array(), $params = array()) {
|
||||||
$this->pattern = $pattern;
|
$this->template = $template;
|
||||||
$this->defaults = (array)$defaults;
|
$this->defaults = (array)$defaults;
|
||||||
$this->params = (array)$params;
|
$this->params = (array)$params;
|
||||||
}
|
}
|
||||||
|
@ -1512,8 +1520,8 @@ class RouterRoute {
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function compile() {
|
function compile() {
|
||||||
$this->_writeRoute($this->pattern, $this->defaults, $this->params);
|
$this->_writeRoute($this->template, $this->defaults, $this->params);
|
||||||
$this->defaults += array('plugin' => null, 'controller' => null);
|
$this->defaults += array('plugin' => null, 'controller' => null, 'action' => null);
|
||||||
return $this->_compiledRoute;
|
return $this->_compiledRoute;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -1527,7 +1535,8 @@ class RouterRoute {
|
||||||
*/
|
*/
|
||||||
function _writeRoute($route, $default, $params) {
|
function _writeRoute($route, $default, $params) {
|
||||||
if (empty($route) || ($route === '/')) {
|
if (empty($route) || ($route === '/')) {
|
||||||
return array('/^[\/]*$/', array());
|
$this->_compiledRoute = '/^[\/]*$/';
|
||||||
|
$this->keys = array();
|
||||||
}
|
}
|
||||||
$names = array();
|
$names = array();
|
||||||
$elements = explode('/', $route);
|
$elements = explode('/', $route);
|
||||||
|
@ -1585,17 +1594,18 @@ class RouterRoute {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->_compiledRoute = '#^' . join('', $parsed) . '[\/]*$#';
|
$this->_compiledRoute = '#^' . join('', $parsed) . '[\/]*$#';
|
||||||
$this->names = $names;
|
$this->keys = $names;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks to see if the given URL matches the given route
|
* Checks to see if the given URL can be parsed by this route.
|
||||||
|
* If the route can be parsed an array of parameters will be returned if not
|
||||||
|
* false will be returned.
|
||||||
*
|
*
|
||||||
* @param array $route
|
* @param string $url The url to attempt to parse.
|
||||||
* @param string $url
|
* @return mixed Boolean false on failure, otherwise an array or parameters
|
||||||
* @return mixed Boolean false on failure, otherwise array
|
|
||||||
*/
|
*/
|
||||||
function match($url) {
|
function parse($url) {
|
||||||
if (!$this->compiled()) {
|
if (!$this->compiled()) {
|
||||||
$this->compile();
|
$this->compile();
|
||||||
}
|
}
|
||||||
|
@ -1627,5 +1637,163 @@ class RouterRoute {
|
||||||
}
|
}
|
||||||
return $r;
|
return $r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to match a url array. If the url matches the routes pattern, then
|
||||||
|
* return an array of parsed params. If the url doesn't match the routes compiled pattern
|
||||||
|
* returns false.
|
||||||
|
*
|
||||||
|
* @param array $url An array of parameters to check matching with.
|
||||||
|
* @return mixed Either a string url for the parameters if they match or false.
|
||||||
|
**/
|
||||||
|
function match($url) {
|
||||||
|
if (!$this->compiled()) {
|
||||||
|
$this->compile();
|
||||||
|
}
|
||||||
|
if (isset($this->defaults['prefix'])) {
|
||||||
|
$prefix = $this->defaults['prefix'];
|
||||||
|
}
|
||||||
|
$url += array('plugin' => null, 'controller' => null);
|
||||||
|
|
||||||
|
$pass = array();
|
||||||
|
$params = Set::diff($url, $this->defaults);
|
||||||
|
$urlInv = array_combine(array_values($url), array_keys($url));
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
while (isset($this->defaults[$i])) {
|
||||||
|
if (isset($urlInv[$this->defaults[$i]])) {
|
||||||
|
if (!in_array($this->defaults[$i], $url) && is_int($urlInv[$this->defaults[$i]])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unset($urlInv[$this->defaults[$i]], $this->defaults[$i]);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
if (is_int($key)) {
|
||||||
|
$pass[] = $value;
|
||||||
|
unset($params[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list($named, $params) = Router::getNamedElements($params);
|
||||||
|
|
||||||
|
if (!strpos($this->template, '*') && (!empty($pass) || !empty($named))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$urlKeys = array_keys($url);
|
||||||
|
$paramsKeys = array_keys($params);
|
||||||
|
$defaultsKeys = array_keys($this->defaults);
|
||||||
|
|
||||||
|
if (!empty($params)) {
|
||||||
|
if (array_diff($paramsKeys, $this->keys) != array()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$required = array_values(array_diff($this->keys, $urlKeys));
|
||||||
|
$reqCount = count($required);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $reqCount; $i++) {
|
||||||
|
if (array_key_exists($required[$i], $this->defaults) && $this->defaults[$required[$i]] === null) {
|
||||||
|
unset($required[$i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$isFilled = true;
|
||||||
|
|
||||||
|
if (!empty($this->keys)) {
|
||||||
|
$filled = array_intersect_key($url, array_combine($this->keys, array_keys($this->keys)));
|
||||||
|
$isFilled = (array_diff($this->keys, array_keys($filled)) === array());
|
||||||
|
if (!$isFilled && empty($params)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($params)) {
|
||||||
|
return $this->__mapRoute(array_merge($url, compact('pass', 'named', 'prefix')));
|
||||||
|
} elseif (!empty($this->keys) && !empty($this->defaults)) {
|
||||||
|
|
||||||
|
if (!empty($required)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
foreach ($params as $key => $val) {
|
||||||
|
if ((!isset($url[$key]) || $url[$key] != $val) || (!isset($this->defaults[$key]) || $this->defaults[$key] != $val) && !in_array($key, $this->keys)) {
|
||||||
|
if (!isset($this->defaults[$key])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (empty($required) && $this->defaults['plugin'] === $url['plugin'] && $this->defaults['controller'] === $url['controller'] && $this->defaults['action'] === $url['action']) {
|
||||||
|
return $this->__mapRoute($route, array_merge($url, compact('pass', 'named', 'prefix')));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->params)) {
|
||||||
|
foreach ($this->params as $key => $reg) {
|
||||||
|
if (array_key_exists($key, $url) && !preg_match('#' . $reg . '#', $url[$key])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->__mapRoute(array_merge($filled, compact('pass', 'named', 'prefix')));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Map route..
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function __mapRoute($params) {
|
||||||
|
if (isset($params['plugin']) && isset($params['controller']) && $params['plugin'] === $params['controller']) {
|
||||||
|
unset($params['controller']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['prefix']) && isset($params['action'])) {
|
||||||
|
$params['action'] = str_replace($params['prefix'] . '_', '', $params['action']);
|
||||||
|
unset($params['prefix']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['pass']) && is_array($params['pass'])) {
|
||||||
|
$params['pass'] = implode('/', Set::filter($params['pass'], true));
|
||||||
|
} elseif (!isset($params['pass'])) {
|
||||||
|
$params['pass'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
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->named['separator'] . $params['named'][$keys[$i]];
|
||||||
|
}
|
||||||
|
$params['named'] = join('/', $named);
|
||||||
|
}
|
||||||
|
$params['pass'] = str_replace('//', '/', $params['pass'] . '/' . $params['named']);
|
||||||
|
}
|
||||||
|
$out = $this->template;
|
||||||
|
|
||||||
|
foreach ($this->keys as $key) {
|
||||||
|
$string = null;
|
||||||
|
if (isset($params[$key])) {
|
||||||
|
$string = $params[$key];
|
||||||
|
unset($params[$key]);
|
||||||
|
} elseif (strpos($out, $key) != strlen($out) - strlen($key)) {
|
||||||
|
$key = $key . '/';
|
||||||
|
}
|
||||||
|
$out = str_replace(':' . $key, $string, $out);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($this->template, '*')) {
|
||||||
|
$out = str_replace('*', $params['pass'], $out);
|
||||||
|
}
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
|
@ -1974,7 +1974,7 @@ class RouterRouteTestCase extends CakeTestCase {
|
||||||
function testConstruction() {
|
function testConstruction() {
|
||||||
$route =& new RouterRoute('/:controller/:action/:id', array('controller' => 'posts', 'id' => null), array('id' => '[0-9]+'));
|
$route =& new RouterRoute('/:controller/:action/:id', array('controller' => 'posts', 'id' => null), array('id' => '[0-9]+'));
|
||||||
|
|
||||||
$this->assertEqual($route->pattern, '/:controller/:action/:id');
|
$this->assertEqual($route->template, '/:controller/:action/:id');
|
||||||
$this->assertEqual($route->defaults, array('controller' => 'posts', 'id' => null));
|
$this->assertEqual($route->defaults, array('controller' => 'posts', 'id' => null));
|
||||||
$this->assertEqual($route->params, array('id' => '[0-9]+'));
|
$this->assertEqual($route->params, array('id' => '[0-9]+'));
|
||||||
$this->assertFalse($route->compiled());
|
$this->assertFalse($route->compiled());
|
||||||
|
@ -1998,21 +1998,21 @@ class RouterRouteTestCase extends CakeTestCase {
|
||||||
$expected = '#^(?:/([^\/]+))?(?:/([^\/]+))?(?:/([0-9]+)?)?[\/]*$#';
|
$expected = '#^(?:/([^\/]+))?(?:/([^\/]+))?(?:/([0-9]+)?)?[\/]*$#';
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
$this->assertEqual($route->names, array('controller', 'action', 'id'));
|
$this->assertEqual($route->keys, array('controller', 'action', 'id'));
|
||||||
|
|
||||||
$route =& new RouterRoute('/:controller/:action/:id', array('controller' => 'testing4'), array('id' => $ID));
|
$route =& new RouterRoute('/:controller/:action/:id', array('controller' => 'testing4'), array('id' => $ID));
|
||||||
$result = $route->compile();
|
$result = $route->compile();
|
||||||
$expected = '#^(?:/([^\/]+))?(?:/([^\/]+))?(?:/([0-9]+))[\/]*$#';
|
$expected = '#^(?:/([^\/]+))?(?:/([^\/]+))?(?:/([0-9]+))[\/]*$#';
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
$this->assertEqual($route->names, array('controller', 'action', 'id'));
|
$this->assertEqual($route->keys, array('controller', 'action', 'id'));
|
||||||
|
|
||||||
$route =& new RouterRoute('/posts/foo:id');
|
$route =& new RouterRoute('/posts/foo:id');
|
||||||
$result = $route->compile();
|
$result = $route->compile();
|
||||||
$expected = '#^/posts(?:/foo([^\/]+))?[\/]*$#';
|
$expected = '#^/posts(?:/foo([^\/]+))?[\/]*$#';
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
$this->assertEqual($route->names, array('id'));
|
$this->assertEqual($route->keys, array('id'));
|
||||||
|
|
||||||
foreach (array(':', '@', ';', '$', '-') as $delim) {
|
foreach (array(':', '@', ';', '$', '-') as $delim) {
|
||||||
$route =& new RouterRoute('/posts/:id'.$delim.':title');
|
$route =& new RouterRoute('/posts/:id'.$delim.':title');
|
||||||
|
@ -2020,14 +2020,26 @@ class RouterRouteTestCase extends CakeTestCase {
|
||||||
$expected = '#^/posts(?:/([^\/]+))?(?:'.preg_quote($delim, '#').'([^\/]+))?[\/]*$#';
|
$expected = '#^/posts(?:/([^\/]+))?(?:'.preg_quote($delim, '#').'([^\/]+))?[\/]*$#';
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
$this->assertEqual($route->names, array('id', 'title'));
|
$this->assertEqual($route->keys, array('id', 'title'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$route =& new RouterRoute('/posts/:id::title/:year');
|
$route =& new RouterRoute('/posts/:id::title/:year');
|
||||||
$result = $route->compile();
|
$result = $route->compile();
|
||||||
$this->assertEqual($result, '#^/posts(?:/([^\/]+))?(?:\\:([^\/]+))?(?:/([^\/]+))?[\/]*$#');
|
$this->assertEqual($result, '#^/posts(?:/([^\/]+))?(?:\\:([^\/]+))?(?:/([^\/]+))?[\/]*$#');
|
||||||
$this->assertEqual($route->names, array('id', 'title', 'year'));
|
$this->assertEqual($route->keys, array('id', 'title', 'year'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test that routes match their pattern.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testMatching() {
|
||||||
|
$route =& new RouterRoute('/blog/:action', array('controller' => 'posts'));
|
||||||
|
$result = $route->match(array('controller' => 'posts', 'action' => 'view'));
|
||||||
|
$this->assertEqual($result, '/blog/view');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
Loading…
Reference in a new issue