aboutsummaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/README.md1
-rwxr-xr-xcli/create-user.php2
-rw-r--r--cli/i18n/I18nData.php36
-rw-r--r--cli/i18n/I18nFile.php4
-rw-r--r--cli/i18n/I18nFileInterface.php10
-rw-r--r--cli/i18n/I18nIgnoreFile.php64
-rw-r--r--cli/manipulate.translation.php124
-rwxr-xr-xcli/prepare.php1
8 files changed, 191 insertions, 51 deletions
diff --git a/cli/README.md b/cli/README.md
index d531b8c3d..0d1c0a7d4 100644
--- a/cli/README.md
+++ b/cli/README.md
@@ -38,6 +38,7 @@ cd /usr/share/FreshRSS
./cli/do-install.php --default_user admin ( --auth_type form --environment production --base_url https://rss.example.net/ --language en --title FreshRSS --allow_anonymous --api_enabled --db-type mysql --db-host localhost:3306 --db-user freshrss --db-password dbPassword123 --db-base freshrss --db-prefix freshrss )
# --auth_type can be: 'form' (default), 'http_auth' (using the Web server access control), 'none' (dangerous)
# --db-type can be: 'sqlite' (default), 'mysql' (MySQL or MariaDB), 'pgsql' (PostgreSQL)
+# --base_url should be a public (routable) URL if possible, and is used for push (PubSubHubbub), for some API functions (e.g. favicons), and external URLs in FreshRSS.
# --environment can be: 'production' (default), 'development' (for additional log messages)
# --language can be: 'en' (default), 'fr', or one of the [supported languages](../app/i18n/)
# --db-prefix is an optional prefix in front of the names of the tables. We suggest using 'freshrss_'
diff --git a/cli/create-user.php b/cli/create-user.php
index 5bc6c1e6c..29675fa53 100755
--- a/cli/create-user.php
+++ b/cli/create-user.php
@@ -20,7 +20,7 @@ $ok = FreshRSS_user_Controller::createUser($username,
empty($options['password']) ? '' : $options['password'],
empty($options['api_password']) ? '' : $options['api_password'],
$values,
- !isset($options['no-default-feeds']));
+ !isset($options['no_default_feeds']));
if (!$ok) {
fail('FreshRSS could not create user!');
diff --git a/cli/i18n/I18nData.php b/cli/i18n/I18nData.php
index b8f958288..2178d330d 100644
--- a/cli/i18n/I18nData.php
+++ b/cli/i18n/I18nData.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) {
@@ -113,6 +117,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
*
* @return bool
diff --git a/cli/i18n/I18nFile.php b/cli/i18n/I18nFile.php
index a07efdf88..bdcf3c079 100644
--- a/cli/i18n/I18nFile.php
+++ b/cli/i18n/I18nFile.php
@@ -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()) {
diff --git a/cli/i18n/I18nFileInterface.php b/cli/i18n/I18nFileInterface.php
new file mode 100644
index 000000000..c5aaf9fcd
--- /dev/null
+++ b/cli/i18n/I18nFileInterface.php
@@ -0,0 +1,10 @@
+<?php
+
+require_once __DIR__ . '/I18nData.php';
+
+interface I18nFileInterface {
+
+ public function load();
+
+ public function dump(I18nData $i18n);
+}
diff --git a/cli/i18n/I18nIgnoreFile.php b/cli/i18n/I18nIgnoreFile.php
new file mode 100644
index 000000000..714e000ca
--- /dev/null
+++ b/cli/i18n/I18nIgnoreFile.php
@@ -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);
+ }
+
+}
diff --git a/cli/manipulate.translation.php b/cli/manipulate.translation.php
index 0e06993ef..35405bb89 100644
--- a/cli/manipulate.translation.php
+++ b/cli/manipulate.translation.php
@@ -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();
}
@@ -49,46 +64,65 @@ if ($i18nData->hasChanged()) {
}
/**
+ * 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;
}
diff --git a/cli/prepare.php b/cli/prepare.php
index 2db2da555..81fb53f85 100755
--- a/cli/prepare.php
+++ b/cli/prepare.php
@@ -7,6 +7,7 @@ $dirs = array(
'/cache',
'/extensions-data',
'/favicons',
+ '/fever',
'/PubSubHubbub',
'/PubSubHubbub/feeds',
'/PubSubHubbub/keys',