mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Added support for redirection routes. Fixes #1151
This commit is contained in:
parent
692aafbf42
commit
7630580511
4 changed files with 201 additions and 0 deletions
74
cake/libs/route/redirect_route.php
Normal file
74
cake/libs/route/redirect_route.php
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
App::import('Core', 'CakeResponse');
|
||||
App::import('Core', 'route/CakeRoute');
|
||||
/**
|
||||
* Redirect route will perform an immediate redirect
|
||||
*
|
||||
* PHP5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs.route
|
||||
* @since CakePHP(tm) v 2.0
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
class RedirectRoute extends CakeRoute {
|
||||
|
||||
/**
|
||||
* A CakeResponse object
|
||||
*
|
||||
* @var CakeResponse
|
||||
*/
|
||||
public $response = null;
|
||||
|
||||
/**
|
||||
* Parses a string url into an array. Parsed urls will result in an automatic
|
||||
* redirection
|
||||
*
|
||||
* @param string $url The url to parse
|
||||
* @return boolean False on failure
|
||||
*/
|
||||
public function parse($url) {
|
||||
$params = parent::parse($url);
|
||||
if (!$params) {
|
||||
return false;
|
||||
}
|
||||
if (!$this->response) {
|
||||
$this->response = new CakeResponse();
|
||||
}
|
||||
$redirect = $this->defaults;
|
||||
if (count($this->defaults) == 1 && !isset($this->defaults['controller'])) {
|
||||
$redirect = $this->defaults[0];
|
||||
}
|
||||
if (isset($this->options['persist']) && is_array($redirect)) {
|
||||
$argOptions['context'] = array('action' => $redirect['action'], 'controller' => $redirect['controller']);
|
||||
$args = Router::getArgs($params['_args_'], $argOptions);
|
||||
$redirect += $args['pass'];
|
||||
$redirect += $args['named'];
|
||||
}
|
||||
$status = 301;
|
||||
if (isset($this->options['status']) && ($this->options['status'] >= 300 && $this->options['status'] < 400)) {
|
||||
$status = $this->options['status'];
|
||||
}
|
||||
$this->response->header(array('Location' => Router::url($redirect, true)));
|
||||
$this->response->statusCode($status);
|
||||
$this->response->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* There is no reverse routing redirection routes
|
||||
*
|
||||
* @param array $url Array of parameters to convert to a string.
|
||||
* @return mixed either false or a string url.
|
||||
*/
|
||||
public function match($url) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -253,6 +253,41 @@ class Router {
|
|||
return self::$routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects a new redirection Route in the router.
|
||||
*
|
||||
* Redirection routes are different from normal routes as they perform an actual
|
||||
* header redirection if a match is found. The redirection can occur within your
|
||||
* application or redirect to an outside location.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* `Router::redirect('/home/*', array('controller' => 'posts', 'action' => 'view', array('persist' => true));`
|
||||
*
|
||||
* Redirects /home/* to /posts/view and passes the parameters to /posts/view
|
||||
*
|
||||
* `Router::redirect('/posts/*', 'http://google.com', array('status' => 302));`
|
||||
*
|
||||
* Redirects /posts/* to http://google.com with a HTTP status of 302
|
||||
*
|
||||
* ### Options:
|
||||
* - `status` Sets the HTTP status (default 301)
|
||||
* - `persist` Passes the params to the redirected route, if it can
|
||||
*
|
||||
* @param string $route A string describing the template of the route
|
||||
* @param array $url A url to redirect to. Can be a string or a Cake array-based url
|
||||
* @param array $options An array matching the named elements in the route to regular expressions which that
|
||||
* element should match. Also contains additional parameters such as which routed parameters should be
|
||||
* shifted into the passed arguments. As well as supplying patterns for routing parameters.
|
||||
* @see routes
|
||||
* @return array Array of routes
|
||||
*/
|
||||
public static function redirect($route, $url, $options) {
|
||||
App::import('Core', 'route/RedirectRoute');
|
||||
$options['routeClass'] = 'RedirectRoute';
|
||||
return self::connect($route, $url, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies what named parameters CakePHP should be parsing. The most common setups are:
|
||||
*
|
||||
|
|
71
cake/tests/cases/libs/route/redirect_route.test.php
Normal file
71
cake/tests/cases/libs/route/redirect_route.test.php
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
App::import('Core', 'route/RedirectRoute');
|
||||
App::import('Core', 'CakeResponse');
|
||||
App::import('Core', 'Router');
|
||||
/**
|
||||
* test case for RedirectRoute
|
||||
*
|
||||
* @package cake.tests.libs.route
|
||||
*/
|
||||
class RedirectRouteTestCase extends CakeTestCase {
|
||||
/**
|
||||
* setUp method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
Configure::write('Routing', array('admin' => null, 'prefixes' => array()));
|
||||
Router::reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* test the parsing of routes.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function testParsing() {
|
||||
$route = new RedirectRoute('/home', array('controller' => 'posts'));
|
||||
$route->response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
$result = $route->parse('/home');
|
||||
$this->assertEqual($route->response->header(), array('Location' => Router::url('/posts', true)));
|
||||
|
||||
$route = new RedirectRoute('/home', array('controller' => 'posts', 'action' => 'index'));
|
||||
$route->response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
$result = $route->parse('/home');
|
||||
$this->assertEqual($route->response->header(), array('Location' => Router::url('/posts', true)));
|
||||
$this->assertEqual($route->response->statusCode(), 301);
|
||||
|
||||
$route = new RedirectRoute('/google', 'http://google.com');
|
||||
$route->response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
$result = $route->parse('/google');
|
||||
$this->assertEqual($route->response->header(), array('Location' => 'http://google.com'));
|
||||
|
||||
$route = new RedirectRoute('/posts/*', array('controller' => 'posts', 'action' => 'view'), array('status' => 302));
|
||||
$route->response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
$result = $route->parse('/posts/2');
|
||||
$this->assertEqual($route->response->header(), array('Location' => Router::url('/posts/view', true)));
|
||||
$this->assertEqual($route->response->statusCode(), 302);
|
||||
|
||||
$route = new RedirectRoute('/posts/*', array('controller' => 'posts', 'action' => 'view'), array('persist' => true));
|
||||
$route->response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
$result = $route->parse('/posts/2');
|
||||
$this->assertEqual($route->response->header(), array('Location' => Router::url('/posts/view/2', true)));
|
||||
|
||||
$route = new RedirectRoute('/posts/*', '/test', array('persist' => true));
|
||||
$route->response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
$result = $route->parse('/posts/2');
|
||||
$this->assertEqual($route->response->header(), array('Location' => Router::url('/test', true)));
|
||||
|
||||
$route = new RedirectRoute('/my_controllers/:action/*', array('controller' => 'tags', 'action' => 'add'), array('persist' => true));
|
||||
$route->response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
$result = $route->parse('/my_controllers/do_something/passme/named:param');
|
||||
$this->assertEqual($route->response->header(), array('Location' => Router::url('/tags/add/passme/named:param', true)));
|
||||
|
||||
$route = new RedirectRoute('/my_controllers/:action/*', array('controller' => 'tags', 'action' => 'add'));
|
||||
$route->response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
$result = $route->parse('/my_controllers/do_something/passme/named:param');
|
||||
$this->assertEqual($route->response->header(), array('Location' => Router::url('/tags/add', true)));
|
||||
}
|
||||
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
App::import('Core', array('Router'));
|
||||
App::import('Core', 'CakeResponse');
|
||||
|
||||
if (!defined('FULL_BASE_URL')) {
|
||||
define('FULL_BASE_URL', 'http://cakephp.org');
|
||||
|
@ -2191,4 +2192,24 @@ class RouterTest extends CakeTestCase {
|
|||
$this->assertEqual($result->here, '/protected/images/index');
|
||||
$this->assertEqual($result->webroot, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* test setting redirect routes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function testRouteRedirection() {
|
||||
Router::redirect('/blog', array('controller' => 'posts'), array('status' => 302));
|
||||
$this->assertEqual(count(Router::$routes), 1);
|
||||
Router::$routes[0]->response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
$this->assertEqual(Router::$routes[0]->options['status'], 302);
|
||||
|
||||
Router::parse('/blog');
|
||||
$this->assertEqual(Router::$routes[0]->response->header(), array('Location' => Router::url('/posts', true)));
|
||||
$this->assertEqual(Router::$routes[0]->response->statusCode(), 302);
|
||||
|
||||
Router::$routes[0]->response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
Router::parse('/not-a-match');
|
||||
$this->assertEqual(Router::$routes[0]->response->header(), array());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue