Kohana v3.3.2
This commit is contained in:
@@ -35,6 +35,9 @@
|
||||
*/
|
||||
class Kohana_Route {
|
||||
|
||||
// Matches a URI group and captures the contents
|
||||
const REGEX_GROUP = '\(((?:(?>[^()]+)|(?R))*)\)';
|
||||
|
||||
// Defines the pattern of a <segment>
|
||||
const REGEX_KEY = '<([a-zA-Z0-9_]++)>';
|
||||
|
||||
@@ -213,9 +216,9 @@ class Kohana_Route {
|
||||
|
||||
// Create a URI with the route and convert it to a URL
|
||||
if ($route->is_external())
|
||||
return Route::get($name)->uri($params);
|
||||
return $route->uri($params);
|
||||
else
|
||||
return URL::site(Route::get($name)->uri($params), $protocol);
|
||||
return URL::site($route->uri($params), $protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -394,23 +397,23 @@ class Kohana_Route {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the route matches a given URI. A successful match will return
|
||||
* Tests if the route matches a given Request. A successful match will return
|
||||
* all of the routed parameters as an array. A failed match will return
|
||||
* boolean FALSE.
|
||||
*
|
||||
* // Params: controller = users, action = edit, id = 10
|
||||
* $params = $route->matches('users/edit/10');
|
||||
* $params = $route->matches(Request::factory('users/edit/10'));
|
||||
*
|
||||
* This method should almost always be used within an if/else block:
|
||||
*
|
||||
* if ($params = $route->matches($uri))
|
||||
* if ($params = $route->matches($request))
|
||||
* {
|
||||
* // Parse the parameters
|
||||
* }
|
||||
*
|
||||
* @param string $uri URI to match
|
||||
* @return array on success
|
||||
* @return FALSE on failure
|
||||
* @param Request $request Request object to match
|
||||
* @return array on success
|
||||
* @return FALSE on failure
|
||||
*/
|
||||
public function matches(Request $request)
|
||||
{
|
||||
@@ -501,109 +504,81 @@ class Kohana_Route {
|
||||
* @param array $params URI parameters
|
||||
* @return string
|
||||
* @throws Kohana_Exception
|
||||
* @uses Route::REGEX_Key
|
||||
* @uses Route::REGEX_GROUP
|
||||
* @uses Route::REGEX_KEY
|
||||
*/
|
||||
public function uri(array $params = NULL)
|
||||
{
|
||||
// Start with the routed URI
|
||||
$uri = $this->_uri;
|
||||
$defaults = $this->_defaults;
|
||||
|
||||
if (strpos($uri, '<') === FALSE AND strpos($uri, '(') === FALSE)
|
||||
/**
|
||||
* Recursively compiles a portion of a URI specification by replacing
|
||||
* the specified parameters and any optional parameters that are needed.
|
||||
*
|
||||
* @param string $portion Part of the URI specification
|
||||
* @param boolean $required Whether or not parameters are required (initially)
|
||||
* @return array Tuple of the compiled portion and whether or not it contained specified parameters
|
||||
*/
|
||||
$compile = function ($portion, $required) use (&$compile, $defaults, $params)
|
||||
{
|
||||
// This is a static route, no need to replace anything
|
||||
$missing = array();
|
||||
|
||||
if ( ! $this->is_external())
|
||||
return $uri;
|
||||
|
||||
// If the localhost setting does not have a protocol
|
||||
if (strpos($this->_defaults['host'], '://') === FALSE)
|
||||
$pattern = '#(?:'.Route::REGEX_KEY.'|'.Route::REGEX_GROUP.')#';
|
||||
$result = preg_replace_callback($pattern, function ($matches) use (&$compile, $defaults, &$missing, $params, &$required)
|
||||
{
|
||||
// Use the default defined protocol
|
||||
$params['host'] = Route::$default_protocol.$this->_defaults['host'];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the supplied host with protocol
|
||||
$params['host'] = $this->_defaults['host'];
|
||||
}
|
||||
|
||||
// Compile the final uri and return it
|
||||
return rtrim($params['host'], '/').'/'.$uri;
|
||||
}
|
||||
|
||||
// Keep track of whether an optional param was replaced
|
||||
$provided_optional = FALSE;
|
||||
|
||||
while (preg_match('#\([^()]++\)#', $uri, $match))
|
||||
{
|
||||
|
||||
// Search for the matched value
|
||||
$search = $match[0];
|
||||
|
||||
// Remove the parenthesis from the match as the replace
|
||||
$replace = substr($match[0], 1, -1);
|
||||
|
||||
while (preg_match('#'.Route::REGEX_KEY.'#', $replace, $match))
|
||||
{
|
||||
list($key, $param) = $match;
|
||||
|
||||
if (isset($params[$param]) AND $params[$param] !== Arr::get($this->_defaults, $param))
|
||||
if ($matches[0][0] === '<')
|
||||
{
|
||||
// Future optional params should be required
|
||||
$provided_optional = TRUE;
|
||||
// Parameter, unwrapped
|
||||
$param = $matches[1];
|
||||
|
||||
// Replace the key with the parameter value
|
||||
$replace = str_replace($key, $params[$param], $replace);
|
||||
}
|
||||
elseif ($provided_optional)
|
||||
{
|
||||
// Look for a default
|
||||
if (isset($this->_defaults[$param]))
|
||||
if (isset($params[$param]))
|
||||
{
|
||||
$replace = str_replace($key, $this->_defaults[$param], $replace);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ungrouped parameters are required
|
||||
throw new Kohana_Exception('Required route parameter not passed: :param', array(
|
||||
':param' => $param,
|
||||
));
|
||||
// This portion is required when a specified
|
||||
// parameter does not match the default
|
||||
$required = ($required OR ! isset($defaults[$param]) OR $params[$param] !== $defaults[$param]);
|
||||
|
||||
// Add specified parameter to this result
|
||||
return $params[$param];
|
||||
}
|
||||
|
||||
// Add default parameter to this result
|
||||
if (isset($defaults[$param]))
|
||||
return $defaults[$param];
|
||||
|
||||
// This portion is missing a parameter
|
||||
$missing[] = $param;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This group has missing parameters
|
||||
$replace = '';
|
||||
break;
|
||||
// Group, unwrapped
|
||||
$result = $compile($matches[2], FALSE);
|
||||
|
||||
if ($result[1])
|
||||
{
|
||||
// This portion is required when it contains a group
|
||||
// that is required
|
||||
$required = TRUE;
|
||||
|
||||
// Add required groups to this result
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
// Do not add optional groups to this result
|
||||
}
|
||||
}
|
||||
}, $portion);
|
||||
|
||||
// Replace the group in the URI
|
||||
$uri = str_replace($search, $replace, $uri);
|
||||
}
|
||||
|
||||
while (preg_match('#'.Route::REGEX_KEY.'#', $uri, $match))
|
||||
{
|
||||
list($key, $param) = $match;
|
||||
|
||||
if ( ! isset($params[$param]))
|
||||
if ($required AND $missing)
|
||||
{
|
||||
// Look for a default
|
||||
if (isset($this->_defaults[$param]))
|
||||
{
|
||||
$params[$param] = $this->_defaults[$param];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ungrouped parameters are required
|
||||
throw new Kohana_Exception('Required route parameter not passed: :param', array(
|
||||
':param' => $param,
|
||||
));
|
||||
}
|
||||
throw new Kohana_Exception(
|
||||
'Required route parameter not passed: :param',
|
||||
array(':param' => reset($missing))
|
||||
);
|
||||
}
|
||||
|
||||
$uri = str_replace($key, $params[$param], $uri);
|
||||
}
|
||||
return array($result, $required);
|
||||
};
|
||||
|
||||
list($uri) = $compile($this->_uri, TRUE);
|
||||
|
||||
// Trim all extra slashes from the URI
|
||||
$uri = preg_replace('#//+#', '/', rtrim($uri, '/'));
|
||||
@@ -626,4 +601,4 @@ class Kohana_Route {
|
||||
return $uri;
|
||||
}
|
||||
|
||||
} // End Route
|
||||
}
|
||||
|
Reference in New Issue
Block a user