From c8a6b8de791f90e1da81a24828be943ff00e7bc5 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 18 Jun 2020 16:36:27 +0900 Subject: [PATCH] Support global routes --- .../framework/parsers/moduleactionparser.php | 1 + common/framework/router.php | 98 ++++++++++++++----- modules/integration_search/conf/module.xml | 6 +- .../integration_search.class.php | 10 -- modules/module/module.class.php | 5 + modules/module/module.controller.php | 13 ++- .../module/queries/insertActionForward.xml | 1 + modules/module/schemas/action_forward.xml | 1 + 8 files changed, 94 insertions(+), 41 deletions(-) diff --git a/common/framework/parsers/moduleactionparser.php b/common/framework/parsers/moduleactionparser.php index dd330ad5e..b504b4a00 100644 --- a/common/framework/parsers/moduleactionparser.php +++ b/common/framework/parsers/moduleactionparser.php @@ -126,6 +126,7 @@ class ModuleActionParser $action_info->standalone = trim($action['standalone']) === 'false' ? 'false' : 'true'; $action_info->check_csrf = (trim($action['check_csrf']) ?: trim($action['check-csrf'])) === 'false' ? 'false' : 'true'; $action_info->meta_noindex = (trim($action['meta_noindex']) ?: trim($action['meta-noindex'])) === 'true' ? 'true' : 'false'; + $action_info->global_route = (trim($action['global_route']) ?: trim($action['global-route'])) === 'true' ? 'true' : 'false'; $action_info->use_ssl = (trim($action['use_ssl']) ?: trim($action['use-ssl'])) === 'true' ? 'true' : 'false'; $info->action->{$action_name} = $action_info; diff --git a/common/framework/router.php b/common/framework/router.php index 55407cbc6..fa6ae892d 100644 --- a/common/framework/router.php +++ b/common/framework/router.php @@ -2,6 +2,8 @@ namespace Rhymix\Framework; +use function Complex\sec; + /** * The router class. */ @@ -59,7 +61,8 @@ class Router */ protected static $_action_cache_prefix = array(); protected static $_action_cache_module = array(); - protected static $_forwarded_cache = array(); + protected static $_global_forwarded_cache = array(); + protected static $_internal_forwarded_cache = array(); protected static $_route_cache = array(); /** @@ -118,7 +121,7 @@ class Router } // Try to detect the prefix. This might be $mid. - if ($rewrite_level > 1 && preg_match('#^([a-zA-Z0-9_-]+)(?:/(.*))?#s', $url, $matches)) + if ($rewrite_level >= 2 && preg_match('#^([a-zA-Z0-9_-]+)(?:/(.*))?#s', $url, $matches)) { // Separate the prefix and the internal part of the URL. $prefix = $matches[1]; @@ -139,7 +142,7 @@ class Router } // Check other modules. - $forwarded_routes = self::_getForwardedRoutes(); + $forwarded_routes = self::_getForwardedRoutes('internal'); foreach ($forwarded_routes[$method] ?: [] as $regexp => $action) { if (preg_match($regexp, $internal_url, $matches)) @@ -166,6 +169,21 @@ class Router } } + // Try registered global routes. + if ($rewrite_level >= 2) + { + $global_routes = self::_getForwardedRoutes('global'); + foreach ($global_routes[$method] ?: [] as $regexp => $action) + { + if (preg_match($regexp, $url, $matches)) + { + $matches = array_filter($matches, 'is_string', \ARRAY_FILTER_USE_KEY); + $allargs = array_merge(['act' => $action[1]], $matches, $args); + return (object)['status' => 200, 'url' => $url, 'args' => $allargs]; + } + } + } + // Try XE-compatible global routes. foreach (self::$_global_routes as $route_info) { @@ -227,12 +245,12 @@ class Router return self::_insertRouteVars(self::$_route_cache[$keys_string], $args); } + // Remove $mid and $act from arguments and work with the remainder. + $args2 = $args; unset($args2['mid'], $args2['act']); + // If $mid exists, try routes defined in the module. if ($rewrite_level >= 2 && isset($args['mid'])) { - // Remove $mid from arguments and work with the remainder. - $args2 = $args; unset($args2['mid'], $args2['act']); - // Get module action info. $action_info = self::_getActionInfoByPrefix($args['mid']); @@ -252,7 +270,7 @@ class Router } // Check other modules for $act. - $forwarded_routes = self::_getForwardedRoutes(); + $forwarded_routes = self::_getForwardedRoutes('internal'); if (isset($forwarded_routes['reverse'][$act])) { $result = self::_getBestMatchingRoute($forwarded_routes['reverse'][$act], $args2); @@ -263,22 +281,26 @@ class Router } } - // 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')) - { - $result = self::_getBestMatchingRoute(self::$_global_routes, $args2); - if ($result !== false) - { - self::$_route_cache[$keys_string] = $result; - return self::_insertRouteVars($result, $args2); - } - } - // Try the generic mid/act pattern. self::$_route_cache[$keys_string] = '$mid/$act'; return $args['mid'] . '/' . $args['act'] . (count($args2) ? ('?' . http_build_query($args2)) : ''); } + // Try registered global routes. + if ($rewrite_level >= 2 && isset($args['act'])) + { + $global_routes = self::_getForwardedRoutes('global'); + if (isset($global_routes['reverse'][$args['act']])) + { + $result = self::_getBestMatchingRoute($global_routes['reverse'][$args['act']], $args2); + if ($result !== false) + { + self::$_route_cache[$keys_string] = $result . '$act:delete'; + return self::_insertRouteVars($result, $args2); + } + } + } + // Try XE-compatible global routes. if ($rewrite_level >= 1) { @@ -343,14 +365,26 @@ class Router /** * Get the list of routes that are registered for action-forward. * - * @return object + * @param string $type + * @return array */ - protected static function _getForwardedRoutes() + protected static function _getForwardedRoutes(string $type): array { - if (count(self::$_forwarded_cache)) + if ($type === 'internal' && count(self::$_internal_forwarded_cache)) { - return self::$_forwarded_cache; + return self::$_internal_forwarded_cache; } + if ($type === 'global' && count(self::$_global_forwarded_cache)) + { + return self::$_global_forwarded_cache; + } + + self::$_global_forwarded_cache['GET'] = array(); + self::$_global_forwarded_cache['POST'] = array(); + self::$_global_forwarded_cache['reverse'] = array(); + self::$_internal_forwarded_cache['GET'] = array(); + self::$_internal_forwarded_cache['POST'] = array(); + self::$_internal_forwarded_cache['reverse'] = array(); $action_forward = \ModuleModel::getActionForward(); foreach ($action_forward as $action_name => $action_info) @@ -359,12 +393,26 @@ class Router { foreach ($action_info->route_regexp as $regexp_info) { - self::$_forwarded_cache[$regexp_info[0]][$regexp_info[1]] = [$action_info->module, $action_name]; + if ($action_info->global_route === 'Y') + { + self::$_global_forwarded_cache[$regexp_info[0]][$regexp_info[1]] = [$action_info->module, $action_name]; + } + else + { + self::$_internal_forwarded_cache[$regexp_info[0]][$regexp_info[1]] = [$action_info->module, $action_name]; + } + } + if ($action_info->global_route === 'Y') + { + self::$_global_forwarded_cache['reverse'][$action_name] = $action_info->route_config; + } + else + { + self::$_internal_forwarded_cache['reverse'][$action_name] = $action_info->route_config; } - self::$_forwarded_cache['reverse'][$action_name] = $action_info->route_config; } } - return self::$_forwarded_cache; + return $type === 'internal' ? self::$_internal_forwarded_cache : self::$_global_forwarded_cache; } /** diff --git a/modules/integration_search/conf/module.xml b/modules/integration_search/conf/module.xml index 89e20d10a..a3f3e86fe 100644 --- a/modules/integration_search/conf/module.xml +++ b/modules/integration_search/conf/module.xml @@ -2,7 +2,11 @@ - + + + + + diff --git a/modules/integration_search/integration_search.class.php b/modules/integration_search/integration_search.class.php index 3d2ff0c17..a2cbc7c34 100644 --- a/modules/integration_search/integration_search.class.php +++ b/modules/integration_search/integration_search.class.php @@ -39,10 +39,6 @@ class integration_search extends ModuleObject } } - if (!$oModuleModel->getActionForward('IS')) - { - return true; - } return false; } @@ -70,12 +66,6 @@ class integration_search extends ModuleObject } } } - - if (!$oModuleModel->getActionForward('IS')) - { - $oModuleController = getController('module'); - $oModuleController->insertActionForward('integration_search', 'view', 'IS'); - } } /** diff --git a/modules/module/module.class.php b/modules/module/module.class.php index 0b6060562..a092b2e9f 100644 --- a/modules/module/module.class.php +++ b/modules/module/module.class.php @@ -135,6 +135,7 @@ class module extends ModuleObject // check route columns in action_forward table if(!$oDB->isColumnExists('action_forward', 'route_regexp')) return true; if(!$oDB->isColumnExists('action_forward', 'route_config')) return true; + if(!$oDB->isColumnExists('action_forward', 'global_route')) return true; } /** @@ -462,6 +463,10 @@ class module extends ModuleObject { $oDB->addColumn('action_forward', 'route_config', 'text'); } + if(!$oDB->isColumnExists('action_forward', 'global_route')) + { + $oDB->addColumn('action_forward', 'global_route', 'char', 1, 'N', true); + } } /** diff --git a/modules/module/module.controller.php b/modules/module/module.controller.php index f84415115..bd532eb48 100644 --- a/modules/module/module.controller.php +++ b/modules/module/module.controller.php @@ -19,14 +19,15 @@ class moduleController extends module * Action forward finds and forwards if an action is not in the requested module * This is used when installing a module */ - function insertActionForward($module, $type, $act, $route_regexp = null, $route_config = null) + function insertActionForward($module, $type, $act, $route_regexp = null, $route_config = null, $global_route = 'N') { $args = new stdClass(); $args->module = $module; $args->type = $type; $args->act = $act; - $args->route_regexp = $route_regexp; - $args->route_config = $route_config; + $args->route_regexp = serialize($route_regexp); + $args->route_config = serialize($route_config); + $args->global_route = $global_route === 'Y' ? 'Y' : 'N'; $output = executeQuery('module.insertActionForward', $args); Rhymix\Framework\Cache::delete('action_forward'); @@ -1337,6 +1338,7 @@ class moduleController extends module 'type' => $module_action_info->action->{$action_name}->type, 'regexp' => array(), 'config' => $action_info->route, + 'global_route' => $action_info->global_route ? 'Y' : 'N', ); } } @@ -1368,7 +1370,8 @@ class moduleController extends module } } elseif ($action_forward[$action_name]->route_regexp !== $route_info['regexp'] || - $action_forward[$action_name]->route_config !== $route_info['config']) + $action_forward[$action_name]->route_config !== $route_info['config'] || + $action_forward[$action_name]->global_route !== $route_info['global_route']) { $output = $this->deleteActionForward($module_name, $route_info['type'], $action_name); if (!$output->toBool()) @@ -1377,7 +1380,7 @@ class moduleController extends module } $output = $this->insertActionForward($module_name, $route_info['type'], $action_name, - serialize($route_info['regexp']), serialize($route_info['config'])); + $route_info['regexp'], $route_info['config'], $route_info['global_route']); if (!$output->toBool()) { return $output; diff --git a/modules/module/queries/insertActionForward.xml b/modules/module/queries/insertActionForward.xml index d2cb1bc68..acd9c532a 100644 --- a/modules/module/queries/insertActionForward.xml +++ b/modules/module/queries/insertActionForward.xml @@ -8,5 +8,6 @@ + diff --git a/modules/module/schemas/action_forward.xml b/modules/module/schemas/action_forward.xml index 2a1989a89..59ad98fa8 100644 --- a/modules/module/schemas/action_forward.xml +++ b/modules/module/schemas/action_forward.xml @@ -4,4 +4,5 @@ +