languageconverter.php

来自「php 开发的内容管理系统」· PHP 代码 · 共 661 行 · 第 1/2 页

PHP
661
字号
<?php/**  * @package MediaWiki  * @subpackage Language  *  * @author Zhengzhu Feng <zhengzhu@gmail.com>  * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License  */class LanguageConverter {	var $mPreferredVariant='';	var $mMainLanguageCode;	var $mVariants, $mVariantFallbacks;	var $mTablesLoaded = false;	var $mTables;	var $mTitleDisplay='';	var $mDoTitleConvert=true, $mDoContentConvert=true;	var $mCacheKey;	var $mLangObj;	var $mMarkup;	var $mFlags;	var $mUcfirst = false;	/**     * Constructor	 *     * @param string $maincode the main language code of this language     * @param array $variants the supported variants of this language     * @param array $variantfallback the fallback language of each variant     * @param array $markup array defining the markup used for manual conversion	 * @param array $flags array defining the custom strings that maps to the flags     * @access public     */	function __construct($langobj, $maincode,								$variants=array(),								$variantfallbacks=array(),								$markup=array(),								$flags = array()) {		global $wgDBname;		$this->mLangObj = $langobj;		$this->mMainLanguageCode = $maincode;		$this->mVariants = $variants;		$this->mVariantFallbacks = $variantfallbacks;		$this->mCacheKey = $wgDBname . ":conversiontables";		$m = array('begin'=>'-{', 'flagsep'=>'|', 'codesep'=>':',				   'varsep'=>';', 'end'=>'}-');		$this->mMarkup = array_merge($m, $markup);		$f = array('A'=>'A', 'T'=>'T');		$this->mFlags = array_merge($f, $flags);	}	/**     * @access public     */	function getVariants() {		return $this->mVariants;	}	/**	 * in case some variant is not defined in the markup, we need	 * to have some fallback. for example, in zh, normally people	 * will define zh-cn and zh-tw, but less so for zh-sg or zh-hk.	 * when zh-sg is preferred but not defined, we will pick zh-cn	 * in this case. right now this is only used by zh.	 *	 * @param string $v the language code of the variant	 * @return string the code of the fallback language or false if there is no fallback     * @private	*/	function getVariantFallback($v) {		return $this->mVariantFallbacks[$v];	}	/**     * get preferred language variants.     * @return string the preferred language code     * @access public	*/	function getPreferredVariant() {		global $wgUser, $wgRequest;		if($this->mPreferredVariant)			return $this->mPreferredVariant;		// see if the preference is set in the request		$req = $wgRequest->getText( 'variant' );		if( in_array( $req, $this->mVariants ) ) {			$this->mPreferredVariant = $req;			return $req;		}		// get language variant preference from logged in users		if(is_object($wgUser) && $wgUser->isLoggedIn() )  {			$this->mPreferredVariant = $wgUser->getOption('variant');			return $this->mPreferredVariant;		}		# FIXME rewrite code for parsing http header. The current code		# is written specific for detecting zh- variants		if( !$this->mPreferredVariant ) {			// see if some supported language variant is set in the			// http header, but we don't set the mPreferredVariant			// variable in case this is called before the user's			// preference is loaded			$pv=$this->mMainLanguageCode;			if(array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {				$header = str_replace( '_', '-', strtolower($_SERVER["HTTP_ACCEPT_LANGUAGE"]));				$zh = strstr($header, 'zh-');				if($zh) {					$pv = substr($zh,0,5);				}			}			return $pv;		}	}	/**     * dictionary-based conversion     *     * @param string $text the text to be converted     * @param string $toVariant the target language code     * @return string the converted text     * @private     */	function autoConvert($text, $toVariant=false) {		$fname="LanguageConverter::autoConvert";		wfProfileIn( $fname );		if(!$this->mTablesLoaded)			$this->loadTables();		if(!$toVariant)			$toVariant = $this->getPreferredVariant();		if(!in_array($toVariant, $this->mVariants))			return $text;		/* we convert everything except:		   1. html markups (anything between < and >)		   2. html entities		   3. place holders created by the parser		*/		global $wgParser;		if (isset($wgParser))			$marker = '|' . $wgParser->UniqPrefix() . '[\-a-zA-Z0-9]+';		else			$marker = "";		// this one is needed when the text is inside an html markup		$htmlfix = '|<[^>]+=\"[^(>=)]*$|^[^(<>=\")]*\"[^>]*>';		$reg = '/<[^>]+>|&[a-z#][a-z0-9]+;' . $marker . $htmlfix . '/';			$matches = preg_split($reg, $text, -1, PREG_SPLIT_OFFSET_CAPTURE);		$m = array_shift($matches);		$ret = strtr($m[0], $this->mTables[$toVariant]);		$mstart = $m[1]+strlen($m[0]);		foreach($matches as $m) {			$ret .= substr($text, $mstart, $m[1]-$mstart);			$ret .= strtr($m[0], $this->mTables[$toVariant]);			$mstart = $m[1] + strlen($m[0]);		}		wfProfileOut( $fname );		return $ret;	}	/**     * convert text to all supported variants     *     * @param string $text the text to be converted     * @return array of string     * @private     */	function autoConvertToAllVariants($text) {		$fname="LanguageConverter::autoConvertToAllVariants";		wfProfileIn( $fname );		if( !$this->mTablesLoaded )			$this->loadTables();		$ret = array();		foreach($this->mVariants as $variant) {			$ret[$variant] = strtr($text, $this->mTables[$variant]);		}		wfProfileOut( $fname );		return $ret;	}	/**	 * Convert text using a parser object for context	 */	function parserConvert( $text, &$parser ) {		global $wgDisableLangConversion;		/* don't do anything if this is the conversion table */		if ( $parser->mTitle->getNamespace() == NS_MEDIAWIKI &&			strpos($parser->mTitle->getText, "Conversiontable") !== false ) 		{			return $text;		}		if($wgDisableLangConversion)			return $text;		$text = $this->convert( $text );		$parser->mOutput->setTitleText( $this->mTitleDisplay );		return $text;	}	/**	 * convert text to different variants of a language. the automatic	 * conversion is done in autoConvert(). here we parse the text	 * marked with -{}-, which specifies special conversions of the	 * text that can not be accomplished in autoConvert()	 *	 * syntax of the markup:	 * -{code1:text1;code2:text2;...}-  or	 * -{text}- in which case no conversion should take place for text     *     * @param string $text text to be converted     * @param bool $isTitle whether this conversion is for the article title     * @return string converted text     * @access public     */	function convert( $text , $isTitle=false) {		$mw =& MagicWord::get( MAG_NOTITLECONVERT );		if( $mw->matchAndRemove( $text ) )			$this->mDoTitleConvert = false;		$mw =& MagicWord::get( MAG_NOCONTENTCONVERT );		if( $mw->matchAndRemove( $text ) ) {			$this->mDoContentConvert = false;		}		// no conversion if redirecting		$mw =& MagicWord::get( MAG_REDIRECT );		if( $mw->matchStart( $text ))			return $text;		if( $isTitle ) {			if( !$this->mDoTitleConvert ) {				$this->mTitleDisplay = $text;				return $text;			}			if( !empty($this->mTitleDisplay))				return $this->mTitleDisplay;			global $wgRequest;			$isredir = $wgRequest->getText( 'redirect', 'yes' );			$action = $wgRequest->getText( 'action' );			if ( $isredir == 'no' || $action == 'edit' ) {				return $text;			}			else {				$this->mTitleDisplay = $this->autoConvert($text);				return $this->mTitleDisplay;			}		}		if( !$this->mDoContentConvert )			return $text;		$plang = $this->getPreferredVariant();		if( isset( $this->mVariantFallbacks[$plang] ) ) {			$fallback = $this->mVariantFallbacks[$plang];		} else {			// This sounds... bad?			$fallback = '';		}		$tarray = explode($this->mMarkup['begin'], $text);		$tfirst = array_shift($tarray);		$text = $this->autoConvert($tfirst);		foreach($tarray as $txt) {			$marked = explode($this->mMarkup['end'], $txt, 2);			$flags = array();			$tt = explode($this->mMarkup['flagsep'], $marked[0], 2);			if(sizeof($tt) == 2) {				$f = explode($this->mMarkup['varsep'], $tt[0]);				foreach($f as $ff) {					$ff = trim($ff);					if(array_key_exists($ff, $this->mFlags) &&						!array_key_exists($this->mFlags[$ff], $flags))						$flags[] = $this->mFlags[$ff];				}				$rules = $tt[1];			}			else				$rules = $marked[0];#FIXME: may cause trouble here...			//strip &nbsp; since it interferes with the parsing, plus,			//all spaces should be stripped in this tag anyway.			$rules = str_replace('&nbsp;', '', $rules);			$carray = $this->parseManualRule($rules, $flags);			$disp = '';			if(array_key_exists($plang, $carray))				$disp = $carray[$plang];			else if(array_key_exists($fallback, $carray))				$disp = $carray[$fallback];			if($disp) {				if(in_array('T',  $flags))					$this->mTitleDisplay = $disp;				else					$text .= $disp;				if(in_array('A', $flags)) {					/* modify the conversion table for this session*/					/* fill in the missing variants, if any,					    with fallbacks */					foreach($this->mVariants as $v) {						if(!array_key_exists($v, $carray)) {							$vf = $this->getVariantFallback($v);							if(array_key_exists($vf, $carray))								$carray[$v] = $carray[$vf];						}					}					foreach($this->mVariants as $vfrom) {						if(!array_key_exists($vfrom, $carray))							continue;						foreach($this->mVariants as $vto) {							if($vfrom == $vto)								continue;							if(!array_key_exists($vto, $carray))								continue;							$this->mTables[$vto][$carray[$vfrom]] = $carray[$vto];

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?