Load front end i18n of plugin automatically

This commit is contained in:
Pig Fang 2019-09-07 23:20:16 +08:00
parent 2b0eb3101c
commit 5718567bea
10 changed files with 124 additions and 2 deletions

View File

@ -0,0 +1,46 @@
<?php
namespace App\Listeners;
use App\Services\Plugin;
use App\Services\PluginManager;
use Illuminate\Filesystem\Filesystem;
class GeneratePluginTranslations
{
/** @var Filesystem */
protected $filesystem;
/** @var PluginManager */
protected $plugins;
public function __construct(Filesystem $filesystem, PluginManager $plugins)
{
$this->filesystem = $filesystem;
$this->plugins = $plugins;
}
public function handle()
{
$plugins = $this->plugins->getEnabledPlugins();
$locales = array_keys(config('locales'));
array_walk($locales, function ($locale) use ($plugins) {
$i18n = $plugins
->filter(function (Plugin $plugin) use ($locale) {
return $this->filesystem->exists(
$plugin->getPath()."/lang/$locale/front-end.yml"
);
})
->map(function (Plugin $plugin) use ($locale) {
return trans($plugin->namespace.'::front-end');
});
if ($i18n->isNotEmpty()) {
$content = 'Object.assign(blessing.i18n, '.
$i18n->toJson(JSON_UNESCAPED_UNICODE).')';
$this->filesystem->put(public_path("lang/${locale}_plugin.js"), $content);
}
});
}
}

View File

@ -23,9 +23,11 @@ class EventServiceProvider extends ServiceProvider
],
'App\Events\PluginWasEnabled' => [
'App\Listeners\CopyPluginAssets',
'App\Listeners\GeneratePluginTranslations',
],
'App\Events\PluginVersionChanged' => [
'App\Listeners\CopyPluginAssets',
'App\Listeners\GeneratePluginTranslations',
],
'App\Events\PluginBootFailed' => [
'App\Listeners\NotifyFailedPlugin',

View File

@ -38,4 +38,14 @@ class JavaScript
return url("lang/$locale.js?t=$compiledModified");
}
public function plugin(string $locale): string
{
$path = public_path("lang/${locale}_plugin.js");
if ($this->filesystem->exists($path)) {
return url("lang/${locale}_plugin.js?t=".$this->filesystem->lastModified($path));
}
return '';
}
}

View File

@ -13,7 +13,7 @@ class Loader extends TranslationLoaderManager
$full = "{$path}/{$locale}/{$group}.yml";
return count($translations) === 0 && $this->files->exists($full)
? resolve(Yaml::class)->loadYaml($full)
? resolve(Yaml::class)->parse($full)
: [];
}
}

View File

@ -15,7 +15,7 @@ class Yaml
$this->cache = $cache;
}
public function loadYaml(string $path): array
public function parse(string $path): array
{
$key = 'yaml-trans-'.md5($path).'-'.filemtime($path);

View File

@ -15,6 +15,7 @@
- Refactor account system.
- PHP version requirement is increased to 7.2.0.
- Use `install.lock` file to detect status of installation.
- Load front end i18n text from `lang/front-end.yml` of a plugin automatically.
## Fixed

View File

@ -15,6 +15,7 @@
- 重构用户系统
- PHP 版本最低要求为 7.2.0
- 使用 `install.lock` 文件来检测安装状态
- 插件系统:自动从 `lang/front-end.yml` 中加载前端多语言
## 修复

View File

@ -1,5 +1,6 @@
@inject('intl', 'App\Services\Translations\JavaScript')
<script src="{{ $intl->generate(app()->getLocale()) }}"></script>
<script src="{{ $intl->plugin(app()->getLocale()) }}"></script>
<script src="{{ webpack_assets('index.js') }}"></script>
<script>{!! option('custom_js') !!}</script>
{{-- Content added by plugins dynamically --}}

View File

@ -0,0 +1,40 @@
<?php
namespace Tests;
use App\Services\Plugin;
use App\Services\PluginManager;
use App\Events\PluginWasEnabled;
use Illuminate\Filesystem\Filesystem;
class GeneratePluginTranslationsTest extends TestCase
{
public function testHandle()
{
config(['locales' => ['en' => [], 'jp' => []]]);
$this->mock(PluginManager::class, function ($mock) {
$mock->shouldReceive('getEnabledPlugins')
->with()
->once()
->andReturn(collect([new Plugin('/reina', ['namespace' => 'れいな'])]));
});
$this->mock(Filesystem::class, function ($mock) {
$mock->shouldReceive('exists')
->with('/reina/lang/en/front-end.yml')
->once()
->andReturn(false);
$mock->shouldReceive('exists')
->with('/reina/lang/jp/front-end.yml')
->once()
->andReturn(true);
$mock->shouldReceive('put')
->with(
public_path('lang/jp_plugin.js'),
'Object.assign(blessing.i18n, ["れいな::front-end"])'
)
->once();
});
$this->app->call('App\Listeners\GeneratePluginTranslations@handle');
}
}

View File

@ -65,4 +65,25 @@ class JavaScriptTest extends TestCase
$this->assertEquals(url('lang/en.js?t=1'), resolve(JavaScript::class)->generate('en'));
}
public function testPlugin()
{
$this->mock(Filesystem::class, function ($mock) {
$mock->shouldReceive('exists')
->with(public_path('lang/en_plugin.js'))
->twice()
->andReturn(false, true);
$mock->shouldReceive('lastModified')
->with(public_path('lang/en_plugin.js'))
->once()
->andReturn(1);
});
$this->assertEquals('', resolve(JavaScript::class)->plugin('en'));
$this->assertEquals(
url('lang/en_plugin.js?t=1'),
resolve(JavaScript::class)->plugin('en')
);
}
}