From 675fb36dc8976d19ed524cf2a69ce0b11aaf78e0 Mon Sep 17 00:00:00 2001 From: kroutony Date: Sat, 22 Feb 2020 15:18:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E5=88=87=E6=8F=9B=E8=AA=9E?= =?UTF-8?q?=E7=B3=BB=E7=9A=84=E6=A9=9F=E5=88=B6=EF=BC=8C=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E7=B4=80=E9=8C=84=E7=B6=B2=E7=AB=99=E7=8B=80=E6=85=8B=E7=9A=84?= =?UTF-8?q?=E5=85=A8=E5=9F=9F=E7=89=A9=E4=BB=B6=E5=8F=8A=E7=9B=B8=E9=97=9C?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E6=A9=9F=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Kernel.php | 4 + app/Http/Middleware/SetAppLanguage.php | 106 ++++++++++++++++++ app/Http/Middleware/SetSiteStates.php | 52 +++++++++ app/Presenters/UrlPresenter.php | 21 ++++ app/Providers/SingletonServiceProvider.php | 39 +++++++ app/Services/SiteStateService.php | 64 +++++++++++ config/app.php | 2 +- config/languages.php | 8 ++ resources/js/admin/app.js | 1 + resources/js/app-common.js | 4 + resources/js/app.js | 3 +- resources/js/{bootstrap.js => lib.js} | 0 resources/views/admin/layouts/app.blade.php | 1 + .../components/languageDropdown.blade.php | 9 ++ resources/views/components/nav.blade.php | 22 +--- 15 files changed, 318 insertions(+), 18 deletions(-) create mode 100644 app/Http/Middleware/SetAppLanguage.php create mode 100644 app/Http/Middleware/SetSiteStates.php create mode 100644 app/Presenters/UrlPresenter.php create mode 100644 app/Providers/SingletonServiceProvider.php create mode 100644 app/Services/SiteStateService.php create mode 100644 config/languages.php create mode 100644 resources/js/app-common.js rename resources/js/{bootstrap.js => lib.js} (100%) create mode 100644 resources/views/components/languageDropdown.blade.php diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index c4500c7..93b3880 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -35,11 +35,14 @@ class Kernel extends HttpKernel \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, + \App\Http\Middleware\SetAppLanguage::class, + \App\Http\Middleware\SetSiteStates::class, ], 'api' => [ 'throttle:60,1', \Illuminate\Routing\Middleware\SubstituteBindings::class, + \App\Http\Middleware\SetSiteStates::class, ], ]; @@ -79,5 +82,6 @@ class Kernel extends HttpKernel \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Auth\Middleware\Authorize::class, + \App\Http\Middleware\SetAppLanguage::class, ]; } diff --git a/app/Http/Middleware/SetAppLanguage.php b/app/Http/Middleware/SetAppLanguage.php new file mode 100644 index 0000000..cea78f4 --- /dev/null +++ b/app/Http/Middleware/SetAppLanguage.php @@ -0,0 +1,106 @@ +get($this->localeRequestKey) !== null) { + //取得傳入的Locale值 + $requestLocale = $request->get($this->localeRequestKey); + //如果有在語言清單內 + if(array_key_exists($requestLocale, $availableLocales)) { + //設定session + $request->session()->put($this->cookieAndSessionKey, $requestLocale); + //設定要被回傳的Cookie及目標Locale + $setLocale = $setLocaleCookie = $requestLocale; + } + } + //假如沒有目標Locale,再讀取Session、Cookie、瀏覽器的Locale + if(!$setLocale) { + $cookieLocale = $request->cookies->get($this->cookieAndSessionKey); + $sessionLocale = $request->session()->get($this->cookieAndSessionKey); + if(array_key_exists($sessionLocale, $availableLocales)) { + //設定要被回傳的Cookie及目標Locale + $setLocale = $sessionLocale; + if(!$cookieLocale) { + $setLocaleCookie = $sessionLocale; + } + } elseif(array_key_exists($cookieLocale, $availableLocales)) { + //設定Session及目標Locale + $request->session()->put($this->cookieAndSessionKey, $cookieLocale); + $setLocale = $cookieLocale; + } else { + //Session及Cookie都沒有Locale值時,讀取HTTP Header的資訊 + $browserLocales = $request->server('HTTP_ACCEPT_LANGUAGE'); + $browserLocales = preg_replace('/;q=0\.\d+/', '', $browserLocales); + $browserLocales = explode(',', $browserLocales); + $browserLocales = array_map(function($lang){ + return strtolower($lang); + }, $browserLocales); + + //與語言清單比對 + $validBrowserLocales = array_intersect($browserLocales, array_keys($availableLocales)); + + if(!empty($validBrowserLocales)) { + //取得第一個瀏覽器Locale + $validBrowserLocale = head($validBrowserLocales); + //設定Session及目標Locale + $request->session()->put($this->cookieAndSessionKey, $validBrowserLocale); + $setLocale = $setLocaleCookie = $validBrowserLocale; + } + } + } + + if($setLocale) { + //如果有目標Locale + app()->setLocale($setLocale); + } else { + //如果沒有目標Locale,則設定成預設語言 + app()->setLocale(config('app.fallback_locale')); + } + + //如果有Cookie,則帶入request + if($setLocaleCookie) { + return $next($request)->withCookie(cookie()->forever($this->cookieAndSessionKey, $setLocaleCookie)); + } else { + return $next($request); + } + } +} diff --git a/app/Http/Middleware/SetSiteStates.php b/app/Http/Middleware/SetSiteStates.php new file mode 100644 index 0000000..2432bbb --- /dev/null +++ b/app/Http/Middleware/SetSiteStates.php @@ -0,0 +1,52 @@ +is(config('admin.route') . '/*')) { + $siteState->isAdminArea = true; + } + + //所有可用語系及其原文名稱 + $siteState->languagesWithLabel = config('languages'); + + //所有可用語系 + $siteState->languages = array_keys($siteState->languagesWithLabel); + + //所有其他可用語系,排除現在語系 + $siteState->otherLanguages = collect($siteState->languages)->filter(function($locale){ + return $locale !== app()->getLocale(); + })->all(); + + //所有語系的當前語言翻譯 + foreach ($siteState->languages as $locale) { + $siteState->languageTranslations[$locale] = trans('languages.' . $locale); + } + + //預設語系 + $siteState->defaultLanguage = config('app.fallback_locale'); + + return $next($request); + } +} diff --git a/app/Presenters/UrlPresenter.php b/app/Presenters/UrlPresenter.php new file mode 100644 index 0000000..b870fb3 --- /dev/null +++ b/app/Presenters/UrlPresenter.php @@ -0,0 +1,21 @@ +request = $request; + } + + public function appendLocale($locale) + { + $url = $this->request->fullUrlWithQuery(['locale' => $locale]); + return $url; + } +} diff --git a/app/Providers/SingletonServiceProvider.php b/app/Providers/SingletonServiceProvider.php new file mode 100644 index 0000000..d842e2a --- /dev/null +++ b/app/Providers/SingletonServiceProvider.php @@ -0,0 +1,39 @@ +app->alias(\App\Services\SiteStateService::class, 'SiteState'); + $this->app->singleton(\App\Services\SiteStateService::class, function($app){ + return new \App\Services\SiteStateService; + }); + } + + /** + * Bootstrap services. + * + * @return void + */ + public function boot() + { + // + } +} diff --git a/app/Services/SiteStateService.php b/app/Services/SiteStateService.php new file mode 100644 index 0000000..e53b256 --- /dev/null +++ b/app/Services/SiteStateService.php @@ -0,0 +1,64 @@ + 'English', + 'zh-tw' => '繁體中文', + 'zh-cn' => '简体中文', + 'ja' => '日本語', + 'ko' => '한국어' +]; diff --git a/resources/js/admin/app.js b/resources/js/admin/app.js index cf327e4..9d01962 100644 --- a/resources/js/admin/app.js +++ b/resources/js/admin/app.js @@ -1 +1,2 @@ import './lib'; +import '../app-common' diff --git a/resources/js/app-common.js b/resources/js/app-common.js new file mode 100644 index 0000000..a877e83 --- /dev/null +++ b/resources/js/app-common.js @@ -0,0 +1,4 @@ +$('.logout-btn').on('click', e => { + e.preventDefault() + $('#logout-form').submit() +}) diff --git a/resources/js/app.js b/resources/js/app.js index 40c55f6..3103dba 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1 +1,2 @@ -require('./bootstrap'); +import './lib' +import './app-common' diff --git a/resources/js/bootstrap.js b/resources/js/lib.js similarity index 100% rename from resources/js/bootstrap.js rename to resources/js/lib.js diff --git a/resources/views/admin/layouts/app.blade.php b/resources/views/admin/layouts/app.blade.php index 5c54257..02bb58b 100644 --- a/resources/views/admin/layouts/app.blade.php +++ b/resources/views/admin/layouts/app.blade.php @@ -31,6 +31,7 @@