use namespace
This commit is contained in:
parent
85d4985137
commit
b4dc1a5093
132
src/Backend.php
132
src/Backend.php
@ -10,112 +10,58 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
use dcAdmin;
|
||||
use dcCore;
|
||||
use dcFavorites;
|
||||
use dcNsProcess;
|
||||
use dcPage;
|
||||
|
||||
class Backend extends dcNsProcess
|
||||
{
|
||||
public static function init(): bool
|
||||
{
|
||||
if (defined('DC_CONTEXT_ADMIN')) {
|
||||
self::$init = dcCore::app()->auth->isSuperAdmin();
|
||||
}
|
||||
|
||||
if (!dcCore::app()->auth->isSuperAdmin()) {
|
||||
return null;
|
||||
return self::$init;
|
||||
}
|
||||
|
||||
public static function process(): bool
|
||||
{
|
||||
if (!self::$init) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dcCore::app()->addBehaviors([
|
||||
'adminModulesListGetActions' => ['translaterAdminBehaviors', 'adminModulesGetActions'],
|
||||
'adminModulesListDoActions' => ['translaterAdminBehaviors', 'adminModulesDoActions'],
|
||||
'adminDashboardFavoritesV2' => ['translaterAdminBehaviors', 'adminDashboardFavoritesV2'],
|
||||
'adminModulesListGetActions' => [BackendBehaviors::class, 'adminModulesGetActions'],
|
||||
'adminModulesListDoActions' => [BackendBehaviors::class, 'adminModulesDoActions'],
|
||||
'adminDashboardFavoritesV2' => function (dcFavorites $favs): void {
|
||||
$favs->register(My::id(), [
|
||||
'title' => My::name(),
|
||||
'url' => dcCore::app()->adminurl->get(My::id()),
|
||||
'small-icon' => urldecode(dcPage::getPF(My::id() . '/icon.svg')),
|
||||
'large-icon' => urldecode(dcPage::getPF(My::id() . '/icon.svg')),
|
||||
//'permissions' => null,
|
||||
]);
|
||||
},
|
||||
]);
|
||||
|
||||
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
|
||||
__('Translater'),
|
||||
dcCore::app()->adminurl->get(basename(__DIR__)),
|
||||
dcPage::getPF(basename(__DIR__) . '/icon.svg'),
|
||||
My::name(),
|
||||
dcCore::app()->adminurl->get(My::id()),
|
||||
dcPage::getPF(My::id() . '/icon.svg'),
|
||||
preg_match(
|
||||
'/' . preg_quote(dcCore::app()->adminurl->get(basename(__DIR__))) . '(&.*)?$/',
|
||||
'/' . preg_quote(dcCore::app()->adminurl->get(My::id())) . '(&.*)?$/',
|
||||
$_SERVER['REQUEST_URI']
|
||||
),
|
||||
dcCore::app()->auth->isSuperAdmin()
|
||||
);
|
||||
|
||||
class translaterAdminBehaviors
|
||||
{
|
||||
/** @var dcTranslater dcTranslater instance */
|
||||
private static $translater = null;
|
||||
|
||||
/**
|
||||
* Create instance of dcTranslater once
|
||||
*
|
||||
* @return dcTranslater dcTranslater instance
|
||||
*/
|
||||
private static function translater(): dcTranslater
|
||||
{
|
||||
if (!is_a(self::$translater, 'dcTranslater')) {
|
||||
self::$translater = new dcTranslater(false);
|
||||
}
|
||||
|
||||
return self::$translater;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add button to go to module translation
|
||||
*
|
||||
* @param adminModulesList $list adminModulesList instance
|
||||
* @param string $id Module id
|
||||
* @param array $prop Module properties
|
||||
*
|
||||
* @return string HTML submit button
|
||||
*/
|
||||
public static function adminModulesGetActions(adminModulesList $list, string $id, array $prop): ?string
|
||||
{
|
||||
if ($list->getList() != $prop['type'] . '-activate'
|
||||
|| !self::translater()->{$prop['type'] . '_menu'}
|
||||
|| !dcCore::app()->auth->isSuperAdmin()
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
if (self::translater()->hide_default
|
||||
&& in_array($id, dcTranslater::$default_distrib_modules[$prop['type']])
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return
|
||||
' <input type="submit" name="translater[' .
|
||||
html::escapeHTML($id) .
|
||||
']" value="' . __('Translate') . '" /> ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to module translation
|
||||
*
|
||||
* @param adminModulesList $list adminModulesList instance
|
||||
* @param array $modules Selected modules ids
|
||||
* @param string $type List type (plugin|theme)
|
||||
*/
|
||||
public static function adminModulesDoActions(adminModulesList $list, array $modules, string $type): void
|
||||
{
|
||||
if (empty($_POST['translater']) || !is_array($_POST['translater'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
dcCore::app()->adminurl->redirect(
|
||||
basename(__DIR__),
|
||||
['part' => 'module', 'type' => $type, 'module' => key($_POST['translater'])],
|
||||
'#module-lang'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add dashboard favorites icon
|
||||
*
|
||||
* @param dcFavorites $favs dcFavorites instance
|
||||
*/
|
||||
public static function adminDashboardFavoritesV2(dcFavorites $favs): void
|
||||
{
|
||||
$favs->register('translater', [
|
||||
'title' => __('Translater'),
|
||||
'url' => dcCore::app()->adminurl->get(basename(__DIR__)),
|
||||
'small-icon' => urldecode(dcPage::getPF(basename(__DIR__) . '/icon.svg')),
|
||||
'large-icon' => urldecode(dcPage::getPF(basename(__DIR__) . '/icon.svg')),
|
||||
//'permissions' => null,
|
||||
]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
86
src/BackendBehaviors.php
Normal file
86
src/BackendBehaviors.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?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 adminModulesList;
|
||||
use dcCore;
|
||||
use Dotclear\Helper\Html\Form\Input;
|
||||
use html;
|
||||
|
||||
class BackendBehaviors
|
||||
{
|
||||
/** @var Translater Translater instance */
|
||||
private static $translater = null;
|
||||
|
||||
/**
|
||||
* Create instance of Translater once
|
||||
*
|
||||
* @return Translater Translater instance
|
||||
*/
|
||||
private static function translater(): Translater
|
||||
{
|
||||
if (!is_a(self::$translater, Translater::class)) {
|
||||
self::$translater = new Translater(false);
|
||||
}
|
||||
|
||||
return self::$translater;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add button to go to module translation
|
||||
*
|
||||
* @param adminModulesList $list adminModulesList instance
|
||||
* @param string $id Module id
|
||||
* @param array $prop Module properties
|
||||
*
|
||||
* @return string HTML submit button
|
||||
*/
|
||||
public static function adminModulesGetActions(adminModulesList $list, string $id, array $prop): ?string
|
||||
{
|
||||
if ($list->getList() != $prop['type'] . '-activate'
|
||||
|| !self::translater()->get($prop['type'] . '_menu')
|
||||
|| !dcCore::app()->auth->isSuperAdmin()
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
if (self::translater()->get('hide_default')
|
||||
&& in_array($id, My::defaultDistribModules($prop['type']))
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (new Input(['translater[' . html::escapeHTML($id) . ']', null]))->value(__('Translate'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to module translation
|
||||
*
|
||||
* @param adminModulesList $list adminModulesList instance
|
||||
* @param array $modules Selected modules ids
|
||||
* @param string $type List type (plugin|theme)
|
||||
*/
|
||||
public static function adminModulesDoActions(adminModulesList $list, array $modules, string $type): void
|
||||
{
|
||||
if (empty($_POST['translater']) || !is_array($_POST['translater'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
dcCore::app()->adminurl->redirect(
|
||||
My::id(),
|
||||
['part' => 'module', 'type' => $type, 'module' => key($_POST['translater'])],
|
||||
'#module-lang'
|
||||
);
|
||||
}
|
||||
}
|
216
src/Config.php
216
src/Config.php
@ -10,93 +10,169 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_MODULE')) {
|
||||
return null;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
use dcCore;
|
||||
use dcNsProcess;
|
||||
use dcPage;
|
||||
|
||||
use Dotclear\Helper\Html\Form\{
|
||||
Checkbox,
|
||||
Div,
|
||||
Fieldset,
|
||||
Input,
|
||||
Label,
|
||||
Legend,
|
||||
Note,
|
||||
Number,
|
||||
Para,
|
||||
Select
|
||||
};
|
||||
|
||||
class Config extends dcNsProcess
|
||||
{
|
||||
public static function init(): bool
|
||||
{
|
||||
self::$init = defined('DC_CONTEXT_ADMIN');
|
||||
|
||||
return self::$init;
|
||||
}
|
||||
|
||||
$translater = new dcTranslater();
|
||||
public static function process(): bool
|
||||
{
|
||||
if (!self::$init) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// nothing to process
|
||||
if (empty($_POST['save'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$translater = new Translater();
|
||||
|
||||
if (!empty($_POST['save'])) {
|
||||
try {
|
||||
foreach ($translater->getDefaultSettings() as $key => $value) {
|
||||
$translater->$key = $_POST[$key] ?? '';
|
||||
foreach (My::defaultSettings() as $key => $value) {
|
||||
$translater->set($key, $_POST[$key] ?? '');
|
||||
}
|
||||
$translater->writeSettings();
|
||||
dcAdminNotices::addSuccessNotice(
|
||||
|
||||
dcPage::addSuccessNotice(
|
||||
__('Configuration successfully updated.')
|
||||
);
|
||||
dcCore::app()->adminurl->redirect(
|
||||
'admin.plugins',
|
||||
['module' => basename(__DIR__), 'conf' => 1, 'redir' => dcCore::app()->admin->__get('list')->getRedir()]
|
||||
['module' => My::id(), 'conf' => 1, 'redir' => dcCore::app()->admin->__get('list')->getRedir()]
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
dcCore::app()->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
echo '
|
||||
<div class="fieldset"><h4>' . __('Translation') . '</h4>
|
||||
<p><label for="write_langphp">' .
|
||||
form::checkbox('write_langphp', '1', $translater->write_langphp) .
|
||||
__('Write .lang.php files') . '</label></p>
|
||||
<p><label for="scan_tpl">' .
|
||||
form::checkbox('scan_tpl', '1', $translater->scan_tpl) .
|
||||
__('Translate also strings of template files') . '</label></p>
|
||||
<p><label for="parse_nodc">' .
|
||||
form::checkbox('parse_nodc', '1', $translater->parse_nodc) .
|
||||
__('Translate only unknow strings') . '</label></p>
|
||||
<p><label for="hide_default">' .
|
||||
form::checkbox('hide_default', '1', $translater->hide_default) .
|
||||
__('Hide default modules of Dotclear') . '</label></p>
|
||||
<p><label for="parse_comment">' .
|
||||
form::checkbox('parse_comment', '1', $translater->parse_comment) .
|
||||
__('Write comments in files') . '</label></p>
|
||||
<p><label for="parse_user">' .
|
||||
form::checkbox('parse_user', '1', $translater->parse_user) .
|
||||
__('Write informations about author in files') . '</label></p>
|
||||
<p><label for="parse_userinfo">' . __('User info:') . '</label>' .
|
||||
form::field('parse_userinfo', 65, 255, $translater->parse_userinfo) . '</p>
|
||||
<p class="form-note">' . sprintf(
|
||||
public static function render(): void
|
||||
{
|
||||
if (!self::$init) {
|
||||
return;
|
||||
}
|
||||
|
||||
$translater = new Translater();
|
||||
|
||||
echo (new Div())->items([
|
||||
(new Fieldset())->class('fieldset')->legend((new Legend(__('Translation'))))->fields([
|
||||
// write_langphp
|
||||
(new Para())->items([
|
||||
(new Checkbox('write_langphp', $translater->get('write_langphp')))->value(1),
|
||||
(new Label(__('Write .lang.php files'), Label::OUTSIDE_LABEL_AFTER))->for('write_langphp')->class('classic'),
|
||||
]),
|
||||
// scan_tpl
|
||||
(new Para())->items([
|
||||
(new Checkbox('scan_tpl', $translater->get('scan_tpl')))->value(1),
|
||||
(new Label(__('Translate also strings of template files'), Label::OUTSIDE_LABEL_AFTER))->for('scan_tpl')->class('classic'),
|
||||
]),
|
||||
// parse_nodc
|
||||
(new Para())->items([
|
||||
(new Checkbox('parse_nodc', $translater->get('parse_nodc')))->value(1),
|
||||
(new Label(__('Translate only unknow strings'), Label::OUTSIDE_LABEL_AFTER))->for('parse_nodc')->class('classic'),
|
||||
]),
|
||||
// hide_default
|
||||
(new Para())->items([
|
||||
(new Checkbox('hide_default', $translater->get('hide_default')))->value(1),
|
||||
(new Label(__('Hide default modules of Dotclear'), Label::OUTSIDE_LABEL_AFTER))->for('hide_default')->class('classic'),
|
||||
]),
|
||||
// parse_comment
|
||||
(new Para())->items([
|
||||
(new Checkbox('parse_comment', $translater->get('parse_comment')))->value(1),
|
||||
(new Label(__('Write comments in files'), Label::OUTSIDE_LABEL_AFTER))->for('parse_comment')->class('classic'),
|
||||
]),
|
||||
// parse_user
|
||||
(new Para())->items([
|
||||
(new Checkbox('parse_user', $translater->get('parse_user')))->value(1),
|
||||
(new Label(__('Write informations about author in files'), Label::OUTSIDE_LABEL_AFTER))->for('parse_user')->class('classic'),
|
||||
]),
|
||||
// parse_userinfo
|
||||
(new Para())->items([
|
||||
(new Label(__('User info:')))->for('parse_userinfo'),
|
||||
(new Input('parse_userinfo'))->size(65)->maxlenght(255)->value($translater->get('parse_userinfo')),
|
||||
]),
|
||||
(new Note())->text(sprintf(
|
||||
__('Following informations can be used: %s'),
|
||||
implode(', ', $translater::$allowed_user_informations)
|
||||
) . '
|
||||
</p>
|
||||
</div>
|
||||
implode(', ', My::defaultUserInformations())
|
||||
))->class('form-note'),
|
||||
]),
|
||||
(new Fieldset())->class('fieldset')->legend((new Legend(__('Import/Export'))))->fields([
|
||||
// import_overwrite
|
||||
(new Para())->items([
|
||||
(new Checkbox('import_overwrite', $translater->get('import_overwrite')))->value(1),
|
||||
(new Label(__('Overwrite existing languages'), Label::OUTSIDE_LABEL_AFTER))->for('import_overwrite')->class('classic'),
|
||||
]),
|
||||
// export_filename
|
||||
(new Para())->items([
|
||||
(new Label(__('Name of exported package:')))->for('export_filename'),
|
||||
(new Input('export_filename'))->size(65)->maxlenght(255)->value($translater->get('export_filename')),
|
||||
]),
|
||||
]),
|
||||
(new Fieldset())->class('fieldset')->legend((new Legend(__('Backups'))))->fields([
|
||||
// backup_auto
|
||||
(new Para())->items([
|
||||
(new Checkbox('backup_auto', $translater->get('backup_auto')))->value(1),
|
||||
(new Label(__('Make backups when changes are made'), Label::OUTSIDE_LABEL_AFTER))->for('backup_auto')->class('classic'),
|
||||
]),
|
||||
// backup_limit
|
||||
(new Para())->items([
|
||||
(new Label(__('Limit backups per module to:')))->for('backup_limit')->class('classic'),
|
||||
(new Number('backup_limit'))->min(0)->max(50)->value($translater->get('backup_limit')),
|
||||
]),
|
||||
(new Note())->text(__('Set to 0 for no limit.'))->class('form-note'),
|
||||
// backup_folder
|
||||
(new Para())->items([
|
||||
(new Label(__('Store backups in:')))->for('backup_folder'),
|
||||
(new Select('backup_folder'))->default($translater->get('backup_folder'))->items(My::backupFoldersCombo()),
|
||||
]),
|
||||
]),
|
||||
(new Fieldset())->class('fieldset')->legend((new Legend(__('Behaviors'))))->fields([
|
||||
// start_page
|
||||
(new Para())->items([
|
||||
(new Label(__('Default start menu:')))->for('start_page'),
|
||||
(new Select('start_page'))->default($translater->get('start_page'))->items(My::startPageCombo()),
|
||||
]),
|
||||
// plugin_menu
|
||||
(new Para())->items([
|
||||
(new Checkbox('plugin_menu', $translater->get('plugin_menu')))->value(1),
|
||||
(new Label(__('Enable menu on plugins page'), Label::OUTSIDE_LABEL_AFTER))->for('plugin_menu')->class('classic'),
|
||||
]),
|
||||
// theme_menu
|
||||
(new Para())->items([
|
||||
(new Checkbox('theme_menu', $translater->get('theme_menu')))->value(1),
|
||||
(new Label(__('Enable menu on themes page'), Label::OUTSIDE_LABEL_AFTER))->for('theme_menu')->class('classic'),
|
||||
]),
|
||||
|
||||
<div class="fieldset"><h4>' . __('Import/Export') . '</h4>
|
||||
<p><label for="import_overwrite">' .
|
||||
form::checkbox('import_overwrite', '1', $translater->import_overwrite) .
|
||||
__('Overwrite existing languages') . '</label></p>
|
||||
<p><label for="export_filename">' . __('Name of exported package:') . '</label>' .
|
||||
form::field('export_filename', 65, 255, $translater->export_filename) . '</p>
|
||||
</div>
|
||||
|
||||
<div class="fieldset"><h4>' . __('Backups') . '</h4>
|
||||
<p><label for="backup_auto">' .
|
||||
form::checkbox('backup_auto', '1', $translater->backup_auto) .
|
||||
__('Make backups when changes are made') . '</label></p>
|
||||
<p><label for="backup_limit" class="classic">' . sprintf(
|
||||
__('Limit backups to %s files per module'),
|
||||
form::number('backup_limit', ['min' => 0, 'max' => 50, 'default' => $translater->backup_limit])
|
||||
) . '</label></p>
|
||||
<p class="form-note">' . __('Set to 0 for no limit.') . '</p>
|
||||
<p><label for="backup_folder">' . __('Store backups in:') . '</label>' .
|
||||
form::combo('backup_folder', $translater::$allowed_backup_folders, $translater->backup_folder) . '</p>
|
||||
</div>
|
||||
|
||||
<div class="fieldset"><h4>' . __('Behaviors') . '</h4>
|
||||
<p><label for="start_page">' . __('Default start menu:') . '</label>' .
|
||||
form::combo('start_page', [
|
||||
__('Plugins') => 'plugin',
|
||||
__('Themes') => 'theme',
|
||||
__('Home') => '-',
|
||||
], $translater->start_page) . '</p>
|
||||
<p><label for="plugin_menu">' .
|
||||
form::checkbox('plugin_menu', '1', $translater->plugin_menu) .
|
||||
__('Enable menu on plugins page') . '</label></p>
|
||||
<p><label for="theme_menu">' .
|
||||
form::checkbox('theme_menu', '1', $translater->theme_menu) .
|
||||
__('Enable menu on themes page') . '</label></p>
|
||||
</div>';
|
||||
]),
|
||||
])->render();
|
||||
|
||||
dcPage::helpBlock('translater.config');
|
||||
}
|
||||
}
|
||||
|
21
src/Exception.php
Normal file
21
src/Exception.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?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
|
||||
{
|
||||
}
|
@ -10,20 +10,35 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return null;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
use dcCore;
|
||||
use dcNamespace;
|
||||
use dcNsProcess;
|
||||
|
||||
class Install extends dcNsProcess
|
||||
{
|
||||
public static function init(): bool
|
||||
{
|
||||
self::$init = defined('DC_CONTEXT_ADMIN') && dcCore::app()->newVersion(My::id(), dcCore::app()->plugins->moduleInfo(My::id(), 'version'));
|
||||
|
||||
return self::$init;
|
||||
}
|
||||
|
||||
public static function process(): bool
|
||||
{
|
||||
if (!self::$init) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!dcCore::app()->newVersion(
|
||||
basename(__DIR__),
|
||||
dcCore::app()->plugins->moduleInfo(basename(__DIR__), 'version')
|
||||
)) {
|
||||
return null;
|
||||
}
|
||||
$translater = new dcTranslater(false);
|
||||
if (!$translater->growUp()) {
|
||||
$translater->writeSettings(false);
|
||||
self::growUp();
|
||||
|
||||
foreach (My::defaultSettings() as $key => $value) {
|
||||
dcCore::app()->blog->settings->get(My::id())->drop($key);
|
||||
dcCore::app()->blog->settings->get(My::id())->put($key, $value, gettype($value), '', false, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -31,4 +46,39 @@ try {
|
||||
dcCore::app()->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade plugin
|
||||
*
|
||||
* @return bool Upgrade done
|
||||
*/
|
||||
public static function growUp()
|
||||
{
|
||||
$current = dcCore::app()->getVersion(My::id());
|
||||
|
||||
// use short settings id
|
||||
if ($current && version_compare($current, '2022.12.22', '<')) {
|
||||
$record = dcCore::app()->con->select(
|
||||
'SELECT * FROM ' . dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME . ' ' .
|
||||
"WHERE setting_ns = 'translater' "
|
||||
);
|
||||
while ($record->fetch()) {
|
||||
if (preg_match('/^translater_(.*?)$/', $record->setting_id, $match)) {
|
||||
$cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME);
|
||||
$cur->setting_id = $match[1];
|
||||
$cur->setting_ns = My::id();
|
||||
$cur->update(
|
||||
"WHERE setting_id = '" . $record->setting_id . "' and setting_ns = 'translater' " .
|
||||
'AND blog_id ' . (null === $record->blog_id ? 'IS NULL ' : ("= '" . dcCore::app()->con->escape($record->blog_id) . "' "))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
291
src/Manage.php
291
src/Manage.php
@ -10,144 +10,152 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
use dcCore;
|
||||
use dcNsProcess;
|
||||
use dcPage;
|
||||
use dt;
|
||||
use html;
|
||||
use files;
|
||||
use form;
|
||||
|
||||
class Manage extends dcNsProcess
|
||||
{
|
||||
public static function init(): bool
|
||||
{
|
||||
if (defined('DC_CONTEXT_ADMIN')) {
|
||||
self::$init = dcCore::app()->auth->isSuperAdmin();
|
||||
}
|
||||
|
||||
dcPage::checkSuper();
|
||||
return self::$init;
|
||||
}
|
||||
|
||||
$translater = new dcTranslater();
|
||||
public static function process(): bool
|
||||
{
|
||||
if (!self::$init) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = $_REQUEST['type'] ?? $translater->start_page ?: '';
|
||||
$module = $_REQUEST['module'] ?? '';
|
||||
$lang = $_REQUEST['lang'] ?? '';
|
||||
// set vars used in process and render methods
|
||||
dcCore::app()->admin->translater = new Translater();
|
||||
dcCore::app()->admin->type = $_REQUEST['type'] ?? dcCore::app()->admin->translater->get('start_page') ?: '';
|
||||
dcCore::app()->admin->module = $_REQUEST['module'] ?? '';
|
||||
dcCore::app()->admin->lang = $_REQUEST['lang'] ?? '';
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if (!in_array($type, ['plugin', 'theme'])) {
|
||||
$type = '';
|
||||
// check module type
|
||||
if (!in_array(dcCore::app()->admin->type, ['plugin', 'theme'])) {
|
||||
dcCore::app()->admin->type = '';
|
||||
}
|
||||
|
||||
if (!empty($type) && !empty($module)) {
|
||||
// check if module exists
|
||||
if (!empty(dcCore::app()->admin->type) && !empty(dcCore::app()->admin->module)) {
|
||||
try {
|
||||
$module = $translater->getModule($type, $module);
|
||||
dcCore::app()->admin->module = dcCore::app()->admin->translater->getModule(dcCore::app()->admin->type, dcCore::app()->admin->module);
|
||||
} catch (Exception $e) {
|
||||
dcCore::app()->error->add($e->getMessage());
|
||||
$module = '';
|
||||
dcCore::app()->admin->module = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($module) && !empty($lang)) {
|
||||
//check if module lang exists
|
||||
if (!empty(dcCore::app()->admin->module) && !empty(dcCore::app()->admin->lang)) {
|
||||
try {
|
||||
$lang = $translater->getLang($module, $lang);
|
||||
dcCore::app()->admin->lang = dcCore::app()->admin->translater->getLang(dcCore::app()->admin->module, dcCore::app()->admin->lang);
|
||||
} catch (Exception $e) {
|
||||
dcCore::app()->error->add($e->getMessage());
|
||||
$lang = '';
|
||||
dcCore::app()->admin->lang = '';
|
||||
}
|
||||
}
|
||||
|
||||
$breadcrumb = [__('Translater') => dcCore::app()->adminurl->get(basename(__DIR__), ['type' => '-'])];
|
||||
if (empty($type)) {
|
||||
$breadcrumb = [__('Translater') => ''];
|
||||
} elseif (empty($module)) {
|
||||
$breadcrumb[$type == 'plugin' ? __('Plugins') : __('Themes')] = '';
|
||||
} elseif (empty($lang)) {
|
||||
$breadcrumb[$type == 'plugin' ? __('Plugins') : __('Themes')] = dcCore::app()->adminurl->get(basename(__DIR__), ['type' => $type]);
|
||||
$breadcrumb[html::escapeHTML($module->name)] = '';
|
||||
} elseif (!empty($lang)) {
|
||||
$breadcrumb[$type == 'plugin' ? __('Plugins') : __('Themes')] = dcCore::app()->adminurl->get(basename(__DIR__), ['type' => $type]);
|
||||
$breadcrumb[html::escapeHTML($module->name)] = dcCore::app()->adminurl->get(basename(__DIR__), ['type' => $type, 'module' => $module->id]);
|
||||
$breadcrumb[html::escapeHTML(sprintf(__('%s language edition'), $lang->name))] = '';
|
||||
}
|
||||
|
||||
// execute action
|
||||
try {
|
||||
if ($action == 'module_create_backups') {
|
||||
if (empty($module) || empty($_POST['codes'])) {
|
||||
if (empty(dcCore::app()->admin->module) || empty($_POST['codes'])) {
|
||||
throw new Exception(__('Nothing to backup'));
|
||||
}
|
||||
$module_codes = $module->getUsedlangs();
|
||||
$module_codes = dcCore::app()->admin->module->getUsedlangs();
|
||||
foreach ($module_codes as $code_id) {
|
||||
if (in_array($code_id, $_POST['codes'])) {
|
||||
$module->createBackup($code_id);
|
||||
dcCore::app()->admin->module->createBackup($code_id);
|
||||
}
|
||||
}
|
||||
dcAdminNotices::addSuccessNotice(__('Backup successfully created'));
|
||||
dcCore::app()->adminurl->redirect(basename(__DIR__), ['type' => $type, 'module' => $module->id]);
|
||||
|
||||
self::redirect(__('Backup successfully created'));
|
||||
}
|
||||
|
||||
if ($action == 'module_restore_backup') {
|
||||
if (empty($module) || empty($_POST['files'])) {
|
||||
if (empty(dcCore::app()->admin->module) || empty($_POST['files'])) {
|
||||
throw new Exception(__('Nothing to restore'));
|
||||
}
|
||||
$module_backups = $module->getBackups(true);
|
||||
$module_backups = dcCore::app()->admin->module->getBackups(true);
|
||||
foreach ($module_backups as $backup_file) {
|
||||
if (in_array($backup_file, $_POST['files'])) {
|
||||
$module->restoreBackup($backup_file);
|
||||
dcCore::app()->admin->module->restoreBackup($backup_file);
|
||||
}
|
||||
}
|
||||
dcAdminNotices::addSuccessNotice(__('Backup successfully restored'));
|
||||
dcCore::app()->adminurl->redirect(basename(__DIR__), ['type' => $type, 'module' => $module->id]);
|
||||
|
||||
self::redirect(__('Backup successfully restored'));
|
||||
}
|
||||
|
||||
if ($action == 'module_delete_backup') {
|
||||
if (empty($module) || empty($_POST['files'])) {
|
||||
if (empty(dcCore::app()->admin->module) || empty($_POST['files'])) {
|
||||
throw new Exception(__('Nothing to delete'));
|
||||
}
|
||||
$module_backups = $module->getBackups(true);
|
||||
$module_backups = dcCore::app()->admin->module->getBackups(true);
|
||||
foreach ($module_backups as $backup_file) {
|
||||
if (in_array($backup_file, $_POST['files'])) {
|
||||
$module->deleteBackup($backup_file);
|
||||
dcCore::app()->admin->module->deleteBackup($backup_file);
|
||||
}
|
||||
}
|
||||
dcAdminNotices::addSuccessNotice(__('Backup successfully deleted'));
|
||||
dcCore::app()->adminurl->redirect(basename(__DIR__), ['type' => $type, 'module' => $module->id]);
|
||||
|
||||
self::redirect(__('Backup successfully deleted'));
|
||||
}
|
||||
|
||||
if ($action == 'module_export_pack') {
|
||||
if (empty($module) || empty($_POST['codes'])) {
|
||||
if (empty(dcCore::app()->admin->module) || empty($_POST['codes'])) {
|
||||
throw new Exception(__('Nothing to export'));
|
||||
}
|
||||
$module->exportPack($_POST['codes']);
|
||||
dcCore::app()->admin->module->exportPack($_POST['codes']);
|
||||
|
||||
dcAdminNotices::addSuccessNotice(__('Language successfully exported'));
|
||||
dcCore::app()->adminurl->redirect(basename(__DIR__), ['type' => $type, 'module' => $module->id]);
|
||||
self::redirect(__('Language successfully exported'));
|
||||
}
|
||||
|
||||
if ($action == 'module_import_pack') {
|
||||
if (empty($_FILES['packfile']['name'])) {
|
||||
throw new Exception(__('Nothing to import'));
|
||||
}
|
||||
$module->importPack($_FILES['packfile']);
|
||||
dcCore::app()->admin->module->importPack($_FILES['packfile']);
|
||||
|
||||
dcAdminNotices::addSuccessNotice(__('Language successfully imported'));
|
||||
dcCore::app()->adminurl->redirect(basename(__DIR__), ['type' => $type, 'module' => $module->id]);
|
||||
self::redirect(__('Language successfully imported'));
|
||||
}
|
||||
|
||||
if ($action == 'module_add_code') {
|
||||
if (empty($module) || empty($_POST['code'])) {
|
||||
if (empty(dcCore::app()->admin->module) || empty($_POST['code'])) {
|
||||
throw new Exception(__('Nothing to create'));
|
||||
}
|
||||
$module->addLang($_POST['code'], $_POST['from'] ?? '');
|
||||
dcCore::app()->admin->module->addLang($_POST['code'], $_POST['from'] ?? '');
|
||||
|
||||
dcAdminNotices::addSuccessNotice(__('Language successfully added'));
|
||||
dcCore::app()->adminurl->redirect(basename(__DIR__), ['type' => $type, 'module' => $module->id, 'lang' => $_POST['code']]);
|
||||
self::redirect(__('Language successfully added'), $_POST['code']);
|
||||
}
|
||||
|
||||
if ($action == 'module_delete_codes') {
|
||||
if (empty($module) || empty($_POST['codes'])) {
|
||||
if (empty(dcCore::app()->admin->module) || empty($_POST['codes'])) {
|
||||
throw new Exception(__('Nothing to delete'));
|
||||
}
|
||||
$module_codes = $module->getUsedlangs();
|
||||
$module_codes = dcCore::app()->admin->module->getUsedlangs();
|
||||
foreach ($module_codes as $code_id) {
|
||||
if (in_array($code_id, $_POST['codes'])) {
|
||||
$module->delLang($code_id);
|
||||
dcCore::app()->admin->module->delLang($code_id);
|
||||
}
|
||||
}
|
||||
dcAdminNotices::addSuccessNotice(__('Language successfully deleted'));
|
||||
dcCore::app()->adminurl->redirect(basename(__DIR__), ['type' => $type, 'module' => $module->id, 'lang' => $_POST['code']]);
|
||||
|
||||
self::redirect(__('Language successfully deleted'), $_POST['code']);
|
||||
}
|
||||
|
||||
if ($action == 'module_update_code') {
|
||||
if (empty($module) || empty($_POST['code']) || empty($_POST['entries'])) {
|
||||
if (empty(dcCore::app()->admin->module) || empty($_POST['code']) || empty($_POST['entries'])) {
|
||||
throw new Exception(__('Nothing to update'));
|
||||
}
|
||||
if (!empty($_POST['update_group'])) {
|
||||
@ -157,49 +165,71 @@ try {
|
||||
}
|
||||
}
|
||||
}
|
||||
$module->updLang($_POST['code'], $_POST['entries']);
|
||||
dcCore::app()->admin->module->updLang($_POST['code'], $_POST['entries']);
|
||||
|
||||
dcAdminNotices::addSuccessNotice(__('Language successfully updated'));
|
||||
dcCore::app()->adminurl->redirect(basename(__DIR__), ['type' => $type, 'module' => $module->id, 'lang' => $_POST['code']]);
|
||||
self::redirect(__('Language successfully updated'), $_POST['code']);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
dcCore::app()->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
echo
|
||||
'<html><head><title>' . __('Translater') . '</title>' .
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function render(): void
|
||||
{
|
||||
if (!self::$init) {
|
||||
return;
|
||||
}
|
||||
|
||||
$breadcrumb = [My::name() => dcCore::app()->adminurl->get(My::id(), ['type' => '-'])];
|
||||
if (empty(dcCore::app()->admin->type)) {
|
||||
$breadcrumb = [My::name() => ''];
|
||||
} elseif (empty(dcCore::app()->admin->module)) {
|
||||
$breadcrumb[dcCore::app()->admin->type == 'plugin' ? __('Plugins') : __('Themes')] = '';
|
||||
} elseif (empty(dcCore::app()->admin->lang)) {
|
||||
$breadcrumb[dcCore::app()->admin->type == 'plugin' ? __('Plugins') : __('Themes')] = dcCore::app()->adminurl->get(My::id(), ['type' => dcCore::app()->admin->type]);
|
||||
$breadcrumb[html::escapeHTML(dcCore::app()->admin->module->name)] = '';
|
||||
} elseif (!empty(dcCore::app()->admin->lang)) {
|
||||
$breadcrumb[dcCore::app()->admin->type == 'plugin' ? __('Plugins') : __('Themes')] = dcCore::app()->adminurl->get(My::id(), ['type' => dcCore::app()->admin->type]);
|
||||
$breadcrumb[html::escapeHTML(dcCore::app()->admin->module->name)] = dcCore::app()->adminurl->get(My::id(), ['type' => dcCore::app()->admin->type, 'module' => dcCore::app()->admin->module->id]);
|
||||
$breadcrumb[html::escapeHTML(sprintf(__('%s language edition'), dcCore::app()->admin->lang->name))] = '';
|
||||
}
|
||||
|
||||
dcPage::openModule(
|
||||
My::name(),
|
||||
dcPage::jsPageTabs() .
|
||||
dcPage::cssModuleLoad(basename(__DIR__) . '/css/translater.css') .
|
||||
dcPage::cssModuleLoad(My::id() . '/css/backend.css') .
|
||||
dcPage::jsJson('translater', [
|
||||
'title_add_detail' => __('Use this text'),
|
||||
'image_field' => dcPage::getPF(basename(__DIR__) . '/img/field.png'),
|
||||
'image_toggle' => dcPage::getPF(basename(__DIR__) . '/img/toggle.png'),
|
||||
'image_field' => dcPage::getPF(My::id() . '/img/field.png'),
|
||||
'image_toggle' => dcPage::getPF(My::id() . '/img/toggle.png'),
|
||||
]) .
|
||||
dcPage::jsModuleLoad(basename(__DIR__) . '/js/translater.js') .
|
||||
dcPage::jsModuleLoad(My::id() . '/js/backend.js') .
|
||||
|
||||
# --BEHAVIOR-- translaterAdminHeaders
|
||||
dcCore::app()->callBehavior('translaterAdminHeaders') .
|
||||
|
||||
'</head><body>' .
|
||||
dcCore::app()->callBehavior('translaterAdminHeaders')
|
||||
);
|
||||
|
||||
echo
|
||||
dcPage::breadcrumb($breadcrumb) .
|
||||
dcPage::notices();
|
||||
|
||||
if (empty($module) && $type != '') {
|
||||
if (empty(dcCore::app()->admin->module) && dcCore::app()->admin->type != '') {
|
||||
// modules list
|
||||
echo '<form id="theme-form" method="post" action="' . dcCore::app()->adminurl->get(basename(__DIR__), ['type' => 'plugin']) . '">';
|
||||
echo '<form id="theme-form" method="post" action="' . dcCore::app()->adminurl->get(My::id(), ['type' => 'plugin']) . '">';
|
||||
|
||||
$res = '';
|
||||
$modules = $translater->getModules($type);
|
||||
$modules = dcCore::app()->admin->translater->getModules(dcCore::app()->admin->type);
|
||||
ksort($modules);
|
||||
foreach ($modules as $module) {
|
||||
if ($translater->hide_default && in_array($module->id, $translater::$default_distrib_modules[$type])) {
|
||||
if (dcCore::app()->admin->translater->get('hide_default') && in_array($module->id, My::defaultDistribModules(dcCore::app()->admin->type))) {
|
||||
continue;
|
||||
}
|
||||
if ($module->root_writable) {
|
||||
$res .= sprintf(
|
||||
'<tr class="line"><td class="nowrap minimal"><a href="%s" title="%s">%s</a></td>',
|
||||
dcCore::app()->adminurl->get(basename(__DIR__), ['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($module->id)
|
||||
);
|
||||
@ -215,7 +245,7 @@ if (empty($module) && $type != '') {
|
||||
$codes[$code_id] = sprintf(
|
||||
'<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))),
|
||||
dcCore::app()->adminurl->get(basename(__DIR__), ['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),
|
||||
$code_id
|
||||
);
|
||||
@ -234,7 +264,7 @@ if (empty($module) && $type != '') {
|
||||
echo '
|
||||
<div class="table-outer">
|
||||
<table class="clear">
|
||||
<caption>' . sprintf(__('Modules list of type "%s"'), $type) . '</caption>
|
||||
<caption>' . sprintf(__('Modules list of type "%s"'), dcCore::app()->admin->type) . '</caption>
|
||||
<tr>
|
||||
<th class="nowrap">' . __('Id') . '</th>
|
||||
<th class="nowrap">' . __('Languages') . '</th>
|
||||
@ -249,17 +279,17 @@ if (empty($module) && $type != '') {
|
||||
echo '</form>';
|
||||
|
||||
dcPage::helpBlock('translater.type');
|
||||
} elseif (!empty($module) && empty($lang)) {
|
||||
$codes = $module->getUsedLangs();
|
||||
$backups = $module->getBackups();
|
||||
$unused_codes = $module->getUnusedLangs();
|
||||
} elseif (!empty(dcCore::app()->admin->module) && empty(dcCore::app()->admin->lang)) {
|
||||
$codes = dcCore::app()->admin->module->getUsedLangs();
|
||||
$backups = dcCore::app()->admin->module->getBackups();
|
||||
$unused_codes = dcCore::app()->admin->module->getUnusedLangs();
|
||||
|
||||
// module summary
|
||||
echo '<h3>' . sprintf(__('Module %s %s by %s'), $module->name, $module->version, $module->author) . '</h3>
|
||||
echo '<h3>' . sprintf(__('Module %s %s by %s'), dcCore::app()->admin->module->name, dcCore::app()->admin->module->version, dcCore::app()->admin->module->author) . '</h3>
|
||||
<ul class="nice col">
|
||||
<li><strong>' . __('Root') . '</strong> ' . $module->root . '</li>
|
||||
<li><strong>' . __('Locales') . '</strong> ' . $module->locales . '</li>
|
||||
<li><strong>' . __('Backups') . '</strong> ' . $module->getBackupRoot() . '</li>
|
||||
<li><strong>' . __('Root') . '</strong> ' . dcCore::app()->admin->module->root . '</li>
|
||||
<li><strong>' . __('Locales') . '</strong> ' . dcCore::app()->admin->module->locales . '</li>
|
||||
<li><strong>' . __('Backups') . '</strong> ' . dcCore::app()->admin->module->getBackupRoot() . '</li>
|
||||
</ul>
|
||||
<p> </p>';
|
||||
|
||||
@ -267,7 +297,7 @@ if (empty($module) && $type != '') {
|
||||
if (count($codes)) {
|
||||
echo
|
||||
'<div class="clear fieldset"><h3>' . __('Translations') . '</h3>' .
|
||||
'<form id="module-translations-form" method="post" action="' . dcCore::app()->adminurl->get(basename(__DIR__)) . '">' .
|
||||
'<form id="module-translations-form" method="post" action="' . dcCore::app()->adminurl->get(My::id()) . '">' .
|
||||
'<table class="clear maximal">' .
|
||||
'<caption>' . __('Existing languages translations') . '</caption>' .
|
||||
'<tr>' .
|
||||
@ -283,7 +313,7 @@ if (empty($module) && $type != '') {
|
||||
'<td class="minimal">' . form::checkbox(['codes[]', 'existing_code_' . $code_id], $code_id, '', '', '', false) . '</td>' .
|
||||
'<td class="nowrap">' .
|
||||
'<a href="' .
|
||||
dcCore::app()->adminurl->get(basename(__DIR__), ['type' => $module->type, 'module' => $module->id, 'lang' => $code_id])
|
||||
dcCore::app()->adminurl->get(My::id(), ['type' => dcCore::app()->admin->module->type, 'module' => dcCore::app()->admin->module->id, 'lang' => $code_id])
|
||||
. '" title="' . sprintf(__('Edit %s language'), html::escapeHTML($code_name)) . '">' . $code_name . '</a>' .
|
||||
'</td>' .
|
||||
'<td class="nowrap maximal"> ' . $code_id . '</td>';
|
||||
@ -297,7 +327,7 @@ if (empty($module) && $type != '') {
|
||||
echo
|
||||
'<td class="nowrap">' . count($backups[$code_id]) . '</td>' .
|
||||
'<td class="nowrap"> ' .
|
||||
dt::str('%Y-%m-%d %H:%M', (int) $time[$code_id], dcCore::app()->blog->settings->system->blog_timezone) .
|
||||
dt::str('%Y-%m-%d %H:%M', (int) $time[$code_id], dcCore::app()->blog->settings->get('system')->get('blog_timezone')) .
|
||||
'</td>';
|
||||
} else {
|
||||
echo '<td class="nowrap">' . __('no backups') . '</td><td class="maximal nowrap">-</td>';
|
||||
@ -317,8 +347,8 @@ if (empty($module) && $type != '') {
|
||||
<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' .
|
||||
dcCore::app()->formNonce() .
|
||||
dcCore::app()->adminurl->getHiddenFormFields(
|
||||
basename(__DIR__),
|
||||
['type' => $module->type, 'module' => $module->id]
|
||||
My::id(),
|
||||
['type' => dcCore::app()->admin->module->type, 'module' => dcCore::app()->admin->module->id]
|
||||
) . '
|
||||
</p></div></form><p> </p></div>';
|
||||
}
|
||||
@ -328,7 +358,7 @@ if (empty($module) && $type != '') {
|
||||
// delete / retore backups
|
||||
if (!empty($backups)) {
|
||||
echo '<div class="fieldset"><h3>' . __('Backups') . '</h3>' .
|
||||
'<form id="module-backups-form" method="post" action="' . dcCore::app()->adminurl->get(basename(__DIR__)) . '">' .
|
||||
'<form id="module-backups-form" method="post" action="' . dcCore::app()->adminurl->get(My::id()) . '">' .
|
||||
'<table class="clear">' .
|
||||
'<caption>' . __('Existing languages backups') . '</caption>' .
|
||||
'<tr>' .
|
||||
@ -360,9 +390,9 @@ if (empty($module) && $type != '') {
|
||||
$backup_code['name'],
|
||||
$backup_code['code'],
|
||||
dt::str(
|
||||
dcCore::app()->blog->settings->system->date_format . ' ' . dcCore::app()->blog->settings->system->time_format,
|
||||
dcCore::app()->blog->settings->get('system')->get('date_format') . ' ' . dcCore::app()->blog->get('settings')->get('system->time_format'),
|
||||
(int) $backup_code['time'],
|
||||
dcCore::app()->blog->settings->system->blog_timezone
|
||||
dcCore::app()->blog->settings->get('system')->get('blog_timezone')
|
||||
),
|
||||
$backup_code['path']['basename'],
|
||||
files::size($backup_code['size'])
|
||||
@ -382,8 +412,8 @@ if (empty($module) && $type != '') {
|
||||
<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' .
|
||||
dcCore::app()->formNonce() .
|
||||
dcCore::app()->adminurl->getHiddenFormFields(
|
||||
basename(__DIR__),
|
||||
['type' => $module->type, 'module' => $module->id]
|
||||
My::id(),
|
||||
['type' => dcCore::app()->admin->module->type, 'module' => dcCore::app()->admin->module->id]
|
||||
) . '
|
||||
</p></div></form><p> </p></div>';
|
||||
}
|
||||
@ -394,7 +424,7 @@ if (empty($module) && $type != '') {
|
||||
// add language
|
||||
if (!empty($unused_codes)) {
|
||||
echo '<div class="col fieldset"><h3>' . __('Add language') . '</h3>
|
||||
<form id="muodule-code-create-form" method="post" action="' . dcCore::app()->adminurl->get(basename(__DIR__)) . '">
|
||||
<form id="muodule-code-create-form" method="post" action="' . dcCore::app()->adminurl->get(My::id()) . '">
|
||||
<p class="field"><label for="code">' . __('Select language:') . '</label>' .
|
||||
form::combo(['code'], array_merge(['-' => '-'], $unused_codes), dcCore::app()->auth->getInfo('user_lang')) . '</p>';
|
||||
if (empty($codes)) {
|
||||
@ -408,36 +438,36 @@ if (empty($module) && $type != '') {
|
||||
<p><input type="submit" name="save" value="' . __('Create') . '" />' .
|
||||
dcCore::app()->formNonce() .
|
||||
dcCore::app()->adminurl->getHiddenFormFields(
|
||||
basename(__DIR__),
|
||||
['type' => $module->type, 'module' => $module->id, 'action' => 'module_add_code']
|
||||
My::id(),
|
||||
['type' => dcCore::app()->admin->module->type, 'module' => dcCore::app()->admin->module->id, 'action' => 'module_add_code']
|
||||
) . '
|
||||
</p></form><p> </p></div>';
|
||||
}
|
||||
|
||||
// Import
|
||||
echo '<div class="col fieldset"><h3>' . __('Import') . '</h3>
|
||||
<form id="module-pack-import-form" method="post" action="' . dcCore::app()->adminurl->get(basename(__DIR__)) . '" enctype="multipart/form-data">
|
||||
<form id="module-pack-import-form" method="post" action="' . dcCore::app()->adminurl->get(My::id()) . '" enctype="multipart/form-data">
|
||||
<p><label for="packfile">' . __('Select languages package to import:') . '<label> ' .
|
||||
'<input id="packfile" type="file" name="packfile" /></p>
|
||||
<p>
|
||||
<input type="submit" name="save" value="' . __('Import') . '" />' .
|
||||
dcCore::app()->formNonce() .
|
||||
dcCore::app()->adminurl->getHiddenFormFields(
|
||||
basename(__DIR__),
|
||||
['type' => $module->type, 'module' => $module->id, 'action' => 'module_import_pack']
|
||||
My::id(),
|
||||
['type' => dcCore::app()->admin->module->type, 'module' => dcCore::app()->admin->module->id, 'action' => 'module_import_pack']
|
||||
) . '
|
||||
</p></form><p> </p></div>';
|
||||
|
||||
echo '</div>';
|
||||
|
||||
dcPage::helpBlock('translater.module');
|
||||
} elseif (!empty($lang)) {
|
||||
$lines = $lang->getMessages();
|
||||
} elseif (!empty(dcCore::app()->admin->lang)) {
|
||||
$lines = dcCore::app()->admin->lang->getMessages();
|
||||
$allowed_l10n_groups = [];
|
||||
|
||||
echo
|
||||
'<div id="lang-form">' .
|
||||
'<form id="lang-edit-form" method="post" action="' . dcCore::app()->adminurl->get(basename(__DIR__)) . '">' .
|
||||
'<form id="lang-edit-form" method="post" action="' . dcCore::app()->adminurl->get(My::id()) . '">' .
|
||||
'<table class="table-outer">' .
|
||||
'<caption>' . sprintf(__('List of %s localized strings'), count($lines)) . '</caption>' .
|
||||
'<tr>' .
|
||||
@ -461,8 +491,7 @@ if (empty($module) && $type != '') {
|
||||
|
||||
$i = 1;
|
||||
foreach ($lines as $msgid => $rs) {
|
||||
$in_dc = ($rs['in_dc'] && $translater->parse_nodc);
|
||||
$allowed_l10n_groups = array_combine($translater::$allowed_l10n_groups, $translater::$allowed_l10n_groups);
|
||||
$in_dc = ($rs['in_dc'] && dcCore::app()->admin->translater->get('parse_nodc'));
|
||||
$t_msgstr = $t_files = $strin = [];
|
||||
|
||||
foreach ($rs['o_msgstrs'] as $o_msgstr) {
|
||||
@ -496,7 +525,7 @@ if (empty($module) && $type != '') {
|
||||
$table_line,
|
||||
$in_dc ? ' offline' : ' translaterline',
|
||||
form::checkbox(['entries[' . $i . '][check]'], 1),
|
||||
form::combo(['entries[' . $i . '][group]'], $allowed_l10n_groups, $rs['group'], '', '', $in_dc),
|
||||
form::combo(['entries[' . $i . '][group]'], My::l10nGroupsCombo(), $rs['group'], '', '', $in_dc),
|
||||
html::escapeHTML($msgid),
|
||||
form::hidden(['entries[' . $i . '][msgid]'], html::escapeHTML($msgid)) .
|
||||
form::field(['entries[' . $i . '][msgstr][0]'], 48, 255, html::escapeHTML($rs['msgstr'][0]), '', '', $in_dc),
|
||||
@ -506,7 +535,7 @@ if (empty($module) && $type != '') {
|
||||
|
||||
if (!empty($rs['plural'])) {
|
||||
$t_msgstr = $strin = [];
|
||||
foreach ($lang->plural as $j => $plural) {
|
||||
foreach (dcCore::app()->admin->lang->plural as $j => $plural) {
|
||||
foreach ($rs['o_msgstrs'] as $o_msgstr) {
|
||||
if (isset($o_msgstr['msgstr'][$j + 1])) {
|
||||
if (!isset($strin[$o_msgstr['msgstr'][$j + 1]])) {
|
||||
@ -542,7 +571,7 @@ if (empty($module) && $type != '') {
|
||||
$table_line,
|
||||
' offline',
|
||||
form::checkbox(['entries[' . $i . '][check]'], 1),
|
||||
form::combo(['entries[' . $i . '][group]'], $allowed_l10n_groups, 'main'),
|
||||
form::combo(['entries[' . $i . '][group]'], My::l10nGroupsCombo(), 'main'),
|
||||
form::field(['entries[' . $i . '][msgid]'], 48, 255, ''),
|
||||
form::field(['entries[' . $i . '][msgstr][0]'], 48, 255, ''),
|
||||
'',
|
||||
@ -557,15 +586,15 @@ if (empty($module) && $type != '') {
|
||||
'<p><label for="update_group">' .
|
||||
form::checkbox('update_group', 1) .
|
||||
__('Change the group of the selected translations to:') . ' ' .
|
||||
form::combo('multigroup', $allowed_l10n_groups) . '</label></p>' .
|
||||
form::combo('multigroup', My::l10nGroupsCombo()) . '</label></p>' .
|
||||
'</div>' .
|
||||
'<p class="col right">' .
|
||||
'<input id="do-action" type="submit" value="' . __('Save') . ' (s)" accesskey="s" /></p>' .
|
||||
dcCore::app()->formNonce() .
|
||||
form::hidden(['code'], $lang->code) .
|
||||
form::hidden(['code'], dcCore::app()->admin->lang->code) .
|
||||
dcCore::app()->adminurl->getHiddenFormFields(
|
||||
basename(__DIR__),
|
||||
['type' => $module->type, 'module' => $module->id, 'lang' => $lang->code, 'action' => 'module_update_code']
|
||||
My::id(),
|
||||
['type' => dcCore::app()->admin->module->type, 'module' => dcCore::app()->admin->module->id, 'lang' => dcCore::app()->admin->lang->code, 'action' => 'module_update_code']
|
||||
) .
|
||||
'</p></div>' .
|
||||
'</form>' .
|
||||
@ -580,14 +609,14 @@ if (empty($module) && $type != '') {
|
||||
'<h3><ul class="nice">%s</ul></h3>',
|
||||
sprintf(
|
||||
$line,
|
||||
dcCore::app()->adminurl->get(basename(__DIR__), ['type' => 'plugin']),
|
||||
$type == 'plugin' ? ' class="active"' : '',
|
||||
dcCore::app()->adminurl->get(My::id(), ['type' => 'plugin']),
|
||||
dcCore::app()->admin->type == 'plugin' ? ' class="active"' : '',
|
||||
__('Translate plugins')
|
||||
) .
|
||||
sprintf(
|
||||
$line,
|
||||
dcCore::app()->adminurl->get(basename(__DIR__), ['type' => 'theme']),
|
||||
$type == 'theme' ? ' class="active"' : '',
|
||||
dcCore::app()->adminurl->get(My::id(), ['type' => 'theme']),
|
||||
dcCore::app()->admin->type == 'theme' ? ' class="active"' : '',
|
||||
__('Translate themes')
|
||||
)
|
||||
);
|
||||
@ -595,4 +624,20 @@ if (empty($module) && $type != '') {
|
||||
dcPage::helpBlock('translater.index');
|
||||
}
|
||||
|
||||
echo '</body></html>';
|
||||
dcPage::closeModule();
|
||||
}
|
||||
|
||||
private static function redirect(string $msg, ?string $lang = null): void
|
||||
{
|
||||
$redir = [
|
||||
'type' => dcCore::app()->admin->type,
|
||||
'module' => dcCore::app()->admin->module->id,
|
||||
];
|
||||
if ($lang) {
|
||||
$redir['lang'] = $lang;
|
||||
}
|
||||
|
||||
dcPage::addSuccessNotice($msg);
|
||||
dcCore::app()->adminurl->redirect(My::id(), $redir);
|
||||
}
|
||||
}
|
||||
|
140
src/My.php
Normal file
140
src/My.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?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 dcCore;
|
||||
|
||||
/**
|
||||
* Plugin definitions
|
||||
*/
|
||||
class My
|
||||
{
|
||||
/**
|
||||
* This module id
|
||||
*/
|
||||
public static function id(): string
|
||||
{
|
||||
return basename(dirname(__DIR__));
|
||||
}
|
||||
|
||||
/**
|
||||
* This module name
|
||||
*/
|
||||
public static function name(): string
|
||||
{
|
||||
return __((string) dcCore::app()->plugins->moduleInfo(self::id(), 'name'));
|
||||
}
|
||||
|
||||
/**
|
||||
* List of allowed backup folder
|
||||
*/
|
||||
public static function backupFoldersCombo(): array
|
||||
{
|
||||
return [
|
||||
__('locales folders of each module') => 'module',
|
||||
__('plugins folder root') => 'plugin',
|
||||
__('public folder root') => 'public',
|
||||
__('cache folder of Dotclear') => 'cache',
|
||||
__('locales folder of translater') => self::id(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* List of possible home tab of the plugin
|
||||
*/
|
||||
public static function startPageCombo()
|
||||
{
|
||||
return [
|
||||
__('Plugins') => 'plugin',
|
||||
__('Themes') => 'theme',
|
||||
__('Home') => '-',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* List of place of tranlsations
|
||||
*/
|
||||
public static function l10nGroupsCombo(): array
|
||||
{
|
||||
$groups = [
|
||||
'main', 'public', 'theme', 'admin', 'date', 'error',
|
||||
];
|
||||
|
||||
return array_combine($groups, $groups);
|
||||
}
|
||||
|
||||
/**
|
||||
* List of user info can be parsed
|
||||
*/
|
||||
public static function defaultUserInformations(): array
|
||||
{
|
||||
return [
|
||||
'firstname', 'displayname', 'name', 'email', 'url',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* List of distributed plugins and themes
|
||||
*/
|
||||
public static function defaultDistribModules(string $type): array
|
||||
{
|
||||
$types = [
|
||||
'plugin' => explode(',', DC_DISTRIB_PLUGINS),
|
||||
'theme' => explode(',', DC_DISTRIB_THEMES),
|
||||
];
|
||||
|
||||
return $types[$type] ?? [];
|
||||
}
|
||||
|
||||
public static function defaultSettings(): array
|
||||
{
|
||||
return [
|
||||
// Show tranlsater button on plugins list
|
||||
'plugin_menu' => false,
|
||||
// Show tranlsater button on themes list
|
||||
'theme_menu' => false,
|
||||
// Create language backup on save
|
||||
'backup_auto' => false,
|
||||
// Backups number limit
|
||||
'backup_limit' => 20,
|
||||
// Backup main folder
|
||||
'backup_folder' => 'module',
|
||||
// Default ui start page
|
||||
'start_page' => '-',
|
||||
// Write .lang.php file (deprecated)
|
||||
'write_langphp' => false,
|
||||
// Scan also template files for translations
|
||||
'scan_tpl' => true,
|
||||
// Disable translation of know dotclear strings
|
||||
'parse_nodc' => true,
|
||||
// Hide official modules
|
||||
'hide_default' => true,
|
||||
// Add comment to translations files
|
||||
'parse_comment' => false,
|
||||
// Parse user info to translations files
|
||||
'parse_user' => false,
|
||||
// User infos to parse
|
||||
'parse_userinfo' => 'displayname, email',
|
||||
// Overwrite existing languages on import
|
||||
'import_overwrite' => false,
|
||||
// Filename of exported lang
|
||||
'export_filename' => 'type-module-l10n-timestamp',
|
||||
// Default service for external proposal tool
|
||||
'proposal_tool' => 'google',
|
||||
// Default lang for external proposal tool
|
||||
'proposal_lang' => 'en',
|
||||
];
|
||||
}
|
||||
}
|
@ -10,18 +10,34 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_RC_PATH')) {
|
||||
return;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
use dcCore;
|
||||
use dcNsProcess;
|
||||
|
||||
class Prepend extends dcNsProcess
|
||||
{
|
||||
public static function init(): bool
|
||||
{
|
||||
if (defined('DC_CONTEXT_ADMIN')) {
|
||||
self::$init = dcCore::app()->auth->isSuperAdmin();
|
||||
}
|
||||
|
||||
Clearbricks::lib()->autoload([
|
||||
'dcTranslater' => __DIR__ . '/inc/class.dc.translater.php',
|
||||
'dcTranslaterDefaultSettings' => __DIR__ . '/inc/class.dc.translater.php',
|
||||
'dcTranslaterModule' => __DIR__ . '/inc/class.dc.translater.module.php',
|
||||
'dcTranslaterLang' => __DIR__ . '/inc/class.dc.translater.lang.php',
|
||||
'translaterRest' => __DIR__ . '/class.translater.rest.php',
|
||||
]);
|
||||
return self::$init;
|
||||
}
|
||||
|
||||
public static function process(): bool
|
||||
{
|
||||
if (!self::$init) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset(dcCore::app()->adminurl)) {
|
||||
dcCore::app()->adminurl->register(basename(__DIR__), 'plugin.php', ['p' => basename(__DIR__)]);
|
||||
dcCore::app()->adminurl->register(My::id(), 'plugin.php', ['p' => My::id()]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,13 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return;
|
||||
}
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
use dcCore;
|
||||
use form;
|
||||
use netHttp;
|
||||
|
||||
/**
|
||||
* Google proposal tool.
|
||||
@ -22,12 +26,12 @@ if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
class googleProposalTool extends translaterProposalTool
|
||||
{
|
||||
private $api = 'https://www.googleapis.com/language/translate/v2';
|
||||
private $agent = 'dcTranslater - http://jcd.lv/?q=translater';
|
||||
private $agent = 'Translater - http://jcd.lv/?q=translater';
|
||||
private $key = null; //ex: AsSDqsGsfdSDSQFQsfedj9bnzY390aIg-1d
|
||||
|
||||
protected function setup()
|
||||
{
|
||||
$this->key = dcCore::app()->blog->settings->get(basename(dirname(__DIR__)))->get('google_proposal_key');
|
||||
$this->key = dcCore::app()->blog->settings->get(My::id())->get('google_proposal_key');
|
||||
|
||||
$this->setName(__('Google'));
|
||||
$this->setDesc(__('Google Translation Tool API'));
|
||||
@ -53,7 +57,7 @@ class googleProposalTool extends translaterProposalTool
|
||||
$key = empty($_POST['translater_google_proposal_key']) ?
|
||||
'' : $_POST['translater_google_proposal_key'];
|
||||
|
||||
dcCore::app()->blog->settings->get(basename(dirname(__DIR__)))->put('google_proposal_key', $key, 'string', '', true, true);
|
||||
dcCore::app()->blog->settings->get(My::id())->put('google_proposal_key', $key, 'string', '', true, true);
|
||||
}
|
||||
|
||||
public function translate($str, $from, $to)
|
||||
|
@ -10,9 +10,12 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return;
|
||||
}
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
use dcCore;
|
||||
use form;
|
||||
|
||||
/**
|
||||
* Microsoft proposal tool.
|
||||
@ -27,8 +30,8 @@ class microsoftProposalTool extends translaterProposalTool
|
||||
protected function setup()
|
||||
{
|
||||
$this->setActive(false);
|
||||
$this->client = dcCore::app()->blog->settings->get(basename(dirname(__DIR__)))->get('microsoft_proposal_client');
|
||||
$this->secret = dcCore::app()->blog->settings->get(basename(dirname(__DIR__)))->get('microsoft_proposal_secret');
|
||||
$this->client = dcCore::app()->blog->settings->get(My::id())->get('microsoft_proposal_client');
|
||||
$this->secret = dcCore::app()->blog->settings->get(My::id())->get('microsoft_proposal_secret');
|
||||
|
||||
$this->setName(__('Bing'));
|
||||
$this->setDesc(__('Microsoft Bing translation tool'));
|
||||
@ -61,8 +64,8 @@ class microsoftProposalTool extends translaterProposalTool
|
||||
$secret = empty($_POST['translater_microsoft_proposal_secret']) ?
|
||||
'' : $_POST['translater_microsoft_proposal_secret'];
|
||||
|
||||
dcCore::app()->blog->settings->get(basename(dirname(__DIR__)))->put('microsoft_proposal_client', $client, 'string', '', true, true);
|
||||
dcCore::app()->blog->settings->get(basename(dirname(__DIR__)))->put('microsoft_proposal_secret', $secret, 'string', '', true, true);
|
||||
dcCore::app()->blog->settings->get(My::id())->put('microsoft_proposal_client', $client, 'string', '', true, true);
|
||||
dcCore::app()->blog->settings->get(My::id())->put('microsoft_proposal_secret', $secret, 'string', '', true, true);
|
||||
}
|
||||
|
||||
public function translate($str, $from, $to)
|
||||
@ -82,6 +85,7 @@ class microsoftProposalTool extends translaterProposalTool
|
||||
private function doYourFuckingJob($client, $secret, $str, $from, $to)
|
||||
{
|
||||
try {
|
||||
$translatedStr = '';
|
||||
//Client ID of the application.
|
||||
$clientID = $client;
|
||||
//Client Secret key of the application.
|
||||
|
@ -10,6 +10,10 @@
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* Translater proposal tool.
|
||||
*
|
||||
|
15
src/Rest.php
15
src/Rest.php
@ -10,9 +10,14 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return;
|
||||
}
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
use dcCore;
|
||||
use html;
|
||||
use text;
|
||||
use xmlTag;
|
||||
|
||||
/**
|
||||
* Translater REST service.
|
||||
@ -20,7 +25,7 @@ if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
* Admin service de retrieve translation of a string
|
||||
* Queries come from translater jquery tools
|
||||
*/
|
||||
class translaterRest
|
||||
class Rest
|
||||
{
|
||||
public static function getProposal($get)
|
||||
{
|
||||
@ -40,7 +45,7 @@ class translaterRest
|
||||
throw new Exception(__('Missing params'));
|
||||
}
|
||||
|
||||
$translater = new dcTranslater();
|
||||
$translater = new Translater();
|
||||
|
||||
if (!empty($str_in)) {
|
||||
if (!$translater->proposal->hasTool($tool)) {
|
||||
|
@ -10,79 +10,24 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return;
|
||||
}
|
||||
declare(strict_types=1);
|
||||
|
||||
class dcTranslaterDefaultSettings
|
||||
{
|
||||
/** @var boolean Show tranlsater button on plugins list */
|
||||
public $plugin_menu = false;
|
||||
/** @var boolean Show tranlsater button on themes list */
|
||||
public $theme_menu = false;
|
||||
/** @var boolean Create language backup on save */
|
||||
public $backup_auto = false;
|
||||
/** @var integer Backups number limit */
|
||||
public $backup_limit = 20;
|
||||
/** @var string Backup main folder */
|
||||
public $backup_folder = 'module';
|
||||
/** @var string Default ui start page */
|
||||
public $start_page = '-';
|
||||
/** @var boolean Write .lang.php file (deprecated) */
|
||||
public $write_langphp = false;
|
||||
/** @var boolean SCan also template files for translations */
|
||||
public $scan_tpl = true;
|
||||
/** @var boolean Disable translation of know dotclear strings */
|
||||
public $parse_nodc = true;
|
||||
/** @var boolean Hide official modules */
|
||||
public $hide_default = true;
|
||||
/** @var boolean Add comment to translations files */
|
||||
public $parse_comment = false;
|
||||
/** @var boolean Parse user info to translations files */
|
||||
public $parse_user = false;
|
||||
/** @var string User infos to parse */
|
||||
public $parse_userinfo = 'displayname, email';
|
||||
/** @var boolean Overwrite existing languages on import */
|
||||
public $import_overwrite = false;
|
||||
/** @var string Filename of exported lang */
|
||||
public $export_filename = 'type-module-l10n-timestamp';
|
||||
/** @var string Default service for external proposal tool */
|
||||
public $proposal_tool = 'google';
|
||||
/** @var string Default lang for external proposal tool */
|
||||
public $proposal_lang = 'en';
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
/**
|
||||
* get default settings
|
||||
*
|
||||
* @return array Settings key/value pair
|
||||
*/
|
||||
public static function getDefaultSettings()
|
||||
{
|
||||
return get_class_vars('dcTranslaterDefaultSettings');
|
||||
}
|
||||
}
|
||||
use dcCore;
|
||||
use dcThemes;
|
||||
use files;
|
||||
use l10n;
|
||||
use path;
|
||||
use text;
|
||||
|
||||
/**
|
||||
* Translater tools.
|
||||
*/
|
||||
class dcTranslater extends dcTranslaterDefaultSettings
|
||||
class Translater
|
||||
{
|
||||
/** @var array $allowed_backup_folders List of allowed backup folder */
|
||||
public static $allowed_backup_folders = [];
|
||||
|
||||
/** @var array $allowed_l10n_groups List of place of tranlsations */
|
||||
public static $allowed_l10n_groups = [
|
||||
'main', 'public', 'theme', 'admin', 'date', 'error',
|
||||
];
|
||||
|
||||
/** @var array $allowed_user_informations List of user info can be parsed */
|
||||
public static $allowed_user_informations = [
|
||||
'firstname', 'displayname', 'name', 'email', 'url',
|
||||
];
|
||||
|
||||
/** @var array $default_distrib_modules List of distributed plugins and themes */
|
||||
public static $default_distrib_modules = ['plugin' => [], 'theme' => []];
|
||||
|
||||
/** @var array $settings Translater settings */
|
||||
private $settings = [];
|
||||
/** @var array $modules List of modules we could work on */
|
||||
private $modules = [];
|
||||
|
||||
@ -98,18 +43,6 @@ class dcTranslater extends dcTranslaterDefaultSettings
|
||||
if ($full) {
|
||||
$this->loadModules();
|
||||
}
|
||||
|
||||
self::$allowed_backup_folders = [
|
||||
__('locales folders of each module') => 'module',
|
||||
__('plugins folder root') => 'plugin',
|
||||
__('public folder root') => 'public',
|
||||
__('cache folder of Dotclear') => 'cache',
|
||||
__('locales folder of translater') => basename(dirname(__DIR__)),
|
||||
];
|
||||
self::$default_distrib_modules = [
|
||||
'plugin' => explode(',', DC_DISTRIB_PLUGINS),
|
||||
'theme' => explode(',', DC_DISTRIB_THEMES),
|
||||
];
|
||||
}
|
||||
|
||||
/// @name settings methods
|
||||
@ -119,13 +52,9 @@ class dcTranslater extends dcTranslaterDefaultSettings
|
||||
*/
|
||||
public function loadSettings(): void
|
||||
{
|
||||
foreach ($this->getDefaultSettings() as $key => $value) {
|
||||
$this->$key = dcCore::app()->blog->settings->get(basename(dirname(__DIR__)))->get($key);
|
||||
|
||||
try {
|
||||
settype($this->$key, gettype($value));
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
foreach (My::defaultSettings() as $key => $value) {
|
||||
$this->settings[$key] = $value;
|
||||
$this->set($key, dcCore::app()->blog->settings->get(My::id())->get($key));
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,43 +65,39 @@ class dcTranslater extends dcTranslaterDefaultSettings
|
||||
*/
|
||||
public function writeSettings($overwrite = true): void
|
||||
{
|
||||
foreach ($this->getDefaultSettings() as $key => $value) {
|
||||
dcCore::app()->blog->settings->get(basename(dirname(__DIR__)))->drop($key);
|
||||
dcCore::app()->blog->settings->get(basename(dirname(__DIR__)))->put($key, $this->$key, gettype($value), '', true, true);
|
||||
foreach (My::defaultSettings() as $key => $value) {
|
||||
dcCore::app()->blog->settings->get(My::id())->drop($key);
|
||||
dcCore::app()->blog->settings->get(My::id())->put($key, $this->settings[$key], gettype($value), '', true, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade plugin
|
||||
* Read a setting
|
||||
*
|
||||
* @return bool Upgrade done
|
||||
* @param string $key The setting id
|
||||
*
|
||||
* @return mixed The setting value
|
||||
*/
|
||||
public function growUp()
|
||||
public function get(string $key): mixed
|
||||
{
|
||||
$current = dcCore::app()->getVersion(basename(dirname(__DIR__)));
|
||||
|
||||
// use short settings id
|
||||
if ($current && version_compare($current, '2022.12.22', '<')) {
|
||||
$record = dcCore::app()->con->select(
|
||||
'SELECT * FROM ' . dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME . ' ' .
|
||||
"WHERE setting_ns = 'translater' "
|
||||
);
|
||||
while ($record->fetch()) {
|
||||
if (preg_match('/^translater_(.*?)$/', $record->setting_id, $match)) {
|
||||
$cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME);
|
||||
$cur->setting_id = $this->{$match[1]} = $match[1];
|
||||
$cur->setting_ns = basename(dirname(__DIR__));
|
||||
$cur->update(
|
||||
"WHERE setting_id = '" . $record->setting_id . "' and setting_ns = 'translater' " .
|
||||
'AND blog_id ' . (null === $record->blog_id ? 'IS NULL ' : ("= '" . dcCore::app()->con->escape($record->blog_id) . "' "))
|
||||
);
|
||||
}
|
||||
return $this->settings[$key] ?? null;
|
||||
}
|
||||
|
||||
return true;
|
||||
/**
|
||||
* Write (temporary) a setting
|
||||
*
|
||||
* @param string $key The setting id
|
||||
* @param mixed $value The setting value
|
||||
*/
|
||||
public function set(string $key, mixed $value): void
|
||||
{
|
||||
if (isset($this->settings[$key])) {
|
||||
try {
|
||||
settype($value, gettype($this->settings[$key]));
|
||||
$this->settings[$key] = $value;
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//@}
|
||||
|
||||
@ -185,11 +110,13 @@ class dcTranslater extends dcTranslaterDefaultSettings
|
||||
{
|
||||
$this->modules['theme'] = $this->modules['plugin'] = [];
|
||||
|
||||
$themes = new dcThemes();
|
||||
$themes->loadModules(dcCore::app()->blog->themes_path, null);
|
||||
if (!(dcCore::app()->themes instanceof dcThemes)) {
|
||||
dcCore::app()->themes = new dcThemes();
|
||||
dcCore::app()->themes->loadModules(dcCore::app()->blog->themes_path, null);
|
||||
}
|
||||
|
||||
$list = [
|
||||
'theme' => $themes->getModules(),
|
||||
'theme' => dcCore::app()->themes->getModules(),
|
||||
'plugin' => dcCore::app()->plugins->getModules(),
|
||||
];
|
||||
foreach ($list as $type => $modules) {
|
||||
@ -199,7 +126,7 @@ class dcTranslater extends dcTranslaterDefaultSettings
|
||||
}
|
||||
$info['id'] = $id;
|
||||
$info['type'] = $type;
|
||||
$this->modules[$type][$id] = new dcTranslaterModule($this, $info);
|
||||
$this->modules[$type][$id] = new TranslaterModule($this, $info);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -224,9 +151,9 @@ class dcTranslater extends dcTranslaterDefaultSettings
|
||||
* @param string $type The module type
|
||||
* @param string $id The module id
|
||||
*
|
||||
* @return dcTranslaterModule The dcTranslaterModule instance
|
||||
* @return TranslaterModule The TranslaterModule instance
|
||||
*/
|
||||
public function getModule(string $type, string $id)
|
||||
public function getModule(string $type, string $id): TranslaterModule
|
||||
{
|
||||
if (!isset($this->modules[$type][$id])) {
|
||||
throw new Exception(
|
||||
@ -240,12 +167,12 @@ class dcTranslater extends dcTranslaterDefaultSettings
|
||||
/**
|
||||
* Return module class of a particular module for a given type of module
|
||||
*
|
||||
* @param dcTranslaterModule $module dcTranslaterModule instance
|
||||
* @param TranslaterModule $module TranslaterModule instance
|
||||
* @param string $lang The lang iso code
|
||||
*
|
||||
* @return dcTranslaterLang dcTranslaterLang instance or false
|
||||
* @return TranslaterLang TranslaterLang instance or false
|
||||
*/
|
||||
public function getLang(dcTranslaterModule $module, string $lang)
|
||||
public function getLang(TranslaterModule $module, string $lang): TranslaterLang
|
||||
{
|
||||
if (!l10n::isCode($lang)) {
|
||||
throw new Exception(
|
||||
@ -253,7 +180,7 @@ class dcTranslater extends dcTranslaterDefaultSettings
|
||||
);
|
||||
}
|
||||
|
||||
return new dcTranslaterLang($module, $lang);
|
||||
return new TranslaterLang($module, $lang);
|
||||
}
|
||||
//@}
|
||||
|
||||
|
@ -10,17 +10,25 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
class dcTranslaterLang
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
use files;
|
||||
use l10n;
|
||||
use path;
|
||||
|
||||
class TranslaterLang
|
||||
{
|
||||
/** @var dcTranslater dcTranslater instance */
|
||||
/** @var Translater Translater instance */
|
||||
public $translater = null;
|
||||
/** @var dcTranslaterModule dcTranslaterModule instance */
|
||||
/** @var TranslaterModule TranslaterModule instance */
|
||||
public $module = null;
|
||||
|
||||
/** @var array Lang properies */
|
||||
private $prop = [];
|
||||
|
||||
public function __construct(dcTranslaterModule $module, string $lang)
|
||||
public function __construct(TranslaterModule $module, string $lang)
|
||||
{
|
||||
$this->translater = $module->translater;
|
||||
$this->module = $module;
|
||||
@ -61,12 +69,12 @@ class dcTranslaterLang
|
||||
$m_msgstrs = $this->getMsgStrs();
|
||||
|
||||
foreach ($this->translater->getModules() as $module) {
|
||||
if ($module->id != $this->module->id) {
|
||||
$m_o_msgstrs[$module->id] = $this->translater->getlang($module, $this->code)->getMsgStrs();
|
||||
if ($module->id != $this->module->get('id')) {
|
||||
$m_o_msgstrs[$module->get('id')] = $this->translater->getlang($module, $this->get('code'))->getMsgStrs();
|
||||
}
|
||||
}
|
||||
$dc_module = new dcTranslaterModule($this->translater, ['id' => 'dotclear', 'root' => DC_ROOT]);
|
||||
$dc_lang = new dcTranslaterLang($dc_module, $this->code);
|
||||
$dc_module = new TranslaterModule($this->translater, ['id' => 'dotclear', 'root' => DC_ROOT]);
|
||||
$dc_lang = new TranslaterLang($dc_module, $this->get('code'));
|
||||
$m_o_msgstrs['dotclear'] = $dc_lang->getMsgStrs();
|
||||
|
||||
# From id list
|
||||
@ -122,30 +130,30 @@ class dcTranslaterLang
|
||||
{
|
||||
$res = [];
|
||||
$scan_ext = ['php'];
|
||||
if ($this->translater->scan_tpl) {
|
||||
if ($this->translater->get('scan_tpl')) {
|
||||
$scan_ext[] = 'html';
|
||||
}
|
||||
|
||||
$files = dcTranslater::scandir($this->module->root);
|
||||
$files = Translater::scandir($this->module->get('root'));
|
||||
foreach ($files as $file) {
|
||||
$extension = files::getExtension($file);
|
||||
if (is_dir($this->module->root . '/' . $file) || !in_array($extension, $scan_ext)) {
|
||||
if (is_dir($this->module->get('root') . '/' . $file) || !in_array($extension, $scan_ext)) {
|
||||
continue;
|
||||
}
|
||||
$contents = file_get_contents($this->module->root . '/' . $file);
|
||||
$contents = file_get_contents($this->module->get('root') . '/' . $file);
|
||||
$msgs = [];
|
||||
# php files
|
||||
if ($extension == 'php') {
|
||||
$msgs = dcTranslater::extractPhpMsgs($contents);
|
||||
$msgs = Translater::extractPhpMsgs($contents);
|
||||
|
||||
# tpl files
|
||||
} elseif ($extension == 'html') {
|
||||
$msgs = dcTranslater::extractTplMsgs($contents);
|
||||
$msgs = Translater::extractTplMsgs($contents);
|
||||
}
|
||||
foreach ($msgs as $msg) {
|
||||
$res[] = [
|
||||
'msgid' => dcTranslater::encodeMsg($msg[0][0]),
|
||||
'msgid_plural' => empty($msg[0][1]) ? '' : dcTranslater::encodeMsg($msg[0][1]),
|
||||
'msgid' => Translater::encodeMsg($msg[0][0]),
|
||||
'msgid_plural' => empty($msg[0][1]) ? '' : Translater::encodeMsg($msg[0][1]),
|
||||
'file' => $file,
|
||||
'line' => $msg[1],
|
||||
];
|
||||
@ -167,18 +175,18 @@ class dcTranslaterLang
|
||||
$res = $exists = $scanned = [];
|
||||
|
||||
$langs = $this->module->getLangs(true);
|
||||
if (!isset($langs[$this->code])) {
|
||||
if (!isset($langs[$this->get('code')])) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
foreach ($langs[$this->code] as $file) {
|
||||
foreach ($langs[$this->get('code')] as $file) {
|
||||
if (in_array($file, $scanned)) {
|
||||
continue;
|
||||
}
|
||||
$scanned[] = $file;
|
||||
$path = path::clean($this->module->locales . '/' . $file);
|
||||
$path = path::clean($this->module->get('locales') . '/' . $file);
|
||||
|
||||
if (dcTranslater::isPoFile($file)) {
|
||||
if (Translater::isPoFile($file)) {
|
||||
$po = l10n::parsePoFile($path);
|
||||
if (!is_array($po)) {
|
||||
continue;
|
||||
@ -189,7 +197,7 @@ class dcTranslaterLang
|
||||
'msgid' => $entry['msgid'],
|
||||
'msgid_plural' => $entry['msgid_plural'] ?? '',
|
||||
'msgstr' => is_array($entry['msgstr']) ? $entry['msgstr'] : [$entry['msgstr']],
|
||||
'lang' => $this->code,
|
||||
'lang' => $this->get('code'),
|
||||
'type' => 'po',
|
||||
'path' => $path,
|
||||
'file' => basename($file),
|
||||
|
@ -10,16 +10,25 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return;
|
||||
}
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
use dcCore;
|
||||
use dt;
|
||||
use html;
|
||||
use files;
|
||||
use fileZip;
|
||||
use fileUnzip;
|
||||
use l10n;
|
||||
use path;
|
||||
|
||||
/**
|
||||
* Translater tools.
|
||||
*/
|
||||
class dcTranslaterModule
|
||||
class TranslaterModule
|
||||
{
|
||||
/** @var dcTranslater dcTranslater instance */
|
||||
/** @var Translater Translater instance */
|
||||
public $translater = null;
|
||||
|
||||
/** @var array Module properies */
|
||||
@ -28,10 +37,7 @@ class dcTranslaterModule
|
||||
/** @var string Backup file regexp */
|
||||
private $backup_file_regexp = '/^l10n-%s-(.*?)-[0-9]*?\.bck\.zip$/';
|
||||
|
||||
/** @var string Locales file regexp */
|
||||
private $locales_file_regexp = '/^(.*?)\/locales\/(.*?)\/(.*?)(.po|.lang.php)$/';
|
||||
|
||||
public function __construct(dcTranslater $translater, array $module)
|
||||
public function __construct(Translater $translater, array $module)
|
||||
{
|
||||
$this->translater = $translater;
|
||||
$this->prop = $module;
|
||||
@ -72,7 +78,7 @@ class dcTranslaterModule
|
||||
public function getBackupRoot(bool $throw = false)
|
||||
{
|
||||
$dir = false;
|
||||
switch ($this->translater->backup_folder) {
|
||||
switch ($this->translater->get('backup_folder')) {
|
||||
case 'module':
|
||||
if ($this->prop['root_writable']) {
|
||||
$dir = $this->prop['locales'];
|
||||
@ -81,7 +87,8 @@ class dcTranslaterModule
|
||||
break;
|
||||
|
||||
case 'plugin':
|
||||
$tmp = path::real(array_pop(explode(PATH_SEPARATOR, DC_PLUGINS_ROOT)));
|
||||
$exp = explode(PATH_SEPARATOR, DC_PLUGINS_ROOT);
|
||||
$tmp = path::real(array_pop($exp));
|
||||
if ($tmp && is_writable($tmp)) {
|
||||
$dir = $tmp;
|
||||
}
|
||||
@ -106,7 +113,7 @@ class dcTranslaterModule
|
||||
break;
|
||||
|
||||
case 'translater':
|
||||
$tmp = path::real(dcCore::app()->plugins->moduleRoot(basename(dirname(__DIR__))));
|
||||
$tmp = path::real(dcCore::app()->plugins->moduleRoot(My::id()));
|
||||
if ($tmp && is_writable($tmp)) {
|
||||
@mkDir($tmp . '/locales');
|
||||
$dir = $tmp . '/locales';
|
||||
@ -138,7 +145,7 @@ class dcTranslaterModule
|
||||
}
|
||||
|
||||
$res = [];
|
||||
$files = dcTranslater::scandir($backup);
|
||||
$files = Translater::scandir($backup);
|
||||
foreach ($files as $file) {
|
||||
$is_backup = preg_match(sprintf($this->backup_file_regexp, preg_quote($this->prop['id'])), $file, $m);
|
||||
|
||||
@ -182,17 +189,17 @@ class dcTranslaterModule
|
||||
}
|
||||
|
||||
$res = [];
|
||||
$files = dcTranslater::scandir($this->prop['locales'] . '/' . $lang);
|
||||
$files = Translater::scandir($this->prop['locales'] . '/' . $lang);
|
||||
foreach ($files as $file) {
|
||||
if (!is_dir($this->prop['locales'] . '/' . $lang . '/' . $file)
|
||||
&& (dcTranslater::isLangphpFile($file) || dcTranslater::isPoFile($file))
|
||||
&& (Translater::isLangphpFile($file) || Translater::isPoFile($file))
|
||||
) {
|
||||
$res[$this->prop['locales'] . '/' . $lang . '/' . $file] = $this->prop['id'] . '/locales/' . $lang . '/' . $file;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($res)) {
|
||||
dcTranslater::isBackupLimit($this->prop['id'], $backup, $this->translater->backup_limit, true);
|
||||
Translater::isBackupLimit($this->prop['id'], $backup, $this->translater->get('backup_limit'), true);
|
||||
|
||||
@set_time_limit(300);
|
||||
$fp = fopen($backup . '/l10n-' . $this->prop['id'] . '-' . $lang . '-' . time() . '.bck.zip', 'wb');
|
||||
@ -206,6 +213,8 @@ class dcTranslaterModule
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -291,7 +300,7 @@ class dcTranslaterModule
|
||||
foreach ($files as $file) {
|
||||
$f = $this->parseZipFilename($file, true);
|
||||
|
||||
if (!$this->translater->import_overwrite
|
||||
if (!$this->translater->get('import_overwrite')
|
||||
&& file_exists($this->prop['locales'] . '/' . $f['lang'] . '/' . $f['group'] . $f['ext'])
|
||||
) {
|
||||
$not_overwrited[] = implode('-', [$f['lang'], $f['group'], $f['ext']]);
|
||||
@ -337,7 +346,7 @@ class dcTranslaterModule
|
||||
*
|
||||
* @param array $langs Langs to export
|
||||
*/
|
||||
public function exportPack(array $langs)
|
||||
public function exportPack(array $langs): void
|
||||
{
|
||||
if (empty($langs)) {
|
||||
throw new Exception(
|
||||
@ -345,7 +354,7 @@ class dcTranslaterModule
|
||||
);
|
||||
}
|
||||
|
||||
$filename = files::tidyFileName($this->translater->export_filename);
|
||||
$filename = files::tidyFileName($this->translater->get('export_filename'));
|
||||
if (empty($filename)) {
|
||||
throw new Exception(
|
||||
__('Export mask is not set in plugin configuration')
|
||||
@ -358,11 +367,11 @@ class dcTranslaterModule
|
||||
continue;
|
||||
}
|
||||
|
||||
$files = dcTranslater::scandir($this->prop['locales'] . '/' . $lang);
|
||||
$files = Translater::scandir($this->prop['locales'] . '/' . $lang);
|
||||
foreach ($files as $file) {
|
||||
if (is_dir($this->prop['locales'] . '/' . $lang . '/' . $file)
|
||||
|| !dcTranslater::isLangphpFile($file)
|
||||
&& !dcTranslater::isPoFile($file)
|
||||
|| !Translater::isLangphpFile($file)
|
||||
&& !Translater::isPoFile($file)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
@ -387,7 +396,7 @@ class dcTranslaterModule
|
||||
$filename = files::tidyFileName(dt::str(str_replace(
|
||||
['timestamp', 'module', 'type', 'version'],
|
||||
[time(), $this->prop['id'], $this->prop['type'], $this->prop['version']],
|
||||
$this->translater->export_filename
|
||||
$this->translater->get('export_filename')
|
||||
)));
|
||||
|
||||
header('Content-Disposition: attachment;filename=' . $filename . '.zip');
|
||||
@ -402,7 +411,7 @@ class dcTranslaterModule
|
||||
*
|
||||
* @param string $file The zip filename
|
||||
* @param boolean $throw Silently failed
|
||||
* @return mixed Array of file info
|
||||
* @return array Array of file info
|
||||
*/
|
||||
public function parseZipFilename(string $file = '', bool $throw = false): array
|
||||
{
|
||||
@ -411,8 +420,8 @@ class dcTranslaterModule
|
||||
if ($is_file) {
|
||||
$module = $f[1] == $this->prop['id'] ? $f[1] : false;
|
||||
$lang = l10n::isCode($f[2]) ? $f[2] : 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;
|
||||
$group = in_array($f[3], My::l10nGroupsCombo()) ? $f[3] : false;
|
||||
$ext = Translater::isLangphpFile($f[4]) || Translater::isPoFile($f[4]) ? $f[4] : false;
|
||||
}
|
||||
|
||||
if (!$is_file || !$module || !$lang || !$group || !$ext) {
|
||||
@ -449,7 +458,7 @@ class dcTranslaterModule
|
||||
|
||||
$prefix = preg_match('/(locales(.*))$/', $this->prop['locales']) ? 'locales' : '';
|
||||
|
||||
$files = dcTranslater::scandir($this->prop['locales']);
|
||||
$files = Translater::scandir($this->prop['locales']);
|
||||
foreach ($files as $file) {
|
||||
if (!preg_match('/.*?locales\/([^\/]*?)\/([^\/]*?)(.lang.php|.po)$/', $prefix . $file, $m)) {
|
||||
continue;
|
||||
@ -474,7 +483,7 @@ class dcTranslaterModule
|
||||
*
|
||||
* @return array The list of iso names and codes
|
||||
*/
|
||||
public function getUsedLangs()
|
||||
public function getUsedLangs(): array
|
||||
{
|
||||
return array_flip($this->getLangs());
|
||||
}
|
||||
@ -484,7 +493,7 @@ class dcTranslaterModule
|
||||
*
|
||||
* @return array The list of iso names and codes
|
||||
*/
|
||||
public function getUnusedLangs()
|
||||
public function getUnusedLangs(): array
|
||||
{
|
||||
return array_diff(l10n::getISOcodes(true, false), $this->getUsedLangs());
|
||||
}
|
||||
@ -496,7 +505,7 @@ class dcTranslaterModule
|
||||
* @param string $from_lang The lang to copy from
|
||||
* @return boolean True on success
|
||||
*/
|
||||
public function addLang(string $lang, string $from_lang = '')
|
||||
public function addLang(string $lang, string $from_lang = ''): bool
|
||||
{
|
||||
if (!l10n::isCode($lang)) {
|
||||
throw new Exception(sprintf(
|
||||
@ -523,11 +532,11 @@ class dcTranslaterModule
|
||||
}
|
||||
|
||||
if (!empty($from_lang) && isset($langs[$from_lang])) {
|
||||
$files = dcTranslater::scandir($this->prop['locales'] . '/' . $from_lang);
|
||||
$files = Translater::scandir($this->prop['locales'] . '/' . $from_lang);
|
||||
foreach ($files as $file) {
|
||||
if (is_dir($this->prop['locales'] . '/' . $from_lang . '/' . $file)
|
||||
|| !dcTranslater::isLangphpFile($file)
|
||||
&& !dcTranslater::isPoFile($file)
|
||||
|| !Translater::isLangphpFile($file)
|
||||
&& !Translater::isPoFile($file)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
@ -541,6 +550,8 @@ class dcTranslaterModule
|
||||
$this->setPoContent($lang, 'main', []);
|
||||
$this->setLangphpContent($lang, 'main', []);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -549,7 +560,7 @@ class dcTranslaterModule
|
||||
* @param string $lang The lang
|
||||
* @param array $msgs The messages
|
||||
*/
|
||||
public function updLang(string $lang, array $msgs)
|
||||
public function updLang(string $lang, array $msgs): void
|
||||
{
|
||||
if (!l10n::isCode($lang)) {
|
||||
throw new Exception(sprintf(
|
||||
@ -566,7 +577,7 @@ class dcTranslaterModule
|
||||
));
|
||||
}
|
||||
|
||||
if ($this->translater->backup_auto) {
|
||||
if ($this->translater->get('backup_auto')) {
|
||||
$this->createBackup($lang);
|
||||
}
|
||||
|
||||
@ -578,7 +589,7 @@ class dcTranslaterModule
|
||||
$rs[$msg['group']][] = $msg;
|
||||
}
|
||||
|
||||
foreach (dcTranslater::$allowed_l10n_groups as $group) {
|
||||
foreach (My::l10nGroupsCombo() as $group) {
|
||||
if (isset($rs[$group])) {
|
||||
continue;
|
||||
}
|
||||
@ -636,12 +647,12 @@ class dcTranslaterModule
|
||||
unlink($this->prop['locales'] . '/' . $file);
|
||||
}
|
||||
|
||||
$dir = dcTranslater::scandir($this->prop['locales'] . '/' . $lang);
|
||||
$dir = Translater::scandir($this->prop['locales'] . '/' . $lang);
|
||||
if (empty($dir)) {
|
||||
rmdir($this->prop['locales'] . '/' . $lang);
|
||||
}
|
||||
|
||||
$loc = dcTranslater::scandir($this->prop['locales']);
|
||||
$loc = Translater::scandir($this->prop['locales']);
|
||||
if (empty($loc)) {
|
||||
rmdir($this->prop['locales']);
|
||||
}
|
||||
@ -656,32 +667,33 @@ class dcTranslaterModule
|
||||
* @param string $group The lang group
|
||||
* @param array $msgs The strings
|
||||
*/
|
||||
private function setPoContent(string $lang, string $group, array $msgs)
|
||||
private function setPoContent(string $lang, string $group, array $msgs): void
|
||||
{
|
||||
$lang = new dcTranslaterLang($this, $lang);
|
||||
$lang = new TranslaterLang($this, $lang);
|
||||
|
||||
$content = '';
|
||||
if ($this->translater->parse_comment) {
|
||||
$content .= '# Language: ' . $lang->name . "\n" .
|
||||
'# Module: ' . $this->id . ' - ' . $this->version . "\n" .
|
||||
if ($this->translater->get('parse_comment')) {
|
||||
$content .= '# Language: ' . $lang->get('name') . "\n" .
|
||||
'# Module: ' . $this->get('id') . ' - ' . $this->get('version') . "\n" .
|
||||
'# Date: ' . dt::str('%Y-%m-%d %H:%M:%S') . "\n";
|
||||
|
||||
if ($this->translater->parse_user && $this->translater->parse_userinfo != '') {
|
||||
$search = dcTranslater::$allowed_user_informations;
|
||||
if ($this->translater->get('parse_user') && $this->translater->get('parse_userinfo') != '') {
|
||||
$search = My::defaultUserInformations();
|
||||
$replace = [];
|
||||
foreach ($search as $n) {
|
||||
$replace[] = dcCore::app()->auth->getInfo('user_' . $n);
|
||||
}
|
||||
$info = trim(str_replace($search, $replace, $this->translater->parse_userinfo));
|
||||
$info = trim(str_replace($search, $replace, $this->translater->get('parse_userinfo')));
|
||||
if (!empty($info)) {
|
||||
$content .= '# Author: ' . html::escapeHTML($info) . "\n";
|
||||
}
|
||||
}
|
||||
$content .= '# Translated with translater ' . dcCore::app()->plugins->moduleInfo(basename(dirname(__DIR__)), 'version') . "\n\n";
|
||||
$content .= '# Translated with translater ' . dcCore::app()->plugins->moduleInfo(My::id(), 'version') . "\n\n";
|
||||
}
|
||||
$content .= "msgid \"\"\n" .
|
||||
"msgstr \"\"\n" .
|
||||
'"Content-Type: text/plain; charset=UTF-8\n"' . "\n" .
|
||||
'"Project-Id-Version: ' . $this->id . ' ' . $this->version . '\n"' . "\n" .
|
||||
'"Project-Id-Version: ' . $this->get('id') . ' ' . $this->get('version') . '\n"' . "\n" .
|
||||
'"POT-Creation-Date: \n"' . "\n" .
|
||||
'"PO-Revision-Date: ' . date('c') . '\n"' . "\n" .
|
||||
'"Last-Translator: ' . dcCore::app()->auth->getInfo('user_cn') . '\n"' . "\n" .
|
||||
@ -691,7 +703,7 @@ class dcTranslaterModule
|
||||
'"Plural-Forms: nplurals=2; plural=(n > 1);\n"' . "\n\n";
|
||||
|
||||
$comments = [];
|
||||
if ($this->translater->parse_comment) {
|
||||
if ($this->translater->get('parse_comment')) {
|
||||
$msgids = $lang->getMsgids();
|
||||
foreach ($msgids as $msg) {
|
||||
$comments[$msg['msgid']] = ($comments[$msg['msgid']] ?? '') .
|
||||
@ -703,22 +715,22 @@ class dcTranslaterModule
|
||||
if (empty($msg['msgstr'][0])) {
|
||||
continue;
|
||||
}
|
||||
if ($this->translater->parse_comment && isset($comments[$msg['msgid']])) {
|
||||
if ($this->translater->get('parse_comment') && isset($comments[$msg['msgid']])) {
|
||||
$content .= $comments[$msg['msgid']];
|
||||
}
|
||||
$content .= 'msgid "' . dcTranslater::poString($msg['msgid'], true) . '"' . "\n";
|
||||
$content .= 'msgid "' . Translater::poString($msg['msgid'], true) . '"' . "\n";
|
||||
if (empty($msg['msgid_plural'])) {
|
||||
$content .= 'msgstr "' . dcTranslater::poString($msg['msgstr'][0], true) . '"' . "\n";
|
||||
$content .= 'msgstr "' . Translater::poString($msg['msgstr'][0], true) . '"' . "\n";
|
||||
} else {
|
||||
$content .= 'msgid_plural "' . dcTranslater::poString($msg['msgid_plural'], true) . '"' . "\n";
|
||||
$content .= 'msgid_plural "' . Translater::poString($msg['msgid_plural'], true) . '"' . "\n";
|
||||
foreach ($msg['msgstr'] as $i => $plural) {
|
||||
$content .= 'msgstr[' . $i . '] "' . dcTranslater::poString(($msg['msgstr'][$i] ?: ''), true) . '"' . "\n";
|
||||
$content .= 'msgstr[' . $i . '] "' . Translater::poString(($msg['msgstr'][$i] ?: ''), true) . '"' . "\n";
|
||||
}
|
||||
}
|
||||
$content .= "\n";
|
||||
}
|
||||
|
||||
$file = $this->locales . '/' . $lang->code . '/' . $group . '.po';
|
||||
$file = $this->get('locales') . '/' . $lang->get('code') . '/' . $group . '.po';
|
||||
$path = path::info($file);
|
||||
if (is_dir($path['dirname']) && !is_writable($path['dirname'])
|
||||
|| file_exists($file) && !is_writable($file)) {
|
||||
@ -743,34 +755,35 @@ class dcTranslaterModule
|
||||
* @param string $group The lang group
|
||||
* @param array $msgs The strings
|
||||
*/
|
||||
private function setLangphpContent(string $lang, string $group, array $msgs)
|
||||
private function setLangphpContent(string $lang, string $group, array $msgs): void
|
||||
{
|
||||
if (!$this->translater->write_langphp) {
|
||||
return null;
|
||||
if (!$this->translater->get('write_langphp')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$lang = new dcTranslaterLang($this, $lang);
|
||||
$lang = new TranslaterLang($this, $lang);
|
||||
|
||||
$content = '';
|
||||
if ($this->translater->parse_comment) {
|
||||
$content .= '// Language: ' . $lang->name . "\n" .
|
||||
'// Module: ' . $this->id . ' - ' . $this->verison . "\n" .
|
||||
if ($this->translater->get('parse_comment')) {
|
||||
$content .= '// Language: ' . $lang->get('name') . "\n" .
|
||||
'// Module: ' . $this->get('id') . ' - ' . $this->get('verison') . "\n" .
|
||||
'// Date: ' . dt::str('%Y-%m-%d %H:%M:%S') . "\n";
|
||||
|
||||
if ($this->translater->parse_user && !empty($this->translater->parse_userinfo)) {
|
||||
$search = dcTranslater::$allowed_user_informations;
|
||||
if ($this->translater->get('parse_user') && !empty($this->translater->get('parse_userinfo'))) {
|
||||
$search = My::defaultUserInformations();
|
||||
$replace = [];
|
||||
foreach ($search as $n) {
|
||||
$replace[] = dcCore::app()->auth->getInfo('user_' . $n);
|
||||
}
|
||||
$info = trim(str_replace($search, $replace, $this->translater->parse_userinfo));
|
||||
$info = trim(str_replace($search, $replace, $this->translater->get('parse_userinfo')));
|
||||
if (!empty($info)) {
|
||||
$content .= '// Author: ' . html::escapeHTML($info) . "\n";
|
||||
}
|
||||
}
|
||||
$content .= '// Translated with dcTranslater - ' . dcCore::app()->plugins->moduleInfo(basename(dirname(__DIR__)), 'version') . "\n\n";
|
||||
$content .= '// Translated with Translater - ' . dcCore::app()->plugins->moduleInfo(My::id(), 'version') . "\n\n";
|
||||
}
|
||||
|
||||
l10n::generatePhpFileFromPo($this->locales . '/' . $lang->code . '/' . $group, $content);
|
||||
l10n::generatePhpFileFromPo($this->get('locales') . '/' . $lang->get('code') . '/' . $group, $content);
|
||||
}
|
||||
//@}
|
||||
}
|
||||
|
@ -10,6 +10,13 @@
|
||||
* @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 dcCore;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Translater proposal tools container.
|
||||
*/
|
||||
|
@ -10,72 +10,93 @@
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\translater;
|
||||
|
||||
class Uninstall
|
||||
{
|
||||
protected static $init = false;
|
||||
|
||||
public static function init(): bool
|
||||
{
|
||||
self::$init = defined('DC_RC_PATH');
|
||||
|
||||
return self::$init;
|
||||
}
|
||||
|
||||
$this->addUserAction(
|
||||
public static function process($uninstaller): ?bool
|
||||
{
|
||||
if (!self::$init) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$uninstaller->addUserAction(
|
||||
/* type */
|
||||
'settings',
|
||||
/* action */
|
||||
'delete_all',
|
||||
/* ns */
|
||||
basename(__DIR__),
|
||||
My::id(),
|
||||
/* description */
|
||||
__('delete all settings')
|
||||
);
|
||||
|
||||
$this->addUserAction(
|
||||
$uninstaller->addUserAction(
|
||||
/* type */
|
||||
'plugins',
|
||||
/* action */
|
||||
'delete',
|
||||
/* ns */
|
||||
basename(__DIR__),
|
||||
My::id(),
|
||||
/* description */
|
||||
__('delete plugin files')
|
||||
);
|
||||
|
||||
$this->addUserAction(
|
||||
$uninstaller->addUserAction(
|
||||
/* type */
|
||||
'versions',
|
||||
/* action */
|
||||
'delete',
|
||||
/* ns */
|
||||
basename(__DIR__),
|
||||
My::id(),
|
||||
/* description */
|
||||
__('delete the version number')
|
||||
);
|
||||
|
||||
$this->addDirectAction(
|
||||
$uninstaller->addDirectAction(
|
||||
/* type */
|
||||
'settings',
|
||||
/* action */
|
||||
'delete_all',
|
||||
/* ns */
|
||||
basename(__DIR__),
|
||||
My::id(),
|
||||
/* description */
|
||||
sprintf(__('delete all %s settings'), basename(__DIR__))
|
||||
sprintf(__('delete all %s settings'), My::id())
|
||||
);
|
||||
|
||||
$this->addDirectAction(
|
||||
$uninstaller->addDirectAction(
|
||||
/* type */
|
||||
'plugins',
|
||||
/* action */
|
||||
'delete',
|
||||
/* ns */
|
||||
basename(__DIR__),
|
||||
My::id(),
|
||||
/* description */
|
||||
sprintf(__('delete %s plugin files'), basename(__DIR__))
|
||||
sprintf(__('delete %s plugin files'), My::id())
|
||||
);
|
||||
|
||||
$this->addDirectAction(
|
||||
$uninstaller->addDirectAction(
|
||||
/* type */
|
||||
'versions',
|
||||
/* action */
|
||||
'delete',
|
||||
/* ns */
|
||||
basename(__DIR__),
|
||||
My::id(),
|
||||
/* description */
|
||||
sprintf(__('delete %s version number'), basename(__DIR__))
|
||||
sprintf(__('delete %s version number'), My::id())
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user