First release of 2.0! :D
This commit is contained in:
201
src/private/php/Utils/Language/LanguageUtils.php
Normal file
201
src/private/php/Utils/Language/LanguageUtils.php
Normal file
@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
namespace Wruczek\TSWebsite\Utils\Language;
|
||||
|
||||
use function htmlspecialchars;
|
||||
use Wruczek\PhpFileCache\PhpFileCache;
|
||||
use Wruczek\TSWebsite\Utils\DatabaseUtils;
|
||||
use Wruczek\TSWebsite\Utils\SingletonTait;
|
||||
|
||||
/**
|
||||
* Class LanguageUtils
|
||||
* @package Wruczek\TSWebsite\Utils
|
||||
* @author Wruczek 2017
|
||||
*/
|
||||
class LanguageUtils {
|
||||
|
||||
use SingletonTait;
|
||||
|
||||
private $cache;
|
||||
private $languages;
|
||||
|
||||
/**
|
||||
* Short function for translate
|
||||
*/
|
||||
public static function tl($identifier, $args = []) {
|
||||
return self::i()->translate($identifier, $args);
|
||||
}
|
||||
|
||||
private function __construct() {
|
||||
$this->cache = new PhpFileCache(__CACHE_DIR, "translations");
|
||||
|
||||
$this->languages = $this->cache->refreshIfExpired("languages", function () {
|
||||
return $this->refreshLanguageCache(false);
|
||||
}, 300);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns language by its ID
|
||||
* @param $languageId int Language ID
|
||||
* @return Language|boolean returns Language when found, false otherwise
|
||||
*/
|
||||
public function getLanguageById($languageId) {
|
||||
foreach ($this->getLanguages() as $lang) {
|
||||
if($lang->getLanguageId() === $languageId)
|
||||
return $lang;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns language by its Language Code
|
||||
* @param $languageCode string Language Code
|
||||
* @return Language|boolean returns Language when found, false otherwise
|
||||
*/
|
||||
public function getLanguageByCode($languageCode) {
|
||||
foreach ($this->getLanguages() as $lang) {
|
||||
if(strcasecmp($lang->getLanguageCode(), $languageCode) === 0)
|
||||
return $lang;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all available languages
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getLanguages() {
|
||||
return $this->languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default language
|
||||
* @return Language default language
|
||||
*/
|
||||
public function getDefaultLanguage() {
|
||||
foreach ($this->getLanguages() as $lang) {
|
||||
if($lang->isDefault())
|
||||
return $lang;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets language as default
|
||||
* @param $language Language
|
||||
* @return boolean true on success, false otherwise
|
||||
*/
|
||||
public function setDefaultLanguage($language) {
|
||||
$db = DatabaseUtils::i()->getDb();
|
||||
|
||||
// set all languages as non-default, if this succeeds...
|
||||
if($db->update("languages", ["isdefault" => 0])) {
|
||||
// ...then set only this language to default
|
||||
$success = $db->update("languages", ["isdefault" => 1], ["langid", $language->getLanguageId()]);
|
||||
$this->refreshLanguageCache();
|
||||
return $success;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tried to determine user language and returns it
|
||||
* @return Language user language if determined, null otherwise
|
||||
*/
|
||||
public function detectUserLanguage() {
|
||||
if (isset($_COOKIE["tswebsite_language"])) { // check cookie
|
||||
$langcode = $_COOKIE["tswebsite_language"];
|
||||
} else if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) { // check http headers
|
||||
$langcode = substr($_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 2);
|
||||
}
|
||||
|
||||
// if language with that code exists, return it
|
||||
if(!empty($langcode) && ($lang = $this->getLanguageByCode($langcode)))
|
||||
return $lang;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes language cache, loads and returns new data
|
||||
* @param bool $updateCache true if the file cache should also be updated
|
||||
* @return array
|
||||
*/
|
||||
public function refreshLanguageCache($updateCache = true) {
|
||||
$db = DatabaseUtils::i()->getDb();
|
||||
$data = $db->select("languages", ["langid", "englishname", "nativename", "langcode", "isdefault"]);
|
||||
|
||||
$langs = [];
|
||||
|
||||
foreach ($data as $lang) {
|
||||
$langid = $lang["langid"];
|
||||
$englishname = $lang["englishname"];
|
||||
$nativename = $lang["nativename"];
|
||||
$langcode = $lang["langcode"];
|
||||
$isdefault = $lang["isdefault"];
|
||||
|
||||
$strings = $db->select("translations", ["identifier", "value", "comment"], ["langid" => $langid]);
|
||||
|
||||
$languageItems = [];
|
||||
|
||||
foreach ($strings as $str)
|
||||
$languageItems[] = new LanguageItem($str["identifier"], $str["value"], $str["comment"]);
|
||||
|
||||
$langs[] = new Language($langid, $englishname, $nativename, $langcode, $isdefault, $languageItems);
|
||||
}
|
||||
|
||||
$this->languages = $langs;
|
||||
|
||||
if($updateCache)
|
||||
$this->cache->store("languages", $langs, 300);
|
||||
|
||||
return $langs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns translated text. If identifier is not found in the current
|
||||
* language, it tries to get it from the default language.
|
||||
* User language is determined with getDefaultLanguage() function.
|
||||
* @param $identifier string Translation identifier
|
||||
* @param array $args Arguments that will replace placeholders
|
||||
* @return string Translated text
|
||||
* @throws \Exception When default site or user language cannot
|
||||
* be found, and/or if $identifier is not found
|
||||
*/
|
||||
public function translate($identifier, $args = []) {
|
||||
if (!is_array($args)) {
|
||||
$args = [$args];
|
||||
}
|
||||
|
||||
$defaultlang = $this->getDefaultLanguage();
|
||||
$lang = $this->getLanguageById(@$_SESSION["userlanguageid"]);
|
||||
|
||||
if(!$lang && !$defaultlang)
|
||||
throw new \Exception("Cannot get user or default language");
|
||||
|
||||
$item = $lang->getLanguageItem($identifier);
|
||||
|
||||
if(!$item)
|
||||
$item = $defaultlang->getLanguageItem($identifier);
|
||||
|
||||
if(!$item)
|
||||
throw new \Exception("Cannot get translation for $identifier");
|
||||
|
||||
$val = $item->getValue();
|
||||
|
||||
// Replace placeholders with values from $args
|
||||
foreach ($args as $i => $iValue) {
|
||||
// Prevent argument placeholder injection
|
||||
$iValue = str_replace(["{", "}"], ["{", "}"], $iValue);
|
||||
|
||||
$val = str_ireplace('{' . $i . '}', $iValue, $val);
|
||||
}
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user