Refactoring Router::mapResources(), adding tests for REST routing and HTTP method overrides

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6409 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
nate 2008-01-26 08:50:06 +00:00
parent ebeb7d0f94
commit d9691a19c8
6 changed files with 69 additions and 23 deletions

View file

@ -263,14 +263,15 @@ class Dispatcher extends Object {
));
} else {
$output = call_user_func_array(array(&$controller, $params['action']), empty($params['pass'])? array(): $params['pass']);
if (empty($controller->output)) {
$controller->output = $output;
}
}
if ($controller->autoRender) {
$output = $controller->render();
$controller->output = $controller->render();
}
$controller->output =& $output;
foreach ($controller->components as $c) {
$path = preg_split('/\/|\./', $c);
$c = $path[count($path) - 1];
@ -327,15 +328,15 @@ class Dispatcher extends Object {
* @access public
*/
function parseParams($fromUrl) {
extract(Router::getNamedExpressions());
include CONFIGS . 'routes.php';
$params = Router::parse($fromUrl);
$params = array();
if (isset($_POST)) {
$params['form'] = $_POST;
if (ini_get('magic_quotes_gpc') == 1) {
$params['form'] = stripslashes_deep($_POST);
} else {
$params['form'] = $_POST;
$params['form'] = stripslashes_deep($params['form']);
}
if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) {
$params['form']['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE');
}
if (isset($params['form']['_method'])) {
if (isset($_SERVER) && !empty($_SERVER)) {
@ -347,6 +348,10 @@ class Dispatcher extends Object {
}
}
extract(Router::getNamedExpressions());
include CONFIGS . 'routes.php';
$params = array_merge(Router::parse($fromUrl), $params);
if (isset($params['form']['data'])) {
$params['data'] = Router::stripEscape($params['form']['data']);
unset($params['form']['data']);
@ -396,6 +401,7 @@ class Dispatcher extends Object {
*/
function baseUrl() {
$dir = $webroot = null;
$config = Configure::read('App');
extract($config);

View file

@ -313,7 +313,7 @@ class Controller extends Object {
*
* @access protected
*/
function __mergeVars () {
function __mergeVars() {
$pluginName = Inflector::camelize($this->plugin);
$pluginController = $pluginName . 'AppController';

View file

@ -24,7 +24,7 @@
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Core', array('Socket', 'Set'));
App::import('Core', array('Socket', 'Set', 'Router'));
/**
* Cake network socket connection class.

View file

@ -185,6 +185,7 @@ class Router extends Object {
*
* @return array Named route elements
* @access public
* @see Router::$__named
* @static
*/
function getNamedExpressions() {
@ -252,13 +253,16 @@ class Router extends Object {
* 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")
* @param array $options
* @param array $options Options to use when generating REST routes
* 'id' - The regular expression fragment to use when matching IDs. By default, matches
* integer values and UUIDs.
* 'prefix' - URL prefix to use for the generated routes. Defaults to '/'.
* @access public
* @static
*/
function mapResources($controller, $options = array()) {
$_this =& Router::getInstance();
$options = array_merge(array('prefix' => '/'), $options);
$options = array_merge(array('prefix' => '/', 'id' => $_this->__named['ID'] . '|' . $_this->__named['UUID']), $options);
$prefix = $options['prefix'];
foreach ((array)$controller as $ctlName) {
@ -270,7 +274,7 @@ class Router extends Object {
Router::connect(
"{$prefix}{$urlName}{$id}",
array('controller' => $urlName, 'action' => $action, '[method]' => $params['method']),
array('id' => $_this->__named['ID'] . '|' . $_this->__named['UUID'])
array('id' => $options['id'])
);
}
$this->__resourceMapped[] = $urlName;

View file

@ -994,6 +994,40 @@ class DispatcherTest extends UnitTestCase {
unlink($filename);
}
function testHttpMethodOverrides() {
Router::reload();
Router::mapResources('Posts');
$_SERVER['REQUEST_METHOD'] = 'POST';
$dispatcher =& new Dispatcher();
$dispatcher->base = false;
$result = $dispatcher->parseParams('/posts');
$expected = array('pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add', '[method]' => 'POST', 'form' => array(), 'url' => array(), 'bare' => 0, 'webservices' => null);
$this->assertEqual($result, $expected);
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT';
$result = $dispatcher->parseParams('/posts/5');
$expected = array('pass' => array(), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT', 'form' => array(), 'url' => array(), 'bare' => 0, 'webservices' => null);
$this->assertEqual($result, $expected);
unset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
$_SERVER['REQUEST_METHOD'] = 'GET';
$result = $dispatcher->parseParams('/posts/5');
$expected = array('pass' => array(), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '[method]' => 'GET', 'form' => array(), 'url' => array(), 'bare' => 0, 'webservices' => null);
$this->assertEqual($result, $expected);
$_POST['_method'] = 'PUT';
$result = $dispatcher->parseParams('/posts/5');
$expected = array('pass' => array(), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT', 'form' => array(), 'url' => array(), 'bare' => 0, 'webservices' => null);
$this->assertEqual($result, $expected);
unset($_POST['_method']);
}
function testEnvironmentDetection() {
$dispatcher =& new Dispatcher();
@ -1001,8 +1035,6 @@ class DispatcherTest extends UnitTestCase {
'IIS' => array(
'No rewrite base path' => array(
'App' => array('base' => false, 'baseUrl' => '/index.php?', 'server' => 'IIS'),
'GET' => array(),
'POST' => array(),
'SERVER' => array('HTTPS' => 'off', 'SCRIPT_NAME' => '/index.php', 'PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot', 'QUERY_STRING' => '', 'REMOTE_ADDR' => '127.0.0.1', 'REMOTE_HOST' => '127.0.0.1', 'REQUEST_METHOD' => 'GET', 'SERVER_NAME' => 'localhost', 'SERVER_PORT' => '80', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'SERVER_SOFTWARE' => 'Microsoft-IIS/5.1', 'APPL_PHYSICAL_PATH' => 'C:\\Inetpub\\wwwroot\\', 'REQUEST_URI' => '/index.php', 'URL' => '/index.php', 'SCRIPT_FILENAME' => 'C:\\Inetpub\\wwwroot\\index.php', 'ORIG_PATH_INFO' => '/index.php', 'PATH_INFO' => '', 'ORIG_PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot\\index.php', 'DOCUMENT_ROOT' => 'C:\\Inetpub\\wwwroot', 'PHP_SELF' => '/index.php', 'HTTP_ACCEPT' => '*/*', 'HTTP_ACCEPT_LANGUAGE' => 'en-us', 'HTTP_CONNECTION' => 'Keep-Alive', 'HTTP_HOST' => 'localhost', 'HTTP_USER_AGENT' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)', 'HTTP_ACCEPT_ENCODING' => 'gzip, deflate', 'argv' => array(), 'argc' => 0),
'reload' => true,
'path' => ''
@ -1014,14 +1046,12 @@ class DispatcherTest extends UnitTestCase {
),
'No rewrite sub dir 1' => array(
'GET' => array(),
'POST' => array(),
'SERVER' => array('QUERY_STRING' => '', 'REQUEST_URI' => '/index.php', 'URL' => '/index.php', 'SCRIPT_FILENAME' => 'C:\\Inetpub\\wwwroot\\index.php', 'ORIG_PATH_INFO' => '/index.php', 'PATH_INFO' => '', 'ORIG_PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot\\index.php', 'DOCUMENT_ROOT' => 'C:\\Inetpub\\wwwroot', 'PHP_SELF' => '/index.php', 'argv' => array(), 'argc' => 0),
'reload' => false,
'path' => ''
),
'No rewrite sub dir 1 with path' => array(
'GET' => array('/posts/add' => ''),
'POST' => array(),
'SERVER' => array('QUERY_STRING' => '/posts/add', 'REQUEST_URI' => '/index.php?/posts/add', 'URL' => '/index.php?/posts/add', 'SCRIPT_FILENAME' => 'C:\\Inetpub\\wwwroot\\index.php', 'argv' => array('/posts/add'), 'argc' => 1),
'reload' => false,
'path' => '/posts/add'
@ -1036,7 +1066,6 @@ class DispatcherTest extends UnitTestCase {
),
'No rewrite sub dir 2 with path' => array(
'GET' => array('/posts/add' => ''),
'POST' => array(),
'SERVER' => array('SCRIPT_NAME' => '/site/index.php', 'PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot', 'QUERY_STRING' => '/posts/add', 'REQUEST_URI' => '/site/index.php?/posts/add', 'URL' => '/site/index.php?/posts/add', 'ORIG_PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot\\site\\index.php', 'DOCUMENT_ROOT' => 'C:\\Inetpub\\wwwroot', 'PHP_SELF' => '/site/index.php', 'argv' => array('/posts/add'), 'argc' => 1),
'reload' => false,
'path' => '/posts/add'
@ -1045,15 +1074,11 @@ class DispatcherTest extends UnitTestCase {
'Apache' => array(
'No rewrite base path' => array(
'App' => array('base' => false, 'baseUrl' => '/index.php', 'dir' => 'app', 'webroot' => 'webroot'),
'GET' => array(),
'POST' => array(),
'SERVER' => array('SERVER_NAME' => 'localhost', 'SERVER_ADDR' => '::1', 'SERVER_PORT' => '80', 'REMOTE_ADDR' => '::1', 'DOCUMENT_ROOT' => '/Library/WebServer/Documents/officespace/app/webroot', 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/app/webroot/index.php', 'REQUEST_METHOD' => 'GET', 'QUERY_STRING' => '', 'REQUEST_URI' => '/', 'SCRIPT_NAME' => '/index.php', 'PHP_SELF' => '/index.php', 'argv' => array(), 'argc' => 0),
'reload' => true,
'path' => ''
),
'No rewrite with path' => array(
'GET' => array(),
'POST' => array(),
'SERVER' => array('UNIQUE_ID' => 'VardGqn@17IAAAu7LY8AAAAK', 'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-us) AppleWebKit/523.10.5 (KHTML, like Gecko) Version/3.0.4 Safari/523.10.6', 'HTTP_ACCEPT' => 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5', 'HTTP_ACCEPT_LANGUAGE' => 'en-us', 'HTTP_ACCEPT_ENCODING' => 'gzip, deflate', 'HTTP_CONNECTION' => 'keep-alive', 'HTTP_HOST' => 'localhost', 'DOCUMENT_ROOT' => '/Library/WebServer/Documents/officespace/app/webroot', 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/officespace/app/webroot/index.php', 'QUERY_STRING' => '', 'REQUEST_URI' => '/index.php/posts/add', 'SCRIPT_NAME' => '/index.php', 'PATH_INFO' => '/posts/add', 'PHP_SELF' => '/index.php/posts/add', 'argv' => array(), 'argc' => 0),
'reload' => false,
'path' => '/posts/add'

View file

@ -121,6 +121,17 @@ class RouterTest extends UnitTestCase {
$_SERVER['REQUEST_METHOD'] = 'GET';
$result = $this->router->parse('/posts/add');
$this->assertEqual($result, array('pass' => array(), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'add'));
$this->router->reload();
$this->router->mapResources('Posts', array('id' => '[a-z0-9_]+'));
$_SERVER['REQUEST_METHOD'] = 'GET';
$result = $this->router->parse('/posts/add');
$this->assertEqual($result, array('pass' => array(), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'view', 'id' => 'add', '[method]' => 'GET'));
$_SERVER['REQUEST_METHOD'] = 'PUT';
$result = $this->router->parse('/posts/name');
$this->assertEqual($result, array('pass' => array(), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'edit', 'id' => 'name', '[method]' => 'PUT'));
}
function testUrlNormalization() {