Initial commit.
This commit is contained in:
435
lib/php/monica/getlang.inc.php
Normal file
435
lib/php/monica/getlang.inc.php
Normal file
@@ -0,0 +1,435 @@
|
||||
<?php
|
||||
// File name: getlang.inc.php
|
||||
// Description: PHP subroutine to get the current user preferred language
|
||||
// Date: 2002-04-11
|
||||
// Author: imacat <imacat@pristine.com.tw>
|
||||
// Copyright: Copyright (C) 2002-2010 Pristine Communications
|
||||
|
||||
// Set the include path
|
||||
if (!defined("INCPATH_SET")) {
|
||||
require_once dirname(__FILE__) . "/incpath.inc.php";
|
||||
}
|
||||
// Referenced subroutines
|
||||
require_once "monica/cgiemu.inc.php";
|
||||
require_once "monica/lninfo.inc.php";
|
||||
require_once "monica/requri.inc.php";
|
||||
|
||||
// getlang: Get the appropriate language from the user-agent.
|
||||
// Input: type: the type of language information to be returned
|
||||
// See lninfo.inc.php for the most current list of available types.
|
||||
// LN_NAME: Language name
|
||||
// LN_CHARSET: It's suggested character set
|
||||
// LN_FILENAME: It's proper format as part of a file name
|
||||
// LN_LOCALE: It's locale
|
||||
// LN_DATABASE: It's proper format as part of a database field name
|
||||
// LN_HTMLID: It's proper format as part of an HTML ID.
|
||||
// LN_SPACE_BREAK: If this language break lines at spaces
|
||||
// LN_IGNORE_CASE: If case can be ignored (can safely do strlower() and strupper())
|
||||
// LN_COUNTRY_FIRST: If country should be listed first in a mail address
|
||||
// LN_DESC: It's long description, in English
|
||||
// LN_DESC_CURLC: It's long description in the current language (UTF-8)
|
||||
// LN_DESC_SELFLC: It's long description in its own language (UTF-8)
|
||||
function getlang($type = null)
|
||||
{
|
||||
$lang = _getlang_getlang();
|
||||
// Return in the proper data type
|
||||
return !is_null($type)? ln($lang, $type): $lang;
|
||||
}
|
||||
|
||||
// getcharset: Get the appropriate character set from the user-agent.
|
||||
function getcharset()
|
||||
{
|
||||
static $charset;
|
||||
// Obtained before
|
||||
if (isset($charset)) {
|
||||
return $charset;
|
||||
}
|
||||
|
||||
// Default character set of this language
|
||||
$default = getlang(LN_CHARSET);
|
||||
// Obtain all the available character sets
|
||||
$all_charsets = _getlang_all_charsets();
|
||||
|
||||
// We have no choice
|
||||
if (count($all_charsets) < 2) {
|
||||
$charset = $all_charsets[0];
|
||||
return $charset;
|
||||
}
|
||||
// Parse the character set by the Accept-Charset header
|
||||
$charset = _getlang_getcs_accept();
|
||||
if (!is_null($charset)) {
|
||||
return $charset;
|
||||
}
|
||||
// Cannot parse - return the default
|
||||
$lang = $default;
|
||||
return $lang;
|
||||
}
|
||||
|
||||
// _getlang_getlang: The real subroutine
|
||||
function _getlang_getlang()
|
||||
{
|
||||
static $lang;
|
||||
// Obtained before
|
||||
if (isset($lang)) {
|
||||
return $lang;
|
||||
}
|
||||
|
||||
// Default fallback settings
|
||||
if (!array_key_exists("ALL_LINGUAS", $GLOBALS)) {
|
||||
$GLOBALS["ALL_LINGUAS"] = array("en");
|
||||
}
|
||||
global $ALL_LINGUAS;
|
||||
if (!defined("DEFAULT_LANG")) {
|
||||
define("DEFAULT_LANG", "en");
|
||||
}
|
||||
|
||||
// Uni-lingual
|
||||
if (count($ALL_LINGUAS) == 1) {
|
||||
$lang = $ALL_LINGUAS[0];
|
||||
return $lang;
|
||||
}
|
||||
// Check the file name for specified language
|
||||
// No setting environment in this case
|
||||
$lang = _getlang_getlang_filename();
|
||||
if (!is_null($lang)) {
|
||||
return $lang;
|
||||
}
|
||||
// Methods below should set the language in the environment
|
||||
// Check the environment for specified language
|
||||
$lang = _getlang_getlang_env();
|
||||
if (!is_null($lang)) {
|
||||
_getlang_getlang_setenv($lang);
|
||||
return $lang;
|
||||
}
|
||||
// Parse the language by the Accept-Language header
|
||||
$lang = _getlang_getlang_accept();
|
||||
if (!is_null($lang)) {
|
||||
_getlang_getlang_setenv($lang);
|
||||
return $lang;
|
||||
}
|
||||
// Parse the language by the console locale
|
||||
$lang = _getlang_getlang_locale();
|
||||
if (!is_null($lang)) {
|
||||
_getlang_getlang_setenv($lang);
|
||||
return $lang;
|
||||
}
|
||||
// Cannot parse - return the default
|
||||
$lang = DEFAULT_LANG;
|
||||
_getlang_getlang_setenv($lang);
|
||||
return $lang;
|
||||
}
|
||||
|
||||
// _getlang_getlang_filename: Check the file name for specified language
|
||||
function _getlang_getlang_filename()
|
||||
{
|
||||
global $ALL_LINGUAS;
|
||||
// Check the file name format
|
||||
if (!preg_match("/\.([^\.\/]+)\.[^\.\/]+$/", REQUEST_PATH, $m)) {
|
||||
return null;
|
||||
}
|
||||
$langfile = $m[1];
|
||||
// Check each language for its file name format
|
||||
for ($l = 0, $map = array(); $l < count($ALL_LINGUAS); $l++) {
|
||||
$lang = $ALL_LINGUAS[$l];
|
||||
if ($langfile == ln($lang, LN_FILENAME)) {
|
||||
return $lang;
|
||||
}
|
||||
}
|
||||
// Not found
|
||||
return null;
|
||||
}
|
||||
|
||||
// _getlang_getlang_env: Check the environment for specified language
|
||||
function _getlang_getlang_env()
|
||||
{
|
||||
global $ALL_LINGUAS;
|
||||
// Check the query string
|
||||
if ( array_key_exists("lang", $_GET)
|
||||
&& in_array($_GET["lang"], $ALL_LINGUAS)) {
|
||||
return $_GET["lang"];
|
||||
// Check the POSTed form
|
||||
} elseif ( array_key_exists("lang", $_POST)
|
||||
&& in_array($_POST["lang"], $ALL_LINGUAS)) {
|
||||
return $_POST["lang"];
|
||||
// Check the cookies
|
||||
} elseif ( array_key_exists("lang", $_COOKIE)
|
||||
&& in_array($_COOKIE["lang"], $ALL_LINGUAS)) {
|
||||
return $_COOKIE["lang"];
|
||||
// Check the session
|
||||
} elseif ( isset($_SESSION)
|
||||
&& array_key_exists("lang", $_SESSION)
|
||||
&& in_array($_SESSION["lang"], $ALL_LINGUAS)) {
|
||||
return $_SESSION["lang"];
|
||||
}
|
||||
// Not set
|
||||
return null;
|
||||
}
|
||||
|
||||
// _getlang_getlang_accept: Parse the language by the Accept-Language header
|
||||
// Refer to HTTP/1.1 section 14.4 for this algorism
|
||||
function _getlang_getlang_accept()
|
||||
{
|
||||
// Accept-Language not set
|
||||
if (!array_key_exists("HTTP_ACCEPT_LANGUAGE", $_SERVER)) {
|
||||
return null;
|
||||
}
|
||||
global $ALL_LINGUAS;
|
||||
|
||||
// Split into language ranges
|
||||
$rngs = preg_split("/\s*,\s*/", trim($_SERVER["HTTP_ACCEPT_LANGUAGE"]));
|
||||
$rngqf = array(); // User Assigned quality factor
|
||||
foreach ($rngs as $range) {
|
||||
// Split into attributes
|
||||
$attrs = preg_split("/\s*;\s*/", trim($range));
|
||||
// First piece is the language range
|
||||
$ln = array_shift($attrs);
|
||||
// Lower-case it
|
||||
$ln = strtolower($ln);
|
||||
// Find the quality factor
|
||||
foreach ($attrs as $attr) {
|
||||
// A numeric quality factor found
|
||||
if (strtolower(substr($attr, 0, 2)) == "q="
|
||||
&& is_numeric(substr($attr, 2))) {
|
||||
$rngqf[$ln] = substr($attr, 2) + 0;
|
||||
}
|
||||
}
|
||||
// Default quality factor to 1
|
||||
if (!array_key_exists($ln, $rngqf)) {
|
||||
$rngqf[$ln] = 1;
|
||||
}
|
||||
}
|
||||
// The default quality factor
|
||||
if (array_key_exists("*", $rngqf)) {
|
||||
$defqf = $rngqf["*"];
|
||||
unset($rngqf["*"]);
|
||||
} else {
|
||||
$defqf = 0;
|
||||
}
|
||||
|
||||
// Language tags (what we have)
|
||||
$tagqf = array(); // Calculated quality factor
|
||||
for ($l = 0; $l < count($ALL_LINGUAS); $l++) {
|
||||
$ln = $ALL_LINGUAS[$l];
|
||||
// Language tag, as specified in ISO
|
||||
$tag = ln($ln, LN_NAME);
|
||||
unset($match); // Matched range of the quality factor
|
||||
// Language ranges (what the user sent to match us)
|
||||
foreach (array_keys($rngqf) as $range) {
|
||||
// Exactly match or match a prefix
|
||||
if ( $tag == $range
|
||||
|| substr($tag, 0, strlen($range)+1) == "$range-") {
|
||||
// Not matched yet
|
||||
if (!isset($match)) {
|
||||
$tagqf[$ln] = $rngqf[$range]; // Quality Factor
|
||||
$match = $range; // Record the matched range
|
||||
// A longer match range
|
||||
} elseif (strlen($range) > strlen($match)) {
|
||||
$tagqf[$ln] = $rngqf[$range]; // Quality Factor
|
||||
$match = $range; // Record the matched range
|
||||
}
|
||||
}
|
||||
}
|
||||
// Not matched - apply a default quality factor
|
||||
if (!array_key_exists($ln, $tagqf)) {
|
||||
$tagqf[$ln] = $defqf;
|
||||
}
|
||||
}
|
||||
|
||||
// Drop unacceptable languages
|
||||
foreach (array_keys($tagqf) as $ln) {
|
||||
if ($tagqf[$ln] <= 0) {
|
||||
unset($tagqf[$ln]);
|
||||
}
|
||||
}
|
||||
// Nothing acceptable
|
||||
if (count($tagqf) == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Sort by the quality factor
|
||||
$GLOBALS["_GETLANG_TAGQF"] =& $tagqf;
|
||||
$GLOBALS["_GETLANG_DEFAULT"] = DEFAULT_LANG;
|
||||
$ln = array_keys($tagqf);
|
||||
usort($ln, "_getlang_cmp_tagqf");
|
||||
unset($GLOBALS["_GETLANG_TAGQF"]);
|
||||
unset($GLOBALS["_GETLANG_DEFAULT"]);
|
||||
// A preferred match
|
||||
return $ln[0];
|
||||
}
|
||||
|
||||
// _getlang_getlang_locale: Parse the language by the console locale
|
||||
function _getlang_getlang_locale()
|
||||
{
|
||||
// Only work on console
|
||||
if (IS_CGI) {
|
||||
return null;
|
||||
}
|
||||
// Check these environment variables in order
|
||||
// See http://www.gnu.org/software/libc/manual/html_node/Using-gettextized-software.html
|
||||
$envs = array("LANGUAGE", "LC_ALL", "LC_MESSAGES", "LANG");
|
||||
for ($i = 0, $lang = null; $i < count($envs); $i++) {
|
||||
$locale = getenv($envs[$i]);
|
||||
// Obtain the first valid one and discard the rest
|
||||
if ($locale !== false && $locale != "") {
|
||||
$lang = $locale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// No locale setting was found
|
||||
if (is_null($lang)) {
|
||||
return null;
|
||||
}
|
||||
// Remove the character set
|
||||
$lang = preg_replace("/\..*$/", "", $lang);
|
||||
// Lower-case it
|
||||
$lang = strtolower($lang);
|
||||
// Replace underscore with dash
|
||||
$lang = str_replace("_", "-", $lang);
|
||||
// en-us is en
|
||||
if ($lang == "en-us") {
|
||||
$lang = "en";
|
||||
}
|
||||
// Not in our available languages list
|
||||
if (!in_array($lang, $GLOBALS["ALL_LINGUAS"])) {
|
||||
return null;
|
||||
}
|
||||
// Return it
|
||||
return $lang;
|
||||
}
|
||||
|
||||
// _getlang_getlang_setenv: Set the language in the environment
|
||||
function _getlang_getlang_setenv($lang)
|
||||
{
|
||||
// Set the session variable
|
||||
if ( isset($_SESSION)
|
||||
&& (!array_key_exists("lang", $_SESSION)
|
||||
|| $_SESSION["lang"] != $lang)) {
|
||||
$_SESSION["lang"] = $lang;
|
||||
}
|
||||
// Set the cookie
|
||||
if ( (!array_key_exists("lang", $_COOKIE)
|
||||
|| $_COOKIE["lang"] != $lang)
|
||||
&& !headers_sent()) {
|
||||
setcookie("lang", $lang, time() + 86400 * 365, "/");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// _getlang_getcs_accept: Parse the character set by the Accept-Charset header
|
||||
// Refer to HTTP/1.1 section 14.2 for this algorism
|
||||
function _getlang_getcs_accept()
|
||||
{
|
||||
// Accept-Charset not set
|
||||
if (!array_key_exists("HTTP_ACCEPT_CHARSET", $_SERVER)) {
|
||||
return null;
|
||||
}
|
||||
// Obtain all the available character sets
|
||||
$all_charsets = _getlang_all_charsets();
|
||||
|
||||
// Split into character set ranges
|
||||
$rngs = preg_split("/\s*,\s*/", trim($_SERVER["HTTP_ACCEPT_CHARSET"]));
|
||||
$rngqf = array(); // User Assigned quality factor
|
||||
foreach ($rngs as $range) {
|
||||
// Split into attributes
|
||||
$attrs = preg_split("/\s*;\s*/", trim($range));
|
||||
// First piece is the character set range
|
||||
$cs = array_shift($attrs);
|
||||
// Lower-case it
|
||||
$cs = strtolower($cs);
|
||||
// Find the quality factor
|
||||
foreach ($attrs as $attr) {
|
||||
// A numeric quality factor found
|
||||
if (strtolower(substr($attr, 0, 2)) == "q="
|
||||
&& is_numeric(substr($attr, 2))) {
|
||||
$rngqf[$cs] = substr($attr, 2) + 0;
|
||||
}
|
||||
}
|
||||
// Default quality factor to 1
|
||||
if (!array_key_exists($cs, $rngqf)) {
|
||||
$rngqf[$cs] = 1;
|
||||
}
|
||||
}
|
||||
// The default quality factor
|
||||
if (array_key_exists("*", $rngqf)) {
|
||||
$defqf = $rngqf["*"];
|
||||
unset($rngqf["*"]);
|
||||
} else {
|
||||
// Default ISO-8859-1 to 1
|
||||
if (!array_key_exists("iso-8859-1", $rngqf)) {
|
||||
$rngqf["iso-8859-1"] = 1;
|
||||
}
|
||||
$defqf = 0;
|
||||
}
|
||||
$tagqf = array(); // Calculated quality factor
|
||||
// Character set tags (what we have)
|
||||
for ($l = 0; $l < count($all_charsets); $l++) {
|
||||
$cs = $all_charsets[$l];
|
||||
$tag = strtolower($cs);
|
||||
// Character set ranges (what the user sent to match us)
|
||||
foreach (array_keys($rngqf) as $range) {
|
||||
// Matched
|
||||
if ($tag == $range) {
|
||||
$tagqf[$cs] = $rngqf[$range]; // Quality Factor
|
||||
}
|
||||
}
|
||||
// Not matched - apply a default quality factor
|
||||
if (!array_key_exists($cs, $tagqf)) {
|
||||
$tagqf[$cs] = $defqf;
|
||||
}
|
||||
}
|
||||
|
||||
// Drop unacceptable languages
|
||||
foreach (array_keys($tagqf) as $cs) {
|
||||
if ($tagqf[$cs] <= 0) {
|
||||
unset($tagqf[$cs]);
|
||||
}
|
||||
}
|
||||
// Nothing acceptable
|
||||
if (count($tagqf) == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Sort by the quality factor
|
||||
$GLOBALS["_GETLANG_TAGQF"] =& $tagqf;
|
||||
$GLOBALS["_GETLANG_DEFAULT"] = getlang(LN_CHARSET);
|
||||
$cs = array_keys($tagqf);
|
||||
usort($cs, "_getlang_cmp_tagqf");
|
||||
unset($GLOBALS["_GETLANG_TAGQF"]);
|
||||
unset($GLOBALS["_GETLANG_DEFAULT"]);
|
||||
// A preferred match
|
||||
return $cs[0];
|
||||
}
|
||||
|
||||
// _getlang_all_charsets: Obtain all the available character sets
|
||||
// Available character sets are the default character set of this
|
||||
// language, and UTF-8
|
||||
function _getlang_all_charsets()
|
||||
{
|
||||
static $charsets;
|
||||
if (isset($charsets)) {
|
||||
return $charsets;
|
||||
}
|
||||
$charsets = array();
|
||||
$charsets[] = getlang(LN_CHARSET);
|
||||
$charsets[] = "UTF-8";
|
||||
$charsets = array_values(array_unique($charsets));
|
||||
return $charsets;
|
||||
}
|
||||
|
||||
// _getlang_cmp_tagqf: Compare the quality factor of the tags
|
||||
function _getlang_cmp_tagqf($a, $b)
|
||||
{
|
||||
global $_GETLANG_TAGQF, $_GETLANG_DEFAULT;
|
||||
if ($_GETLANG_TAGQF[$a] != $_GETLANG_TAGQF[$b]) {
|
||||
return $_GETLANG_TAGQF[$b] < $_GETLANG_TAGQF[$a]? -1: 1;
|
||||
}
|
||||
if ($a == $_GETLANG_DEFAULT) {
|
||||
return -1;
|
||||
}
|
||||
if ($b == $_GETLANG_DEFAULT) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user