diff options
| author | lsces <lester@lsces.co.uk> | 2025-08-27 15:01:45 +0100 |
|---|---|---|
| committer | lsces <lester@lsces.co.uk> | 2025-08-27 15:01:45 +0100 |
| commit | 6e24ce632d3bfaf09bf6aaffe2055fb1d485c17e (patch) | |
| tree | 9c02b29e21f8f620f5366c39d08ff46077fbfa08 /includes | |
| parent | b01baded7e661fa6cdf217c5d7cb04e6dbf8e2b2 (diff) | |
| download | languages-6e24ce632d3bfaf09bf6aaffe2055fb1d485c17e.tar.gz languages-6e24ce632d3bfaf09bf6aaffe2055fb1d485c17e.tar.bz2 languages-6e24ce632d3bfaf09bf6aaffe2055fb1d485c17e.zip | |
Restructure fo namespace layout
Diffstat (limited to 'includes')
| -rwxr-xr-x | includes/classes/Babelfish.php | 177 | ||||
| -rwxr-xr-x | includes/classes/Bablotron.php | 172 | ||||
| -rwxr-xr-x | includes/classes/LibertyTranslations.php | 173 |
3 files changed, 522 insertions, 0 deletions
diff --git a/includes/classes/Babelfish.php b/includes/classes/Babelfish.php new file mode 100755 index 0000000..8029db5 --- /dev/null +++ b/includes/classes/Babelfish.php @@ -0,0 +1,177 @@ +<?php +/** + * @package languages + * @version $Header$ + * + * Tiki is copyright (c) 2002-2003, Luis Argerich, Garland Foster, Eduardo Polidor, et. al. + * All Rights Reserved. See below for details and a complete list of authors. + * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See http://www.gnu.org/copyleft/lesser.html for details. + * + * This file copyright (c) 2002-2003, Ross Smith II + */ + +/** + * @package languages + */ +class Babelfish { + /** + * Return the host name of the server + * + * @todo move to BitBase class + */ + function host() { + if (isset($_SERVER['HTTP_HOST'])) { + // HTTP_HOST already includes a ':port' if it is used + return $_SERVER['HTTP_HOST']; + } + + if (!isset($_SERVER['SERVER_NAME'])) { + return false; + } + + $rv = $_SERVER['SERVER_NAME']; + + if (!isset($_SERVER['SERVER_PORT'])) { + return $rv; + } + + if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) { + if ($_SERVER['SERVER_PORT'] != 443) { + $rv .= ':' . $_SERVER['SERVER_PORT']; + } + } else { + if ($_SERVER['SERVER_PORT'] != 80) { + $rv .= ':' . $_SERVER['SERVER_PORT']; + } + } + + return $rv; + } + + /** + * Return babelfish URL to translate \c $lang_from to \c $lang_to + * + * @param lang_from + * @param lang_to + */ + function url($lang_from, $lang_to) { + static $url_map = array( + 'en' => 'english', + 'fr' => 'french', + 'de' => 'german', + 'it' => 'italian', + 'es' => 'spanish', + 'pt' => 'portugese', + ); + + $lang_from = strtolower($lang_from); + $lang_to = strtolower($lang_to); + + if (!isset($url_map[$lang_from])) { + return ''; + } + + $url = 'http://jump.altavista.com/translate_' . $url_map[$lang_from] . '.go' . + '?http://babelfish.altavista.com/babelfish/tr?doit=done' . + '&lp=' . $lang_from . '_' . $lang_to . + '&urltext=http'; + if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') { + $url .= 's'; + } + $url .= '://' . Babelfish::host() . $_SERVER['REQUEST_URI'] . + (strpos('?', $_SERVER['REQUEST_URI']) ? '&' : '?') . + 'babelfish=' . $lang_from . '_' . $lang_to; + + return $url; + } + + /** + * Return HTML of babelfish links + * + * @param lang_from Language to translate from + */ + function links($lang_from = 'en') { + static $fishes = array( + 'en' => array( # English + 'de' => 'Übersetzen Sie diese Seite ins Deutsche', + 'es' => 'Traduzca esta paginación a español', + 'fr' => 'Traduisez cette page en français', + 'it' => 'Tradurre questa pagina in italiano', + 'pt' => 'Traduza esta página em portuguêses', + 'zh' => '翻译这页成汉语 (CN)', + 'ja' => '日本語にこのページを翻訳しなさい (Nihongo)', + 'ko' => '한국인으로 이 페이지를 번역하십시요 (Hangul)', + ), + 'fr' => array( # French + 'de' => 'Übersetzen Sie diese Seite in Deutschen', + 'en' => 'Translate this page into English', + ), + 'de' => array( # German + 'en' => 'Translate this page into English', + 'fr' => 'Traduisez cette page en français', + ), + 'it' => array( # Italian + 'en' => 'Translate this page into English', + ), + 'es' => array( # Spanish + 'en' => 'Translate this page into English', + ), + 'pt' => array( # Portugese + 'en' => 'Translate this page into English', + ), + 'ru' => array( # Russian + 'en' => 'Translate this page into English', + ), + ); + + // \todo Use phpsniff or PEAR's Net_UserAgent_Detect to detect the browser type + // as Netscape 4.x and possibly others displays 'ꯍ' literally +// if (preg_match('/(mozilla\/4)/i', $_SERVER['HTTP_USER_AGENT'])) { +// $fishes['en']['zh'] = 'Translate this page into Chinese (CN)'; +// $fishes['en']['ja'] = 'Translate this page into Japenese (Nihongo)'; +// $fishes['en']['ko'] = 'Translate this page into Korean (Hangul)'; +// } + + // If we have already translated this page (babelfish=en_fr), then don't display the strings again + if (!isset($fishes[$lang_from]) || isset($_GET['babelfish'])) { + return []; + } + + $a = []; + foreach ($fishes[$lang_from] as $lang_to => $msg) { + $a[] = array('target' => $lang_to, + 'href' => Babelfish::url($lang_from, $lang_to), + 'msg' => $msg); + } + + return $a; + } + + /** + * Return javascript code to display babelfish logo + * + * \static + */ + function logo($lang = 'en') { + static $s = "<script language=\"JavaScript1.2\" src=\"http://www.altavista.com/r?%str\"></script>"; + + $lang = strtolower($lang); + + switch ($lang) { + case 'en': + case 'de': + case 'fr': + case 'it': + return sprintf($s, $lang); + case 'es': + return sprintf($s, 'esp'); + case 'pt': + return sprintf($s, 'port'); + } + + return ''; + } + +} + +?> diff --git a/includes/classes/Bablotron.php b/includes/classes/Bablotron.php new file mode 100755 index 0000000..ca33be6 --- /dev/null +++ b/includes/classes/Bablotron.php @@ -0,0 +1,172 @@ +<?php +/** + * Spellcheck Library + * + * @package kernel + * @version $Header$ + * + * Copyright (c) 2004 bitweaver.org + * Copyright (c) 2003 tikwiki.org + * Copyright (c) 2002-2003, Luis Argerich, Garland Foster, Eduardo Polidor, et. al. + * All Rights Reserved. See below for details and a complete list of authors. + * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See http://www.gnu.org/copyleft/lesser.html for details + * + * $Id$ + * + * A spell checking library. + * + * Currently used for BitBase. + * @author lrargerich <lrargerich@yahoo.com> + * created 2002/11/14 + */ + +/** + * Spellcheck Library + * + * @package kernel + * @todo does not need to inherit BitBase class. Should hold a BitDb connection as a + * global variable. + */ +class Bablotron extends BitBase +{ + /** + * @todo Variable is scoped here but not really used in this scope below. + */ + public $words; + /** + * Used to store the current language. + * + * @todo Not sure where this gets set from. Is used in other libraries. + */ + public $lan; + /** + * @todo Empty variable - does nothing + */ + public $db; + /** + * Spellchecking and finding of alternative words + */ + function __construct( $lan ) + { + parent::__construct(); + $this->lan = $lan; + } + /** + * @todo Empty function - does nothing + */ + function sql_error($query, $result) + { + return; + } + /** + * Spellchecks a line of text + * @param text line of text + * @param threshold the similarity threshold + * @returns array a list of alternative words if spelt incorrectly + */ + function spellcheck_text($text, $threshold = 5) + { + $words = preg_split("/\s/", $text); + $results = []; + foreach ($words as $word) + { + if (!$this->word_exists($word)) + { + $results[$word] = $this->find_similar_words($word, $threshold); + } + } + return $results; + } + /** + * Spellchecks a word + * @param word the word + * @param threshold the similarity threshold + * @returns array a list of alternative words if spelt incorrectly + */ + function spellcheck_word($word, $threshold = 5) + { + $results = []; + if (!$this->word_exists($word)) + { + $results[$word] = $this->find_similar_words($word, $threshold); + } + return $results; + } + /** + * Spellchecks a line of text + * @param text line of text + * @param threshold Not used @todo param threshold Not used + * @return array a list of incorrectly spelt words or words not found in the database + */ + function quick_spellcheck_text($text, $threshold = 5) + { + $words = preg_split("/\s/", $text); + $results = []; + foreach ($words as $word) + { + if (!$this->word_exists($word)) + { + $results[] = $word; + } + } + return $results; + } + /** + * Lists similar words by relevance threshold. + * @param word the word + * @param threshold the similarity threshold + * @return array of similar words and Levenshtein distance + */ + function find_similar_words($word, $threshold) + { + $similar = []; + $tbl = 'babl_words_' . $this->lan; + $word = addslashes( ( trim( $word ) ) ); + $sndx = substr($word, 0, 2); + $query = "select `word` AS word from `$tbl` where `di`=?"; + @$result = $this->mDb->query($query, array($sndx)); + while ($res = $result->fetchRow() ) + { + $tword = $res["word"]; + $lev = levenshtein($tword, $word); + if (count($similar) < $threshold) + { + $similar[$tword] = $lev; + asort ($similar); + } + else + { + // If the array is full then if the lev is better than the worst lev + // then update $keys = array_keys($similar); + $last_key = $keys[count($keys) - 1]; + if ($lev < $similar[$last_key]) + { + unset ($similar[$last_key]); + $similar[$tword] = $lev; + asort ($similar); + } + } + } + return $similar; + } + /** + * Checks if a word exists + * @param word the word + * @return int number of matches + */ + function word_exists($word) + { + $tbl = 'babl_words_' . $this->lan; + $word = addslashes( ( trim( $word ) ) ); + $query = "select `word` AS word from `$tbl` where `word`=?"; + $result = $this->mDb->query($query,array($word)); + return $result->numRows(); + } + /** + * @todo Empty function - does nothing + */ + function find_similar($word, $threshold) + { + } +} +?> diff --git a/includes/classes/LibertyTranslations.php b/includes/classes/LibertyTranslations.php new file mode 100755 index 0000000..0527b9b --- /dev/null +++ b/includes/classes/LibertyTranslations.php @@ -0,0 +1,173 @@ +<?php +/** + * @package languages + * @version $Header$ + * + * @author ? + */ + +namespace Bitweaver\Languages; +use Bitweaver\BitBase; +use Bitweaver\Liberty\LibertyBase; + + /** + * @package languages + */ + class LibertyTranslations extends LibertyBase { + public function __construct( $pContentId = null ) { + $this->mContentId = $pContentId; + parent::__construct(); + } + + public function getContentTranslations() { + global $gBitSystem, $gBitLanguage; + $ret = []; + if( BitBase::verifyId( $this->mContentId ) ) { + $translationId = $this->mDb->getOne( "SELECT `translation_id` FROM `".BIT_DB_PREFIX."i18n_content_trans_map` WHERE `content_id`=?", array( $this->mContentId ) ); + if( BitBase::verifyId( $translationId ) ) { + $query = "SELECT lc.`content_id`, lc.`title`, lc.`lang_code`, ictm.`translation_id` + FROM `".BIT_DB_PREFIX."i18n_content_trans_map` ictm + INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON( lc.`content_id`=ictm.`content_id` ) + WHERE ictm.`translation_id`=?"; + $result = $this->mDb->query( $query, array( $translationId ) ); + while( $aux = $result->fetchRow() ) { + // default to site language + if( empty( $aux['lang_code'] )) { + $aux['lang_code'] = $gBitLanguage->mLanguage; + } + $ret[$aux['lang_code']] = $aux; + } + } + } + return $ret; + } + + public function storeTranslation( $pParamHash ) { + if( $this->verify( $pParamHash ) ) { + $table = BIT_DB_PREFIX."i18n_content_trans_map"; + if( !BitBase::verifyId( $pParamHash['translation_store']['translation_id'] ?? 0 ) && is_array( $pParamHash['translation_store'] ) ) { + foreach( $pParamHash['translation_store'] as $store ) { + $result = $this->mDb->associateInsert( $table, $store ); + } + } else { + $result = $this->mDb->associateInsert( $table, $pParamHash['translation_store'] ); + } + } + } + + public function verify( array &$pParamHash ): bool { + $i = 0; + + // make sure we don't have a translation_id for this content yet + if( BitBase::verifyId( $pParamHash['from_id'] ?? 0 ) ) { + $pParamHash['translation_id'] = $this->mDb->getOne( "SELECT `translation_id` FROM `".BIT_DB_PREFIX."i18n_content_trans_map` WHERE `content_id`=?", array( $pParamHash['from_id'] ) ); + } + + // if we have this page in this translation, we should inform the user somehow. + // in theory, this shouldn't happen, but there might be a situation where we end up with 2 users translating the same page at the same time. (is this true?) + + // if we have a translation_id, we add this content to the same group of translations + if( BitBase::verifyId( $pParamHash['translation_id'] ?? 0 ) ) { + $pParamHash['translation_store']['translation_id'] = $pParamHash['translation_id']; + $pParamHash['translation_store']['content_id'] = $pParamHash['content_id']; + } elseif( BitBase::verifyId( $pParamHash['from_id'] ?? 0 ) ) { + // we have a from_id but no translation_id, this is a new entry in the translation map and we need both, the original and the new content_id entered + // we can simply use the from_id as the translation_id + $pParamHash['translation_store'][$i]['translation_id'] = $pParamHash['from_id']; + $pParamHash['translation_store'][$i]['content_id'] = $pParamHash['from_id']; + $i++; + $pParamHash['translation_store'][$i]['translation_id'] = $pParamHash['from_id']; + $pParamHash['translation_store'][$i]['content_id'] = $pParamHash['content_id']; + } + return count( $this->mErrors ) == 0; + } + + public function expunge(): bool { + if( BitBase::verifyId( $this->mContentId ) ) { + $result = $this->mDb->query( "DELETE FROM `".BIT_DB_PREFIX."i18n_content_trans_map` WHERE `content_id`=?", $this->mContentId ); + } + return true; + } +} + +// ================== service functions ================== + +function translation_content_display( &$pObject ) { + global $gBitSmarty, $gBitLanguage; + $trans = new LibertyTranslations( $pObject->mContentId ); + $translations = $trans->getContentTranslations(); + // merge this information that we can display the appropriate flags + if( count( $translations ) > 1 ) { + foreach( $translations as $key => $trans ) { + $translations[$key] = array_merge( $gBitLanguage->mLanguageList[$trans['lang_code']], $trans ); + } + $gBitSmarty->assign( 'i18nTranslations', $translations ); + } +} + +function translation_content_edit( &$pObject, &$pParamHash ) { + global $gBitLanguage, $gBitSmarty, $gBitUser; + $trans = new LibertyTranslations( $pObject->mContentId ); + $translationId = null; + $translations = $trans->getContentTranslations(); + foreach( $gBitLanguage->mLanguageList as $lang_code => $language ) { + $translationsList[$lang_code] = $language; + if( !empty( $translations[$lang_code]['content_id'] ) ) { + $translationsList[$lang_code]['content_id'] = $translations[$lang_code]['content_id']; + $translationsList[$lang_code]['title'] = $translations[$lang_code]['title']; + $translationId = $translations[$lang_code]['translation_id']; + } + } + $gBitSmarty->assign( 'translationsList', $translationsList ); + $gBitSmarty->assign( 'translationId', $translationId ); + + if( BitBase::verifyId( $_REQUEST['i18n']['from_id'] ?? 0 ) ) { + // load the content we're translating from + $transObject = LibertyBase::getLibertyObject( $_REQUEST['i18n']['from_id'] ); + $gBitSmarty->assign( "translateFrom", $transObject ); + + // attempt google translation + if( !empty( $_REQUEST['i18n']['google'] ) && !empty( $transObject->mInfo['data'] )) { + // temporarily replace \n with a string + $nl = 'nlnlnlnlnl'; + // initiate some variables + $transObject->mInfo['google_guess'] = ''; + // we need to split the strings into small chunks due to url length limitations + $strings = str_split( $transObject->mInfo['data'], 1500 ); + foreach( $strings as $string ) { + $requestUrl = "http://translate.google.com/translate_t?ie=UTF-8&oe=UTF-8&text=".urlencode( preg_replace( '/[\n]/', $nl, $string ))."&langpair=en|{$_REQUEST['i18n']['lang_code']}"; + if( $handle = fopen( $requestUrl, "r" )) { + $data = ''; + while( !feof( $handle )) { + $data .= fread( $handle, 8192 ); + } + fclose( $handle ); + preg_match_all( "!<div id=result_box[^>]*>([^<]*)</div>.*!", $data, $matches ); + if( isset( $matches[1][0] )) { + $transObject->mInfo['google_guess'] .= preg_replace( "/".preg_quote( $nl, "/" )."/", "\n", $matches[1][0] ); + } + } + } +die; + } + } +} + +// store the content +function translation_content_store( $pObject, $pParamHash ) { + // if we are creating this content and we have a from_id, we know that we're translating a page + // mInfo['content_id'] isn't set when content is created + if( empty( $pObject->mInfo['content_id'] ) && BitBase::verifyId( $_REQUEST['i18n']['from_id'] ?? 0 ) ) { + $trans = new LibertyTranslations(); + $storeHash = $_REQUEST['i18n']; + $storeHash['content_id'] = $pParamHash['content_id']; + if( !$trans->storeTranslation( $storeHash ) ) { + // error + } + } +} + +function translation_content_expunge( $pObject, $pParamHash ) { + $trans = new LibertyTranslations( $pObject->mContentId ); + $trans->expunge(); +}
\ No newline at end of file |
