Преглед изворни кода

Add language detection when the user is not logged in (#3022)

Before, when the user was not logged in, pages where translated with the '_' user language.
Now, they are translated with the user preferred language if there is one supported by FreshRSS or with the system default language.
Alexis Degrugillier пре 5 година
родитељ
комит
36bda2e715
5 измењених фајлова са 50 додато и 5 уклоњено
  1. 5 0
      app/Controllers/authController.php
  2. 7 4
      app/FreshRSS.php
  3. 10 0
      app/views/auth/register.phtml
  4. 1 1
      lib/Minz/Request.php
  5. 27 0
      lib/Minz/Translate.php

+ 5 - 0
app/Controllers/authController.php

@@ -148,6 +148,8 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
 					FreshRSS_FormAuth::deleteCookie();
 				}
 
+				Minz_Translate::init($conf->language);
+
 				// All is good, go back to the index.
 				Minz_Request::good(_t('feedback.auth.login.success'),
 				                   array('c' => 'index', 'a' => 'index'));
@@ -191,6 +193,8 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
 				Minz_Session::_param('csrf');
 				FreshRSS_Auth::giveAccess();
 
+				Minz_Translate::init($conf->language);
+
 				Minz_Request::good(_t('feedback.auth.login.success'),
 				                   array('c' => 'index', 'a' => 'index'));
 			} else {
@@ -231,6 +235,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
 
 		$this->view->show_tos_checkbox = file_exists(join_path(DATA_PATH, 'tos.html'));
 		$this->view->show_email_field = FreshRSS_Context::$system_conf->force_email_validation;
+		$this->view->preferred_language = Minz_Translate::getLanguage(null, Minz_Request::getPreferredLanguages(), FreshRSS_Context::$system_conf->language);
 		Minz_View::prependTitle(_t('gen.auth.registration.title') . ' · ');
 	}
 }

+ 7 - 4
app/FreshRSS.php

@@ -68,7 +68,7 @@ class FreshRSS extends Minz_FrontController {
 				// Basic protection against XSRF attacks
 				FreshRSS_Auth::removeAccess();
 				$http_referer = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'];
-				Minz_Translate::init('en');	//TODO: Better choice of fallback language
+				self::initI18n();
 				Minz_Error::error(403, array('error' => array(
 						_t('feedback.access.denied'),
 						' [HTTP_REFERER=' . htmlspecialchars($http_referer, ENT_NOQUOTES, 'UTF-8') . ']'
@@ -80,7 +80,7 @@ class FreshRSS extends Minz_FrontController {
 					!FreshRSS_Auth::hasAccess('admin'))
 				)) {
 				// Token-based protection against XSRF attacks, except for the login or self-create user forms
-				Minz_Translate::init('en');	//TODO: Better choice of fallback language
+				self::initI18n();
 				Minz_Error::error(403, array('error' => array(
 						_t('feedback.access.denied'),
 						' [CSRF]'
@@ -90,8 +90,11 @@ class FreshRSS extends Minz_FrontController {
 	}
 
 	private static function initI18n() {
-		Minz_Session::_param('language', FreshRSS_Context::$user_conf->language);
-		Minz_Translate::init(FreshRSS_Context::$user_conf->language);
+		$selected_language = FreshRSS_Auth::hasAccess() ? FreshRSS_Context::$user_conf->language : null;
+		$language = Minz_Translate::getLanguage($selected_language, Minz_Request::getPreferredLanguages(), FreshRSS_Context::$system_conf->language);
+
+		Minz_Session::_param('language', $language);
+		Minz_Translate::init($language);
 	}
 
 	public static function loadStylesAndScripts() {

+ 10 - 0
app/views/auth/register.phtml

@@ -4,6 +4,16 @@
 	<form method="post" action="<?= _url('user', 'create') ?>">
 		<input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" />
 
+		<div class="form-group">
+			<label for="new_user_language"><?= _t('admin.user.language') ?></label>
+			<select name="new_user_language" id="new_user_language">
+			<?php $languages = Minz_Translate::availableLanguages(); ?>
+			<?php foreach ($languages as $lang) { ?>
+			<option value="<?= $lang ?>"<?= $this->preferred_language === $lang ? ' selected="selected"' : '' ?>><?= _t('gen.lang.' . $lang) ?></option>
+			<?php } ?>
+			</select>
+		</div>
+
 		<div class="form-group">
 			<label for="new_user_name"><?= _t('gen.auth.username') ?></label>
 			<input id="new_user_name" name="new_user_name" type="text" size="16" required="required" autocomplete="off" pattern="<?= FreshRSS_user_Controller::USERNAME_PATTERN ?>" autocapitalize="off" />

+ 1 - 1
lib/Minz/Request.php

@@ -395,7 +395,7 @@ class Minz_Request {
 	/**
 	 * @return array
 	 */
-	public static function getPreferredLanguage() {
+	public static function getPreferredLanguages() {
 		if (preg_match_all('/(^|,)\s*(?P<lang>[^;,]+)/', static::getHeader('HTTP_ACCEPT_LANGUAGE'), $matches)) {
 			return $matches['lang'];
 		}

+ 27 - 0
lib/Minz/Translate.php

@@ -63,6 +63,8 @@ class Minz_Translate {
 	public static function availableLanguages() {
 		$list_langs = array();
 
+		self::registerPath(APP_PATH . '/i18n');
+
 		foreach (self::$path_list as $path) {
 			$scan = scandir($path);
 			if (is_array($scan)) {
@@ -79,6 +81,31 @@ class Minz_Translate {
 		return array_unique($list_langs);
 	}
 
+	/**
+	 * Return the language to use in the application.
+	 * It returns the connected language if it exists then returns the first match from the
+	 * preferred languages then returns the default language
+	 * @param $user the connected user language (nullable)
+	 * @param $preferred an array of the preferred languages
+	 * @param $default the preferred language to use
+	 * @return a string containing the language to use
+	 */
+	public static function getLanguage($user, $preferred, $default) {
+		if (null !== $user) {
+			return $user;
+		}
+
+		$languages = Minz_Translate::availableLanguages();
+		foreach ($preferred as $language) {
+			$language = strtolower($language);
+			if (in_array($language, $languages, true)) {
+				return $language;
+			}
+		}
+
+		return $default;
+	}
+
 	/**
 	 * Register a new path.
 	 * @param $path a path containing i18n directories (e.g. ./en/, ./fr/).