Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add twig extension to canonicalize locales for momentjs (#336)
- Loading branch information
1 parent
43463cd
commit 6c297ca
Showing
6 changed files
with
305 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
use Sonata\Form\Twig\CanonicalizeRuntime; | ||
use Sonata\Form\Twig\Extension\CanonicalizeExtension; | ||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; | ||
use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator; | ||
|
||
return static function (ContainerConfigurator $containerConfigurator): void { | ||
// Use "service" function for creating references to services when dropping support for Symfony 4.4 | ||
$containerConfigurator->services() | ||
|
||
->set('sonata.form.twig.canonicalize_extension', CanonicalizeExtension::class) | ||
->tag('twig.extension') | ||
|
||
->set('sonata.form.twig.canonicalize_runtime', CanonicalizeRuntime::class) | ||
->tag('twig.runtime') | ||
->args([ | ||
new ReferenceConfigurator('request_stack'), | ||
]); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\Form\Twig; | ||
|
||
use Symfony\Component\HttpFoundation\RequestStack; | ||
use Twig\Extension\RuntimeExtensionInterface; | ||
|
||
final class CanonicalizeRuntime implements RuntimeExtensionInterface | ||
{ | ||
// @todo: there are more locales which are not supported by "Moment.js" NPM library and they need to be translated/normalized/canonicalized here | ||
private const MOMENT_UNSUPPORTED_LOCALES = [ | ||
'de' => ['de', 'de-at'], | ||
'es' => ['es', 'es-do'], | ||
'nl' => ['nl', 'nl-be'], | ||
'fr' => ['fr', 'fr-ca', 'fr-ch'], | ||
]; | ||
|
||
private RequestStack $requestStack; | ||
|
||
/** | ||
* @internal This class should only be used through Twig | ||
*/ | ||
public function __construct(RequestStack $requestStack) | ||
{ | ||
$this->requestStack = $requestStack; | ||
} | ||
|
||
/** | ||
* Returns a canonicalized locale for "Moment.js" NPM library, | ||
* or `null` if the locale's language is "en", which doesn't require localization. | ||
*/ | ||
public function getCanonicalizedLocaleForMoment(): ?string | ||
{ | ||
$locale = $this->getLocale(); | ||
|
||
// "en" language doesn't require localization. | ||
if (('en' === $lang = substr($locale, 0, 2)) && !\in_array($locale, ['en-au', 'en-ca', 'en-gb', 'en-ie', 'en-nz'], true)) { | ||
return null; | ||
} | ||
|
||
foreach (self::MOMENT_UNSUPPORTED_LOCALES as $language => $locales) { | ||
if ($language === $lang && !\in_array($locale, $locales, true)) { | ||
$locale = $language; | ||
} | ||
} | ||
|
||
return $locale; | ||
} | ||
|
||
private function getLocale(): string | ||
{ | ||
$request = $this->requestStack->getCurrentRequest(); | ||
if (null === $request) { | ||
throw new \LogicException('The request stack is empty.'); | ||
} | ||
|
||
return str_replace('_', '-', $request->getLocale()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\Form\Twig\Extension; | ||
|
||
use Sonata\Form\Twig\CanonicalizeRuntime; | ||
use Twig\Extension\AbstractExtension; | ||
use Twig\TwigFunction; | ||
|
||
final class CanonicalizeExtension extends AbstractExtension | ||
{ | ||
/** | ||
* @return TwigFunction[] | ||
*/ | ||
public function getFunctions(): array | ||
{ | ||
return [ | ||
new TwigFunction('sonata_form_canonicalize_locale_for_moment', [CanonicalizeRuntime::class, 'getCanonicalizedLocaleForMoment']), | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\Form\Tests\Twig; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Sonata\Form\Twig\CanonicalizeRuntime; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\RequestStack; | ||
|
||
final class CanonicalizeRuntimeTest extends TestCase | ||
{ | ||
private Request $request; | ||
|
||
private CanonicalizeRuntime $canonicalizeRuntime; | ||
|
||
protected function setUp(): void | ||
{ | ||
$this->request = new Request(); | ||
$requestStack = new RequestStack(); | ||
$requestStack->push($this->request); | ||
$this->canonicalizeRuntime = new CanonicalizeRuntime($requestStack); | ||
} | ||
|
||
/** | ||
* @dataProvider momentLocalesProvider | ||
*/ | ||
public function testCanonicalizedLocaleForMoment(?string $expected, string $original): void | ||
{ | ||
$this->changeLocale($original); | ||
static::assertSame($expected, $this->canonicalizeRuntime->getCanonicalizedLocaleForMoment()); | ||
} | ||
|
||
/** | ||
* @return array<array{?string, string}> | ||
*/ | ||
public function momentLocalesProvider(): array | ||
{ | ||
return [ | ||
['af', 'af'], | ||
['ar-dz', 'ar-dz'], | ||
['ar', 'ar'], | ||
['ar-ly', 'ar-ly'], | ||
['ar-ma', 'ar-ma'], | ||
['ar-sa', 'ar-sa'], | ||
['ar-tn', 'ar-tn'], | ||
['az', 'az'], | ||
['be', 'be'], | ||
['bg', 'bg'], | ||
['bn', 'bn'], | ||
['bo', 'bo'], | ||
['br', 'br'], | ||
['bs', 'bs'], | ||
['ca', 'ca'], | ||
['cs', 'cs'], | ||
['cv', 'cv'], | ||
['cy', 'cy'], | ||
['da', 'da'], | ||
['de-at', 'de-at'], | ||
['de', 'de'], | ||
['de', 'de-de'], | ||
['dv', 'dv'], | ||
['el', 'el'], | ||
[null, 'en'], | ||
[null, 'en-us'], | ||
['en-au', 'en-au'], | ||
['en-ca', 'en-ca'], | ||
['en-gb', 'en-gb'], | ||
['en-ie', 'en-ie'], | ||
['en-nz', 'en-nz'], | ||
['eo', 'eo'], | ||
['es-do', 'es-do'], | ||
['es', 'es-ar'], | ||
['es', 'es-mx'], | ||
['es', 'es'], | ||
['et', 'et'], | ||
['eu', 'eu'], | ||
['fa', 'fa'], | ||
['fi', 'fi'], | ||
['fo', 'fo'], | ||
['fr-ca', 'fr-ca'], | ||
['fr-ch', 'fr-ch'], | ||
['fr', 'fr-fr'], | ||
['fr', 'fr'], | ||
['fy', 'fy'], | ||
['gd', 'gd'], | ||
['gl', 'gl'], | ||
['he', 'he'], | ||
['hi', 'hi'], | ||
['hr', 'hr'], | ||
['hu', 'hu'], | ||
['hy-am', 'hy-am'], | ||
['id', 'id'], | ||
['is', 'is'], | ||
['it', 'it'], | ||
['ja', 'ja'], | ||
['jv', 'jv'], | ||
['ka', 'ka'], | ||
['kk', 'kk'], | ||
['km', 'km'], | ||
['ko', 'ko'], | ||
['ky', 'ky'], | ||
['lb', 'lb'], | ||
['lo', 'lo'], | ||
['lt', 'lt'], | ||
['lv', 'lv'], | ||
['me', 'me'], | ||
['mi', 'mi'], | ||
['mk', 'mk'], | ||
['ml', 'ml'], | ||
['mr', 'mr'], | ||
['ms', 'ms'], | ||
['ms-my', 'ms-my'], | ||
['my', 'my'], | ||
['nb', 'nb'], | ||
['ne', 'ne'], | ||
['nl-be', 'nl-be'], | ||
['nl', 'nl'], | ||
['nl', 'nl-nl'], | ||
['nn', 'nn'], | ||
['pa-in', 'pa-in'], | ||
['pl', 'pl'], | ||
['pt-br', 'pt-br'], | ||
['pt', 'pt'], | ||
['ro', 'ro'], | ||
['ru', 'ru'], | ||
['se', 'se'], | ||
['si', 'si'], | ||
['sk', 'sk'], | ||
['sl', 'sl'], | ||
['sq', 'sq'], | ||
['sr-cyrl', 'sr-cyrl'], | ||
['sr', 'sr'], | ||
['ss', 'ss'], | ||
['sv', 'sv'], | ||
['sw', 'sw'], | ||
['ta', 'ta'], | ||
['te', 'te'], | ||
['tet', 'tet'], | ||
['th', 'th'], | ||
['tlh', 'tlh'], | ||
['tl-ph', 'tl-ph'], | ||
['tr', 'tr'], | ||
['tzl', 'tzl'], | ||
['tzm', 'tzm'], | ||
['tzm-latn', 'tzm-latn'], | ||
['uk', 'uk'], | ||
['uz', 'uz'], | ||
['vi', 'vi'], | ||
['x-pseudo', 'x-pseudo'], | ||
['yo', 'yo'], | ||
['zh-cn', 'zh-cn'], | ||
['zh-hk', 'zh-hk'], | ||
['zh-tw', 'zh-tw'], | ||
]; | ||
} | ||
|
||
private function changeLocale(string $locale): void | ||
{ | ||
$this->request->setLocale($locale); | ||
} | ||
} |