update Piwik to version 2.16 (fixes #91)

This commit is contained in:
oliver 2016-04-10 18:55:57 +02:00
commit d885a4baa9
5833 changed files with 418860 additions and 226988 deletions

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -9,9 +9,7 @@
namespace Piwik\Plugins\LanguagesManager\Commands;
use Piwik\Plugin\ConsoleCommand;
use Piwik\Plugins\LanguagesManager\API;
use Piwik\Plugins\LanguagesManager\Commands\Update;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@ -19,14 +17,14 @@ use Symfony\Component\Console\Output\OutputInterface;
/**
*/
class CreatePull extends ConsoleCommand
class CreatePull extends TranslationBase
{
protected function configure()
{
$this->setName('translations:createpull')
->setDescription('Updates translation files')
->addOption('username', 'u', InputOption::VALUE_OPTIONAL, 'oTrance username')
->addOption('password', 'p', InputOption::VALUE_OPTIONAL, 'oTrance password')
->addOption('username', 'u', InputOption::VALUE_OPTIONAL, 'Transifex username')
->addOption('password', 'p', InputOption::VALUE_OPTIONAL, 'Transifex password')
->addOption('plugin', 'P', InputOption::VALUE_OPTIONAL, 'optional name of plugin to update translations for');
}
@ -51,7 +49,7 @@ class CreatePull extends ConsoleCommand
chdir(PIWIK_DOCUMENT_ROOT);
shell_exec('
git checkout master > /dev/null 2>&1
git checkout -f master > /dev/null 2>&1
git pull > /dev/null 2>&1
git submodule init > /dev/null 2>&1
git submodule update > /dev/null 2>&1
@ -77,7 +75,7 @@ class CreatePull extends ConsoleCommand
// switch to branch and update it to latest master
shell_exec('
git checkout translationupdates > /dev/null 2>&1
git checkout -f translationupdates > /dev/null 2>&1
git merge master > /dev/null 2>&1
git push origin translationupdates > /dev/null 2>&1
');
@ -97,7 +95,7 @@ class CreatePull extends ConsoleCommand
shell_exec('git add lang/. > /dev/null 2>&1');
if (empty($plugin)) {
foreach (Update::getPluginsInCore() AS $pluginName) {
foreach (Update::getPluginsInCore() as $pluginName) {
shell_exec(sprintf('git add plugins/%s/lang/. > /dev/null 2>&1', $pluginName));
}
}
@ -115,7 +113,7 @@ class CreatePull extends ConsoleCommand
$stats = shell_exec('git diff --numstat HEAD');
preg_match_all('/([0-9]+)\t([0-9]+)\t[a-zA-Z\/]*lang\/([a-z]{2,3})\.json/', $stats, $lineChanges);
preg_match_all('/([0-9]+)\t([0-9]+)\t[a-zA-Z\/]*lang\/([a-z]{2,3}(?:-[a-z]{2,3})?)\.json/', $stats, $lineChanges);
$addedLinesSum = 0;
if (!empty($lineChanges[1])) {
@ -123,18 +121,19 @@ class CreatePull extends ConsoleCommand
}
$linesSumByLang = array();
for($i=0; $i<count($lineChanges[0]); $i++) {
$lineChangesCount = count($lineChanges[0]);
for ($i = 0; $i < $lineChangesCount; $i++) {
@$linesSumByLang[$lineChanges[3][$i]] += $lineChanges[1][$i];
}
preg_match_all('/M [a-zA-Z\/]*lang\/([a-z]{2,3})\.json/', $changes, $modifiedFiles);
preg_match_all('/A [a-zA-Z\/]*lang\/([a-z]{2,3})\.json/', $changes, $addedFiles);
preg_match_all('/M [a-zA-Z\/]*lang\/([a-z]{2,3}(?:-[a-z]{2,3})?)\.json/', $changes, $modifiedFiles);
preg_match_all('/A [a-zA-Z\/]*lang\/([a-z]{2,3}(?:-[a-z]{2,3})?)\.json/', $changes, $addedFiles);
$messages = array();
$languageCodesTouched = array();
if (!empty($addedFiles[1])) {
foreach ($addedFiles[1] AS $addedFile) {
foreach ($addedFiles[1] as $addedFile) {
$languageInfo = $this->getLanguageInfoByIsoCode($addedFile);
$messages[$addedFile] = sprintf('- Added %s (%s changes / %s translated)\n', $languageInfo['english_name'], $linesSumByLang[$addedFile], $languageInfo['percentage_complete']);
}
@ -142,11 +141,11 @@ class CreatePull extends ConsoleCommand
}
if (!empty($modifiedFiles[1])) {
foreach ($modifiedFiles[1] AS $modifiedFile) {
foreach ($modifiedFiles[1] as $modifiedFile) {
$languageInfo = $this->getLanguageInfoByIsoCode($modifiedFile);
$messages[$modifiedFile] = sprintf('- Updated %s (%s changes / %s translated)\n', $languageInfo['english_name'], $linesSumByLang[$modifiedFile], $languageInfo['percentage_complete']);
}
$languageCodesTouched = $modifiedFiles[1];
$languageCodesTouched = array_merge($languageCodesTouched, $modifiedFiles[1]);
}
$message = implode('', $messages);
@ -160,7 +159,7 @@ class CreatePull extends ConsoleCommand
implode(', ', $languageCodesTouched)
);
shell_exec('git commit -m "language update ${pluginName} refs #3430"');
shell_exec('git commit -m "language update ${pluginName}"');
shell_exec('git push');
shell_exec('git checkout master > /dev/null 2>&1');
@ -170,7 +169,7 @@ class CreatePull extends ConsoleCommand
private function getLanguageInfoByIsoCode($isoCode)
{
$languages = API::getInstance()->getAvailableLanguagesInfo();
foreach ($languages AS $languageInfo) {
foreach ($languages as $languageInfo) {
if ($languageInfo['code'] == $isoCode) {
return $languageInfo;
}

View file

@ -1,172 +0,0 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\LanguagesManager\Commands;
use Piwik\Plugin\ConsoleCommand;
use Piwik\Unzip;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
*/
class FetchFromOTrance extends ConsoleCommand
{
const DOWNLOADPATH = 'tmp/oTrance';
protected function configure()
{
$this->setName('translations:fetch')
->setDescription('Fetches translations files from oTrance to '.self::DOWNLOADPATH)
->addOption('username', 'u', InputOption::VALUE_OPTIONAL, 'oTrance username')
->addOption('password', 'p', InputOption::VALUE_OPTIONAL, 'oTrance password');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln("Starting to fetch latest language pack");
$dialog = $this->getHelperSet()->get('dialog');
$cookieFile = self::getDownloadPath() . DIRECTORY_SEPARATOR . 'cookie.txt';
@unlink($cookieFile);
$username = $input->getOption('username');
$password = $input->getOption('password');
while (!file_exists($cookieFile)) {
if (empty($username)) {
$username = $dialog->ask($output, 'What is your oTrance username? ');
}
if (empty($password)) {
$password = $dialog->askHiddenResponse($output, 'What is your oTrance password? ');
}
// send login request to oTrance and save the login cookie
$curl = curl_init('http://translations.piwik.org/public/index/login');
curl_setopt($curl, CURLOPT_POSTFIELDS, sprintf("user=%s&pass=%s&autologin=1", $username, $password));
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookieFile);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_exec($curl);
curl_close($curl);
if (strpos(file_get_contents($cookieFile), 'oTranCe_autologin') !== false) {
break;
}
$username = null;
$password = null;
@unlink($cookieFile);
$output->writeln("Invalid oTrance credentials. Please try again...");
}
// send request to create a new download package using the cookie file
$createNewPackage = true;
if ($input->isInteractive()) {
$createNewPackage = $dialog->askConfirmation($output, 'Shall we create a new language pack? ');
}
if ($createNewPackage) {
$curl = curl_init('http://translations.piwik.org/public/export/update.all');
curl_setopt($curl, CURLOPT_COOKIEFILE, $cookieFile);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_exec($curl);
curl_close($curl);
}
// request download page to search for available packages
$curl = curl_init('http://translations.piwik.org/public/downloads/');
curl_setopt($curl, CURLOPT_COOKIEFILE, $cookieFile);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
preg_match_all('/language\_pack\-[0-9]{8}\-[0-9]{6}\.tar\.gz/i', $response, $matches);
if (empty($matches[0])) {
$output->writeln("No packages found for download. Please try again.");
return;
}
$downloadPackage = array_shift($matches[0]);
$continueWithPackage = true;
if ($input->isInteractive()) {
$continueWithPackage = $dialog->askConfirmation($output, "Found language pack $downloadPackage. Proceed? ");
}
if (!$continueWithPackage) {
$output->writeln('Aborted.');
return;
}
// download language pack
$packageHandle = fopen(self::getDownloadPath() . DIRECTORY_SEPARATOR . 'language_pack.tar.gz', 'w');
$curl = curl_init('http://translations.piwik.org/public/downloads/download/file/'.$downloadPackage);
curl_setopt($curl, CURLOPT_COOKIEFILE, self::getDownloadPath() . DIRECTORY_SEPARATOR . 'cookie.txt');
curl_setopt($curl, CURLOPT_FILE, $packageHandle);
curl_exec($curl);
curl_close($curl);
@unlink($cookieFile);
$output->writeln("Extracting package...");
$unzipper = Unzip::factory('tar.gz', self::getDownloadPath() . DIRECTORY_SEPARATOR . 'language_pack.tar.gz');
$unzipper->extract(self::getDownloadPath());
@unlink(self::getDownloadPath() . DIRECTORY_SEPARATOR . 'en.php');
@unlink(self::getDownloadPath() . DIRECTORY_SEPARATOR . 'language_pack.tar.gz');
$filesToConvert = _glob(self::getDownloadPath() . DIRECTORY_SEPARATOR . '*.php');
$output->writeln("Converting downloaded php files to json");
$progress = $this->getHelperSet()->get('progress');
$progress->start($output, count($filesToConvert));
foreach ($filesToConvert AS $filename) {
require_once $filename;
$basename = explode(".", basename($filename));
$nested = array();
foreach ($translations as $key => $value) {
list($plugin, $nkey) = explode("_", $key, 2);
$nested[$plugin][$nkey] = $value;
}
$translations = $nested;
$data = json_encode($translations, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
$newFile = sprintf("%s/%s.json", self::getDownloadPath(), $basename[0]);
file_put_contents($newFile, $data);
@unlink($filename);
$progress->advance();
}
$progress->finish();
$output->writeln("Finished fetching new language files from oTrance");
}
public static function getDownloadPath() {
$path = PIWIK_DOCUMENT_ROOT . DIRECTORY_SEPARATOR . self::DOWNLOADPATH;
if (!is_dir($path)) {
mkdir($path);
}
return $path;
}
}

View file

@ -0,0 +1,123 @@
<?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\Plugins\LanguagesManager\Commands;
use Piwik\Container\StaticContainer;
use Piwik\Exception\AuthenticationFailedException;
use Piwik\Plugins\LanguagesManager\API as LanguagesManagerApi;
use Piwik\Translation\Transifex\API;
use Symfony\Component\Console\Helper\ProgressHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
*/
class FetchTranslations extends TranslationBase
{
const DOWNLOAD_PATH = '/transifex';
protected function configure()
{
$path = StaticContainer::get('path.tmp') . self::DOWNLOAD_PATH;
$this->setName('translations:fetch')
->setDescription('Fetches translations files from Transifex to ' . $path)
->addOption('username', 'u', InputOption::VALUE_OPTIONAL, 'Transifex username')
->addOption('password', 'p', InputOption::VALUE_OPTIONAL, 'Transifex password')
->addOption('lastupdate', 'l', InputOption::VALUE_OPTIONAL, 'Last time update ran', time()-30*24*3600)
->addOption('plugin', 'r', InputOption::VALUE_OPTIONAL, 'Plugin to update');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$username = $input->getOption('username');
$password = $input->getOption('password');
$plugin = $input->getOption('plugin');
$lastUpdate = $input->getOption('lastupdate');
$resource = 'piwik-'. ($plugin ? 'plugin-'.strtolower($plugin) : 'base');
$transifexApi = new API($username, $password);
// remove all existing translation files in download path
$files = glob($this->getDownloadPath() . DIRECTORY_SEPARATOR . '*.json');
array_map('unlink', $files);
if (!$transifexApi->resourceExists($resource)) {
$output->writeln("Skipping resource $resource as it doesn't exist on Transifex");
return;
}
$output->writeln("Fetching translations from Transifex for resource $resource");
$availableLanguages = LanguagesManagerApi::getInstance()->getAvailableLanguageNames();
$languageCodes = array();
foreach ($availableLanguages as $languageInfo) {
$languageCodes[] = $languageInfo['code'];
}
$languageCodes = array_filter($languageCodes, function($code) {
return !in_array($code, array('en', 'dev'));
});
try {
$languages = $transifexApi->getAvailableLanguageCodes();
if (!empty($plugin)) {
$languages = array_filter($languages, function ($language) {
return LanguagesManagerApi::getInstance()->isLanguageAvailable(str_replace('_', '-', strtolower($language)));
});
}
} catch (AuthenticationFailedException $e) {
$languages = $languageCodes;
}
/** @var ProgressHelper $progress */
$progress = $this->getHelperSet()->get('progress');
$progress->start($output, count($languages));
$statistics = $transifexApi->getStatistics($resource);
foreach ($languages as $language) {
try {
// if we have modification date given from statistics api compare it with given last update time to ignore not update resources
if (LanguagesManagerApi::getInstance()->isLanguageAvailable(str_replace('_', '-', strtolower($language))) && isset($statistics->$language)) {
$lastupdated = strtotime($statistics->$language->last_update);
if ($lastUpdate > $lastupdated) {
$progress->advance();
continue;
}
}
$translations = $transifexApi->getTranslations($resource, $language, true);
file_put_contents($this->getDownloadPath() . DIRECTORY_SEPARATOR . str_replace('_', '-', strtolower($language)) . '.json', $translations);
} catch (\Exception $e) {
$output->writeln("Error fetching language file $language: " . $e->getMessage());
}
$progress->advance();
}
$progress->finish();
}
public static function getDownloadPath()
{
$path = StaticContainer::get('path.tmp') . self::DOWNLOAD_PATH;
if (!is_dir($path)) {
mkdir($path);
}
return $path;
}
}

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -9,14 +9,13 @@
namespace Piwik\Plugins\LanguagesManager\Commands;
use Piwik\Plugin\ConsoleCommand;
use Piwik\Plugins\LanguagesManager\API;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
*/
class LanguageCodes extends ConsoleCommand
class LanguageCodes extends TranslationBase
{
protected function configure()
{
@ -29,7 +28,7 @@ class LanguageCodes extends ConsoleCommand
$languages = API::getInstance()->getAvailableLanguageNames();
$languageCodes = array();
foreach ($languages AS $languageInfo) {
foreach ($languages as $languageInfo) {
$languageCodes[] = $languageInfo['code'];
}

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -9,14 +9,13 @@
namespace Piwik\Plugins\LanguagesManager\Commands;
use Piwik\Plugin\ConsoleCommand;
use Piwik\Plugins\LanguagesManager\API;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
*/
class LanguageNames extends ConsoleCommand
class LanguageNames extends TranslationBase
{
protected function configure()
{
@ -29,7 +28,7 @@ class LanguageNames extends ConsoleCommand
$languages = API::getInstance()->getAvailableLanguageNames();
$languageNames = array();
foreach ($languages AS $languageInfo) {
foreach ($languages as $languageInfo) {
$languageNames[] = $languageInfo['english_name'];
}

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -9,15 +9,12 @@
namespace Piwik\Plugins\LanguagesManager\Commands;
use Piwik\Plugin\ConsoleCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
*/
class PluginsWithTranslations extends ConsoleCommand
class PluginsWithTranslations extends TranslationBase
{
protected function configure()
{

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -9,23 +9,21 @@
namespace Piwik\Plugins\LanguagesManager\Commands;
use Piwik\Plugin\ConsoleCommand;
use Piwik\Plugins\LanguagesManager\API;
use Piwik\Translate\Filter\ByBaseTranslations;
use Piwik\Translate\Filter\ByParameterCount;
use Piwik\Translate\Filter\EmptyTranslations;
use Piwik\Translate\Filter\EncodedEntities;
use Piwik\Translate\Filter\UnnecassaryWhitespaces;
use Piwik\Translate\Validate\CoreTranslations;
use Piwik\Translate\Validate\NoScripts;
use Piwik\Translate\Writer;
use Piwik\Plugins\LanguagesManager\TranslationWriter\Filter\ByBaseTranslations;
use Piwik\Plugins\LanguagesManager\TranslationWriter\Filter\ByParameterCount;
use Piwik\Plugins\LanguagesManager\TranslationWriter\Filter\EmptyTranslations;
use Piwik\Plugins\LanguagesManager\TranslationWriter\Filter\EncodedEntities;
use Piwik\Plugins\LanguagesManager\TranslationWriter\Filter\UnnecassaryWhitespaces;
use Piwik\Plugins\LanguagesManager\TranslationWriter\Validate\CoreTranslations;
use Piwik\Plugins\LanguagesManager\TranslationWriter\Validate\NoScripts;
use Piwik\Plugins\LanguagesManager\TranslationWriter\Writer;
use Symfony\Component\Console\Helper\DialogHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
*/
class SetTranslations extends ConsoleCommand
class SetTranslations extends TranslationBase
{
protected function configure()
{
@ -38,6 +36,7 @@ class SetTranslations extends ConsoleCommand
protected function execute(InputInterface $input, OutputInterface $output)
{
/** @var DialogHelper $dialog */
$dialog = $this->getHelperSet()->get('dialog');
$languageCode = $input->getOption('code');

View file

@ -0,0 +1,27 @@
<?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\Plugins\LanguagesManager\Commands;
use Piwik\Development;
use Piwik\Plugin\ConsoleCommand;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
*/
abstract class TranslationBase extends ConsoleCommand
{
public function isEnabled()
{
return Development::isEnabled();
}
}

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -9,8 +9,9 @@
namespace Piwik\Plugins\LanguagesManager\Commands;
use Piwik\Plugin\ConsoleCommand;
use Piwik\Plugins\LanguagesManager\API;
use Symfony\Component\Console\Helper\DialogHelper;
use Symfony\Component\Console\Helper\ProgressHelper;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@ -19,112 +20,108 @@ use Symfony\Component\Console\Output\OutputInterface;
/**
*/
class Update extends ConsoleCommand
class Update extends TranslationBase
{
protected function configure()
{
$this->setName('translations:update')
->setDescription('Updates translation files')
->addOption('username', 'u', InputOption::VALUE_OPTIONAL, 'oTrance username')
->addOption('password', 'p', InputOption::VALUE_OPTIONAL, 'oTrance password')
->addOption('force', 'f', InputOption::VALUE_NONE, 'Force update of all language files')
->addOption('username', 'u', InputOption::VALUE_OPTIONAL, 'Transifex username')
->addOption('password', 'p', InputOption::VALUE_OPTIONAL, 'Transifex password')
->addOption('plugin', 'P', InputOption::VALUE_OPTIONAL, 'optional name of plugin to update translations for');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$dialog = $this->getHelperSet()->get('dialog');
$start = microtime(true);
$command = $this->getApplication()->find('translations:fetch');
$arguments = array(
'command' => 'translations:fetch',
'--username' => $input->getOption('username'),
'--password' => $input->getOption('password')
);
$inputObject = new ArrayInput($arguments);
$inputObject->setInteractive($input->isInteractive());
$command->run($inputObject, $output);
/** @var DialogHelper $dialog */
$dialog = $this->getHelperSet()->get('dialog');
$languages = API::getInstance()->getAvailableLanguageNames();
$languageCodes = array();
foreach ($languages AS $languageInfo) {
foreach ($languages as $languageInfo) {
$languageCodes[] = $languageInfo['code'];
}
$plugin = $input->getOption('plugin');
$files = _glob(FetchFromOTrance::getDownloadPath() . DIRECTORY_SEPARATOR . '*.json');
$output->writeln("Starting to import new language files");
if (!$input->isInteractive()) {
$output->writeln("(!) Non interactive mode: New languages will be skipped");
}
$progress = $this->getHelperSet()->get('progress');
$progress->start($output, count($files));
foreach ($files AS $filename) {
$progress->advance();
$code = basename($filename, '.json');
if (!in_array($code, $languageCodes)) {
if (!empty($plugin)) {
continue; # never create a new language for plugin only
}
$createNewFile = false;
if ($input->isInteractive()) {
$createNewFile = $dialog->askConfirmation($output, "\nLanguage $code does not exist. Should it be added? ", false);
}
if (!$createNewFile) {
continue; # do not create a new file for the language
}
@touch(PIWIK_DOCUMENT_ROOT . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . $code . '.json');
API::unsetInstance(); // unset language manager instance, so valid names are refetched
}
$command = $this->getApplication()->find('translations:set');
$arguments = array(
'command' => 'translations:set',
'--code' => $code,
'--file' => $filename,
'--plugin' => $plugin
);
$inputObject = new ArrayInput($arguments);
$inputObject->setInteractive($input->isInteractive());
$command->run($inputObject, new NullOutput());
// update core modules that aren't in their own repo
if (empty($plugin)) {
foreach (self::getPluginsInCore() AS $pluginName) {
// update translation files
$command = $this->getApplication()->find('translations:set');
$arguments = array(
'command' => 'translations:set',
'--code' => $code,
'--file' => $filename,
'--plugin' => $pluginName
);
$inputObject = new ArrayInput($arguments);
$inputObject->setInteractive($input->isInteractive());
$command->run($inputObject, new NullOutput());
}
}
$pluginList = array($plugin);
if (empty($plugin)) {
$pluginList = self::getPluginsInCore();
array_unshift($pluginList, '');
} else {
$input->setOption('force', true); // force plugin only updates
}
$progress->finish();
$output->writeln("Finished.");
foreach ($pluginList as $plugin) {
$output->writeln("");
// fetch base or specific plugin
$this->fetchTranslations($input, $output, $plugin);
$files = _glob(FetchTranslations::getDownloadPath() . DIRECTORY_SEPARATOR . '*.json');
if (count($files) == 0) {
$output->writeln("No translation updates available! Skipped.");
continue;
}
$output->writeln("Starting to import new language files");
/** @var ProgressHelper $progress */
$progress = $this->getHelperSet()->get('progress');
$progress->start($output, count($files));
foreach ($files as $filename) {
$progress->advance();
$code = basename($filename, '.json');
if (!in_array($code, $languageCodes)) {
if (!empty($plugin)) {
continue; # never create a new language for plugin only
}
$createNewFile = false;
if ($input->isInteractive()) {
$createNewFile = $dialog->askConfirmation($output, "\nLanguage $code does not exist. Should it be added? ", false);
}
if (!$createNewFile) {
continue; # do not create a new file for the language
}
@touch(PIWIK_DOCUMENT_ROOT . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . $code . '.json');
API::unsetInstance(); // unset language manager instance, so valid names are refetched
}
$command = $this->getApplication()->find('translations:set');
$arguments = array(
'command' => 'translations:set',
'--code' => $code,
'--file' => $filename,
'--plugin' => $plugin
);
$inputObject = new ArrayInput($arguments);
$inputObject->setInteractive($input->isInteractive());
$command->run($inputObject, new NullOutput());
}
$progress->finish();
}
$output->writeln("Finished in " . round(microtime(true)-$start, 3) . "s");
}
/**
@ -151,7 +148,7 @@ class Update extends ConsoleCommand
$pluginsNotInCore = array_merge($submodulePlugins, $newPlugins);
$pluginsWithTranslations = glob(sprintf('%s/plugins/*/lang/en.json', PIWIK_INCLUDE_PATH));
$pluginsWithTranslations = array_map(function($elem){
$pluginsWithTranslations = array_map(function ($elem) {
return str_replace(array(sprintf('%s/plugins/', PIWIK_INCLUDE_PATH), '/lang/en.json'), '', $elem);
}, $pluginsWithTranslations);
@ -159,4 +156,48 @@ class Update extends ConsoleCommand
return $pluginsInCore;
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @param string $plugin
* @throws \Exception
*/
protected function fetchTranslations(InputInterface $input, OutputInterface $output, $plugin)
{
$command = $this->getApplication()->find('translations:fetch');
$arguments = array(
'command' => 'translations:fetch',
'--username' => $input->getOption('username'),
'--password' => $input->getOption('password'),
'--plugin' => $plugin
);
if ($input->getOption('force')) {
$arguments['--lastupdate'] = 1;
} else {
$lastModDate = strtotime('2015-01-04 00:00:00'); // date of inital transifex setup
try {
// try to find the language file (of given plugin) with the newest modification date in git log
$path = ($plugin ? 'plugins/' . $plugin . '/' : '') . 'lang';
$files = explode("\n", trim(shell_exec('git ls-tree -r --name-only HEAD ' . $path)));
foreach ($files as $file) {
$fileModDate = shell_exec('git log -1 --format="%at" -- ' . $file);
if (basename($file) != 'en.json' && $fileModDate > $lastModDate) {
$lastModDate = $fileModDate;
}
}
} catch (\Exception $e) {
}
if ($lastModDate != 0) {
$arguments['--lastupdate'] = $lastModDate;
}
}
$inputObject = new ArrayInput($arguments);
$inputObject->setInteractive($input->isInteractive());
$command->run($inputObject, $output);
}
}