Commit 9092b231 authored by Oliver Bartsch's avatar Oliver Bartsch Committed by Stefan Bürk
Browse files

[BUGFIX] Restore backend module rerouting functionality

Due to the changes in #99620, it is now possible
for a second level module to not define any route.
Such module then automatically uses the routes
from the first available sub module (third-level).

However, this now led to the fact that it was no
longer possible for the BackendModuleValidator
to restore the actually last used third-level module
of such sub modules, because the module object
in the Route object got replaced by the fallback.

This use case is now also properly handled by
checking whether the resolved module is the
request modules' fallback.

Resolves: #99684
Related: #99620
Releases: main
Change-Id: I8cd19417fa66593dd4c612a07723dcbcf5162f5f

Reviewed-by: Stefan Bürk's avatarStefan Bürk <>
Tested-by: core-ci's avatarcore-ci <>
Tested-by: Christian Kuhn's avatarChristian Kuhn <>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <>
Tested-by: Stefan Bürk's avatarStefan Bürk <>
parent 5d94b732
......@@ -77,7 +77,20 @@ class BackendModuleValidator implements MiddlewareInterface
// Overwrite the requested module and the route target
$module = $selectedSubModule;
$route->setOptions(array_replace_recursive($route->getOptions(), $module->getDefaultRouteOptions()));
$route->setOptions(array_replace_recursive($route->getOptions(), $module->getDefaultRouteOptions()['_default']));
} elseif (($routeIdentifier = $route->getOption('_identifier')) !== null
&& $routeIdentifier === $module->getParentModule()?->getIdentifier()
) {
// In case the actually requested module is the parent of the actually resolved module,
// the parent module does not define a route itself and uses the current third-level module
// as fallback. Therefore, we have to check the special "action" key on the "inaccessible"
// parent module to still allow rerouting to another (last used) third-level module.
$inaccessibleParentModule = $module->getParentModule();
$subModuleIdentifier = (string)($backendUser->getModuleData($inaccessibleParentModule->getIdentifier())['action'] ?? '');
if ($inaccessibleParentModule->hasSubModule($subModuleIdentifier)) {
$module = $inaccessibleParentModule->getSubModule($subModuleIdentifier);
$route->setOptions(array_replace_recursive($route->getOptions(), $module->getDefaultRouteOptions()['_default']));
// Validate the requested module
......@@ -52,9 +52,9 @@ class Module extends BaseModule implements ModuleInterface
$defaultRouteOptions = $firstSubModule->getDefaultRouteOptions();
if ($defaultRouteOptions === []) {
if (!isset($defaultRouteOptions['_default'])) {
throw new NonRoutableModuleException(
'No routes could be resolved for module ' . $this->identifier,
'No default route could be resolved for module ' . $this->identifier,
......@@ -95,7 +95,7 @@ final class ModuleRegistry
foreach ($this->modules as $module) {
if (!$module->hasParentModule() && !$module->isStandalone()) {
// Skip modules first level modules, which are not standalone
// Skip first level modules, which are not standalone
$routeCollection = new RouteCollection();
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment