Kohana v3.3.2

This commit is contained in:
Deon George
2014-09-06 23:43:07 +10:00
parent f96694b18f
commit 8888719653
236 changed files with 1685 additions and 996 deletions

View File

@@ -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
}