Move all the files in src directory

This commit is contained in:
2021-05-07 09:58:35 +02:00
parent 4c43053c5b
commit 7a4141a70b
83 changed files with 0 additions and 5 deletions

379
src/language.php Normal file
View File

@@ -0,0 +1,379 @@
<?php
/** DomFramework
* @package domframework
* @author Dominique Fournier <dominique@fournier38.fr>
* @license BSD
*/
namespace Domframework;
/** Language class : change the messages
*/
class language
{
// Language.php
// Use Gettext, so the locales must be available in the system
// Check the output of the command 'locale -a' :
// en_GB.utf8
// en_US.utf8
// [...]
// fr_FR.utf8
// The directories must be of this format but with a UTF8 in capital !
// Example : ./locale/en_US.UTF8/LC_MESSAGES/programme.mo
// The only available codeset is UTF8
// The languages are always in the format fr_FR (without the codeset)
/** Language cache directory */
public $cacheDir = "data/locale";
/** Choose the best language in the browser list and which is available in
* locale path
* @param string|null $repLocale Directory where are stored the translations
* @param string|null $languageCode The coding langugage of the soft
* @return string The choosed locale whithout charset (like fr_FR)
*/
function languageSelection ($repLocale = "./locale", $languageCode = "fr_FR")
{
$arrAccept = array ();
if (isset ($_SERVER["HTTP_ACCEPT_LANGUAGE"]))
{
// Analyse de HTTP_ACCEPT_LANGUAGE
// HTTP_ACCEPT_LANGUAGE est de la forme : fr,en;q=0.7,en-us;q=0.3
// Recuperation de la liste des languages souhaitees
$arrAccept = explode(",", strtolower ($_SERVER["HTTP_ACCEPT_LANGUAGE"]));
// Pre-traitement des choix de l'utilisateur
foreach ($arrAccept as $key=>$value)
{
// Suppression des poids (l'ordre est donne dans la pile)
if ( ($pos = strpos ($value, ";")) !== FALSE)
{
$arrAccept[$key] = substr ($value, 0, $pos);
}
// Si la language proposee est du style en-us, convertit en en-US
if ( ($pos = strpos ($value, "-")) !== FALSE)
{
$arrAccept[$key] = substr ($arrAccept[$key], 0, $pos).
strtoupper (substr ($arrAccept[$key], $pos));
}
// Remplacement des tirets par des soulignes
$arrAccept[$key] = str_replace ("-", "_", $arrAccept[$key]);
}
}
if (isset ($_SERVER["LC_MESSAGES"]))
{
// La ligne ci-dessous permet de récupérer la language sans le codeset si
// il est fourni en_US.UTF8 -> en_US
@list ($languageCodetmp, $codeset) = explode (".",
$_SERVER["LC_MESSAGES"]);
$arrAccept[] = $languageCodetmp;
}
if (isset ($_SERVER["LANG"]))
{
// La ligne ci-dessous permet de récupérer la language sans le codeset si
// il est fourni en_US.UTF8 -> en_US
@list ($languageCodetmp, $codeset) = explode (".", $_SERVER["LANG"]);
$arrAccept[] = $languageCodetmp;
}
// Si l'utilisateur n'a defini aucune language, on met la language par
// defaut
if (empty ($arrAccept))
$arrAccept[] = $languageCode;
// Le tableau $arrAccept est trié par priorité de language souhaité par
// l'utilisateur (0=>le plus important)
// Recherche des languages disponibles dans le repertoire $repLocale
$arrLanguageAvailable = $this->languageTraductionsList ($repLocale);
$arrLanguageAvailable[] = $languageCode;
$languageCode = "";
// Analyse pour donner la meilleure language possible
foreach ($arrAccept as $value)
{
// Regarde si un repertoire existe avec la language proposee.
// Recherche insensible à la casse, retourne le nom du fichier avec la
// casse
$val2 = strtolower ($value);
foreach ($arrLanguageAvailable as $val)
{
$val3 = strtolower ($val);
if ($val2 === $val3)
{
$languageCode = $val;
break;
}
}
// Regarde si un repertoire existe avec language en tant que base
// (l'utilisateur demande fr et on a fr_FR.utf-8)
foreach ($arrLanguageAvailable as $languageCodeAvailable)
{
if ($value === substr ($languageCodeAvailable, 0, strlen ($value)))
{
$languageCode = $languageCodeAvailable;
break;
}
}
// On a trouvé : on arrête de chercher
if ($languageCode !== "")
break;
}
// Si on n'a toujours pas trouve de language, c'est que la language par
// defaut proposee en tete de fichier est inconnue : on met la language "C"
// et le code s'affiche selon la programmation
if ($languageCode === "")
$languageCode = "C";
return ($languageCode);
}
/** Return the language recorded in the Cookie. Check if this language is
* @param string $cookieName The cookie name
* @param string|null $repLocale The directory use to store the locale files
* allowed
* @return string The language allowed or FALSE
*/
function languageCookie ($cookieName, $repLocale = "./locale")
{
if (!isset ($_COOKIE[$cookieName]))
return FALSE;
$listeTranslations = $this->languageTraductionsList ($repLocale);
if ($listeTranslations === FALSE)
return FALSE;
if (in_array ($_COOKIE[$cookieName], $listeTranslations))
return $_COOKIE[$cookieName];
return FALSE;
}
/** Set the cookie with a TTL of one month
* @param string $cookieName The name of the cookie
* @param string $languageCode Language to store
* @param string $sitepath The site path
*/
function languageCookieSet ($cookieName, $languageCode, $sitepath)
{
@setcookie ($cookieName, $languageCode, time()+60*60*24*30, $sitepath);
}
/** Return an array with all the languages available in the $repLocale dir
* The languages are in the format 'en_US' without the codeset.
* @param string|null $repLocale The directory use to store the locale files
* Return FALSE if there is an error
*/
function languageTraductionsList ($repLocale = "./locale")
{
if (! is_dir ($repLocale) || ! is_readable ($repLocale))
return FALSE;
$list = glob ("$repLocale/*");
foreach ($list as $key=>$val)
{
$val = basename ($val);
$pos = strpos ($val, ".");
if ($pos === FALSE)
$list[$key] = $val;
else
$list[$key] = substr ($val, 0, $pos);
}
sort ($list);
return $list;
}
/** Return the full text of the category
* Return false if it doesn't exists
* @param string $category The category to analyze
*/
private function languageCategoryText ($category)
{
$categories[LC_ALL] = "LC_ALL";
$categories[LC_COLLATE] = "LC_COLLATE";
$categories[LC_CTYPE] = "LC_CTYPE";
$categories[LC_MONETARY] = "LC_MONETARY";
$categories[LC_NUMERIC] = "LC_NUMERIC";
$categories[LC_TIME] = "LC_TIME";
$categories[LC_MESSAGES] = "LC_MESSAGES";
if (! isset ($categories[$category]))
return FALSE;
return $categories[$category];
}
/** This function manage the cache of $package.mo files as Apache cache them
* It return the directory to use
* @param string $languageCode Language with format "fr_FR"
* @param string|null $package The package name of the soft ($package.mo
* file). "messages" by default
* @param string|null $category The folder name LC_MESSAGES by default
* @param string|null $repLocale The folder where all the locales are stored
*/
function languageCache ($languageCode, $package="messages",
$category=LC_MESSAGES, $repLocale = "./locale")
{
// Apache cache le fichier messages.mo jusqu'au prochain redémarrage. L'idée
// est de créer un fichier temporaire basé sur le fichier normal. Du coup,
// si on change le fichier temporaire, Apache recharge le cache et donne les
// dernières traductions.
// Cette fonction gère le cache et renvoie le nom du fichier temporaire
// La ligne ci-dessous permet de récupérer la language sans le codeset si
// il est fourni en_US.UTF8 -> en_US
if (($pos = strpos ($languageCode, ".")) !== FALSE)
list ($languageCode, $codeset) = explode (".", $languageCode);
$codeset = "UTF8"; // SANS TIRET ET EN MAJSUCULES!!!
// -> Le répertoire de données doit être fr_FR.UTF8
$category = $this->languageCategoryText ($category);
$temporaries = glob ("$repLocale/$languageCode.$codeset/$category/*-*.mo");
$moFile = "$repLocale/$languageCode.$codeset/$category/$package.mo";
if (! file_exists ($moFile))
return "";
$linkBase = $this->cacheDir."/".filemtime($moFile)."/";
$linkEnd = "$languageCode.$codeset/$category/$package.mo";
$link = $linkBase.$linkEnd;
clearstatcache (false, $moFile);
// Manage the cache directory
if (! file_exists (dirname ($link)))
{
// Try to create the cache dir. If there is an error, return the official
// moFile. Apache will need to be restarted
@mkdir (dirname ($link), 0777, true);
}
if (is_dir (dirname ($link)) && is_writeable (dirname ($link)) &&
is_readable (dirname ($link)))
{
// Manage the cache file
if (! file_exists ($link) || ! is_readable ($link) ||
filemtime ($moFile) > filemtime ($link))
{
// Do not remove immediately the old files : they can be used by Apache
$files = glob ($this->cacheDir."/*/".$linkEnd);
foreach ($files as $file)
{
unlink ($file);
// Remove the empty dirs. If not empty, do not display an error
@rmdir (dirname ($file));
@rmdir (dirname (dirname ($file)));
@rmdir (dirname (dirname (dirname ($file))));
}
copy ($moFile, $link);
chmod ($link, 0666);
}
if (filemtime ($moFile) <= filemtime ($link))
{
return $link;
}
}
return $moFile;
}
/** Start the Gettext support with the cached file .mo provided as parameter
* @param string $moFile The .mo file
* @param string $languageCode The language code to use
* @param integer $category the LC_ type to use
* @param string|null $repLocale The locale directory. Use "./locale" if not
* provided
*/
function languageActivation ($moFile, $languageCode, $category = LC_MESSAGES,
$repLocale = "./locale")
{
// Active le support Gettext pour le fichier de language .mo caché fourni en
// paramètre.
// fichierMo : fichier messages-1354015006.mo
// On ne vérifie pas la language fournie, elle doit correspondre à un
// fichier de language (qui peut être récupéré par languageSelection ou
// languageTraductionsList
// Language doit être fourni sans codeset (fr_FR et PAS fr_FR.UTF8)
if ($languageCode !== "C" && $moFile !== "")
{
$package = substr (basename ($moFile) , 0, -3);
// La ligne ci-dessous permet de récupérer la language sans le codeset si
// il est fourni en_US.UTF8 -> en_US
if (($pos = strpos ($languageCode, ".")) !== FALSE)
list ($languageCode, $codeset) = explode (".", $languageCode);
$codeset = "UTF8"; // SANS TIRET ET EN MAJSUCULES!!!
// -> Le répertoire de données doit être fr_FR.UTF8
putenv ('LANG='.$languageCode.'.'.$codeset);
putenv ('LANGUAGE='.$languageCode.'.'.$codeset);
$GLOBALS["domframework"]["lang"] = $languageCode;
bind_textdomain_codeset ($package, "utf-8");
bindtextdomain ($package, $repLocale);
textdomain ($package);
$rc = setlocale (LC_MESSAGES, $languageCode.'.'.$codeset);
if ($rc === FALSE)
{
// Language non disponible sur le système
// La liste des languages est affichée par 'locale -a'
return FALSE;
}
$rc = setlocale (LC_TIME, $languageCode.'.'.$codeset);
return TRUE;
}
return FALSE;
}
/** The complete stack of language selection
@param string $package The package name (package.(po|mo) files)
@param string $languageCookie The name of the cookie saved in the browser
@param string $forcedLanguage The name of a forced language
@return string The language with format fr_FR to be used */
public function activeLanguage ($package, $languageCookie,
$forcedLanguage = null)
{
// Prefered language in the browser
$langNav = $this->languageSelection ("./locale", "fr_FR");
// Language defined in the cookie
$langCookie = $this->languageCookie ($languageCookie);
if ($forcedLanguage !== null)
$languageCode = $forcedLanguage;
elseif ($langCookie !== FALSE)
{
$languageCode = $langCookie;
// Update the already set cookie
$this->languageCookieSet ($languageCookie, $languageCode, "/");
}
else
$languageCode = $langNav;
// Cache the domframework's .mo file too
$dfFile = $this->languageCache ($languageCode, "domframework", LC_MESSAGES,
dirname (__FILE__)."/locale");
$dfDir = dirname (dirname (dirname ($dfFile)));
$this->languageActivation ($dfFile, $languageCode, LC_MESSAGES, $dfDir);
$languageCodeFichier = $this->languageCache ($languageCode, $package);
$languageCodeDir = dirname (dirname (dirname ($languageCodeFichier)));
$this->languageActivation ($languageCodeFichier, $languageCode, LC_MESSAGES,
$languageCodeDir);
return $languageCode;
}
/** Return the language name from the language
Ex. : $languageCode=fr_FR, return France
@param string $languageCode Language with format "fr_FR"
@return string Then language name */
public function languageName ($languageCode)
{
switch ($languageCode)
{
case "fr_FR": return dgettext ("domframework", "French");
case "en_US": return dgettext ("domframework", "English (US)");
case "en_GB": return dgettext ("domframework", "English (GB)");
default:
throw new \Exception ("No language available for '$languageCode'", 500);
}
}
/** Return the language subtag for the language
* http://www.iana.org/assignments/language-subtag-registry/
* language-subtag-registry
* @param string $languageCode The language code to convert
*/
public function languageSubTag ($languageCode)
{
return str_replace ("_", "-", $languageCode);
}
}