Skip to main content

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.