I run a multi-language Symfony 4.4 website where the locale is part of the URL. So I have /it/
, /fr/
and so on.
My routes look like this:
/**
* @Route({
* "it": "/it/azienda/",
* "es": "/es/empresa/"
* }, name="app_cms_about")
*/
Then I've a pre-controller event that set the correct locale:
public function onRouteRequest(ControllerEvent $event)
{
// ... checks and stuff ...
$event->getRequest()->setLocale($ln);
}
Everything works as expected via web, but now I need to manage this language difference in a CLI Command: basically it means that when I run $this->urlGenerator->generate('app_cms_about')
from the CLI, I expect to get the locale-based URL.
The user must pass the locale to the CLI Command to as an argument:
protected function configure()
{
$this->addArgument(
"app_language",
InputArgument::REQUIRED,
'The site to run on: `it`, `es`, ...');
}
Now I just need to set this somehow. I'd love to it with an event, but of course there is no getRequest()
on the CLI event to set the locale on.
How do I set the locale on a Symfony 4 CLI Command?
CodePudding user response:
Setting the locale does not make a lot of sense for a console application. What has a locale is the user request, and there is no request during a command line run.
But you want seems to be to be able to get URLs with the appropriate locale:
Then, straight from the docs:
When a route is localized, Symfony uses by default the current request locale. Pass a different '_locale' value if you want to set the locale explicitly
E.g.:
$aboutUrlIt = $this->router->generate('app_cms_about', ['_locale' => 'it']);
You mention in comments the setting default_locale
, and that since you can change this it means console applications "have a locale set". But you are reaching the wrong conclussion from this: this setting is to set a default locale in case where no locale is set in the request. Or, for example, when there is no request, as in a command line application.
You cannot change that setting during runtime, because that setting is part of the compiled container, which is compiled before the application is run.
CodePudding user response:
Following Symfony calls with xdebug I was able to find the solution I was looking for. I built a listener as the one I'm using via web:
services:
App\EventListener\CommandStartListener:
tags:
- { name: kernel.event_listener, method: onCommandStart, event: console.command }
<?php
namespace App\EventListener;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Routing\RouterInterface;
class CommandStartListener
{
protected RouterInterface $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function onCommandStart(ConsoleCommandEvent $event) : ?string
{
// ... checks and stuff ...
try {
$lnParam = $event->getInput()->getArgument("app_language");
} catch( \Exception $ex) {
return null;
}
$this->router->getContext()->setParameter('_locale', $lnParam);
return $lnParam;
}
}
This makes any urlGenerator->generate()
behave correctly.
hat tip to @yivi for pointing me into the right direction.