40+ translations!). * This is mostly useful to developers who integrate Piwik API results in their own application. * * You can also request the default language to load for a user via "getLanguageForUser", * or update it via "setLanguageForUser". * * @package LanguagesManager */ class API { static private $instance = null; /** * @return \Piwik\Plugins\LanguagesManager\API */ static public function getInstance() { if (self::$instance == null) { self::$instance = new self; } return self::$instance; } protected $availableLanguageNames = null; protected $languageNames = null; /** * Returns true if specified language is available * * @param string $languageCode * @return bool true if language available; false otherwise */ public function isLanguageAvailable($languageCode) { return $languageCode !== false && Filesystem::isValidFilename($languageCode) && in_array($languageCode, $this->getAvailableLanguages()); } /** * Return array of available languages * * @return array Arry of strings, each containing its ISO language code */ public function getAvailableLanguages() { if (!is_null($this->languageNames)) { return $this->languageNames; } $path = PIWIK_INCLUDE_PATH . "/lang/"; $languages = _glob($path . "*.json"); $pathLength = strlen($path); $languageNames = array(); if ($languages) { foreach ($languages as $language) { $languageNames[] = substr($language, $pathLength, -strlen('.json')); } } $this->languageNames = $languageNames; return $languageNames; } /** * Return information on translations (code, language, % translated, etc) * * @return array Array of arrays */ public function getAvailableLanguagesInfo() { $data = file_get_contents(PIWIK_INCLUDE_PATH . '/lang/en.json'); $englishTranslation = json_decode($data, true); $filenames = $this->getAvailableLanguages(); $languagesInfo = array(); foreach ($filenames as $filename) { $data = file_get_contents(sprintf('%s/lang/%s.json', PIWIK_INCLUDE_PATH, $filename)); $translations = json_decode($data, true); $intersect = function($array, $array2) { $res = $array; foreach($array as $module => $keys) { if(!isset($array2[$module])) { unset($res[$module]); } else { $res[$module] = array_intersect_key($res[$module], array_filter($array2[$module], 'strlen')); } } return $res; }; $translationStringsDone = $intersect($englishTranslation, $translations); $percentageComplete = count($translationStringsDone, COUNT_RECURSIVE) / count($englishTranslation, COUNT_RECURSIVE); $percentageComplete = round(100 * $percentageComplete, 0); $languageInfo = array('code' => $filename, 'name' => $translations['General']['OriginalLanguageName'], 'english_name' => $translations['General']['EnglishLanguageName'], 'translators' => $translations['General']['TranslatorName'], 'translators_email' => $translations['General']['TranslatorEmail'], 'percentage_complete' => $percentageComplete . '%', ); $languagesInfo[] = $languageInfo; } return $languagesInfo; } /** * Return array of available languages * * @return array Arry of array, each containing its ISO language code and name of the language */ public function getAvailableLanguageNames() { if (!is_null($this->availableLanguageNames)) { return $this->availableLanguageNames; } $filenames = $this->getAvailableLanguages(); $languagesInfo = array(); foreach ($filenames as $filename) { $data = file_get_contents(PIWIK_INCLUDE_PATH . "/lang/$filename.json"); $translations = json_decode($data, true); $languagesInfo[] = array( 'code' => $filename, 'name' => $translations['General']['OriginalLanguageName'], 'english_name' => $translations['General']['EnglishLanguageName'] ); } $this->availableLanguageNames = $languagesInfo; return $this->availableLanguageNames; } /** * Returns translation strings by language * * @param string $languageCode ISO language code * @return array|false Array of arrays, each containing 'label' (translation index) and 'value' (translated string); false if language unavailable */ public function getTranslationsForLanguage($languageCode) { if (!$this->isLanguageAvailable($languageCode)) { return false; } $data = file_get_contents(PIWIK_INCLUDE_PATH . "/lang/$languageCode.json"); $translations = json_decode($data, true); $languageInfo = array(); foreach ($translations as $module => $keys) { foreach($keys as $key => $value) { $languageInfo[] = array( 'label' => sprintf("%s_%s", $module, $key), 'value' => $value ); } } return $languageInfo; } /** * Returns translation strings by language for given plugin * * @param string $pluginName name of plugin * @param string $languageCode ISO language code * @return array|false Array of arrays, each containing 'label' (translation index) and 'value' (translated string); false if language unavailable * * @ignore */ public function getPluginTranslationsForLanguage($pluginName, $languageCode) { if (!$this->isLanguageAvailable($languageCode)) { return false; } $languageFile = PIWIK_INCLUDE_PATH . "/plugins/$pluginName/lang/$languageCode.json"; if (!file_exists($languageFile)) { return false; } $data = file_get_contents($languageFile); $translations = json_decode($data, true); $languageInfo = array(); foreach ($translations as $module => $keys) { foreach($keys as $key => $value) { $languageInfo[] = array( 'label' => sprintf("%s_%s", $module, $key), 'value' => $value ); } } return $languageInfo; } /** * Returns the language for the user * * @param string $login * @return string */ public function getLanguageForUser($login) { Piwik::checkUserIsSuperUserOrTheUser($login); Piwik::checkUserIsNotAnonymous(); return Db::fetchOne('SELECT language FROM ' . Common::prefixTable('user_language') . ' WHERE login = ? ', array($login)); } /** * Sets the language for the user * * @param string $login * @param string $languageCode * @return bool */ public function setLanguageForUser($login, $languageCode) { Piwik::checkUserIsSuperUserOrTheUser($login); Piwik::checkUserIsNotAnonymous(); if (!$this->isLanguageAvailable($languageCode)) { return false; } $paramsBind = array($login, $languageCode, $languageCode); Db::query('INSERT INTO ' . Common::prefixTable('user_language') . ' (login, language) VALUES (?,?) ON DUPLICATE KEY UPDATE language=?', $paramsBind); } }