From becebc5347e51dfec0c2f66980a9c841b1b3554b Mon Sep 17 00:00:00 2001 From: Yanhao Li Date: Wed, 30 Oct 2019 15:19:10 -0400 Subject: [PATCH] User now could change his own language on the profile page --- .../add_language_column_to_twill_users.php | 40 +++++ src/Helpers/i18n_helpers.php | 159 ++++++++++++++++++ src/Http/Middleware/Localization.php | 24 +++ src/Models/User.php | 1 + src/Repositories/UserRepository.php | 7 + views/users/form.blade.php | 20 ++- 6 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 migrations/add_language_column_to_twill_users.php create mode 100644 src/Http/Middleware/Localization.php diff --git a/migrations/add_language_column_to_twill_users.php b/migrations/add_language_column_to_twill_users.php new file mode 100644 index 000000000..350f72efd --- /dev/null +++ b/migrations/add_language_column_to_twill_users.php @@ -0,0 +1,40 @@ +string('language')->nullable(); + }); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $twillUsersTable = config('twill.users_table', 'twill_users'); + + if (Schema::hasTable($twillUsersTable) && Schema::hasColumn($twillUsersTable, 'language')) { + Schema::table($twillUsersTable, function (Blueprint $table) { + $table->dropColumn('language'); + }); + } + } +} diff --git a/src/Helpers/i18n_helpers.php b/src/Helpers/i18n_helpers.php index 866b392e5..cec06f66a 100644 --- a/src/Helpers/i18n_helpers.php +++ b/src/Helpers/i18n_helpers.php @@ -236,3 +236,162 @@ function camelCaseToWords($camelCaseString) return ucfirst(strtolower($words)); } } + +if (!function_exists('getLanguageNativeNameFromCode')) { + /** + * @param string $code + * @return string + */ + function getLanguageNativeNameFromCode($code) + { + $codeToLanguageMappings = [ + 'ar' => + [ + 'english_name' => 'Arabic', + 'native_name' => 'العربية', + ], + 'bg' => + [ + 'english_name' => 'Bulgarian', + 'native_name' => 'български език', + ], + 'zh-CN' => + [ + 'english_name' => 'Chinese (Simplified)', + 'native_name' => '简体中文', + ], + 'zh-TW' => + [ + 'english_name' => 'Chinese (Traditional)', + 'native_name' => '繁體中文', + ], + 'cs' => + [ + 'english_name' => 'Czech', + 'native_name' => 'čeština', + ], + 'da' => + [ + 'english_name' => 'Danish', + 'native_name' => 'Dansk', + ], + 'nl' => + [ + 'english_name' => 'Dutch', + 'native_name' => 'Nederlands', + ], + 'en' => + [ + 'english_name' => 'English', + 'native_name' => 'English', + ], + 'fi' => + [ + 'english_name' => 'Finnish', + 'native_name' => 'Suomi', + ], + 'fr' => + [ + 'english_name' => 'French', + 'native_name' => 'Français', + ], + 'de' => + [ + 'english_name' => 'German', + 'native_name' => 'Deutsch', + ], + 'el' => + [ + 'english_name' => 'Greek', + 'native_name' => 'Ελληνικά', + ], + 'hu' => + [ + 'english_name' => 'Hungarian', + 'native_name' => 'Magyar', + ], + 'it' => + [ + 'english_name' => 'Italian', + 'native_name' => 'Italiano', + ], + 'ja' => + [ + 'english_name' => 'Japanese', + 'native_name' => '日本語', + ], + 'ko' => + [ + 'english_name' => 'Korean', + 'native_name' => '한국어', + ], + 'no' => + [ + 'english_name' => 'Norwegian', + 'native_name' => 'Norsk', + ], + 'pl' => + [ + 'english_name' => 'Polish', + 'native_name' => 'Polski', + ], + 'pt' => + [ + 'english_name' => 'Portuguese', + 'native_name' => 'Português', + ], + 'pt-BR' => + [ + 'english_name' => 'Portuguese-Brazil', + 'native_name' => 'Português-Brasil', + ], + 'ro' => + [ + 'english_name' => 'Romanian', + 'native_name' => 'Română', + ], + 'ru' => + [ + 'english_name' => 'Russian', + 'native_name' => 'Русский', + ], + 'es' => + [ + 'english_name' => 'Spanish-Spain', + 'native_name' => 'Español-España', + ], + 'es-419' => + [ + 'english_name' => 'Spanish-Latin America', + 'native_name' => 'Español-Latinoamérica', + ], + 'sv' => + [ + 'english_name' => 'Swedish', + 'native_name' => 'Svenska', + ], + 'th' => + [ + 'english_name' => 'Thai', + 'native_name' => 'ไทย', + ], + 'tr' => + [ + 'english_name' => 'Turkish', + 'native_name' => 'Türkçe', + ], + 'uk' => + [ + 'english_name' => 'Ukrainian', + 'native_name' => 'Українська', + ], + 'vn' => + [ + 'english_name' => 'Vietnamese', + 'native_name' => 'Tiếng Việt', + ], + ]; + + return $codeToLanguageMappings[$code]['native_name'] ?? $code ; + } +} diff --git a/src/Http/Middleware/Localization.php b/src/Http/Middleware/Localization.php new file mode 100644 index 000000000..b75ad5014 --- /dev/null +++ b/src/Http/Middleware/Localization.php @@ -0,0 +1,24 @@ +user()->language) { + app()->setLocale($request->user()->language); + } + + return $next($request); + } +} diff --git a/src/Models/User.php b/src/Models/User.php index ef053b511..42e69bbcb 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -31,6 +31,7 @@ class User extends AuthenticatableContract 'description', 'google_2fa_enabled', 'google_2fa_secret', + 'language' ]; protected $dates = [ diff --git a/src/Repositories/UserRepository.php b/src/Repositories/UserRepository.php index c0a33e199..3ae41524d 100644 --- a/src/Repositories/UserRepository.php +++ b/src/Repositories/UserRepository.php @@ -2,6 +2,7 @@ namespace A17\Twill\Repositories; +use App; use A17\Twill\Models\User; use A17\Twill\Repositories\Behaviors\HandleMedias; use A17\Twill\Repositories\Behaviors\HandleOauth; @@ -133,6 +134,12 @@ public function prepareFieldsBeforeSave($user, $fields) public function afterSave($user, $fields) { $this->sendWelcomeEmail($user); + $language = $fields['language']; + if ($language !== App::getLocale()) { + $user->language = $language; + session()->put('twill_locale', $language); + $user->save(); + } parent::afterSave($user, $fields); } diff --git a/views/users/form.blade.php b/views/users/form.blade.php index 26cbe0e65..460edd511 100644 --- a/views/users/form.blade.php +++ b/views/users/form.blade.php @@ -1,7 +1,7 @@ @extends('twill::layouts.form', [ 'contentFieldsetLabel' => __('twill::lang.user-management.content-fieldset-label'), 'editModalTitle' => __('twill::lang.user-management.edit-modal-title'), - 'reloadOnSuccess' => true + 'reloadOnSuccess' => false ]) @php @@ -44,6 +44,7 @@ 'label' => 'Description' ]) @endif + @if($with2faSettings ?? false) @formField('checkbox', [ 'name' => 'google_2fa_enabled', @@ -76,6 +77,23 @@ @endcomponent @endunless @endif + + @formField('select', [ + 'name' => 'language', + 'label' => 'Language', + 'placeholder' => 'Select a language', + 'default' => App::getLocale(), + 'options' => [ + [ + 'value' => 'en', + 'label' => getLanguageNativeNameFromCode('en') + ], + [ + 'value' => 'ja', + 'label' => getLanguageNativeNameFromCode('ja') + ] + ] + ]) @stop @push('vuexStore')