personal-website/utils/localization.php

103 lines
2.8 KiB
PHP
Executable File

<?php
/////////////////////////////////////////////////
// Avaliable variables after importing this file
/////////////////////////////////////////////////
// The actual language being used
$lang = null;
// Avaliable detected languages
$langs = [];
// Function that gets the strings
$trans = function(){ return 'N/A'; };
/* I use functions to create scopes. Anything below
* shouldn't be accesible from outside
*/
/* -------------------------------------------------*/
$__langfunc = function() use (&$lang, &$langs, &$trans){
///////////////
/// Get basedir
///////////////
// DOCUMENT_ROOT makes sure we always get the right folder
$basedir = sprintf('%s/lang', $_SERVER['DOCUMENT_ROOT']);
///////////////////////////////////////
/// Get the languages we have avaliable
///////////////////////////////////////
// To get the langs we scan the folder with the ini files
$langs = scandir($basedir);
// Filter for those that have to letters and end in ".ini"
$langs = array_filter($langs, fn($x) => preg_match('/.*\.ini/', $x) === 1);
// And we remove the ".ini" part
$langs = array_map(fn($x) => substr($x, 0, 2), $langs);
////////////////////////////////////
/// Get the optimal language to use
////////////////////////////////////
/* Try to get the language from browser-sent headers. The
* format for the header is like this: "en_US,es;q=0.5,ar;q=0.1".
* q=N represents the weight of preference, no q means q=1.0.
*/
{
// Divide language string per language
$http_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
// Sanitize lang string and cast weight
$http_langs = array_map(function($x){
$x = explode(';',$x);
$x[0] = strtolower(substr($x[0], 0, 2));
$x[1] = (float)(explode('=',$x[1]??'q=1.0')[1]??1.0);
return $x;
}, $http_langs);
// Sort by weight
usort($http_langs, function($a, $b){
if($a[1] === $b[1]) return 0;
return ($a[1] > $b[1]) ? -1 : 1;
});
// Create new neat array like this: ['en', 'es', 'ar']
$user_langs = [];
array_walk($http_langs, function($arr) use (&$user_langs){
if(!in_array($arr[0], $user_langs)) $user_langs[] = $arr[0];
});
// Assign the first match
foreach($user_langs as $ilang){
if(in_array($ilang, $langs)) {
$lang = $ilang;
break;
}
}
}
// Manully selected lang > HTTP lang > fallback lang
$lang = ($_GET['lang']??null) ?: $lang ?: 'en';
///////////////////////////////////////////////////
/// Get file and build function to get the strings
///////////////////////////////////////////////////
$text = parse_ini_file("$basedir/$lang.ini", true);
$trans = function (string $index) use ($text): string{
return htmlspecialchars($text[$index]??"N/A", ENT_QUOTES);
};
};
// Burn after reading
$__langfunc();
unset($__langfunc);