From ce43f9a586407e2bacccae823854b54c86a8bc18 Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Tue, 23 Jun 2020 18:17:16 +0800 Subject: [PATCH] fix loading i18n of plugins --- app/Http/View/Composers/FootComposer.php | 5 -- app/Listeners/GeneratePluginTranslations.php | 46 ------------- app/Providers/EventServiceProvider.php | 2 - app/Services/Translations/JavaScript.php | 52 +++++++++----- .../ComposersTest/FootComposerTest.php | 9 +-- .../GeneratePluginTranslationsTest.php | 39 ----------- .../TranslationsTest/JavaScriptTest.php | 68 ++++++++++++------- 7 files changed, 77 insertions(+), 144 deletions(-) delete mode 100644 app/Listeners/GeneratePluginTranslations.php delete mode 100644 tests/ListenersTest/GeneratePluginTranslationsTest.php diff --git a/app/Http/View/Composers/FootComposer.php b/app/Http/View/Composers/FootComposer.php index 3c54697b..28f21dc4 100644 --- a/app/Http/View/Composers/FootComposer.php +++ b/app/Http/View/Composers/FootComposer.php @@ -55,11 +55,6 @@ class FootComposer $scripts[] = [ 'src' => $this->javascript->generate($locale), ]; - if ($pluginI18n = $this->javascript->plugin($locale)) { - $scripts[] = [ - 'src' => $pluginI18n, - ]; - } if (Str::startsWith(config('app.asset.env'), 'dev')) { $scripts[] = [ 'src' => $this->webpack->url('style.js'), diff --git a/app/Listeners/GeneratePluginTranslations.php b/app/Listeners/GeneratePluginTranslations.php deleted file mode 100644 index a0a714f9..00000000 --- a/app/Listeners/GeneratePluginTranslations.php +++ /dev/null @@ -1,46 +0,0 @@ -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); - } - }); - } -} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 81f6ecc9..247401ee 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -11,11 +11,9 @@ class EventServiceProvider extends ServiceProvider protected $listen = [ 'App\Events\PluginWasEnabled' => [ Listeners\CopyPluginAssets::class, - Listeners\GeneratePluginTranslations::class, ], 'plugin.versionChanged' => [ Listeners\CopyPluginAssets::class, - Listeners\GeneratePluginTranslations::class, ], 'App\Events\PluginBootFailed' => [ Listeners\NotifyFailedPlugin::class, diff --git a/app/Services/Translations/JavaScript.php b/app/Services/Translations/JavaScript.php index 66868ad0..01ecd92d 100644 --- a/app/Services/Translations/JavaScript.php +++ b/app/Services/Translations/JavaScript.php @@ -2,6 +2,8 @@ namespace App\Services\Translations; +use App\Services\Plugin; +use App\Services\PluginManager; use Illuminate\Cache\Repository; use Illuminate\Filesystem\Filesystem; @@ -13,23 +15,49 @@ class JavaScript /** @var Repository */ protected $cache; + /** @var PluginManager */ + protected $plugins; + protected $prefix = 'front-end-trans-'; - public function __construct(Filesystem $filesystem, Repository $cache) - { + public function __construct( + Filesystem $filesystem, + Repository $cache, + PluginManager $plugins + ) { $this->filesystem = $filesystem; $this->cache = $cache; + $this->plugins = $plugins; } public function generate(string $locale): string { - $source = resource_path("lang/$locale/front-end.yml"); + $plugins = $this->plugins->getEnabledPlugins(); + $sourceFiles = $plugins + ->map(function (Plugin $plugin) use ($locale) { + return $plugin->getPath()."/lang/$locale/front-end.yml"; + }) + ->filter(function ($path) { + return $this->filesystem->exists($path); + }); + $sourceFiles->push(resource_path("lang/$locale/front-end.yml")); + $sourceModified = $sourceFiles->max(function ($path) { + return $this->filesystem->lastModified($path); + }); + $compiled = public_path("lang/$locale.js"); - $sourceModified = $this->filesystem->lastModified($source); - $compiledModified = intval($this->cache->get($this->prefix.$locale, 0)); + $compiledModified = (int) $this->cache->get($this->prefix.$locale, 0); if ($sourceModified > $compiledModified || !$this->filesystem->exists($compiled)) { - $content = 'blessing.i18n = '.json_encode(trans('front-end'), JSON_UNESCAPED_UNICODE); + $translations = trans('front-end'); + foreach ($plugins as $plugin) { + $translations = array_merge( + $translations, + [$plugin->name => trans($plugin->namespace.'::front-end')] + ); + } + + $content = 'blessing.i18n = '.json_encode($translations, JSON_UNESCAPED_UNICODE); $this->filesystem->put($compiled, $content); $this->cache->put($this->prefix.$locale, $sourceModified); @@ -43,16 +71,4 @@ class JavaScript { $this->cache->put($this->prefix.$locale, 0); } - - public function plugin(string $locale): string - { - $path = public_path("lang/${locale}_plugin.js"); - if ($this->filesystem->exists($path)) { - $lastModified = $this->filesystem->lastModified($path); - - return url()->asset("lang/${locale}_plugin.js?t=$lastModified"); - } - - return ''; - } } diff --git a/tests/HttpTest/ViewTest/ComposersTest/FootComposerTest.php b/tests/HttpTest/ViewTest/ComposersTest/FootComposerTest.php index f95cd26d..43ae93e2 100644 --- a/tests/HttpTest/ViewTest/ComposersTest/FootComposerTest.php +++ b/tests/HttpTest/ViewTest/ComposersTest/FootComposerTest.php @@ -30,10 +30,6 @@ class FootComposerTest extends TestCase ->with('en') ->once() ->andReturn('en.js'); - $mock->shouldReceive('plugin') - ->with('en') - ->once() - ->andReturn('en_plugin.js'); }); $this->mock(Webpack::class, function ($mock) { $mock->shouldReceive('url')->with('style.css'); @@ -48,10 +44,7 @@ class FootComposerTest extends TestCase ->andReturn('app.js'); }); - $this->get('/user') - ->assertSee('en.js') - ->assertSee('en_plugin.js') - ->assertSee('app.js'); + $this->get('/user')->assertSee('en.js')->assertSee('app.js'); } public function testAddExtra() diff --git a/tests/ListenersTest/GeneratePluginTranslationsTest.php b/tests/ListenersTest/GeneratePluginTranslationsTest.php deleted file mode 100644 index 3a7b4b67..00000000 --- a/tests/ListenersTest/GeneratePluginTranslationsTest.php +++ /dev/null @@ -1,39 +0,0 @@ - ['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'); - } -} diff --git a/tests/ServicesTest/TranslationsTest/JavaScriptTest.php b/tests/ServicesTest/TranslationsTest/JavaScriptTest.php index c2eb791e..aa563504 100644 --- a/tests/ServicesTest/TranslationsTest/JavaScriptTest.php +++ b/tests/ServicesTest/TranslationsTest/JavaScriptTest.php @@ -2,6 +2,8 @@ namespace Tests; +use App\Services\Plugin; +use App\Services\PluginManager; use App\Services\Translations\JavaScript; use Illuminate\Cache\Repository; use Illuminate\Filesystem\Filesystem; @@ -12,20 +14,35 @@ class JavaScriptTest extends TestCase protected function setUp(): void { parent::setUp(); - $this->app->forgetInstance(JavaScript::class); + app()->forgetInstance(JavaScript::class); } public function testGenerateFreshFile() { + $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(true); $mock->shouldReceive('lastModified') ->with(resource_path('lang/en/front-end.yml')) ->once() ->andReturn(1); + $mock->shouldReceive('lastModified') + ->with('/reina/lang/en/front-end.yml') + ->once() + ->andReturn(2); $mock->shouldReceive('put') ->withArgs(function ($path, $content) { $this->assertEquals(public_path('lang/en.js'), $path); $this->assertTrue(Str::startsWith($content, 'blessing.i18n')); + $this->assertStringContainsString('"れいな::front-end"', $content); return true; }) @@ -38,20 +55,37 @@ class JavaScriptTest extends TestCase ->once() ->andReturn(0); $mock->shouldReceive('put') - ->with('front-end-trans-en', 1) + ->with('front-end-trans-en', 2) ->once(); }); - $this->assertEquals(url('lang/en.js?t=1'), resolve(JavaScript::class)->generate('en')); + $this->assertEquals( + url('lang/en.js?t=2'), + resolve(JavaScript::class)->generate('en') + ); } public function testGenerateCached() { + $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(true); $mock->shouldReceive('lastModified') ->with(resource_path('lang/en/front-end.yml')) ->once() ->andReturn(1); + $mock->shouldReceive('lastModified') + ->with('/reina/lang/en/front-end.yml') + ->once() + ->andReturn(2); $mock->shouldReceive('exists') ->with(public_path('lang/en.js')) ->once() @@ -61,10 +95,13 @@ class JavaScriptTest extends TestCase $mock->shouldReceive('get') ->with('front-end-trans-en', 0) ->once() - ->andReturn(1); + ->andReturn(2); }); - $this->assertEquals(url('lang/en.js?t=1'), resolve(JavaScript::class)->generate('en')); + $this->assertEquals( + url('lang/en.js?t=2'), + resolve(JavaScript::class)->generate('en') + ); } public function testResetTime() @@ -78,27 +115,6 @@ class JavaScriptTest extends TestCase resolve(JavaScript::class)->resetTime('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') - ); - } - public function testFallbackLocale() { $this->get('/', ['Accept-Language' => 'xyz'])