Merge pull request #1829 from aledeg/improve-i18n-tools

Improve i18n tools
pull/1834/head
Alexis Degrugillier 7 years ago committed by GitHub
commit a891df3283
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      cli/i18n/I18nData.php
  2. 4
      cli/i18n/I18nFile.php
  3. 10
      cli/i18n/I18nFileInterface.php
  4. 64
      cli/i18n/I18nIgnoreFile.php
  5. 124
      cli/manipulate.translation.php

@ -49,7 +49,8 @@ class I18nData {
* @throws Exception
*/
public function addKey($key, $value) {
if (array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
if (array_key_exists($this->getFilenamePrefix($key), $this->data[static::REFERENCE_LANGUAGE]) &&
array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
throw new Exception('The selected key already exist.');
}
$this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)][$key] = $value;
@ -67,7 +68,8 @@ class I18nData {
if (!in_array($language, $this->getAvailableLanguages())) {
throw new Exception('The selected language does not exist.');
}
if (!array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
if (!array_key_exists($this->getFilenamePrefix($key), $this->data[static::REFERENCE_LANGUAGE]) ||
!array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
throw new Exception('The selected key does not exist for the selected language.');
}
$this->data[$language][$this->getFilenamePrefix($key)][$key] = $value;
@ -80,7 +82,8 @@ class I18nData {
* @throws Exception
*/
public function duplicateKey($key) {
if (!array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
if (!array_key_exists($this->getFilenamePrefix($key), $this->data[static::REFERENCE_LANGUAGE]) ||
!array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
throw new Exception('The selected key does not exist.');
}
$value = $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)][$key];
@ -102,7 +105,8 @@ class I18nData {
* @throws Exception
*/
public function removeKey($key) {
if (!array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
if (!array_key_exists($this->getFilenamePrefix($key), $this->data[static::REFERENCE_LANGUAGE]) ||
!array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
throw new Exception('The selected key does not exist.');
}
foreach ($this->getAvailableLanguages() as $language) {
@ -112,6 +116,30 @@ class I18nData {
}
}
/**
* WARNING! This is valid only for ignore files. It's not the best way to
* handle that but as it's meant to be used only for the cli tool, there
* is no point of spending time on making it better than that.
*
* Ignore a key from a language, or reverse it.
*
* @param string $key
* @param string $language
* @param boolean $reverse
*/
public function ignore($key, $language, $reverse = false) {
$index = array_search($key, $this->data[$language]);
if ($index && $reverse) {
unset($this->data[$language][$index]);
return;
}
if ($index && !$reverse) {
return;
}
$this->data[$language][] = $key;
}
/**
* Check if the data has changed
*

@ -1,8 +1,9 @@
<?php
require_once __DIR__ . '/I18nData.php';
require_once __DIR__ . '/I18nFileInterface.php';
class i18nFile {
class I18nFile implements I18nFileInterface{
private $i18nPath;
@ -11,6 +12,7 @@ class i18nFile {
}
public function load() {
$i18n = array();
$dirs = new DirectoryIterator($this->i18nPath);
foreach ($dirs as $dir) {
if ($dir->isDot()) {

@ -0,0 +1,10 @@
<?php
require_once __DIR__ . '/I18nData.php';
interface I18nFileInterface {
public function load();
public function dump(I18nData $i18n);
}

@ -0,0 +1,64 @@
<?php
require_once __DIR__ . '/I18nData.php';
require_once __DIR__ . '/I18nFileInterface.php';
class I18nIgnoreFile implements I18nFileInterface {
private $i18nPath;
public function __construct() {
$this->i18nPath = __DIR__ . '/ignore';
}
public function dump(I18nData $i18n) {
foreach ($i18n->getData() as $language => $content) {
$filename = $this->i18nPath . DIRECTORY_SEPARATOR . $language . '.php';
file_put_contents($filename, $this->format($content));
}
}
public function load() {
$i18n = array();
$files = new DirectoryIterator($this->i18nPath);
foreach ($files as $file) {
if (!$file->isFile()) {
continue;
}
$i18n[$file->getBasename('.php')] = (include $file->getPathname());
}
return new I18nData($i18n);
}
/**
* Format an array of translation
*
* It takes an array of translation and format it to be dumped in a
* translation file. The array is first converted to a string then some
* formatting regexes are applied to match the original content.
*
* @param array $translation
* @return string
*/
private function format($translation) {
$translation = var_export(($translation), true);
$patterns = array(
'/array \(/',
'/=>\s*array/',
'/ {2}/',
'/\d+ => /',
);
$replacements = array(
'array(',
'=> array',
"\t", // Double quoting is mandatory to have a tab instead of the \t string
'',
);
$translation = preg_replace($patterns, $replacements, $translation);
// Double quoting is mandatory to have new lines instead of \n strings
return sprintf("<?php\n\nreturn %s;\n", $translation);
}
}

@ -1,45 +1,60 @@
<?php
$options = getopt("h");
$options = getopt("a:hk:l:rv:");
if (array_key_exists('h', $options)) {
help();
}
if (1 === $argc || 5 < $argc) {
help();
if (!array_key_exists('a', $options)) {
error('You need to specify the action to perform.');
}
require_once __DIR__ . '/i18n/I18nFile.php';
$i18nFile = new I18nFile();
if ('ignore' === $options['a']) {
require_once __DIR__ . '/i18n/I18nIgnoreFile.php';
$i18nFile = new I18nIgnoreFile();
} else {
require_once __DIR__ . '/i18n/I18nFile.php';
$i18nFile = new I18nFile();
}
$i18nData = $i18nFile->load();
switch ($argv[1]) {
case 'add_language' :
$i18nData->addLanguage($argv[2]);
break;
case 'add_key' :
if (3 === $argc) {
help();
switch ($options['a']) {
case 'add' :
if (array_key_exists('k', $options) && array_key_exists('v', $options) && array_key_exists('l', $options)) {
$i18nData->addValue($options['k'], $options['v'], $options['l']);
} elseif (array_key_exists('k', $options) && array_key_exists('v', $options)) {
$i18nData->addKey($options['k'], $options['v']);
} elseif (array_key_exists('l', $options)) {
$i18nData->addLanguage($options['l']);
} else {
error('You need to specify a valid set of options.');
}
$i18nData->addKey($argv[2], $argv[3]);
break;
case 'add_value':
if (4 === $argc) {
help();
case 'delete' :
if (array_key_exists('k', $options)) {
$i18nData->removeKey($options['k']);
} else {
error('You need to specify the key to delete.');
}
$i18nData->addValue($argv[2], $argv[3], $argv[4]);
break;
case 'duplicate_key' :
$i18nData->duplicateKey($argv[2]);
break;
case 'delete_key' :
$i18nData->removeKey($argv[2]);
case 'duplicate' :
if (array_key_exists('k', $options)) {
$i18nData->duplicateKey($options['k']);
} else {
error('You need to specify the key to duplicate');
}
break;
case 'format' :
$i18nFile->dump($i18nData);
break;
case 'ignore' :
if (array_key_exists('l', $options) && array_key_exists('k', $options)) {
$i18nData->ignore($options['k'], $options['l'], array_key_exists('r', $options));
} else {
error('You need to specify a valid set of options.');
}
break;
default :
help();
}
@ -48,47 +63,66 @@ if ($i18nData->hasChanged()) {
$i18nFile->dump($i18nData);
}
/**
* Output error message.
*/
function error($message) {
$error = <<<ERROR
WARNING
%s\n\n
ERROR;
echo sprintf($error, $message);
help();
}
/**
* Output help message.
*/
function help() {
$help = <<<HELP
NAME
%s
%1\$s
SYNOPSIS
php %s [OPTION] [OPERATION] [KEY] [VALUE] [LANGUAGE]
php %1\$s [OPTIONS]
DESCRIPTION
Manipulate translation files. Available operations are
Check if translation files have missing keys or missing translations.
Manipulate translation files.
-a=ACTION
select the action to perform. Available actions are add, delete,
duplicate, format, and ignore. This option is mandatory.
-k=KEY select the key to work on.
-v=VAL select the value to set.
-l=LANG select the language to work on.
-h display this help and exit.
OPERATION
add_language
add a new language by duplicating the referential. This operation
needs only a KEY.
EXEMPLE
Exemple 1: add a language. It adds a new language by duplicating the referential.
php %1\$s -a add -l my_lang
Exemple 2: add a new key. It adds the key in the referential.
php %1\$s -a add -k my_key -v my_value
add_key add a new key in the referential. This operation needs a KEY and
a VALUE.
Exemple 3: add a new value. It adds a new value for the selected key in the selected language.
php %1\$s -a add -k my_key -v my_value -l my_lang
add_value
add a value in the referential. This operation needs a KEY, a
VALUE, and a LANGUAGE.
Exemple 4: delete a key. It deletes the selected key in every languages.
php %1\$s -a delete -k my_key
duplicate_key
duplicate a referential key in other languages. This operation
needs only a KEY.
Exemple 5: duplicate a key. It duplicates the key from the referential in every languages.
php %1\$s -a duplicate -k my_key
delete_key
delete a referential key from all languages. This operation needs
only a KEY.
Exemple 6: format i18n files.
php %1\$s -a format
format format i18n files.
Exemple 7: ignore a key. It adds the key in the ignore file to mark it as translated.
php %1\$s -a ignore -k my_key -l my_lang
Exemple 8: revert ignore a key. It removes the key from the ignore file.
php %1\$s -a ignore -r -k my_key -l my_lang\n\n
HELP;
$file = str_replace(__DIR__ . '/', '', __FILE__);
echo sprintf($help, $file, $file);
echo sprintf($help, $file);
exit;
}

Loading…
Cancel
Save