Bläddra i källkod

Merge pull request #504 from Flatta/feature-detectlang

Detect user language (Feature request)
Serghey Rodin 10 år sedan
förälder
incheckning
0d2dc08d74

+ 1 - 1
web/edit/user/index.php

@@ -62,7 +62,7 @@ exec (VESTA_CMD."v-list-user-packages json", $output, $return_var);
 $packages = json_decode(implode('', $output), true);
 unset($output);
 
-// List lanugages
+// List languages
 exec (VESTA_CMD."v-list-sys-languages json", $output, $return_var);
 $languages = json_decode(implode('', $output), true);
 unset($output);

+ 112 - 0
web/inc/i18n.php

@@ -0,0 +1,112 @@
+<?php
+// Functions for internationalization
+
+/**
+ * Translates string to given language in first parameter, key given in second parameter (dynamically loads required language). Works like spritf from second parameter
+ * @global array $LANG Associative array of language pharses
+ * @return string Translated string
+ */
+function _translate() {
+    global $LANG;
+
+    $args = func_get_args();
+    $l = $args[0];
+
+    if (!$l) return 'NO LANGUAGE DEFINED';
+    $key = $args[1];
+
+    if (!isset($LANG[$l])) {
+        require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$l.'.php');
+    }
+
+    if (!isset($LANG[$l][$key])) {
+        $text=$key;
+    } else {
+        $text=$LANG[$l][$key];
+    }
+
+    array_shift($args);
+    if (count($args)>1) {
+        $args[0] = $text;
+        return call_user_func_array("sprintf",$args);
+    } else {
+        return $text;
+    }
+}
+
+/**
+ * Translates string by a given key in first parameter to current session language. Works like sprintf
+ * @global array $LANG Associative array of language pharses
+ * @return string Translated string
+ * @see _translate()
+ */
+function __() {
+    $args = func_get_args();
+    array_unshift($args,$_SESSION['language']);
+    return call_user_func_array("_translate",$args);
+}
+
+/**
+ * Detects user language from Accept-Language HTTP header.
+ * @param string Fallback language (default: 'en')
+ * @return string Language code (such as 'en' and 'ja')
+ */
+function detect_user_language($fallback='en') {
+    static $user_lang = '';
+
+    // Already detected
+    if (!empty($user_lang)) return $user_lang;
+
+    // Check if Accept-Language header is available
+    if (!isset($_SERVER) ||
+        !isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ||
+        !is_string($_SERVER['HTTP_ACCEPT_LANGUAGE'])
+    ) {
+        // Store result for reusing
+        $user_lang = $fallback;
+        return $user_lang;
+    }
+
+    // Sort Accept-Language by `q` value
+    $accept_langs = explode(',', preg_replace('/\s/', '', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])));
+    $accept_langs_sorted = [];
+    foreach ($accept_langs as $lang) {
+        $div = explode(';q=', $lang, 2);
+        if (count($div) < 2) {
+            // `q` value was not specfied
+            // -> Set default `q` value (1)
+            $div[] = '1';
+        }
+        list($code, $q) = $div;
+        if (preg_match('/^[\w\-]+$/', $code)) {
+            // Acceptable language code
+            $accept_langs_sorted[$code] = (double)$q;
+        }
+    }
+    arsort($accept_langs_sorted);
+
+    // List languages
+    exec (VESTA_CMD."v-list-sys-languages json", $output, $return_var);
+    $languages = json_decode(implode('', $output), true);
+    unset($output);
+
+    // Find best matching language
+    foreach ($accept_langs_sorted as $user_lang => $dummy) {
+        $decision = '';
+        foreach ($languages as $prov_lang) {
+            if (strlen($decision) > strlen($prov_lang)) continue;
+            if (strpos($user_lang, $prov_lang) !== false) {
+                $decision = $prov_lang;
+            }
+        }
+        if (!empty($decision)) {
+            // Store result for reusing
+            $user_lang = $decision;
+            return $user_lang;
+        }
+    }
+
+    // Store result for reusing
+    $user_lang = $fallback;
+    return $user_lang;
+}

+ 2 - 48
web/inc/main.php

@@ -1,6 +1,8 @@
 <?php
 session_start();
 
+require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n.php');
+
 // Check system settings
 if ((!isset($_SESSION['VERSION'])) && (!defined('NO_AUTH_REQUIRED'))) {
     session_destroy();
@@ -14,63 +16,15 @@ if ((!isset($_SESSION['user'])) && (!defined('NO_AUTH_REQUIRED'))) {
     $_SESSION['request_uri'] = $_SERVER['REQUEST_URI'];
     header("Location: /login/");
     exit;
-
 }
 
 if (isset($_SESSION['user'])) {
-    require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$_SESSION['language'].'.php');
     if(!isset($_SESSION['token'])){
         $token = uniqid(mt_rand(), true);
         $_SESSION['token'] = $token;
     }
 }
 
-
-/**
- * Translates string by a given key in first parameter to current session language. Works like sprintf
- * @global array $LANG Associative array of language pharses
- * @return string Translated string
- * @see _translate()
- */
-function __() {
-   $args = func_get_args();
-   array_unshift($args,$_SESSION['language']);
-   return call_user_func_array("_translate",$args);
-}
-
-/**
- * Translates string to given language in first parameter, key given in second parameter (dynamically loads required language). Works like spritf from second parameter
- * @global array $LANG Associative array of language pharses
- * @return string Translated string
- */
-function _translate() {
-    global $LANG;
-
-    $args = func_get_args();
-    $l = $args[0];
-
-    if (!$l) return 'NO LANGUAGE DEFINED';
-    $key = $args[1];
-
-    if (!isset($LANG[$l])) {
-        require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$l.'.php');
-    }
-
-    if (!isset($LANG[$l][$key])) {
-        $text=$key;
-    } else {
-        $text=$LANG[$l][$key];
-    }
-
-    array_shift($args);
-    if (count($args)>1) {
-        $args[0] = $text;
-        return call_user_func_array("sprintf",$args);
-    } else {
-        return $text;
-    }
-}
-
 define('VESTA_CMD', '/usr/bin/sudo /usr/local/vesta/bin/');
 
 $i = 0;

+ 3 - 39
web/js/i18n.js.php

@@ -1,46 +1,10 @@
 <?php
 session_start();
-if (empty($_SESSION['language'])) {
-    $_SESSION['language'] = 'en';
-}
-require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$_SESSION['language'].'.php');
-
-if (!function_exists('_translate')) {
-    function _translate() {
-        global $LANG;
-
-        $args = func_get_args();
-        $l = $args[0];
-
-        if (!$l) return 'NO LANGUAGE DEFINED';
-        $key = $args[1];
 
-        if (!isset($LANG[$l])) {
-            require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$l.'.php');
-        }
+require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n.php');
 
-        if (!isset($LANG[$l][$key])) {
-            $text=$key;
-        } else {
-            $text=$LANG[$l][$key];
-        }
-
-        array_shift($args);
-        if (count($args)>1) {
-            $args[0] = $text;
-            return call_user_func_array("sprintf",$args);
-        } else {
-            return $text;
-        }
-    }
-}
-
-if (!function_exists('__')) {
-    function __() {
-        $args = func_get_args();
-        array_unshift($args,$_SESSION['language']);
-        return call_user_func_array("_translate",$args);
-    }
+if (empty($_SESSION['language'])) {
+    $_SESSION['language'] = detect_user_language();
 }
 ?>
 

+ 2 - 2
web/login/index.php

@@ -93,8 +93,8 @@ foreach ($sys_arr as $key => $value) {
     $_SESSION[$key] = $value;
 }
 
-// Set default language
-if (empty($_SESSION['language'])) $_SESSION['language']='en';
+// Detect language
+if (empty($_SESSION['language'])) $_SESSION['language'] = detect_user_language();
 
 require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$_SESSION['language'].'.php');
 require_once('../templates/header.html');

+ 2 - 8
web/reset/index.php

@@ -74,14 +74,8 @@ if ((!empty($_POST['user'])) && (!empty($_POST['code'])) && (!empty($_POST['pass
     }
 }
 
-// Set system language
-exec (VESTA_CMD . "v-list-sys-config json", $output, $return_var);
-$data = json_decode(implode('', $output), true);
-if (!empty( $data['config']['LANGUAGE'])) {
-    $_SESSION['language'] = $data['config']['LANGUAGE'];
-} else {
-    $_SESSION['language'] = 'en';
-}
+// Detect language
+if (empty($_SESSION['language'])) $_SESSION['language'] = detect_user_language();
 
 if (empty($_GET['action'])) {
     require_once '../templates/header.html';

+ 1 - 1
web/templates/admin/edit_user.html

@@ -125,7 +125,7 @@
                                                 if (( $value == $v_language ) || ( $svalue == $v_language)){
                                                     echo 'selected' ;
                                                 }
-                                                if (( $value == 'en' ) && (empty($v_language))){
+                                                if (( $value == detect_user_language() ) && (empty($v_language))){
                                                     echo 'selected' ;
                                                 }
                                                 echo ">".htmlentities($value)."</option>\n";

+ 1 - 1
web/templates/user/edit_user.html

@@ -104,7 +104,7 @@
                                                 if (( $value == $v_language ) || ( $svalue == $v_language)){
                                                     echo 'selected' ;
                                                 }
-                                                if (( $value == 'en' ) && (empty($v_language))){
+                                                if (( $value == detect_user_language() ) && (empty($v_language))){
                                                     echo 'selected' ;
                                                 }
                                                 echo ">".htmlentities($value)."</option>\n";