Skip to content

Commit 0d2dc08

Browse files
committed
Merge pull request hestiacp#504 from Flatta/feature-detectlang
Detect user language (Feature request)
2 parents 3c09b55 + e3c1b17 commit 0d2dc08

File tree

8 files changed

+124
-100
lines changed

8 files changed

+124
-100
lines changed

web/edit/user/index.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
$packages = json_decode(implode('', $output), true);
6363
unset($output);
6464

65-
// List lanugages
65+
// List languages
6666
exec (VESTA_CMD."v-list-sys-languages json", $output, $return_var);
6767
$languages = json_decode(implode('', $output), true);
6868
unset($output);

web/inc/i18n.php

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
// Functions for internationalization
3+
4+
/**
5+
* Translates string to given language in first parameter, key given in second parameter (dynamically loads required language). Works like spritf from second parameter
6+
* @global array $LANG Associative array of language pharses
7+
* @return string Translated string
8+
*/
9+
function _translate() {
10+
global $LANG;
11+
12+
$args = func_get_args();
13+
$l = $args[0];
14+
15+
if (!$l) return 'NO LANGUAGE DEFINED';
16+
$key = $args[1];
17+
18+
if (!isset($LANG[$l])) {
19+
require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$l.'.php');
20+
}
21+
22+
if (!isset($LANG[$l][$key])) {
23+
$text=$key;
24+
} else {
25+
$text=$LANG[$l][$key];
26+
}
27+
28+
array_shift($args);
29+
if (count($args)>1) {
30+
$args[0] = $text;
31+
return call_user_func_array("sprintf",$args);
32+
} else {
33+
return $text;
34+
}
35+
}
36+
37+
/**
38+
* Translates string by a given key in first parameter to current session language. Works like sprintf
39+
* @global array $LANG Associative array of language pharses
40+
* @return string Translated string
41+
* @see _translate()
42+
*/
43+
function __() {
44+
$args = func_get_args();
45+
array_unshift($args,$_SESSION['language']);
46+
return call_user_func_array("_translate",$args);
47+
}
48+
49+
/**
50+
* Detects user language from Accept-Language HTTP header.
51+
* @param string Fallback language (default: 'en')
52+
* @return string Language code (such as 'en' and 'ja')
53+
*/
54+
function detect_user_language($fallback='en') {
55+
static $user_lang = '';
56+
57+
// Already detected
58+
if (!empty($user_lang)) return $user_lang;
59+
60+
// Check if Accept-Language header is available
61+
if (!isset($_SERVER) ||
62+
!isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ||
63+
!is_string($_SERVER['HTTP_ACCEPT_LANGUAGE'])
64+
) {
65+
// Store result for reusing
66+
$user_lang = $fallback;
67+
return $user_lang;
68+
}
69+
70+
// Sort Accept-Language by `q` value
71+
$accept_langs = explode(',', preg_replace('/\s/', '', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])));
72+
$accept_langs_sorted = [];
73+
foreach ($accept_langs as $lang) {
74+
$div = explode(';q=', $lang, 2);
75+
if (count($div) < 2) {
76+
// `q` value was not specfied
77+
// -> Set default `q` value (1)
78+
$div[] = '1';
79+
}
80+
list($code, $q) = $div;
81+
if (preg_match('/^[\w\-]+$/', $code)) {
82+
// Acceptable language code
83+
$accept_langs_sorted[$code] = (double)$q;
84+
}
85+
}
86+
arsort($accept_langs_sorted);
87+
88+
// List languages
89+
exec (VESTA_CMD."v-list-sys-languages json", $output, $return_var);
90+
$languages = json_decode(implode('', $output), true);
91+
unset($output);
92+
93+
// Find best matching language
94+
foreach ($accept_langs_sorted as $user_lang => $dummy) {
95+
$decision = '';
96+
foreach ($languages as $prov_lang) {
97+
if (strlen($decision) > strlen($prov_lang)) continue;
98+
if (strpos($user_lang, $prov_lang) !== false) {
99+
$decision = $prov_lang;
100+
}
101+
}
102+
if (!empty($decision)) {
103+
// Store result for reusing
104+
$user_lang = $decision;
105+
return $user_lang;
106+
}
107+
}
108+
109+
// Store result for reusing
110+
$user_lang = $fallback;
111+
return $user_lang;
112+
}

web/inc/main.php

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
session_start();
33

4+
require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n.php');
5+
46
// Check system settings
57
if ((!isset($_SESSION['VERSION'])) && (!defined('NO_AUTH_REQUIRED'))) {
68
session_destroy();
@@ -14,63 +16,15 @@
1416
$_SESSION['request_uri'] = $_SERVER['REQUEST_URI'];
1517
header("Location: /login/");
1618
exit;
17-
1819
}
1920

2021
if (isset($_SESSION['user'])) {
21-
require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$_SESSION['language'].'.php');
2222
if(!isset($_SESSION['token'])){
2323
$token = uniqid(mt_rand(), true);
2424
$_SESSION['token'] = $token;
2525
}
2626
}
2727

28-
29-
/**
30-
* Translates string by a given key in first parameter to current session language. Works like sprintf
31-
* @global array $LANG Associative array of language pharses
32-
* @return string Translated string
33-
* @see _translate()
34-
*/
35-
function __() {
36-
$args = func_get_args();
37-
array_unshift($args,$_SESSION['language']);
38-
return call_user_func_array("_translate",$args);
39-
}
40-
41-
/**
42-
* Translates string to given language in first parameter, key given in second parameter (dynamically loads required language). Works like spritf from second parameter
43-
* @global array $LANG Associative array of language pharses
44-
* @return string Translated string
45-
*/
46-
function _translate() {
47-
global $LANG;
48-
49-
$args = func_get_args();
50-
$l = $args[0];
51-
52-
if (!$l) return 'NO LANGUAGE DEFINED';
53-
$key = $args[1];
54-
55-
if (!isset($LANG[$l])) {
56-
require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$l.'.php');
57-
}
58-
59-
if (!isset($LANG[$l][$key])) {
60-
$text=$key;
61-
} else {
62-
$text=$LANG[$l][$key];
63-
}
64-
65-
array_shift($args);
66-
if (count($args)>1) {
67-
$args[0] = $text;
68-
return call_user_func_array("sprintf",$args);
69-
} else {
70-
return $text;
71-
}
72-
}
73-
7428
define('VESTA_CMD', '/usr/bin/sudo /usr/local/vesta/bin/');
7529

7630
$i = 0;

web/js/i18n.js.php

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,10 @@
11
<?php
22
session_start();
3-
if (empty($_SESSION['language'])) {
4-
$_SESSION['language'] = 'en';
5-
}
6-
require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$_SESSION['language'].'.php');
7-
8-
if (!function_exists('_translate')) {
9-
function _translate() {
10-
global $LANG;
11-
12-
$args = func_get_args();
13-
$l = $args[0];
14-
15-
if (!$l) return 'NO LANGUAGE DEFINED';
16-
$key = $args[1];
173

18-
if (!isset($LANG[$l])) {
19-
require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$l.'.php');
20-
}
4+
require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n.php');
215

22-
if (!isset($LANG[$l][$key])) {
23-
$text=$key;
24-
} else {
25-
$text=$LANG[$l][$key];
26-
}
27-
28-
array_shift($args);
29-
if (count($args)>1) {
30-
$args[0] = $text;
31-
return call_user_func_array("sprintf",$args);
32-
} else {
33-
return $text;
34-
}
35-
}
36-
}
37-
38-
if (!function_exists('__')) {
39-
function __() {
40-
$args = func_get_args();
41-
array_unshift($args,$_SESSION['language']);
42-
return call_user_func_array("_translate",$args);
43-
}
6+
if (empty($_SESSION['language'])) {
7+
$_SESSION['language'] = detect_user_language();
448
}
459
?>
4610

web/login/index.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@
9393
$_SESSION[$key] = $value;
9494
}
9595

96-
// Set default language
97-
if (empty($_SESSION['language'])) $_SESSION['language']='en';
96+
// Detect language
97+
if (empty($_SESSION['language'])) $_SESSION['language'] = detect_user_language();
9898

9999
require_once($_SERVER['DOCUMENT_ROOT'].'/inc/i18n/'.$_SESSION['language'].'.php');
100100
require_once('../templates/header.html');

web/reset/index.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,8 @@
7474
}
7575
}
7676

77-
// Set system language
78-
exec (VESTA_CMD . "v-list-sys-config json", $output, $return_var);
79-
$data = json_decode(implode('', $output), true);
80-
if (!empty( $data['config']['LANGUAGE'])) {
81-
$_SESSION['language'] = $data['config']['LANGUAGE'];
82-
} else {
83-
$_SESSION['language'] = 'en';
84-
}
77+
// Detect language
78+
if (empty($_SESSION['language'])) $_SESSION['language'] = detect_user_language();
8579

8680
if (empty($_GET['action'])) {
8781
require_once '../templates/header.html';

web/templates/admin/edit_user.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@
125125
if (( $value == $v_language ) || ( $svalue == $v_language)){
126126
echo 'selected' ;
127127
}
128-
if (( $value == 'en' ) && (empty($v_language))){
128+
if (( $value == detect_user_language() ) && (empty($v_language))){
129129
echo 'selected' ;
130130
}
131131
echo ">".htmlentities($value)."</option>\n";

web/templates/user/edit_user.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
if (( $value == $v_language ) || ( $svalue == $v_language)){
105105
echo 'selected' ;
106106
}
107-
if (( $value == 'en' ) && (empty($v_language))){
107+
if (( $value == detect_user_language() ) && (empty($v_language))){
108108
echo 'selected' ;
109109
}
110110
echo ">".htmlentities($value)."</option>\n";

0 commit comments

Comments
 (0)