Language switch doesn't work with pretty URLs on CRUD controllers
Describe the bug After switching to pretty URLs, I can't switch locale in CRUD controllers anymore.
To Reproduce Package version: 4.24.4 PHP version: 8.4
Locale configuration in config/packages/translation.yaml:
framework:
default_locale: ru
enabled_locales: ['en', 'ru']
Dashboard controller:
public function configureDashboard(): Dashboard
{
return Dashboard::new()
->setLocales(['en', 'ru'])
;
}
- I'm on the page http://localhost:7000/ru/admin/dashboard/customer (Ru locale)
- The locale switcher shows two languages - English and Russian
- The En locale link is: http://localhost:7000/ru/admin/dashboard/customer?_locale=en
- When I click on the English link, nothing changes, I still see the Russian language page.
- If I edit the URL manually to switch to the
/en/URL prefix, I get theNo route found for "GET http://localhost:7000/en/admin/dashboard/customer"error.
This issue doesn't happen on the Dashboard http://localhost:7000/ru/admin/dashboard - the link to the English version is correct: http://localhost:7000/en/admin/dashboard and on custom routes (non-CRUD controllers).
For custom controllers, I can see the following entries in the generated routes file in the cache:
...
'admin_profile.en' => [[], ['_controller' => 'App\\Controller\\Admin\\ProfileController', '_locale' => 'en', '_canonical_route' => 'admin_profile'], [], [['text', '/en/admin/profile']], [], [], []],
'admin_profile.ru' => [[], ['_controller' => 'App\\Controller\\Admin\\ProfileController', '_locale' => 'ru', '_canonical_route' => 'admin_profile'], [], [['text', '/ru/admin/profile']], [], [], []],
...
'admin_profile' => [[], ['_controller' => 'App\\Controller\\Admin\\ProfileController'], ['_locale' => 'en|ru'], [['text', '/admin/profile']], [], [], []],
But for CRUD controllers, I can see only this kind of entries:
'admin_dashboard_customer_index' => [[], ['_locale' => 'ru', '_controller' => 'App\\Controller\\Admin\\CustomerCrudController::index', 'routeCreatedByEasyAdmin' => true, 'dashboardControllerFqcn' => 'App\\Controller\\Admin\\DashboardController', 'crudControllerFqcn' => 'App\\Controller\\Admin\\CustomerCrudController', 'crudAction' => 'index'], ['_locale' => 'en|ru'], [['text', '/ru/admin/dashboard/customer']], [], [], []],
I think the issue is a regression after #6754. The \EasyCorp\Bundle\EasyAdminBundle\Router\AdminRouteGenerator::generateAdminRoutes() method now adds the _locale parameter to the generated CRUD controller routes. This leads to the issue in the \Symfony\Component\Routing\Loader\Configurator\Traits\PrefixTrait::addPrefix() method that is postprocessing routes returned by the EasyAdmin generator where it checks for the _locale parameter presence and if present, it doesn't generate localized URLs:
final protected function addPrefix(RouteCollection $routes, string|array $prefix, bool $trailingSlashOnRoot): void
{
...
foreach ($routes->all() as $name => $route) {
if (null === $locale = $route->getDefault('_locale')) { // Prefixed locale routes are generated inside this IF block
$priority = $routes->getPriority($name) ?? 0;
$routes->remove($name);
foreach ($prefix as $locale => $localePrefix) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setRequirement('_locale', preg_quote($locale));
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setPath($localePrefix.(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));
$routes->add($name.'.'.$locale, $localizedRoute, $priority);
}
...
The following patch solves the issue for me until a proper fix is introduced:
--- a/src/Router/AdminRouteGenerator.php
+++ b/src/Router/AdminRouteGenerator.php
@@ -169,7 +169,6 @@
}
$defaults = [
- '_locale' => $this->defaultLocale,
'_controller' => $crudControllerFqcn.'::'.$actionName,
EA::ROUTE_CREATED_BY_EASYADMIN => true,
EA::DASHBOARD_CONTROLLER_FQCN => $dashboardFqcn,
I also have the same issue when adding the locale prefixes to admin routes, and the patch @speller fixes it for me too.
I just implemented the pretty URLs, and the dashboard index was correctly using the browser's language, but opening a CRUD Controller would switch it to the fallback language. @speller's patch fixes it, thanks!