<?php
namespace Cms\FrontendBundle\Service\Resolvers;
use App\Util\Locales;
use Cms\CoreBundle\Util\DateTimeUtils;
use Cms\CoreBundle\Util\Doctrine\EntityManager;
use Cms\FrontendBundle\Service\ResolverManager;
use Cms\TenantBundle\Model\SimpleTenantableInterface;
use DateTimeZone;
use Products\NotificationsBundle\Entity\NotificationsConfig;
use Products\NotificationsBundle\Entity\Profile;
use Products\NotificationsBundle\Service\Notifications\NotificationsConfigService;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
final class LocaleResolver extends AbstractResolver
{
private NotificationsConfigService $notificationsConfigService;
private TokenStorageInterface $tokenStorage;
private RequestStack $request;
/**
* {@inheritDoc}
* @param NotificationsConfigService $notificationsConfigService
* @param TokenStorageInterface $tokenStorage
* @param RequestStack $request
*/
public function __construct(
ResolverManager $rm,
EntityManager $em,
NotificationsConfigService $notificationsConfigService,
TokenStorageInterface $tokenStorage,
RequestStack $request
)
{
parent::__construct($rm, $em);
$this->notificationsConfigService = $notificationsConfigService;
$this->tokenStorage = $tokenStorage;
$this->request = $request;
}
/**
* @param SimpleTenantableInterface $tenantable
* @return DateTimeZone|null
*/
public function resolveTimezoneByTenant(SimpleTenantableInterface $tenantable): ?DateTimeZone
{
// attempt to get the timezone
$timezone = $tenantable->getTenant()->getLocale()->getTimezone();
// if we did not find anything, fallback to utc
if ( ! $timezone) {
$timezone = DateTimeUtils::ZONES__UTC;
}
// use datetime helper to convert into a timezone
// we do this to prevent making a bunch of extra objects
return DateTimeUtils::timezone($timezone);
}
/**
* NOTE: this is really just done for future use in the event we allow better multi-lingual UIs and such...
*
* @param SimpleTenantableInterface $tenantable
* @return string
*/
public function resolvePrimaryLocaleByTenant(SimpleTenantableInterface $tenantable): string
{
return Locales::RFC4646__ENGLISH__UNITED_STATES;
}
/**
* @param SimpleTenantableInterface $tenantable
* @return array
*/
public function resolveSecondaryLocalesByTenant(SimpleTenantableInterface $tenantable): array
{
$notificationsConfig = $this->notificationsConfigService->getNotificationsConfig(
$tenantable,
);
return ($notificationsConfig instanceof NotificationsConfig) ? $notificationsConfig->getTranslationLocales() : [];
}
/**
* @param SimpleTenantableInterface $tenantable
* @return array
*/
public function resolveSecondaryLanguagesByTenant(SimpleTenantableInterface $tenantable): array
{
$locales = $this->resolveSecondaryLocalesByTenant($tenantable);
if (empty($locales)) {
return [];
}
$languages = [];
foreach ($locales as $locale) {
$language = Locales::languageForLocale($locale);
$languages[$language] = locale_get_display_language($language, $language);
}
asort($languages);
return $languages;
}
/**
* @param SimpleTenantableInterface $tenantable
* @return string
*/
public function resolveUserEffectiveLanguage(SimpleTenantableInterface $tenantable): string
{
$user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
if ($user instanceof Profile) {
return $user->getEffectiveLanguage();
}
$request = $this->request->getCurrentRequest();
$googleCookie = $request->cookies->get('googtrans');
if ( ! empty($googleCookie)) {
return explode('/', $googleCookie)[2] ?? Locales::ISO6391__ENGLISH;
}
$preferredLanguage = $request->getPreferredLanguage();
if ($preferredLanguage !== null) {
$languageCode = explode('_', $preferredLanguage)[0];
$supportedLanguagesCodes = array_keys($this->resolveSecondaryLanguagesByTenant($tenantable));
return in_array($languageCode, $supportedLanguagesCodes) ? $languageCode : Locales::ISO6391__ENGLISH;
}
return Locales::ISO6391__ENGLISH;
}
}