diff --git a/etemplate/inc/class.bolangfile.inc.php b/etemplate/inc/class.bolangfile.inc.php new file mode 100644 index 0000000000..12a42850be --- /dev/null +++ b/etemplate/inc/class.bolangfile.inc.php @@ -0,0 +1,243 @@ + + * @author Ralf Becker + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @package etemplate + * @subpackage translationtools + * @version $Id$ + */ + +class bolangfile +{ + var $total; + var $debug = False; + /** + * storage object + * + * @var solangfile + */ + var $so; + var $loaded_apps = array(); + var $source_langarray = ''; + var $missing_langarray = ''; + var $target_langarray = ''; + var $extra_langarray = array(); + var $src_file; + var $src_apps = array(); + var $tgt_file; + var $tgt_lang; + + function __construct() + { + $this->so = new solangfile(); // is now in etemplate, to not doublicate it + } + + /* Sessions used to save state and not reread the langfile between adding/deleting phrases */ + function save_sessiondata($source='##unset##',$target='##unset##') + { + if ($source == '##unset##') + { + $source = &$this->source_langarray; + } + if ($target == '##unset##') + { + $target = &$this->target_langarray; + } + if($this->debug) { echo '
Save:'; _debug_array($source); } + $GLOBALS['egw']->session->appsession('developer_source_lang','developer_tools',$source); + if($this->debug) { echo '
Save:'; _debug_array($target); } + $GLOBALS['egw']->session->appsession('developer_target_lang','developer_tools',$target); + $GLOBALS['egw']->session->appsession('developer_source_file','developer_tools',$this->src_file); + $GLOBALS['egw']->session->appsession('developer_target_file','developer_tools',$this->tgt_file); + $GLOBALS['egw']->session->appsession('developer_t_lang','developer_tools',$this->tgt_lang); + $GLOBALS['egw']->session->appsession('developer_loaded_apps','developer_tools',$this->loaded_apps); + $GLOBALS['egw']->session->appsession('developer_src_apps','developer_tools',$this->src_apps); + $GLOBALS['egw']->session->appsession('developer_missing_lang','developer_tools',$this->missing_langarray); + } + + function read_sessiondata() + { + $source = $GLOBALS['egw']->session->appsession('developer_source_lang','developer_tools'); + if($this->debug) { echo '
Read:'; _debug_array($source); } + + $target = $GLOBALS['egw']->session->appsession('developer_target_lang','developer_tools'); + if($this->debug) { echo '
Read:'; _debug_array($target); } + + $src_file = $GLOBALS['egw']->session->appsession('developer_source_file','developer_tools'); + $tgt_file = $GLOBALS['egw']->session->appsession('developer_target_file','developer_tools'); + $tgt_lang = $GLOBALS['egw']->session->appsession('developer_t_lang','developer_tools'); + $loaded_apps = $GLOBALS['egw']->session->appsession('developer_loaded_apps','developer_tools'); + $src_apps = $GLOBALS['egw']->session->appsession('developer_src_apps','developer_tools'); + $missing = $GLOBALS['egw']->session->appsession('developer_missing_lang','developer_tools'); + + $this->set_sessiondata($source,$target,$src_file,$tgt_file,$tgt_lang,$loaded_apps,$src_apps,$missing); + } + + function set_sessiondata($source,$target,$src_file,$tgt_file,$tgt_lang,$loaded_apps,$src_apps,$missing) + { + $this->source_langarray = $source; + $this->target_langarray = $target; + $this->src_file = $src_file; + $this->tgt_file = $tgt_file; + $this->tgt_lang = $tgt_lang; + $this->loaded_apps = $loaded_apps; + $this->src_apps = $src_apps; + $this->missing_langarray = $missing; + } + + function clear_sessiondata() + { + $GLOBALS['egw']->session->appsession('developer_source_lang','developer_tools',''); + $GLOBALS['egw']->session->appsession('developer_target_lang','developer_tools',''); + $GLOBALS['egw']->session->appsession('developer_source_file','developer_tools',''); + $GLOBALS['egw']->session->appsession('developer_target_file','developer_tools',''); + $GLOBALS['egw']->session->appsession('developer_t_lang','developer_tools',''); + $GLOBALS['egw']->session->appsession('developer_loaded_apps','developer_tools',''); + } + + function addphrase($entry) + { + /* _debug_array($this->source_langarray);exit; */ + if (empty($entry['content'])) $entry['content'] = $entry['message_id']; + + $mess_id = strtolower(trim($entry['message_id'])); + $this->source_langarray[$mess_id] = array( + 'message_id' => $mess_id, + 'content' => $entry['content'], + 'app_name' => $entry['app_name'] == 'phpgwapi' ? 'common' : $entry['app_name'], + 'lang' => 'en' + ); + @ksort($this->source_langarray); + + if (!empty($entry['target'])) + { + $this->target_langarray[$mess_id] = array( + 'message_id' => $mess_id, + 'content' => $entry['target'], + 'app_name' => $entry['app_name'] == 'phpgwapi' ? 'common' : $entry['app_name'], + 'lang' => $this->tgt_lang + ); + } + } + + function movephrase($mess='') + { + if ($mess !='' && ($this->missing_langarray[$mess]['message_id'])) + { + $this->source_langarray[$mess] = $m = array( + 'message_id' => $this->missing_langarray[$mess]['message_id'], + 'content' => $this->missing_langarray[$mess]['content'], + 'app_name' => $this->missing_langarray[$mess]['app_name'], + 'lang' => 'en' + ); + @ksort($this->source_langarray); + reset($this->source_langarray); + + if ($this->tgt_lang == 'en') + { + $this->target_langarray[$mess] = $m; + + @ksort($this->target_langarray); + reset($this->target_langarray); + } + } + //else echo "'$mess' not found in missing_langarray !!!
\n"; + } + + function missing_app($app,$userlang='en') + { + $this->missing_langarray = array(); + + if (!is_array($this->extra_langarray['common'])) + { + $this->extra_langarray['common'] = $this->so->load_app('phpgwapi',$userlang); + } + $plist = $this->so->missing_app($app = trim($app),$userlang); + + foreach($plist as $p => $loc) + { + $_mess_id = strtolower(trim($p)); + if ($loc != $app) + { + if (!is_array($this->extra_langarray[$loc])) + { + $this->extra_langarray[$loc] = $this->so->load_app($loc,$userlang); + //echo "

loading translations for '$loc'

\n"; + } + } + if (!empty($_mess_id) && !$this->source_langarray[$_mess_id] && + !$this->extra_langarray['common'][$_mess_id] && + ($app == $loc || !$this->extra_langarray[$loc][$_mess_id])) + { + //echo "Havn't found '$_mess_id'/$loc !!!
\n"; + $this->missing_langarray[$_mess_id] = array( + 'message_id' => $_mess_id, + 'app_name' => $loc, + 'content' => $p + ); + } + } + if (is_array($this->missing_langarray)) + { + reset ($this->missing_langarray); + @ksort($this->missing_langarray); + } + return $this->missing_langarray; + } + + function add_app($app,$userlang='en') + { + if(gettype($this->source_langarray) == 'array') + { + return $this->source_langarray; + } + $this->source_langarray = $this->so->load_app($app,$userlang,False); + $this->src_file = $this->so->src_file; + $this->loaded_apps = $this->so->loaded_apps; + $this->src_apps = $this->so->src_apps; + return $this->source_langarray; + } + + function load_app($app,$userlang='en') + { + if(gettype($this->target_langarray) == 'array') + { + if ($this->tgt_lang == $userlang) + { + return $this->target_langarray; + } + } + $this->target_langarray = $this->so->load_app($app,$userlang); + $this->tgt_file = $this->so->tgt_file; + $this->tgt_lang = $userlang; + $this->loaded_apps = $this->so->loaded_apps; + return $this->target_langarray; + } + + function write_file($which,$app_name,$userlang) + { + switch ($which) + { + case 'source': + $this->src_file = $this->so->write_file($app_name,$this->source_langarray,$userlang,$which); + break; + case 'target': + // removing phrases not in the source language + $before = count($this->target_langarray); + $this->target_langarray = array_intersect_assoc($this->target_langarray,$this->source_langarray); + if ($before > ($after = count($this->target_langarray))) + { + echo '
'. lang('Removed %1 phrases from the target language, as they are not present in the source language!',$before-$after)."\n"; + } + $this->tgt_file = $this->so->write_file($app_name,$this->target_langarray,$userlang,$which); + break; + default: + break; + } + $this->save_sessiondata(); + } +} diff --git a/etemplate/inc/class.solangfile.inc.php b/etemplate/inc/class.solangfile.inc.php index 99eb049f66..c6a51220df 100644 --- a/etemplate/inc/class.solangfile.inc.php +++ b/etemplate/inc/class.solangfile.inc.php @@ -6,7 +6,8 @@ * @author Miles Lott * @author Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @package translationtools + * @package etemplate + * @subpackage translationtools * @version $Id$ */ diff --git a/etemplate/inc/class.uilangfile.inc.php b/etemplate/inc/class.uilangfile.inc.php new file mode 100644 index 0000000000..5126600d09 --- /dev/null +++ b/etemplate/inc/class.uilangfile.inc.php @@ -0,0 +1,642 @@ + + * @author Ralf Becker + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @package etemplate + * @subpackage translationtools + * @version $Id$ + */ + +class uilangfile +{ + var $helpme; + var $public_functions = array( + 'index' => True, + 'edit' => True, + 'create' => True, + 'addphrase' => True, + 'missingphrase'=> True, + 'missingphrase2'=> True, + 'download' => True + ); + /** + * business object + * + * @var bolangfile + */ + var $bo; + /** + * Reference to global Template object + * + * @var Template + */ + var $template; + /** + * nextmatchs object + * + * @var nextmatches + */ + var $nextmatchs; + + function __construct() + { + $this->template = $GLOBALS['egw']->template; + $this->template->egroupware_hack = False; // else the phrases got translated + $this->bo = new bolangfile(); + $this->nextmatchs = new nextmatchs(); + translation::add_app('developer_tools'); + translation::add_app('common'); + egw_framework::csp_script_src_attrs('unsafe-inline'); + } + + function addphrase() + { + $app_name = get_var('app_name',array('POST','GET')); + $sourcelang = get_var('sourcelang',array('POST','GET')); + $targetlang = get_var('targetlang',array('POST','GET')); + $entry = $_POST['entry']; + + $this->bo->read_sessiondata(); + if($_POST['add'] || $_POST['cancel'] || $_POST['more']) + { + if($_POST['add'] || $_POST['more']) + { + if (get_magic_quotes_gpc()) + { + foreach(array('message_id','content','target') as $name) + { + $entry[$name] = stripslashes($entry[$name]); + } + } + $this->bo->addphrase($entry); + if ($sourcelang == $targetlang) + { + $this->bo->target_langarray = $this->bo->source_langarray; + } + $this->bo->save_sessiondata(); + } + if (!$_POST['more']) + { + $GLOBALS['egw']->redirect_link('/index.php',array( + 'menuaction' => 'etemplate.uilangfile.edit', + 'app_name' => $app_name, + 'sourcelang' => $sourcelang, + 'targetlang' => $targetlang + )); + } + } + $GLOBALS['egw_info']['flags']['app_header'] = $GLOBALS['egw_info']['apps'][$GLOBALS['egw_info']['flags']['currentapp']]['title']. + ' - '.lang('Add new phrase'); + + common::egw_header(); + echo parse_navbar(); + + $this->template->set_var('form_action',$GLOBALS['egw']->link('/index.php','menuaction=etemplate.uilangfile.addphrase')); + $this->template->set_var('sourcelang',$sourcelang); + $this->template->set_var('targetlang',$targetlang); + $this->template->set_var('app_name',$app_name); + + $this->template->set_file(array('form' => 'addphrase.tpl')); + $this->template->set_var('message_id_field',''); + if ($app_name == 'api') $app_name = 'common'; + $this->template->set_var('app_field',$this->lang_option($app_name,isset($entry)?$entry['app_name']:$app_name,'entry[app_name]')); + $this->template->set_var('translation_field',''); + $this->template->set_var('target_field',''); + + $this->template->set_var('lang_message_id',lang('message_id in English')); + $this->template->set_var('lang_app',lang('Application')); + $this->template->set_var('lang_translation',lang('Phrase in English (or empty if identical)')); + $this->template->set_var('lang_target',lang('Translation of phrase')); + $this->template->set_var('lang_add',lang('Add')); + $this->template->set_var('lang_more',lang('Add more')); + $this->template->set_var('lang_cancel',lang('Cancel')); + + $this->template->pfp('phpgw_body','form'); + } + + function missingphrase() + { + $app_name = get_var('app_name',array('POST','GET')); + $sourcelang = get_var('sourcelang',array('POST','GET')); + $targetlang = get_var('targetlang',array('POST','GET')); + + $this->bo->read_sessiondata(); + $this->bo->missing_app($app_name,$sourcelang); + $this->bo->save_sessiondata(); + + // we have to redirect here, as solangfile defines function sidebox_menu, which clashes with the iDots func. + // + $GLOBALS['egw']->redirect_link('/index.php',array( + 'menuaction' => 'etemplate.uilangfile.missingphrase2', + 'app_name' => $app_name, + 'sourcelang' => $sourcelang, + 'targetlang' => $targetlang + )); + } + + function missingphrase2() + { + $app_name = get_var('app_name',array('POST','GET')); + $sourcelang = get_var('sourcelang',array('POST','GET')); + $targetlang = get_var('targetlang',array('POST','GET')); + $newlang = $_POST['newlang']; + $dlsource = $_POST['dlsource']; + $writesource = $_POST['writesource']; + $dltarget = $_POST['dltarget']; + $writetarget = $_POST['writetarget']; + $update = $_POST['update']; + $entry = $_POST['entry']; + $submit = $_POST['submit']; + $this->bo->read_sessiondata(); + + $this->template->set_file(array('langfile' => 'langmissing.tpl')); + $this->template->set_block('langfile','header','header'); + $this->template->set_block('langfile','postheader','postheader'); + $this->template->set_block('langfile','detail','detail'); + $this->template->set_block('langfile','prefooter','prefooter'); + $this->template->set_block('langfile','footer','footer'); + if(!$sourcelang) + { + $sourcelang = 'en'; + } + if(!$targetlang) + { + $targetlang = 'en'; + } + $missingarray = $this->bo->missing_langarray; + //echo "missingarray=
"; print_r($this->bo->missing_langarray); echo "
\n"; + if ($update) + { + $deleteme = $_POST['delete']; + //echo "deleteme=
"; print_r($deleteme); echo "
\n"; + + while (list($_mess,$_checked) = @each($deleteme)) + { + if($_checked == 'on') + { + $_mess = $this->recode_id($_mess); + $this->bo->movephrase($_mess); + /* _debug_array($missingarray[$_mess]); */ + unset($missingarray[$_mess]); + /* _debug_array($missingarray[$_mess]); */ + } + } + unset($deleteme); + + $this->bo->save_sessiondata(); + $GLOBALS['egw']->redirect_link('/index.php',array( + 'menuaction' => 'etemplate.uilangfile.edit', + 'app_name' => $app_name, + 'sourcelang' => $sourcelang, + 'targetlang' => $targetlang + )); + } + common::egw_header(); + echo parse_navbar(); + + $this->template->set_var('lang_remove',lang('Add phrase')); + $this->template->set_var('lang_application',lang('Application')); + $this->template->set_var('lang_update',lang('Add')); + $this->template->set_var('lang_view',lang('Cancel')); + + $this->template->set_var('action_url',$GLOBALS['egw']->link('/index.php','menuaction=etemplate.uilangfile.missingphrase2')); + $this->template->set_var('sourcelang',$sourcelang); + $this->template->set_var('targetlang',$targetlang); + $this->template->set_var('app_name',$app_name); + $this->template->set_var('app_title',$GLOBALS['egw_info']['apps'][$app_name]['title']); + $this->template->pfp('out','header'); + if($sourcelang && $targetlang) + { + $this->template->set_var('lang_appname',lang('Application')); + $this->template->set_var('lang_message',lang('Message')); + $this->template->set_var('lang_original',lang('Original')); + $this->template->set_var('view_link', + $GLOBALS['egw']->link( + '/index.php', + 'menuaction=etemplate.uilangfile.edit&app_name='.$app_name.'&sourcelang=' . $sourcelang . '&targetlang=' . $targetlang + ) + ); + $this->template->pfp('out','postheader'); + while(list($key,$data) = @each($missingarray)) + { + $mess_id = $this->encode_id($key); + $this->template->set_var('mess_id',$mess_id); + $this->template->set_var('source_content',html::htmlspecialchars($data['content'])); + $this->template->set_var('transapp',$this->lang_option($app_name,$data['app_name'],"transapp[$mess_id]")); + $this->template->set_var('tr_class',$this->nextmatchs->alternate_row_color('',true)); + $this->template->pfp('out','detail'); + } + $this->template->pfp('out','prefooter'); + $this->template->pfp('out','footer'); + } + /* _debug_array($this->bo->loaded_apps); */ + $this->bo->save_sessiondata(); + } + + function edit() + { + if ($_POST['cancel']) + { + $GLOBALS['egw']->redirect_link('/index.php','menuaction=etemplate.uilangfile.index'); + } + $app_name = get_var('app_name',array('POST','GET')); + $sourcelang = get_var('sourcelang',array('POST','GET')); + $targetlang = get_var('targetlang',array('POST','GET')); + $entry = $_POST['entry']; + + if($_POST['addphrase'] || $_POST['missingphrase']) + { + $GLOBALS['egw']->redirect_link('/index.php',array( + 'menuaction' => 'etemplate.uilangfile.'.($_POST['addphrase']?'addphrase':'missingphrase'), + 'app_name' => $app_name, + 'sourcelang' => $sourcelang, + 'targetlang' => $targetlang + )); + } + if ($_POST['revert']) + { + $this->bo->clear_sessiondata(); + } + $this->bo->read_sessiondata(); + + if($_POST['dlsource']) + { + $this->download('source',$sourcelang); + } + if($_POST['dltarget']) + { + $this->download('target',$targetlang); + } + $GLOBALS['egw_info']['flags']['css'] .= ".untranslated { background-color: #dab0b0; }\n"; + common::egw_header(); + echo parse_navbar(); + + $this->template->set_file(array('langfile' => 'langfile.tpl')); + $this->template->set_block('langfile','header','header'); + $this->template->set_block('langfile','postheader','postheader'); + $this->template->set_block('langfile','detail','detail'); + $this->template->set_block('langfile','detail_long','detail_long'); + $this->template->set_block('langfile','footer','footer'); + + $this->template->set_var('action_url',$GLOBALS['egw']->link('/index.php','menuaction=etemplate.uilangfile.edit')); + $this->template->set_var('lang_remove',lang('Remove')); + $this->template->set_var('lang_application',lang('Application')); + $this->template->set_var('lang_source',lang('Source Language')); + $this->template->set_var('lang_target',lang('Target Language')); + $this->template->set_var('lang_submit',lang('Load')); + $this->template->set_var('lang_update',lang('Save')); + $this->template->set_var('lang_revert',lang('Revert')); + $this->template->set_var('lang_cancel',lang('Cancel')); + $this->template->set_var('lang_step',lang('Step')); + $help = 'onMouseOver="self.status=\'%s\'; return true;" onMouseOut="self.status=\'\'; return true;"'; + $this->template->set_var('cancel_help',sprintf($help,str_replace("'","\\'",lang('Returns to the application list, not saved changes get lost !!!')))); + $this->template->set_var('load_help',sprintf($help,str_replace("'","\\'",lang('Loads the selected lang-files, to be modified in the next steps')))); + $this->template->set_var('update_help',sprintf($help,str_replace("'","\\'",lang('Saves the added/changed translations to an internal buffer, to be used in further steps')))); + $this->template->set_var('search_help',sprintf($help,str_replace("'","\\'",lang('Searches the source-code for phrases not in the actual source-lang-file')))); + $this->template->set_var('add_help',sprintf($help,str_replace("'","\\'",lang('Allows you to add a single phrase')))); + $this->template->set_var('revert_help',sprintf($help,str_replace("'","\\'",lang('Clears the internal buffer, all changes made sofar are lost')))); + $this->template->set_var('download_help',sprintf($help,str_replace("'","\\'",lang('Download the lang-file to be saved in the apps setup-dir')))); + $this->template->set_var('write_help',sprintf($help,str_replace("'","\\'",lang('Write the lang-file to the apps setup-dir')))); + + if(!$sourcelang) + { + $sourcelang = 'en'; + } + if(!$targetlang) + { + $targetlang = $GLOBALS['egw_info']['user']['preferences']['common']['lang']; + } + + foreach(translation::list_langs() as $lang_id => $lang_name) + { + $sourcelangs .= '