Skip to content
This repository has been archived by the owner on Feb 8, 2025. It is now read-only.

feat: add locale property to users #925

Merged
merged 4 commits into from
May 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions app/Helpers/LocaleHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

namespace App\Helpers;

use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;

class LocaleHelper
{
private const LANG_SPLIT = '/(-|_)/';

/**
* Get the current or default locale.
*
* @return string
*/
public static function getLocale()
{
$locale = Auth::check() ? Auth::user()->locale : null;
if (!$locale) {
$locale = config('app.locale');
}

return $locale;
}

/**
* Get the current lang from locale.
*
* @return string lang, lowercase form.
*/
public static function getLang($locale = null)
{
if (is_null($locale)) {
$locale = App::getLocale();
}
if (preg_match(self::LANG_SPLIT, $locale)) {
$locale = preg_split(self::LANG_SPLIT, $locale, 2)[0];
}

return mb_strtolower($locale);
}

/**
* Get the list of avalaible languages.
*
* @return \Illuminate\Support\Collection
*/
public static function getLocaleList()
{
return collect(config('app.languages'))->map(function ($lang) {
return [
'lang' => $lang,
'name' => self::getLocaleName($lang),
'name-orig' => self::getLocaleName($lang, $lang),
];
});
}

/**
* Get the name of one language.
*
* @param string $lang
* @param string $locale
*
* @return string
*/
private static function getLocaleName($lang, $locale = null): string
{
$name = trans('app.locale_'.$lang, [], $locale);
if ($name === 'app.locale_'.$lang) {
// The name of the new language is not already set, even in english
$name = $lang; // @codeCoverageIgnore
}

return $name;
}

/**
* Get the direction: left to right/right to left.
*
* @return string
*/
public static function getDirection()
{
$lang = self::getLang();
switch ($lang) {
// Source: https://meta.wikimedia.org/wiki/Template:List_of_language_names_ordered_by_code
// @codeCoverageIgnoreStart
case 'ar':
case 'arc':
case 'dv':
case 'fa':
case 'ha':
case 'he':
case 'khw':
case 'ks':
case 'ku':
case 'ps':
case 'ur':
case 'yi':
// @codeCoverageIgnoreEnd
return 'rtl';
default:
return 'ltr';
}
}
}
4 changes: 4 additions & 0 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Kernel extends HttpKernel
'sentry.context',
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
'locale',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\HandleInertiaRequests::class,
],
Expand All @@ -43,6 +44,7 @@ class Kernel extends HttpKernel
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
'sentry.context',
'locale',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
Expand All @@ -60,6 +62,7 @@ class Kernel extends HttpKernel
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'locale' => \App\Http\Middleware\CheckLocale::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'sentry.context' => \App\Http\Middleware\SentryContext::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
Expand All @@ -86,5 +89,6 @@ class Kernel extends HttpKernel
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
\App\Http\Middleware\CheckLocale::class,
];
}
30 changes: 30 additions & 0 deletions app/Http/Middleware/CheckLocale.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace App\Http\Middleware;

use Closure;
use App\Helpers\LocaleHelper;
use Illuminate\Support\Facades\App;

class CheckLocale
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$locale = $request->query('lang');

if (empty($locale)) {
$locale = LocaleHelper::getLocale();
}

App::setLocale($locale);

return $next($request);
}
}
8 changes: 8 additions & 0 deletions config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,12 @@

],

/*
|--------------------------------------------------------------------------
| Available languages
|--------------------------------------------------------------------------
*/

'languages' => ['en', 'fr'],

];
32 changes: 32 additions & 0 deletions database/migrations/2021_05_28_192850_user_locale.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class UserLocale extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('locale', 5)->nullable()->after('password');
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('locale');
});
}
}
42 changes: 27 additions & 15 deletions resources/js/langs.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,26 @@ export default {
loadedLanguages : ['en'], // our default language that is preloaded

_setI18nLanguage (lang) {
this.i18n.locale = lang;
if (this.i18n.mode === 'legacy') {
this.i18n.global.locale = lang;
} else {
this.i18n.global.locale.value = lang;
}
axios.defaults.headers.common['Accept-Language'] = lang;
document.querySelector('html').setAttribute('lang', lang);
},

_loadLanguageAsync (lang) {
if (this.i18n.locale !== lang) {
if (!this.loadedLanguages.includes(lang)) {
return this._loadLanguageMessagesAsync(lang).then(msgs => {
this.i18n.global.setLocaleMessage(lang, msgs);
this.loadedLanguages.push(lang);
return this.i18n;
});
return this._loadLanguageMessagesAsync(lang)
.then(msgs => {
if (msgs !== null) {
this.i18n.global.setLocaleMessage(lang, msgs);
this.loadedLanguages.push(lang);
}
return this.i18n;
});
}
}
return Promise.resolve(this.i18n);
Expand All @@ -38,17 +45,22 @@ export default {
const q = src.indexOf('?');
const query = q > 0 ? src.substring(q) : '';

return axios.get(`js/langs/${lang}.json${query}`).then(msgs => {
return msgs.data;
});
return axios.get(`js/langs/${lang}.json${query}`)
.then(msgs => {
return msgs.data;
})
.catch(error => {
return null;
});
},

loadLanguage (lang, set) {
return this._loadLanguageAsync(lang).then(i18n => {
if (set) {
this._setI18nLanguage(lang);
}
return i18n;
});
return this._loadLanguageAsync(lang)
.then(i18n => {
if (set) {
this._setI18nLanguage(lang);
}
return i18n;
});
}
};
29 changes: 14 additions & 15 deletions resources/js/pluralization.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Pluralization form for every langage not following engl-ish like form.
* Pluralization form for every language not following engl-ish like form.
*
* 'plurals' functions represent possible plural form transformations.
* plurals functions represent possible plural form transformations.
* This return a list of lang/plural function to apply.
*
* @see /~https://github.com/laravel/framework/blob/master/src/Illuminate/Translation/MessageSelector.php
Expand Down Expand Up @@ -37,17 +37,16 @@ function pluralF (choice, choicesLength) {
}

export default {
'ar': pluralE,
'cs': pluralC,
'fr': pluralB,
'he': pluralF,
'hr': pluralD,
'id': pluralA,
'ja': pluralA,
'ru': pluralD,
'tr': pluralA,
'uk': pluralD,
'vi': pluralA,
'zh': pluralA,
'zh-TW': pluralA,
ar: pluralE,
cs: pluralC,
fr: pluralB,
he: pluralF,
hr: pluralD,
id: pluralA,
ja: pluralA,
ru: pluralD,
tr: pluralA,
uk: pluralD,
vi: pluralA,
zh: pluralA,
};
3 changes: 3 additions & 0 deletions resources/lang/en/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,7 @@
'rate_manager_average' => 'It’s going well',
'rate_manager_good' => 'Simply great',
'duration' => ':hours h :minutes',
/* */
'locale_en' => 'English',
'locale_fr' => 'French',
];
Loading