PDF rausgenommen
This commit is contained in:
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Translation\Loader;
|
||||
|
||||
/**
|
||||
* Loads a pseudo-language for developers where translation are equal to translation ids.
|
||||
*/
|
||||
class DevelopmentLoader implements LoaderInterface
|
||||
{
|
||||
const LANGUAGE_ID = 'dev';
|
||||
|
||||
/**
|
||||
* Decorated loader.
|
||||
*
|
||||
* @var LoaderInterface
|
||||
*/
|
||||
private $loader;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $fallbackLanguage = 'en';
|
||||
|
||||
/**
|
||||
* @param LoaderInterface $loader Decorate another loader to add the pseudo-language.
|
||||
*/
|
||||
public function __construct(LoaderInterface $loader)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($language, array $directories)
|
||||
{
|
||||
if ($language !== self::LANGUAGE_ID) {
|
||||
return $this->loader->load($language, $directories);
|
||||
}
|
||||
|
||||
return $this->getDevelopmentTranslations($directories);
|
||||
}
|
||||
|
||||
private function getDevelopmentTranslations(array $directories)
|
||||
{
|
||||
$fallbackTranslations = $this->loader->load($this->fallbackLanguage, $directories);
|
||||
|
||||
$translations = array();
|
||||
|
||||
foreach ($fallbackTranslations as $section => $sectionFallbackTranslations) {
|
||||
$translationIds = array_keys($sectionFallbackTranslations);
|
||||
$sectionTranslations = $this->prefixTranslationsWithSection($section, $translationIds);
|
||||
|
||||
$translations[$section] = array_combine($translationIds, $sectionTranslations);
|
||||
}
|
||||
|
||||
return $translations;
|
||||
}
|
||||
|
||||
private function prefixTranslationsWithSection($section, $translationIds)
|
||||
{
|
||||
return array_map(function ($translation) use ($section) {
|
||||
return $section . '_' . $translation;
|
||||
}, $translationIds);
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Translation\Loader;
|
||||
|
||||
use Piwik\Common;
|
||||
|
||||
/**
|
||||
* Loads translations from JSON files.
|
||||
*/
|
||||
class JsonFileLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($language, array $directories)
|
||||
{
|
||||
if (empty($language)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$translations = array();
|
||||
|
||||
foreach ($directories as $directory) {
|
||||
$filename = $directory . '/' . $language . '.json';
|
||||
|
||||
if (! file_exists($filename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$translations = array_replace_recursive(
|
||||
$translations,
|
||||
$this->loadFile($filename)
|
||||
);
|
||||
}
|
||||
|
||||
return $translations;
|
||||
}
|
||||
|
||||
private function loadFile($filename)
|
||||
{
|
||||
$data = file_get_contents($filename);
|
||||
$translations = json_decode($data, true);
|
||||
|
||||
if (is_null($translations) && Common::hasJsonErrorOccurred()) {
|
||||
throw new \Exception(sprintf(
|
||||
'Not able to load translation file %s: %s',
|
||||
$filename,
|
||||
Common::getLastJsonError()
|
||||
));
|
||||
}
|
||||
|
||||
if (!is_array($translations)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $translations;
|
||||
}
|
||||
}
|
65
msd2/tracking/piwik/core/Translation/Loader/LoaderCache.php
Normal file
65
msd2/tracking/piwik/core/Translation/Loader/LoaderCache.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Translation\Loader;
|
||||
|
||||
use Piwik\Cache;
|
||||
|
||||
/**
|
||||
* Caches the translations loaded by another loader.
|
||||
*/
|
||||
class LoaderCache implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* @var LoaderInterface
|
||||
*/
|
||||
private $loader;
|
||||
|
||||
/**
|
||||
* @var Cache\Lazy
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
public function __construct(LoaderInterface $loader, Cache\Lazy $cache)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($language, array $directories)
|
||||
{
|
||||
if (empty($language)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$cacheKey = $this->getCacheKey($language, $directories);
|
||||
|
||||
$translations = $this->cache->fetch($cacheKey);
|
||||
|
||||
if (empty($translations) || !is_array($translations)) {
|
||||
$translations = $this->loader->load($language, $directories);
|
||||
|
||||
$this->cache->save($cacheKey, $translations, 43200); // ttl=12hours
|
||||
}
|
||||
|
||||
return $translations;
|
||||
}
|
||||
|
||||
private function getCacheKey($language, array $directories)
|
||||
{
|
||||
$cacheKey = 'Translations-' . $language . '-';
|
||||
|
||||
// in case loaded plugins change (ie Tests vs Tracker vs UI etc)
|
||||
$cacheKey .= sha1(implode('', $directories));
|
||||
|
||||
return $cacheKey;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Translation\Loader;
|
||||
|
||||
/**
|
||||
* Loads translations.
|
||||
*/
|
||||
interface LoaderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $language
|
||||
* @param mixed[] $directories Directories containing translation files.
|
||||
* @throws \Exception The translation file was not found
|
||||
* @return string[] Translations.
|
||||
*/
|
||||
public function load($language, array $directories);
|
||||
}
|
148
msd2/tracking/piwik/core/Translation/Transifex/API.php
Normal file
148
msd2/tracking/piwik/core/Translation/Transifex/API.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Translation\Transifex;
|
||||
|
||||
use Exception;
|
||||
use Piwik\Cache;
|
||||
use Piwik\Exception\AuthenticationFailedException;
|
||||
use Piwik\Http;
|
||||
|
||||
class API
|
||||
{
|
||||
protected $apiUrl = 'https://www.transifex.com/api/2/';
|
||||
protected $username = '';
|
||||
protected $password = '';
|
||||
protected $projectSlug = '';
|
||||
|
||||
public function __construct($username, $password, $project = 'matomo')
|
||||
{
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->projectSlug = $project;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all resources available on Transifex project
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAvailableResources()
|
||||
{
|
||||
$cache = Cache::getTransientCache();
|
||||
$cacheId = 'transifex_resources_' . $this->projectSlug;
|
||||
$resources = $cache->fetch($cacheId);
|
||||
|
||||
if (empty($resources)) {
|
||||
$apiPath = 'project/' . $this->projectSlug . '/resources';
|
||||
$resources = $this->getApiResults($apiPath);
|
||||
$cache->save($cacheId, $resources);
|
||||
}
|
||||
|
||||
return $resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given resource exists in Transifex project
|
||||
*
|
||||
* @param string $resource
|
||||
* @return bool
|
||||
*/
|
||||
public function resourceExists($resource)
|
||||
{
|
||||
$resources = $this->getAvailableResources();
|
||||
foreach ($resources as $res) {
|
||||
if ($res->slug == $resource) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all language codes the transifex project is available for
|
||||
*
|
||||
* @return array
|
||||
* @throws AuthenticationFailedException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getAvailableLanguageCodes()
|
||||
{
|
||||
$cache = Cache::getTransientCache();
|
||||
$cacheId = 'transifex_languagescodes_' . $this->projectSlug;
|
||||
$languageCodes = $cache->fetch($cacheId);
|
||||
|
||||
if (empty($languageCodes)) {
|
||||
$apiData = $this->getApiResults('project/' . $this->projectSlug . '/languages');
|
||||
foreach ($apiData as $languageData) {
|
||||
$languageCodes[] = $languageData->language_code;
|
||||
}
|
||||
$cache->save($cacheId, $languageCodes);
|
||||
}
|
||||
return $languageCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns statistic data for the given resource
|
||||
*
|
||||
* @param string $resource e.g. piwik-base, piwik-plugin-api,...
|
||||
* @return array
|
||||
* @throws AuthenticationFailedException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getStatistics($resource)
|
||||
{
|
||||
return $this->getApiResults('project/' . $this->projectSlug . '/resource/' . $resource . '/stats/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the translations for the given resource and language
|
||||
*
|
||||
* @param string $resource e.g. piwik-base, piwik-plugin-api,...
|
||||
* @param string $language e.g. de, pt_BR, hy,...
|
||||
* @param bool $raw if true plain response wil be returned (unparsed json)
|
||||
* @return mixed
|
||||
* @throws AuthenticationFailedException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getTranslations($resource, $language, $raw = false)
|
||||
{
|
||||
if ($this->resourceExists($resource)) {
|
||||
$apiPath = 'project/' . $this->projectSlug . '/resource/' . $resource . '/translation/' . $language . '/?mode=onlytranslated&file';
|
||||
return $this->getApiResults($apiPath, $raw);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns response for API request with given path
|
||||
*
|
||||
* @param $apiPath
|
||||
* @param bool $raw
|
||||
* @return mixed
|
||||
* @throws AuthenticationFailedException
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getApiResults($apiPath, $raw = false)
|
||||
{
|
||||
$apiUrl = $this->apiUrl . $apiPath;
|
||||
|
||||
$response = Http::sendHttpRequest($apiUrl, 1000, null, null, 5, false, false, true, 'GET', $this->username, $this->password);
|
||||
|
||||
$httpStatus = $response['status'];
|
||||
$response = $response['data'];
|
||||
|
||||
if ($httpStatus == 401) {
|
||||
throw new AuthenticationFailedException();
|
||||
} elseif ($httpStatus != 200) {
|
||||
throw new Exception('Error while getting API results', $httpStatus);
|
||||
}
|
||||
|
||||
return $raw ? $response : json_decode($response);
|
||||
}
|
||||
}
|
271
msd2/tracking/piwik/core/Translation/Translator.php
Normal file
271
msd2/tracking/piwik/core/Translation/Translator.php
Normal file
@ -0,0 +1,271 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.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\Plugin;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user