2001-01-11 10:52:33 +01:00
< ? php
/************************************************************************** \
2001-01-13 11:18:50 +01:00
* phpGroupWare API - Translation class for SQL *
* This file written by Joseph Engo < jengo @ phpgroupware . org > *
* and Dan Kuykendall < seek3r @ phpgroupware . org > *
2003-08-28 16:31:11 +02:00
* Handles multi - language support use SQL tables *
2001-01-13 11:18:50 +01:00
* Copyright ( C ) 2000 , 2001 Joseph Engo *
* -------------------------------------------------------------------------*
2001-01-16 14:52:32 +01:00
* This library is part of the phpGroupWare API *
* http :// www . phpgroupware . org / api *
* ------------------------------------------------------------------------ *
2001-01-13 11:18:50 +01:00
* This library is free software ; you can redistribute it and / or modify it *
* under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation ; either version 2.1 of the License , *
* or any later version . *
* This library is distributed in the hope that it will be useful , but *
* WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . *
* See the GNU Lesser General Public License for more details . *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library ; if not , write to the Free Software Foundation , *
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA *
2001-01-11 10:52:33 +01:00
\ **************************************************************************/
/* $Id$ */
2003-10-04 15:24:34 +02:00
// define the maximal length of a message_id, all message_ids have to be unique
2003-04-02 19:46:37 +02:00
// in this length, our column is varchar 255, but addslashes might add some length
2003-10-04 15:24:34 +02:00
if ( ! defined ( 'MAX_MESSAGE_ID_LENGTH' ))
{
define ( 'MAX_MESSAGE_ID_LENGTH' , 230 );
}
2003-10-05 12:44:16 +02:00
// some constanst for pre php4.3
if ( ! defined ( 'PHP_SHLIB_SUFFIX' ))
{
define ( 'PHP_SHLIB_SUFFIX' , strtoupper ( substr ( PHP_OS , 0 , 3 )) == 'WIN' ? 'dll' : 'so' );
}
if ( ! defined ( 'PHP_SHLIB_PREFIX' ))
{
define ( 'PHP_SHLIB_PREFIX' , PHP_SHLIB_SUFFIX == 'dll' ? 'php_' : '' );
}
2003-10-04 15:24:34 +02:00
2001-06-15 23:29:33 +02:00
class translation
{
2003-09-14 12:20:46 +02:00
var $userlang = 'en' ;
var $loaded_apps = array ();
2003-10-05 12:44:16 +02:00
function translation ( $warnings = False )
2003-10-04 15:24:34 +02:00
{
$this -> db = is_object ( $GLOBALS [ 'phpgw' ] -> db ) ? $GLOBALS [ 'phpgw' ] -> db : $GLOBALS [ 'phpgw_setup' ] -> db ;
2003-10-05 04:06:11 +02:00
if ( ! isset ( $GLOBALS [ 'phpgw_setup' ]))
{
$this -> system_charset = $GLOBALS [ 'phpgw_info' ][ 'server' ][ 'system_charset' ];
}
else
{
$this -> db -> query ( " SELECT config_value FROM phpgw_config WHERE config_app='phpgwapi' AND config_name='system_charset' " , __LINE__ , __FILE__ );
if ( $this -> db -> next_record ())
{
$this -> system_charset = $this -> db -> f ( 0 );
}
}
2003-10-05 12:44:16 +02:00
// load multi-byte-string-extension if needed, and set its internal encodeing to your system_charset
if ( $this -> system_charset && substr ( $this -> system_charset , 0 , 3 ) != 'iso' )
{
2003-10-05 12:57:50 +02:00
if ( $this -> mbstring = extension_loaded ( 'mbstring' ) || @ dl ( PHP_SHLIB_PREFIX . 'mbstring.' . PHP_SHLIB_SUFFIX ))
2003-10-05 12:44:16 +02:00
{
ini_set ( 'mbstring.internal_encoding' , $this -> system_charset );
if ( ini_get ( 'mbstring.func_overload' ) < 4 )
{
if ( $warnings ) echo " <p>Warning: Please set <b>mbstring.func_overload = 4</b> in your php.ini for useing <b> $this->system_charset </b> as your charset !!!</p> \n " ;
}
}
else
{
if ( $warnings ) echo " <p>Warning: Please get and/or enable the <b>mbstring extension</b> in your php.ini for useing <b> $this->system_charset </b> as your charset !!!</p> \n " ;
}
}
2003-10-05 04:06:11 +02:00
}
/*
@ function charset
2003-10-05 12:44:16 +02:00
@ abstract returns the charset to use ( ! $lang ) or the charset of the lang - files or $lang
2003-10-05 04:06:11 +02:00
*/
function charset ( $lang = False )
{
if ( $lang )
{
2003-10-05 12:44:16 +02:00
if ( ! isset ( $this -> charsets [ $lang ]))
{
$this -> db -> query ( " SELECT content FROM phpgw_lang WHERE lang=' $lang ' AND message_id='charset' AND app_name='common' " , __LINE__ , __FILE__ );
$this -> charsets [ $lang ] = $this -> db -> next_record () ? $this -> db -> f ( 0 ) : 'iso-8859-1' ;
}
return $this -> charsets [ $lang ];
2003-10-05 04:06:11 +02:00
}
2003-10-05 12:44:16 +02:00
return $this -> system_charset ? $this -> system_charset : $this -> translate ( 'charset' );
2003-10-04 15:24:34 +02:00
}
2003-09-14 12:20:46 +02:00
function init ()
{
// post-nuke and php-nuke are using $GLOBALS['lang'] too
// but not as array!
// this produces very strange results
if ( ! is_array ( $GLOBALS [ 'lang' ]))
{
$GLOBALS [ 'lang' ] = array ();
}
if ( $GLOBALS [ 'phpgw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'lang' ])
{
$this -> userlang = $GLOBALS [ 'phpgw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'lang' ];
}
$this -> add_app ( 'common' );
2003-09-23 23:26:58 +02:00
if ( ! count ( $GLOBALS [ 'lang' ]))
{
$this -> userlang = 'en' ;
$this -> add_app ( 'common' );
}
2003-09-14 12:20:46 +02:00
$this -> add_app ( $GLOBALS [ 'phpgw_info' ][ 'flags' ][ 'currentapp' ]);
}
2003-10-04 15:24:34 +02:00
/*!
@ function translate
@ abstract translates a phrase and evtl . substitute some variables
@ returns the translation
*/
2003-09-14 12:20:46 +02:00
function translate ( $key , $vars = false )
2002-02-20 05:44:19 +01:00
{
2003-08-28 16:31:11 +02:00
if ( ! $vars )
2002-10-19 00:53:12 +02:00
{
2003-08-28 16:31:11 +02:00
$vars = array ();
2002-02-17 19:43:31 +01:00
}
2003-09-14 12:20:46 +02:00
if ( ! is_array ( $GLOBALS [ 'lang' ]) || ! count ( $GLOBALS [ 'lang' ]))
2001-06-15 23:29:33 +02:00
{
2003-09-14 12:20:46 +02:00
$this -> init ();
2001-06-15 23:29:33 +02:00
}
2003-08-28 16:31:11 +02:00
$ret = $key . '*' ; // save key if we dont find a translation
2003-09-14 12:20:46 +02:00
2003-08-28 16:31:11 +02:00
$key = strtolower ( trim ( substr ( $key , 0 , MAX_MESSAGE_ID_LENGTH )));
2002-02-20 05:30:19 +01:00
2003-08-28 16:31:11 +02:00
if ( isset ( $GLOBALS [ 'lang' ][ $key ]))
2002-02-20 05:44:19 +01:00
{
2003-08-28 16:31:11 +02:00
$ret = $GLOBALS [ 'lang' ][ $key ];
2002-02-20 05:44:19 +01:00
}
2001-06-15 23:29:33 +02:00
$ndx = 1 ;
2003-09-14 12:20:46 +02:00
foreach ( $vars as $val )
2001-06-15 23:29:33 +02:00
{
$ret = preg_replace ( " /% $ndx / " , $val , $ret );
++ $ndx ;
}
return $ret ;
}
2003-10-04 15:24:34 +02:00
/*!
@ function add_app
@ abstract adds translations for an application from the database to the lang - array
@ syntax add_app ( $app , $lang = False )
@ param $app name of the application to add ( or 'common' for the general translations )
@ param $lang 2 - char code of the language to use or False if the users language should be used
*/
2003-09-15 10:42:47 +02:00
function add_app ( $app , $lang = False )
2001-06-15 23:29:33 +02:00
{
2003-09-15 10:42:47 +02:00
$lang = $lang ? $lang : $this -> userlang ;
if ( ! isset ( $this -> loaded_apps [ $app ]) || $this -> loaded_apps [ $app ] != $lang )
2003-08-28 16:31:11 +02:00
{
2003-09-15 10:42:47 +02:00
$sql = " select message_id,content from phpgw_lang where lang=' " . $lang . " ' and app_name=' " . $app . " ' " ;
2003-10-04 15:24:34 +02:00
$this -> db -> query ( $sql , __LINE__ , __FILE__ );
while ( $this -> db -> next_record ())
2003-09-14 12:20:46 +02:00
{
2003-10-04 15:24:34 +02:00
$GLOBALS [ 'lang' ][ strtolower ( $this -> db -> f ( 'message_id' ))] = $this -> db -> f ( 'content' );
2003-09-14 12:20:46 +02:00
}
2003-09-15 10:42:47 +02:00
$this -> loaded_apps [ $app ] = $lang ;
2001-06-15 23:29:33 +02:00
}
}
2003-09-14 12:20:46 +02:00
2003-10-04 15:24:34 +02:00
/*!
@ function get_installed_langs
@ abstract returns a list of installed langs
@ returns array with 2 - character lang - code as key and descriptiv lang - name as data
*/
2003-04-02 19:46:37 +02:00
function get_installed_langs ()
{
2003-09-14 12:20:46 +02:00
if ( ! is_array ( $this -> langs ))
2003-04-02 19:46:37 +02:00
{
2003-10-04 15:24:34 +02:00
$this -> db -> query ( " SELECT DISTINCT l.lang,ln.lang_name FROM phpgw_lang l,phpgw_languages ln WHERE l.lang = ln.lang_id " , __LINE__ , __FILE__ );
if ( ! $this -> db -> num_rows ())
2003-09-14 12:20:46 +02:00
{
return False ;
}
2003-10-04 15:24:34 +02:00
while ( $this -> db -> next_record ())
2003-09-14 12:20:46 +02:00
{
2003-10-04 15:24:34 +02:00
$this -> langs [ $this -> db -> f ( 'lang' )] = $this -> db -> f ( 'lang_name' );
2003-09-14 12:20:46 +02:00
}
2003-04-02 19:46:37 +02:00
}
2003-09-14 12:20:46 +02:00
return $this -> langs ;
2003-04-02 19:46:37 +02:00
}
2003-10-04 15:24:34 +02:00
/*!
@ function get_installed_charsets
@ abstract returns a list of installed charsets
@ returns array with charset as key and comma - separated list of langs useing the charset as data
*/
function get_installed_charsets ()
{
if ( ! is_array ( $this -> charsets ))
{
$this -> db -> query ( " SELECT DISTINCT l.lang,ln.lang_name,l.content AS charset FROM phpgw_lang l,phpgw_languages ln WHERE l.lang = ln.lang_id AND l.message_id='charset' " , __LINE__ , __FILE__ );
if ( ! $this -> db -> num_rows ())
{
return False ;
}
while ( $this -> db -> next_record ())
{
$data = & $this -> charsets [ $charset = $this -> db -> f ( 'charset' )];
$data .= ( $data ? ', ' : $charset . ': ' ) .
$this -> db -> f ( 'lang_name' ) . ' (' . $this -> db -> f ( 'lang' ) . ')' ;
}
}
return $this -> charsets ;
}
2003-10-05 04:06:11 +02:00
/*!
@ function convert
@ abstract converts a string $data from charset $from to charset $to
2003-10-05 12:44:16 +02:00
@
2003-10-05 04:06:11 +02:00
*/
2003-10-05 12:44:16 +02:00
function convert ( $data , $from = 'iso-8859-1' , $to = 'utf-8' )
2003-10-05 04:06:11 +02:00
{
2003-10-05 12:44:16 +02:00
if ( $from == $to )
{
return $data ;
}
if ( $from == 'iso-8859-1' && $to == 'utf-8' )
2003-10-05 04:06:11 +02:00
{
return utf8_encode ( $data );
}
2003-10-05 12:44:16 +02:00
if ( $to == 'iso-8859-1' && $from == 'utf-8' )
2003-10-05 04:06:11 +02:00
{
return utf8_decode ( $data );
}
2003-10-05 12:44:16 +02:00
if ( $this -> mbstring )
{
return mb_convert_encoding ( $data , $to , $from );
}
die ( " <p>Can't convert from charset ' $from ' to ' $to ' without the <b>mbstring extension</b> !!!</p> " );
2003-10-05 04:06:11 +02:00
}
2003-10-04 15:24:34 +02:00
/*!
@ function install_langs
@ abstract installs translations for the selected langs into the database
@ syntax install_langs ( $langs , $upgrademethod = 'dumpold' )
@ param $langs array of langs to install ( as data NOT keys ( ! ))
@ param $upgrademethod 'dumpold' ( recommended & fastest ), 'addonlynew' languages , 'addmissing' phrases
*/
2003-10-05 04:06:11 +02:00
function install_langs ( $langs , $upgrademethod = 'dumpold' , $only_app = False )
2003-10-04 15:24:34 +02:00
{
@ set_time_limit ( 0 ); // we might need some time
if ( ! isset ( $GLOBALS [ 'phpgw_info' ][ 'server' ]) && $upgrademethod != 'dumpold' )
{
$this -> db -> query ( " select * from phpgw_config WHERE config_app='phpgwapi' AND config_name='lang_ctimes' " , __LINE__ , __FILE__ );
if ( $this -> db -> next_record ())
{
$GLOBALS [ 'phpgw_info' ][ 'server' ][ 'lang_ctimes' ] = unserialize ( stripslashes ( $this -> db -> f ( 'config_value' )));
}
}
if ( ! is_array ( $langs ) || ! count ( $langs ))
{
return ;
}
$this -> db -> transaction_begin ();
if ( $upgrademethod == 'dumpold' )
{
// dont delete the custom main- & loginscreen messages every time
$this -> db -> query ( " DELETE FROM phpgw_lang where app_name != 'mainscreen' AND app_name != 'loginscreen' " , __LINE__ , __FILE__ );
//echo '<br>Test: dumpold';
$GLOBALS [ 'phpgw_info' ][ 'server' ][ 'lang_ctimes' ] = array ();
}
foreach ( $langs as $lang )
{
//echo '<br>Working on: ' . $lang;
$addlang = False ;
if ( $upgrademethod == 'addonlynew' )
{
//echo "<br>Test: addonlynew - select count(*) from phpgw_lang where lang='".$lang."'";
$this -> db -> query ( " SELECT COUNT(*) FROM phpgw_lang WHERE lang=' " . $lang . " ' " , __LINE__ , __FILE__ );
$this -> db -> next_record ();
if ( $this -> db -> f ( 0 ) == 0 )
{
//echo '<br>Test: addonlynew - True';
$addlang = True ;
}
}
if (( $addlang && $upgrademethod == 'addonlynew' ) || ( $upgrademethod != 'addonlynew' ))
{
//echo '<br>Test: loop above file()';
if ( ! is_object ( $GLOBALS [ 'phpgw_setup' ]))
{
$GLOBALS [ 'phpgw_setup' ] = CreateObject ( 'phpgwapi.setup' );
$GLOBALS [ 'phpgw_setup' ] -> db = $this -> db ;
}
$setup_info = $GLOBALS [ 'phpgw_setup' ] -> detection -> get_versions ();
$setup_info = $GLOBALS [ 'phpgw_setup' ] -> detection -> get_db_versions ( $setup_info );
$raw = array ();
2003-10-05 04:06:11 +02:00
$apps = $only_app ? array ( $only_app ) : array_keys ( $setup_info );
2003-10-04 15:24:34 +02:00
// Visit each app/setup dir, look for a phpgw_lang file
2003-10-05 04:06:11 +02:00
foreach ( $apps as $app )
2003-10-04 15:24:34 +02:00
{
2003-10-05 04:06:11 +02:00
$appfile = PHPGW_SERVER_ROOT . SEP . $app . SEP . 'setup' . SEP . 'phpgw_' . strtolower ( $lang ) . '.lang' ;
2003-10-04 15:24:34 +02:00
//echo '<br>Checking in: ' . $app['name'];
2003-10-05 04:06:11 +02:00
if ( $GLOBALS [ 'phpgw_setup' ] -> app_registered ( $app ) && file_exists ( $appfile ))
2003-10-04 15:24:34 +02:00
{
//echo '<br>Including: ' . $appfile;
$lines = file ( $appfile );
foreach ( $lines as $line )
{
list ( $message_id , $app_name ,, $content ) = explode ( " \t " , $line );
$message_id = $this -> db -> db_addslashes ( substr ( strtolower ( chop ( $message_id )), 0 , MAX_MESSAGE_ID_LENGTH ));
$app_name = $this -> db -> db_addslashes ( chop ( $app_name ));
$content = $this -> db -> db_addslashes ( chop ( $content ));
$raw [ $app_name ][ $message_id ] = $content ;
}
$GLOBALS [ 'phpgw_info' ][ 'server' ][ 'lang_ctimes' ][ $lang ][ $app [ 'name' ]] = filectime ( $appfile );
}
}
2003-10-05 04:06:11 +02:00
$charset = @ $raw [ 'common' ][ 'charset' ] ? $raw [ 'common' ][ 'charset' ] : $this -> charset ( $lang );
//echo "<p>lang='$lang', charset='$charset', system_charset='$this->system_charset')</p>\n";
2003-10-04 15:24:34 +02:00
foreach ( $raw as $app_name => $ids )
{
foreach ( $ids as $message_id => $content )
{
2003-10-05 04:06:11 +02:00
if ( $this -> system_charset && $charset && $charset != $this -> system_charset )
{
$content = $this -> convert ( $content , $charset , $this -> system_charset );
}
2003-10-04 15:24:34 +02:00
$addit = False ;
//echo '<br>APPNAME:' . $app_name . ' PHRASE:' . $message_id;
if ( $upgrademethod == 'addmissing' )
{
//echo '<br>Test: addmissing';
$this -> db -> query ( " SELECT COUNT(*) FROM phpgw_lang WHERE message_id=' $message_id ' AND lang=' $lang ' AND (app_name=' $app_name ' OR app_name='common') AND content=' $content ' " , __LINE__ , __FILE__ );
$this -> db -> next_record ();
if ( $this -> db -> f ( 0 ) == 0 )
{
//echo '<br>Test: addmissing - True - Total: ' . $this->db->f(0);
$addit = True ;
}
}
if ( $addit || $upgrademethod == 'addonlynew' || $upgrademethod == 'dumpold' )
{
if ( $message_id && $content )
{
//echo "<br>adding - insert into phpgw_lang values ('$message_id','$app_name','$lang','$content')";
$result = $this -> db -> query ( " INSERT INTO phpgw_lang (message_id,app_name,lang,content) VALUES(' $message_id ',' $app_name ',' $lang ',' $content ') " , __LINE__ , __FILE__ );
if ( intval ( $result ) <= 0 )
{
echo " <br>Error inserting record: phpgw_lang values (' $message_id ',' $app_name ',' $lang ',' $content ') " ;
}
}
}
}
}
}
}
$this -> db -> transaction_commit ();
// update the ctimes of the installed langsfiles for the autoloading of the lang-files
//
$this -> db -> query ( " DELETE from phpgw_config WHERE config_app='phpgwapi' AND config_name='lang_ctimes' " , __LINE__ , __FILE__ );
$this -> db -> query ( $query = " INSERT INTO phpgw_config(config_app,config_name,config_value) VALUES ('phpgwapi','lang_ctimes',' " .
addslashes ( serialize ( $GLOBALS [ 'phpgw_info' ][ 'server' ][ 'lang_ctimes' ])) . " ') " , __LINE__ , __FILE__ );
}
/*!
@ function autolaod_changed_langfiles
@ abstract re - loads all ( ! ) langfiles if one langfile for the an app and the language of the user has changed
*/
function autoload_changed_langfiles ()
{
//echo "<h1>check_langs()</h1>\n";
if ( $GLOBALS [ 'phpgw_info' ][ 'server' ][ 'lang_ctimes' ] && ! is_array ( $GLOBALS [ 'phpgw_info' ][ 'server' ][ 'lang_ctimes' ]))
{
$GLOBALS [ 'phpgw_info' ][ 'server' ][ 'lang_ctimes' ] = unserialize ( $GLOBALS [ 'phpgw_info' ][ 'server' ][ 'lang_ctimes' ]);
}
//_debug_array($GLOBALS['phpgw_info']['server']['lang_ctimes']);
$lang = $GLOBALS [ 'phpgw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'lang' ];
$apps = $GLOBALS [ 'phpgw_info' ][ 'user' ][ 'apps' ];
$apps [ 'phpgwapi' ] = True ; // check the api too
foreach ( $apps as $app => $data )
{
$fname = PHPGW_SERVER_ROOT . " / $app /setup/phpgw_ $lang .lang " ;
if ( file_exists ( $fname ))
{
$ctime = filectime ( $fname );
$ltime = intval ( $GLOBALS [ 'phpgw_info' ][ 'server' ][ 'lang_ctimes' ][ $lang ][ $app ]);
//echo "checking lang='$lang', app='$app', ctime='$ctime', ltime='$ltime'<br>\n";
if ( $ctime != $ltime )
{
// update all langs
$this -> install_langs ( array_keys ( $this -> get_installed_langs ()));
break ;
}
}
}
}
2003-10-05 04:06:11 +02:00
/* Following functions are called for app (un)install */
/*!
@ function get_langs
@ abstract return array of installed languages , e . g . array ( 'de' , 'en' )
*/
function get_langs ( $DEBUG = False )
{
if ( $DEBUG )
{
echo '<br>get_langs(): checking db...' . " \n " ;
}
2003-10-05 12:57:50 +02:00
if ( ! $this -> langs )
{
$this -> get_installed_langs ();
}
return $this -> langs ? array_keys ( $this -> langs ) : array ();
2003-10-05 04:06:11 +02:00
}
/*!
@ function drop_langs
@ abstract delete all lang entries for an application , return True if langs were found
@ param $appname app_name whose translations you want to delete
*/
function drop_langs ( $appname , $DEBUG = False )
{
if ( $DEBUG )
{
echo '<br>drop_langs(): Working on: ' . $appname ;
}
$this -> db -> query ( " SELECT COUNT(message_id) FROM phpgw_lang WHERE app_name=' $appname ' " , __LINE__ , __FILE__ );
$this -> db -> next_record ();
if ( $this -> db -> f ( 0 ))
{
$this -> db -> query ( " DELETE FROM phpgw_lang WHERE app_name=' $appname ' " , __LINE__ , __FILE__ );
return True ;
}
return False ;
}
/*!
@ function add_langs
@ abstract process an application ' s lang files , calling get_langs () to see what langs the admin installed already
@ param $appname app_name of application to process
*/
function add_langs ( $appname , $DEBUG = False , $force_langs = False )
{
$langs = $this -> get_langs ( $DEBUG );
if ( is_array ( $force_langs ))
{
foreach ( $force_langs as $lang )
{
if ( ! in_array ( $lang , $langs ))
{
$langs [] = $lang ;
}
}
}
if ( $DEBUG )
{
echo '<br>add_langs(): chose these langs: ' ;
_debug_array ( $langs );
}
$this -> install_langs ( $langs , 'addmissing' , $appname );
}
2001-06-15 23:29:33 +02:00
}