update PSR CS

master
Jean-Christian Paul Denis 2021-11-01 22:32:32 +01:00
parent ba70d79862
commit ce6b10dd3c
Signed by: JcDenis
GPG Key ID: 1B5B8C5B90B6C951
16 changed files with 644 additions and 582 deletions

View File

@ -10,7 +10,6 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_CONTEXT_ADMIN')) { if (!defined('DC_CONTEXT_ADMIN')) {
return; return;
} }
@ -46,6 +45,7 @@ class translaterAdminBehaviors
if (!(self::$translater instanceof dcTranslater)) { if (!(self::$translater instanceof dcTranslater)) {
self::$translater = new dcTranslater($core, false); self::$translater = new dcTranslater($core, false);
} }
return self::$translater; return self::$translater;
} }

View File

@ -10,7 +10,6 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_CONTEXT_MODULE')) { if (!defined('DC_CONTEXT_MODULE')) {
return null; return null;
} }
@ -19,8 +18,8 @@ $translater = new dcTranslater($core);
if (!empty($_POST['save'])) { if (!empty($_POST['save'])) {
try { try {
foreach($translater->getDefaultSettings() as $k => $v) { foreach ($translater->getDefaultSettings() as $k => $v) {
$translater->setSetting($k, (isset($_POST[$k]) ? $_POST[$k] : '')); $translater->setSetting($k, ($_POST[$k] ?? ''));
} }
dcPage::addSuccessNotice( dcPage::addSuccessNotice(
__('Configuration successfully updated.') __('Configuration successfully updated.')
@ -57,7 +56,9 @@ __('Write informations about author in files') . '</label></p>
<p><label for="parse_userinfo">' . __('User info:') . '</label>' . <p><label for="parse_userinfo">' . __('User info:') . '</label>' .
form::field('parse_userinfo', 65, 255, $translater->parse_userinfo) . '</p> form::field('parse_userinfo', 65, 255, $translater->parse_userinfo) . '</p>
<p class="form-note">' . sprintf( <p class="form-note">' . sprintf(
__('Following informations can be used: %s'), implode(', ', $translater::$allowed_user_informations)) . ' __('Following informations can be used: %s'),
implode(', ', $translater::$allowed_user_informations)
) . '
</p> </p>
</div> </div>
@ -73,15 +74,17 @@ form::field('export_filename', 65, 255, $translater->export_filename) . '</p>
<p><label for="backup_auto">' . <p><label for="backup_auto">' .
form::checkbox('backup_auto', '1', $translater->backup_auto) . form::checkbox('backup_auto', '1', $translater->backup_auto) .
__('Make backups when changes are made') . '</label></p> __('Make backups when changes are made') . '</label></p>
<p><label for="backup_limit" class="classic">' . sprintf(__('Limit backups to %s files per module'), <p><label for="backup_limit" class="classic">' . sprintf(
form::number('backup_limit', ['min' => 0, 'max' => 50, 'default' => $translater->backup_limit])) . '</label></p> __('Limit backups to %s files per module'),
form::number('backup_limit', ['min' => 0, 'max' => 50, 'default' => $translater->backup_limit])
) . '</label></p>
<p><label for="backup_folder">' . __('Store backups in:') . '</label>' . <p><label for="backup_folder">' . __('Store backups in:') . '</label>' .
form::combo('backup_folder', $translater::$allowed_backup_folders, $translater->backup_folder) . '</p> form::combo('backup_folder', $translater::$allowed_backup_folders, $translater->backup_folder) . '</p>
</div> </div>
<div class="fieldset"><h4>' . __('Behaviors') . '</h4> <div class="fieldset"><h4>' . __('Behaviors') . '</h4>
<p><label for="start_page">' . __('Default start menu:') . '</label>' . <p><label for="start_page">' . __('Default start menu:') . '</label>' .
form::combo('start_page',[ form::combo('start_page', [
__('Plugins') => 'plugin', __('Plugins') => 'plugin',
__('Themes') => 'theme', __('Themes') => 'theme',
__('Home') => '-' __('Home') => '-'

View File

@ -10,7 +10,6 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_RC_PATH')) { if (!defined('DC_RC_PATH')) {
return; return;
} }
@ -21,11 +20,11 @@ $this->registerModule(
'Jean-Christian Denis & contributors', 'Jean-Christian Denis & contributors',
'2021.09.28', '2021.09.28',
[ [
'requires' => [['core', '2.19']], 'requires' => [['core', '2.19']],
'permissions' => null, 'permissions' => null,
'type' => 'plugin', 'type' => 'plugin',
'support' => 'http://forum.dotclear.org/viewtopic.php?id=39220', 'support' => 'http://forum.dotclear.org/viewtopic.php?id=39220',
'details' => 'https://plugins.dotaddict.org/dc2/details/translater', 'details' => 'https://plugins.dotaddict.org/dc2/details/translater',
'repository' => 'https://raw.githubusercontent.com/JcDenis/translater/master/dcstore.xml' 'repository' => 'https://raw.githubusercontent.com/JcDenis/translater/master/dcstore.xml'
] ]
); );

View File

@ -10,18 +10,18 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_CONTEXT_ADMIN')) { if (!defined('DC_CONTEXT_ADMIN')) {
return null; return null;
} }
$id = 'translater'; $id = 'translater';
try { try {
if (version_compare($core->getVersion($id), $core->plugins->moduleInfo($id, 'version'), '>=')) { if (version_compare($core->getVersion($id), $core->plugins->moduleInfo($id, 'version'), '>=')) {
return null; return null;
} }
$translater = new dcTranslater($core, false); $translater = new dcTranslater($core, false);
$settings = $translater->getDefaultSettings(); $settings = $translater->getDefaultSettings();
foreach($settings as $key => $setting) { foreach ($settings as $key => $setting) {
$translater->setSetting($key, $setting['value'], false); $translater->setSetting($key, $setting['value'], false);
} }
$core->setVersion($id, $core->plugins->moduleInfo($id, 'version')); $core->setVersion($id, $core->plugins->moduleInfo($id, 'version'));
@ -30,4 +30,5 @@ try {
} catch (Exception $e) { } catch (Exception $e) {
$core->error->add($e->getMessage()); $core->error->add($e->getMessage());
} }
return false; return false;

View File

@ -10,7 +10,6 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_RC_PATH')) { if (!defined('DC_RC_PATH')) {
return; return;
} }

View File

@ -10,49 +10,72 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_CONTEXT_ADMIN')) { if (!defined('DC_CONTEXT_ADMIN')) {
return; return;
} }
$this->addUserAction( $this->addUserAction(
/* type */ 'settings', /* type */
/* action */ 'delete_all', 'settings',
/* ns */ 'translater', /* action */
/* description */ __('delete all settings') 'delete_all',
/* ns */
'translater',
/* description */
__('delete all settings')
); );
$this->addUserAction( $this->addUserAction(
/* type */ 'plugins', /* type */
/* action */ 'delete', 'plugins',
/* ns */ 'translater', /* action */
/* description */ __('delete plugin files') 'delete',
/* ns */
'translater',
/* description */
__('delete plugin files')
); );
$this->addUserAction( $this->addUserAction(
/* type */ 'versions', /* type */
/* action */ 'delete', 'versions',
/* ns */ 'translater', /* action */
/* description */ __('delete the version number') 'delete',
/* ns */
'translater',
/* description */
__('delete the version number')
); );
$this->addDirectAction( $this->addDirectAction(
/* type */ 'settings', /* type */
/* action */ 'delete_all', 'settings',
/* ns */ 'translater', /* action */
/* description */ sprintf(__('delete all %s settings'), 'translater') 'delete_all',
/* ns */
'translater',
/* description */
sprintf(__('delete all %s settings'), 'translater')
); );
$this->addDirectAction( $this->addDirectAction(
/* type */ 'plugins', /* type */
/* action */ 'delete', 'plugins',
/* ns */ 'translater', /* action */
/* description */ sprintf(__('delete %s plugin files'), 'translater') 'delete',
/* ns */
'translater',
/* description */
sprintf(__('delete %s plugin files'), 'translater')
); );
$this->addDirectAction( $this->addDirectAction(
/* type */ 'versions', /* type */
/* action */ 'delete', 'versions',
/* ns */ 'translater', /* action */
/* description */ sprintf(__('delete %s version number'), 'translater') 'delete',
/* ns */
'translater',
/* description */
sprintf(__('delete %s version number'), 'translater')
); );

View File

@ -10,7 +10,6 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class dcTranslaterLang class dcTranslaterLang
{ {
/** @var dCore dcCore instance */ /** @var dCore dcCore instance */
@ -25,12 +24,12 @@ class dcTranslaterLang
public function __construct(dcTranslaterModule $module, string $lang) public function __construct(dcTranslaterModule $module, string $lang)
{ {
$this->core = $module->core; $this->core = $module->core;
$this->translater = $module->translater; $this->translater = $module->translater;
$this->module = $module; $this->module = $module;
$this->prop['code'] = $lang; $this->prop['code'] = $lang;
$this->prop['name'] = l10n::getLanguageName($lang); $this->prop['name'] = l10n::getLanguageName($lang);
$this->prop['plural'] = explode(':', l10n::getLanguagePluralExpression($lang)); $this->prop['plural'] = explode(':', l10n::getLanguagePluralExpression($lang));
} }
@ -64,18 +63,18 @@ class dcTranslaterLang
$m_msgids = $this->getMsgIds(); $m_msgids = $this->getMsgIds();
$m_msgstrs = $this->getMsgStrs(); $m_msgstrs = $this->getMsgStrs();
foreach($this->translater->getModules() as $module) { foreach ($this->translater->getModules() as $module) {
if ($module->id != $this->module->id) { if ($module->id != $this->module->id) {
$m_o_msgstrs[$module->id] = $this->translater->getlang($module, $this->code)->getMsgStrs(); $m_o_msgstrs[$module->id] = $this->translater->getlang($module, $this->code)->getMsgStrs();
} }
} }
$dc_module = new dcTranslaterModule($this->translater, ['id' => 'dotclear', 'root' => DC_ROOT]); $dc_module = new dcTranslaterModule($this->translater, ['id' => 'dotclear', 'root' => DC_ROOT]);
$dc_lang = new dctranslaterLang($dc_module, $this->code); $dc_lang = new dctranslaterLang($dc_module, $this->code);
$m_o_msgstrs['dotclear'] = $dc_lang->getMsgStrs(); $m_o_msgstrs['dotclear'] = $dc_lang->getMsgStrs();
# From id list # From id list
foreach($m_msgids as $rs) { foreach ($m_msgids as $rs) {
$res[$rs['msgid']]['files'][] = [trim($rs['file'],'/'), $rs['line']]; $res[$rs['msgid']]['files'][] = [trim($rs['file'], '/'), $rs['line']];
$res[$rs['msgid']]['group'] = 'main'; $res[$rs['msgid']]['group'] = 'main';
$res[$rs['msgid']]['plural'] = $rs['msgid_plural']; $res[$rs['msgid']]['plural'] = $rs['msgid_plural'];
$res[$rs['msgid']]['msgstr'] = ['']; $res[$rs['msgid']]['msgstr'] = [''];
@ -84,8 +83,7 @@ class dcTranslaterLang
} }
# From str list # From str list
foreach($m_msgstrs as $rs) { foreach ($m_msgstrs as $rs) {
if (!isset($res[$rs['msgid']])) { if (!isset($res[$rs['msgid']])) {
$res[$rs['msgid']]['files'][] = []; $res[$rs['msgid']]['files'][] = [];
$res[$rs['msgid']]['in_dc'] = false; $res[$rs['msgid']]['in_dc'] = false;
@ -98,8 +96,8 @@ class dcTranslaterLang
} }
# From others str list # From others str list
foreach($m_o_msgstrs as $o_module => $o_msgstrs) { foreach ($m_o_msgstrs as $o_module => $o_msgstrs) {
foreach($o_msgstrs as $rs) { foreach ($o_msgstrs as $rs) {
if (!isset($res[$rs['msgid']])) { if (!isset($res[$rs['msgid']])) {
continue; continue;
} }
@ -114,6 +112,7 @@ class dcTranslaterLang
} }
} }
} }
return $res; return $res;
} }
@ -124,14 +123,14 @@ class dcTranslaterLang
*/ */
public function getMsgIds(): array public function getMsgIds(): array
{ {
$res = []; $res = [];
$scan_ext = ['php']; $scan_ext = ['php'];
if ($this->translater->scan_tpl) { if ($this->translater->scan_tpl) {
$scan_ext[] = 'html'; $scan_ext[] = 'html';
} }
$files = dcTranslater::scandir($this->module->root); $files = dcTranslater::scandir($this->module->root);
foreach($files as $file) { foreach ($files as $file) {
$extension = files::getExtension($file); $extension = files::getExtension($file);
if (is_dir($this->module->root . '/' . $file) || !in_array($extension, $scan_ext)) { if (is_dir($this->module->root . '/' . $file) || !in_array($extension, $scan_ext)) {
continue; continue;
@ -145,7 +144,7 @@ class dcTranslaterLang
} elseif ($extension == 'html') { } elseif ($extension == 'html') {
$msgs = dcTranslater::extractTplMsgs($contents); $msgs = dcTranslater::extractTplMsgs($contents);
} }
foreach($msgs as $msg) { foreach ($msgs as $msg) {
$res[] = [ $res[] = [
'msgid' => dcTranslater::encodeMsg($msg[0][0]), 'msgid' => dcTranslater::encodeMsg($msg[0][0]),
'msgid_plural' => empty($msg[0][1]) ? '' : dcTranslater::encodeMsg($msg[0][1]), 'msgid_plural' => empty($msg[0][1]) ? '' : dcTranslater::encodeMsg($msg[0][1]),
@ -156,6 +155,7 @@ class dcTranslaterLang
unset($contents); unset($contents);
} }
return $res; return $res;
} }
@ -173,12 +173,12 @@ class dcTranslaterLang
return $res; return $res;
} }
foreach($langs[$this->code] as $file) { foreach ($langs[$this->code] as $file) {
if (in_array($file, $scanned)) { if (in_array($file, $scanned)) {
continue; continue;
} }
$scanned[] = $file; $scanned[] = $file;
$path = path::clean($this->module->locales . '/' . $file); $path = path::clean($this->module->locales . '/' . $file);
if (dcTranslater::isPoFile($file)) { if (dcTranslater::isPoFile($file)) {
$po = l10n::parsePoFile($path); $po = l10n::parsePoFile($path);
@ -186,22 +186,22 @@ class dcTranslaterLang
continue; continue;
} }
$entries = $po[1]; $entries = $po[1];
foreach($entries as $entry) { foreach ($entries as $entry) {
$res[] = [ $res[] = [
'msgid' => $entry['msgid'], 'msgid' => $entry['msgid'],
'msgid_plural' => $entry['msgid_plural'] ?? '', 'msgid_plural' => $entry['msgid_plural'] ?? '',
'msgstr' => is_array($entry['msgstr']) ? $entry['msgstr'] : [$entry['msgstr']], 'msgstr' => is_array($entry['msgstr']) ? $entry['msgstr'] : [$entry['msgstr']],
'lang' => $this->code, 'lang' => $this->code,
'type' => 'po', 'type' => 'po',
'path' => $path, 'path' => $path,
'file' => basename($file), 'file' => basename($file),
'group'=> str_replace('.po', '', basename($file)) 'group' => str_replace('.po', '', basename($file))
]; ];
$exists[] = $entry['msgid']; $exists[] = $entry['msgid'];
} }
} }
} }
return $res; return $res;
} }
} }

View File

@ -10,7 +10,6 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_CONTEXT_ADMIN')) { if (!defined('DC_CONTEXT_ADMIN')) {
return; return;
} }
@ -40,10 +39,10 @@ class dcTranslaterModule
$this->translater = $translater; $this->translater = $translater;
$this->prop = $module; $this->prop = $module;
$this->prop['root'] = path::real($this->prop['root']); $this->prop['root'] = path::real($this->prop['root']);
$i = path::info($this->prop['root']); $i = path::info($this->prop['root']);
$this->prop['basename'] = $i['basename']; $this->prop['basename'] = $i['basename'];
$this->prop['locales'] = $this->prop['root'] . '/locales'; $this->prop['locales'] = $this->prop['root'] . '/locales';
} }
/** /**
@ -76,11 +75,12 @@ class dcTranslaterModule
public function getBackupRoot(bool $throw = false) public function getBackupRoot(bool $throw = false)
{ {
$dir = false; $dir = false;
switch($this->translater->backup_folder) { switch ($this->translater->backup_folder) {
case 'module': case 'module':
if ($this->prop['root_writable']) { if ($this->prop['root_writable']) {
$dir = $this->prop['locales']; $dir = $this->prop['locales'];
} }
break; break;
case 'plugin': case 'plugin':
@ -88,6 +88,7 @@ class dcTranslaterModule
if ($tmp && is_writable($tmp)) { if ($tmp && is_writable($tmp)) {
$dir = $tmp; $dir = $tmp;
} }
break; break;
case 'public': case 'public':
@ -95,6 +96,7 @@ class dcTranslaterModule
if ($tmp && is_writable($tmp)) { if ($tmp && is_writable($tmp)) {
$dir = $tmp; $dir = $tmp;
} }
break; break;
case 'cache': case 'cache':
@ -103,6 +105,7 @@ class dcTranslaterModule
@mkDir($tmp . '/l10n'); @mkDir($tmp . '/l10n');
$dir = $tmp . '/l10n'; $dir = $tmp . '/l10n';
} }
break; break;
case 'translater': case 'translater':
@ -111,11 +114,13 @@ class dcTranslaterModule
@mkDir($tmp . '/locales'); @mkDir($tmp . '/locales');
$dir = $tmp . '/locales'; $dir = $tmp . '/locales';
} }
break; break;
} }
if (!$dir && $throw) { if (!$dir && $throw) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Failed to find backups folder for module %s'), $id __('Failed to find backups folder for module %s'),
$id
)); ));
} }
@ -135,9 +140,9 @@ class dcTranslaterModule
return []; return [];
} }
$res = []; $res = [];
$files = dcTranslater::scandir($backup); $files = dcTranslater::scandir($backup);
foreach($files AS $file) { foreach ($files as $file) {
$is_backup = preg_match(sprintf($this->backup_file_regexp, preg_quote($this->prop['id'])), $file, $m); $is_backup = preg_match(sprintf($this->backup_file_regexp, preg_quote($this->prop['id'])), $file, $m);
if (is_dir($backup . '/' . $file) if (is_dir($backup . '/' . $file)
@ -158,6 +163,7 @@ class dcTranslaterModule
$res[$m[1]][$file]['module'] = $this->prop['id']; $res[$m[1]][$file]['module'] = $this->prop['id'];
} }
} }
return $res; return $res;
} }
@ -173,18 +179,18 @@ class dcTranslaterModule
if (!is_dir($this->prop['locales'] . '/' . $lang)) { if (!is_dir($this->prop['locales'] . '/' . $lang)) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Failed to find language %s'), $lang __('Failed to find language %s'),
$lang
)); ));
} }
$res = []; $res = [];
$files = dcTranslater::scandir($this->prop['locales'] . '/' . $lang); $files = dcTranslater::scandir($this->prop['locales'] . '/' . $lang);
foreach($files as $file) { foreach ($files as $file) {
if (!is_dir($this->prop['locales'] . '/' . $lang . '/' . $file) if (!is_dir($this->prop['locales'] . '/' . $lang . '/' . $file)
&& (dcTranslater::isLangphpFile($file) || dcTranslater::isPoFile($file)) && (dcTranslater::isLangphpFile($file) || dcTranslater::isPoFile($file))
) { ) {
$res[$this->prop['locales'] . '/' . $lang . '/' .$file] = $res[$this->prop['locales'] . '/' . $lang . '/' . $file] = $this->prop['id'] . '/locales/' . $lang . '/' . $file;
$this->prop['id'] . '/locales/' . $lang . '/' . $file;
} }
} }
@ -192,9 +198,9 @@ class dcTranslaterModule
dcTranslater::isBackupLimit($backup, $this->translater->backup_limit, true); dcTranslater::isBackupLimit($backup, $this->translater->backup_limit, true);
@set_time_limit(300); @set_time_limit(300);
$fp = fopen($backup . '/l10n-' . $this->prop['id'] . '-' . $lang . '-' . time() . '.bck.zip', 'wb'); $fp = fopen($backup . '/l10n-' . $this->prop['id'] . '-' . $lang . '-' . time() . '.bck.zip', 'wb');
$zip = new fileZip($fp); $zip = new fileZip($fp);
foreach($res AS $from => $to) { foreach ($res as $from => $to) {
$zip->addFile($from, $to); $zip->addFile($from, $to);
} }
$zip->write(); $zip->write();
@ -217,14 +223,15 @@ class dcTranslaterModule
if (!file_exists($backup . '/' . $file)) { if (!file_exists($backup . '/' . $file)) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Failed to find file %s'), $file __('Failed to find file %s'),
$file
)); ));
} }
$zip = new fileUnzip($backup . '/' . $file); $zip = new fileUnzip($backup . '/' . $file);
$zip_files = $zip->getFilesList(); $zip_files = $zip->getFilesList();
foreach($zip_files AS $zip_file) { foreach ($zip_files as $zip_file) {
$f = $this->parseZipFilename($zip_file, true); $f = $this->parseZipFilename($zip_file, true);
$zip->unzip($zip_file, $this->prop['locales'] . '/' . $f['lang'] . '/' . $f['group'] . $f['ext']); $zip->unzip($zip_file, $this->prop['locales'] . '/' . $f['lang'] . '/' . $f['group'] . $f['ext']);
$done = true; $done = true;
@ -256,7 +263,8 @@ class dcTranslaterModule
if (!files::isDeletable($backup . '/' . $file)) { if (!files::isDeletable($backup . '/' . $file)) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Failed to delete file %s'), $file __('Failed to delete file %s'),
$file
)); ));
} }
@ -275,21 +283,22 @@ class dcTranslaterModule
{ {
files::uploadStatus($zip_file); files::uploadStatus($zip_file);
$imported = false; $imported = false;
$not_overwrited = []; $not_overwrited = [];
$res = []; $res = [];
# Load Unzip object # Load Unzip object
$zip = new fileUnzip($zip_file['tmp_name']); $zip = new fileUnzip($zip_file['tmp_name']);
$files = $zip->getFilesList(); $files = $zip->getFilesList();
foreach($files as $file) { foreach ($files as $file) {
$f = $this->parseZipFilename($file, true); $f = $this->parseZipFilename($file, true);
if (!$this->translater->import_overwrite if (!$this->translater->import_overwrite
&& file_exists($this->prop['locales'] . '/' . $f['lang'] . '/' . $f['group'] . $f['ext']) && file_exists($this->prop['locales'] . '/' . $f['lang'] . '/' . $f['group'] . $f['ext'])
) { ) {
$not_overwrited[] = implode('-', [$f['lang'], $f['group'], $f['ext']]); $not_overwrited[] = implode('-', [$f['lang'], $f['group'], $f['ext']]);
continue; continue;
} }
@ -313,13 +322,16 @@ class dcTranslaterModule
if (!empty($not_overwrited)) { if (!empty($not_overwrited)) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Some languages has not been overwrited %s'), implode(', ', $not_overwrited) __('Some languages has not been overwrited %s'),
implode(', ', $not_overwrited)
)); ));
} elseif (!$done) { } elseif (!$done) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Nothing to import from %s'), $zip_file['name'] __('Nothing to import from %s'),
$zip_file['name']
)); ));
} }
return true; return true;
} }
@ -344,14 +356,13 @@ class dcTranslaterModule
} }
$res = []; $res = [];
foreach($langs AS $lang) { foreach ($langs as $lang) {
if (!is_dir($this->prop['locales'] . '/' . $lang)) { if (!is_dir($this->prop['locales'] . '/' . $lang)) {
continue; continue;
} }
$files = dcTranslater::scandir($this->prop['locales'] . '/' . $lang); $files = dcTranslater::scandir($this->prop['locales'] . '/' . $lang);
foreach($files as $file) { foreach ($files as $file) {
if (is_dir($this->prop['locales'] . '/' . $lang . '/' . $file) if (is_dir($this->prop['locales'] . '/' . $lang . '/' . $file)
|| !dcTranslater::isLangphpFile($file) || !dcTranslater::isLangphpFile($file)
&& !dcTranslater::isPoFile($file) && !dcTranslater::isPoFile($file)
@ -359,8 +370,7 @@ class dcTranslaterModule
continue; continue;
} }
$res[$this->prop['locales'] . '/' . $lang . '/' . $file] = $res[$this->prop['locales'] . '/' . $lang . '/' . $file] = $this->prop['id'] . '/locales/' . $lang . '/' . $file;
$this->prop['id'] . '/locales/' . $lang . '/' . $file;
} }
} }
@ -371,9 +381,9 @@ class dcTranslaterModule
} }
@set_time_limit(300); @set_time_limit(300);
$fp = fopen('php://output', 'wb'); $fp = fopen('php://output', 'wb');
$zip = new fileZip($fp); $zip = new fileZip($fp);
foreach($res as $from => $to) { foreach ($res as $from => $to) {
$zip->addFile($from, $to); $zip->addFile($from, $to);
} }
@ -403,19 +413,22 @@ class dcTranslaterModule
if ($is_file) { if ($is_file) {
$module = $f[1] == $this->prop['id'] ?$f[1] : false; $module = $f[1] == $this->prop['id'] ?$f[1] : false;
$lang = l10n::isCode($f[2]) ? $f[2] : false; $lang = l10n::isCode($f[2]) ? $f[2] : false;
$group = in_array($f[3], dctranslater::$allowed_l10n_groups) ? $f[3] : false; $group = in_array($f[3], dctranslater::$allowed_l10n_groups) ? $f[3] : false;
$ext = dctranslater::isLangphpFile($f[4]) || dctranslater::isPoFile($f[4]) ? $f[4] : false; $ext = dctranslater::isLangphpFile($f[4]) || dctranslater::isPoFile($f[4]) ? $f[4] : false;
} }
if (!$is_file || !$module || !$lang || !$group || !$ext) { if (!$is_file || !$module || !$lang || !$group || !$ext) {
if ($throw) { if ($throw) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Zip file %s is not in translater format'), $file __('Zip file %s is not in translater format'),
$file
)); ));
} }
return []; return [];
} }
return [ return [
'module' => $module, 'module' => $module,
'lang' => $lang, 'lang' => $lang,
@ -440,7 +453,7 @@ class dcTranslaterModule
$prefix = preg_match('/(locales(.*))$/', $this->prop['locales']) ? 'locales' : ''; $prefix = preg_match('/(locales(.*))$/', $this->prop['locales']) ? 'locales' : '';
$files = dcTranslater::scandir($this->prop['locales']); $files = dcTranslater::scandir($this->prop['locales']);
foreach($files as $file) { foreach ($files as $file) {
if (!preg_match('/.*?locales\/([^\/]*?)\/([^\/]*?)(.lang.php|.po)$/', $prefix . $file, $m)) { if (!preg_match('/.*?locales\/([^\/]*?)\/([^\/]*?)(.lang.php|.po)$/', $prefix . $file, $m)) {
continue; continue;
} }
@ -455,6 +468,7 @@ class dcTranslaterModule
$res[$m[1]] = l10n::getLanguageName($m[1]); // Lang name $res[$m[1]] = l10n::getLanguageName($m[1]); // Lang name
} }
} }
return $res; return $res;
} }
@ -489,14 +503,16 @@ class dcTranslaterModule
{ {
if (!l10n::isCode($lang)) { if (!l10n::isCode($lang)) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Unknow language %s'), $lang __('Unknow language %s'),
$lang
)); ));
} }
$langs = $this->getLangs(); $langs = $this->getLangs();
if (isset($langs[$lang])) { if (isset($langs[$lang])) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Language %s already exists'), $lang __('Language %s already exists'),
$lang
)); ));
} }
@ -504,13 +520,14 @@ class dcTranslaterModule
if (!empty($from_lang) && !isset($langs[$from_lang])) { if (!empty($from_lang) && !isset($langs[$from_lang])) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Failed to copy file from language %s'), $from_lang __('Failed to copy file from language %s'),
$from_lang
)); ));
} }
if (!empty($from_lang) && isset($langs[$from_lang])) { if (!empty($from_lang) && isset($langs[$from_lang])) {
$files = dcTranslater::scandir($this->prop['locales'] . '/' . $from_lang); $files = dcTranslater::scandir($this->prop['locales'] . '/' . $from_lang);
foreach($files as $file) { foreach ($files as $file) {
if (is_dir($this->prop['locales'] . '/' . $from_lang . '/' . $file) if (is_dir($this->prop['locales'] . '/' . $from_lang . '/' . $file)
|| !dcTranslater::isLangphpFile($file) || !dcTranslater::isLangphpFile($file)
&& !dcTranslater::isPoFile($file) && !dcTranslater::isPoFile($file)
@ -518,7 +535,8 @@ class dcTranslaterModule
continue; continue;
} }
files::putContent($this->prop['locales'] . '/' . $lang . '/' . $file, files::putContent(
$this->prop['locales'] . '/' . $lang . '/' . $file,
file_get_contents($this->prop['locales'] . '/' . $from_lang . '/' . $file) file_get_contents($this->prop['locales'] . '/' . $from_lang . '/' . $file)
); );
} }
@ -538,14 +556,16 @@ class dcTranslaterModule
{ {
if (!l10n::isCode($lang)) { if (!l10n::isCode($lang)) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Unknow language %s'), $lang __('Unknow language %s'),
$lang
)); ));
} }
$langs = $this->getLangs(); $langs = $this->getLangs();
if (!isset($langs[$lang])) { if (!isset($langs[$lang])) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Failed to find language %s'), $lang __('Failed to find language %s'),
$lang
)); ));
} }
@ -554,19 +574,19 @@ class dcTranslaterModule
} }
$rs = []; $rs = [];
foreach($msgs as $msg) { foreach ($msgs as $msg) {
if (empty($msg['msgstr'][0])) { if (empty($msg['msgstr'][0])) {
continue; continue;
} }
$rs[$msg['group']][] = $msg; $rs[$msg['group']][] = $msg;
} }
foreach(dcTranslater::$allowed_l10n_groups as $group) { foreach (dcTranslater::$allowed_l10n_groups as $group) {
if (isset($rs[$group])) { if (isset($rs[$group])) {
continue; continue;
} }
$po_file = $this->prop['locales'] . '/' . $lang . '/' . $group . '.po'; $po_file = $this->prop['locales'] . '/' . $lang . '/' . $group . '.po';
$langphp_file = $this->prop['locales'] . '/' . $lang . '/' . $group . '.lang.php'; $langphp_file = $this->prop['locales'] . '/' . $lang . '/' . $group . '.lang.php';
if (file_exists($po_file)) { if (file_exists($po_file)) {
@ -579,11 +599,12 @@ class dcTranslaterModule
if (empty($rs)) { if (empty($rs)) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('No string to write, language %s deleted'), $lang __('No string to write, language %s deleted'),
$lang
)); ));
} }
foreach($rs as $group => $msgs) { foreach ($rs as $group => $msgs) {
$this->setPoContent($lang, $group, $msgs); $this->setPoContent($lang, $group, $msgs);
$this->setLangphpContent($lang, $group, $msgs); $this->setLangphpContent($lang, $group, $msgs);
} }
@ -601,18 +622,20 @@ class dcTranslaterModule
# Path is right formed # Path is right formed
if (!l10n::isCode($lang)) { if (!l10n::isCode($lang)) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Unknow language %s'), $lang __('Unknow language %s'),
$lang
)); ));
} }
$files = $this->getLangs(true); $files = $this->getLangs(true);
if (!isset($files[$lang])) { if (!isset($files[$lang])) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Failed to find language %s'), $lang __('Failed to find language %s'),
$lang
)); ));
} }
foreach($files[$lang] as $file) { foreach ($files[$lang] as $file) {
unlink($this->prop['locales'] . '/' . $file); unlink($this->prop['locales'] . '/' . $file);
} }
@ -625,6 +648,7 @@ class dcTranslaterModule
if (empty($loc)) { if (empty($loc)) {
rmdir($this->prop['locales']); rmdir($this->prop['locales']);
} }
return true; return true;
} }
@ -641,14 +665,13 @@ class dcTranslaterModule
$content = ''; $content = '';
if ($this->translater->parse_comment) { if ($this->translater->parse_comment) {
$content .= $content .= '# Language: ' . $lang->name . "\n" .
'# Language: ' . $lang->name . "\n" . '# Module: ' . $this->id . ' - ' . $this->version . "\n" .
'# Module: ' . $this->id . " - " . $this->version . "\n" .
'# Date: ' . dt::str('%Y-%m-%d %H:%M:%S') . "\n"; '# Date: ' . dt::str('%Y-%m-%d %H:%M:%S') . "\n";
if ($this->translater->parse_user && $this->translater->parse_userinfo != '') { if ($this->translater->parse_user && $this->translater->parse_userinfo != '') {
$search = dctranslater::$allowed_user_informations; $search = dctranslater::$allowed_user_informations;
foreach($search AS $n) { foreach ($search as $n) {
$replace[] = $this->core->auth->getInfo('user_' . $n); $replace[] = $this->core->auth->getInfo('user_' . $n);
} }
$info = trim(str_replace($search, $replace, $this->translater->parse_userinfo)); $info = trim(str_replace($search, $replace, $this->translater->parse_userinfo));
@ -656,11 +679,9 @@ class dcTranslaterModule
$content .= '# Author: ' . html::escapeHTML($info) . "\n"; $content .= '# Author: ' . html::escapeHTML($info) . "\n";
} }
} }
$content .= $content .= '# Translated with translater ' . $this->core->plugins->moduleInfo('translater', 'version') . "\n\n";
'# Translated with translater ' . $this->core->plugins->moduleInfo('translater', 'version') . "\n\n";
} }
$content .= $content .= "msgid \"\"\n" .
"msgid \"\"\n" .
"msgstr \"\"\n" . "msgstr \"\"\n" .
'"Content-Type: text/plain; charset=UTF-8\n"' . "\n" . '"Content-Type: text/plain; charset=UTF-8\n"' . "\n" .
'"Project-Id-Version: ' . $this->id . ' ' . $this->version . '\n"' . "\n" . '"Project-Id-Version: ' . $this->id . ' ' . $this->version . '\n"' . "\n" .
@ -675,14 +696,13 @@ class dcTranslaterModule
$comments = []; $comments = [];
if ($this->translater->parse_comment) { if ($this->translater->parse_comment) {
$msgids = $lang->getMsgids(); $msgids = $lang->getMsgids();
foreach($msgids as $msg) { foreach ($msgids as $msg) {
$comments[$msg['msgid']] = (isset($comments[$msg['msgid']]) ? $comments[$msg['msgid']] = ($comments[$msg['msgid']] ?? '') .
$comments[$msg['msgid']] : '') . '#: ' . trim($msg['file'], '/') . ':' . $msg['line'] . "\n";
'#: '.trim($msg['file'],'/') . ':' . $msg['line'] . "\n";
} }
} }
foreach($msgs as $msg) { foreach ($msgs as $msg) {
if (empty($msg['msgstr'][0])) { if (empty($msg['msgstr'][0])) {
continue; continue;
} }
@ -694,7 +714,7 @@ class dcTranslaterModule
$content .= 'msgstr "' . dcTranslater::poString($msg['msgstr'][0], true) . '"' . "\n"; $content .= 'msgstr "' . dcTranslater::poString($msg['msgstr'][0], true) . '"' . "\n";
} else { } else {
$content .= 'msgid_plural "' . dcTranslater::poString($msg['msgid_plural'], true) . '"' . "\n"; $content .= 'msgid_plural "' . dcTranslater::poString($msg['msgid_plural'], true) . '"' . "\n";
foreach($msg['msgstr'] as $i => $plural) { foreach ($msg['msgstr'] as $i => $plural) {
$content .= 'msgstr[' . $i . '] "' . dcTranslater::poString(($msg['msgstr'][$i] ?: ''), true) . '"' . "\n"; $content .= 'msgstr[' . $i . '] "' . dcTranslater::poString(($msg['msgstr'][$i] ?: ''), true) . '"' . "\n";
} }
} }
@ -706,13 +726,15 @@ class dcTranslaterModule
if (is_dir($path['dirname']) && !is_writable($path['dirname']) if (is_dir($path['dirname']) && !is_writable($path['dirname'])
|| file_exists($file) && !is_writable($file)) { || file_exists($file) && !is_writable($file)) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Failed to grant write acces on file %s'), $file __('Failed to grant write acces on file %s'),
$file
)); ));
} }
if (!($f = @files::putContent($file, $content))) { if (!($f = @files::putContent($file, $content))) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Failed to write file %s'), $file __('Failed to write file %s'),
$file
)); ));
} }
} }
@ -734,23 +756,21 @@ class dcTranslaterModule
$content = ''; $content = '';
if ($this->translater->parse_comment) { if ($this->translater->parse_comment) {
$content .= $content .= '// Language: ' . $lang->name . "\n" .
'// Language: ' . $lang->name . "\n" . '// Module: ' . $this->id . ' - ' . $this->verison . "\n" .
'// Module: ' . $this->id . " - " . $this->verison . "\n" .
'// Date: ' . dt::str('%Y-%m-%d %H:%M:%S') . "\n"; '// Date: ' . dt::str('%Y-%m-%d %H:%M:%S') . "\n";
if ($this->translater->parse_user && !empty($this->translater->parse_userinfo)) { if ($this->translater->parse_user && !empty($this->translater->parse_userinfo)) {
$search = dcTranslater::$allowed_user_informations; $search = dcTranslater::$allowed_user_informations;
foreach($search as $n) { foreach ($search as $n) {
$replace[] = $this->core->auth->getInfo('user_' . $n); $replace[] = $this->core->auth->getInfo('user_' . $n);
} }
$info = trim(str_replace($search, $replace,$this->translater->parse_userinfo)); $info = trim(str_replace($search, $replace, $this->translater->parse_userinfo));
if (!empty($info)) { if (!empty($info)) {
$content .= '// Author: ' . html::escapeHTML($info) . "\n"; $content .= '// Author: ' . html::escapeHTML($info) . "\n";
} }
} }
$content .= $content .= '// Translated with dcTranslater - ' . $this->core->plugins->moduleInfo('translater', 'version') . "\n\n";
'// Translated with dcTranslater - ' . $this->core->plugins->moduleInfo('translater', 'version') . "\n\n";
} }
l10n::generatePhpFileFromPo($this->locales . '/' . $lang->code . '/' . $group, $content); l10n::generatePhpFileFromPo($this->locales . '/' . $lang->code . '/' . $group, $content);

View File

@ -10,7 +10,6 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_CONTEXT_ADMIN')) { if (!defined('DC_CONTEXT_ADMIN')) {
return; return;
} }
@ -26,105 +25,105 @@ class dcTranslater
/** @var array $default_settings Plugins default settings */ /** @var array $default_settings Plugins default settings */
private static $default_settings = [ private static $default_settings = [
'plugin_menu' => [ 'plugin_menu' => [
'id' => 'translater_plugin_menu', 'id' => 'translater_plugin_menu',
'value' => 0, 'value' => 0,
'type' => 'boolean', 'type' => 'boolean',
'label' => 'Put an link in plugins page' 'label' => 'Put an link in plugins page'
], ],
'theme_menu' => [ 'theme_menu' => [
'id' => 'translater_theme_menu', 'id' => 'translater_theme_menu',
'value' => 0, 'value' => 0,
'type' => 'boolean', 'type' => 'boolean',
'label' => 'Put a link in themes page' 'label' => 'Put a link in themes page'
], ],
'backup_auto' => [ 'backup_auto' => [
'id' => 'translater_backup_auto', 'id' => 'translater_backup_auto',
'value' => 1, 'value' => 1,
'type' => 'boolean', 'type' => 'boolean',
'label' => 'Make a backup of languages old files when there are modified' 'label' => 'Make a backup of languages old files when there are modified'
], ],
'backup_limit' => [ 'backup_limit' => [
'id' => 'translater_backup_limit', 'id' => 'translater_backup_limit',
'value' => 20, 'value' => 20,
'type' => 'string', 'type' => 'string',
'label' => 'Maximum backups per module' 'label' => 'Maximum backups per module'
], ],
'backup_folder' => [ 'backup_folder' => [
'id' => 'translater_backup_folder', 'id' => 'translater_backup_folder',
'value' => 'module', 'value' => 'module',
'type' => 'string', 'type' => 'string',
'label' => 'In which folder to store backups' 'label' => 'In which folder to store backups'
], ],
'start_page' => [ 'start_page' => [
'id' => 'translater_start_page', 'id' => 'translater_start_page',
'value' => '-', 'value' => '-',
'type' => 'string', 'type' => 'string',
'label' => 'Page to start on' 'label' => 'Page to start on'
], ],
'write_langphp' => [ 'write_langphp' => [
'id' => 'translater_write_langphp', 'id' => 'translater_write_langphp',
'value' => 0, 'value' => 0,
'type' => 'boolean', 'type' => 'boolean',
'label' => 'Write .lang.php languages files' 'label' => 'Write .lang.php languages files'
], ],
'scan_tpl' => [ 'scan_tpl' => [
'id' => 'translater_scan_tpl', 'id' => 'translater_scan_tpl',
'value' => 1, 'value' => 1,
'type' => 'boolean', 'type' => 'boolean',
'label' => 'Translate strings of templates files' 'label' => 'Translate strings of templates files'
], ],
'parse_nodc' => [ 'parse_nodc' => [
'id' => 'translater_parse_nodc', 'id' => 'translater_parse_nodc',
'value' => 1, 'value' => 1,
'type' => 'boolean', 'type' => 'boolean',
'label' => 'Translate only untranslated strings of Dotclear', 'label' => 'Translate only untranslated strings of Dotclear',
], ],
'hide_default' => [ 'hide_default' => [
'id' => 'translater_hide_default', 'id' => 'translater_hide_default',
'value' => 1, 'value' => 1,
'type' => 'boolean', 'type' => 'boolean',
'label' => 'Hide default modules of Dotclear', 'label' => 'Hide default modules of Dotclear',
], ],
'parse_comment' => [ 'parse_comment' => [
'id' => 'translater_parse_comment', 'id' => 'translater_parse_comment',
'value' => 0, 'value' => 0,
'type' => 'boolean', 'type' => 'boolean',
'label' => 'Write comments and strings informations in lang files' 'label' => 'Write comments and strings informations in lang files'
], ],
'parse_user' => [ 'parse_user' => [
'id' => 'translater_parse_user', 'id' => 'translater_parse_user',
'value' => 0, 'value' => 0,
'type' => 'boolean', 'type' => 'boolean',
'label' => 'Write inforamtions about author in lang files' 'label' => 'Write inforamtions about author in lang files'
], ],
'parse_userinfo' => [ 'parse_userinfo' => [
'id' => 'translater_parse_userinfo', 'id' => 'translater_parse_userinfo',
'value' => 'displayname, email', 'value' => 'displayname, email',
'type' => 'string', 'type' => 'string',
'label' => 'Type of informations about user to write' 'label' => 'Type of informations about user to write'
], ],
'import_overwrite' => [ 'import_overwrite' => [
'id' => 'translater_import_overwrite', 'id' => 'translater_import_overwrite',
'value' => 0, 'value' => 0,
'type' => 'boolean', 'type' => 'boolean',
'label' => 'Overwrite existing languages when import packages' 'label' => 'Overwrite existing languages when import packages'
], ],
'export_filename' => [ 'export_filename' => [
'id' => 'translater_export_filename', 'id' => 'translater_export_filename',
'value' => 'type-module-l10n-timestamp', 'value' => 'type-module-l10n-timestamp',
'type' => 'string', 'type' => 'string',
'label' => 'Name of files of exported package' 'label' => 'Name of files of exported package'
], ],
'proposal_tool' => [ 'proposal_tool' => [
'id' => 'translater_proposal_tool', 'id' => 'translater_proposal_tool',
'value' => 'google', 'value' => 'google',
'type' => 'string', 'type' => 'string',
'label' => 'Id of default tool for proposed translation' 'label' => 'Id of default tool for proposed translation'
], ],
'proposal_lang' => [ 'proposal_lang' => [
'id' => 'translater_proposal_lang', 'id' => 'translater_proposal_lang',
'value' => 'en', 'value' => 'en',
'type' => 'string', 'type' => 'string',
'label' => 'Default source language for proposed translation' 'label' => 'Default source language for proposed translation'
] ]
]; ];
@ -224,6 +223,7 @@ class dcTranslater
$s = self::$default_settings[$id]; $s = self::$default_settings[$id];
$this->core->blog->settings->translater->drop($s['id']); $this->core->blog->settings->translater->drop($s['id']);
$this->core->blog->settings->translater->put($s['id'], $value, $s['type'], $s['label'], $overwrite, true); $this->core->blog->settings->translater->put($s['id'], $value, $s['type'], $s['label'], $overwrite, true);
return true; return true;
} }
@ -252,13 +252,13 @@ class dcTranslater
'theme' => $themes->getModules(), 'theme' => $themes->getModules(),
'plugin' => $this->core->plugins->getModules() 'plugin' => $this->core->plugins->getModules()
]; ];
foreach($list as $type => $modules) { foreach ($list as $type => $modules) {
foreach($modules as $id => $info) { foreach ($modules as $id => $info) {
if (!$info['root_writable']) { if (!$info['root_writable']) {
// continue; // continue;
} }
$info['id'] = $id; $info['id'] = $id;
$info['type'] = $type; $info['type'] = $type;
$this->modules[$type][$id] = new dcTranslaterModule($this, $info); $this->modules[$type][$id] = new dcTranslaterModule($this, $info);
} }
} }
@ -290,8 +290,10 @@ class dcTranslater
throw new Exception( throw new Exception(
sprintf(__('Failed to find module %s'), $id) sprintf(__('Failed to find module %s'), $id)
); );
return false; return false;
} }
return $this->modules[$type][$id]; return $this->modules[$type][$id];
} }
@ -308,8 +310,10 @@ class dcTranslater
throw new Exception( throw new Exception(
sprintf(__('Failed find language %s'), $lang) sprintf(__('Failed find language %s'), $lang)
); );
return false; return false;
} }
return new dcTranslaterLang($module, $lang); return new dcTranslaterLang($module, $lang);
} }
//@} //@}
@ -332,18 +336,19 @@ class dcTranslater
} }
$files = files::scandir($path); $files = files::scandir($path);
foreach($files AS $file) { foreach ($files as $file) {
if (in_array($file, ['.', '..'])) { if (in_array($file, ['.', '..'])) {
continue; continue;
} }
if (is_dir($path . '/' . $file)) { if (is_dir($path . '/' . $file)) {
$res[] = $file; $res[] = $file;
$res = self::scanDir($path . '/' . $file, $dir . '/' . $file, $res); $res = self::scanDir($path . '/' . $file, $dir . '/' . $file, $res);
} else { } else {
$res[] = empty($dir) ? $file : $dir . '/' . $file; $res[] = empty($dir) ? $file : $dir . '/' . $file;
} }
} }
return $res; return $res;
} }
@ -368,14 +373,15 @@ class dcTranslater
public static function poString(string $string, bool $reverse = false): string public static function poString(string $string, bool $reverse = false): string
{ {
if ($reverse) { if ($reverse) {
$smap = array('"', "\n", "\t", "\r"); $smap = ['"', "\n", "\t", "\r"];
$rmap = array('\\"', '\\n"' . "\n" . '"', '\\t', '\\r'); $rmap = ['\\"', '\\n"' . "\n" . '"', '\\t', '\\r'];
return trim((string) str_replace($smap, $rmap, $string)); return trim((string) str_replace($smap, $rmap, $string));
} else {
$smap = array('/"\s+"/', '/\\\\n/', '/\\\\r/', '/\\\\t/', '/\\\"/');
$rmap = array('', "\n", "\r", "\t", '"');
return trim((string) preg_replace($smap, $rmap, $string));
} }
$smap = ['/"\s+"/', '/\\\\n/', '/\\\\r/', '/\\\\t/', '/\\\"/'];
$rmap = ['', "\n", "\r", "\t", '"'];
return trim((string) preg_replace($smap, $rmap, $string));
} }
/** /**
@ -411,9 +417,9 @@ class dcTranslater
public static function isBackupLimit(string $root, int $limit = 10, bool $throw = false): bool public static function isBackupLimit(string $root, int $limit = 10, bool $throw = false): bool
{ {
$count = 0; $count = 0;
foreach(self::scandir($root) AS $file) { foreach (self::scandir($root) as $file) {
if (!is_dir($root . '/' . $file) if (!is_dir($root . '/' . $file)
&& preg_match('/^(l10n-'. $id . '(.*?).bck.zip)$/', $root) && preg_match('/^(l10n-' . $id . '(.*?).bck.zip)$/', $root)
) { ) {
$count++; $count++;
} }
@ -426,8 +432,10 @@ class dcTranslater
sprintf(__('Limit of %s backups for module %s exceed'), $this->backup_limit, $id) sprintf(__('Limit of %s backups for module %s exceed'), $this->backup_limit, $id)
); );
} }
return true; return true;
} }
return false; return false;
} }
@ -445,12 +453,12 @@ class dcTranslater
$duplicate = $final_strings = $lines = []; $duplicate = $final_strings = $lines = [];
// split content by line to combine match/line on the end // split content by line to combine match/line on the end
$content = str_replace("\r\n", "\n", $content); $content = str_replace("\r\n", "\n", $content);
$o = 0; $o = 0;
$parts = explode("\n", $content); $parts = explode("\n", $content);
foreach($parts as $li => $part) { foreach ($parts as $li => $part) {
$m = explode($func . '(', $part); $m = explode($func . '(', $part);
for($i = 1; $i < count($m); $i++) { for ($i = 1; $i < count($m); $i++) {
$lines[$o] = $li+1; $lines[$o] = $li + 1;
$o++; $o++;
} }
} }
@ -460,14 +468,15 @@ class dcTranslater
array_shift($parts); array_shift($parts);
// walk through parts // walk through parts
$p = 0; $p = 0;
foreach($parts as $part) { foreach ($parts as $part) {
// should start with quote // should start with quote
if (!in_array(substr($part,0,1), ['"', "'"])) { if (!in_array(substr($part, 0, 1), ['"', "'"])) {
$p++; $p++;
continue; continue;
} }
// put back first parenthesis // put back first parenthesis
$part = '('.$part; $part = '(' . $part;
// find pairs of parenthesis // find pairs of parenthesis
preg_match_all("/\((?:[^\)\(]+|(?R))*+\)/s", $part, $subparts); preg_match_all("/\((?:[^\)\(]+|(?R))*+\)/s", $part, $subparts);
// find quoted strings (single or double) // find quoted strings (single or double)
@ -475,16 +484,17 @@ class dcTranslater
// strings exist // strings exist
if (!empty($strings[0])) { if (!empty($strings[0])) {
// remove quotes // remove quotes
$strings[0] = array_map(function($v){ return substr($v, 1, -1);}, $strings[0]); $strings[0] = array_map(function ($v) { return substr($v, 1, -1);}, $strings[0]);
// filter duplicate strings (only check first string for plurals form) // filter duplicate strings (only check first string for plurals form)
if (!in_array($strings[0][0], $duplicate)) { if (!in_array($strings[0][0], $duplicate)) {
// fill final array // fill final array
$final_strings[] = [$strings[0], $lines[$p]]; $final_strings[] = [$strings[0], $lines[$p]];
$duplicate[] = $strings[0][0]; $duplicate[] = $strings[0][0];
} }
} }
$p++; $p++;
} }
return $final_strings; return $final_strings;
} }
@ -500,12 +510,12 @@ class dcTranslater
$duplicate = $final_strings = $lines = []; $duplicate = $final_strings = $lines = [];
// split content by line to combine match/line on the end // split content by line to combine match/line on the end
$content = str_replace("\r\n", "\n", $content); $content = str_replace("\r\n", "\n", $content);
$o = 0; $o = 0;
$parts = explode("\n", $content); $parts = explode("\n", $content);
foreach($parts as $li => $part) { foreach ($parts as $li => $part) {
$m = explode('{{' . $func . ' ', $part); $m = explode('{{' . $func . ' ', $part);
for($i = 1; $i < count($m); $i++) { for ($i = 1; $i < count($m); $i++) {
$lines[$o] = $li+1; $lines[$o] = $li + 1;
$o++; $o++;
} }
} }
@ -515,18 +525,19 @@ class dcTranslater
} }
// walk through parts // walk through parts
$p = 0; $p = 0;
foreach($parts[1] as $part) { foreach ($parts[1] as $part) {
// strings exist // strings exist
if (!empty($part)) { if (!empty($part)) {
// filter duplicate strings // filter duplicate strings
if (!in_array($part, $duplicate)) { if (!in_array($part, $duplicate)) {
// fill final array // fill final array
$final_strings[] = [[$part], $lines[$p]]; $final_strings[] = [[$part], $lines[$p]];
$duplicate[] = $part; $duplicate[] = $part;
} }
} }
$p++; $p++;
} }
return $final_strings; return $final_strings;
} }
//@} //@}

View File

@ -18,7 +18,7 @@ class translaterProposals
{ {
public $core; public $core;
private $stack = array(); private $stack = [];
public function __construct($core) public function __construct($core)
{ {

View File

@ -10,7 +10,6 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_CONTEXT_ADMIN')) { if (!defined('DC_CONTEXT_ADMIN')) {
return; return;
} }
@ -25,13 +24,13 @@ class translaterRest
{ {
public static function getProposal($core, $get) public static function getProposal($core, $get)
{ {
$from = !empty($get['langFrom']) ? trim($get['langFrom']) : ''; $from = !empty($get['langFrom']) ? trim($get['langFrom']) : '';
$to = !empty($get['langTo']) ? trim($get['langTo']) : ''; $to = !empty($get['langTo']) ? trim($get['langTo']) : '';
$tool = !empty($get['langTool']) ? trim($get['langTool']) : ''; $tool = !empty($get['langTool']) ? trim($get['langTool']) : '';
$str_in = !empty($get['langStr']) ? trim($get['langStr']) : ''; $str_in = !empty($get['langStr']) ? trim($get['langStr']) : '';
$str_in = text::toUTF8($str_in); $str_in = text::toUTF8($str_in);
$str_in = trim($str_in); $str_in = trim($str_in);
$str_out = ''; $str_out = '';
$rsp = new xmlTag(); $rsp = new xmlTag();
@ -51,19 +50,20 @@ class translaterRest
throw new Exception(__('Translation tool is not configured')); throw new Exception(__('Translation tool is not configured'));
} }
$str_out = (string) $translater->proposal->getTool($tool)->translate($str_in ,$from, $to); $str_out = (string) $translater->proposal->getTool($tool)->translate($str_in, $from, $to);
} }
$x = new xmlTag('proposal'); $x = new xmlTag('proposal');
$x->lang_from = $from; $x->lang_from = $from;
$x->lang_to = $to; $x->lang_to = $to;
$x->tool = $tool; $x->tool = $tool;
$x->str_from = $str_in; $x->str_from = $str_in;
$x->str_to = text::toUTF8(html::decodeEntities($str_out)); $x->str_to = text::toUTF8(html::decodeEntities($str_out));
$rsp->insertNode($x); $rsp->insertNode($x);
} catch (Exception $e) { } catch (Exception $e) {
$core->error->add($e->getMessage()); $core->error->add($e->getMessage());
} }
return $rsp; return $rsp;
} }
} }

View File

@ -10,7 +10,6 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_CONTEXT_ADMIN')) { if (!defined('DC_CONTEXT_ADMIN')) {
return; return;
} }
@ -22,9 +21,9 @@ if (!defined('DC_CONTEXT_ADMIN')) {
*/ */
class googleProposalTool extends translaterProposalTool class googleProposalTool extends translaterProposalTool
{ {
private $api = 'https://www.googleapis.com/language/translate/v2'; private $api = 'https://www.googleapis.com/language/translate/v2';
private $agent = 'dcTranslater - http://jcd.lv/?q=translater'; private $agent = 'dcTranslater - http://jcd.lv/?q=translater';
private $key = null; //ex: AsSDqsGsfdSDSQFQsfedj9bnzY390aIg-1d private $key = null; //ex: AsSDqsGsfdSDSQFQsfedj9bnzY390aIg-1d
protected function setup() protected function setup()
{ {
@ -41,7 +40,7 @@ class googleProposalTool extends translaterProposalTool
'<p><label class="classic" for="translater_google_proposal_key">' . '<p><label class="classic" for="translater_google_proposal_key">' .
__('API Console Single Access Key') . '<br />' . __('API Console Single Access Key') . '<br />' .
form::field('translater_google_proposal_key', 65, 255, $this->key) . form::field('translater_google_proposal_key', 65, 255, $this->key) .
'</label></p>'. '</label></p>' .
'<p>' . __('You must have on Google API console:') . '</p>' . '<p>' . __('You must have on Google API console:') . '</p>' .
'<ul>' . '<ul>' .
'<li><a href="https://code.google.com/apis/console/#access">' . __('A single access API key') . '</a></li>' . '<li><a href="https://code.google.com/apis/console/#access">' . __('A single access API key') . '</a></li>' .
@ -60,19 +59,19 @@ class googleProposalTool extends translaterProposalTool
public function translate($str, $from, $to) public function translate($str, $from, $to)
{ {
try { try {
$data = array( $data = [
'key' => $this->key, 'key' => $this->key,
'q' => $str, 'q' => $str,
'source' => $from, 'source' => $from,
'target' => $to 'target' => $to
); ];
$path = ''; $path = '';
$client = netHttp::initClient($this->api, $path); $client = netHttp::initClient($this->api, $path);
$client->setUserAgent($this->agent); $client->setUserAgent($this->agent);
$client->useGzip(false); $client->useGzip(false);
$client->setPersistReferers(false); $client->setPersistReferers(false);
$client->get($path,$data); $client->get($path, $data);
$rs = $client->getContent(); $rs = $client->getContent();
@ -89,8 +88,9 @@ class googleProposalTool extends translaterProposalTool
} }
return $dec->data->translations[0]->translatedText; return $dec->data->translations[0]->translatedText;
} catch (Exception $e) {
} }
catch (Exception $e) {}
return ''; return '';
} }
} }

View File

@ -10,7 +10,6 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_CONTEXT_ADMIN')) { if (!defined('DC_CONTEXT_ADMIN')) {
return; return;
} }
@ -70,7 +69,8 @@ class microsoftProposalTool extends translaterProposalTool
{ {
try { try {
return $this->doYourFuckingJob($this->client, $this->secret, $str, $from, $to); return $this->doYourFuckingJob($this->client, $this->secret, $str, $from, $to);
} catch (Exception $e) {} } catch (Exception $e) {
}
return ''; return '';
} }
@ -83,20 +83,20 @@ class microsoftProposalTool extends translaterProposalTool
{ {
try { try {
//Client ID of the application. //Client ID of the application.
$clientID = $client; $clientID = $client;
//Client Secret key of the application. //Client Secret key of the application.
$clientSecret = $secret; $clientSecret = $secret;
//OAuth Url. //OAuth Url.
$authUrl = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13/"; $authUrl = 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13/';
//Application Scope Url //Application Scope Url
$scopeUrl = "http://api.microsofttranslator.com"; $scopeUrl = 'http://api.microsofttranslator.com';
//Application grant type //Application grant type
$grantType = "client_credentials"; $grantType = 'client_credentials';
//Get the Access token. //Get the Access token.
$accessToken = $this->getTokens($grantType, $scopeUrl, $clientID, $clientSecret, $authUrl); $accessToken = $this->getTokens($grantType, $scopeUrl, $clientID, $clientSecret, $authUrl);
//Create the authorization Header string. //Create the authorization Header string.
$authHeader = "Authorization: Bearer " . $accessToken; $authHeader = 'Authorization: Bearer ' . $accessToken;
//Set the params.// //Set the params.//
$fromLanguage = $from; $fromLanguage = $from;
@ -105,7 +105,7 @@ class microsoftProposalTool extends translaterProposalTool
$contentType = 'text/plain'; $contentType = 'text/plain';
$category = 'general'; $category = 'general';
$params = "text=" . urlencode($inputStr) . "&to=" . $toLanguage . "&from=" . $fromLanguage; $params = 'text=' . urlencode($inputStr) . '&to=' . $toLanguage . '&from=' . $fromLanguage;
$translateUrl = "http://api.microsofttranslator.com/v2/Http.svc/Translate?$params"; $translateUrl = "http://api.microsofttranslator.com/v2/Http.svc/Translate?$params";
//Get the curlResponse. //Get the curlResponse.
@ -113,8 +113,8 @@ class microsoftProposalTool extends translaterProposalTool
//Interprets a string of XML into an object. //Interprets a string of XML into an object.
$xmlObj = simplexml_load_string($curlResponse); $xmlObj = simplexml_load_string($curlResponse);
foreach((array)$xmlObj[0] as $val){ foreach ((array) $xmlObj[0] as $val) {
$translatedStr = $val; $translatedStr = $val;
} }
return (string) $translatedStr; return (string) $translatedStr;
@ -148,40 +148,42 @@ class microsoftProposalTool extends translaterProposalTool
//Initialize the Curl Session. //Initialize the Curl Session.
$ch = curl_init(); $ch = curl_init();
//Create the request Array. //Create the request Array.
$paramArr = array ( $paramArr = [
'grant_type' => $grantType, 'grant_type' => $grantType,
'scope' => $scopeUrl, 'scope' => $scopeUrl,
'client_id' => $clientID, 'client_id' => $clientID,
'client_secret' => $clientSecret 'client_secret' => $clientSecret
); ];
//Create an Http Query.// //Create an Http Query.//
$paramArr = http_build_query($paramArr); $paramArr = http_build_query($paramArr);
//Set the Curl URL. //Set the Curl URL.
curl_setopt($ch, CURLOPT_URL, $authUrl); curl_setopt($ch, CURLOPT_URL, $authUrl);
//Set HTTP POST Request. //Set HTTP POST Request.
curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POST, true);
//Set data to POST in HTTP "POST" Operation. //Set data to POST in HTTP "POST" Operation.
curl_setopt($ch, CURLOPT_POSTFIELDS, $paramArr); curl_setopt($ch, CURLOPT_POSTFIELDS, $paramArr);
//CURLOPT_RETURNTRANSFER- TRUE to return the transfer as a string of the return value of curl_exec(). //CURLOPT_RETURNTRANSFER- TRUE to return the transfer as a string of the return value of curl_exec().
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//CURLOPT_SSL_VERIFYPEER- Set FALSE to stop cURL from verifying the peer's certificate. //CURLOPT_SSL_VERIFYPEER- Set FALSE to stop cURL from verifying the peer's certificate.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//Execute the cURL session. //Execute the cURL session.
$strResponse = curl_exec($ch); $strResponse = curl_exec($ch);
//Get the Error Code returned by Curl. //Get the Error Code returned by Curl.
$curlErrno = curl_errno($ch); $curlErrno = curl_errno($ch);
if($curlErrno) { if ($curlErrno) {
$curlError = curl_error($ch); $curlError = curl_error($ch);
curl_close($ch); curl_close($ch);
throw new Exception($curlError); throw new Exception($curlError);
} }
//Close the Curl Session. //Close the Curl Session.
curl_close($ch); curl_close($ch);
//Decode the returned JSON string. //Decode the returned JSON string.
$objResponse = json_decode($strResponse); $objResponse = json_decode($strResponse);
if (@$objResponse->error){ if (@$objResponse->error) {
throw new Exception($objResponse->error_description); throw new Exception($objResponse->error_description);
} }
return $objResponse->access_token; return $objResponse->access_token;
} catch (Exception $e) { } catch (Exception $e) {
throw $e; throw $e;
@ -198,17 +200,18 @@ class microsoftProposalTool extends translaterProposalTool
* @return string. * @return string.
* *
*/ */
private function curlRequest($url, $authHeader) { private function curlRequest($url, $authHeader)
{
//Initialize the Curl Session. //Initialize the Curl Session.
$ch = curl_init(); $ch = curl_init();
//Set the Curl url. //Set the Curl url.
curl_setopt ($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_URL, $url);
//Set the HTTP HEADER Fields. //Set the HTTP HEADER Fields.
curl_setopt ($ch, CURLOPT_HTTPHEADER, array($authHeader,"Content-Type: text/xml")); curl_setopt($ch, CURLOPT_HTTPHEADER, [$authHeader,'Content-Type: text/xml']);
//CURLOPT_RETURNTRANSFER- TRUE to return the transfer as a string of the return value of curl_exec(). //CURLOPT_RETURNTRANSFER- TRUE to return the transfer as a string of the return value of curl_exec().
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//CURLOPT_SSL_VERIFYPEER- Set FALSE to stop cURL from verifying the peer's certificate. //CURLOPT_SSL_VERIFYPEER- Set FALSE to stop cURL from verifying the peer's certificate.
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, False); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//Execute the cURL session. //Execute the cURL session.
$curlResponse = curl_exec($ch); $curlResponse = curl_exec($ch);
//Get the Error Code returned by Curl. //Get the Error Code returned by Curl.
@ -216,10 +219,12 @@ class microsoftProposalTool extends translaterProposalTool
if ($curlErrno) { if ($curlErrno) {
$curlError = curl_error($ch); $curlError = curl_error($ch);
curl_close($ch); curl_close($ch);
throw new Exception($curlError); throw new Exception($curlError);
} }
//Close a cURL session. //Close a cURL session.
curl_close($ch); curl_close($ch);
return $curlResponse; return $curlResponse;
} }
} }

View File

@ -21,12 +21,12 @@ abstract class translaterProposalTool
public $core; public $core;
private $active = false; private $active = false;
private $name = 'unknow'; private $name = 'unknow';
private $desc = 'no description'; private $desc = 'no description';
/** /**
Constructor Constructor
*/ */
final public function __construct($core) final public function __construct($core)
{ {
$this->core = $core; $this->core = $core;
@ -37,7 +37,7 @@ abstract class translaterProposalTool
Set name of this tool Set name of this tool
@param string Tool's name @param string Tool's name
*/ */
final protected function setName($name) final protected function setName($name)
{ {
$this->name = (string) $name; $this->name = (string) $name;
@ -47,7 +47,7 @@ abstract class translaterProposalTool
Get name of this tool Get name of this tool
@return string Tool's name @return string Tool's name
*/ */
final public function getName() final public function getName()
{ {
return $this->name; return $this->name;
@ -57,7 +57,7 @@ abstract class translaterProposalTool
Set description of this tool Set description of this tool
@param string Tool's description @param string Tool's description
*/ */
final protected function setDesc($desc) final protected function setDesc($desc)
{ {
$this->desc = (string) $desc; $this->desc = (string) $desc;
@ -67,7 +67,7 @@ abstract class translaterProposalTool
Get description of this tool Get description of this tool
@return string Tool's description @return string Tool's description
*/ */
final public function getDesc() final public function getDesc()
{ {
return $this->desc; return $this->desc;
@ -77,7 +77,7 @@ abstract class translaterProposalTool
Set tool as (un)active Set tool as (un)active
@param boolean $active True to set it as active @param boolean $active True to set it as active
*/ */
final protected function setActive($active) final protected function setActive($active)
{ {
$this->active = (boolean) $active; $this->active = (boolean) $active;
@ -87,7 +87,7 @@ abstract class translaterProposalTool
Check if this tool is active Check if this tool is active
@return boolean True if it is active @return boolean True if it is active
*/ */
final public function isActive() final public function isActive()
{ {
return $this->active; return $this->active;
@ -95,19 +95,19 @@ abstract class translaterProposalTool
/** /**
Set tool's info - using setName(),setDesc(),setActive() Set tool's info - using setName(),setDesc(),setActive()
*/ */
abstract protected function setup(); abstract protected function setup();
/** /**
Get configuration interface Get configuration interface
@return Form field @return Form field
*/ */
abstract public function form(); abstract public function form();
/** /**
Save configuration Save configuration
*/ */
abstract public function save(); abstract public function save();
/** /**
@ -117,6 +117,6 @@ abstract class translaterProposalTool
@param string $from Source language code @param string $from Source language code
@param string to Destination language code @param string to Destination language code
@return Translated string @return Translated string
*/ */
abstract public function translate($str,$from,$to); abstract public function translate($str, $from, $to);
} }

128
index.php
View File

@ -10,7 +10,6 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_CONTEXT_ADMIN')) { if (!defined('DC_CONTEXT_ADMIN')) {
return; return;
} }
@ -19,10 +18,10 @@ dcPage::checkSuper();
$translater = new dcTranslater($core); $translater = new dcTranslater($core);
$type = $_REQUEST['type'] ?? $translater->start_page ?: ''; $type = $_REQUEST['type'] ?? $translater->start_page ?: '';
$module = $_REQUEST['module'] ?? ''; $module = $_REQUEST['module'] ?? '';
$lang = $_REQUEST['lang'] ?? ''; $lang = $_REQUEST['lang'] ?? '';
$action = $_POST['action'] ?? ''; $action = $_POST['action'] ?? '';
if (!in_array($type, ['plugin', 'theme'])) { if (!in_array($type, ['plugin', 'theme'])) {
$type = ''; $type = '';
@ -31,7 +30,7 @@ if (!in_array($type, ['plugin', 'theme'])) {
if (!empty($type) && !empty($module)) { if (!empty($type) && !empty($module)) {
try { try {
$module = $translater->getModule($type, $module); $module = $translater->getModule($type, $module);
} catch(Exception $e) { } catch (Exception $e) {
$core->error->add($e->getMessage()); $core->error->add($e->getMessage());
$module = ''; $module = '';
} }
@ -40,7 +39,7 @@ if (!empty($type) && !empty($module)) {
if (!empty($module) && !empty($lang)) { if (!empty($module) && !empty($lang)) {
try { try {
$lang = $translater->getLang($module, $lang); $lang = $translater->getLang($module, $lang);
} catch(Exception $e) { } catch (Exception $e) {
$core->error->add($e->getMessage()); $core->error->add($e->getMessage());
$lang = ''; $lang = '';
} }
@ -53,10 +52,10 @@ if (empty($type)) {
$breadcrumb[$type == 'plugin' ? __('Plugins') : __('Themes')] = ''; $breadcrumb[$type == 'plugin' ? __('Plugins') : __('Themes')] = '';
} elseif (empty($lang)) { } elseif (empty($lang)) {
$breadcrumb[$type == 'plugin' ? __('Plugins') : __('Themes')] = $core->adminurl->get('translater', ['type' => $type]); $breadcrumb[$type == 'plugin' ? __('Plugins') : __('Themes')] = $core->adminurl->get('translater', ['type' => $type]);
$breadcrumb[html::escapeHTML($module->name)] = ''; $breadcrumb[html::escapeHTML($module->name)] = '';
} elseif (!empty($lang)) { } elseif (!empty($lang)) {
$breadcrumb[$type == 'plugin' ? __('Plugins') : __('Themes')] = $core->adminurl->get('translater', ['type' => $type]); $breadcrumb[$type == 'plugin' ? __('Plugins') : __('Themes')] = $core->adminurl->get('translater', ['type' => $type]);
$breadcrumb[html::escapeHTML($module->name)] = $core->adminurl->get('translater', ['type' => $type, 'module' => $module->id]); $breadcrumb[html::escapeHTML($module->name)] = $core->adminurl->get('translater', ['type' => $type, 'module' => $module->id]);
$breadcrumb[html::escapeHTML(sprintf(__('%s language edition'), $lang->name))] = ''; $breadcrumb[html::escapeHTML(sprintf(__('%s language edition'), $lang->name))] = '';
} }
@ -66,7 +65,7 @@ try {
throw new Exception(__('Nothing to backup')); throw new Exception(__('Nothing to backup'));
} }
$module_codes = $module->getUsedlangs(); $module_codes = $module->getUsedlangs();
foreach($module_codes as $code_id) { foreach ($module_codes as $code_id) {
if (in_array($code_id, $_POST['codes'])) { if (in_array($code_id, $_POST['codes'])) {
$module->createBackup($code_id); $module->createBackup($code_id);
} }
@ -77,10 +76,10 @@ try {
if ($action == 'module_restore_backup') { if ($action == 'module_restore_backup') {
if (empty($module) || empty($_POST['files'])) { if (empty($module) || empty($_POST['files'])) {
throw New Exception(__('Nothing to restore')); throw new Exception(__('Nothing to restore'));
} }
$module_backups = $module->getBackups(true); $module_backups = $module->getBackups(true);
foreach($module_backups as $backup_file) { foreach ($module_backups as $backup_file) {
if (in_array($backup_file, $_POST['files'])) { if (in_array($backup_file, $_POST['files'])) {
$module->restoreBackup($backup_file); $module->restoreBackup($backup_file);
} }
@ -91,10 +90,10 @@ try {
if ($action == 'module_delete_backup') { if ($action == 'module_delete_backup') {
if (empty($module) || empty($_POST['files'])) { if (empty($module) || empty($_POST['files'])) {
throw New Exception(__('Nothing to delete')); throw new Exception(__('Nothing to delete'));
} }
$module_backups = $module->getBackups(true); $module_backups = $module->getBackups(true);
foreach($module_backups as $backup_file) { foreach ($module_backups as $backup_file) {
if (in_array($backup_file, $_POST['files'])) { if (in_array($backup_file, $_POST['files'])) {
$module->deleteBackup($backup_file); $module->deleteBackup($backup_file);
} }
@ -138,7 +137,7 @@ try {
throw new Exception(__('Nothing to delete')); throw new Exception(__('Nothing to delete'));
} }
$module_codes = $module->getUsedlangs(); $module_codes = $module->getUsedlangs();
foreach($module_codes as $code_id) { foreach ($module_codes as $code_id) {
if (in_array($code_id, $_POST['codes'])) { if (in_array($code_id, $_POST['codes'])) {
$module->delLang($code_id); $module->delLang($code_id);
} }
@ -152,7 +151,7 @@ try {
throw new Exception(__('Nothing to update')); throw new Exception(__('Nothing to update'));
} }
if (!empty($_POST['update_group'])) { if (!empty($_POST['update_group'])) {
foreach($_POST['entries'] as $i => $entry) { foreach ($_POST['entries'] as $i => $entry) {
if (isset($entry['check']) && isset($_POST['multigroup'])) { if (isset($entry['check']) && isset($_POST['multigroup'])) {
$_POST['entries'][$i]['group'] = $_POST['multigroup']; $_POST['entries'][$i]['group'] = $_POST['multigroup'];
} }
@ -162,9 +161,7 @@ try {
dcPage::addSuccessNotice(__('Language successfully updated')); dcPage::addSuccessNotice(__('Language successfully updated'));
$core->adminurl->redirect('translater', ['type' => $type, 'module' => $module->id, 'lang' => $_POST['code']]); $core->adminurl->redirect('translater', ['type' => $type, 'module' => $module->id, 'lang' => $_POST['code']]);
} }
} catch (Exception $e) { } catch (Exception $e) {
$core->error->add($e->getMessage()); $core->error->add($e->getMessage());
} }
@ -192,7 +189,7 @@ if (empty($module) && $type != '') {
// modules list // modules list
echo '<form id="theme-form" method="post" action="' . $core->adminurl->get('translater', ['type' => 'plugin']) . '">'; echo '<form id="theme-form" method="post" action="' . $core->adminurl->get('translater', ['type' => 'plugin']) . '">';
$res = ''; $res = '';
$modules = $translater->getModules($type); $modules = $translater->getModules($type);
ksort($modules); ksort($modules);
foreach ($modules as $module) { foreach ($modules as $module) {
@ -223,7 +220,7 @@ if (empty($module) && $type != '') {
$code_id $code_id
); );
} else { } else {
$codes[$code_id] = html::escapeHTML($code_name) . '(' .$code_id . ')'; $codes[$code_id] = html::escapeHTML($code_name) . '(' . $code_id . ')';
} }
} }
$res .= sprintf( $res .= sprintf(
@ -237,7 +234,7 @@ if (empty($module) && $type != '') {
echo ' echo '
<div class="table-outer"> <div class="table-outer">
<table class="clear"> <table class="clear">
<caption>' . sprintf(__('Modules list of type "%s"'), $type) .'</caption> <caption>' . sprintf(__('Modules list of type "%s"'), $type) . '</caption>
<tr> <tr>
<th class="nowrap">' . __('Id') . '</th> <th class="nowrap">' . __('Id') . '</th>
<th class="nowrap">' . __('Languages') . '</th> <th class="nowrap">' . __('Languages') . '</th>
@ -246,17 +243,15 @@ if (empty($module) && $type != '') {
</tr>' . </tr>' .
$res . $res .
'</table></div>'; '</table></div>';
} else { } else {
echo '<tr><td colspan="6">' . __('There is no editable modules') . '</td></tr>'; echo '<tr><td colspan="6">' . __('There is no editable modules') . '</td></tr>';
} }
echo '</form>'; echo '</form>';
dcPage::helpBlock('translater.type'); dcPage::helpBlock('translater.type');
} elseif (!empty($module) && empty($lang)) { } elseif (!empty($module) && empty($lang)) {
$codes = $module->getUsedLangs(); $codes = $module->getUsedLangs();
$backups = $module->getBackups(); $backups = $module->getBackups();
$unused_codes = $module->getUnusedLangs(); $unused_codes = $module->getUnusedLangs();
// module summary // module summary
@ -274,7 +269,7 @@ if (empty($module) && $type != '') {
'<div class="clear fieldset"><h3>' . __('Translations') . '</h3>' . '<div class="clear fieldset"><h3>' . __('Translations') . '</h3>' .
'<form id="module-translations-form" method="post" action="' . $core->adminurl->get('translater') . '">' . '<form id="module-translations-form" method="post" action="' . $core->adminurl->get('translater') . '">' .
'<table class="clear maximal">' . '<table class="clear maximal">' .
'<caption>' . __('Existing languages translations') .'</caption>' . '<caption>' . __('Existing languages translations') . '</caption>' .
'<tr>' . '<tr>' .
'<th class="nowrap" colspan="2">' . __('Language') . '</th>' . '<th class="nowrap" colspan="2">' . __('Language') . '</th>' .
'<th class="nowrap">' . __('Code') . '</th>' . '<th class="nowrap">' . __('Code') . '</th>' .
@ -282,7 +277,7 @@ if (empty($module) && $type != '') {
'<th class="nowrap">' . __('Last backup') . '</th>' . '<th class="nowrap">' . __('Last backup') . '</th>' .
'</tr>'; '</tr>';
foreach($codes AS $code_name => $code_id) { foreach ($codes as $code_name => $code_id) {
echo echo
'<tr class="line">' . '<tr class="line">' .
'<td class="minimal">' . form::checkbox(['codes[]', 'existing_code_' . $code_id], $code_id, '', '', '', false) . '</td>' . '<td class="minimal">' . form::checkbox(['codes[]', 'existing_code_' . $code_id], $code_id, '', '', '', false) . '</td>' .
@ -294,7 +289,7 @@ if (empty($module) && $type != '') {
'<td class="nowrap maximal"> ' . $code_id . '</td>'; '<td class="nowrap maximal"> ' . $code_id . '</td>';
if (isset($backups[$code_id])) { if (isset($backups[$code_id])) {
foreach($backups[$code_id] AS $file => $info) { foreach ($backups[$code_id] as $file => $info) {
$time[$code_id] = isset($time[$code_id]) && $time[$code_id] > $info['time'] ? $time[$code_id] = isset($time[$code_id]) && $time[$code_id] > $info['time'] ?
$time[$code_id] : $info['time']; $time[$code_id] : $info['time'];
} }
@ -343,8 +338,7 @@ if (empty($module) && $type != '') {
'<th class="nowrap">' . __('Size') . '</th>' . '<th class="nowrap">' . __('Size') . '</th>' .
'</tr>'; '</tr>';
$table_line = $table_line = '<tr class="line">' .
'<tr class="line">' .
'<td class="minimal">%s</td>' . '<td class="minimal">%s</td>' .
'<td class="nowrap"><label for="%s">%s</label></td>' . '<td class="nowrap"><label for="%s">%s</label></td>' .
'<td class="nowrap maximal">%s</td>' . '<td class="nowrap maximal">%s</td>' .
@ -353,14 +347,16 @@ if (empty($module) && $type != '') {
'<td class="nowrap count">%s</td>' . '<td class="nowrap count">%s</td>' .
'</tr>'; '</tr>';
$i=0; $i = 0;
foreach($backups as $backup_codes) { foreach ($backups as $backup_codes) {
foreach($backup_codes as $backup_file => $backup_code) { foreach ($backup_codes as $backup_file => $backup_code) {
$i++; $i++;
$form_id = 'form_file_' . $backup_code['code'] . $backup_code['time']; $form_id = 'form_file_' . $backup_code['code'] . $backup_code['time'];
echo sprintf($table_line, echo sprintf(
$table_line,
form::checkbox(['files[]', $form_id], $backup_file, '', '', '', false), form::checkbox(['files[]', $form_id], $backup_file, '', '', '', false),
$form_id, $backup_code['name'], $form_id,
$backup_code['name'],
$backup_code['code'], $backup_code['code'],
dt::str( dt::str(
$core->blog->settings->system->date_format . ' ' . $core->blog->settings->system->time_format, $core->blog->settings->system->date_format . ' ' . $core->blog->settings->system->time_format,
@ -380,7 +376,7 @@ if (empty($module) && $type != '') {
<p class="col right">' . __('Selected backups action:') . ' ' . <p class="col right">' . __('Selected backups action:') . ' ' .
form::combo('action', [ form::combo('action', [
__('Restore backups') => 'module_restore_backup', __('Restore backups') => 'module_restore_backup',
__('Delete backups') => 'module_delete_backup' __('Delete backups') => 'module_delete_backup'
]) . ' ]) . '
<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' . <input id="do-action" type="submit" value="' . __('ok') . '" /></p>' .
$core->formNonce() . $core->formNonce() .
@ -434,7 +430,6 @@ if (empty($module) && $type != '') {
echo '</div>'; echo '</div>';
dcPage::helpBlock('translater.module'); dcPage::helpBlock('translater.module');
} elseif (!empty($lang)) { } elseif (!empty($lang)) {
$lines = $lang->getMessages(); $lines = $lang->getMessages();
@ -451,8 +446,7 @@ if (empty($module) && $type != '') {
'<th>' . __('File') . '</th>' . '<th>' . __('File') . '</th>' .
'</tr>'; '</tr>';
$table_line = $table_line = '<tr class="line%s">' .
'<tr class="line%s">' .
'<td class="nowrap minimal">%s</td>' . '<td class="nowrap minimal">%s</td>' .
'<td class="nowrap minimal">%s</td>' . '<td class="nowrap minimal">%s</td>' .
'<td>%s</td>' . '<td>%s</td>' .
@ -464,20 +458,20 @@ if (empty($module) && $type != '') {
$table_li = '<i>%s</i><br />'; $table_li = '<i>%s</i><br />';
$i = 1; $i = 1;
foreach ($lines AS $msgid => $rs) { foreach ($lines as $msgid => $rs) {
$in_dc = ($rs['in_dc'] && $translater->parse_nodc); $in_dc = ($rs['in_dc'] && $translater->parse_nodc);
$allowed_l10n_groups = array_combine($translater::$allowed_l10n_groups, $translater::$allowed_l10n_groups); $allowed_l10n_groups = array_combine($translater::$allowed_l10n_groups, $translater::$allowed_l10n_groups);
$t_msgstr = $t_files = $strin = []; $t_msgstr = $t_files = $strin = [];
foreach($rs['o_msgstrs'] as $o_msgstr) { foreach ($rs['o_msgstrs'] as $o_msgstr) {
if (!isset($strin[$o_msgstr['msgstr'][0]])) { if (!isset($strin[$o_msgstr['msgstr'][0]])) {
$strin[$o_msgstr['msgstr'][0]] = []; $strin[$o_msgstr['msgstr'][0]] = [];
} }
$strin[$o_msgstr['msgstr'][0]][] = ['module' => $o_msgstr['module'], 'file' => $o_msgstr['file']]; $strin[$o_msgstr['msgstr'][0]][] = ['module' => $o_msgstr['module'], 'file' => $o_msgstr['file']];
} }
foreach($strin as $k => $v) { foreach ($strin as $k => $v) {
$res = []; $res = [];
foreach($v as $str) { foreach ($v as $str) {
$res[] = sprintf($table_li, html::escapeHTML($str['module'] . ':' . $str['file'])); $res[] = sprintf($table_li, html::escapeHTML($str['module'] . ':' . $str['file']));
} }
$t_msgstr[] = sprintf($table_ul, html::escapeHTML($k), implode('', $res)); $t_msgstr[] = sprintf($table_ul, html::escapeHTML($k), implode('', $res));
@ -488,14 +482,17 @@ if (empty($module) && $type != '') {
$t_files[] = $rs['files'][0][0] . ':' . $rs['files'][0][1]; $t_files[] = $rs['files'][0][0] . ':' . $rs['files'][0][1];
} else { } else {
$res = []; $res = [];
foreach($rs['files'] as $location) { foreach ($rs['files'] as $location) {
$res[] = sprintf($table_li, implode(' : ', $location)); $res[] = sprintf($table_li, implode(' : ', $location));
} }
$t_files[] = sprintf($table_ul, sprintf(__('%s occurrences'), count($rs['files'])), implode('', $res));; $t_files[] = sprintf($table_ul, sprintf(__('%s occurrences'), count($rs['files'])), implode('', $res));
;
} }
} }
echo sprintf($table_line, $in_dc ? ' offline' : ' translaterline', echo sprintf(
$table_line,
$in_dc ? ' offline' : ' translaterline',
form::checkbox(['entries[' . $i . '][check]'], 1), form::checkbox(['entries[' . $i . '][check]'], 1),
form::combo(['entries[' . $i . '][group]'], $allowed_l10n_groups, $rs['group'], '', '', $in_dc), form::combo(['entries[' . $i . '][group]'], $allowed_l10n_groups, $rs['group'], '', '', $in_dc),
html::escapeHTML($msgid), html::escapeHTML($msgid),
@ -507,29 +504,31 @@ if (empty($module) && $type != '') {
if (!empty($rs['plural'])) { if (!empty($rs['plural'])) {
$t_msgstr = $strin = []; $t_msgstr = $strin = [];
foreach($lang->plural as $j => $plural) { foreach ($lang->plural as $j => $plural) {
foreach($rs['o_msgstrs'] as $o_msgstr) { foreach ($rs['o_msgstrs'] as $o_msgstr) {
if (isset($o_msgstr['msgstr'][$j+1])) { if (isset($o_msgstr['msgstr'][$j + 1])) {
if (!isset($strin[$o_msgstr['msgstr'][$j+1]])) { if (!isset($strin[$o_msgstr['msgstr'][$j + 1]])) {
$strin[$o_msgstr['msgstr'][$j+1]] = []; $strin[$o_msgstr['msgstr'][$j + 1]] = [];
} }
$strin[$o_msgstr['msgstr'][$j+1]][] = ['module' => $o_msgstr['module'], 'file' => $o_msgstr['file']]; $strin[$o_msgstr['msgstr'][$j + 1]][] = ['module' => $o_msgstr['module'], 'file' => $o_msgstr['file']];
} }
} }
foreach($strin as $k => $v) { foreach ($strin as $k => $v) {
$res = []; $res = [];
foreach($v as $str) { foreach ($v as $str) {
$res[] = sprintf($table_li, html::escapeHTML($str['module'] . ':' . $str['file'])); $res[] = sprintf($table_li, html::escapeHTML($str['module'] . ':' . $str['file']));
} }
$t_msgstr[] = sprintf($table_ul, html::escapeHTML($k), implode('', $res)); $t_msgstr[] = sprintf($table_ul, html::escapeHTML($k), implode('', $res));
} }
echo sprintf($table_line, $in_dc ? ' offline' : ' translaterline', echo sprintf(
$table_line,
$in_dc ? ' offline' : ' translaterline',
'+', '+',
sprintf(__('Plural "%s"'), $plural), sprintf(__('Plural "%s"'), $plural),
sprintf(__('Plural form of "%s"'), $rs['plural']), sprintf(__('Plural form of "%s"'), $rs['plural']),
form::hidden(['entries[' . $i . '][msgid_plural]'], html::escapeHTML($rs['plural'])) . form::hidden(['entries[' . $i . '][msgid_plural]'], html::escapeHTML($rs['plural'])) .
form::field(['entries[' . $i . '][msgstr][' . $j+1 . ']'], 48, 255, html::escapeHTML($rs['msgstr'][$j+1] ?? ''), '', '', $in_dc), form::field(['entries[' . $i . '][msgstr][' . $j + 1 . ']'], 48, 255, html::escapeHTML($rs['msgstr'][$j + 1] ?? ''), '', '', $in_dc),
implode('', $t_msgstr), implode('', $t_msgstr),
'' ''
); );
@ -537,7 +536,9 @@ if (empty($module) && $type != '') {
} }
$i++; $i++;
} }
echo sprintf($table_line, ' offline', echo sprintf(
$table_line,
' offline',
form::checkbox(['entries[' . $i . '][check]'], 1), form::checkbox(['entries[' . $i . '][check]'], 1),
form::combo(['entries[' . $i . '][group]'], $allowed_l10n_groups, 'main'), form::combo(['entries[' . $i . '][group]'], $allowed_l10n_groups, 'main'),
form::field(['entries[' . $i . '][msgid]'], 48, 255, ''), form::field(['entries[' . $i . '][msgid]'], 48, 255, ''),
@ -570,7 +571,6 @@ if (empty($module) && $type != '') {
'</div>'; '</div>';
dcPage::helpBlock('translater.lang'); dcPage::helpBlock('translater.lang');
} else { } else {
$line = '<li><a href="%s"%s>%s</a></li>'; $line = '<li><a href="%s"%s>%s</a></li>';
echo '<h4><i>' . __('Translate your Dotclear plugins and themes') . '</i></h4>' . echo '<h4><i>' . __('Translate your Dotclear plugins and themes') . '</i></h4>' .
@ -580,12 +580,14 @@ if (empty($module) && $type != '') {
$line, $line,
$core->adminurl->get('translater', ['type' => 'plugin']), $core->adminurl->get('translater', ['type' => 'plugin']),
$type == 'plugin' ? ' class="active"' : '', $type == 'plugin' ? ' class="active"' : '',
__('Translate plugins')) . __('Translate plugins')
) .
sprintf( sprintf(
$line, $line,
$core->adminurl->get('translater', ['type' => 'theme']), $core->adminurl->get('translater', ['type' => 'theme']),
$type == 'theme' ? ' class="active"' : '', $type == 'theme' ? ' class="active"' : '',
__('Translate themes')) __('Translate themes')
)
); );
dcPage::helpBlock('translater.index'); dcPage::helpBlock('translater.index');

View File

@ -1,20 +1,19 @@
<?php <?php
# -- BEGIN LICENSE BLOCK ---------------------------------- /**
# * @brief translater, a plugin for Dotclear 2
# This file is part of translater, a plugin for Dotclear 2. *
# * @package Dotclear
# Copyright (c) 2009-2021 Jean-Christian Denis and contributors * @subpackage Plugin
# *
# Licensed under the GPL version 2.0 license. * @author Jean-Christian Denis & contributors
# A copy of this license is available in LICENSE file or at *
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * @copyright Jean-Christian Denis
# * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
# -- END LICENSE BLOCK ------------------------------------ */
if (!defined('DC_RC_PATH')) { if (!defined('DC_RC_PATH')) {
return; return;
} }
foreach(['index', 'type', 'module', 'lang', 'config'] as $v) { foreach (['index', 'type', 'module', 'lang', 'config'] as $v) {
$__resources['help']['translater.' . $v] = dirname(__FILE__) . '/help/translater.' . $v . '.html'; $__resources['help']['translater.' . $v] = dirname(__FILE__) . '/help/translater.' . $v . '.html';
} }