Separate _getBestMatchingRoute() from _insertRouteVars()

This commit is contained in:
Kijin Sung 2020-06-16 23:30:37 +09:00
parent 7ac27fffce
commit c0c11a42ff

View file

@ -207,20 +207,20 @@ class Router
$action = $action_info->action->{$act} ?? null; $action = $action_info->action->{$act} ?? null;
if ($action && $action->route) if ($action && $action->route)
{ {
$result = self::_insertRouteVars($action->route, $args2); $result = self::_getBestMatchingRoute($action->route, $args2);
if ($result !== false) if ($result !== false)
{ {
return $args['mid'] . '/' . $result; return $args['mid'] . '/' . self::_insertRouteVars($result, $args2);
} }
} }
// Check XE-compatible routes that start with $mid and contain no $act. // Check XE-compatible routes that start with $mid and contain no $act.
if (!isset($args['act']) || ($args['act'] === 'rss' || $args['act'] === 'atom' || $args['act'] === 'api')) if (!isset($args['act']) || ($args['act'] === 'rss' || $args['act'] === 'atom' || $args['act'] === 'api'))
{ {
$result = self::_insertRouteVars(self::$_global_routes, $args2); $result = self::_getBestMatchingRoute(self::$_global_routes, $args2);
if ($result !== false) if ($result !== false)
{ {
return $result; return self::_insertRouteVars($result, $args2);
} }
} }
@ -233,10 +233,10 @@ class Router
{ {
if (!isset($args['act']) || ($args['act'] === 'rss' || $args['act'] === 'atom')) if (!isset($args['act']) || ($args['act'] === 'rss' || $args['act'] === 'atom'))
{ {
$result = self::_insertRouteVars(self::$_global_routes, $args); $result = self::_getBestMatchingRoute(self::$_global_routes, $args);
if ($result !== false) if ($result !== false)
{ {
return $result; return self::_insertRouteVars($result, $args);
} }
} }
} }
@ -288,23 +288,24 @@ class Router
} }
/** /**
* Insert variables into a route. * Find the best matching route for an array of variables.
* *
* @param array $routes * @param array $routes
* @param array $vars * @param array $vars
* @return string|false * @return string|false
*/ */
protected static function _insertRouteVars(array $routes, array $vars) protected static function _getBestMatchingRoute(array $routes, array $vars)
{ {
// If the action only has one route, select it. // If the action only has one route, select it.
if (count($routes) == 1) if (count($routes) == 1)
{ {
$selected_route = key($routes); $only_route = key($routes);
$matched_arguments = array_intersect_key($routes[$selected_route]['vars'], $vars); $matched_arguments = array_intersect_key($routes[$only_route]['vars'], $vars);
if (count($matched_arguments) !== count($routes[$selected_route]['vars'])) if (count($matched_arguments) !== count($routes[$only_route]['vars']))
{ {
return false; return false;
} }
return $only_route;
} }
// If the action has multiple routes, select the one that matches the most arguments. // If the action has multiple routes, select the one that matches the most arguments.
@ -325,11 +326,22 @@ class Router
return false; return false;
} }
arsort($reordered_routes); arsort($reordered_routes);
$selected_route = array_first_key($reordered_routes); $best_route = array_first_key($reordered_routes);
return $best_route;
} }
}
/**
* Insert variables into a route.
*
* @param string $route
* @param array $vars
* @return string
*/
protected static function _insertRouteVars(string $route, array $vars): string
{
// Replace variable placeholders with actual variable values. // Replace variable placeholders with actual variable values.
$composed_url = preg_replace_callback('#\\$([a-zA-Z0-9_]+)(?::[a-z]+)?#i', function($match) use(&$vars) { $route = preg_replace_callback('#\\$([a-zA-Z0-9_]+)(?::[a-z]+)?#i', function($match) use(&$vars) {
if (isset($vars[$match[1]])) if (isset($vars[$match[1]]))
{ {
$replacement = urlencode($vars[$match[1]]); $replacement = urlencode($vars[$match[1]]);
@ -340,9 +352,9 @@ class Router
{ {
return $match[0]; return $match[0];
} }
}, $selected_route); }, $route);
// Add a query string for the remaining arguments. // Add a query string for the remaining arguments.
return $composed_url . (count($vars) ? ('?' . http_build_query($vars)) : ''); return $route . (count($vars) ? ('?' . http_build_query($vars)) : '');
} }
} }