use Dotclear Helper

master
Jean-Christian Paul Denis 2023-04-07 23:32:00 +02:00
parent 596fa4f3c8
commit f0debe050f
Signed by: JcDenis
GPG Key ID: 1B5B8C5B90B6C951
9 changed files with 183 additions and 169 deletions

View File

@ -17,7 +17,7 @@ namespace Dotclear\Plugin\translater;
use adminModulesList; use adminModulesList;
use dcCore; use dcCore;
use Dotclear\Helper\Html\Form\Submit; use Dotclear\Helper\Html\Form\Submit;
use html; use Dotclear\Helper\Html\Html;
class BackendBehaviors class BackendBehaviors
{ {
@ -61,7 +61,7 @@ class BackendBehaviors
return null; return null;
} }
return (new Submit(['translater[' . html::escapeHTML($id) . ']', null]))->value(__('Translate'))->render(); return (new Submit(['translater[' . Html::escapeHTML($id) . ']', null]))->value(__('Translate'))->render();
} }
/** /**

View File

@ -17,7 +17,6 @@ namespace Dotclear\Plugin\translater;
use dcCore; use dcCore;
use dcNsProcess; use dcNsProcess;
use dcPage; use dcPage;
use Dotclear\Helper\Html\Form\{ use Dotclear\Helper\Html\Form\{
Checkbox, Checkbox,
Div, Div,
@ -30,6 +29,8 @@ use Dotclear\Helper\Html\Form\{
Para, Para,
Select Select
}; };
use Dotclear\Helper\Html\Html;
use Exception;
class Config extends dcNsProcess class Config extends dcNsProcess
{ {

View File

@ -1,21 +0,0 @@
<?php
/**
* @brief translater, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis & contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1);
namespace Dotclear\Plugin\translater;
use Exception as PhpException;
class Exception extends PhpException
{
}

View File

@ -17,6 +17,7 @@ namespace Dotclear\Plugin\translater;
use dcCore; use dcCore;
use dcNamespace; use dcNamespace;
use dcNsProcess; use dcNsProcess;
use Exception;
class Install extends dcNsProcess class Install extends dcNsProcess
{ {
@ -62,13 +63,13 @@ class Install extends dcNsProcess
"WHERE setting_ns = 'translater' " "WHERE setting_ns = 'translater' "
); );
while ($record->fetch()) { while ($record->fetch()) {
if (preg_match('/^translater_(.*?)$/', $record->setting_id, $match)) { if (preg_match('/^translater_(.*?)$/', $record->f('setting_id'), $match)) {
$cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME); $cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME);
$cur->setting_id = $match[1]; $cur->setField('setting_id', $match[1]);
$cur->setting_ns = My::id(); $cur->setField('setting_ns', My::id());
$cur->update( $cur->update(
"WHERE setting_id = '" . $record->setting_id . "' and setting_ns = 'translater' " . "WHERE setting_id = '" . $record->f('setting_id') . "' and setting_ns = 'translater' " .
'AND blog_id ' . (null === $record->blog_id ? 'IS NULL ' : ("= '" . dcCore::app()->con->escape($record->blog_id) . "' ")) 'AND blog_id ' . (null === $record->f('blog_id') ? 'IS NULL ' : ("= '" . dcCore::app()->con->escapeStr((string) $record->f('blog_id')) . "' "))
); );
} }
} }

View File

@ -17,10 +17,23 @@ namespace Dotclear\Plugin\translater;
use dcCore; use dcCore;
use dcNsProcess; use dcNsProcess;
use dcPage; use dcPage;
use Dotclear\Helper\File\Files;
use Dotclear\Helper\Html\Form\{
Checkbox,
File,
Form,
Hidden,
Input,
Label,
Note,
Para,
Select,
Submit,
Text
};
use Dotclear\Helper\Html\Html;
use Exception;
use dt; use dt;
use html;
use files;
use form;
class Manage extends dcNsProcess class Manage extends dcNsProcess
{ {
@ -159,11 +172,11 @@ class Manage extends dcNsProcess
$breadcrumb[$current->type == 'plugin' ? __('Plugins') : __('Themes')] = ''; $breadcrumb[$current->type == 'plugin' ? __('Plugins') : __('Themes')] = '';
} elseif (empty($current->lang)) { } elseif (empty($current->lang)) {
$breadcrumb[$current->type == 'plugin' ? __('Plugins') : __('Themes')] = dcCore::app()->adminurl?->get(My::id(), ['type' => $current->type]); $breadcrumb[$current->type == 'plugin' ? __('Plugins') : __('Themes')] = dcCore::app()->adminurl?->get(My::id(), ['type' => $current->type]);
$breadcrumb[html::escapeHTML($current->module->name)] = ''; $breadcrumb[Html::escapeHTML($current->module->name)] = '';
} elseif (!empty($current->lang)) { } elseif (!empty($current->lang)) {
$breadcrumb[$current->type == 'plugin' ? __('Plugins') : __('Themes')] = dcCore::app()->adminurl?->get(My::id(), ['type' => $current->type]); $breadcrumb[$current->type == 'plugin' ? __('Plugins') : __('Themes')] = dcCore::app()->adminurl?->get(My::id(), ['type' => $current->type]);
$breadcrumb[html::escapeHTML($current->module->name)] = dcCore::app()->adminurl?->get(My::id(), ['type' => $current->type, 'module' => $current->module->id]); $breadcrumb[Html::escapeHTML($current->module->name)] = dcCore::app()->adminurl?->get(My::id(), ['type' => $current->type, 'module' => $current->module->id]);
$breadcrumb[html::escapeHTML(sprintf(__('%s language edition'), $current->lang->name))] = ''; $breadcrumb[Html::escapeHTML(sprintf(__('%s language edition'), $current->lang->name))] = '';
} }
dcPage::openModule( dcPage::openModule(
@ -200,13 +213,13 @@ class Manage extends dcNsProcess
$res .= sprintf( $res .= sprintf(
'<tr class="line"><td class="nowrap minimal"><a href="%s" title="%s">%s</a></td>', '<tr class="line"><td class="nowrap minimal"><a href="%s" title="%s">%s</a></td>',
dcCore::app()->adminurl?->get(My::id(), ['type' => $module->type, 'module' => $module->id]), dcCore::app()->adminurl?->get(My::id(), ['type' => $module->type, 'module' => $module->id]),
html::escapeHTML(sprintf(__('Translate module %s'), __($module->name))), Html::escapeHTML(sprintf(__('Translate module %s'), __($module->name))),
html::escapeHTML($module->id) Html::escapeHTML($module->id)
); );
} else { } else {
$res .= sprintf( $res .= sprintf(
'<tr class="line offline"><td class="nowrap">%s</td>', '<tr class="line offline"><td class="nowrap">%s</td>',
html::escapeHTML($module->id) Html::escapeHTML($module->id)
); );
} }
$codes = $module->getLangs(); $codes = $module->getLangs();
@ -214,19 +227,19 @@ class Manage extends dcNsProcess
if ($module->root_writable) { if ($module->root_writable) {
$codes[$code_id] = sprintf( $codes[$code_id] = sprintf(
'<a class="wait maximal nowrap" title="%s" href="%s">%s (%s)</a>', '<a class="wait maximal nowrap" title="%s" href="%s">%s (%s)</a>',
html::escapeHTML(sprintf(__('Edit language %s of module %s'), html::escapeHTML($code_name), __($module->name))), Html::escapeHTML(sprintf(__('Edit language %s of module %s'), Html::escapeHTML($code_name), __($module->name))),
dcCore::app()->adminurl?->get(My::id(), ['type' => $module->type, 'module' => $module->id, 'lang' => $code_id]), dcCore::app()->adminurl?->get(My::id(), ['type' => $module->type, 'module' => $module->id, 'lang' => $code_id]),
html::escapeHTML($code_name), Html::escapeHTML($code_name),
$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(
'<td class="nowrap maximal">%s</td><td class="nowrap minimal">%s</td><td class="nowrap minimal count">%s</td></tr>', '<td class="nowrap maximal">%s</td><td class="nowrap minimal">%s</td><td class="nowrap minimal count">%s</td></tr>',
implode(', ', $codes), implode(', ', $codes),
html::escapeHTML(__($module->name)), Html::escapeHTML(__($module->name)),
$module->version $module->version
); );
} }
@ -280,11 +293,11 @@ class Manage extends dcNsProcess
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">' . (new Checkbox(['codes[]', 'existing_code_' . $code_id]))->value($code_id)->render() . '</td>' .
'<td class="nowrap">' . '<td class="nowrap">' .
'<a href="' . '<a href="' .
dcCore::app()->adminurl?->get(My::id(), ['type' => $current->module->type, 'module' => $current->module->id, 'lang' => $code_id]) dcCore::app()->adminurl?->get(My::id(), ['type' => $current->module->type, 'module' => $current->module->id, 'lang' => $code_id])
. '" title="' . sprintf(__('Edit %s language'), html::escapeHTML($code_name)) . '">' . $code_name . '</a>' . . '" title="' . sprintf(__('Edit %s language'), Html::escapeHTML($code_name)) . '">' . $code_name . '</a>' .
'</td>' . '</td>' .
'<td class="nowrap maximal"> ' . $code_id . '</td>'; '<td class="nowrap maximal"> ' . $code_id . '</td>';
@ -306,21 +319,23 @@ class Manage extends dcNsProcess
} }
echo '</table> echo '</table>
<div class="two-cols"> <div class="two-cols">
<p class="col checkboxes-helpers"></p> <p class="col checkboxes-helpers"></p>' .
<p class="col right">' . __('Selected languages action:') . ' ' . (new Para())->class('col right')->items(array_merge([
form::combo('action', [ (new Text('', __('Selected languages action:'))),
(new Select('action'))->items([
__('Backup languages') => 'module_create_backups', __('Backup languages') => 'module_create_backups',
__('Delete languages') => 'module_delete_codes', __('Delete languages') => 'module_delete_codes',
__('Export languages') => 'module_export_pack', __('Export languages') => 'module_export_pack',
]) . ' ]),
<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' . (new Submit('do-action'))->value(__('ok')),
dcCore::app()->formNonce() . dcCore::app()->formNonce(false),
dcCore::app()->adminurl?->getHiddenFormFields( ], dcCore::app()->adminurl?->hiddenFormFields(
My::id(), My::id(),
['type' => $current->module->type, 'module' => $current->module->id] ['type' => $current->module->type, 'module' => $current->module->id]
) . ' )
</p></div></form><p>&nbsp;</p></div>'; ))->render() .
'</div></form><p>&nbsp;</p></div>';
} }
// backups // backups
@ -355,7 +370,7 @@ class Manage extends dcNsProcess
$form_id = 'form_file_' . $backup_code['code'] . $backup_code['time']; $form_id = 'form_file_' . $backup_code['code'] . $backup_code['time'];
echo sprintf( echo sprintf(
$table_line, $table_line,
form::checkbox(['files[]', $form_id], $backup_file, '', '', '', false), (new Checkbox(['files[]', $form_id]))->value($backup_file)->render(),
$form_id, $form_id,
$backup_code['name'], $backup_code['name'],
$backup_code['code'], $backup_code['code'],
@ -365,27 +380,29 @@ class Manage extends dcNsProcess
dcCore::app()->blog?->settings->get('system')->get('blog_timezone') dcCore::app()->blog?->settings->get('system')->get('blog_timezone')
), ),
$backup_code['path']['basename'], $backup_code['path']['basename'],
files::size($backup_code['size']) Files::size($backup_code['size'])
); );
} }
} }
echo ' echo '
</table> </table>
<div class="two-cols"> <div class="two-cols">
<p class="col checkboxes-helpers"></p> <p class="col checkboxes-helpers"></p>' .
<p class="col right">' . __('Selected backups action:') . ' ' . (new Para())->class('col right')->items(array_merge([
form::combo('action', [ (new Text('', __('Selected backups action:'))),
(new Select('action'))->items([
__('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>' . (new Submit('do-action'))->value(__('ok')),
dcCore::app()->formNonce() . dcCore::app()->formNonce(false),
dcCore::app()->adminurl?->getHiddenFormFields( ], dcCore::app()->adminurl?->hiddenFormFields(
My::id(), My::id(),
['type' => $current->module->type, 'module' => $current->module->id] ['type' => $current->module->type, 'module' => $current->module->id]
) . ' )
</p></div></form><p>&nbsp;</p></div>'; ))->render() .
'</div></form><p>&nbsp;</p></div>';
} }
} }
@ -394,39 +411,52 @@ class Manage extends dcNsProcess
// add language // add language
if (!empty($unused_codes)) { if (!empty($unused_codes)) {
echo '<div class="col fieldset"><h3>' . __('Add language') . '</h3> echo '<div class="col fieldset"><h3>' . __('Add language') . '</h3>
<form id="muodule-code-create-form" method="post" action="' . dcCore::app()->adminurl?->get(My::id()) . '"> <form id="muodule-code-create-form" method="post" action="' . dcCore::app()->adminurl?->get(My::id()) . '">' .
<p class="field"><label for="code">' . __('Select language:') . '</label>' . (new Para())->class('field')->items([
form::combo(['code'], array_merge(['-' => '-'], $unused_codes), (string) dcCore::app()->auth?->getInfo('user_lang')) . '</p>'; (new Label(__('Select language:')))->for('code'),
(new Select(['code']))->default((string) dcCore::app()->auth?->getInfo('user_lang'))->items(array_merge(['-' => '-'], $unused_codes)),
])->render();
if (empty($codes)) { if (empty($codes)) {
echo '<p>' . form::hidden(['from'], '') . '</p>'; echo (new Para())->items([(new Hidden(['from'], ''))])->render();
} else { } else {
echo echo
'<p class="field"><label for="from">' . __('Copy from language:') . '</label>' . (new Para())->class('field')->items([
form::combo(['from'], array_merge(['-' => ''], $codes)) . ' (' . __('optionnal') . ')</p>'; (new Label(__('Copy from language:')))->for('from'),
(new Select(['from']))->items(array_merge(['-' => ''], $codes)),
(new Note())->class('form-note')->text(__('optionnal')),
])->render();
} }
echo ' echo
<p><input type="submit" name="save" value="' . __('Create') . '" />' . (new Para())->items(array_merge([
dcCore::app()->formNonce() . (new Submit(['save']))->value(__('Create')),
dcCore::app()->adminurl?->getHiddenFormFields( dcCore::app()->formNonce(false),
], dcCore::app()->adminurl?->hiddenFormFields(
My::id(), My::id(),
['type' => $current->module->type, 'module' => $current->module->id, 'action' => 'module_add_code'] ['type' => $current->module->type, 'module' => $current->module->id, 'action' => 'module_add_code']
) . ' )
</p></form><p>&nbsp;</p></div>'; ))->render() .
'</form><p>&nbsp;</p></div>';
} }
// Import // Import
echo '<div class="col fieldset"><h3>' . __('Import') . '</h3> echo '<div class="col fieldset"><h3>' . __('Import') . '</h3>' .
<form id="module-pack-import-form" method="post" action="' . dcCore::app()->adminurl?->get(My::id()) . '" enctype="multipart/form-data"> (new Form('module-pack-import-form'))->method('post')->action(dcCore::app()->adminurl?->get(My::id()))->extra('enctype="multipart/form-data"')->fields([
<p><label for="packfile">' . __('Select languages package to import:') . '<label> ' . (new Para())->items([
'<input id="packfile" type="file" name="packfile" /></p> (new Label(__('Select languages package to import:')))->for('packfile'),
<p> (new File('packfile')),
<input type="submit" name="save" value="' . __('Import') . '" />' .
dcCore::app()->formNonce() . ]),
dcCore::app()->adminurl?->getHiddenFormFields( (new Para())->items(array_merge([
(new Submit(['save']))->value(__('Import')),
dcCore::app()->formNonce(false),
], dcCore::app()->adminurl?->hiddenFormFields(
My::id(), My::id(),
['type' => $current->module->type, 'module' => $current->module->id, 'action' => 'module_import_pack'] ['type' => $current->module->type, 'module' => $current->module->id, 'action' => 'module_import_pack']
) . ' )
</p></form><p>&nbsp;</p></div>'; )),
])->render() .
'<p>&nbsp;</p></div>';
echo '</div>'; echo '</div>';
@ -473,9 +503,9 @@ class Manage extends dcNsProcess
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((string) $k), implode('', $res)); $t_msgstr[] = sprintf($table_ul, Html::escapeHTML((string) $k), implode('', $res));
} }
if (!empty($rs['files'][0])) { if (!empty($rs['files'][0])) {
@ -494,11 +524,11 @@ class Manage extends dcNsProcess
echo sprintf( echo sprintf(
$table_line, $table_line,
$in_dc ? ' offline' : ' translaterline', $in_dc ? ' offline' : ' translaterline',
form::checkbox(['entries[' . $i . '][check]'], 1), (new Checkbox(['entries[' . $i . '][check]']))->value(1)->render(),
form::combo(['entries[' . $i . '][group]'], My::l10nGroupsCombo(), $rs['group'], '', '', $in_dc), (new Select(['entries[' . $i . '][group]']))->default($rs['group'])->items(My::l10nGroupsCombo())->disabled($in_dc)->render(),
html::escapeHTML($msgid), Html::escapeHTML($msgid),
form::hidden(['entries[' . $i . '][msgid]'], html::escapeHTML($msgid)) . (new Hidden(['entries[' . $i . '][msgid]'], Html::escapeHTML($msgid)))->render() .
form::field(['entries[' . $i . '][msgstr][0]'], 48, 255, html::escapeHTML($rs['msgstr'][0]), '', '', $in_dc), (new Input(['entries[' . $i . '][msgstr][0]']))->size(48)->maxlenght(255)->value(Html::escapeHTML($rs['msgstr'][0]))->disabled($in_dc)->render(),
implode('', $t_msgstr), implode('', $t_msgstr),
implode('', $t_files) implode('', $t_files)
); );
@ -517,9 +547,9 @@ class Manage extends dcNsProcess
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((string) $k), implode('', $res)); $t_msgstr[] = sprintf($table_ul, Html::escapeHTML((string) $k), implode('', $res));
} }
echo sprintf( echo sprintf(
@ -528,8 +558,8 @@ class Manage extends dcNsProcess
'+', '+',
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'])) . (new Hidden(['entries[' . $i . '][msgid_plural]'], Html::escapeHTML($rs['plural'])))->render() .
form::field(['entries[' . $i . '][msgstr][' . ($j + 1) . ']'], 48, 255, html::escapeHTML($rs['msgstr'][$j + 1] ?? ''), '', '', $in_dc), (new Input(['entries[' . $i . '][msgstr][' . ($j + 1) . ']']))->size(48)->maxlenght(255)->value(Html::escapeHTML($rs['msgstr'][$j + 1] ?? ''))->disbaled($in_dc)->render(),
implode('', $t_msgstr), implode('', $t_msgstr),
'' ''
); );
@ -540,10 +570,10 @@ class Manage extends dcNsProcess
echo sprintf( echo sprintf(
$table_line, $table_line,
' offline', ' offline',
form::checkbox(['entries[' . $i . '][check]'], 1), (new Checkbox(['entries[' . $i . '][check]']))->value(1)->render(),
form::combo(['entries[' . $i . '][group]'], My::l10nGroupsCombo(), 'main'), (new Select(['entries[' . $i . '][group]']))->items(My::l10nGroupsCombo())->default('main')->render(),
form::field(['entries[' . $i . '][msgid]'], 48, 255, ''), (new Input(['entries[' . $i . '][msgid]']))->size(48)->maxlenght(255)->render(),
form::field(['entries[' . $i . '][msgstr][0]'], 48, 255, ''), (new Input(['entries[' . $i . '][msgstr][0]']))->size(48)->maxlenght(255)->render(),
'', '',
'' ''
); );
@ -553,20 +583,23 @@ class Manage extends dcNsProcess
'<div class="two-cols">' . '<div class="two-cols">' .
'<div class="col left">' . '<div class="col left">' .
'<p class="checkboxes-helpers"></p>' . '<p class="checkboxes-helpers"></p>' .
'<p><label for="update_group">' .
form::checkbox('update_group', 1) . (new Para())->items([
__('Change the group of the selected translations to:') . ' ' . (new Checkbox('update_group'))->value(1),
form::combo('multigroup', My::l10nGroupsCombo()) . '</label></p>' . (new Label(__('Change the group of the selected translations to:'), Label::OUTSIDE_LABEL_AFTER))->for('update_group')->class('classic'),
(new Select('multigroup'))->items(My::l10nGroupsCombo()),
])->render() .
'</div>' . '</div>' .
'<p class="col right">' . (new Para())->class('col right')->items(array_merge([
'<input id="do-action" type="submit" value="' . __('Save') . ' (s)" accesskey="s" /></p>' . (new Submit('do-action'))->value(__('Save') . ' (s)')->accesskey('s'),
dcCore::app()->formNonce() . dcCore::app()->formNonce(false),
form::hidden(['code'], $current->lang->code) . (new Hidden(['code'], $current->lang->code)),
dcCore::app()->adminurl?->getHiddenFormFields( ], dcCore::app()->adminurl?->hiddenFormFields(
My::id(), My::id(),
['type' => $current->module?->type, 'module' => $current->module?->id, 'lang' => $current->lang->code, 'action' => 'module_update_code'] ['type' => $current->module?->type, 'module' => $current->module?->id, 'lang' => $current->lang->code, 'action' => 'module_update_code']
) . )
'</p></div>' . ))->render() .
'</div>' .
'</form>' . '</form>' .
'<p>&nbsp;</p>' . '<p>&nbsp;</p>' .
'</div>'; '</div>';

View File

@ -15,6 +15,7 @@ declare(strict_types=1);
namespace Dotclear\Plugin\translater; namespace Dotclear\Plugin\translater;
use dcCore; use dcCore;
use Exception;
class ManageVars class ManageVars
{ {

View File

@ -17,10 +17,11 @@ namespace Dotclear\Plugin\translater;
use dcCore; use dcCore;
use dcModuleDefine; use dcModuleDefine;
use dcThemes; use dcThemes;
use files; use Dotclear\Helper\File\Files;
use Dotclear\Helper\File\Path;
use Dotclear\Helper\Text;
use Exception;
use l10n; use l10n;
use path;
use text;
/** /**
* Translater tools. * Translater tools.
@ -133,12 +134,12 @@ class Translater extends Settings
*/ */
public static function scandir(string $path, string $dir = '', array $res = []): array public static function scandir(string $path, string $dir = '', array $res = []): array
{ {
$path = (string) path::real($path, false); $path = (string) Path::real($path, false);
if (empty($path) || !is_dir($path) || !is_readable($path)) { if (empty($path) || !is_dir($path) || !is_readable($path)) {
return []; return [];
} }
$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;
@ -163,7 +164,7 @@ class Translater extends Settings
*/ */
public static function encodeMsg(string $str): string public static function encodeMsg(string $str): string
{ {
return text::toUTF8(stripslashes(trim($str))); return Text::toUTF8(stripslashes(trim($str)));
} }
/** /**
@ -195,7 +196,7 @@ class Translater extends Settings
*/ */
public static function isPoFile(string $file): bool public static function isPoFile(string $file): bool
{ {
return files::getExtension($file) == 'po'; return Files::getExtension($file) == 'po';
} }
/** /**
@ -206,7 +207,7 @@ class Translater extends Settings
*/ */
public static function isLangphpFile(string $file): bool public static function isLangphpFile(string $file): bool
{ {
return files::getExtension($file) == 'php' && stristr($file, '.lang.php'); return Files::getExtension($file) == 'php' && stristr($file, '.lang.php');
} }
/** /**

View File

@ -15,9 +15,9 @@ declare(strict_types=1);
namespace Dotclear\Plugin\translater; namespace Dotclear\Plugin\translater;
use dcModuleDefine; use dcModuleDefine;
use files; use Dotclear\Helper\File\Files;
use Dotclear\Helper\File\Path;
use l10n; use l10n;
use path;
class TranslaterLang class TranslaterLang
{ {
@ -123,7 +123,7 @@ class TranslaterLang
$files = Translater::scandir($this->module->root); $files = Translater::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 . DIRECTORY_SEPARATOR . $file) || !in_array($extension, $scan_ext)) { if (is_dir($this->module->root . DIRECTORY_SEPARATOR . $file) || !in_array($extension, $scan_ext)) {
continue; continue;
} }
@ -171,7 +171,7 @@ class TranslaterLang
continue; continue;
} }
$scanned[] = $file; $scanned[] = $file;
$path = path::clean($this->module->locales . DIRECTORY_SEPARATOR . $file); $path = Path::clean($this->module->locales . DIRECTORY_SEPARATOR . $file);
if (Translater::isPoFile($file)) { if (Translater::isPoFile($file)) {
$po = l10n::parsePoFile($path); $po = l10n::parsePoFile($path);

View File

@ -16,13 +16,14 @@ namespace Dotclear\Plugin\translater;
use dcCore; use dcCore;
use dcModuleDefine; use dcModuleDefine;
use Dotclear\Helper\File\Files;
use Dotclear\Helper\File\Path;
use Dotclear\Helper\File\Zip\Unzip;
use Dotclear\Helper\File\Zip\Zip;
use Dotclear\Helper\Html\Html;
use Exception;
use dt; use dt;
use html;
use files;
use fileZip;
use fileUnzip;
use l10n; use l10n;
use path;
/** /**
* Translater tools. * Translater tools.
@ -68,7 +69,7 @@ class TranslaterModule
$this->author = $define->get('author'); $this->author = $define->get('author');
$this->version = $define->get('version'); $this->version = $define->get('version');
$this->root_writable = $define->get('root_writable'); $this->root_writable = $define->get('root_writable');
$this->root = (string) path::real($define->get('root'), false); $this->root = (string) Path::real($define->get('root'), false);
$this->locales = $this->root . DIRECTORY_SEPARATOR . My::LOCALES_FOLDER; $this->locales = $this->root . DIRECTORY_SEPARATOR . My::LOCALES_FOLDER;
} }
@ -93,7 +94,7 @@ class TranslaterModule
case 'plugin': case 'plugin':
$exp = explode(PATH_SEPARATOR, DC_PLUGINS_ROOT); $exp = explode(PATH_SEPARATOR, DC_PLUGINS_ROOT);
$tmp = path::real(array_pop($exp)); $tmp = Path::real(array_pop($exp));
if ($tmp !== false && is_writable($tmp)) { if ($tmp !== false && is_writable($tmp)) {
$dir = $tmp; $dir = $tmp;
} }
@ -101,7 +102,7 @@ class TranslaterModule
break; break;
case 'public': case 'public':
$tmp = path::real((string) dcCore::app()->blog?->public_path); $tmp = Path::real((string) dcCore::app()->blog?->public_path);
if ($tmp !== false && is_writable($tmp)) { if ($tmp !== false && is_writable($tmp)) {
$dir = $tmp; $dir = $tmp;
} }
@ -109,7 +110,7 @@ class TranslaterModule
break; break;
case 'cache': case 'cache':
$tmp = path::real(DC_TPL_CACHE); $tmp = Path::real(DC_TPL_CACHE);
if ($tmp !== false && is_writable($tmp)) { if ($tmp !== false && is_writable($tmp)) {
@mkDir($tmp . '/l10n'); @mkDir($tmp . '/l10n');
$dir = $tmp . '/l10n'; $dir = $tmp . '/l10n';
@ -118,7 +119,7 @@ class TranslaterModule
break; break;
case 'translater': case 'translater':
$tmp = path::real(dcCore::app()->plugins->moduleRoot(My::id())); $tmp = Path::real(dcCore::app()->plugins->moduleRoot(My::id()));
if ($tmp !== false && is_writable($tmp)) { if ($tmp !== false && is_writable($tmp)) {
@mkDir($tmp . DIRECTORY_SEPARATOR . My::LOCALES_FOLDER); @mkDir($tmp . DIRECTORY_SEPARATOR . My::LOCALES_FOLDER);
$dir = $tmp . DIRECTORY_SEPARATOR . My::LOCALES_FOLDER; $dir = $tmp . DIRECTORY_SEPARATOR . My::LOCALES_FOLDER;
@ -166,7 +167,7 @@ class TranslaterModule
} else { } else {
$res[$m[1]][$file]['code'] = $m[1]; $res[$m[1]][$file]['code'] = $m[1];
$res[$m[1]][$file]['name'] = l10n::getLanguageName($m[1]); $res[$m[1]][$file]['name'] = l10n::getLanguageName($m[1]);
$res[$m[1]][$file]['path'] = path::info($backup . '/' . $file); $res[$m[1]][$file]['path'] = Path::info($backup . '/' . $file);
$res[$m[1]][$file]['time'] = filemtime($backup . '/' . $file); $res[$m[1]][$file]['time'] = filemtime($backup . '/' . $file);
$res[$m[1]][$file]['size'] = filesize($backup . '/' . $file); $res[$m[1]][$file]['size'] = filesize($backup . '/' . $file);
$res[$m[1]][$file]['module'] = $this->id; $res[$m[1]][$file]['module'] = $this->id;
@ -211,12 +212,10 @@ class TranslaterModule
Translater::isBackupLimit($this->id, $backup, $this->translater->backup_limit, true); Translater::isBackupLimit($this->id, $backup, $this->translater->backup_limit, true);
@set_time_limit(300); @set_time_limit(300);
$fp = fopen($backup . '/l10n-' . $this->id . '-' . $lang . '-' . time() . '.bck.zip', 'wb'); $zip = new Zip($backup . '/l10n-' . $this->id . '-' . $lang . '-' . time() . '.bck.zip');
$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->close(); $zip->close();
unset($zip); unset($zip);
@ -243,7 +242,7 @@ class TranslaterModule
)); ));
} }
$zip = new fileUnzip($backup . '/' . $file); $zip = new Unzip($backup . '/' . $file);
$zip_files = $zip->getFilesList(); $zip_files = $zip->getFilesList();
foreach ($zip_files as $zip_file) { foreach ($zip_files as $zip_file) {
@ -276,7 +275,7 @@ class TranslaterModule
return false; return false;
} }
if (!files::isDeletable($backup . '/' . $file)) { if (!Files::isDeletable($backup . '/' . $file)) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Failed to delete file %s'), __('Failed to delete file %s'),
$file $file
@ -296,14 +295,14 @@ class TranslaterModule
*/ */
public function importPack(array $zip_file): bool public function importPack(array $zip_file): bool
{ {
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 Unzip($zip_file['tmp_name']);
$files = $zip->getFilesList(); $files = $zip->getFilesList();
foreach ($files as $file) { foreach ($files as $file) {
@ -326,7 +325,7 @@ class TranslaterModule
foreach ($res as $rs) { foreach ($res as $rs) {
if (!is_dir($rs['root'])) { if (!is_dir($rs['root'])) {
files::makeDir($rs['root'], true); Files::makeDir($rs['root'], true);
} }
$zip->unzip($rs['from'], $rs['to']); $zip->unzip($rs['from'], $rs['to']);
@ -363,7 +362,7 @@ class TranslaterModule
); );
} }
$filename = files::tidyFileName($this->translater->export_filename); $filename = Files::tidyFileName($this->translater->export_filename);
if (empty($filename)) { if (empty($filename)) {
throw new Exception( throw new Exception(
__('Export mask is not set in plugin configuration') __('Export mask is not set in plugin configuration')
@ -396,13 +395,12 @@ class TranslaterModule
} }
@set_time_limit(300); @set_time_limit(300);
$fp = fopen('php://output', 'wb'); $zip = new Zip('php://output');
$zip = new fileZip($fp);
foreach ($res as $from => $to) { foreach ($res as $from => $to) {
$zip->addFile($from, $to); $zip->addFile($from, $to);
} }
$filename = files::tidyFileName(dt::str(str_replace( $filename = Files::tidyFileName(dt::str(str_replace(
['timestamp', 'module', 'type', 'version'], ['timestamp', 'module', 'type', 'version'],
[time(), $this->id, $this->type, $this->version], [time(), $this->id, $this->type, $this->version],
$this->translater->export_filename $this->translater->export_filename
@ -410,7 +408,7 @@ class TranslaterModule
header('Content-Disposition: attachment;filename=' . $filename . '.zip'); header('Content-Disposition: attachment;filename=' . $filename . '.zip');
header('Content-Type: application/x-zip'); header('Content-Type: application/x-zip');
$zip->write(); $zip->close();
unset($zip); unset($zip);
exit; exit;
} }
@ -531,7 +529,7 @@ class TranslaterModule
)); ));
} }
files::makeDir($this->locales . DIRECTORY_SEPARATOR . $lang, true); Files::makeDir($this->locales . DIRECTORY_SEPARATOR . $lang, true);
if (!empty($from_lang) && !isset($langs[$from_lang])) { if (!empty($from_lang) && !isset($langs[$from_lang])) {
throw new Exception(sprintf( throw new Exception(sprintf(
@ -550,7 +548,7 @@ class TranslaterModule
continue; continue;
} }
files::putContent( Files::putContent(
implode(DIRECTORY_SEPARATOR, [$this->locales, $lang, $file]), implode(DIRECTORY_SEPARATOR, [$this->locales, $lang, $file]),
(string) file_get_contents(implode(DIRECTORY_SEPARATOR, [$this->locales, $from_lang, $file])) (string) file_get_contents(implode(DIRECTORY_SEPARATOR, [$this->locales, $from_lang, $file]))
); );
@ -695,7 +693,7 @@ class TranslaterModule
} }
$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 .= '# Translated with translater ' . dcCore::app()->plugins->moduleInfo(My::id(), 'version') . "\n\n"; $content .= '# Translated with translater ' . dcCore::app()->plugins->moduleInfo(My::id(), 'version') . "\n\n";
@ -741,7 +739,7 @@ class TranslaterModule
} }
$file = implode(DIRECTORY_SEPARATOR, [$this->locales, $lang->code, $group . '.po']); $file = implode(DIRECTORY_SEPARATOR, [$this->locales, $lang->code, $group . '.po']);
$path = path::info($file); $path = Path::info($file);
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(
@ -750,7 +748,7 @@ class TranslaterModule
)); ));
} }
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'), __('Failed to write file %s'),
$file $file
@ -787,7 +785,7 @@ class TranslaterModule
} }
$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 .= '// Translated with Translater - ' . dcCore::app()->plugins->moduleInfo(My::id(), 'version') . "\n\n"; $content .= '// Translated with Translater - ' . dcCore::app()->plugins->moduleInfo(My::id(), 'version') . "\n\n";