Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

534 lines (485 sloc) 18.755 kb
<?php /*
ocPortal
Copyright (c) ocProducts, 2004-2012
See text/EN/licence.txt for full licencing information.
*/
if (!function_exists('_do_lang'))
{
/**
* Get the human-readable form of a language id, or a language entry from a language INI file.
*
* @param ID_TEXT The language id
* @param ?mixed The first token [string or tempcode] (replaces {1}) (NULL: none)
* @param ?mixed The second token [string or tempcode] (replaces {2}) (NULL: none)
* @param ?mixed The third token (replaces {3}). May be an array of [of string], to allow any number of additional args (NULL: none)
* @param ?LANGUAGE_NAME The language to use (NULL: users language)
* @param boolean Whether to cause ocPortal to exit if the lookup does not succeed
* @return ?mixed The human-readable content (NULL: not found). String normally. Tempcode if tempcode parameters.
*/
function _do_lang($codename,$token1=NULL,$token2=NULL,$token3=NULL,$lang=NULL,$require_result=true)
{
$pos=strpos($codename,':');
if ($pos!==false)
{
require_lang(substr($codename,0,$pos));
$codename=substr($codename,$pos+1);
}
global $LANGUAGE,$USER_LANG_CACHED,$RECORD_LANG_STRINGS,$XSS_DETECT,$PAGE_CACHE_FILE,$PAGE_CACHE_LANG_LOADED;
if ($RECORD_LANG_STRINGS)
{
global $RECORDED_LANG_STRINGS;
$RECORDED_LANG_STRINGS[$codename]=1;
}
if ($lang===NULL)
{
$lang=($USER_LANG_CACHED===NULL)?user_lang():$USER_LANG_CACHED;
}// else // This else assumes we initially load all language files in the users language. Reasonable. EDIT: Actually, no it is not - the user_lang() initially is not accurate until ocPortal gets past a certain startup position
{
if ((!isset($LANGUAGE[$lang][$codename])) && ((!array_key_exists($lang,$LANGUAGE)) || (!array_key_exists($codename,$LANGUAGE[$lang]))))
{
global $PAGE_CACHE_LAZY_LOAD,$PAGE_CACHE_LANGS_REQUESTED,$LANG_REQUESTED_LANG;
if ($PAGE_CACHE_LAZY_LOAD)
{
$PAGE_CACHE_LAZY_LOAD=false; // We can't be lazy any more, but we will keep growing our pool so hopefully CAN be lazy the next time
foreach ($PAGE_CACHE_LANGS_REQUESTED as $request)
{
list($that_codename,$that_lang)=$request;
unset($LANG_REQUESTED_LANG[$that_lang][$that_codename]);
require_lang($that_codename,$that_lang);
}
$ret=_do_lang($codename,$token1,$token2,$token3,$lang,$require_result);
if ($ret===NULL)
{
$PAGE_CACHE_LANG_LOADED[$lang][$codename]=NULL;
if ($GLOBALS['MEM_CACHE']!==NULL)
{
persistant_cache_set($PAGE_CACHE_FILE,$PAGE_CACHE_LANG_LOADED);
} else
{
@rewind($PAGE_CACHE_FILE);
@ftruncate($PAGE_CACHE_FILE,0);
@fwrite($PAGE_CACHE_FILE,serialize($PAGE_CACHE_LANG_LOADED));
}
}
return $ret;
}
require_all_open_lang_files($lang);
}
}
if ($lang=='xxx') return 'xxx'; // Helpful for testing language compliancy. We don't expect to see non x's if we're running this language
if ((!isset($LANGUAGE[$lang][$codename])) && ((!array_key_exists($lang,$LANGUAGE)) || (!array_key_exists($codename,$LANGUAGE[$lang]))))
{
if ($lang!=fallback_lang())
{
$ret=do_lang($codename,$token1,$token2,$token3,fallback_lang(),$require_result);
if ($codename=='charset')
{
switch (strtolower($lang))
{
case 'ar':
case 'bg':
case 'zh-CN':
case 'zh-TW':
case 'hr':
case 'cs':
case 'da':
case 'nl':
case 'fi':
case 'fr':
case 'de':
case 'el':
case 'hi':
case 'it':
case 'ja':
case 'ko':
case 'pl':
case 'pt':
case 'ro':
case 'ru':
case 'es':
case 'sv':
$ret='utf-8';
break;
}
} elseif (substr($codename,0,3)=='FC_')
{
$ret=ocp_mb_substr(trim(do_lang(substr($codename,3),$token1,$token2,$token3,$lang)),0,1);
} elseif ($codename=='locale')
{
$ret=strtolower($lang).'_'.strtoupper($lang);
} else
{
$ret2=(strtolower($codename)!=$codename)?google_translate($ret,$lang):$ret;
if ($ret2!=$ret)
{
$ret=$ret2;
}
}
if ($PAGE_CACHE_FILE!==NULL)
{
if ((!isset($PAGE_CACHE_LANG_LOADED[$lang][$codename])) && (isset($PAGE_CACHE_LANG_LOADED[fallback_lang()][$codename])))
{
$PAGE_CACHE_LANG_LOADED[$lang][$codename]=$ret; // Will have been cached into fallback_lang() from the nested do_lang call, we need to copy it into our cache bucket for this language
if ($GLOBALS['MEM_CACHE']!==NULL)
{
persistant_cache_set($PAGE_CACHE_FILE,$PAGE_CACHE_LANG_LOADED);
} else
{
@rewind($PAGE_CACHE_FILE);
@ftruncate($PAGE_CACHE_FILE,0);
@fwrite($PAGE_CACHE_FILE,serialize($PAGE_CACHE_LANG_LOADED));
}
}
}
return $ret;
} else
{
if ($require_result)
{
global $USER_LANG_LOOP,$REQUIRE_LANG_LOOP;
//print_r(debug_backtrace());
if ($USER_LANG_LOOP==1) critical_error('RELAY','Missing language code: '.escape_html($codename).'. This language code is required to produce error messages, and thus a critical error was prompted by the non-ability to show less-critical error messages. It is likely the source language files (lang/'.fallback_lang().'/*.ini) for ocPortal on this website have been corrupted.');
if ($REQUIRE_LANG_LOOP>=2) return ''; // Probably failing to load global.ini, so just output with some text missing
require_code('view_modes');
erase_cached_language();
fatal_exit(do_lang_tempcode('MISSING_LANG_ENTRY',escape_html($codename)));
} else return NULL;
}
}
if ($PAGE_CACHE_FILE!==NULL)
{
if (!isset($PAGE_CACHE_LANG_LOADED[$lang][$codename]))
{
$PAGE_CACHE_LANG_LOADED[$lang][$codename]=$LANGUAGE[$lang][$codename];
if ($GLOBALS['MEM_CACHE']!==NULL)
{
persistant_cache_set($PAGE_CACHE_FILE,$PAGE_CACHE_LANG_LOADED);
} else
{
@rewind($PAGE_CACHE_FILE);
@ftruncate($PAGE_CACHE_FILE,0);
@fwrite($PAGE_CACHE_FILE,serialize($PAGE_CACHE_LANG_LOADED));
}
}
}
// Put in parameters
static $non_plural_non_vowel=array('1','b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z');
$looked_up=$LANGUAGE[$lang][$codename];
if ($looked_up===NULL) return NULL; // Learning cache pool has told us this string definitely does not exist
$out=str_replace('\n',"\n",$looked_up);
$plural_or_vowel_check=strpos($out,'|')!==false;
if ($XSS_DETECT) ocp_mark_as_escaped($out);
if ($token1!==NULL)
{
if (((is_object($token1)) && ($token2===NULL)) || (($token2!==NULL) && (is_object($token2)))) // Tempcode only supported in first two
{
$bits=preg_split('#\{\d[^\}]*\}#',$out,2,PREG_SPLIT_OFFSET_CAPTURE);
$ret=new ocp_tempcode();
foreach ($bits as $bit)
{
if ($XSS_DETECT) ocp_mark_as_escaped($bit[0]);
$at=$bit[1];
if ($at!=0)
{
if ($out[$at-2]=='1') $ret->attach($token1);
elseif ($out[$at-2]=='2') $ret->attach($token2);
elseif (($plural_or_vowel_check) && (substr($out[$at-2],0,2)=='1|'))
{
$exploded=explode('|',$out[$at-2]);
$_token=$token1->evaluate();
$_token_denum=str_replace(',','',$_token);
$ret->attach((in_array(is_numeric($_token_denum)?$_token_denum:strtolower(substr($_token,0,1)),$non_plural_non_vowel))?$exploded[1]:$exploded[2]);
}
elseif (($plural_or_vowel_check) && (substr($out[$at-2],0,2)=='2|'))
{
$exploded=explode('|',$out[$at-2]);
$_token=$token2->evaluate();
$_token_denum=str_replace(',','',$_token);
$ret->attach((in_array(is_numeric($_token_denum)?$_token_denum:strtolower(substr($_token,0,1)),$non_plural_non_vowel))?$exploded[1]:$exploded[2]);
}
}
$ret->attach($bit[0]);
}
return $ret;
} elseif ($token1!==NULL)
{
$out=str_replace('{1}',$token1,$out);
if ($plural_or_vowel_check)
{
$_token_denum=str_replace(',','',$token1);
$out=preg_replace('#\{1\|(.*)\|(.*)\}#U',(in_array(is_numeric($_token_denum)?$_token_denum:strtolower(substr($token1,0,1)),$non_plural_non_vowel))?'\\1':'\\2',$out);
}
if (($XSS_DETECT) && (ocp_is_escaped($token1))) ocp_mark_as_escaped($out);
}
if ($token2!==NULL)
{
if ($XSS_DETECT) $escaped=ocp_is_escaped($out);
$out=str_replace('{2}',$token2,$out);
if ($plural_or_vowel_check)
{
$_token_denum=str_replace(',','',$token1);
$out=preg_replace('#\{2\|(.*)\|(.*)\}#U',(in_array(is_numeric($_token_denum)?$_token_denum:strtolower(substr($token2,0,1)),$non_plural_non_vowel))?'\\1':'\\2',$out);
}
if (($XSS_DETECT) && (ocp_is_escaped($token2)) && ($escaped)) ocp_mark_as_escaped($out);
if ($token3!==NULL)
{
$i=3;
if (!is_array($token3)) $token3=array($token3);
foreach ($token3 as $token)
{
if ($XSS_DETECT) $escaped=ocp_is_escaped($out);
$out=str_replace('{'.strval($i).'}',$token,$out);
if ($plural_or_vowel_check)
{
$_token_denum=str_replace(',','',$token);
$out=preg_replace('#\{'.strval($i).'\|(.*)\|(.*)\}#U',(in_array(is_numeric($_token_denum)?$_token_denum:strtolower(substr($token,0,1)),$non_plural_non_vowel))?'\\1':'\\2',$out);
}
if (($XSS_DETECT) && (ocp_is_escaped($token)) && ($escaped)) ocp_mark_as_escaped($out);
$i++;
}
}
}
}
return $out;
}
}
if (!function_exists('get_translated_text'))
{
/**
* Try to return the human-readable version of the language id, passed in as $entry.
*
* @param integer The id
* @param ?object The database connection to use (NULL: standard site connection)
* @param ?LANGUAGE_NAME The language (NULL: uses the current language)
* @return string The human-readable version
*/
function get_translated_text($entry,$connection=NULL,$lang=NULL)
{
if ($entry==0) return do_lang('FAILED_ENTRY');
if ($entry===NULL) fatal_exit(do_lang_tempcode('NULL_LANG_STRING'));
if ($connection===NULL) $connection=$GLOBALS['SITE_DB'];
global $RECORD_LANG_STRINGS_CONTENT;
if ($RECORD_LANG_STRINGS_CONTENT)
{
global $RECORDED_LANG_STRINGS_CONTENT;
$RECORDED_LANG_STRINGS_CONTENT[$entry]=($connection->connection_write!=$GLOBALS['SITE_DB']->connection_write);
}
if ($lang===NULL) $lang=user_lang();
if ((array_key_exists($entry,$connection->text_lookup_original_cache)) && ($lang==user_lang()))
{
return $connection->text_lookup_original_cache[$entry];
}
if ($lang=='xxx') return '!!!'; // Helpful for testing language compliancy. We don't expect to see non x's/!'s if we're running this language
$result=$connection->query_select('translate',array('text_original','text_parsed'),array('id'=>$entry,'language'=>$lang),'',1);
if (!array_key_exists(0,$result))
{
$result=$connection->query_select('translate',array('*'),array('id'=>$entry,'language'=>get_site_default_lang()),'',1);
if (!array_key_exists(0,$result))
{
$result=$connection->query_select('translate',array('*'),array('id'=>$entry),'',1);
}
if (array_key_exists(0,$result))
{
$result[0]['text_original']=google_translate($result[0]['text_original'],$lang);
$result[0]['text_parsed']='';
$connection->query_insert('translate',array('broken'=>1,'language'=>$lang)+$result[0]);
}
}
if (!array_key_exists(0,$result))
{
$member_id=function_exists('get_member')?get_member():$GLOBALS['FORUM_DRIVER']->get_guest_id();
$connection->query_insert('translate',array('id'=>$entry,'source_user'=>$member_id,'broken'=>0,'importance_level'=>3,'text_original'=>'','text_parsed'=>'','language'=>$lang));
$msg=do_lang('LANGUAGE_CORRUPTION',strval($entry));
if (preg_match('#^localhost[\.\:$]#',ocp_srv('HTTP_HOST'))!=0) fatal_exit($msg);
require_code('site');
attach_message(make_string_tempcode($msg),'warn');
return '';
}
if ($lang==user_lang())
{
$connection->text_lookup_original_cache[$entry]=$result[0]['text_original'];
$connection->text_lookup_cache[$entry]=$result[0]['text_parsed'];
}
return $result[0]['text_original'];
}
}
/**
* Convert a language string into another language string.
*
* @param mixed The string to convert
* @param LONG_TEXT The language to convert to
* @return LONG_TEXT The converted string
*/
function google_translate($str_in, $lang)
{
$tempcode=is_object($str_in);
$GLOBALS['NO_QUERY_LIMIT']=true;
if (get_option('enable_google_translate',true)!=='1') return $str_in;
if ($tempcode) $str_in=$str_in->evaluate();
global $DOING_TRANSLATE;
if (!isset($DOING_TRANSLATE)) $DOING_TRANSLATE=false;
if ($DOING_TRANSLATE) return $tempcode?protect_from_escaping($str_in):$str_in; // Don't want loops
if ($str_in=='') return $tempcode?protect_from_escaping(escape_html('')):escape_html('');
if (strpos($str_in,'gtranslate_cache')!==false) return $tempcode?protect_from_escaping($str_in):$str_in; // Stop loops about corrupt/missing database tables
$language_list = array( 'ar'=>'Arabic', 'bg'=>'Bulgarian', 'zh-cn'=>'Simplified Chinese', 'zh-tw'=>'Traditional Chinese', 'hr'=>'Croatian', 'cs'=>'Czech', 'da'=>'Danish', 'nl'=>'Dutch', 'en'=>'English', 'fi'=>'Finnish', 'fr'=>'French', 'de'=>'German', 'el'=>'Greek', 'hi'=>'Hindi', 'it'=>'Italian', 'ja'=>'Japanese', 'ko'=>'Korean', 'pl'=>'Polish', 'pt'=>'Portuguese', 'ro'=>'Romanian', 'ru'=>'Russian', 'es'=>'Spanish', 'sv'=>'Swedish');
$lang=strtolower($lang);
if (!array_key_exists($lang,$language_list)) return $tempcode?protect_from_escaping($str_in):$str_in;
$DOING_TRANSLATE=true;
require_lang('lang');
$chache = check_google_cache($str_in, $lang);
if(count($chache) == 0)
{
require_code('GTranslate');
$translate = new GTranslate();
$num_matches=array();
$matches=array();
$rep=array();
$prepped = $str_in;
$j=0;
foreach (array(array('[',']'),array('{','}')) as $symbol)
{
$_matches=array();
$_num_matches=preg_match_all('#['.preg_quote($symbol[0]).'][^'.preg_quote($symbol[0]).preg_quote($symbol[1]).']*['.preg_quote($symbol[1]).']#',$str_in,$_matches);
$matches[$symbol[0]]=$_matches;
$num_matches[$symbol[0]]=$_num_matches;
for ($i=0;$i<$_num_matches;$i++)
{
$from=$_matches[0][$i];
$to='<span class="notranslate">'.strval($j).'</span>';
$rep['!'.strval($j)]=$from; // The '!' bit is because we can't trust indexing in PHP arrays if it is numeric
$pos=0;
do
{
$pos=strpos($prepped,$from,$pos);
if ($pos!==false)
{
$pos_open=strrpos(substr($prepped,0,$pos),'<');
$pos_close=strrpos(substr($prepped,0,$pos),'>');
if (($pos_open===false) || (($pos_close!==false) && ($pos_close>$pos_open)))
{
$prepped=substr($prepped,0,$pos).$to.substr($prepped,$pos+strlen($from));
$pos+=strlen($to);
} else
{
$pos_title=strrpos(substr($prepped,0,$pos),'title="');
$pos_alt=strrpos(substr($prepped,0,$pos),'alt="');
$pos_quote=strrpos(substr($prepped,0,$pos),'"');
if ((($pos_alt!==false) && ($pos_alt>$pos_open) && ($pos_quote==$pos_alt+4)) || (($pos_title!==false) && ($pos_title>$pos_open) && ($pos_quote==$pos_title+6)))
{
$to2=' conv'.strval($j).' ';
$prepped=substr($prepped,0,$pos).$to2.substr($prepped,$pos+strlen($from));
$pos+=strlen($to2);
} else
{
$pos+=strlen($from);
}
}
}
}
while ($pos!==false);
$j++;
}
}
if (strpos(preg_replace('#<[^>]*>#','',$prepped),'{')!==false)
{
$DOING_TRANSLATE=false;
return $tempcode?protect_from_escaping($str_in):$str_in; // Cannot translate as it has very complex Tempcode in it
}
$to = $language_list[$lang];
$from_lang=strtolower(get_site_default_lang());
try
{
$convertedstring = $translate->Text($prepped)->From(array_key_exists($from_lang,$language_list)?$language_list[$from_lang]:'English')->To($to);
}
catch (Exception $e)
{
}
if ($convertedstring===NULL) $convertedstring=$str_in;
do
{
$before=$convertedstring;
$convertedstring=preg_replace('#(<span class="notranslate">\d+) (.*</span>)#','${1}</span> <span class="notranslate">${2}',$convertedstring);
}
while ($before!=$convertedstring);
foreach (array_reverse($rep) as $_j=>$from)
{
$j=intval(substr($_j,1));
$convertedstring=preg_replace('#\s*<span class="notranslate">\s*'.preg_quote(strval($j)).'\s*</span>\s*#',$from,$convertedstring);
$convertedstring=preg_replace('# conv'.preg_quote(strval($j)).'\s*#',$from,$convertedstring);
}
$convertedstring=str_replace('<html> ','',$convertedstring);
$convertedstring=str_replace('&#39;','',$convertedstring);
save_google_cache($str_in, $lang, $convertedstring);
$str = $convertedstring;
} else
{
$str = $chache['t_result'];
}
$DOING_TRANSLATE=false;
if ((function_exists('ocp_mark_as_escaped')) && (ocp_is_escaped($str_in))) ocp_mark_as_escaped($str);
return $tempcode?protect_from_escaping($str):$str;
}
/**
* Check google cache.
*
* @param STRING The string TO CONVERT
* @param STRING The lANGUAGE STRING
* @return ARRAY array of data
*/
function check_google_cache($str, $lang)
{
if (!$GLOBALS['SITE_DB']->table_exists('gtranslate_cache'))
{
$GLOBALS['SITE_DB']->create_table('gtranslate_cache',
array('id'=>'*AUTO','language'=>'LANGUAGE_NAME','stringtoconvert'=>'LONG_TEXT','t_result'=>'LONG_TEXT','create_time'=>'TIME'),true
);
}
$where=array('stringtoconvert'=>$str, 'language'=>$lang);
$_result=$GLOBALS['SITE_DB']->query_select('gtranslate_cache',array('*'),$where,'',1);
if(count($_result)==1)
{
$data = $_result[0];
} else
{
$data = array();
}
return $data;
}
/**
* Save successful google response of gtranslate table.
*
* @param STRING The string TO CONVERT
* @param STRING The lANGUAGE STRING
* @param STRING result of request
* @return BINARY If success return true
*/
function save_google_cache($str, $lang, $result)
{
$time = time();
$GLOBALS['SITE_DB']->query_insert('gtranslate_cache',array('language'=>$lang,'stringtoconvert'=>$str,'t_result'=>$result,'create_time'=>$time));
return true;
}
if (!function_exists('get_site_default_lang'))
{
/**
* Get the site's default language, with support for URL overrides.
*
* @return LANGUAGE_NAME The site's default language
*/
function get_site_default_lang()
{
// Site default then
global $SITE_INFO;
if (!array_key_exists('default_lang',$SITE_INFO)) // We must be installing
{
global $IN_MINIKERNEL_VERSION;
if ($IN_MINIKERNEL_VERSION==1)
{
if (array_key_exists('lang',$_POST)) return $_POST['lang'];
if (array_key_exists('lang',$_GET)) return $_GET['lang'];
}
return fallback_lang();
}
return $SITE_INFO['default_lang'];
}
}
Jump to Line
Something went wrong with that request. Please try again.