1
0
mirror of https://github.com/flarum/core.git synced 2025-08-15 04:44:08 +02:00

Refactor translation and validation

We now use Symfony's Translation component. Yay! We get more powerful pluralisation and better a fallback mechanism. Will want to implement the caching mechanism at some point too. The API is replicated in JavaScript, which could definitely use some testing.

Validators have been refactored so that they are decoupled from models completely (i.e. they simply validate arrays of user input). Language packs should include Laravel's validation messages.

ref #267
This commit is contained in:
Toby Zerner
2015-10-15 22:30:45 +10:30
parent a23180f279
commit c08b62af80
32 changed files with 578 additions and 4096 deletions

View File

@@ -10,15 +10,36 @@
namespace Flarum\Locale;
use Symfony\Component\Translation\Translator;
class LocaleManager
{
protected $locales = [];
/**
* @var Translator
*/
protected $translator;
protected $translations = [];
protected $locales = [];
protected $js = [];
protected $config = [];
/**
* @param Translator $translator
*/
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function getLocale()
{
return $this->translator->getLocale();
}
public function setLocale($locale)
{
$this->translator->setLocale($locale);
}
public function addLocale($locale, $name)
{
@@ -35,9 +56,9 @@ class LocaleManager
return isset($this->locales[$locale]);
}
public function addTranslations($locale, $translations)
public function addTranslations($locale, $file)
{
$this->translations[$locale][] = $translations;
$this->translator->addResource('yaml', $file, $locale);
}
public function addJsFile($locale, $js)
@@ -45,26 +66,6 @@ class LocaleManager
$this->js[$locale][] = $js;
}
public function addConfig($locale, $config)
{
$this->config[$locale][] = $config;
}
public function getTranslations($locale)
{
$files = array_get($this->translations, $locale, []);
$parts = explode('-', $locale);
if (count($parts) > 1) {
$files = array_merge(array_get($this->translations, $parts[0], []), $files);
}
$compiler = new TranslationCompiler($locale, $files);
return $compiler->getTranslations();
}
public function getJsFiles($locale)
{
$files = array_get($this->js, $locale, []);
@@ -78,18 +79,19 @@ class LocaleManager
return $files;
}
public function getConfig($locale)
/**
* @return Translator
*/
public function getTranslator()
{
if (empty($this->config[$locale])) {
return [];
}
return $this->translator;
}
$config = [];
foreach ($this->config[$locale] as $file) {
$config = array_merge($config, include $file);
}
return $config;
/**
* @param Translator $translator
*/
public function setTranslator($translator)
{
$this->translator = $translator;
}
}

View File

@@ -13,6 +13,8 @@ namespace Flarum\Locale;
use Flarum\Event\ConfigureLocales;
use Flarum\Foundation\AbstractServiceProvider;
use Illuminate\Contracts\Events\Dispatcher;
use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\Translator;
class LocaleServiceProvider extends AbstractServiceProvider
{
@@ -21,9 +23,9 @@ class LocaleServiceProvider extends AbstractServiceProvider
*/
public function boot(Dispatcher $events)
{
$manager = $this->app->make('flarum.localeManager');
$locales = $this->app->make('flarum.localeManager');
$events->fire(new ConfigureLocales($manager));
$events->fire(new ConfigureLocales($locales));
}
/**
@@ -32,11 +34,18 @@ class LocaleServiceProvider extends AbstractServiceProvider
public function register()
{
$this->app->singleton('Flarum\Locale\LocaleManager');
$this->app->alias('Flarum\Locale\LocaleManager', 'flarum.localeManager');
$this->app->instance('translator', new Translator);
$this->app->singleton('translator', function () {
$defaultLocale = $this->app->make('flarum.settings')->get('default_locale');
$translator = new Translator($defaultLocale, new MessageSelector());
$translator->setFallbackLocales([$defaultLocale]);
$translator->addLoader('yaml', new YamlFileLoader());
return $translator;
});
$this->app->alias('translator', 'Symfony\Component\Translation\Translator');
$this->app->alias('translator', 'Symfony\Component\Translation\TranslatorInterface');
}
}

View File

@@ -1,47 +0,0 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Locale;
use Symfony\Component\Yaml\Yaml;
class TranslationCompiler
{
protected $locale;
protected $filenames;
public function __construct($locale, array $filenames)
{
$this->locale = $locale;
$this->filenames = $filenames;
}
public function getTranslations()
{
// @todo caching
$translations = [];
foreach ($this->filenames as $filename) {
$translations = array_replace_recursive($translations, Yaml::parse(file_get_contents($filename)));
}
// Temporary solution to resolve references.
// TODO: Make it do more than one level deep, unit test.
array_walk_recursive($translations, function (&$value, $key) use ($translations) {
if (preg_match('/^=>\s*([a-z0-9_\.]+)$/i', $value, $matches)) {
$value = array_get($translations, $matches[1]);
}
});
return $translations;
}
}

View File

@@ -1,79 +0,0 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Locale;
use Symfony\Component\Translation\TranslatorInterface;
class Translator implements TranslatorInterface
{
protected $translations = [];
protected $plural;
public function setTranslations(array $translations)
{
$this->translations = $translations;
}
public function setPlural(callable $plural)
{
$this->plural = $plural;
}
protected function plural($count)
{
if ($this->plural) {
$plural = $this->plural;
return $plural($count);
}
}
public function getLocale()
{
//
}
public function setLocale($locale)
{
//
}
public function trans($id, array $parameters = [], $domain = null, $locale = null)
{
$translation = array_get($this->translations, $id);
if (is_array($translation) && isset($parameters['count'])) {
$plural = $this->plural($parameters['count']);
if ($plural) {
$translation = $translation[$plural];
}
}
if (is_string($translation)) {
foreach ($parameters as $k => $v) {
$translation = str_replace('{'.$k.'}', $v, $translation);
}
return $translation;
}
return $id;
}
public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null)
{
$parameters['count'] = $number;
return $this->trans($id, $parameters, $domain, $locale);
}
}

View File

@@ -0,0 +1,42 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Locale;
use Symfony\Component\Translation\Loader\YamlFileLoader as BaseYamlFileLoader;
use Symfony\Component\Translation\MessageCatalogueInterface;
class YamlFileLoader extends BaseYamlFileLoader
{
/**
* {@inheritdoc}
*/
public function load($resource, $locale, $domain = 'messages')
{
$messages = parent::load($resource, $locale, $domain);
foreach ($messages->all($domain) as $id => $translation) {
$messages->set($id, $this->getTranslation($messages, $id, $domain));
}
return $messages;
}
private function getTranslation(MessageCatalogueInterface $messages, $id, $domain)
{
$translation = $messages->get($id, $domain);
if (preg_match('/^=>\s*([a-z0-9_\.]+)$/i', $translation, $matches)) {
return $this->getTranslation($messages, $matches[1], $domain);
}
return $translation;
}
}