User Detection Events
The UserHelper dispatches two events that allow you to intercept and override the user's detected language list and country before the default detection logic runs.
Calling stopPropagation() on the event skips the built-in detection entirely and uses the value you set instead.
Override accepted languages
Event: i18n.user.languages
Event class: OpenDxp\Bundle\I18nBundle\Event\UserLanguagesEvent
Constant: I18nEvents::USER_LANGUAGES
Dispatched at the start of UserHelper::getLanguagesAcceptedByUser(), before the Accept-Language header is parsed.
Use cases
- Force a specific language for a user group (e.g. based on a session value or JWT claim)
- Map custom language codes to OpenDXP-valid language codes
- Return an empty list to suppress automatic language detection
Example
<?php
namespace App\EventListener;
use OpenDxp\Bundle\I18nBundle\Event\UserLanguagesEvent;
use OpenDxp\Bundle\I18nBundle\I18nEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class UserLanguagesListener implements EventSubscriberInterface
{
public function __construct(private readonly RequestStack $requestStack)
{
}
public static function getSubscribedEvents(): array
{
return [
I18nEvents::USER_LANGUAGES => 'onUserLanguages',
];
}
public function onUserLanguages(UserLanguagesEvent $event): void
{
$session = $this->requestStack->getSession();
$language = $session->get('preferred_language');
if ($language !== null) {
$event->setLanguages([$language]);
$event->stopPropagation(); // skip Accept-Language header parsing
}
}
}
Override detected country
Event: i18n.user.country
Event class: OpenDxp\Bundle\I18nBundle\Event\UserCountryEvent
Constant: I18nEvents::USER_COUNTRY
Dispatched at the start of UserHelper::guessCountry(), before the GeoIP database is consulted.
Use cases
- Override country detection via a session or cookie value
- Use a custom IP-to-country resolver instead of GeoIP
- Provide country detection when no GeoIP database is configured
Example
<?php
namespace App\EventListener;
use OpenDxp\Bundle\I18nBundle\Event\UserCountryEvent;
use OpenDxp\Bundle\I18nBundle\I18nEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class UserCountryListener implements EventSubscriberInterface
{
public function __construct(private readonly RequestStack $requestStack)
{
}
public static function getSubscribedEvents(): array
{
return [
I18nEvents::USER_COUNTRY => 'onUserCountry',
];
}
public function onUserCountry(UserCountryEvent $event): void
{
$session = $this->requestStack->getSession();
$country = $session->get('forced_country');
if ($country !== null) {
$event->setCountry(strtoupper($country));
$event->stopPropagation(); // skip GeoIP lookup
}
}
}
Registering listeners
# config/services.yaml
services:
App\EventListener\UserLanguagesListener:
tags:
- { name: kernel.event_subscriber }
App\EventListener\UserCountryListener:
tags:
- { name: kernel.event_subscriber }
Passing null as country
setCountry(null) is a valid override — it signals that the country is intentionally unknown. Only stopPropagation() determines whether the GeoIP lookup is skipped; the value itself may be null.