diff --git a/common/framework/router.php b/common/framework/router.php index 2a453483e..e18a891a0 100644 --- a/common/framework/router.php +++ b/common/framework/router.php @@ -136,6 +136,18 @@ class Router } } + // Check other modules. + $all_routes = self::_getAllCachedRoutes(); + foreach ($all_routes->{$method} as $regexp => $action) + { + if (preg_match($regexp, $internal_url, $matches)) + { + $matches = array_filter($matches, 'is_string', \ARRAY_FILTER_USE_KEY); + $allargs = array_merge(['mid' => $prefix, 'act' => $action[1]], $matches, $args); + return $allargs; + } + } + // Try the generic mid/act pattern. if (preg_match('#^[a-zA-Z0-9_]+$#', $internal_url)) { @@ -223,6 +235,18 @@ class Router } } + // Check other modules for $act. + $all_routes = self::_getAllCachedRoutes(); + if (isset($all_routes->reverse[$act])) + { + $result = self::_getBestMatchingRoute($all_routes->reverse[$act], $args2); + if ($result !== false) + { + self::$_route_cache[$keys_string] = '$mid/' . $result . '$act:delete'; + return $args['mid'] . '/' . self::_insertRouteVars($result, $args2); + } + } + // 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')) { @@ -300,6 +324,23 @@ class Router return self::$_action_cache_module[$module] = $action_info ?: false; } + /** + * Get the list of all cached routes from all modules. + * + * @return object + */ + protected static function _getAllCachedRoutes() + { + $cache_key = 'site_and_module:action_with_routes'; + $result = Cache::get($cache_key); + if ($result === null) + { + $result = (object)array('GET' => [], 'POST' => [], 'reverse' => []); + Cache::set($cache_key, $result, 0, true); + } + return $result; + } + /** * Find the best matching route for an array of variables. * diff --git a/modules/member/conf/module.xml b/modules/member/conf/module.xml index 446984c48..ab494595a 100644 --- a/modules/member/conf/module.xml +++ b/modules/member/conf/module.xml @@ -2,20 +2,20 @@ - - + + - + - - - - - + + + + + diff --git a/modules/module/module.model.php b/modules/module/module.model.php index a2108437b..260983caa 100644 --- a/modules/module/module.model.php +++ b/modules/module/module.model.php @@ -723,13 +723,36 @@ class moduleModel extends module $info = Rhymix\Framework\Cache::get($cache_key); if($info === null) { + // Load the XML file. $info = Rhymix\Framework\Parsers\ModuleActionParser::loadXML($xml_file); + + // Add all routes from the module to a global list. + $action_cache_key = 'site_and_module:action_with_routes'; + $action_with_routes = Rhymix\Framework\Cache::get($action_cache_key) ?: (object)array('GET' => [], 'POST' => [], 'reverse' => []); + foreach ($info->route->GET as $regexp => $action) + { + $action_with_routes->GET[$regexp] = [$module, $action]; + } + foreach ($info->route->POST as $regexp => $action) + { + $action_with_routes->POST[$regexp] = [$module, $action]; + } + foreach ($info->action as $action_name => $action_info) + { + if (count($action_info->route) && $action_info->standalone !== 'false') + { + $action_with_routes->reverse[$action_name] = $action_info->route; + } + } + + // Set cache entries. + Rhymix\Framework\Cache::set($action_cache_key, $action_with_routes, 0, true); Rhymix\Framework\Cache::set($cache_key, $info, 0, true); } return $info; } - + /** * Get a skin list for js API. * return void