Permalink
Browse files

Start adding _scheme and other _ keys

Add requestContext parameters, this should be re-factored
into a separate object, or be built in the route collection.
Currently generating the request context incurs some overhead.

One test for string urls is still failing.
  • Loading branch information...
markstory committed Apr 23, 2012
1 parent 9808f3f commit 810b8522f7a8c35e42d8ba1f5e20f161a1b179e0
@@ -46,12 +46,12 @@ public function parse($url) {
* @param array $url Array of parameters to convert to a string.
* @return mixed either false or a string url.
*/
public function match($url) {
public function match($url, $context = array()) {
if (isset($url['controller']) && isset($url['plugin']) && $url['plugin'] != $url['controller']) {
return false;
}
$this->defaults['controller'] = $url['controller'];
$result = parent::match($url);
$result = parent::match($url, $context);
unset($this->defaults['controller']);
return $result;
}
@@ -97,9 +97,10 @@ public function parse($url) {
* There is no reverse routing redirection routes
*
* @param array $url Array of parameters to convert to a string.
* @param array $context Array of request context parameters.
* @return mixed either false or a string url.
*/
public function match($url) {
public function match($url, $context = array()) {
return false;
}
@@ -355,13 +355,25 @@ public function match($url, $context = array()) {
$defaults = $this->defaults;
$hostOptions = array_intersect_key($url, $context);
if (!empty($hostOptions)) {
// Check for properties that will cause and
// absoulte url. Copy the other properties over.
if (
isset($hostOptions['_scheme']) ||
isset($hostOptions['_port']) ||
isset($hostOptions['_host'])
) {
$hostOptions += $context;
if ($hostOptions['_port'] == $context['_port']) {
unset($hostOptions['_port']);
}
}
// If no base is set, copy one in.
if (!isset($hostOptions['_base']) && isset($context['_base'])) {
$hostOptions['_base'] = $context['_base'];
}
unset($url['_host'], $url['_scheme'], $url['_port'], $url['_base']);
if (isset($defaults['prefix'])) {
@@ -460,7 +472,15 @@ protected function _writeUrl($params, $pass = array(), $hostOptions = array()) {
if (strpos($this->template, '*')) {
$out = str_replace('*', $pass, $out);
}
// add base url if applicable.
if (isset($hostOptions['_base'])) {
$out = $hostOptions['_base'] . $out;
unset($hostOptions['_base']);
}
$out = str_replace('//', '/', $out);
if (!empty($hostOptions)) {
$host = $hostOptions['_host'];
@@ -469,10 +489,9 @@ protected function _writeUrl($params, $pass = array(), $hostOptions = array()) {
$host .= ':' . $hostOptions['_port'];
}
$out = sprintf(
'%s://%s%s%s',
'%s://%s%s',
$hostOptions['_scheme'],
$host,
$hostOptions['_base'],
$out
);
}
@@ -46,17 +46,17 @@ public function add(Route $route) {
* @return void
* @TODO Remove persistent params? Are they even useful?
*/
public function match($url, $requestContext = null) {
public function match($url, $currentParams = array(), $requestContext = array()) {
$names = $this->_getNames($url);
foreach ($names as $name) {
if (isset($this->_routeTable[$name])) {
$output = $this->_matchRoutes($this->_routeTable[$name], $url, $requestContext);
$output = $this->_matchRoutes($this->_routeTable[$name], $url, $currentParams, $requestContext);
if ($output) {
return $output;
}
}
}
return $this->_matchRoutes($this->_routes, $url, $requestContext);
return $this->_matchRoutes($this->_routes, $url, $currentParams, $requestContext);
}
/**
@@ -67,17 +67,17 @@ public function match($url, $requestContext = null) {
* @param array $requestContext The current request parameters, used for persistent parameters.
* @return mixed Either false on failure, or a string on success.
*/
protected function _matchRoutes($routes, $url, $requestContext) {
protected function _matchRoutes($routes, $url, $currentParams, $requestContext) {
$output = false;
for ($i = 0, $len = count($routes); $i < $len; $i++) {
$originalUrl = $url;
$route =& $routes[$i];
if (isset($route->options['persist'], $requestContext)) {
$url = $route->persistParams($url, $requestContext);
if (isset($route->options['persist'], $currentParams)) {
$url = $route->persistParams($url, $currentParams);
}
if ($match = $route->match($url)) {
if ($match = $route->match($url, $requestContext)) {
$output = trim($match, '/');
break;
}
@@ -473,11 +473,16 @@ public static function setRequestInfo($request) {
if ($request instanceof Request) {
static::$_requests[] = $request;
} else {
$requestObj = new Request();
$request += array(array(), array());
$request[0] += array('controller' => false, 'action' => false, 'plugin' => null);
$requestObj->addParams($request[0])->addPaths($request[1]);
static::$_requests[] = $requestObj;
$requestData = $request;
$requestData += array(array(), array());
$requestData[0] += array(
'controller' => false,
'action' => false,
'plugin' => null
);
$request = new Request();
$request->addParams($requestData[0])->addPaths($requestData[1]);
static::$_requests[] = $request;
}
}
@@ -626,38 +631,51 @@ public static function promote($which = null) {
* @return string Full translated URL with base path.
*/
public static function url($url = null, $full = false) {
$params = array('plugin' => null, 'controller' => null, 'action' => 'index');
if (is_bool($full)) {
$escape = false;
} else {
extract($full + array('escape' => false, 'full' => false));
}
$path = array('base' => null);
if (!empty(static::$_requests)) {
$request = static::$_requests[count(static::$_requests) - 1];
// TODO refactor so there is less overhead
// incurred on each URL generated.
$request = static::getRequest(true);
if ($request) {
$params = $request->params;
$path = array('base' => $request->base, 'here' => $request->here);
$requestContext = array(
'_base' => $request->base,
'_port' => $request->port(),
'_scheme' => $request->scheme(),
'_host' => $request->host()
);
$here = $request->here;
} else {
$params = array(
'plugin' => null,
'controller' => null,
'action' => 'index'
);
$requestContext = array(
'_base' => '',
'_port' => 80,
'_scheme' => 'http',
'_host' => 'localhost',
);
$here = null;
}
$base = $path['base'];
$extension = $output = $q = $frag = null;
if (empty($url)) {
$output = isset($path['here']) ? $path['here'] : '/';
$output = isset($here) ? $here : '/';
if ($full && defined('FULL_BASE_URL')) {
$output = FULL_BASE_URL . $output;
}
return $output;
} elseif (is_array($url)) {
if (isset($url['base']) && $url['base'] === false) {
$base = null;
unset($url['base']);
}
if (isset($url['full_base']) && $url['full_base'] === true) {
if (isset($url['_full']) && $url['_full'] === true) {
$full = true;
unset($url['full_base']);
unset($url['_full']);
}
if (isset($url['?'])) {
$q = $url['?'];
@@ -671,6 +689,8 @@ public static function url($url = null, $full = false) {
$extension = '.' . $url['ext'];
unset($url['ext']);
}
// Copy the current action if the controller is the current one.
if (empty($url['action'])) {
if (empty($url['controller']) || $params['controller'] === $url['controller']) {
$url['action'] = $params['action'];
@@ -691,9 +711,13 @@ public static function url($url = null, $full = false) {
}
}
$url += array('controller' => $params['controller'], 'plugin' => $params['plugin']);
$output = self::$_routes->match($url, $params);
$url += array(
'controller' => $params['controller'],
'plugin' => $params['plugin']
);
$output = self::$_routes->match($url, $params, $requestContext);
} else {
// String urls.
if (
(strpos($url, '://') !== false ||
(strpos($url, 'javascript:') === 0) ||
@@ -719,8 +743,7 @@ public static function url($url = null, $full = false) {
}
$protocol = preg_match('#^[a-z][a-z0-9+-.]*\://#i', $output);
if ($protocol === 0) {
$output = str_replace('//', '/', $base . '/' . $output);
$output = str_replace('//', '/', '/' . $output);
if ($full && defined('FULL_BASE_URL')) {
$output = FULL_BASE_URL . $output;
}
@@ -70,8 +70,8 @@ public function testFullBaseURL() {
}
$this->assertRegExp('/^http(s)?:\/\//', Router::url('/', true));
$this->assertRegExp('/^http(s)?:\/\//', Router::url(null, true));
$this->assertRegExp('/^http(s)?:\/\//', Router::url(array('full_base' => true)));
$this->assertSame(FULL_BASE_URL . '/', Router::url(array('full_base' => true)));
$this->assertRegExp('/^http(s)?:\/\//', Router::url(array('_full' => true)));
$this->assertSame(FULL_BASE_URL . '/', Router::url(array('_full' => true)));
}
/**
@@ -1440,7 +1440,7 @@ public function testRemoveBase() {
$expected = '/base/my_controller/my_action';
$this->assertEquals($expected, $result);
$result = Router::url(array('controller' => 'my_controller', 'action' => 'my_action', 'base' => false));
$result = Router::url(array('controller' => 'my_controller', 'action' => 'my_action', '_base' => false));
$expected = '/my_controller/my_action';
$this->assertEquals($expected, $result);
}
@@ -1834,7 +1834,7 @@ public function testRequestRoute() {
* @return void
*/
public function testGetParams() {
$paths = array('base' => '/', 'here' => '/products/display/5', 'webroot' => '/webroot');
$paths = array('base' => '', 'here' => '/products/display/5', 'webroot' => '/webroot');
$params = array('param1' => '1', 'param2' => '2');
Router::setRequestInfo(array($params, $paths));
@@ -2079,11 +2079,11 @@ public function testUrlWithRequestAction() {
Router::setRequestInfo($firstRequest);
Router::setRequestInfo($secondRequest);
$result = Router::url(array('base' => false));
$result = Router::url(array('_base' => false));
$this->assertEquals('/comments/listing', $result, 'with second requests, the last should win.');
Router::popRequest();
$result = Router::url(array('base' => false));
$result = Router::url(array('_base' => false));
$this->assertEquals('/posts', $result, 'with second requests, the last should win.');
}

0 comments on commit 810b852

Please sign in to comment.