<?php
namespace w3des\AdminBundle\Controller;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use w3des\AdminBundle\Service\I18n;
class I18nController
{
private CacheInterface $cache;
private TranslatorInterface $translator;
private int $expire;
private I18n $i18n;
public function __construct(I18n $i18n, CacheInterface $cache, TranslatorInterface $translator)
{
$this->cache = $cache;
$this->translator = $translator;
$this->expire = 3600 * 24 * 7;
$this->i18n = $i18n;
}
public function __invoke(Request $request, string $domain, bool $simple, string $_locale, string $hash = null)
{
$res = new Response();
$res->setEtag( md5($_locale . ($simple ? 'T' : 'N') . ($hash ?: $this->i18n->getHash())), true);
$res->setLastModified(new \DateTime('@' . $this->i18n->getHash()));
$res->setPublic();
$res->setVary('Authorization,User-Agent');
if ($hash) {
$res->setMaxAge($this->expire);
$res->headers->addCacheControlDirective('must-revalidate', true);
}
if ($res->isNotModified($request)) {
return $res;
}
$res->setContent($this->load($domain, $simple, $_locale));
$res->headers->set('Content-Type', 'text/javascript');
$res->setStatusCode(200);
return $res;
}
private function load(string $domain, bool $simple, string $_locale) {
return $this->cache->get('locale.' . $domain . '.' . $_locale . ($simple ? '.simple' : ''), function (ItemInterface $item) use ($domain, $_locale, $simple) {
/** @var \Symfony\Component\Translation\TranslatorBagInterface $trans */
$item->tag(I18n::CACHE_TAG);
$messages = [];
$prefix = $simple ? '' : ($domain . '.');
$fallback = $this->translator->getCatalogue($_locale)
->getFallbackCatalogue();
if ($fallback->getFallbackCatalogue()) {
foreach ($fallback->getFallbackCatalogue()
->all($domain) as $k => $v) {
$messages[$prefix . $k] = $v;
}
}
foreach ($fallback->all($domain) as $k => $v) {
$messages[$prefix . $k] = $v;
}
if ($fallback->getLocale() != $_locale) {
foreach ($this->translator->getCatalogue($_locale)
->all($domain) as $k => $v) {
$messages[$prefix . $k] = $v;
}
}
return sprintf("window.i18n = window.i18n || { locale : '%s', fallback : '%s', domain: {}, flat: {} };
window.i18n.domain = {...window.i18n.domain, ...%s};
", $_locale, $fallback->getLocale(), \json_encode($messages, \JSON_UNESCAPED_UNICODE));
});
}
}