mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-31 09:06:17 +00:00
Starting refactoring of Route methods into a separate class. Tests added.
This commit is contained in:
parent
2669b6179f
commit
fec83abd90
2 changed files with 305 additions and 13 deletions
|
@ -98,18 +98,6 @@ class Router {
|
||||||
*/
|
*/
|
||||||
var $__currentRoute = array();
|
var $__currentRoute = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Default HTTP request method => controller action map.
|
||||||
*
|
*
|
||||||
|
@ -125,6 +113,18 @@ class Router {
|
||||||
array('action' => 'edit', 'method' => 'POST', 'id' => true)
|
array('action' => 'edit', 'method' => 'POST', 'id' => true)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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'
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of resource-mapped controllers
|
* List of resource-mapped controllers
|
||||||
*
|
*
|
||||||
|
@ -1428,4 +1428,204 @@ class Router {
|
||||||
return compact('pass', 'named');
|
return compact('pass', 'named');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single Route used by the Router to connect requests to
|
||||||
|
* parameter maps.
|
||||||
|
*
|
||||||
|
* Not normally created as a standalone. Use Router::connect() to create
|
||||||
|
* Routes for your application.
|
||||||
|
*
|
||||||
|
* @package cake.libs
|
||||||
|
* @since 1.3.0
|
||||||
|
* @see Router::connect
|
||||||
|
*/
|
||||||
|
class RouterRoute {
|
||||||
|
/**
|
||||||
|
* An array of named segments in a Route.
|
||||||
|
* `/:controller/:action/:id` has 3 named elements
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
**/
|
||||||
|
var $names = array();
|
||||||
|
/**
|
||||||
|
* An array of additional parameters for the Route.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
**/
|
||||||
|
var $params = array();
|
||||||
|
/**
|
||||||
|
* Default parameters for a Route
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $defaults = array();
|
||||||
|
/**
|
||||||
|
* The routes pattern string.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
**/
|
||||||
|
var $pattern = null;
|
||||||
|
/**
|
||||||
|
* The compiled route regular expresssion
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
**/
|
||||||
|
var $_compiledRoute = null;
|
||||||
|
/**
|
||||||
|
* 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'
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* Constructor for a Route
|
||||||
|
*
|
||||||
|
* @param string $pattern Pattern string with parameter placeholders
|
||||||
|
* @param array $defaults Array of defaults for the route.
|
||||||
|
* @param string $params Array of parameters and additional options for the Route
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function RouterRoute($pattern, $defaults = array(), $params = array()) {
|
||||||
|
$this->pattern = $pattern;
|
||||||
|
$this->defaults = (array)$defaults;
|
||||||
|
$this->params = (array)$params;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Check if a Route has been compiled into a regular expression.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
**/
|
||||||
|
function compiled() {
|
||||||
|
return !empty($this->_compiledRoute);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Compiles the routes regular expression. Modifies defaults property so all necessary keys are set
|
||||||
|
* and populates $this->names with the named routing elements.
|
||||||
|
*
|
||||||
|
* @return array Returns a string regular expression of the compiled route.
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function compile() {
|
||||||
|
$this->_writeRoute($this->pattern, $this->defaults, $this->params);
|
||||||
|
$this->defaults += array('plugin' => null, 'controller' => null);
|
||||||
|
return $this->_compiledRoute;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Builds a route regular expression
|
||||||
|
*
|
||||||
|
* @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 array
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _writeRoute($route, $default, $params) {
|
||||||
|
if (empty($route) || ($route === '/')) {
|
||||||
|
return array('/^[\/]*$/', array());
|
||||||
|
}
|
||||||
|
$names = array();
|
||||||
|
$elements = explode('/', $route);
|
||||||
|
|
||||||
|
foreach ($elements as $element) {
|
||||||
|
if (empty($element)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$q = null;
|
||||||
|
$element = trim($element);
|
||||||
|
$namedParam = strpos($element, ':') !== false;
|
||||||
|
|
||||||
|
if ($namedParam && preg_match('/^:([^:]+)$/', $element, $r)) {
|
||||||
|
if (isset($params[$r[1]])) {
|
||||||
|
if ($r[1] != 'plugin' && array_key_exists($r[1], $default)) {
|
||||||
|
$q = '?';
|
||||||
|
}
|
||||||
|
$parsed[] = '(?:/(' . $params[$r[1]] . ')' . $q . ')' . $q;
|
||||||
|
} else {
|
||||||
|
$parsed[] = '(?:/([^\/]+))?';
|
||||||
|
}
|
||||||
|
$names[] = $r[1];
|
||||||
|
} elseif ($element === '*') {
|
||||||
|
$parsed[] = '(?:/(.*))?';
|
||||||
|
} else if ($namedParam && preg_match_all('/(?!\\\\):([a-z_0-9]+)/i', $element, $matches)) {
|
||||||
|
$matchCount = count($matches[1]);
|
||||||
|
|
||||||
|
foreach ($matches[1] as $i => $name) {
|
||||||
|
$pos = strpos($element, ':' . $name);
|
||||||
|
$before = substr($element, 0, $pos);
|
||||||
|
$element = substr($element, $pos + strlen($name) + 1);
|
||||||
|
$after = null;
|
||||||
|
|
||||||
|
if ($i + 1 === $matchCount && $element) {
|
||||||
|
$after = preg_quote($element);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($i === 0) {
|
||||||
|
$before = '/' . $before;
|
||||||
|
}
|
||||||
|
$before = preg_quote($before, '#');
|
||||||
|
|
||||||
|
if (isset($params[$name])) {
|
||||||
|
if (isset($default[$name]) && $name != 'plugin') {
|
||||||
|
$q = '?';
|
||||||
|
}
|
||||||
|
$parsed[] = '(?:' . $before . '(' . $params[$name] . ')' . $q . $after . ')' . $q;
|
||||||
|
} else {
|
||||||
|
$parsed[] = '(?:' . $before . '([^\/]+)' . $after . ')?';
|
||||||
|
}
|
||||||
|
$names[] = $name;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$parsed[] = '/' . $element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->_compiledRoute = '#^' . join('', $parsed) . '[\/]*$#';
|
||||||
|
$this->names = $names;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
function match($url) {
|
||||||
|
if (!$this->compiled()) {
|
||||||
|
$this->compile();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match($this->_compiledRoute, $url, $r)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
foreach ($this->defaults as $key => $val) {
|
||||||
|
if ($key{0} === '[' && preg_match('/^\[(\w+)\]$/', $key, $header)) {
|
||||||
|
if (isset($this->__headerMap[$header[1]])) {
|
||||||
|
$header = $this->__headerMap[$header[1]];
|
||||||
|
} else {
|
||||||
|
$header = 'http_' . $header[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$val = (array)$val;
|
||||||
|
$h = false;
|
||||||
|
|
||||||
|
foreach ($val as $v) {
|
||||||
|
if (env(strtoupper($header)) === $v) {
|
||||||
|
$h = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$h) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
}
|
||||||
?>
|
?>
|
|
@ -1938,4 +1938,96 @@ class RouterTest extends CakeTestCase {
|
||||||
$this->assertEqual(Router::getparams(true), $expected);
|
$this->assertEqual(Router::getparams(true), $expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test case for RouterRoute
|
||||||
|
*
|
||||||
|
* @package cake.tests.cases.libs.
|
||||||
|
**/
|
||||||
|
class RouterRouteTestCase extends CakeTestCase {
|
||||||
|
/**
|
||||||
|
* setUp method
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function setUp() {
|
||||||
|
$this->_routing = Configure::read('Routing');
|
||||||
|
Configure::write('Routing', array('admin' => null, 'prefixes' => array()));
|
||||||
|
Router::reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* end the test and reset the environment
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function endTest() {
|
||||||
|
Configure::write('Routing', $this->_routing);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the construction of a RouterRoute
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testConstruction() {
|
||||||
|
$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->defaults, array('controller' => 'posts', 'id' => null));
|
||||||
|
$this->assertEqual($route->params, array('id' => '[0-9]+'));
|
||||||
|
$this->assertFalse($route->compiled());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test Route compiling.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testCompiling() {
|
||||||
|
extract(Router::getNamedExpressions());
|
||||||
|
|
||||||
|
$route =& new RouterRoute('/:controller/:action/:id', array('controller' => 'posts', 'id' => null), array('id' => '[0-9]+'));
|
||||||
|
$result = $route->compile();
|
||||||
|
$expected = '#^(?:/([^\/]+))?(?:/([^\/]+))?(?:/([0-9]+)?)?[\/]*$#';
|
||||||
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
|
$route = new RouterRoute('/:controller/:action/:id', array('controller' => 'testing4', 'id' => null), array('id' => $ID));
|
||||||
|
$result = $route->compile();
|
||||||
|
$expected = '#^(?:/([^\/]+))?(?:/([^\/]+))?(?:/([0-9]+)?)?[\/]*$#';
|
||||||
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
|
$this->assertEqual($route->names, array('controller', 'action', 'id'));
|
||||||
|
|
||||||
|
$route =& new RouterRoute('/:controller/:action/:id', array('controller' => 'testing4'), array('id' => $ID));
|
||||||
|
$result = $route->compile();
|
||||||
|
$expected = '#^(?:/([^\/]+))?(?:/([^\/]+))?(?:/([0-9]+))[\/]*$#';
|
||||||
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
|
$this->assertEqual($route->names, array('controller', 'action', 'id'));
|
||||||
|
|
||||||
|
$route =& new RouterRoute('/posts/foo:id');
|
||||||
|
$result = $route->compile();
|
||||||
|
$expected = '#^/posts(?:/foo([^\/]+))?[\/]*$#';
|
||||||
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
|
$this->assertEqual($route->names, array('id'));
|
||||||
|
|
||||||
|
foreach (array(':', '@', ';', '$', '-') as $delim) {
|
||||||
|
$route =& new RouterRoute('/posts/:id'.$delim.':title');
|
||||||
|
$result = $route->compile();
|
||||||
|
$expected = '#^/posts(?:/([^\/]+))?(?:'.preg_quote($delim, '#').'([^\/]+))?[\/]*$#';
|
||||||
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
|
$this->assertEqual($route->names, array('id', 'title'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$route =& new RouterRoute('/posts/:id::title/:year');
|
||||||
|
$result = $route->compile();
|
||||||
|
$this->assertEqual($result, '#^/posts(?:/([^\/]+))?(?:\\:([^\/]+))?(?:/([^\/]+))?[\/]*$#');
|
||||||
|
$this->assertEqual($route->names, array('id', 'title', 'year'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
Loading…
Add table
Reference in a new issue