forked from rebillar/site-accueil-insa
282 lines
7.8 KiB
PHP
282 lines
7.8 KiB
PHP
<?php
|
|
/**
|
|
* Matomo - free/libre analytics platform
|
|
*
|
|
* @link https://matomo.org
|
|
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
|
*/
|
|
|
|
namespace Piwik\Translation;
|
|
|
|
use Piwik\Config;
|
|
use Piwik\Piwik;
|
|
use Piwik\Translation\Loader\LoaderInterface;
|
|
|
|
/**
|
|
* Translates messages.
|
|
*
|
|
* @api
|
|
*/
|
|
class Translator
|
|
{
|
|
/**
|
|
* Contains the translated messages, indexed by the language name.
|
|
*
|
|
* @var array
|
|
*/
|
|
private $translations = array();
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $currentLanguage;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $fallback = 'en';
|
|
|
|
/**
|
|
* Directories containing the translations to load.
|
|
*
|
|
* @var string[]
|
|
*/
|
|
private $directories = array();
|
|
|
|
/**
|
|
* @var LoaderInterface
|
|
*/
|
|
private $loader;
|
|
|
|
public function __construct(LoaderInterface $loader, array $directories = null)
|
|
{
|
|
$this->loader = $loader;
|
|
$this->currentLanguage = $this->getDefaultLanguage();
|
|
|
|
if ($directories === null) {
|
|
// TODO should be moved out of this class
|
|
$directories = array(PIWIK_INCLUDE_PATH . '/lang');
|
|
}
|
|
$this->directories = $directories;
|
|
}
|
|
|
|
/**
|
|
* Clean a string that may contain HTML special chars, single/double quotes, HTML entities, leading/trailing whitespace
|
|
*
|
|
* @param string $s
|
|
* @return string
|
|
*/
|
|
public static function clean($s)
|
|
{
|
|
return html_entity_decode(trim($s), ENT_QUOTES, 'UTF-8');
|
|
}
|
|
|
|
/**
|
|
* Returns an internationalized string using a translation ID. If a translation
|
|
* cannot be found for the ID, the ID is returned.
|
|
*
|
|
* @param string $translationId Translation ID, eg, `General_Date`.
|
|
* @param array|string|int $args `sprintf` arguments to be applied to the internationalized
|
|
* string.
|
|
* @param string|null $language Optionally force the language.
|
|
* @return string The translated string or `$translationId`.
|
|
* @api
|
|
*/
|
|
public function translate($translationId, $args = array(), $language = null)
|
|
{
|
|
$args = is_array($args) ? $args : array($args);
|
|
$translationId = $translationId ?? '';
|
|
|
|
if (strpos($translationId, "_") !== false) {
|
|
list($plugin, $key) = explode("_", $translationId, 2);
|
|
$language = is_string($language) ? $language : $this->currentLanguage;
|
|
|
|
$translationId = $this->getTranslation($translationId, $language, $plugin, $key);
|
|
}
|
|
|
|
if (count($args) == 0) {
|
|
return str_replace('%%', '%', $translationId);
|
|
}
|
|
return vsprintf($translationId, $args);
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getCurrentLanguage()
|
|
{
|
|
return $this->currentLanguage;
|
|
}
|
|
|
|
/**
|
|
* @param string $language
|
|
*/
|
|
public function setCurrentLanguage($language)
|
|
{
|
|
if (!$language) {
|
|
$language = $this->getDefaultLanguage();
|
|
}
|
|
|
|
$this->currentLanguage = $language;
|
|
}
|
|
|
|
/**
|
|
* @return string The default configured language.
|
|
*/
|
|
public function getDefaultLanguage()
|
|
{
|
|
$generalSection = Config::getInstance()->General;
|
|
|
|
// the config may not be available (for example, during environment setup), so we default to 'en'
|
|
// if the config cannot be found.
|
|
return @$generalSection['default_language'] ?: 'en';
|
|
}
|
|
|
|
/**
|
|
* Generate javascript translations array
|
|
*/
|
|
public function getJavascriptTranslations()
|
|
{
|
|
$clientSideTranslations = array();
|
|
foreach ($this->getClientSideTranslationKeys() as $id) {
|
|
list($plugin, $key) = explode('_', $id, 2);
|
|
$clientSideTranslations[$id] = $this->getTranslation($id, $this->currentLanguage, $plugin, $key);
|
|
}
|
|
|
|
$js = 'var translations = ' . json_encode($clientSideTranslations) . ';';
|
|
$js .= "\n" . 'if (typeof(piwik_translations) == \'undefined\') { var piwik_translations = new Object; }' .
|
|
'for(var i in translations) { piwik_translations[i] = translations[i];} ';
|
|
return $js;
|
|
}
|
|
|
|
/**
|
|
* Returns the list of client side translations by key. These translations will be outputted
|
|
* to the translation JavaScript.
|
|
*/
|
|
private function getClientSideTranslationKeys()
|
|
{
|
|
$result = array();
|
|
|
|
/**
|
|
* Triggered before generating the JavaScript code that allows i18n strings to be used
|
|
* in the browser.
|
|
*
|
|
* Plugins should subscribe to this event to specify which translations
|
|
* should be available to JavaScript.
|
|
*
|
|
* Event handlers should add whole translation keys, ie, keys that include the plugin name.
|
|
*
|
|
* **Example**
|
|
*
|
|
* public function getClientSideTranslationKeys(&$result)
|
|
* {
|
|
* $result[] = "MyPlugin_MyTranslation";
|
|
* }
|
|
*
|
|
* @param array &$result The whole list of client side translation keys.
|
|
*/
|
|
Piwik::postEvent('Translate.getClientSideTranslationKeys', array(&$result));
|
|
|
|
$result = array_unique($result);
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Add a directory containing translations.
|
|
*
|
|
* @param string $directory
|
|
*/
|
|
public function addDirectory($directory)
|
|
{
|
|
if (isset($this->directories[$directory])) {
|
|
return;
|
|
}
|
|
// index by name to avoid duplicates
|
|
$this->directories[$directory] = $directory;
|
|
|
|
// clear currently loaded translations to force reloading them
|
|
$this->translations = array();
|
|
}
|
|
|
|
/**
|
|
* Should be used by tests only, and this method should eventually be removed.
|
|
*/
|
|
public function reset()
|
|
{
|
|
$this->currentLanguage = $this->getDefaultLanguage();
|
|
$this->directories = array(PIWIK_INCLUDE_PATH . '/lang');
|
|
$this->translations = array();
|
|
}
|
|
|
|
/**
|
|
* @param string $translation
|
|
* @return null|string
|
|
*/
|
|
public function findTranslationKeyForTranslation($translation)
|
|
{
|
|
foreach ($this->getAllTranslations() as $key => $translations) {
|
|
$possibleKey = array_search($translation, $translations);
|
|
if (!empty($possibleKey)) {
|
|
return $key . '_' . $possibleKey;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Returns all the translation messages loaded.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getAllTranslations()
|
|
{
|
|
$this->loadTranslations($this->currentLanguage);
|
|
|
|
if (!isset($this->translations[$this->currentLanguage])) {
|
|
return array();
|
|
}
|
|
|
|
return $this->translations[$this->currentLanguage];
|
|
}
|
|
|
|
private function getTranslation($id, $lang, $plugin, $key)
|
|
{
|
|
$this->loadTranslations($lang);
|
|
|
|
if (isset($this->translations[$lang][$plugin])
|
|
&& isset($this->translations[$lang][$plugin][$key])
|
|
) {
|
|
return $this->translations[$lang][$plugin][$key];
|
|
}
|
|
|
|
/**
|
|
* Fallback for keys moved to new Intl plugin to avoid untranslated string in non core plugins
|
|
* @todo remove this in Piwik 3.0
|
|
*/
|
|
if ($plugin != 'Intl') {
|
|
if (isset($this->translations[$lang]['Intl'])
|
|
&& isset($this->translations[$lang]['Intl'][$key])
|
|
) {
|
|
return $this->translations[$lang]['Intl'][$key];
|
|
}
|
|
}
|
|
|
|
// fallback
|
|
if ($lang !== $this->fallback) {
|
|
return $this->getTranslation($id, $this->fallback, $plugin, $key);
|
|
}
|
|
|
|
return $id;
|
|
}
|
|
|
|
private function loadTranslations($language)
|
|
{
|
|
if (empty($language) || isset($this->translations[$language])) {
|
|
return;
|
|
}
|
|
|
|
$this->translations[$language] = $this->loader->load($language, $this->directories);
|
|
}
|
|
}
|