Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsgiehl <stefan@matomo.org>2021-03-03 20:01:46 +0300
committersgiehl <stefan@matomo.org>2021-03-03 20:03:18 +0300
commit5e2c5dce5cd88ba3872a72ae3e7675514e3a6098 (patch)
treee349abc16ccb2394cda9fc20d072cc28d271a312 /plugins/LanguagesManager
parent4aa36276203768513e888a394112f5acbb3da5c7 (diff)
Adds command to validate translations
Diffstat (limited to 'plugins/LanguagesManager')
-rw-r--r--plugins/LanguagesManager/Commands/SetTranslations.php22
-rw-r--r--plugins/LanguagesManager/Commands/Validate.php142
-rw-r--r--plugins/LanguagesManager/TranslationWriter/Writer.php20
3 files changed, 181 insertions, 3 deletions
diff --git a/plugins/LanguagesManager/Commands/SetTranslations.php b/plugins/LanguagesManager/Commands/SetTranslations.php
index cc62c84656..6790d40158 100644
--- a/plugins/LanguagesManager/Commands/SetTranslations.php
+++ b/plugins/LanguagesManager/Commands/SetTranslations.php
@@ -31,7 +31,8 @@ class SetTranslations extends TranslationBase
->setDescription('Sets new translations for a given language')
->addOption('code', 'c', InputOption::VALUE_REQUIRED, 'code of the language to set translations for')
->addOption('file', 'f', InputOption::VALUE_REQUIRED, 'json file to load new translations from')
- ->addOption('plugin', 'pl', InputOption::VALUE_OPTIONAL, 'optional name of plugin to set translations for');
+ ->addOption('plugin', 'pl', InputOption::VALUE_OPTIONAL, 'optional name of plugin to set translations for')
+ ->addOption('validate', '', InputOption::VALUE_OPTIONAL, 'when set, the file will not be written, but validated. The given value will be used as filename to write filter results to.');
}
protected function execute(InputInterface $input, OutputInterface $output)
@@ -97,7 +98,24 @@ class SetTranslations extends TranslationBase
return;
}
- $translationWriter->save();
+ if ($input->getOption('validate')) {
+ $translationWriter->applyFilters();
+ $filteredData = $translationWriter->getFilteredData();
+ unset($filteredData[EmptyTranslations::class]);
+
+ if (!empty($filteredData)) {
+ $content = "Filtered File: ".($plugin??'Base')." / ". $languageCode ."\n";
+ foreach ($filteredData as $filter => $data) {
+ $content .= "- Filtered by: $filter\n";
+ $content .= json_encode($data, JSON_PRETTY_PRINT);
+ $content .= "\n";
+ }
+ $content .= "\n\n";
+ file_put_contents($input->getOption('validate'), $content, FILE_APPEND);
+ }
+ } else {
+ $translationWriter->save();
+ }
$output->writeln("Finished.");
}
diff --git a/plugins/LanguagesManager/Commands/Validate.php b/plugins/LanguagesManager/Commands/Validate.php
new file mode 100644
index 0000000000..07082ba730
--- /dev/null
+++ b/plugins/LanguagesManager/Commands/Validate.php
@@ -0,0 +1,142 @@
+<?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\Plugins\LanguagesManager\Commands;
+
+use Piwik\Plugin\Manager;
+use Piwik\Plugins\LanguagesManager\API;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ */
+class Validate extends TranslationBase
+{
+ protected function configure()
+ {
+ $this->setName('translations:validate')
+ ->setDescription('Validates translation files')
+ ->addOption('username', 'u', InputOption::VALUE_OPTIONAL, 'Transifex username')
+ ->addOption('password', 'p', InputOption::VALUE_OPTIONAL, 'Transifex password')
+ ->addOption('slug', 's', InputOption::VALUE_OPTIONAL, 'Transifex project slug')
+ ->addOption('all', 'a', InputOption::VALUE_NONE, 'Force to update all plugins (even non core). Can not be used with plugin option')
+ ->addOption('plugin', 'P', InputOption::VALUE_OPTIONAL, 'optional name of plugin to update translations for');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $output->setDecorated(true);
+
+ $start = microtime(true);
+
+ $languages = API::getInstance()->getAvailableLanguageNames();
+
+ $languageCodes = array();
+ foreach ($languages as $languageInfo) {
+ $languageCodes[] = $languageInfo['code'];
+ }
+
+ $plugin = $input->getOption('plugin');
+
+ $pluginList = array($plugin);
+ if (empty($plugin)) {
+ $pluginList = self::getAllPlugins();
+ array_unshift($pluginList, '');
+ }
+
+ file_put_contents(PIWIK_DOCUMENT_ROOT . '/filter.txt', '');
+
+ 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;
+ }
+
+ foreach ($files as $filename) {
+
+ $code = basename($filename, '.json');
+
+ $command = $this->getApplication()->find('translations:set');
+ $arguments = array(
+ 'command' => 'translations:set',
+ '--code' => $code,
+ '--file' => $filename,
+ '--plugin' => $plugin,
+ '--validate' => PIWIK_DOCUMENT_ROOT . '/filter.txt'
+ );
+ $inputObject = new ArrayInput($arguments);
+ $inputObject->setInteractive($input->isInteractive());
+ $command->run($inputObject, $output);
+ }
+
+ $output->writeln('');
+ }
+
+ $output->writeln("Finished in " . round(microtime(true)-$start, 3) . "s");
+ }
+
+ /**
+ * Returns all plugins having their own translations that are bundled in core
+ * @return array
+ */
+ public static function getAllPlugins()
+ {
+ static $pluginsWithTranslations;
+
+ if (!empty($pluginsWithTranslations)) {
+ return $pluginsWithTranslations;
+ }
+
+ $pluginsWithTranslations = array();
+ foreach (Manager::getPluginsDirectories() as $pluginsDir) {
+ $pluginsWithTranslations = array_merge($pluginsWithTranslations, glob(sprintf('%s*/lang/en.json', $pluginsDir)));
+ }
+ $pluginsWithTranslations = array_map(function ($elem) {
+ $replace = Manager::getPluginsDirectories();
+ $replace[] = '/lang/en.json';
+ return str_replace($replace, '', $elem);
+ }, $pluginsWithTranslations);
+
+ return $pluginsWithTranslations;
+ }
+
+ /**
+ * @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'),
+ '--slug' => $input->getOption('slug'),
+ '--plugin' => $plugin,
+ '--lastupdate' => 1
+ );
+
+ $inputObject = new ArrayInput($arguments);
+ $inputObject->setInteractive($input->isInteractive());
+ $command->run($inputObject, $output);
+ }
+}
diff --git a/plugins/LanguagesManager/TranslationWriter/Writer.php b/plugins/LanguagesManager/TranslationWriter/Writer.php
index eb957f9494..c720087711 100644
--- a/plugins/LanguagesManager/TranslationWriter/Writer.php
+++ b/plugins/LanguagesManager/TranslationWriter/Writer.php
@@ -70,6 +70,13 @@ class Writer
*/
protected $filterMessages = array();
+ /**
+ * Data that had been changed by filters
+ *
+ * @var array
+ */
+ protected $filteredData = array();
+
const UNFILTERED = 'unfiltered';
const FILTERED = 'filtered';
@@ -338,6 +345,16 @@ class Writer
}
/**
+ * Returns the cleaning errors
+ *
+ * @return array
+ */
+ public function getFilteredData()
+ {
+ return $this->filteredData;
+ }
+
+ /**
* @param FilterAbstract $filter
*/
public function addFilter(FilterAbstract $filter)
@@ -350,7 +367,7 @@ class Writer
*
* @return bool error state
*/
- protected function applyFilters()
+ public function applyFilters()
{
// skip if already cleaned
if ($this->currentState == self::FILTERED) {
@@ -373,6 +390,7 @@ class Writer
$filteredData = $filter->getFilteredData();
if (!empty($filteredData)) {
$this->filterMessages[] = get_class($filter) . " changed: " . var_export($filteredData, 1);
+ $this->filteredData[get_class($filter)] = $filteredData;
}
}