mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-05-09 20:12:14 +09:00
Implement route priority
This commit is contained in:
parent
ca183c89a0
commit
a2bd361737
3 changed files with 35 additions and 41 deletions
|
|
@ -55,7 +55,7 @@ class ModuleActionParser
|
||||||
$info->permission_check = new \stdClass;
|
$info->permission_check = new \stdClass;
|
||||||
|
|
||||||
// Parse grants.
|
// Parse grants.
|
||||||
foreach ($xml->grants->grant as $grant)
|
foreach ($xml->grants->grant ?: [] as $grant)
|
||||||
{
|
{
|
||||||
$grant_info = new \stdClass;
|
$grant_info = new \stdClass;
|
||||||
$grant_info->title = self::_getElementsByLang($grant, 'title', $lang);
|
$grant_info->title = self::_getElementsByLang($grant, 'title', $lang);
|
||||||
|
|
@ -65,7 +65,7 @@ class ModuleActionParser
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse permissions not defined in the <actions> section.
|
// Parse permissions not defined in the <actions> section.
|
||||||
foreach ($xml->permissions->permission as $permission)
|
foreach ($xml->permissions->permission ?: [] as $permission)
|
||||||
{
|
{
|
||||||
$action_name = trim($permission['action']);
|
$action_name = trim($permission['action']);
|
||||||
$permission = trim($permission['target']);
|
$permission = trim($permission['target']);
|
||||||
|
|
@ -78,7 +78,7 @@ class ModuleActionParser
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse menus.
|
// Parse menus.
|
||||||
foreach ($xml->menus->menu as $menu)
|
foreach ($xml->menus->menu ?: [] as $menu)
|
||||||
{
|
{
|
||||||
$menu_info = new \stdClass;
|
$menu_info = new \stdClass;
|
||||||
$menu_info->title = self::_getElementsByLang($menu, 'title', $lang);
|
$menu_info->title = self::_getElementsByLang($menu, 'title', $lang);
|
||||||
|
|
@ -90,7 +90,7 @@ class ModuleActionParser
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse actions.
|
// Parse actions.
|
||||||
foreach ($xml->actions->action as $action)
|
foreach ($xml->actions->action ?: [] as $action)
|
||||||
{
|
{
|
||||||
// Parse permissions.
|
// Parse permissions.
|
||||||
$action_name = trim($action['name']);
|
$action_name = trim($action['name']);
|
||||||
|
|
@ -108,21 +108,23 @@ class ModuleActionParser
|
||||||
|
|
||||||
// Parse routes.
|
// Parse routes.
|
||||||
$route_attr = trim($action['route']);
|
$route_attr = trim($action['route']);
|
||||||
$route_tags = $action->route;
|
$route_tags = $action->route ?: [];
|
||||||
$method = trim($action['method']);
|
$method = trim($action['method']);
|
||||||
$route_arg = [];
|
$route_arg = [];
|
||||||
if ($route_attr || count($route_tags))
|
if ($route_attr || count($route_tags))
|
||||||
{
|
{
|
||||||
$methods = $method ? explode('|', strtoupper($method)) : (starts_with('proc', $action_name) ? ['POST'] : ['GET']);
|
$methods = $method ? explode('|', strtoupper($method)) : (starts_with('proc', $action_name) ? ['POST'] : ['GET']);
|
||||||
$routes = $route_attr ? explode_with_escape('|', $route_attr) : array();
|
$routes = $route_attr ? array_map(function($route) {
|
||||||
|
return ['route' => trim($route), 'priority' => 0];
|
||||||
|
}, explode_with_escape('|', $route_attr)) : array();
|
||||||
foreach ($route_tags as $route_tag)
|
foreach ($route_tags as $route_tag)
|
||||||
{
|
{
|
||||||
$routes[] = trim($route_tag['route']);
|
$routes[] = ['route' => trim($route_tag['route']), 'priority' => intval($route_tag['priority'] ?: 0)];
|
||||||
}
|
}
|
||||||
foreach ($routes as $route)
|
foreach ($routes as $route)
|
||||||
{
|
{
|
||||||
$route_info = self::analyzeRoute($route);
|
$route_info = self::analyzeRoute($route);
|
||||||
$route_arg[$route_info->route] = $route_info->vars;
|
$route_arg[$route_info->route] = ['priority' => intval($route_info->priority), 'vars' => $route_info->vars];
|
||||||
foreach ($methods as $method)
|
foreach ($methods as $method)
|
||||||
{
|
{
|
||||||
$info->route->{$method}[$route_info->regexp] = $action_name;
|
$info->route->{$method}[$route_info->regexp] = $action_name;
|
||||||
|
|
@ -177,10 +179,10 @@ class ModuleActionParser
|
||||||
/**
|
/**
|
||||||
* Convert route definition into a regular expression.
|
* Convert route definition into a regular expression.
|
||||||
*
|
*
|
||||||
* @param string $route
|
* @param array $route
|
||||||
* @return object
|
* @return object
|
||||||
*/
|
*/
|
||||||
public static function analyzeRoute(string $route)
|
public static function analyzeRoute(array $route)
|
||||||
{
|
{
|
||||||
// Replace variables in the route definition into appropriate regexp.
|
// Replace variables in the route definition into appropriate regexp.
|
||||||
$var_regexp = '#\\$([a-zA-Z0-9_]+)(?::(' . implode('|', array_keys(self::$_shortcuts)) . '))?#';
|
$var_regexp = '#\\$([a-zA-Z0-9_]+)(?::(' . implode('|', array_keys(self::$_shortcuts)) . '))?#';
|
||||||
|
|
@ -199,14 +201,15 @@ class ModuleActionParser
|
||||||
$named_group = '(?P<' . $match[1] . '>' . $var_pattern . ')';
|
$named_group = '(?P<' . $match[1] . '>' . $var_pattern . ')';
|
||||||
$vars[$match[1]] = $var_type;
|
$vars[$match[1]] = $var_type;
|
||||||
return $named_group;
|
return $named_group;
|
||||||
}, $route);
|
}, $route['route']);
|
||||||
|
|
||||||
// Anchor the regexp at both ends.
|
// Anchor the regexp at both ends.
|
||||||
$regexp = '#^' . strtr($regexp, ['#' => '\\#']) . '$#u';
|
$regexp = '#^' . strtr($regexp, ['#' => '\\#']) . '$#u';
|
||||||
|
|
||||||
// Return the regexp and variable list.
|
// Return the regexp and variable list.
|
||||||
$result = new \stdClass;
|
$result = new \stdClass;
|
||||||
$result->route = preg_replace($var_regexp, '\\$$1', $route);
|
$result->route = preg_replace($var_regexp, '\\$$1', $route['route']);
|
||||||
|
$result->priority = $route['priority'] ?: 0;
|
||||||
$result->regexp = $regexp;
|
$result->regexp = $regexp;
|
||||||
$result->vars = $vars;
|
$result->vars = $vars;
|
||||||
return $result;
|
return $result;
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,12 @@ class Router
|
||||||
'$mid/$document_srl' => array(
|
'$mid/$document_srl' => array(
|
||||||
'regexp' => '#^(?<mid>[a-zA-Z0-9_-]+)/(?<document_srl>[0-9]+)$#',
|
'regexp' => '#^(?<mid>[a-zA-Z0-9_-]+)/(?<document_srl>[0-9]+)$#',
|
||||||
'vars' => ['mid' => 'any', 'document_srl' => 'int'],
|
'vars' => ['mid' => 'any', 'document_srl' => 'int'],
|
||||||
|
'priority' => 30,
|
||||||
),
|
),
|
||||||
'$mid/category/$category' => array(
|
'$mid/category/$category' => array(
|
||||||
'regexp' => '#^(?<mid>[a-zA-Z0-9_-]+)/category/(?<category>[0-9]+)$#',
|
'regexp' => '#^(?<mid>[a-zA-Z0-9_-]+)/category/(?<category>[0-9]+)$#',
|
||||||
'vars' => ['mid' => 'any', 'category' => 'int'],
|
'vars' => ['mid' => 'any', 'category' => 'int'],
|
||||||
|
'priority' => 10,
|
||||||
),
|
),
|
||||||
'$mid/entry/$entry' => array(
|
'$mid/entry/$entry' => array(
|
||||||
'regexp' => '#^(?<mid>[a-zA-Z0-9_-]+)/entry/(?<entry>[^/]+)$#',
|
'regexp' => '#^(?<mid>[a-zA-Z0-9_-]+)/entry/(?<entry>[^/]+)$#',
|
||||||
|
|
@ -38,6 +40,7 @@ class Router
|
||||||
'$mid/$act' => array(
|
'$mid/$act' => array(
|
||||||
'regexp' => '#^(?<mid>[a-zA-Z0-9_-]+)/(?<act>rss|atom|api)$#',
|
'regexp' => '#^(?<mid>[a-zA-Z0-9_-]+)/(?<act>rss|atom|api)$#',
|
||||||
'vars' => ['mid' => 'any', 'act' => 'word'],
|
'vars' => ['mid' => 'any', 'act' => 'word'],
|
||||||
|
'priority' => 20,
|
||||||
),
|
),
|
||||||
'files/download/$file_srl/$file_key/$filename' => array(
|
'files/download/$file_srl/$file_key/$filename' => array(
|
||||||
'regexp' => '#^files/download/(?<file_srl>[0-9]+)/(?<file_key>[a-zA-Z0-9_-]+)/(?<filename>[^/]+)$#',
|
'regexp' => '#^files/download/(?<file_srl>[0-9]+)/(?<file_key>[a-zA-Z0-9_-]+)/(?<filename>[^/]+)$#',
|
||||||
|
|
@ -209,7 +212,7 @@ class Router
|
||||||
// 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::_getRearrangedGlobalRoutes(), $args2);
|
$result = self::_insertRouteVars(self::$_global_routes, $args2);
|
||||||
if ($result !== false)
|
if ($result !== false)
|
||||||
{
|
{
|
||||||
return $result;
|
return $result;
|
||||||
|
|
@ -225,7 +228,7 @@ 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::_getRearrangedGlobalRoutes(), $args);
|
$result = self::_insertRouteVars(self::$_global_routes, $args);
|
||||||
if ($result !== false)
|
if ($result !== false)
|
||||||
{
|
{
|
||||||
return $result;
|
return $result;
|
||||||
|
|
@ -279,24 +282,6 @@ class Router
|
||||||
return self::$_action_cache_module[$module] = $action_info ?: false;
|
return self::$_action_cache_module[$module] = $action_info ?: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get rearranged global routes for argument matching.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected static function _getRearrangedGlobalRoutes(): array
|
|
||||||
{
|
|
||||||
if (!self::$_rearranged_global_routes)
|
|
||||||
{
|
|
||||||
foreach (self::$_global_routes as $route_name => $route_info)
|
|
||||||
{
|
|
||||||
self::$_rearranged_global_routes[$route_name] = $route_info['vars'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::$_rearranged_global_routes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert variables into a route.
|
* Insert variables into a route.
|
||||||
*
|
*
|
||||||
|
|
@ -310,8 +295,8 @@ class Router
|
||||||
if (count($routes) == 1)
|
if (count($routes) == 1)
|
||||||
{
|
{
|
||||||
$selected_route = key($routes);
|
$selected_route = key($routes);
|
||||||
$matched_arguments = array_intersect_key($routes[$selected_route], $vars);
|
$matched_arguments = array_intersect_key($routes[$selected_route]['vars'], $vars);
|
||||||
if (count($matched_arguments) !== count($routes[$selected_route]))
|
if (count($matched_arguments) !== count($routes[$selected_route]['vars']))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -324,10 +309,10 @@ class Router
|
||||||
$reordered_routes = array();
|
$reordered_routes = array();
|
||||||
foreach ($routes as $route => $route_vars)
|
foreach ($routes as $route => $route_vars)
|
||||||
{
|
{
|
||||||
$matched_arguments = array_intersect_key($route_vars, $vars);
|
$matched_arguments = array_intersect_key($route_vars['vars'], $vars);
|
||||||
if (count($matched_arguments) === count($route_vars))
|
if (count($matched_arguments) === count($route_vars['vars']))
|
||||||
{
|
{
|
||||||
$reordered_routes[$route] = count($matched_arguments);
|
$reordered_routes[$route] = $route_vars['priority'] ?? count($matched_arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!count($reordered_routes))
|
if (!count($reordered_routes))
|
||||||
|
|
|
||||||
|
|
@ -57,13 +57,19 @@
|
||||||
</grants>
|
</grants>
|
||||||
<actions>
|
<actions>
|
||||||
<action name="dispBoardContent" type="view" permission="list" standalone="false" index="true">
|
<action name="dispBoardContent" type="view" permission="list" standalone="false" index="true">
|
||||||
<route route="$document_srl:int" />
|
<route route="$document_srl:int" priority="51" />
|
||||||
<route route="page/$page:int" />
|
<route route="$document_srl:int/page/$page:int" priority="52" />
|
||||||
<route route="search/$search_target/$search_keyword" />
|
<route route="category/$category:int/search/$search_target:word/$search_keyword:any" priority="41" />
|
||||||
|
<route route="category/$category:int/search/$search_target:word/$search_keyword:any/page/$page:int" priority="42" />
|
||||||
|
<route route="search/$search_target:word/$search_keyword:any" priority="31" />
|
||||||
|
<route route="search/$search_target:word/$search_keyword:any/page/$page:int" priority="32" />
|
||||||
|
<route route="category/$category:int" priority="21" />
|
||||||
|
<route route="category/$category:int/page/$page:int" priority="22" />
|
||||||
|
<route route="page/$page:int" priority="10" />
|
||||||
</action>
|
</action>
|
||||||
<action name="dispBoardWrite" type="view" permission="write_document" standalone="false" meta-noindex="true">
|
<action name="dispBoardWrite" type="view" permission="write_document" standalone="false" meta-noindex="true">
|
||||||
<route route="write" />
|
<route route="write" />
|
||||||
<route route="$document_srl/edit" />
|
<route route="$document_srl:int/edit" />
|
||||||
</action>
|
</action>
|
||||||
<action name="dispBoardDelete" type="view" permission="write_document" standalone="false" meta-noindex="true" route="$document_srl/delete" />
|
<action name="dispBoardDelete" type="view" permission="write_document" standalone="false" meta-noindex="true" route="$document_srl/delete" />
|
||||||
<action name="dispBoardWriteComment" type="view" permission="write_comment" standalone="false" meta-noindex="true" route="$document_srl/comment" />
|
<action name="dispBoardWriteComment" type="view" permission="write_comment" standalone="false" meta-noindex="true" route="$document_srl/comment" />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue