diff --git a/release.txt b/CHANGELOG.md similarity index 80% rename from release.txt rename to CHANGELOG.md index 590d033..20cba0d 100644 --- a/release.txt +++ b/CHANGELOG.md @@ -1,6 +1,29 @@ x.x xxxxxxxx - help translation - source translation + - settings page + +2021.08.19 + * Fixed PSR-2 Coding Style + +2018.10.26 - Pierre Van Glabeke + * Bug avec php 7.2 (https://forum.dotclear.org/viewtopic.php?pid=342810#p342810) + +2018.10.18 - Pierre Van Glabeke + * Modifs localisation + +2018.02.14 - Pierre Van Glabeke + * Suppression ?> en fin de lang.php + +2017.05.10 - Pierre Van Glabeke + * Suppression ligne 614 de "continue" dans \inc\class.dc.translater.php + +2016.08.20 - Pierre Van Glabeke + * Ajout Pluriel dans po + * Ajout favori + +2016.07.08 - Pierre Van Glabeke + * Modifs localisation 2013.05.11 * Rewrited proposal tools diff --git a/_admin.php b/_admin.php index db7739c..667c857 100644 --- a/_admin.php +++ b/_admin.php @@ -3,8 +3,7 @@ # # This file is part of translater, a plugin for Dotclear 2. # -# Copyright (c) 2009-2013 Jean-Christian Denis and contributors -# contact@jcdenis.fr +# Copyright (c) 2009-2016 Jean-Christian Denis and contributors # # Licensed under the GPL version 2.0 license. # A copy of this license is available in LICENSE file or at @@ -12,96 +11,109 @@ # # -- END LICENSE BLOCK ------------------------------------ -if (!defined('DC_CONTEXT_ADMIN')){return;} +if (!defined('DC_CONTEXT_ADMIN')) { + return; +} $core->blog->settings->addNamespace('translater'); -$core->addBehavior('pluginsToolsTabs',array('translaterAdminBehaviors','pluginsToolsTabs')); -$core->addBehavior('adminCurrentThemeDetails',array('translaterAdminBehaviors','adminCurrentThemeDetails')); -$core->addBehavior('addTranslaterProposalTool',array('translaterAdminBehaviors','addGoogleProposalTool')); -$core->addBehavior('addTranslaterProposalTool',array('translaterAdminBehaviors','addYahooProposalTool')); -$core->addBehavior('addTranslaterProposalTool',array('translaterAdminBehaviors','addMicrosoftProposalTool')); -$core->rest->addFunction('getProposal',array('translaterRest','getProposal')); +$core->addBehavior('pluginsToolsTabs', ['translaterAdminBehaviors', 'pluginsToolsTabs']); +$core->addBehavior('adminCurrentThemeDetails', ['translaterAdminBehaviors', 'adminCurrentThemeDetails']); +$core->addBehavior('addTranslaterProposalTool', ['translaterAdminBehaviors', 'addGoogleProposalTool']); +$core->addBehavior('addTranslaterProposalTool', ['translaterAdminBehaviors', 'addYahooProposalTool']); +$core->addBehavior('addTranslaterProposalTool', ['translaterAdminBehaviors', 'addMicrosoftProposalTool']); +$core->rest->addFunction('getProposal', ['translaterRest', 'getProposal']); $_menu['Plugins']->addItem( - __('Translater'), - 'plugin.php?p=translater', - 'index.php?pf=translater/icon.png', - preg_match('/plugin.php\?p=translater(&.*)?$/',$_SERVER['REQUEST_URI']), - $core->auth->isSuperAdmin() + __('Translater'), + 'plugin.php?p=translater', + 'index.php?pf=translater/icon.png', + preg_match('/plugin.php\?p=translater(&.*)?$/', $_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin() ); class translaterAdminBehaviors { - # Plugins tab - public static function pluginsToolsTabs($core) - { - if (!$core->blog->settings->translater->translater_plugin_menu || !$core->auth->isSuperAdmin()) { - return; - } - - echo - '
'. - ' | '.__('Name').' | '. - ''.__('Version').' | '. - ''.__('Details').' | '. - ''.__('Author').' | '. - '
---|---|---|---|---|
'. - ''.__($plugin['name']).' | '. - ''.$name.' | '. - ''.$plugin['version'].' | '. - ''.$plugin['desc'].' | '. - ''.$plugin['author'].' | '. - '
'.__('Translate this theme').'
'; - } - } - - # Google Translater tools - public static function addGoogleProposalTool($proposal) - { - $proposal->addTool('googleProposalTool'); - } - - # Yahoo Babelfish tools - public static function addYahooProposalTool($proposal) - { - $proposal->addTool('yahooProposalTool'); - } - - # Microsoft Bing tools - public static function addMicrosoftProposalTool($proposal) - { - $proposal->addTool('microsoftProposalTool'); - } + # Plugins tab + public static function pluginsToolsTabs($core) + { + if (!$core->blog->settings->translater->translater_plugin_menu || !$core->auth->isSuperAdmin()) { + return; + } + + echo + '' . + ' | ' . __('Name') . ' | ' . + '' . __('Version') . ' | ' . + '' . __('Details') . ' | ' . + '' . __('Author') . ' | ' . + '
---|---|---|---|---|
' . + '' . __($plugin['name']) . ' | ' . + '' . $name . ' | ' . + '' . $plugin['version'] . ' | ' . + '' . $plugin['desc'] . ' | ' . + '' . $plugin['author'] . ' | ' . + '
' . __('Translate this theme') . '
'; + } + } + + # Google Translater tools + public static function addGoogleProposalTool($proposal) + { + $proposal->addTool('googleProposalTool'); + } + + # Yahoo Babelfish tools + public static function addYahooProposalTool($proposal) + { + $proposal->addTool('yahooProposalTool'); + } + + # Microsoft Bing tools + public static function addMicrosoftProposalTool($proposal) + { + $proposal->addTool('microsoftProposalTool'); + } } -?> \ No newline at end of file + +$core->addBehavior('adminDashboardFavorites', 'translaterDashboardFavorites'); + +function translaterDashboardFavorites($core, $favs) +{ + $favs->register('translater', [ + 'title' => __('Translater'), + 'url' => 'plugin.php?p=translater', + 'small-icon' => 'index.php?pf=translater/icon.png', + 'large-icon' => 'index.php?pf=translater/icon-big.png', + 'permissions' => 'usage,contentadmin' + ]); +} \ No newline at end of file diff --git a/_define.php b/_define.php index 6a23ca1..8bac4fb 100644 --- a/_define.php +++ b/_define.php @@ -3,8 +3,7 @@ # # This file is part of translater, a plugin for Dotclear 2. # -# Copyright (c) 2009-2013 Jean-Christian Denis and contributors -# contact@jcdenis.fr +# Copyright (c) 2009-2021 Jean-Christian Denis and contributors # # Licensed under the GPL version 2.0 license. # A copy of this license is available in LICENSE file or at @@ -12,13 +11,20 @@ # # -- END LICENSE BLOCK ------------------------------------ -if (!defined('DC_RC_PATH')){return;} +if (!defined('DC_RC_PATH')) { + return; +} $this->registerModule( - /* Name */ "translater", - /* Description*/ "Translate your Dotclear plugins and themes", - /* Author */ "JC Denis", - /* Version */ '2013.05.11', - /* Permissions */ null -); -?> \ No newline at end of file + 'translater', + 'Translate your Dotclear plugins and themes', + 'Jean-Christian Denis & contributors', + '2021.08.15', + [ + 'permissions' => 'usage,contentadmin,admin', + 'type' => 'plugin', + 'dc_min' => '2.19', + 'support' => 'http://forum.dotclear.org/viewtopic.php?id=39220', + 'details' => 'https://plugins.dotaddict.org/dc2/details/translater' + ] +); \ No newline at end of file diff --git a/_install.php b/_install.php index 35cac0d..a95aba7 100644 --- a/_install.php +++ b/_install.php @@ -3,8 +3,7 @@ # # This file is part of translater, a plugin for Dotclear 2. # -# Copyright (c) 2009-2013 Jean-Christian Denis and contributors -# contact@jcdenis.fr +# Copyright (c) 2009-2016 Jean-Christian Denis and contributors # # Licensed under the GPL version 2.0 license. # A copy of this license is available in LICENSE file or at @@ -12,48 +11,48 @@ # # -- END LICENSE BLOCK ------------------------------------ -if (!defined('DC_CONTEXT_ADMIN')){return;} +if (!defined('DC_CONTEXT_ADMIN')) { + return; +} $rdc_version = '2.5-alpha'; -$new_version = $core->plugins->moduleInfo('translater','version'); +$new_version = $core->plugins->moduleInfo('translater', 'version'); $old_version = $core->getVersion('translater'); -if (version_compare($old_version,$new_version,'>=')) return; +if (version_compare($old_version, $new_version, '>=')) { + return; +} -try -{ - if (version_compare(str_replace("-r","-p",DC_VERSION),$rdc_version,'<')) { - throw new Exception(sprintf('%s requires Dotclear %s','translater',$rdc_version)); - } - - $core->blog->settings->addNamespace('translater'); - - $core->blog->settings->translater->put('translater_plugin_menu',0,'boolean','Put a link in plugins page',false,true); - $core->blog->settings->translater->put('translater_theme_menu',0,'boolean','Put a link in themes page',false,true); - $core->blog->settings->translater->put('translater_backup_auto',1,'boolean','Make a backup of languages old files when there are modified',false,true); - $core->blog->settings->translater->put('translater_backup_limit',20,'string','Maximum backups per module',false,true); - $core->blog->settings->translater->put('translater_backup_folder','module','string','In which folder to store backups',false,true); - $core->blog->settings->translater->put('translater_start_page','setting,','string','Page to start on',false,true); - $core->blog->settings->translater->put('translater_write_po',1,'boolean','Write .po languages files',false,true); - $core->blog->settings->translater->put('translater_write_langphp',1,'boolean','Write .lang.php languages files',false,true); - $core->blog->settings->translater->put('translater_scan_tpl',0,'boolean','Translate strings of templates files',false,true); - $core->blog->settings->translater->put('translater_parse_nodc',1,'boolean','Translate only untranslated strings of Dotclear',false,true); - $core->blog->settings->translater->put('translater_hide_default',1,'boolean','Hide default modules of Dotclear',false,true); - $core->blog->settings->translater->put('translater_parse_comment',1,'boolean','Write comments and strings informations in lang files',false,true); - $core->blog->settings->translater->put('translater_parse_user',1,'boolean','Write inforamtions about author in lang files',false,true); - $core->blog->settings->translater->put('translater_parse_userinfo','displayname, email','string','Type of informations about user to write',false,true); - $core->blog->settings->translater->put('translater_import_overwrite',0,'boolean','Overwrite existing languages when import packages',false,true); - $core->blog->settings->translater->put('translater_export_filename','type-module-l10n-timestamp','string','Name of files of exported package',false,true); - $core->blog->settings->translater->put('translater_proposal_tool','google','string','Id of default tool for proposed translation',false,true); - $core->blog->settings->translater->put('translater_proposal_lang','en','string','Default source language for proposed translation',false,true); - - $core->setVersion('translater',$new_version); - - return true; +try { + if (version_compare(str_replace("-r", "-p", DC_VERSION), $rdc_version, '<')) { + throw new Exception(sprintf('%s requires Dotclear %s', 'translater', $rdc_version)); + } + + $core->blog->settings->addNamespace('translater'); + + $core->blog->settings->translater->put('translater_plugin_menu', 0, 'boolean', 'Put a link in plugins page', false, true); + $core->blog->settings->translater->put('translater_theme_menu', 0,'boolean', 'Put a link in themes page', false, true); + $core->blog->settings->translater->put('translater_backup_auto', 1,'boolean', 'Make a backup of languages old files when there are modified', false, true); + $core->blog->settings->translater->put('translater_backup_limit', 20,'string', 'Maximum backups per module', false, true); + $core->blog->settings->translater->put('translater_backup_folder', 'module',' string', 'In which folder to store backups', false, true); + $core->blog->settings->translater->put('translater_start_page', 'setting,', 'string', 'Page to start on', false, true); + $core->blog->settings->translater->put('translater_write_po', 1, 'boolean', 'Write .po languages files', false, true); + $core->blog->settings->translater->put('translater_write_langphp', 1, 'boolean', 'Write .lang.php languages files', false, true); + $core->blog->settings->translater->put('translater_scan_tpl', 0, 'boolean', 'Translate strings of templates files', false, true); + $core->blog->settings->translater->put('translater_parse_nodc', 1, 'boolean', 'Translate only untranslated strings of Dotclear', false, true); + $core->blog->settings->translater->put('translater_hide_default', 1, 'boolean', 'Hide default modules of Dotclear', false, true); + $core->blog->settings->translater->put('translater_parse_comment', 1, 'boolean', 'Write comments and strings informations in lang files', false, true); + $core->blog->settings->translater->put('translater_parse_user', 1,'boolean', 'Write inforamtions about author in lang files', false, true); + $core->blog->settings->translater->put('translater_parse_userinfo', 'displayname, email', 'string','Type of informations about user to write', false, true); + $core->blog->settings->translater->put('translater_import_overwrite', 0, 'boolean', 'Overwrite existing languages when import packages', false, true); + $core->blog->settings->translater->put('translater_export_filename', 'type-module-l10n-timestamp', 'string','Name of files of exported package', false, true); + $core->blog->settings->translater->put('translater_proposal_tool', 'google', 'string', 'Id of default tool for proposed translation', false, true); + $core->blog->settings->translater->put('translater_proposal_lang', 'en', 'string', 'Default source language for proposed translation', false, true); + + $core->setVersion('translater', $new_version); + + return true; +} catch (Exception $e) { + $core->error->add($e->getMessage()); } -catch (Exception $e) -{ - $core->error->add($e->getMessage()); -} -return false; -?> \ No newline at end of file +return false; \ No newline at end of file diff --git a/_prepend.php b/_prepend.php index 6e177f1..62d19ef 100644 --- a/_prepend.php +++ b/_prepend.php @@ -3,8 +3,7 @@ # # This file is part of translater, a plugin for Dotclear 2. # -# Copyright (c) 2009-2013 Jean-Christian Denis and contributors -# contact@jcdenis.fr +# Copyright (c) 2009-2016 Jean-Christian Denis and contributors # # Licensed under the GPL version 2.0 license. # A copy of this license is available in LICENSE file or at @@ -12,15 +11,16 @@ # # -- END LICENSE BLOCK ------------------------------------ -if (!defined('DC_RC_PATH')){return;} +if (!defined('DC_RC_PATH')) { + return; +} global $__autoload; -$__autoload['dcTranslater'] = dirname(__FILE__).'/inc/class.dc.translater.php'; -$__autoload['translaterRest'] = dirname(__FILE__).'/inc/class.translater.rest.php'; -$__autoload['translaterProposals'] = dirname(__FILE__).'/inc/class.translater.proposals.php'; +$__autoload['dcTranslater'] = dirname(__FILE__) . '/inc/class.dc.translater.php'; +$__autoload['translaterRest'] = dirname(__FILE__) . '/inc/class.translater.rest.php'; +$__autoload['translaterProposals'] = dirname(__FILE__) . '/inc/class.translater.proposals.php'; -$__autoload['translaterProposalTool'] = dirname(__FILE__).'/inc/lib.translater.proposal.php'; -$__autoload['googleProposalTool'] = dirname(__FILE__).'/inc/lib.translater.google.php'; -$__autoload['microsoftProposalTool'] = dirname(__FILE__).'/inc/lib.translater.microsoft.php'; -?> \ No newline at end of file +$__autoload['translaterProposalTool'] = dirname(__FILE__) . '/inc/lib.translater.proposal.php'; +$__autoload['googleProposalTool'] = dirname(__FILE__) . '/inc/lib.translater.google.php'; +$__autoload['microsoftProposalTool'] = dirname(__FILE__) . '/inc/lib.translater.microsoft.php'; \ No newline at end of file diff --git a/_uninstall.php b/_uninstall.php index 0e83c16..15650a4 100644 --- a/_uninstall.php +++ b/_uninstall.php @@ -3,8 +3,7 @@ # # This file is part of translater, a plugin for Dotclear 2. # -# Copyright (c) 2009-2013 Jean-Christian Denis and contributors -# contact@jcdenis.fr +# Copyright (c) 2009-2016 Jean-Christian Denis and contributors # # Licensed under the GPL version 2.0 license. # A copy of this license is available in LICENSE file or at @@ -12,48 +11,49 @@ # # -- END LICENSE BLOCK ------------------------------------ -if (!defined('DC_CONTEXT_ADMIN')){return;} +if (!defined('DC_CONTEXT_ADMIN')) { + return; +} $this->addUserAction( - /* type */ 'settings', - /* action */ 'delete_all', - /* ns */ 'translater', - /* description */ __('delete all settings') + /* type */ 'settings', + /* action */ 'delete_all', + /* ns */ 'translater', + /* description */ __('delete all settings') ); $this->addUserAction( - /* type */ 'plugins', - /* action */ 'delete', - /* ns */ 'translater', - /* description */ __('delete plugin files') + /* type */ 'plugins', + /* action */ 'delete', + /* ns */ 'translater', + /* description */ __('delete plugin files') ); $this->addUserAction( - /* type */ 'versions', - /* action */ 'delete', - /* ns */ 'translater', - /* description */ __('delete the version number') + /* type */ 'versions', + /* action */ 'delete', + /* ns */ 'translater', + /* description */ __('delete the version number') ); $this->addDirectAction( - /* type */ 'settings', - /* action */ 'delete_all', - /* ns */ 'translater', - /* description */ sprintf(__('delete all %s settings'),'translater') + /* type */ 'settings', + /* action */ 'delete_all', + /* ns */ 'translater', + /* description */ sprintf(__('delete all %s settings'), 'translater') ); $this->addDirectAction( - /* type */ 'plugins', - /* action */ 'delete', - /* ns */ 'translater', - /* description */ sprintf(__('delete %s plugin files'),'translater') + /* type */ 'plugins', + /* action */ 'delete', + /* ns */ 'translater', + /* description */ sprintf(__('delete %s plugin files'), 'translater') ); $this->addDirectAction( - /* type */ 'versions', - /* action */ 'delete', - /* ns */ 'translater', - /* description */ sprintf(__('delete %s version number'),'translater') -); -?> \ No newline at end of file + /* type */ 'versions', + /* action */ 'delete', + /* ns */ 'translater', + /* description */ sprintf(__('delete %s version number'), 'translater') +); \ No newline at end of file diff --git a/icon-big.png b/icon-big.png new file mode 100644 index 0000000..ad8442e Binary files /dev/null and b/icon-big.png differ diff --git a/icon.png b/icon.png index 877f82f..4dcb2e0 100644 Binary files a/icon.png and b/icon.png differ diff --git a/inc/class.dc.translater.php b/inc/class.dc.translater.php index 54fe45b..0e922a5 100644 --- a/inc/class.dc.translater.php +++ b/inc/class.dc.translater.php @@ -3,8 +3,7 @@ # # This file is part of translater, a plugin for Dotclear 2. # -# Copyright (c) 2009-2013 Jean-Christian Denis and contributors -# contact@jcdenis.fr +# Copyright (c) 2009-2016 Jean-Christian Denis and contributors # # Licensed under the GPL version 2.0 license. # A copy of this license is available in LICENSE file or at @@ -12,1574 +11,1516 @@ # # -- END LICENSE BLOCK ------------------------------------ -if (!defined('DC_CONTEXT_ADMIN')){return;} +if (!defined('DC_CONTEXT_ADMIN')) { + return; +} /** * Translater tools. */ class dcTranslater { - public $core; - public $proposal; - - # List of l10n code/name allowed from clearbricks l10n class - protected static $iso = array(); - # List of type of folder where backups could be saved - public static $allowed_backup_folders = array( - 'public', - 'module', - 'plugin', - 'cache', - 'translater' - ); - # List of l10n groups (subname) of file allowed - public static $allowed_l10n_groups = array( - 'main', - 'public', - 'theme', - 'admin', - 'date', - 'error' - ); - # List of informations about author allowed - public static $allowed_user_informations = array( - 'firstname', - 'displayname', - 'name', - 'email', - 'url' - ); - # List of settings and infos - private $default_settings = array( - 'plugin_menu' => array( - 'id' => 'translater_plugin_menu', - 'value' => 0, - 'type' => 'boolean', - 'label' => 'Put an link in plugins page' - ), - 'theme_menu' => array( - 'id' => 'translater_theme_menu', - 'value' => 0, - 'type' => 'boolean', - 'label' => 'Put a link in themes page' - ), - 'backup_auto' => array( - 'id' => 'translater_backup_auto', - 'value' => 1, - 'type' => 'boolean', - 'label' => 'Make a backup of languages old files when there are modified' - ), - 'backup_limit' => array( - 'id' => 'translater_backup_limit', - 'value' => 20, - 'type' => 'string', - 'label' => 'Maximum backups per module' - ), - 'backup_folder' => array( - 'id' => 'translater_backup_folder', - 'value' => 'module', - 'type' => 'string', - 'label' => 'In which folder to store backups' - ), - 'start_page' => array( - 'id' => 'translater_start_page', - 'value' => 'setting', - 'type' => 'string', - 'label' => 'Page to start on' - ), - 'write_po' => array( - 'id' => 'translater_write_po', - 'value' => 1, - 'type' => 'boolean', - 'label' => 'Write .po languages files' - ), - 'write_langphp' => array( - 'id' => 'translater_write_langphp', - 'value' => 1, - 'type' => 'boolean', - 'label' => 'Write .lang.php languages files' - ), - 'scan_tpl' => array( - 'id' => 'translater_scan_tpl', - 'value' => 0, - 'type' => 'boolean', - 'label' => 'Translate strings of templates files' - ), - 'parse_nodc' => array( - 'id' => 'translater_parse_nodc', - 'value' => 1, - 'type' => 'boolean', - 'label' => 'Translate only untranslated strings of Dotclear', - ), - 'hide_default' => array( - 'id' => 'translater_hide_default', - 'value' => 1, - 'type' => 'boolean', - 'label' => 'Hide default modules of Dotclear', - ), - 'parse_comment' => array( - 'id' => 'translater_parse_comment', - 'value' => 1, - 'type' => 'boolean', - 'label' => 'Write comments and strings informations in lang files' - ), - 'parse_user' => array( - 'id' => 'translater_parse_user', - 'value' => 1, - 'type' => 'boolean', - 'label' => 'Write inforamtions about author in lang files' - ), - 'parse_userinfo' => array( - 'id' => 'translater_parse_userinfo', - 'value' => 'displayname, email', - 'type' => 'string', - 'label' => 'Type of informations about user to write' - ), - 'import_overwrite' => array( - 'id' => 'translater_import_overwrite', - 'value' => 0, - 'type' => 'boolean', - 'label' => 'Overwrite existing languages when import packages' - ), - 'export_filename' => array( - 'id' => 'translater_export_filename', - 'value' => 'type-module-l10n-timestamp', - 'type' => 'string', - 'label' => 'Name of files of exported package' - ), - 'proposal_tool' => array( - 'id' => 'translater_proposal_tool', - 'value' => 'google', - 'type' => 'string', - 'label' => 'Id of default tool for proposed translation' - ), - 'proposal_lang' => array( - 'id' => 'translater_proposal_lang', - 'value' => 'en', - 'type' => 'string', - 'label' => 'Default source language for proposed translation' - ) - ); - # List of default modules of Dotclear - public static $default_dotclear_modules = array( - 'plugin' => array( - 'aboutConfig', - 'akismet', - 'antispam', - 'blogroll', - 'blowupConfig', - 'daInstaller', - 'externalMedia', - 'fairTrackbacks', - 'importExport', - 'maintenance', - 'pages', - 'pings', - 'simpleMenu', - 'tags', - 'themeEditor', - 'userPref', - 'widgets' - ), - 'theme' => array( - 'default', - 'blueSilence', - 'customCSS', - 'ductile' - ) - ); - - # List of modules (from plugins,thems, by dcModule::getModules) - private $modules = array(); - # Particular module - private $module = array(); - - # Construtor - function __construct($core) - { - $this->core =& $core; - $core->blog->settings->addNamespace('translater'); - $this->loadModules(); - $this->proposal = new translaterProposals($core); - } - - # Return array of default settings - public function getDefaultSettings() - { - return $this->default_settings; - } - - # Get settings for current blog - public function getSettings($id=null) - { - $res = array(); - foreach($this->default_settings AS $k => $v) - { - if ($k == $id) - { - return $this->core->blog->settings->translater->get( - $this->default_settings[$k]['id'] - ); - } - $res[$k] = $this->core->blog->settings->translater->get( - $this->default_settings[$k]['id'] - ); - } - return $res; - } - - # Get a setting according to default settings list - public function get($id) - { - if (isset($this->default_settings[$id])) - { - return $this->core->blog->settings->translater->get( - $this->default_settings[$id]['id'] - ); - } - return null; - } - - # See get() - public function __get($id) - { - return $this->get($id); - } - - # Set a setting according to default settings list - public function set($k,$v) - { - if (!isset($this->default_settings[$k])) return false; + public $core; + public $proposal; + + # List of l10n code/name allowed from clearbricks l10n class + protected static $iso = array(); + # List of type of folder where backups could be saved + public static $allowed_backup_folders = array( + 'public', + 'module', + 'plugin', + 'cache', + 'translater' + ); + # List of l10n groups (subname) of file allowed + public static $allowed_l10n_groups = array( + 'main', + 'public', + 'theme', + 'admin', + 'date', + 'error' + ); + # List of informations about author allowed + public static $allowed_user_informations = array( + 'firstname', + 'displayname', + 'name', + 'email', + 'url' + ); + # List of settings and infos + private $default_settings = array( + 'plugin_menu' => array( + 'id' => 'translater_plugin_menu', + 'value' => 0, + 'type' => 'boolean', + 'label' => 'Put an link in plugins page' + ), + 'theme_menu' => array( + 'id' => 'translater_theme_menu', + 'value' => 0, + 'type' => 'boolean', + 'label' => 'Put a link in themes page' + ), + 'backup_auto' => array( + 'id' => 'translater_backup_auto', + 'value' => 1, + 'type' => 'boolean', + 'label' => 'Make a backup of languages old files when there are modified' + ), + 'backup_limit' => array( + 'id' => 'translater_backup_limit', + 'value' => 20, + 'type' => 'string', + 'label' => 'Maximum backups per module' + ), + 'backup_folder' => array( + 'id' => 'translater_backup_folder', + 'value' => 'module', + 'type' => 'string', + 'label' => 'In which folder to store backups' + ), + 'start_page' => array( + 'id' => 'translater_start_page', + 'value' => 'setting', + 'type' => 'string', + 'label' => 'Page to start on' + ), + 'write_po' => array( + 'id' => 'translater_write_po', + 'value' => 1, + 'type' => 'boolean', + 'label' => 'Write .po languages files' + ), + 'write_langphp' => array( + 'id' => 'translater_write_langphp', + 'value' => 1, + 'type' => 'boolean', + 'label' => 'Write .lang.php languages files' + ), + 'scan_tpl' => array( + 'id' => 'translater_scan_tpl', + 'value' => 0, + 'type' => 'boolean', + 'label' => 'Translate strings of templates files' + ), + 'parse_nodc' => array( + 'id' => 'translater_parse_nodc', + 'value' => 1, + 'type' => 'boolean', + 'label' => 'Translate only untranslated strings of Dotclear', + ), + 'hide_default' => array( + 'id' => 'translater_hide_default', + 'value' => 1, + 'type' => 'boolean', + 'label' => 'Hide default modules of Dotclear', + ), + 'parse_comment' => array( + 'id' => 'translater_parse_comment', + 'value' => 1, + 'type' => 'boolean', + 'label' => 'Write comments and strings informations in lang files' + ), + 'parse_user' => array( + 'id' => 'translater_parse_user', + 'value' => 1, + 'type' => 'boolean', + 'label' => 'Write inforamtions about author in lang files' + ), + 'parse_userinfo' => array( + 'id' => 'translater_parse_userinfo', + 'value' => 'displayname, email', + 'type' => 'string', + 'label' => 'Type of informations about user to write' + ), + 'import_overwrite' => array( + 'id' => 'translater_import_overwrite', + 'value' => 0, + 'type' => 'boolean', + 'label' => 'Overwrite existing languages when import packages' + ), + 'export_filename' => array( + 'id' => 'translater_export_filename', + 'value' => 'type-module-l10n-timestamp', + 'type' => 'string', + 'label' => 'Name of files of exported package' + ), + 'proposal_tool' => array( + 'id' => 'translater_proposal_tool', + 'value' => 'google', + 'type' => 'string', + 'label' => 'Id of default tool for proposed translation' + ), + 'proposal_lang' => array( + 'id' => 'translater_proposal_lang', + 'value' => 'en', + 'type' => 'string', + 'label' => 'Default source language for proposed translation' + ) + ); + # List of default modules of Dotclear + public static $default_dotclear_modules = array( + 'plugin' => array( + 'aboutConfig', + 'akismet', + 'antispam', + 'attachments', + 'blogroll', + 'blowupConfig', + 'breadcrumb', + 'dcCKEditor', + 'dclegacy', + 'dcLegacyEditor', + 'fairTrackbacks', + 'importExport', + 'maintenance', + 'pages', + 'pings', + 'simpleMenu', + 'tags', + 'themeEditor', + 'userPref', + 'widgets' + ), + 'theme' => array( + 'default', + 'berlin', + 'blueSilence', + 'customCSS', + 'ductile' + ) + ); + + # List of modules (from plugins,thems, by dcModule::getModules) + private $modules = array(); + # Particular module + private $module = array(); + + # Construtor + function __construct($core) + { + $this->core =& $core; + $core->blog->settings->addNamespace('translater'); + $this->loadModules(); + $this->proposal = new translaterProposals($core); + } + + # Return array of default settings + public function getDefaultSettings() + { + return $this->default_settings; + } + + # Get settings for current blog + public function getSettings($id = null) + { + $res = array(); + foreach($this->default_settings AS $k => $v) { + if ($k == $id) { + return $this->core->blog->settings->translater->get( + $this->default_settings[$k]['id'] + ); + } + $res[$k] = $this->core->blog->settings->translater->get( + $this->default_settings[$k]['id'] + ); + } + return $res; + } + + # Get a setting according to default settings list + public function get($id) + { + if (isset($this->default_settings[$id])) + { + return $this->core->blog->settings->translater->get( + $this->default_settings[$id]['id'] + ); + } + return null; + } + + # See get() + public function __get($id) + { + return $this->get($id); + } + + # Set a setting according to default settings list + public function set($k, $v) + { + if (!isset($this->default_settings[$k])) { + return false; + } - $this->dropOldSettings($this->default_settings[$k]['id']); - $this->core->blog->settings->translater->put( - $this->default_settings[$k]['id'], - $v, - $this->default_settings[$k]['type'], - $this->default_settings[$k]['label'], - true,true - ); - return true; - } - - # See set() - public function __set($k,$v) - { - return $this->set($k,$v); - } - - # Drop old "per blog" settings (as of version 2013.05.11) - private function dropOldSettings($id) - { - $this->core->blog->settings->translater->drop($id); - } - - # Retrieve a particular info for a given module - public function moduleInfo($id,$info) - { - if (isset($this->modules['plugin'][$id])) - { - $type = 'plugin'; - } - elseif (isset($this->modules['theme'][$id])) - { - $type = 'theme'; - } - else - { - return null; - } - - if ($info == 'type') - { - return $type; - } - - return isset($this->modules[$type][$id][$info]) ? $this->modules[$type][$id][$info] : null; - } - - # Load array of modules infos by type of modules - private function loadModules() - { - $themes = new dcThemes($this->core); - $themes->loadModules($this->core->blog->themes_path,null); - $this->modules['theme'] = $this->modules['plugin'] = array(); - - $m = $themes->getModules(); - foreach($m AS $k => $v) - { - if (!$v['root_writable']) continue; - $this->modules['theme'][$k] = $v; - $this->modules['theme'][$k]['id'] = $k; - $this->modules['theme'][$k]['type'] = 'theme'; - } - - $m = $this->core->plugins->getModules(); - foreach($m AS $k => $v) - { - if (!$v['root_writable']) continue; - $this->modules['plugin'][$k] = $v; - $this->modules['plugin'][$k]['id'] = $k; - $this->modules['plugin'][$k]['type'] = 'plugin'; - } - } + $this->dropOldSettings($this->default_settings[$k]['id']); + $this->core->blog->settings->translater->put( + $this->default_settings[$k]['id'], + $v, + $this->default_settings[$k]['type'], + $this->default_settings[$k]['label'], + true,true + ); + return true; + } + + # See set() + public function __set($k, $v) + { + return $this->set($k, $v); + } + + # Drop old "per blog" settings (as of version 2013.05.11) + private function dropOldSettings($id) + { + $this->core->blog->settings->translater->drop($id); + } + + # Retrieve a particular info for a given module + public function moduleInfo($id, $info) + { + if (isset($this->modules['plugin'][$id])) { + $type = 'plugin'; + } elseif (isset($this->modules['theme'][$id])) { + $type = 'theme'; + } else { + return null; + } + + if ($info == 'type') { + return $type; + } + + return isset($this->modules[$type][$id][$info]) ? $this->modules[$type][$id][$info] : null; + } + + # Load array of modules infos by type of modules + private function loadModules() + { + $themes = new dcThemes($this->core); + $themes->loadModules($this->core->blog->themes_path, null); + $this->modules['theme'] = $this->modules['plugin'] = array(); + + $m = $themes->getModules(); + foreach($m AS $k => $v) { + if (!$v['root_writable']) { + continue; + } + $this->modules['theme'][$k] = $v; + $this->modules['theme'][$k]['id'] = $k; + $this->modules['theme'][$k]['type'] = 'theme'; + } + + $m = $this->core->plugins->getModules(); + foreach($m AS $k => $v) + { + if (!$v['root_writable']) { + continue; + } + $this->modules['plugin'][$k] = $v; + $this->modules['plugin'][$k]['id'] = $k; + $this->modules['plugin'][$k]['type'] = 'plugin'; + } + } - # Return array of modules infos by type of modules - public function listModules($type='') - { - return in_array($type,array('plugin','theme')) ? - $this->modules[$type] : - array_merge($this->modules['theme'],$this->modules['plugin']); - } - - # Return array object of a particular module for a given type of module - public function getModule($module='',$type='') - { - $o = new ArrayObject(); - - # Load nothing? - if (empty($module)) { - return false; - } - - # Unknow type? - if (!in_array($type,array('plugin','theme'))) { - $modules = array_merge($this->modules['theme'],$this->modules['plugin']); - } - else { - $modules = $this->modules[$type]; - } - - # Unknow module? - if (!isset($modules[$module])) { - throw new Exception(sprintf( - __('Cannot find module %s'),$module) - ); - return false; - } - - # Module info - foreach($modules[$module] as $a => $b) { - $o->{$a} = $b; - } - $o->root = path::real($o->root); - # Locales path - $o->locales = $o->root.'/locales'; - # Module exists - $o->exists = true; - # Module Basename - $i = path::info($o->root); - $o->basename = $i['basename']; - - return $o; - } - - public function getBackupFolder($module,$throw=false) - { - $dir = false; - switch($this->backup_folder) - { - case 'module': - # plugin - if (isset($this->modules['plugin'][$module]) - && $this->modules['plugin'][$module]['root_writable']) - { - $dir = path::real($this->modules['plugin'][$module]['root']).'/locales'; - } - #theme - elseif (isset($this->modules['theme'][$module]) - && $this->modules['theme'][$module]['root_writable']) - { - $dir = path::real($this->modules['theme'][$module]['root']).'/locales'; - } - break; + # Return array of modules infos by type of modules + public function listModules($type='') + { + return in_array($type, array('plugin', 'theme')) ? + $this->modules[$type] : + array_merge($this->modules['theme'], $this->modules['plugin']); + } + + # Return array object of a particular module for a given type of module + public function getModule($module='',$type='') + { + $o = new ArrayObject(); + + # Load nothing? + if (empty($module)) { + return false; + } + + # Unknow type? + if (!in_array($type, array('plugin', 'theme'))) { + $modules = array_merge($this->modules['theme'], $this->modules['plugin']); + } else { + $modules = $this->modules[$type]; + } + + # Unknow module? + if (!isset($modules[$module])) { + throw new Exception(sprintf( + __('Cannot find module %s'), $module + )); + return false; + } + + # Module info + foreach($modules[$module] as $a => $b) { + $o->{$a} = $b; + } + $o->root = path::real($o->root); + # Locales path + $o->locales = $o->root . '/locales'; + # Module exists + $o->exists = true; + # Module Basename + $i = path::info($o->root); + $o->basename = $i['basename']; + + return $o; + } + + public function getBackupFolder($module, $throw = false) + { + $dir = false; + switch($this->backup_folder) { + case 'module': + # plugin + if (isset($this->modules['plugin'][$module]) + && $this->modules['plugin'][$module]['root_writable']) { + $dir = path::real($this->modules['plugin'][$module]['root']) . '/locales'; + #theme + } + elseif (isset($this->modules['theme'][$module]) + && $this->modules['theme'][$module]['root_writable']) { + $dir = path::real($this->modules['theme'][$module]['root']) . '/locales'; + } + break; - case 'plugin': - $tmp = path::real(array_pop(explode(PATH_SEPARATOR, DC_PLUGINS_ROOT))); - if ($tmp && is_writable($tmp)) - { - $dir = $tmp; - } - break; + case 'plugin': + $tmp = path::real(array_pop(explode(PATH_SEPARATOR, DC_PLUGINS_ROOT))); + if ($tmp && is_writable($tmp)) { + $dir = $tmp; + } + break; - case 'public': - $tmp = path::real($this->core->blog->public_path); - if ($tmp && is_writable($tmp)) - { - $dir = $tmp; - } - break; + case 'public': + $tmp = path::real($this->core->blog->public_path); + if ($tmp && is_writable($tmp)) { + $dir = $tmp; + } + break; - case 'cache': - $tmp = path::real(DC_TPL_CACHE); - if ($tmp && is_writable($tmp)) - { - @mkDir($tmp.'/l10n'); - $dir = $tmp.'/l10n'; - } - break; + case 'cache': + $tmp = path::real(DC_TPL_CACHE); + if ($tmp && is_writable($tmp)) { + @mkDir($tmp . '/l10n'); + $dir = $tmp . '/l10n'; + } + break; - case 'translater': - $tmp = path::real($this->modules['plugin']['translater']['root']); - if ($tmp && is_writable($tmp)) - { - @mkDir($tmp.'/locales'); - $dir = $tmp.'/locales'; - } - break; - } - if (!$dir && $throw) - { - throw new Exception(sprintf( - __('Cannot find backups folder for module %s'),$module) - ); - } - - return $dir; - } - - public function getLangsFolder($module='',$throw=false) - { - $dir = $module == 'dotclear' ? - DC_ROOT : - self::getModuleFolder($module,false); - - if (!$dir && $throw) - { - throw new Exception(sprintf( - __('Cannot find languages folder for module %s'),$module) - ); - } - - return !$dir ? false : $dir.'/locales'; - } + case 'translater': + $tmp = path::real($this->modules['plugin']['translater']['root']); + if ($tmp && is_writable($tmp)) { + @mkDir($tmp . '/locales'); + $dir = $tmp . '/locales'; + } + break; + } + if (!$dir && $throw) { + throw new Exception(sprintf( + __('Cannot find backups folder for module %s'), $module + )); + } + + return $dir; + } + + public function getLangsFolder($module = '', $throw = false) + { + $dir = $module == 'dotclear' ? + DC_ROOT : + self::getModuleFolder($module, false); + + if (!$dir && $throw) { + throw new Exception(sprintf( + __('Cannot find languages folder for module %s'), $module + )); + } + + return !$dir ? false : $dir . '/locales'; + } - public function getModuleFolder($module='',$throw=false) - { - $dir = false; - if ((isset($this->modules['plugin'][$module]['root']) - && ($tmp = path::real($this->modules['plugin'][$module]['root']))) || - (isset($this->modules['theme'][$module]['root']) - && ($tmp = path::real($this->modules['theme'][$module]['root'])))) - { - $dir = $tmp; - } - if (!$dir && $throw) - { - throw new Exception(sprintf( - __('Cannot find root folder for module %s'),$module) - ); - } - - return $dir; - } + public function getModuleFolder($module = '', $throw = false) + { + $dir = false; + if ((isset($this->modules['plugin'][$module]['root']) + && ($tmp = path::real($this->modules['plugin'][$module]['root']))) || + (isset($this->modules['theme'][$module]['root']) + && ($tmp = path::real($this->modules['theme'][$module]['root'])))) { + $dir = $tmp; + } + if (!$dir && $throw) { + throw new Exception(sprintf( + __('Cannot find root folder for module %s'), $module + )); + } + + return $dir; + } - public function isBackupLimit($module,$throw=false) - { - # Find folder of backups - $backup = self::getBackupFolder($module,true); - - # Count backup files - $count = 0; - foreach(self::scandir($backup) AS $file) - { - if (!is_dir($backup.'/'.$file) - && preg_match('/^(l10n-'.$module.'(.*?).bck.zip)$/',$backup)) - { - $count++; - } - } - - # Limite exceed - if ($count >= $this->backup_limit) - { - if ($throw) - { - throw new Exception(sprintf( - __('Limit of %s backups for module %s exceed'), - $this->backup_limit,$module) - ); - } - return true; - } - else - { - return false; - } - } + public function isBackupLimit($module, $throw = false) + { + # Find folder of backups + $backup = self::getBackupFolder($module, true); + + # Count backup files + $count = 0; + foreach(self::scandir($backup) AS $file) { + if (!is_dir($backup . '/' . $file) + && preg_match('/^(l10n-'. $module . '(.*?).bck.zip)$/', $backup)) { + $count++; + } + } + + # Limite exceed + if ($count >= $this->backup_limit) { + if ($throw) { + throw new Exception(sprintf( + __('Limit of %s backups for module %s exceed'), + $this->backup_limit, $module + )); + } + return true; + } else { + return false; + } + } - public function listBackups($module,$return_filename=false) - { - # Not a module installed - self::getLangsFolder($module,true); - - # No backup folder for this module - $backup = self::getBackupFolder($module,false); - if (!$backup) return array(); - - # Scan files for backups - $res = $sort = array(); - $files = self::scandir($backup); - foreach($files AS $file) - { - # Not a bakcup file - $is_backup = preg_match( - '/^(l10n-('.$module.')-(.*?)-([0-9]*?).bck.zip)$/',$file,$m); - - if (is_dir($backup.'/'.$file) - || !$is_backup - || !self::isIsoCode($m[3])) continue; - - # Backup infos - if ($return_filename) - { - $res[] = $file; - } - else - { - $res[$m[3]][$file] = path::info($backup.'/'.$file); - $res[$m[3]][$file]['time']= filemtime($backup.'/'.$file); - $res[$m[3]][$file]['size'] = filesize($backup.'/'.$file); - $res[$m[3]][$file]['module'] = $module; - } - } - return $res; - } - - public function createBackup($module,$lang) - { - # Not a module installed - $locales = self::getLangsFolder($module,true); - - # No backup folder for this module - $backup = self::getBackupFolder($module,true); - - # Not an existing lang - if (!is_dir($locales.'/'.$lang)) - { - throw new Exception(sprintf( - __('Cannot find language folder %s for module %s'),$lang,$module) - ); - } - - # Scan files for a lang - $res = array(); - $files = self::scandir($locales.'/'.$lang); - foreach($files as $file) - { - # Only lang file - if (!is_dir($locales.'/'.$lang.'/'.$file) - && (self::isLangphpFile($file) - || self::isPoFile($file))) - { - $res[$locales.'/'.$lang.'/'.$file] = - $module.'/locales/'.$lang.'/'.$file; - } - } - - # Do Zip - if (!empty($res)) - { - self::isBackupLimit($module,true); - - @set_time_limit(300); - $fp = fopen($backup.'/l10n-'.$module.'-'.$lang.'-'.time().'.bck.zip','wb'); - $zip = new fileZip($fp); - foreach($res AS $src => $dest) - { - $zip->addFile($src,$dest); - } - $zip->write(); - $zip->close(); - unset($zip); - } - } - - public function deleteBackup($module,$file) - { - # Not a module installed - self::getLangsFolder($module,true); - - # No backup folder for this module - $backup = self::getBackupFolder($module,true); - - # Not a bakcup file - $is_backup = preg_match('/^(l10n-('.$module.')-(.*?)-([0-9]*?).bck.zip)$/',$file,$m); - - if (is_dir($backup.'/'.$file) - || !$is_backup - || !self::isIsoCode($m[3])) continue; - - if (!files::isDeletable($backup.'/'.$file)) - { - throw new Exception(sprintf( - __('Cannot delete backup file %s'),$file) - ); - } - - unlink($backup.'/'.$file); - } - - public function restoreBackup($module,$file) - { - # Not a module installed - $locales = self::getModuleFolder($module,true); - - # No backup folder for this module - $backup = self::getBackupFolder($module,true); - - if (!file_exists($backup.'/'.$file)) - { - throw new Exception(sprintf( - __('Cannot find backup file %s'),$file) - ); - } - - $zip = new fileUnzip($backup.'/'.$file); - $zip_files = $zip->getFilesList(); - - foreach($zip_files AS $zip_file) - { - $f = self::explodeZipFilename($zip_file,true); - if ($module != $f['module']) continue; - - $zip->unzip($zip_file,$locales.'/locales/'.$f['lang'].'/'.$f['group'].$f['ext']); - $done = true; - } - $zip->close(); - unset($zip); - } - - public function exportPack($modules,$langs) - { - # Not a query good formed - if (!is_array($modules) || 1 > count($modules) - || !is_array($langs) || 1 > count($langs)) - { - throw new Exception( - __('Wrong export query') - ); - } - - # Filter default filename - $filename = files::tidyFileName($this->export_filename); - - # Not a filename good formed - if (empty($filename)) - { - throw new Exception(sprintf( - __('Cannot use export mask %s'),$this->export_filename) - ); - } - - # Modules folders - $res = array(); - $count = array(); - foreach($modules AS $module) - { - # Not a module installed - $locales = self::getLangsFolder($module,false); - if (!$locales) continue; - - # Langs folders - foreach($langs AS $lang) - { - # Not a lang folder - if (!is_dir($locales.'/'.$lang)) continue; - - # Scan files for a lang - $files = self::scandir($locales.'/'.$lang); - foreach($files as $file) - { - # Not a lang file - if (is_dir($locales.'/'.$lang.'/'.$file) - || !self::isLangphpFile($file) - && !self::isPoFile($file)) continue; - - # Add file to zip in format "module/locales/lang/filename" - $res[$locales.'/'.$lang.'/'.$file] = - $module.'/locales/'.$lang.'/'.$file; - - $count[$module] = 1; - } - } - } - - # Nothing to do - if (empty($res)) - { - throw new Exception('Nothing to export'); - } - - # Prepare files to zip - @set_time_limit(300); - $fp = fopen('php://output','wb'); - $zip = new fileZip($fp); - foreach($res as $from => $to) - { - $zip->addFile($from,$to); - } - - # Set filename - $file_infos = 1 < count($count) ? - array(time(),'modules','multi',self::$dcTranslaterVersion) : - array( - time(), - $modules[0], - self::moduleInfo($modules[0],'type'), - self::moduleInfo($modules[0],'version') - ); - $filename = - files::tidyFileName( - dt::str( - str_replace( - array('timestamp','module','type','version'), - $file_infos, - $this->export_filename - ) - ) - ); - - # Send Zip - header('Content-Disposition: attachment;filename='.$filename.'.zip'); - header('Content-Type: application/x-zip'); - $zip->write(); - unset($zip); - exit; - } - - public function importPack($modules,$zip_file) - { - # Not a file uploaded - files::uploadStatus($zip_file); - - # No modules to update - if (!is_array($modules) || 1 > count($modules)) - { - throw new Exception(__('Wrong import query')); - } - - $done = false; - $res = array(); - - # Load Unzip object - $zip = new fileUnzip($zip_file['tmp_name']); - $files = $zip->getFilesList(); - - # Scan zip - foreach($files AS $file) - { - $f = self::explodeZipFilename($file,false); - - # Not a requested module - if (!is_array($f) - || !in_array($f['module'],$modules)) continue; - - # Get locales folder (even if "locales" is not set) - if (!$dir = self::getModuleFolder($f['module'],false)) continue; - $locales = $dir.'/locales'; - - # Not allow overwrite - if (!$this->import_overwrite - && file_exists($locales.'/'.$f['lang'].'/'.$f['group'].$f['ext'])) continue; - - $res[] = array( - 'from' => $file, - 'root' => $locales.'/'.$f['lang'], - 'to' => $locales.'/'.$f['lang'].'/'.$f['group'].$f['ext'] - ); - } - # Unzip files - foreach ($res AS $rs) - { - if (!is_dir($rs['root'])) - files::makeDir($rs['root'],true); + public function listBackups($module, $return_filename = false) + { + # Not a module installed + self::getLangsFolder($module, true); + + # No backup folder for this module + $backup = self::getBackupFolder($module, false); + if (!$backup) { + return array(); + } + + # Scan files for backups + $res = $sort = array(); + $files = self::scandir($backup); + foreach($files AS $file) { + # Not a bakcup file + $is_backup = preg_match( + '/^(l10n-(' . $module . ')-(.*?)-([0-9]*?).bck.zip)$/', $file, $m + ); + + if (is_dir($backup . '/' . $file) + || !$is_backup + || !self::isIsoCode($m[3])) { + continue; + } + + # Backup infos + if ($return_filename) { + $res[] = $file; + } else { + $res[$m[3]][$file] = path::info($backup . '/' . $file); + $res[$m[3]][$file]['time']= filemtime($backup . '/' . $file); + $res[$m[3]][$file]['size'] = filesize($backup . '/' . $file); + $res[$m[3]][$file]['module'] = $module; + } + } + return $res; + } + + public function createBackup($module, $lang) + { + # Not a module installed + $locales = self::getLangsFolder($module, true); + + # No backup folder for this module + $backup = self::getBackupFolder($module, true); + + # Not an existing lang + if (!is_dir($locales . '/' . $lang)) { + throw new Exception(sprintf( + __('Cannot find language folder %s for module %s') ,$lang, $module + )); + } + + # Scan files for a lang + $res = array(); + $files = self::scandir($locales . '/' . $lang); + foreach($files as $file) { + # Only lang file + if (!is_dir($locales . '/' . $lang . '/' . $file) + && (self::isLangphpFile($file) + || self::isPoFile($file))) { + $res[$locales . '/' . $lang . '/' . $file] = + $module . '/locales/' . $lang . '/' . $file; + } + } + + # Do Zip + if (!empty($res)) { + self::isBackupLimit($module, true); + + @set_time_limit(300); + $fp = fopen($backup . '/l10n-' . $module . '-' . $lang . '-' . time() . '.bck.zip', 'wb'); + $zip = new fileZip($fp); + foreach($res AS $src => $dest) { + $zip->addFile($src, $dest); + } + $zip->write(); + $zip->close(); + unset($zip); + } + } + + public function deleteBackup($module, $file) + { + # Not a module installed + self::getLangsFolder($module, true); + + # No backup folder for this module + $backup = self::getBackupFolder($module, true); + + # Not a bakcup file + $is_backup = preg_match('/^(l10n-(' . $module . ')-(.*?)-([0-9]*?).bck.zip)$/', $file, $m); + + if (is_dir($backup . '/' . $file) + || !$is_backup + || !self::isIsoCode($m[3])) { + return; + } + + if (!files::isDeletable($backup . '/' . $file)) { + throw new Exception(sprintf( + __('Cannot delete backup file %s'), $file + )); + } + + unlink($backup . '/' . $file); + } + + public function restoreBackup($module, $file) + { + # Not a module installed + $locales = self::getModuleFolder($module, true); + + # No backup folder for this module + $backup = self::getBackupFolder($module, true); + + if (!file_exists($backup . '/' . $file)) { + throw new Exception(sprintf( + __('Cannot find backup file %s'), $file + )); + } + + $zip = new fileUnzip($backup . '/' . $file); + $zip_files = $zip->getFilesList(); + + foreach($zip_files AS $zip_file) { + $f = self::explodeZipFilename($zip_file, true); + if ($module != $f['module']) { + continue; + } + + $zip->unzip($zip_file, $locales . '/locales/' . $f['lang'] . '/' . $f['group'] . $f['ext']); + $done = true; + } + $zip->close(); + unset($zip); + } + + public function exportPack($modules, $langs) + { + # Not a query good formed + if (!is_array($modules) || 1 > count($modules) + || !is_array($langs) || 1 > count($langs)) { + throw new Exception( + __('Wrong export query') + ); + } + + # Filter default filename + $filename = files::tidyFileName($this->export_filename); + + # Not a filename good formed + if (empty($filename)) { + throw new Exception(sprintf( + __('Cannot use export mask %s'), $this->export_filename + )); + } + + # Modules folders + $res = array(); + $count = array(); + foreach($modules AS $module) { + # Not a module installed + $locales = self::getLangsFolder($module, false); + if (!$locales) { + continue; + } + + # Langs folders + foreach($langs AS $lang) { + # Not a lang folder + if (!is_dir($locales . '/' . $lang)) { + continue; + } + + # Scan files for a lang + $files = self::scandir($locales . '/' . $lang); + foreach($files as $file) { + # Not a lang file + if (is_dir($locales . '/' . $lang . '/' . $file) + || !self::isLangphpFile($file) + && !self::isPoFile($file)) { + continue; + } + + # Add file to zip in format "module/locales/lang/filename" + $res[$locales . '/' . $lang . '/' . $file] = + $module . '/locales/' . $lang . '/' . $file; + + $count[$module] = 1; + } + } + } + + # Nothing to do + if (empty($res)) { + throw new Exception('Nothing to export'); + } + + # Prepare files to zip + @set_time_limit(300); + $fp = fopen('php://output', 'wb'); + $zip = new fileZip($fp); + foreach($res as $from => $to) { + $zip->addFile($from,$to); + } + + # Set filename + $file_infos = 1 < count($count) ? + array(time(), 'modules', 'multi', self::$dcTranslaterVersion) : + array( + time(), + $modules[0], + self::moduleInfo($modules[0], 'type'), + self::moduleInfo($modules[0], 'version') + ); + $filename = + files::tidyFileName( + dt::str( + str_replace( + array('timestamp', 'module', 'type', 'version'), + $file_infos, + $this->export_filename + ) + ) + ); + + # Send Zip + header('Content-Disposition: attachment;filename=' . $filename . '.zip'); + header('Content-Type: application/x-zip'); + $zip->write(); + unset($zip); + exit; + } + + public function importPack($modules, $zip_file) + { + # Not a file uploaded + files::uploadStatus($zip_file); + + # No modules to update + if (!is_array($modules) || 1 > count($modules)) { + throw new Exception(__('Wrong import query')); + } + + $done = false; + $res = array(); + + # Load Unzip object + $zip = new fileUnzip($zip_file['tmp_name']); + $files = $zip->getFilesList(); + + # Scan zip + foreach($files AS $file) { + $f = self::explodeZipFilename($file, false); + + # Not a requested module + if (!is_array($f) + || !in_array($f['module'],$modules)) { + continue; + } + + # Get locales folder (even if "locales" is not set) + if (!$dir = self::getModuleFolder($f['module'], false)) { + continue; + } + $locales = $dir . '/locales'; + + # Not allow overwrite + if (!$this->import_overwrite + && file_exists($locales . '/' . $f['lang'] . '/' . $f['group'] . $f['ext'])) { + continue; + } + + $res[] = array( + 'from' => $file, + 'root' => $locales . '/' . $f['lang'], + 'to' => $locales . '/' . $f['lang'] . '/' . $f['group'] . $f['ext'] + ); + } + # Unzip files + foreach ($res AS $rs) { + if (!is_dir($rs['root'])) { + files::makeDir($rs['root'], true); + } - $zip->unzip($rs['from'],$rs['to']); - $done = true; - } - $zip->close(); - unlink($zip_file['tmp_name']); - - # No file unzip - if (!$done) - { - throw new Exception(sprintf( - __('Nothing to import for these modules in pack %s'), - $zip_file['name']) - ); - } - } - - public function explodeZipFilename($file='',$throw=false) - { - # module/locales/lang/group.ext - $is_file = preg_match( - '/^(.*?)\/locales\/(.*?)\/(.*?)(.po|.lang.php)$/',$file,$f); - - # Explode file to infos - if ($is_file) { - $module = null !== self::moduleInfo($f[1],'name') ? - $f[1] : false; - $lang = self::isIsoCode($f[2]) ? - $f[2] : false; - $group = in_array($f[3],self::$allowed_l10n_groups) ? - $f[3] : false; - $ext = self::isLangphpFile($f[4]) || self::isPoFile($f[4]) ? - $f[4] : false; - } - # Not good formed - if (!$is_file || !$module || !$lang || !$group || !$ext) - { - if ($throw) - { - throw new Exception(sprintf( - __('Zip file %s is not in translater format'),$file) - ); - } - return false; - } - return array( - 'module' => $module, - 'lang' => $lang, - 'group' => $group, - 'ext' => $ext - ); - } - - public function listLangs($module,$return_path=false) - { - $res = array(); - - # Not a module installed - $locales = self::getLangsFolder($module,true); - - # Add prefix "locales" as scandir remove it - $prefix = preg_match('/(locales(.*))$/',$locales) ? 'locales' : ''; - - # Retrieve langs folders - $files = self::scandir($locales); - foreach($files as $file) - { - if (!preg_match( - '/(.*?(locales\/)([^\/]*?)\/([^\/]*?)(.lang.php|.po))$/', - $prefix.$file,$m)) continue; - - if (!self::isIsoCode($m[3])) continue; - - if ($return_path) - { - $res[$m[3]][] = $file; # Path - } - else - { - $res[$m[3]] = self::$iso[$m[3]]; # Lang name - } - } - return $res; - } - - public function addLang($module,$lang,$from_lang='') - { - # Not a module installed - $locales = self::getLangsFolder($module,true); - - # Path is right formed - self::isIsoCode($lang,true); - - # Retrieve langs folders - $langs = self::listLangs($module); - - # Lang folder is not present - if (isset($langs[$lang])) - { - throw new Exception(sprintf( - __('Language %s already exists for module %s'),$lang,$module) - ); - } - - # Create new lang directory - files::makeDir($locales.'/'.$lang,true); - - # Verify folder of other lang - if (!empty($from_lang) && !isset($langs[$from_lang])) - { - throw new Exception(sprintf( - __('Cannot copy file from language %s for module %s'), - $from_lang,$module) - ); - } - - # Copy files from other lang - if (!empty($from_lang) - && isset($langs[$from_lang])) - { - $files = self::scandir($locales.'/'.$from_lang); - foreach($files as $file) - { - if (is_dir($locales.'/'.$from_lang.'/'.$file) - || !self::isLangphpFile($file) - && !self::isPoFile($file)) continue; - - files::putContent($locales.'/'.$lang.'/'.$file, - file_get_contents($locales.'/'.$from_lang.'/'.$file)); - } - } - else - { - # Create basic empty lang file as translater need these files to be present - self::setLangphpFile($module,$lang,'main',array()); - self::setPoFile($module,$lang,'main',array()); - } - } - - public function updLang($module,$lang,$msgs) - { - # Not a module installed - $locales = self::getLangsFolder($module,true); - - # Path is right formed - self::isIsoCode($lang,true); - - # Retrieve langs folders - $langs = self::listLangs($module); - - # Lang folder is not present - if (!isset($langs[$lang])) - { - throw new Exception(sprintf( - __('Cannot find language folder %s for module %s'),$lang,$module) - ); - } - - # Sort msgids by groups - $rs = array(); - foreach($msgs as $msg) - { - $msg['group'] = isset($msg['group']) ? $msg['group'] : ''; - $msg['msgid'] = isset($msg['msgid']) ? $msg['msgid'] : ''; - $msg['msgstr'] = isset($msg['msgstr']) ? trim($msg['msgstr']) : ''; + $zip->unzip($rs['from'], $rs['to']); + $done = true; + } + $zip->close(); + unlink($zip_file['tmp_name']); + + # No file unzip + if (!$done) { + throw new Exception(sprintf( + __('Nothing to import for these modules in pack %s'), + $zip_file['name'] + )); + } + } + + public function explodeZipFilename($file = '', $throw = false) + { + # module/locales/lang/group.ext + $is_file = preg_match( + '/^(.*?)\/locales\/(.*?)\/(.*?)(.po|.lang.php)$/', $file, $f + ); + + # Explode file to infos + if ($is_file) { + $module = null !== self::moduleInfo($f[1], 'name') ? + $f[1] : false; + $lang = self::isIsoCode($f[2]) ? + $f[2] : false; + $group = in_array($f[3], self::$allowed_l10n_groups) ? + $f[3] : false; + $ext = self::isLangphpFile($f[4]) || self::isPoFile($f[4]) ? + $f[4] : false; + } + # Not good formed + if (!$is_file || !$module || !$lang || !$group || !$ext) { + if ($throw) { + throw new Exception(sprintf( + __('Zip file %s is not in translater format'), $file + )); + } + return false; + } + return array( + 'module' => $module, + 'lang' => $lang, + 'group' => $group, + 'ext' => $ext + ); + } + + public function listLangs($module, $return_path = false) + { + $res = array(); + + # Not a module installed + $locales = self::getLangsFolder($module, true); + + # Add prefix "locales" as scandir remove it + $prefix = preg_match('/(locales(.*))$/', $locales) ? 'locales' : ''; + + # Retrieve langs folders + $files = self::scandir($locales); + foreach($files as $file) { + if (!preg_match( + '/(.*?(locales\/)([^\/]*?)\/([^\/]*?)(.lang.php|.po))$/', + $prefix . $file, $m)) { + continue; + } + + if (!self::isIsoCode($m[3])) { + continue; + } + + if ($return_path) { + $res[$m[3]][] = $file; # Path + } else { + $res[$m[3]] = self::$iso[$m[3]]; # Lang name + } + } + return $res; + } + + public function addLang($module, $lang, $from_lang = '') + { + # Not a module installed + $locales = self::getLangsFolder($module, true); + + # Path is right formed + self::isIsoCode($lang, true); + + # Retrieve langs folders + $langs = self::listLangs($module); + + # Lang folder is not present + if (isset($langs[$lang])) { + throw new Exception(sprintf( + __('Language %s already exists for module %s'), $lang, $module + )); + } + + # Create new lang directory + files::makeDir($locales . '/' . $lang, true); + + # Verify folder of other lang + if (!empty($from_lang) && !isset($langs[$from_lang])) { + throw new Exception(sprintf( + __('Cannot copy file from language %s for module %s'), + $from_lang, $module + )); + } + + # Copy files from other lang + if (!empty($from_lang) + && isset($langs[$from_lang])) { + $files = self::scandir($locales . '/' . $from_lang); + foreach($files as $file) { + if (is_dir($locales . '/' . $from_lang . '/' . $file) + || !self::isLangphpFile($file) + && !self::isPoFile($file)) { + continue; + } + + files::putContent($locales . '/' . $lang . '/' . $file, + file_get_contents($locales . '/' . $from_lang . '/' . $file) + ); + } + } else { + # Create basic empty lang file as translater need these files to be present + self::setLangphpFile($module, $lang, 'main', array()); + self::setPoFile($module, $lang, 'main', array()); + } + } + + public function updLang($module, $lang, $msgs) + { + # Not a module installed + $locales = self::getLangsFolder($module, true); + + # Path is right formed + self::isIsoCode($lang, true); + + # Retrieve langs folders + $langs = self::listLangs($module); + + # Lang folder is not present + if (!isset($langs[$lang])) { + throw new Exception(sprintf( + __('Cannot find language folder %s for module %s'), $lang, $module + )); + } + + # Sort msgids by groups + $rs = array(); + foreach($msgs as $msg) { + $msg['group'] = isset($msg['group']) ? $msg['group'] : ''; + $msg['msgid'] = isset($msg['msgid']) ? $msg['msgid'] : ''; + $msg['msgstr'] = isset($msg['msgstr']) ? trim($msg['msgstr']) : ''; /* - if (get_magic_quotes_gpc()) { - $msg['msgid'] = stripcslashes($msg['msgid']); - $msg['msgstr'] = stripcslashes($msg['msgstr']); - } -*/ if ($msg['msgstr'] == '') continue; - - $rs[$msg['group']][$msg['msgid']] = $msg['msgstr']; - } - - # Backup files if auto-backup is on - if ($this->backup_auto) - { - self::createBackup($module,$lang); - } - - # Delete empty files (files with no group) - foreach(self::$allowed_l10n_groups AS $group) - { - if (isset($rs[$group])) continue; - - $po_file = $locales.'/'.$lang.'/'.$group.'.po'; - $langphp_file = $locales.'/'.$lang.'/'.$group.'.lang.php'; - - if (file_exists($po_file)) - { - unlink($po_file); - } - if (file_exists($langphp_file)) - { - unlink($langphp_file); - } - } - - # No msgstr to write - if (empty($rs)) - { - throw new Exception(sprintf( - __('No string to write, language %s deleted for module %s'), - $lang,$module) - ); - } - - # Write .po and .lang.php files - foreach($rs AS $group => $msgs) - { - self::setLangphpFile($module,$lang,$group,$msgs); - self::setPoFile($module,$lang,$group,$msgs); - } - } - - public function delLang($module,$lang,$del_empty_dir=true) - { - # Not a module installed - $locales = self::getLangsFolder($module,true); - - # Path is right formed - self::isIsoCode($lang,true); - - # Retrieve langs folders - $files = self::listLangs($module,true); - - # Lang folder is not present - if (!isset($files[$lang])) - { - throw new Exception(sprintf( - __('Cannot find language folder %s for module %s'),$lang,$module) - ); - } - - # Delete .po and .lang.php files - foreach($files[$lang] as $file) - { - unlink($locales.'/'.$file); - } - - # Delete lang folder if empty - $dir = self::scandir($locales.'/'.$lang); - if (empty($dir)) - { - rmdir($locales.'/'.$lang); - } - - # Delete locales folder if empty - $loc = self::scandir($locales); - if (empty($loc)) - { - rmdir($locales); - } - } - - public static function encodeMsg($str) - { - return text::toUTF8(stripslashes(trim($str))); - } - - /* Scan a module folder to find all l10n strings in .php files */ - public function getMsgIds($module) - { - $res = array(); - - # Not a module installed - $dir = self::getModuleFolder($module,true); - - $files = self::scandir($dir); - - $scan_ext = array('php'); - if ($this->scan_tpl) - { - $scan_ext[] = 'html'; - } - - foreach($files AS $file) - { - if (is_dir($dir.'/'.$file) - || !in_array(files::getExtension($file),$scan_ext)) continue; - - $contents = file($dir.'/'.$file); - foreach($contents AS $line => $content) - { - # php files - //if (preg_match_all("|__\((['\"]{1})(.*)([\"']{1})\)|U",$content,$matches)) - if (preg_match_all("|__\((['\"]{1})(.*?)([\"']{1})\)|",$content,$matches)) - { - foreach($matches[2] as $id) - { - $res[] = array( - 'msgid' => self::encodeMsg($id), - 'file' => $file, - 'line' => $line + 1 - ); - } - } - # tpl files - if ($this->scan_tpl - && preg_match_all('/\{\{tpl:lang\s([^}]+)\}\}/',$content,$matches)) - { - foreach($matches[1] as $id) - { - $res[] = array( - 'msgid' => self::encodeMsg($id), - 'file' => $file, - 'line' => $line + 1 - ); - } - } - } - unset($contents); - } - return $res; - } - - /* Scan a lang folder to find l10n translations in files */ - public function getMsgStrs($module,$requested_lang='') - { - $res = array(); - - # Not a module installed - $locales = self::getLangsFolder($module,true); - - $langs = self::listLangs($module,true); - - # Not an existing lang - if (!isset($langs[$requested_lang])) return $res; - - # Lang files - $exists = array(); - foreach($langs[$requested_lang] as $file) - { - if (in_array($file,$exists)) continue; - $exists[] = $file; - $path = path::clean($locales.'/'.$file); - - # .po files - if (self::isPoFile($file)) - { - $po = self::getPoFile($path); - if (!is_array($po)) continue; - - foreach($po as $id => $str) - { - $is_po[$requested_lang][$id] = 1; - - $res[] = array( - 'msgid' => self::encodeMsg($id), - 'msgstr' => self::encodeMsg($str), - 'lang' => $requested_lang, - 'type' => 'po', - 'path' => $path, - 'file' => basename($file), - 'group'=> str_replace('.po','',basename($file)) - ); - } - } - # .lang.php files - elseif (self::isLangphpFile($file)) - { - $php = self::getLangphpFile($path); - foreach($php AS $id => $str) - { - # Don't overwrite .po - if (isset($is_po[$requested_lang][$id])) continue; - $res[] = array( - 'msgid' => self::encodeMsg($id), - 'msgstr' => self::encodeMsg($str), - 'lang' => $requested_lang, - 'type' => 'php', - 'path' => $path, - 'file' => basename($file), - 'group'=> str_replace('.lang.php','',basename($file)) - ); - } - } - } - return $res; - } - - public function getMsgs($module,$requested_lang='') - { - # Get messages ids of a module - $m_msgids = self::getMsgIds($module); - - # Get messages translations for a module - $m_msgstrs = self::getMsgStrs($module,$requested_lang); - - # Get messages translations for others modules - foreach(self::listModules() AS $o_module => $o_infos) - { - if ($o_module == $module) continue; - $m_o_msgstrs[$o_module] = self::getMsgStrs($o_module,$requested_lang); - } - $m_o_msgstrs['dotclear'] = self::getMsgStrs('dotclear',$requested_lang); - - # Only one lang or all - $langs = '' == $requested_lang ? - self::listLangs($module) : - array($requested_lang => self::isIsoCode($requested_lang)); - - # Let's go reorder the mixture - $res = array(); - foreach($langs AS $lang => $iso) - { - $res[$lang] = array(); - - # From id list - foreach($m_msgids AS $rs) - { - $res[$lang][$rs['msgid']]['files'][] = array(trim($rs['file'],'/'),$rs['line']); - $res[$lang][$rs['msgid']]['group'] = 'main'; - $res[$lang][$rs['msgid']]['msgstr'] = ''; - $res[$lang][$rs['msgid']]['in_dc'] = false; - $res[$lang][$rs['msgid']]['o_msgstrs'] = array(); - } - - # From str list - foreach($m_msgstrs AS $rs) - { - if ($rs['lang'] != $lang) continue; - - if (!isset($res[$lang][$rs['msgid']])) - { - $res[$lang][$rs['msgid']]['files'][] = array(); - $res[$lang][$rs['msgid']]['in_dc'] = false; - $res[$lang][$rs['msgid']]['o_msgstrs'] = array(); - } - $res[$lang][$rs['msgid']]['group'] = $rs['group']; - $res[$lang][$rs['msgid']]['msgstr'] = $rs['msgstr']; - $res[$lang][$rs['msgid']]['in_dc'] = false; - } - - # From others str list - foreach($m_o_msgstrs AS $o_module => $o_msgstrs) - { - foreach($o_msgstrs AS $rs) - { - if ($rs['lang'] != $lang) continue; - - if (!isset($res[$lang][$rs['msgid']])) continue; - - $res[$lang][$rs['msgid']]['o_msgstrs'][] = array( - 'msgstr' => $rs['msgstr'], - 'module' => $o_module, - 'file' => $rs['file'] - ); - if ($o_module == 'dotclear') - { - $res[$lang][$rs['msgid']]['in_dc'] = true; - } - } - } - } - return '' == $requested_lang ? $res : $res[$requested_lang]; - } - - /* Write a lang file */ - private function writeLangFile($dir,$content,$throw) - { - $path = path::info($dir); - if (is_dir($path['dirname']) && !is_writable($path['dirname']) - || file_exists($dir) && !is_writable($dir)) - { - throw new Exception(sprintf( - __('Cannot grant write acces on lang file %s'),$dir) - ); - } - - # -- BEHAVIOR -- dcTranslaterBeforeWriteLangFile - $this->core->callBehavior('dcTranslaterBeforeWriteLangFile',$dir,$content,$throw); - - $f = @files::putContent($dir,$content); - if (!$f && $throw) - { - throw new Exception(sprintf( - __('Cannot write lang file %s'),$dir) - ); - } - - # -- BEHAVIOR -- dcTranslaterAfterWriteLangFile - $this->core->callBehavior('dcTranslaterAfterWriteLangFile',$f,$dir,$content,$throw); - - return $f; - } - - /* Try if a file is a .lang.php file */ - public static function isLangphpFile($file) - { - return files::getExtension($file) == 'php' && stristr($file,'.lang.php'); - } - - /* Get and parse a .lang.php file */ - public static function getLangphpFile($file) - { - if (!file_exists($file)) return array(); - - $res = array(); - $content = implode('',file($file)); - $count = preg_match_all('/(\$GLOBALS\[\'__l10n\'\]\[\'(.*?)\'\]\s*\x3D\s*\'(.*?)\';)/',$content, $m); - - if (!$count) return array(); - - for ($i=0; $i<$count; $i++) - { - $id = $m[2][$i]; - $str = self::langphpString($m[3][$i]); - - if ($str) - { - $res[self::langphpString($id)] = $str; - } - } - if (!empty($res[''])) - { - $res = array_diff_key($res,array(''=>1)); - } - return $res; - } - - /* Construct and write a .lang.php file */ - private function setLangphpFile($module,$lang,$group,$fields) - { - if (!$this->write_langphp) return; - - # Not a module installed - $locales = self::getLangsFolder($module,true); - - # Path is right formed - $lang_name = self::isIsoCode($lang,true); - - $l = "parse_comment) - { - $l .= - '// Language: '.$lang_name." \n". - '// Module: '.$module." - ".self::moduleInfo($module,'version')."\n". - '// Date: '.dt::str('%Y-%m-%d %H:%M:%S')." \n"; - - if ($this->parse_user && !empty($this->parse_userinfo)) - { - $search = self::$allowed_user_informations; - foreach($search AS $n) - { - $replace[] = $this->core->auth->getInfo('user_'.$n); - } - $info = trim(str_replace($search,$replace,$this->parse_userinfo)); - if (!empty($info)) - { - $l .= '// Author: '.html::escapeHTML($info)."\n"; - } - } - $l .= - '// Translated with dcTranslater - '.$this->core->plugins->moduleInfo('translater','version')." \n\n"; - } - if ($this->parse_comment) - { - $infos = self::getMsgids($module); - foreach($infos AS $info) - { - if (isset($fields[$info['msgid']])) - { - $comments[$info['msgid']] = (isset($comments[$info['msgid']]) ? - $comments[$info['msgid']] : ''). - '#'.trim($info['file'],'/').':'.$info['line']."\n"; - } - } - } - - foreach($fields as $id => $str) - { - if ($this->parse_comment && isset($comments[$id])) - { - $l .= $comments[$id]; - } - - $l .= - '$GLOBALS[\'__l10n\'][\''.addcslashes($id,"'").'\'] = '. - '\''.self::langphpString($str,true)."';\n"; - - if ($this->parse_comment) - { - $l .= "\n"; - } - } - $l .= "?>"; - - self::writeLangFile($locales.'/'.$lang.'/'.$group.'.lang.php',$l,true); - } - - /* Parse a .lang.php string */ - private static function langphpString($string,$reverse=false) - { - if ($reverse) - { - $smap = array('\'', "\n", "\t", "\r"); - $rmap = array('\\\'', '\\n"' . "\n" . '"', '\\t', '\\r'); - return trim((string) str_replace($smap, $rmap, $string)); - } - else - { - $smap = array('/\\\\n/', '/\\\\r/', '/\\\\t/', "/\\\'/"); - $rmap = array("\n", "\r", "\t", "'"); - return trim((string) preg_replace($smap, $rmap, $string)); - } - } - - /* Try if a file is a .po file */ - public static function isPoFile($file) - { - return files::getExtension($file) == 'po'; - } - - /* Get and parse a .po file */ - public static function getPoFile($file) - { - if (!file_exists($file)) return false; - - $res = array(); - $content = implode('',file($file)); - - $count = preg_match_all('/msgid\s(.*(?:\n".*")*)\nmsgstr\s(.*(?:\n".*")*)/',$content,$m); - - if (!$count) return false; - - for ($i=0; $i<$count; $i++) - { - $id = preg_replace('/"(.*)"/s','\\1',$m[1][$i]); - $str= preg_replace('/"(.*)"/s','\\1',$m[2][$i]); - - $str = self::poString($str); - - if ($str) - { - $res[self::poString($id)] = $str; - } - } - - if (!empty($res[''])) - { - $res = array_diff_key($res,array(''=>1)); - } - return $res; - } - /* Construct and parse a .po file */ - private function setPoFile($module,$lang,$group,$fields) - { - if (!$this->write_po) return; - - # Not a module installed - $locales = self::getLangsFolder($module,true); - - # Path is right formed - self::isIsoCode($lang,true); - - $l = ''; - if ($this->parse_comment) - { - $l .= - '# Language: '.self::$iso[$lang]."\n". - '# Module: '.$module." - ".self::moduleInfo($module,'version')."\n". - '# Date: '.dt::str('%Y-%m-%d %H:%M:%S')."\n"; - - if ($this->parse_user && !empty($this->parse_userinfo)) - { - $search = self::$allowed_user_informations; - foreach($search AS $n) - { - $replace[] = $this->core->auth->getInfo('user_'.$n); - } - $info = trim(str_replace($search,$replace,$this->parse_userinfo)); - if (!empty($info)) - { - $l .= '# Author: '.html::escapeHTML($info)."\n"; - } - } - $l .= - '# Translated with translater '.$this->core->plugins->moduleInfo('translater','version')."\n"; - } - $l .= - "\n". - "msgid \"\"\n". - "msgstr \"\"\n". - '"Content-Type: text/plain; charset=UTF-8\n"'."\n". - '"Project-Id-Version: '.$module.' '.self::moduleInfo($module,'version').'\n"'."\n". - '"POT-Creation-Date: \n"'."\n". - '"PO-Revision-Date: '.date('c').'\n"'."\n". - '"Last-Translator: '.$this->core->auth->getInfo('user_cn').'\n"'."\n". - '"Language-Team: \n"'."\n". - '"MIME-Version: 1.0\n"'."\n". - '"Content-Transfer-Encoding: 8bit\n"'."\n\n"; - - if ($this->parse_comment) - { - $infos = self::getMsgids($module); - foreach($infos AS $info) - { - if (isset($fields[$info['msgid']])) - { - $comments[$info['msgid']] = (isset($comments[$info['msgid']]) ? - $comments[$info['msgid']] : ''). - '#: '.trim($info['file'],'/').':'.$info['line']."\n"; - } - } - } - - foreach($fields as $id => $str) - { - if ($this->parse_comment && isset($comments[$id])) - { - $l .= $comments[$id]; - } - $l .= - 'msgid "'.self::poString($id,true) .'"'."\n". - 'msgstr "'.self::poString($str,true).'"'."\n\n"; - } - - self::writeLangFile($locales.'/'.$lang.'/'.$group.'.po',$l,true); - } - - /* Parse .po string */ - private static function poString($string,$reverse=false) - { - if ($reverse) - { - $smap = array('"', "\n", "\t", "\r"); - $rmap = array('\\"', '\\n"' . "\n" . '"', '\\t', '\\r'); - return trim((string) str_replace($smap, $rmap, $string)); - } - else - { - $smap = array('/"\s+"/', '/\\\\n/', '/\\\\r/', '/\\\\t/', '/\\\"/'); - $rmap = array('', "\n", "\r", "\t", '"'); - return trim((string) preg_replace($smap, $rmap, $string)); - } - } - - /* Scan recursively a folder and return files and folders names */ - public static function scandir($path,$dir='',$res=array()) - { - $path = path::real($path); - if (!is_dir($path) || !is_readable($path)) return array(); - - $files = files::scandir($path); - - foreach($files AS $file) - { - if ($file == '.' || $file == '..') continue; - - if (is_dir($path.'/'.$file)) - { - $res[] = $file; - $res = self::scanDir($path.'/'.$file,$dir.'/'.$file,$res); - } - else - { - $res[] = empty($dir) ? $file : $dir.'/'.$file; - } - } - return $res; - } - - /* Return array of langs like in clearbreaks l10n */ - public static function getIsoCodes($flip=false,$name_with_code=false) - { - if (empty(self::$iso)) - { - self::$iso = l10n::getISOcodes($flip,$name_with_code); - } - return self::$iso; - } - - /* Find if lang code exists or lang name */ - public static function isIsoCode($iso,$throw=false) - { - $codes = self::getIsoCodes(); - $code = isset($codes[$iso]) ? $codes[$iso] : false; - if (!$code && $throw) - { - throw new Exception(sprintf( - __('Cannot find language for code %s'),$iso) - ); - } - return $code; - } -} -?> \ No newline at end of file + if (get_magic_quotes_gpc()) { + $msg['msgid'] = stripcslashes($msg['msgid']); + $msg['msgstr'] = stripcslashes($msg['msgstr']); + } +*/ if ($msg['msgstr'] == '') { + continue; + } + + $rs[$msg['group']][$msg['msgid']] = $msg['msgstr']; + } + + # Backup files if auto-backup is on + if ($this->backup_auto) { + self::createBackup($module, $lang); + } + + # Delete empty files (files with no group) + foreach(self::$allowed_l10n_groups AS $group) { + if (isset($rs[$group])) { + continue; + } + + $po_file = $locales . '/' . $lang . '/' . $group . '.po'; + $langphp_file = $locales . '/' . $lang . '/' . $group . '.lang.php'; + + if (file_exists($po_file)) { + unlink($po_file); + } + if (file_exists($langphp_file)) { + unlink($langphp_file); + } + } + + # No msgstr to write + if (empty($rs)) { + throw new Exception(sprintf( + __('No string to write, language %s deleted for module %s'), + $lang, $module + )); + } + + # Write .po and .lang.php files + foreach($rs AS $group => $msgs) { + self::setLangphpFile($module, $lang, $group, $msgs); + self::setPoFile($module, $lang, $group, $msgs); + } + } + + public function delLang($module, $lang, $del_empty_dir = true) + { + # Not a module installed + $locales = self::getLangsFolder($module, true); + + # Path is right formed + self::isIsoCode($lang, true); + + # Retrieve langs folders + $files = self::listLangs($module, true); + + # Lang folder is not present + if (!isset($files[$lang])) { + throw new Exception(sprintf( + __('Cannot find language folder %s for module %s'), $lang, $module + )); + } + + # Delete .po and .lang.php files + foreach($files[$lang] as $file) { + unlink($locales . '/' . $file); + } + + # Delete lang folder if empty + $dir = self::scandir($locales . '/' . $lang); + if (empty($dir)) { + rmdir($locales . '/' . $lang); + } + + # Delete locales folder if empty + $loc = self::scandir($locales); + if (empty($loc)) { + rmdir($locales); + } + } + + public static function encodeMsg($str) + { + return text::toUTF8(stripslashes(trim($str))); + } + + /* Scan a module folder to find all l10n strings in .php files */ + public function getMsgIds($module) + { + $res = array(); + + # Not a module installed + $dir = self::getModuleFolder($module, true); + + $files = self::scandir($dir); + + $scan_ext = array('php'); + if ($this->scan_tpl) { + $scan_ext[] = 'html'; + } + + foreach($files AS $file) { + if (is_dir($dir . '/' . $file) + || !in_array(files::getExtension($file),$scan_ext)) { + continue; + } + + $contents = file($dir . '/' . $file); + foreach($contents AS $line => $content) { + # php files + //if (preg_match_all("|__\((['\"]{1})(.*)([\"']{1})\)|U", $content, $matches)) + if (preg_match_all("|__\((['\"]{1})(.*?)([\"']{1})\)|", $content, $matches)) { + foreach($matches[2] as $id) { + $res[] = array( + 'msgid' => self::encodeMsg($id), + 'file' => $file, + 'line' => $line + 1 + ); + } + } + # tpl files + if ($this->scan_tpl + && preg_match_all('/\{\{tpl:lang\s([^}]+)\}\}/', $content, $matches)) { + foreach($matches[1] as $id) { + $res[] = array( + 'msgid' => self::encodeMsg($id), + 'file' => $file, + 'line' => $line + 1 + ); + } + } + } + unset($contents); + } + return $res; + } + + /* Scan a lang folder to find l10n translations in files */ + public function getMsgStrs($module, $requested_lang = '') + { + $res = array(); + + # Not a module installed + $locales = self::getLangsFolder($module, true); + + $langs = self::listLangs($module, true); + + # Not an existing lang + if (!isset($langs[$requested_lang])) { + return $res; + } + + # Lang files + $exists = array(); + foreach($langs[$requested_lang] as $file) { + if (in_array($file,$exists)) { + continue; + } + $exists[] = $file; + $path = path::clean($locales . '/' . $file); + + # .po files + if (self::isPoFile($file)) { + $po = self::getPoFile($path); + if (!is_array($po)) { + continue; + } + + foreach($po as $id => $str) { + $is_po[$requested_lang][$id] = 1; + + $res[] = array( + 'msgid' => self::encodeMsg($id), + 'msgstr' => self::encodeMsg($str), + 'lang' => $requested_lang, + 'type' => 'po', + 'path' => $path, + 'file' => basename($file), + 'group'=> str_replace('.po', '', basename($file)) + ); + } + # .lang.php files + } elseif (self::isLangphpFile($file)) { + $php = self::getLangphpFile($path); + foreach($php AS $id => $str) { + # Don't overwrite .po + if (isset($is_po[$requested_lang][$id])) { + continue; + } + $res[] = array( + 'msgid' => self::encodeMsg($id), + 'msgstr' => self::encodeMsg($str), + 'lang' => $requested_lang, + 'type' => 'php', + 'path' => $path, + 'file' => basename($file), + 'group'=> str_replace('.lang.php', '', basename($file)) + ); + } + } + } + return $res; + } + + public function getMsgs($module, $requested_lang = '') + { + # Get messages ids of a module + $m_msgids = self::getMsgIds($module); + + # Get messages translations for a module + $m_msgstrs = self::getMsgStrs($module, $requested_lang); + + # Get messages translations for others modules + foreach(self::listModules() AS $o_module => $o_infos) { + if ($o_module == $module) continue; + $m_o_msgstrs[$o_module] = self::getMsgStrs($o_module, $requested_lang); + } + $m_o_msgstrs['dotclear'] = self::getMsgStrs('dotclear', $requested_lang); + + # Only one lang or all + $langs = '' == $requested_lang ? + self::listLangs($module) : + array($requested_lang => self::isIsoCode($requested_lang)); + + # Let's go reorder the mixture + $res = array(); + foreach($langs AS $lang => $iso) { + $res[$lang] = array(); + + # From id list + foreach($m_msgids AS $rs) { + $res[$lang][$rs['msgid']]['files'][] = array(trim($rs['file'],'/'), $rs['line']); + $res[$lang][$rs['msgid']]['group'] = 'main'; + $res[$lang][$rs['msgid']]['msgstr'] = ''; + $res[$lang][$rs['msgid']]['in_dc'] = false; + $res[$lang][$rs['msgid']]['o_msgstrs'] = array(); + } + + # From str list + foreach($m_msgstrs AS $rs) { + if ($rs['lang'] != $lang) { + continue; + } + + if (!isset($res[$lang][$rs['msgid']])) { + $res[$lang][$rs['msgid']]['files'][] = array(); + $res[$lang][$rs['msgid']]['in_dc'] = false; + $res[$lang][$rs['msgid']]['o_msgstrs'] = array(); + } + $res[$lang][$rs['msgid']]['group'] = $rs['group']; + $res[$lang][$rs['msgid']]['msgstr'] = $rs['msgstr']; + $res[$lang][$rs['msgid']]['in_dc'] = false; + } + + # From others str list + foreach($m_o_msgstrs AS $o_module => $o_msgstrs) { + foreach($o_msgstrs AS $rs) { + if ($rs['lang'] != $lang) { + continue; + } + + if (!isset($res[$lang][$rs['msgid']])) { + continue; + } + + $res[$lang][$rs['msgid']]['o_msgstrs'][] = array( + 'msgstr' => $rs['msgstr'], + 'module' => $o_module, + 'file' => $rs['file'] + ); + if ($o_module == 'dotclear') { + $res[$lang][$rs['msgid']]['in_dc'] = true; + } + } + } + } + return '' == $requested_lang ? $res : $res[$requested_lang]; + } + + /* Write a lang file */ + private function writeLangFile($dir, $content, $throw) + { + $path = path::info($dir); + if (is_dir($path['dirname']) && !is_writable($path['dirname']) + || file_exists($dir) && !is_writable($dir)) { + throw new Exception(sprintf( + __('Cannot grant write acces on lang file %s'), $dir + )); + } + + # -- BEHAVIOR -- dcTranslaterBeforeWriteLangFile + $this->core->callBehavior('dcTranslaterBeforeWriteLangFile', $dir, $content, $throw); + + $f = @files::putContent($dir,$content); + if (!$f && $throw) { + throw new Exception(sprintf( + __('Cannot write lang file %s'), $dir + )); + } + + # -- BEHAVIOR -- dcTranslaterAfterWriteLangFile + $this->core->callBehavior('dcTranslaterAfterWriteLangFile', $f, $dir, $content, $throw); + + return $f; + } + + /* Try if a file is a .lang.php file */ + public static function isLangphpFile($file) + { + return files::getExtension($file) == 'php' && stristr($file, '.lang.php'); + } + + /* Get and parse a .lang.php file */ + public static function getLangphpFile($file) + { + if (!file_exists($file)) { + return array(); + } + + $res = array(); + $content = implode('',file($file)); + $count = preg_match_all('/(\$GLOBALS\[\'__l10n\'\]\[\'(.*?)\'\]\s*\x3D\s*\'(.*?)\';)/', $content, $m); + + if (!$count) { + return array(); + } + + for ($i = 0; $i < $count; $i++) { + $id = $m[2][$i]; + $str = self::langphpString($m[3][$i]); + + if ($str) { + $res[self::langphpString($id)] = $str; + } + } + if (!empty($res[''])) { + $res = array_diff_key($res,array(''=>1)); + } + return $res; + } + + /* Construct and write a .lang.php file */ + private function setLangphpFile($module, $lang, $group, $fields) + { + if (!$this->write_langphp) { + return; + } + + # Not a module installed + $locales = self::getLangsFolder($module, true); + + # Path is right formed + $lang_name = self::isIsoCode($lang, true); + + $l = "parse_comment) { + $l .= + '// Language: ' . $lang_name . " \n" . + '// Module: ' . $module . " - " . self::moduleInfo($module, 'version') . "\n" . + '// Date: ' . dt::str('%Y-%m-%d %H:%M:%S') . " \n"; + + if ($this->parse_user && !empty($this->parse_userinfo)) { + $search = self::$allowed_user_informations; + foreach($search AS $n) { + $replace[] = $this->core->auth->getInfo('user_' . $n); + } + $info = trim(str_replace($search,$replace,$this->parse_userinfo)); + if (!empty($info)) { + $l .= '// Author: ' . html::escapeHTML($info) . "\n"; + } + } + $l .= + '// Translated with dcTranslater - ' . $this->core->plugins->moduleInfo('translater', 'version') . " \n\n"; + } + if ($this->parse_comment) { + $infos = self::getMsgids($module); + foreach($infos AS $info) { + if (isset($fields[$info['msgid']])) { + $comments[$info['msgid']] = (isset($comments[$info['msgid']]) ? + $comments[$info['msgid']] : '') . + '#'.trim($info['file'],'/') . ':' . $info['line'] . "\n"; + } + } + } + + foreach($fields as $id => $str) { + if ($this->parse_comment && isset($comments[$id])) { + $l .= $comments[$id]; + } + + $l .= + '$GLOBALS[\'__l10n\'][\'' . addcslashes($id, "'") . '\'] = ' . + '\'' . self::langphpString($str, true) . "';\n"; + + if ($this->parse_comment) { + $l .= "\n"; + } + } + $l .= ""; + + self::writeLangFile($locales . '/' . $lang . '/' . $group . '.lang.php', $l, true); + } + + /* Parse a .lang.php string */ + private static function langphpString($string, $reverse = false) + { + if ($reverse) { + $smap = array('\'', "\n", "\t", "\r"); + $rmap = array('\\\'', '\\n"' . "\n" . '"', '\\t', '\\r'); + return trim((string) str_replace($smap, $rmap, $string)); + } else { + $smap = array('/\\\\n/', '/\\\\r/', '/\\\\t/', "/\\\'/"); + $rmap = array("\n", "\r", "\t", "'"); + return trim((string) preg_replace($smap, $rmap, $string)); + } + } + + /* Try if a file is a .po file */ + public static function isPoFile($file) + { + return files::getExtension($file) == 'po'; + } + + /* Get and parse a .po file */ + public static function getPoFile($file) + { + if (!file_exists($file)) { + return false; + } + + $res = array(); + $content = implode('',file($file)); + + $count = preg_match_all('/msgid\s(.*(?:\n".*")*)\nmsgstr\s(.*(?:\n".*")*)/', $content, $m); + + if (!$count) return false; + + for ($i = 0; $i < $count; $i++) { + $id = preg_replace('/"(.*)"/s','\\1', $m[1][$i]); + $str= preg_replace('/"(.*)"/s','\\1', $m[2][$i]); + + $str = self::poString($str); + + if ($str) { + $res[self::poString($id)] = $str; + } + } + + if (!empty($res[''])) { + $res = array_diff_key($res, array(''=>1)); + } + return $res; + } + /* Construct and parse a .po file */ + private function setPoFile($module, $lang, $group, $fields) + { + if (!$this->write_po) { + return; + } + + # Not a module installed + $locales = self::getLangsFolder($module, true); + + # Path is right formed + self::isIsoCode($lang, true); + + $l = ''; + if ($this->parse_comment) { + $l .= + '# Language: ' . self::$iso[$lang] . "\n" . + '# Module: ' . $module . " - " . self::moduleInfo($module, 'version') . "\n" . + '# Date: ' . dt::str('%Y-%m-%d %H:%M:%S') . "\n"; + + if ($this->parse_user && !empty($this->parse_userinfo)) { + $search = self::$allowed_user_informations; + foreach($search AS $n) { + $replace[] = $this->core->auth->getInfo('user_' . $n); + } + $info = trim(str_replace($search, $replace, $this->parse_userinfo)); + if (!empty($info)) { + $l .= '# Author: ' . html::escapeHTML($info) . "\n"; + } + } + $l .= + '# Translated with translater ' . $this->core->plugins->moduleInfo('translater', 'version') . "\n"; + } + $l .= + "\n". + "msgid \"\"\n" . + "msgstr \"\"\n" . + '"Content-Type: text/plain; charset=UTF-8\n"' . "\n" . + '"Project-Id-Version: ' . $module . ' ' . self::moduleInfo($module, 'version') . '\n"' . "\n" . + '"POT-Creation-Date: \n"' . "\n" . + '"PO-Revision-Date: ' . date('c') . '\n"' . "\n" . + '"Last-Translator: ' . $this->core->auth->getInfo('user_cn') . '\n"' . "\n" . + '"Language-Team: \n"' . "\n" . + '"MIME-Version: 1.0\n"' . "\n" . + '"Content-Transfer-Encoding: 8bit\n"' . "\n" . + '"Plural-Forms: nplurals=2; plural=(n > 1);\n"' . "\n\n"; + + if ($this->parse_comment) { + $infos = self::getMsgids($module); + foreach($infos AS $info) { + if (isset($fields[$info['msgid']])) { + $comments[$info['msgid']] = (isset($comments[$info['msgid']]) ? + $comments[$info['msgid']] : '') . + '#: '.trim($info['file'],'/') . ':' . $info['line'] . "\n"; + } + } + } + + foreach($fields as $id => $str) { + if ($this->parse_comment && isset($comments[$id])) { + $l .= $comments[$id]; + } + $l .= + 'msgid "' . self::poString($id, true) . '"' . "\n" . + 'msgstr "' . self::poString($str, true) . '"' . "\n\n"; + } + + self::writeLangFile($locales . '/' . $lang . '/' . $group . '.po', $l, true); + } + + /* Parse .po string */ + private static function poString($string, $reverse = false) + { + if ($reverse) { + $smap = array('"', "\n", "\t", "\r"); + $rmap = array('\\"', '\\n"' . "\n" . '"', '\\t', '\\r'); + return trim((string) str_replace($smap, $rmap, $string)); + } else { + $smap = array('/"\s+"/', '/\\\\n/', '/\\\\r/', '/\\\\t/', '/\\\"/'); + $rmap = array('', "\n", "\r", "\t", '"'); + return trim((string) preg_replace($smap, $rmap, $string)); + } + } + + /* Scan recursively a folder and return files and folders names */ + public static function scandir($path, $dir = '', $res = array()) + { + $path = path::real($path); + if (!is_dir($path) || !is_readable($path)) { + return array(); + } + + $files = files::scandir($path); + + foreach($files AS $file) { + if ($file == '.' || $file == '..') { + continue; + } + + if (is_dir($path . '/' . $file)) { + $res[] = $file; + $res = self::scanDir($path . '/' . $file, $dir . '/' . $file, $res); + } else { + $res[] = empty($dir) ? $file : $dir . '/' . $file; + } + } + return $res; + } + + /* Return array of langs like in clearbreaks l10n */ + public static function getIsoCodes($flip = false, $name_with_code = false) + { + if (empty(self::$iso)) { + self::$iso = l10n::getISOcodes($flip, $name_with_code); + } + return self::$iso; + } + + /* Find if lang code exists or lang name */ + public static function isIsoCode($iso, $throw = false) + { + $codes = self::getIsoCodes(); + $code = isset($codes[$iso]) ? $codes[$iso] : false; + if (!$code && $throw) { + throw new Exception(sprintf( + __('Cannot find language for code %s'), $iso + )); + } + return $code; + } +} \ No newline at end of file diff --git a/inc/class.translater.proposals.php b/inc/class.translater.proposals.php index 441d051..3303fbd 100644 --- a/inc/class.translater.proposals.php +++ b/inc/class.translater.proposals.php @@ -3,62 +3,59 @@ # # This file is part of translater, a plugin for Dotclear 2. # -# Copyright (c) 2009-2013 Jean-Christian Denis and contributors -# contact@jcdenis.fr -# +# Copyright (c) 2009-2016 Jean-Christian Denis and contributors +# # Licensed under the GPL version 2.0 license. # A copy of this license is available in LICENSE file or at # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html # # -- END LICENSE BLOCK ------------------------------------ - /** * Translater proposal tools container. */ class translaterProposals { - public $core; - - private $stack = array(); - - public function __construct($core) - { - $this->core = $core; - - # --BEHAVIOR-- addTranslaterProposalTool - $core->callBehavior('addTranslaterProposalTool',$this); - } - - public function addTool($id) - { - if (!class_exists($id)) { - return; - } - - $r = new ReflectionClass($id); - $p = $r->getParentClass(); + public $core; - if (!$p || $p->name != 'translaterProposalTool') { - return; - } - - $this->stack[$id] = new $id($this->core); - } - - public function getTools() - { - return $this->stack; - } - - public function getTool($id) - { - return array_key_exists($id,$this->stack) ? $this->stack[$id] : null; - } - - public function hasTool($id) - { - return array_key_exists($id,$this->stack); - } -} -?> \ No newline at end of file + private $stack = array(); + + public function __construct($core) + { + $this->core = $core; + + # --BEHAVIOR-- addTranslaterProposalTool + $core->callBehavior('addTranslaterProposalTool', $this); + } + + public function addTool($id) + { + if (!class_exists($id)) { + return; + } + + $r = new ReflectionClass($id); + $p = $r->getParentClass(); + + if (!$p || $p->name != 'translaterProposalTool') { + return; + } + + $this->stack[$id] = new $id($this->core); + } + + public function getTools() + { + return $this->stack; + } + + public function getTool($id) + { + return array_key_exists($id, $this->stack) ? $this->stack[$id] : null; + } + + public function hasTool($id) + { + return array_key_exists($id, $this->stack); + } +} \ No newline at end of file diff --git a/inc/class.translater.rest.php b/inc/class.translater.rest.php index 490e51f..cd61df2 100644 --- a/inc/class.translater.rest.php +++ b/inc/class.translater.rest.php @@ -3,8 +3,7 @@ # # This file is part of translater, a plugin for Dotclear 2. # -# Copyright (c) 2009-2013 Jean-Christian Denis and contributors -# contact@jcdenis.fr +# Copyright (c) 2009-2016 Jean-Christian Denis and contributors # # Licensed under the GPL version 2.0 license. # A copy of this license is available in LICENSE file or at @@ -12,7 +11,9 @@ # # -- END LICENSE BLOCK ------------------------------------ -if (!defined('DC_CONTEXT_ADMIN')){return;} +if (!defined('DC_CONTEXT_ADMIN')) { + return; +} /** * Translater REST service. @@ -22,55 +23,47 @@ if (!defined('DC_CONTEXT_ADMIN')){return;} */ class translaterRest { - public static function getProposal($core,$get) - { - $from = !empty($get['langFrom']) ? trim($get['langFrom']) : ''; - $to = !empty($get['langTo']) ? trim($get['langTo']) : ''; - $tool = !empty($get['langTool']) ? trim($get['langTool']) : ''; - $str_in = !empty($get['langStr']) ? trim($get['langStr']) : ''; + public static function getProposal($core, $get) + { + $from = !empty($get['langFrom']) ? trim($get['langFrom']) : ''; + $to = !empty($get['langTo']) ? trim($get['langTo']) : ''; + $tool = !empty($get['langTool']) ? trim($get['langTool']) : ''; + $str_in = !empty($get['langStr']) ? trim($get['langStr']) : ''; - $str_in = text::toUTF8($str_in); - $str_in = trim($str_in); - $str_out = ''; + $str_in = text::toUTF8($str_in); + $str_in = trim($str_in); + $str_out = ''; - $rsp = new xmlTag(); + $rsp = new xmlTag(); - try - { - if (empty($from) || empty($to) || empty($tool)) - { - throw new Exception(__('Missing params')); - } + try { + if (empty($from) || empty($to) || empty($tool)) { + throw new Exception(__('Missing params')); + } - $translater = new dcTranslater($core); + $translater = new dcTranslater($core); - if (!empty($str_in)) - { - if (!$translater->proposal->hasTool($tool)) - { - throw new Exception(__('Failed to get translation tool')); - } - if (!$translater->proposal->getTool($tool)->isActive()) - { - throw new Exception(__('Translation tool is not configured')); - } + if (!empty($str_in)) { + if (!$translater->proposal->hasTool($tool)) { + throw new Exception(__('Failed to get translation tool')); + } + if (!$translater->proposal->getTool($tool)->isActive()) { + throw new Exception(__('Translation tool is not configured')); + } - $str_out = (string) $translater->proposal->getTool($tool)->translate($str_in,$from,$to); - } + $str_out = (string) $translater->proposal->getTool($tool)->translate($str_in ,$from, $to); + } - $x = new xmlTag('proposal'); - $x->lang_from = $from; - $x->lang_to = $to; - $x->tool = $tool; - $x->str_from = $str_in; - $x->str_to = text::toUTF8(html::decodeEntities($str_out)); - $rsp->insertNode($x); - } - catch (Exception $e) - { - $core->error->add($e->getMessage()); - } - return $rsp; - } -} -?> \ No newline at end of file + $x = new xmlTag('proposal'); + $x->lang_from = $from; + $x->lang_to = $to; + $x->tool = $tool; + $x->str_from = $str_in; + $x->str_to = text::toUTF8(html::decodeEntities($str_out)); + $rsp->insertNode($x); + } catch (Exception $e) { + $core->error->add($e->getMessage()); + } + return $rsp; + } +} \ No newline at end of file diff --git a/inc/lib.translater.google.php b/inc/lib.translater.google.php index ebe613c..47436d1 100644 --- a/inc/lib.translater.google.php +++ b/inc/lib.translater.google.php @@ -3,8 +3,7 @@ # # This file is part of translater, a plugin for Dotclear 2. # -# Copyright (c) 2009-2013 Jean-Christian Denis and contributors -# contact@jcdenis.fr +# Copyright (c) 2009-2016 Jean-Christian Denis and contributors # # Licensed under the GPL version 2.0 license. # A copy of this license is available in LICENSE file or at @@ -12,7 +11,9 @@ # # -- END LICENSE BLOCK ------------------------------------ -if (!defined('DC_CONTEXT_ADMIN')){return;} +if (!defined('DC_CONTEXT_ADMIN')) { + return; +} /** * Google proposal tool. @@ -21,77 +22,75 @@ if (!defined('DC_CONTEXT_ADMIN')){return;} */ class googleProposalTool extends translaterProposalTool { - private $api = 'https://www.googleapis.com/language/translate/v2'; - private $agent = 'dcTranslater - http://jcd.lv/?q=translater'; - private $key = null; //ex: AsSDqsGsfdSDSQFQsfedj9bnzY390aIg-1d - - protected function setup() - { - $this->key = $this->core->blog->settings->translater->translater_google_proposal_key; - - $this->setName(__('Google')); - $this->setDesc(__('Google Translation Tool API')); - $this->setActive(!empty($this->key)); - } - - public function form() - { - return - ''. - ''.__('You must have on Google API console:').'
'. - ''; - } - - public function save() - { - $key = empty($_POST['translater_google_proposal_key']) ? - '' : $_POST['translater_google_proposal_key']; - - $this->core->blog->settings->translater->put('translater_google_proposal_key',$key,'string','',true,true); - } - - public function translate($str,$from,$to) - { - try - { - $data = array( - 'key' => $this->key, - 'q' => $str, - 'source' => $from, - 'target' => $to - ); - - $path = ''; - $client = netHttp::initClient($this->api,$path); - $client->setUserAgent($this->agent); - $client->useGzip(false); - $client->setPersistReferers(false); - $client->get($path,$data); + private $api = 'https://www.googleapis.com/language/translate/v2'; + private $agent = 'dcTranslater - http://jcd.lv/?q=translater'; + private $key = null; //ex: AsSDqsGsfdSDSQFQsfedj9bnzY390aIg-1d - $rs = $client->getContent(); - - if ($client->getStatus() != 200) { - throw new Exception(__('Failed to query service.')); - } - - if (null === ($dec = json_decode($rs))) { - throw new Exception('Failed to decode result'); - } - - if ('' == @$dec->data->translations[0]->translatedText) { - throw new Exception('No data response'); - } - - return $dec->data->translations[0]->translatedText; - } - catch (Exception $e) {} - return ''; - } -} -?> \ No newline at end of file + protected function setup() + { + $this->key = $this->core->blog->settings->translater->translater_google_proposal_key; + + $this->setName(__('Google')); + $this->setDesc(__('Google Translation Tool API')); + $this->setActive(!empty($this->key)); + } + + public function form() + { + return + ''. + '' . __('You must have on Google API console:') . '
' . + ''.__('You must have:').'
'. - 'From $fromLanguage | To $toLanguage | "; - echo "
".$inputStr." | ".$translatedStr." |
' . __('You must have:') . '
' . + 'From $fromLanguage | To $toLanguage | "; + echo "
" . $inputStr . " | " . $translatedStr . " |
' . __('About') . ' | |
---|---|
' . __('Name') . ' | ' . $M->name . ' | +
' . __('Version') . ' | ' . $M->version . ' | +
' . __('Author') . ' | ' . $M->author . ' | +
' . __('Type') . ' | ' . $M->type . ' | +
' . __('Root') . ' | ' . $M->root . ' | +
' . __('Backups') . ' | ' . + $translater->getBackupFolder($module) . ' | +
'; - # Summary - echo ' -
'.__('About').' | |
---|---|
'.__('Name').' | '.$M->name.' | -
'.__('Version').' | '.$M->version.' | -
'.__('Author').' | '.$M->author.' | -
'.__('Type').' | '.$M->type.' | -
'.__('Root').' | '.$M->root.' | -
'.__('Backups').' | '. - $translater->getBackupFolder($module).' | -
'; + if (count($M->langs)) { + echo + '
' . __('Languages') . ' | ' . + '' . __('Code') . ' | ' . + '' . __('Backups') . ' | ' . + '' . __('Last backup') . ' | ' . + '||||
---|---|---|---|---|---|---|---|
' . + '' . $name . '' . + ' | ' . + '' . $lang . ' | '; + + if (isset($M->backups[$lang])) { + foreach($M->backups[$lang] AS $file => $info) { + $time[$lang] = isset($time[$lang]) && $time[$lang] > $info['time'] ? + $time[$lang] : $info['time']; + } + echo + '' . count($M->backups[$lang]) . ' | ' . + '' . + dt::str('%Y-%m-%d %H:%M', $time[$lang], $core->blog->settings->system->blog_timezone) . + ' | '; + } else { + echo '' . __('no backup') . ' | '; + } + echo '
'.__('Languages').' | '. - ''.__('Code').' | '. - ''.__('Backups').' | '. - ''.__('Last backup').' | '. - '||||
---|---|---|---|---|---|---|---|
'. - ''.$name.''. - ' | '. - ''.$lang.' | '; - - if (isset($M->backups[$lang])) - { - foreach($M->backups[$lang] AS $file => $info) - { - $time[$lang] = isset($time[$lang]) && $time[$lang] > $info['time'] ? - $time[$lang] : $info['time']; - } - echo - ''.count($M->backups[$lang]).' | '. - ''. - dt::str('%Y-%m-%d %H:%M',$time[$lang],$core->blog->settings->system->blog_timezone). - ' | '; - } - else - { - echo ''.__('no backup').' | '; - } - echo '
'; + } - # Edit lang - if (!empty($M->langs)) - { - echo ' -
'; - } + # New lang + if (!empty($M->unused_langs)) { + echo ' +
'; + } - # New lang - if (!empty($M->unused_langs)) - { - echo ' -
'; - } + # Delete lang + if (!empty($M->used_langs)) { + echo ' +
'; + } + echo '
'; - } - echo '
'; + } - if (!empty($M->used_langs)) - { - echo ' -
'; - } + if (!empty($M->backups)) { + echo + '
'; + } - if (!empty($M->backups)) - { - echo - '
'; - } + echo '
'; - # Import - echo ' -
'; + # Export + if (!empty($M->used_langs)) { + echo + '
'; + } + echo '
'; - } - echo '
' . sprintf(__('Nothing to configure for %s tool . '), $v->getName()) . '
' : + $form + ) . '
- '.form::field('translater_parse_userinfo',65,255,$translater->parse_userinfo).'
'.sprintf(__('Nothing to configure for %s tool.'),$v->getName()).'
' : - $form - ).''. - $core->formNonce(). - form::hidden(array('p'),'translater'). - form::hidden(array('part'),'setting'). - form::hidden(array('action'),'save_setting').' -
' . + $core->formNonce() . + form::hidden(array('p'), 'translater') . + form::hidden(array('part'), 'setting') . + form::hidden(array('action'), 'save_setting') . ' +
'. -''.__('Settings').' - '. -'translater - '.$core->plugins->moduleInfo('translater','version').' -
-'; -?> \ No newline at end of file +echo ' +'; \ No newline at end of file diff --git a/locales/fr/help/help.html b/locales/fr/help/translater.html similarity index 77% rename from locales/fr/help/help.html rename to locales/fr/help/translater.html index 643a622..6424d93 100644 --- a/locales/fr/help/help.html +++ b/locales/fr/help/translater.html @@ -1,24 +1,18 @@ - +Cet onglet permet d'ajouter, de supprimer ou d'étider des langues d'une extension. Il est possible de copier la traduction d'une langue à une autre lors de sa création. La supression d'une langue ne supprimera pas les éventuelles sauvegardes associées à cette langue.
-Si vous souhaitez plus d'aide ou apporter votre contribution à cette extension, voici quelques liens utiles.
+Si vous souhaitez plus d'aide ou apporter votre contribution à ce plugin, voici quelques liens utiles.
- + \ No newline at end of file diff --git a/locales/fr/main.lang.php b/locales/fr/main.lang.php index 5f75960..eab0d78 100644 --- a/locales/fr/main.lang.php +++ b/locales/fr/main.lang.php @@ -1,402 +1,420 @@ \ No newline at end of file diff --git a/locales/fr/main.po b/locales/fr/main.po index 5f6e1fa..b31dd9c 100644 --- a/locales/fr/main.po +++ b/locales/fr/main.po @@ -1,531 +1,556 @@ # Language: Français -# Module: translater - 2013.05.11 -# Date: 2013-05-12 23:35:00 -# Translated with translater 2013.05.11 +# Module: translater - 2018.02.14 +# Date: 2018-10-18 09:43:01 +# Translated with translater 2018.02.14 msgid "" msgstr "" "Content-Type: text/plain; charset=UTF-8\n" -"Project-Id-Version: translater 2013.05.11\n" +"Project-Id-Version: translater 2018.02.14\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2013-05-12T23:35:00+00:00\n" -"Last-Translator: Jean-Christian Denis\n" +"PO-Revision-Date: 2018-10-18T09:43:01+00:00\n" +"Last-Translator: brol\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: _admin.php:26 -#: index.php:537 -#: index.php:570 -#: index.php:1384 +#: _admin.php:25 +#: _admin.php:112 +#: index.php:536 +#: index.php:569 +#: index.php:1383 msgid "Translater" msgstr "Traducteur" -#: _admin.php:44 -msgid "Translate extensions" -msgstr "Traduire les extensions" +#: _admin.php:43 +msgid "Translate plugins" +msgstr "Traduire les plugins" -#: _admin.php:48 -#: index.php:670 -msgid "Name" -msgstr "Nom" - -#: _admin.php:62 +#: _admin.php:61 msgid "Translate this plugin" -msgstr "Traduire cette extension" +msgstr "Traduire ce plugin" -#: _admin.php:85 +#: _admin.php:84 msgid "Translate this theme" msgstr "Traduire ce thème" -#: inc/class.dc.translater.php:434 +#: _uninstall.php:20 +msgid "delete all settings" +msgstr "effacer tous les paramètres" + +#: _uninstall.php:27 +msgid "delete plugin files" +msgstr "effacer les fichiers du plugin" + +#: _uninstall.php:34 +msgid "delete the version number" +msgstr "effacer le n° de version" + +#: _uninstall.php:42 +msgid "delete all %s settings" +msgstr "effacer tous les paramètres de %s" + +#: _uninstall.php:49 +msgid "delete %s plugin files" +msgstr "effacer les fichiers du plugin %s" + +#: _uninstall.php:56 +msgid "delete %s version number" +msgstr "effacer la version de %s" + +#: inc/class.dc.translater.php:359 +msgid "Cannot find module %s" +msgstr "Impossible de trouver le module %s" + +#: inc/class.dc.translater.php:437 msgid "Cannot find backups folder for module %s" msgstr "Impossible de trouver le dossier de sauvegarde du module %s" -#: inc/class.dc.translater.php:450 +#: inc/class.dc.translater.php:453 msgid "Cannot find languages folder for module %s" msgstr "Impossible de trouver le dossier de langue du module %s" -#: inc/class.dc.translater.php:470 +#: inc/class.dc.translater.php:473 msgid "Cannot find root folder for module %s" msgstr "Impossible de trouver le dossier racine du module %s" -#: inc/class.dc.translater.php:499 +#: inc/class.dc.translater.php:502 msgid "Limit of %s backups for module %s exceed" msgstr "La limite de %s sauvegardes pour le module % est dépassée" -#: inc/class.dc.translater.php:561 -#: inc/class.dc.translater.php:951 -#: inc/class.dc.translater.php:1028 +#: inc/class.dc.translater.php:564 +#: inc/class.dc.translater.php:954 +#: inc/class.dc.translater.php:1031 msgid "Cannot find language folder %s for module %s" msgstr "Impossible de trouver le dossier de langue %s pour le module %s" -#: inc/class.dc.translater.php:616 +#: inc/class.dc.translater.php:619 msgid "Cannot delete backup file %s" msgstr "Impossible d'effacer le fichier de sauvegarde %s" -#: inc/class.dc.translater.php:634 +#: inc/class.dc.translater.php:637 msgid "Cannot find backup file %s" msgstr "Impossible de trouver le fichier de sauvegarde %s" -#: inc/class.dc.translater.php:660 +#: inc/class.dc.translater.php:663 msgid "Wrong export query" msgstr "Mauvaise requète d'exportation" -#: inc/class.dc.translater.php:671 +#: inc/class.dc.translater.php:674 msgid "Cannot use export mask %s" msgstr "Impossible d'utiliser le masque d'exportation %s" -#: inc/class.dc.translater.php:759 +#: inc/class.dc.translater.php:762 msgid "Wrong import query" msgstr "Mauvaise requète d'importation" -#: inc/class.dc.translater.php:808 +#: inc/class.dc.translater.php:811 msgid "Nothing to import for these modules in pack %s" msgstr "Rien à importer pour ces modules dans le paquetage %s" -#: inc/class.dc.translater.php:837 +#: inc/class.dc.translater.php:840 msgid "Zip file %s is not in translater format" msgstr "Le fichier zip n'est pas au format de translater" -#: inc/class.dc.translater.php:897 +#: inc/class.dc.translater.php:900 msgid "Language %s already exists for module %s" msgstr "La langue %s existe dèjà pour le module %s" -#: inc/class.dc.translater.php:908 +#: inc/class.dc.translater.php:911 msgid "Cannot copy file from language %s for module %s" msgstr "Impossible de copier le fichier depuis le langage %s pour le module %s" -#: inc/class.dc.translater.php:1000 +#: inc/class.dc.translater.php:1003 msgid "No string to write, language %s deleted for module %s" msgstr "Aucune chaine à écrire, la langue %s a été effacée pour le module %s" -#: inc/class.dc.translater.php:1264 +#: inc/class.dc.translater.php:1267 msgid "Cannot grant write acces on lang file %s" msgstr "Impossible d'avoir les droits en écriture sur le fichier de langue %s" -#: inc/class.dc.translater.php:1275 +#: inc/class.dc.translater.php:1278 msgid "Cannot write lang file %s" msgstr "Impossible d'écrire le fichier de langue %s" -#: inc/class.dc.translater.php:1579 +#: inc/class.dc.translater.php:1583 msgid "Cannot find language for code %s" msgstr "Impossible de trouver de langue pour le code %s" -#: inc/class.translater.rest.php:42 +#: inc/class.translater.rest.php:41 msgid "Missing params" msgstr "Paramètres manquants" -#: inc/class.translater.rest.php:51 +#: inc/class.translater.rest.php:50 msgid "Failed to get translation tool" msgstr "Impossible de trouver l'outil de traduction" -#: inc/class.translater.rest.php:55 +#: inc/class.translater.rest.php:54 msgid "Translation tool is not configured" msgstr "L'outil de traduction n'est pas configuré" -#: inc/lib.translater.google.php:44 +#: inc/lib.translater.google.php:43 msgid "You must have on Google API console:" msgstr "Vous devez avoir sur la console des API Google :" -#: inc/lib.translater.google.php:80 -msgid "Failed to query service." -msgstr "Impossible d'interoger le service." +#: inc/lib.translater.google.php:46 +msgid "Activate the \"translate API\" service" +msgstr "Activer le service \"translate API\"" -#: inc/lib.translater.microsoft.php:49 +#: inc/lib.translater.google.php:79 +msgid "Failed to query service." +msgstr "Impossible d'interroger le service." + +#: inc/lib.translater.microsoft.php:48 msgid "You must have:" msgstr "Vous devez avoir :" -#: index.php:26 -#: index.php:526 -#: index.php:1382 +#: index.php:25 +#: index.php:525 +#: index.php:1381 msgid "Settings" msgstr "Paramètres" -#: index.php:42 +#: index.php:27 +#: index.php:426 +#: index.php:462 +#: index.php:500 +#: index.php:571 +msgid "Themes" +msgstr "Thèmes" + +#: index.php:41 msgid "locales folders of each module" msgstr "le répertoire locales de chaque module" -#: index.php:43 +#: index.php:42 msgid "plugins folder root" -msgstr "le répertoire racine des extensions" +msgstr "le répertoire racine des plugins" -#: index.php:44 +#: index.php:43 msgid "public folder root" msgstr "le répertoire public du blog" -#: index.php:45 +#: index.php:44 msgid "cache folder of Dotclear" msgstr "le répertoire cache de Dotclear" -#: index.php:46 +#: index.php:45 msgid "locales folder of translater" -msgstr "le répertoire locales de l'extension translater" +msgstr "le répertoire locales du plugin translater" -#: index.php:51 +#: index.php:50 msgid "Translation successfully updated" msgstr "Traduction mise à jour avec succès" -#: index.php:52 +#: index.php:51 msgid "Translation successfully created" -msgstr "Traduction crée avec succès" +msgstr "Traduction créée avec succès" -#: index.php:53 +#: index.php:52 msgid "Translation successfully deleted" msgstr "Traduction effacée avec succès" -#: index.php:54 +#: index.php:53 msgid "Backups successfully create" -msgstr "Sauvegardes crées avec succès" +msgstr "Sauvegardes créées avec succès" -#: index.php:55 +#: index.php:54 msgid "Backups successfully restored" msgstr "Sauvegardes effectuées avec succès" -#: index.php:56 +#: index.php:55 msgid "Backups successfully deleted" msgstr "Sauvegardes effacées avec succès" -#: index.php:57 +#: index.php:56 msgid "Package successfully imported" msgstr "Paquetage importé avec succès" -#: index.php:58 +#: index.php:57 msgid "Package successfully exported" msgstr "Paquetage exporté avec succès" -#: index.php:62 +#: index.php:61 msgid "Failed to update settings: %s" msgstr "Impossible de mettre à jour les paramètres : %s" -#: index.php:63 +#: index.php:62 msgid "Failed to update translation: %s" msgstr "Impossible de mettre à jour la traduction : %s" -#: index.php:64 +#: index.php:63 msgid "Failed to create translation: %s" msgstr "Impossible de créer la traduction : %s" -#: index.php:65 +#: index.php:64 msgid "Failed to delete translation: %s" msgstr "Impossible d'effacer la traduction : %s" -#: index.php:66 +#: index.php:65 msgid "Failed to create backups: %s" msgstr "Impossible de créer les sauvegardes : %s" -#: index.php:67 +#: index.php:66 msgid "Failed to restore backups: %s" msgstr "Impossible de restaurer les sauvegardes : %s" -#: index.php:68 +#: index.php:67 msgid "Failed to delete backups: %s" msgstr "Impossible d'effacer les sauvegardes : %s" -#: index.php:69 +#: index.php:68 msgid "Failed to import package: %s" msgstr "Impossible d'importer le paquetage : %s" -#: index.php:70 +#: index.php:69 msgid "Failed to export package: %s" msgstr "Impossible d'exporter le paquetage : %s" -#: index.php:112 +#: index.php:111 msgid "No lang to create" msgstr "Pas de langue à créer" -#: index.php:134 +#: index.php:133 msgid "No lang to delete" msgstr "Pas de langue à effacer" -#: index.php:156 +#: index.php:155 msgid "No lang to backup" msgstr "Pas de langue à sauvegarder" -#: index.php:189 +#: index.php:188 msgid "No blackup to restore" msgstr "Pas de langue à restaurer" -#: index.php:208 +#: index.php:207 msgid "No bakcup to to restore" msgstr "Pas de sauvegarde à restaurer" -#: index.php:229 -#: index.php:247 +#: index.php:228 +#: index.php:246 msgid "No backup to delete" msgstr "Pas de sauvegarde à effacer" -#: index.php:290 -#: index.php:364 +#: index.php:289 +#: index.php:363 msgid "Nothing to export" msgstr "Rien à exporter" -#: index.php:312 +#: index.php:311 msgid "No language to update" msgstr "Pas de langue à mettre à jour" -#: index.php:443 -#: index.php:490 +#: index.php:442 +#: index.php:489 msgid "Failed to launch translater: %s" msgstr "Impossible de démarrer translater : %s" -#: index.php:556 +#: index.php:555 msgid "Use this %s translation:" msgstr "Utiliser la traduction de %s :" -#: index.php:557 +#: index.php:556 msgid "Translate this text with %s" msgstr "Traduire ce texte avec %s" -#: index.php:558 +#: index.php:557 msgid "Use this text" msgstr "Utiliser ce texte" -#: index.php:606 +#: index.php:605 msgid "Translate theme \"%s\" (by %s)" msgstr "Traduire le thème \"%s\" (de %s)" -#: index.php:607 +#: index.php:606 msgid "Translate plugin \"%s\" (by %s)" -msgstr "Traduire l'extension \"%s\" (de %s)" +msgstr "Traduire le plugin \"%s\" (de %s)" -#: index.php:627 -#: index.php:741 +#: index.php:626 +#: index.php:740 msgid "Edit translation" msgstr "Modifier la traduction" -#: index.php:639 +#: index.php:638 msgid "Id" msgstr "Id" -#: index.php:649 +#: index.php:648 msgid "There is no editable modules" msgstr "Il n'y a pas de modules modifiables." -#: index.php:665 +#: index.php:664 msgid "Summary" msgstr "Résumé" -#: index.php:666 +#: index.php:665 msgid "Module" msgstr "Module" -#: index.php:668 +#: index.php:667 msgid "About" msgstr "À propos" -#: index.php:678 +#: index.php:677 msgid "Root" msgstr "Racine" -#: index.php:680 -#: index.php:694 -#: index.php:811 -#: index.php:1342 +#: index.php:679 +#: index.php:693 +#: index.php:810 +#: index.php:1341 msgid "Backups" msgstr "Sauvegardes" -#: index.php:695 +#: index.php:694 msgid "Last backup" msgstr "Dernière sauvegarde" -#: index.php:722 +#: index.php:721 msgid "no backup" msgstr "Aucune sauvegarde" -#: index.php:731 -msgid "Translations" -msgstr "Traductions" - -#: index.php:737 +#: index.php:736 msgid "Edit language" msgstr "Modifier une langue" -#: index.php:757 +#: index.php:756 msgid "Add language" msgstr "Ajouter une langue" -#: index.php:764 +#: index.php:763 msgid "Copy from language:" msgstr "Copier depuis la langue :" -#: index.php:766 +#: index.php:765 msgid "Optionnal" msgstr "Optionnel" -#: index.php:773 +#: index.php:772 msgid "Add translation" msgstr "Ajouter la traduction" -#: index.php:790 +#: index.php:789 msgid "Delete language" msgstr "Effacer une langue" -#: index.php:794 +#: index.php:793 msgid "Delete translation" msgstr "Effacer la traduction" -#: index.php:816 +#: index.php:815 msgid "Create backups" msgstr "Créer une sauvegarde" -#: index.php:818 +#: index.php:817 msgid "Choose languages to backup" msgstr "Choisir la langue à sauvegarder" -#: index.php:839 -msgid "Backup" -msgstr "Sauvegarde" - -#: index.php:856 +#: index.php:855 msgid "List of backups" msgstr "Liste des sauvegardes" -#: index.php:860 -#: index.php:1066 +#: index.php:859 +#: index.php:1065 msgid "File" msgstr "Fichier" -#: index.php:863 -msgid "Size" -msgstr "Taille" - -#: index.php:887 +#: index.php:886 msgid "Selected backups action:" msgstr "Action sur les sauvegardes sélectionnées :" -#: index.php:889 +#: index.php:888 msgid "Restore backups" msgstr "Restaurer les sauvegardes" -#: index.php:890 +#: index.php:889 msgid "Delete backups" msgstr "Effacer les sauvegardes" -#: index.php:916 -#: index.php:1183 +#: index.php:915 +#: index.php:1182 msgid "Choose language package to import" msgstr "Choisir le paquetage de langue à importer" -#: index.php:938 -#: index.php:1240 +#: index.php:937 +#: index.php:1239 msgid "Choose languages to export" msgstr "Choisir les langues à exporter" -#: index.php:1059 +#: index.php:1058 msgid "Group" msgstr "Groupe" -#: index.php:1061 +#: index.php:1060 msgid "String" msgstr "Chaîne" -#: index.php:1063 -#: index.php:1284 +#: index.php:1062 +#: index.php:1283 msgid "Translation" msgstr "Traduction" -#: index.php:1064 +#: index.php:1063 msgid "Existing" msgstr "Existant" -#: index.php:1127 +#: index.php:1126 msgid "%s occurrences" msgstr "%s occurrences" -#: index.php:1153 +#: index.php:1152 msgid "Total of %s strings." msgstr "Total de %s chaînes." -#: index.php:1155 +#: index.php:1154 msgid "Change the group of the selected entries to:" msgstr "Changer le groupe des entrées sélectionnées vers :" -#: index.php:1212 +#: index.php:1211 msgid "Choose modules to export" msgstr "Choisir les modules à exporter" -#: index.php:1214 +#: index.php:1213 msgid "Modules" msgstr "Modules" -#: index.php:1287 +#: index.php:1286 msgid "Write .po files" -msgstr "Écrire les fichier .po" +msgstr "Écrire les fichiers .po" -#: index.php:1290 +#: index.php:1289 msgid "Write .lang.php files" -msgstr "Écrire les fichier .lang.php" +msgstr "Écrire les fichiers .lang.php" -#: index.php:1293 +#: index.php:1292 msgid "Translate also strings of template files" msgstr "Traduire également les chaînes des fichiers de template" -#: index.php:1296 +#: index.php:1295 msgid "Translate only unknow strings" msgstr "Traduire uniquement les chaînes inconnues" -#: index.php:1299 +#: index.php:1298 msgid "Hide default modules of Dotclear" msgstr "Cacher les modules d'origine de Dotclear" -#: index.php:1302 +#: index.php:1301 msgid "Write comments in files" msgstr "Écrire les commentaires dans les fichiers" -#: index.php:1305 +#: index.php:1304 msgid "Write informations about author in files" msgstr "Écrire les informations à propos de l'auteur dans les fichiers" -#: index.php:1309 +#: index.php:1308 msgid "Tools" msgstr "Outils" -#: index.php:1310 +#: index.php:1309 msgid "Default language of l10n source:" msgstr "Langue par défaut des sources l10n :" -#: index.php:1314 +#: index.php:1313 msgid "Select and configure the tool to use to translate strings:" msgstr "Sélectionner et configurer un outil de traduction :" -#: index.php:1326 +#: index.php:1325 msgid "Nothing to configure for %s tool." msgstr "Rien à configurer pour l'outil %s." -#: index.php:1337 +#: index.php:1336 msgid "Overwrite existing languages" msgstr "Écraser les langages existants" -#: index.php:1338 +#: index.php:1337 msgid "Name of exported package" msgstr "Nom du paquetage exporté" -#: index.php:1345 +#: index.php:1344 msgid "Make backups when changes are made" msgstr "Faire des sauvegardes lors des modifications" -#: index.php:1346 +#: index.php:1345 msgid "Limit backups to %s files per module" msgstr "Limiter les sauvegardes à %s fichiers par module" -#: index.php:1349 +#: index.php:1348 msgid "Store backups in %s" msgstr "Stocker les sauvegardes dans %s" -#: index.php:1354 +#: index.php:1353 msgid "Behaviors" msgstr "Comportements" -#: index.php:1355 +#: index.php:1354 msgid "Default start menu:" msgstr "Menu de départ par défaut :" -#: index.php:1360 +#: index.php:1359 msgid "Enable menu on extensions page" -msgstr "Activer le menu sur la page des extensions" +msgstr "Activer le menu sur la page des plugins" -#: index.php:1363 +#: index.php:1362 msgid "Enable menu on themes page" msgstr "Activer le menu sur la page des thèmes" @@ -533,5 +558,5 @@ msgid "translater" msgstr "Traducteur" msgid "Translate your Dotclear plugins and themes" -msgstr "Traduire vos extensions et thèmes pour Dotclear" +msgstr "Traduire vos plugins et thèmes pour Dotclear" diff --git a/locales/fr/resources.php b/locales/fr/resources.php index b0da71f..8dbafa9 100644 --- a/locales/fr/resources.php +++ b/locales/fr/resources.php @@ -10,7 +10,8 @@ # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html # -- END LICENSE BLOCK ------------------------------------ -if (!defined('DC_RC_PATH')) { return; } +if (!defined('DC_RC_PATH')) { + return; +} -$__resources['help']['translater'] = dirname(__FILE__).'/help/help.html'; -?> \ No newline at end of file +$__resources['help']['translater'] = dirname(__FILE__) . '/help/translater.html'; \ No newline at end of file