| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace BookStack\Http\Middleware; | 
					
						
							| 
									
										
										
										
											2017-01-16 00:27:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | use Carbon\Carbon; | 
					
						
							|  |  |  | use Closure; | 
					
						
							| 
									
										
										
										
											2018-08-12 20:10:55 +08:00
										 |  |  | use Illuminate\Http\Request; | 
					
						
							| 
									
										
										
										
											2017-01-16 00:27:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class Localization | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-01-19 20:11:18 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * Array of right-to-left locales. | 
					
						
							| 
									
										
										
										
											2019-01-19 20:11:18 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2022-05-09 21:58:04 +08:00
										 |  |  |     protected $rtlLocales = ['ar', 'fa', 'he']; | 
					
						
							| 
									
										
										
										
											2018-09-22 20:18:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-19 20:11:18 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Map of BookStack locale names to best-estimate system locale names. | 
					
						
							| 
									
										
										
										
											2021-10-25 21:49:03 +08:00
										 |  |  |      * Locales can often be found by running `locale -a` on a linux system. | 
					
						
							| 
									
										
										
										
											2019-01-19 20:11:18 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  |     protected $localeMap = [ | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |         'ar'          => 'ar', | 
					
						
							|  |  |  |         'bg'          => 'bg_BG', | 
					
						
							|  |  |  |         'bs'          => 'bs_BA', | 
					
						
							|  |  |  |         'ca'          => 'ca', | 
					
						
							|  |  |  |         'da'          => 'da_DK', | 
					
						
							|  |  |  |         'de'          => 'de_DE', | 
					
						
							| 
									
										
										
										
											2019-01-19 20:11:18 +08:00
										 |  |  |         'de_informal' => 'de_DE', | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |         'en'          => 'en_GB', | 
					
						
							|  |  |  |         'es'          => 'es_ES', | 
					
						
							|  |  |  |         'es_AR'       => 'es_AR', | 
					
						
							| 
									
										
										
										
											2021-10-25 21:49:03 +08:00
										 |  |  |         'et'          => 'et_EE', | 
					
						
							| 
									
										
										
										
											2022-03-30 20:12:17 +08:00
										 |  |  |         'eu'          => 'eu_ES', | 
					
						
							| 
									
										
										
										
											2022-05-09 21:58:04 +08:00
										 |  |  |         'fa'          => 'fa_IR', | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |         'fr'          => 'fr_FR', | 
					
						
							|  |  |  |         'he'          => 'he_IL', | 
					
						
							|  |  |  |         'hr'          => 'hr_HR', | 
					
						
							|  |  |  |         'id'          => 'id_ID', | 
					
						
							|  |  |  |         'it'          => 'it_IT', | 
					
						
							|  |  |  |         'ja'          => 'ja', | 
					
						
							|  |  |  |         'ko'          => 'ko_KR', | 
					
						
							| 
									
										
										
										
											2021-08-22 03:24:58 +08:00
										 |  |  |         'lt'          => 'lt_LT', | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |         'lv'          => 'lv_LV', | 
					
						
							|  |  |  |         'nl'          => 'nl_NL', | 
					
						
							|  |  |  |         'nb'          => 'nb_NO', | 
					
						
							|  |  |  |         'pl'          => 'pl_PL', | 
					
						
							|  |  |  |         'pt'          => 'pt_PT', | 
					
						
							|  |  |  |         'pt_BR'       => 'pt_BR', | 
					
						
							|  |  |  |         'ru'          => 'ru', | 
					
						
							|  |  |  |         'sk'          => 'sk_SK', | 
					
						
							|  |  |  |         'sl'          => 'sl_SI', | 
					
						
							|  |  |  |         'sv'          => 'sv_SE', | 
					
						
							|  |  |  |         'uk'          => 'uk_UA', | 
					
						
							|  |  |  |         'vi'          => 'vi_VN', | 
					
						
							|  |  |  |         'zh_CN'       => 'zh_CN', | 
					
						
							|  |  |  |         'zh_TW'       => 'zh_TW', | 
					
						
							|  |  |  |         'tr'          => 'tr_TR', | 
					
						
							| 
									
										
										
										
											2019-01-19 20:11:18 +08:00
										 |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-16 00:27:24 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Handle an incoming request. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * @param \Illuminate\Http\Request $request | 
					
						
							|  |  |  |      * @param \Closure                 $next | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2017-01-16 00:27:24 +08:00
										 |  |  |      * @return mixed | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function handle($request, Closure $next) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $defaultLang = config('app.locale'); | 
					
						
							| 
									
										
										
										
											2019-03-08 05:09:23 +08:00
										 |  |  |         config()->set('app.default_locale', $defaultLang); | 
					
						
							| 
									
										
										
										
											2018-08-12 20:10:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-17 21:41:43 +08:00
										 |  |  |         $locale = $this->getUserLocale($request, $defaultLang); | 
					
						
							| 
									
										
										
										
											2019-08-19 01:57:35 +08:00
										 |  |  |         config()->set('app.lang', str_replace('_', '-', $this->getLocaleIso($locale))); | 
					
						
							| 
									
										
										
										
											2019-06-12 03:35:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-22 20:18:26 +08:00
										 |  |  |         // Set text direction
 | 
					
						
							|  |  |  |         if (in_array($locale, $this->rtlLocales)) { | 
					
						
							|  |  |  |             config()->set('app.rtl', true); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-16 00:27:24 +08:00
										 |  |  |         app()->setLocale($locale); | 
					
						
							|  |  |  |         Carbon::setLocale($locale); | 
					
						
							| 
									
										
										
										
											2019-01-19 20:11:18 +08:00
										 |  |  |         $this->setSystemDateLocale($locale); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-16 00:27:24 +08:00
										 |  |  |         return $next($request); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-08-12 20:10:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-17 21:41:43 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the locale specifically for the currently logged in user if available. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function getUserLocale(Request $request, string $default): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             $user = user(); | 
					
						
							|  |  |  |         } catch (\Exception $exception) { | 
					
						
							|  |  |  |             return $default; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($user->isDefault() && config('app.auto_detect_locale')) { | 
					
						
							|  |  |  |             return $this->autoDetectLocale($request, $default); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return setting()->getUser($user, 'language', $default); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-12 20:10:55 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Autodetect the visitors locale by matching locales in their headers | 
					
						
							|  |  |  |      * against the locales supported by BookStack. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-01-17 21:41:43 +08:00
										 |  |  |     protected function autoDetectLocale(Request $request, string $default): string | 
					
						
							| 
									
										
										
										
											2018-08-12 20:10:55 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         $availableLocales = config('app.locales'); | 
					
						
							|  |  |  |         foreach ($request->getLanguages() as $lang) { | 
					
						
							|  |  |  |             if (in_array($lang, $availableLocales)) { | 
					
						
							|  |  |  |                 return $lang; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-12 20:10:55 +08:00
										 |  |  |         return $default; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-19 20:11:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-12 03:35:31 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * Get the ISO version of a BookStack language name. | 
					
						
							| 
									
										
										
										
											2019-06-12 03:35:31 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-01-17 21:41:43 +08:00
										 |  |  |     public function getLocaleIso(string $locale): string | 
					
						
							| 
									
										
										
										
											2019-06-12 03:35:31 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         return $this->localeMap[$locale] ?? $locale; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-19 20:11:18 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Set the system date locale for localized date formatting. | 
					
						
							|  |  |  |      * Will try both the standard locale name and the UTF8 variant. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function setSystemDateLocale(string $locale) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-06-12 03:35:31 +08:00
										 |  |  |         $systemLocale = $this->getLocaleIso($locale); | 
					
						
							| 
									
										
										
										
											2019-01-19 20:11:18 +08:00
										 |  |  |         $set = setlocale(LC_TIME, $systemLocale); | 
					
						
							|  |  |  |         if ($set === false) { | 
					
						
							|  |  |  |             setlocale(LC_TIME, $systemLocale . '.utf8'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-01-16 00:27:24 +08:00
										 |  |  | } |