title.php

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

PHP
2,308
字号
<?php/** * See title.txt * * @package MediaWiki *//** */require_once( 'normal/UtfNormal.php' );define ( 'GAID_FOR_UPDATE', 1 );# Title::newFromTitle maintains a cache to avoid# expensive re-normalization of commonly used titles.# On a batch operation this can become a memory leak# if not bounded. After hitting this many titles,# reset the cache.define( 'MW_TITLECACHE_MAX', 1000 );/** * Title class * - Represents a title, which may contain an interwiki designation or namespace * - Can fetch various kinds of data from the database, albeit inefficiently. * * @package MediaWiki */class Title {	/**	 * Static cache variables	 */	static private $titleCache=array();	static private $interwikiCache=array();			/**	 * All member variables should be considered private	 * Please use the accessor functions	 */	 /**#@+	 * @private	 */	var $mTextform;           # Text form (spaces not underscores) of the main part	var $mUrlform;            # URL-encoded form of the main part	var $mDbkeyform;          # Main part with underscores	var $mNamespace;          # Namespace index, i.e. one of the NS_xxxx constants	var $mInterwiki;          # Interwiki prefix (or null string)	var $mFragment;           # Title fragment (i.e. the bit after the #)	var $mArticleID;          # Article ID, fetched from the link cache on demand	var $mLatestID;         # ID of most recent revision	var $mRestrictions;       # Array of groups allowed to edit this article	                        # Only null or "sysop" are supported	var $mRestrictionsLoaded; # Boolean for initialisation on demand	var $mPrefixedText;       # Text form including namespace/interwiki, initialised on demand	var $mDefaultNamespace;   # Namespace index when there is no namespace	                    # Zero except in {{transclusion}} tags	var $mWatched;      # Is $wgUser watching this page? NULL if unfilled, accessed through userIsWatching()	/**#@-*/	/**	 * Constructor	 * @private	 */	/* private */ function Title() {		$this->mInterwiki = $this->mUrlform =		$this->mTextform = $this->mDbkeyform = '';		$this->mArticleID = -1;		$this->mNamespace = NS_MAIN;		$this->mRestrictionsLoaded = false;		$this->mRestrictions = array();		# Dont change the following, NS_MAIN is hardcoded in several place		# See bug #696		$this->mDefaultNamespace = NS_MAIN;		$this->mWatched = NULL;		$this->mLatestID = false;	}	/**	 * Create a new Title from a prefixed DB key	 * @param string $key The database key, which has underscores	 *	instead of spaces, possibly including namespace and	 *	interwiki prefixes	 * @return Title the new object, or NULL on an error	 * @static	 * @access public	 */	/* static */ function newFromDBkey( $key ) {		$t = new Title();		$t->mDbkeyform = $key;		if( $t->secureAndSplit() )			return $t;		else			return NULL;	}	/**	 * Create a new Title from text, such as what one would	 * find in a link. Decodes any HTML entities in the text.	 *	 * @param string $text the link text; spaces, prefixes,	 *	and an initial ':' indicating the main namespace	 *	are accepted	 * @param int $defaultNamespace the namespace to use if	 * 	none is specified by a prefix	 * @return Title the new object, or NULL on an error	 * @static	 * @access public	 */	function newFromText( $text, $defaultNamespace = NS_MAIN ) {		$fname = 'Title::newFromText';		if( is_object( $text ) ) {			throw new MWException( 'Title::newFromText given an object' );		}		/**		 * Wiki pages often contain multiple links to the same page.		 * Title normalization and parsing can become expensive on		 * pages with many links, so we can save a little time by		 * caching them.		 *		 * In theory these are value objects and won't get changed...		 */		if( $defaultNamespace == NS_MAIN && isset( Title::$titleCache[$text] ) ) {			return Title::$titleCache[$text];		}		/**		 * Convert things like &eacute; &#257; or &#x3017; into real text...		 */		$filteredText = Sanitizer::decodeCharReferences( $text );		$t =& new Title();		$t->mDbkeyform = str_replace( ' ', '_', $filteredText );		$t->mDefaultNamespace = $defaultNamespace;		static $cachedcount = 0 ;		if( $t->secureAndSplit() ) {			if( $defaultNamespace == NS_MAIN ) {				if( $cachedcount >= MW_TITLECACHE_MAX ) {					# Avoid memory leaks on mass operations...					Title::$titleCache = array();					$cachedcount=0;				}				$cachedcount++;				Title::$titleCache[$text] =& $t;			}			return $t;		} else {			$ret = NULL;			return $ret;		}	}	/**	 * Create a new Title from URL-encoded text. Ensures that	 * the given title's length does not exceed the maximum.	 * @param string $url the title, as might be taken from a URL	 * @return Title the new object, or NULL on an error	 * @static	 * @access public	 */	function newFromURL( $url ) {		global $wgLegalTitleChars;		$t = new Title();		# For compatibility with old buggy URLs. "+" is usually not valid in titles,		# but some URLs used it as a space replacement and they still come		# from some external search tools.		if ( strpos( $wgLegalTitleChars, '+' ) === false ) {			$url = str_replace( '+', ' ', $url );		}		$t->mDbkeyform = str_replace( ' ', '_', $url );		if( $t->secureAndSplit() ) {			return $t;		} else {			return NULL;		}	}	/**	 * Create a new Title from an article ID	 *	 * @todo This is inefficiently implemented, the page row is requested	 *       but not used for anything else	 *	 * @param int $id the page_id corresponding to the Title to create	 * @return Title the new object, or NULL on an error	 * @access public	 * @static	 */	function newFromID( $id ) {		$fname = 'Title::newFromID';		$dbr =& wfGetDB( DB_SLAVE );		$row = $dbr->selectRow( 'page', array( 'page_namespace', 'page_title' ),			array( 'page_id' => $id ), $fname );		if ( $row !== false ) {			$title = Title::makeTitle( $row->page_namespace, $row->page_title );		} else {			$title = NULL;		}		return $title;	}	/**	 * Make an array of titles from an array of IDs 	 */	function newFromIDs( $ids ) {		$dbr =& wfGetDB( DB_SLAVE );		$res = $dbr->select( 'page', array( 'page_namespace', 'page_title' ),			'page_id IN (' . $dbr->makeList( $ids ) . ')', __METHOD__ );		$titles = array();		while ( $row = $dbr->fetchObject( $res ) ) {			$titles[] = Title::makeTitle( $row->page_namespace, $row->page_title );		}		return $titles;	}	/**	 * Create a new Title from a namespace index and a DB key.	 * It's assumed that $ns and $title are *valid*, for instance when	 * they came directly from the database or a special page name.	 * For convenience, spaces are converted to underscores so that	 * eg user_text fields can be used directly.	 *	 * @param int $ns the namespace of the article	 * @param string $title the unprefixed database key form	 * @return Title the new object	 * @static	 * @access public	 */	function &makeTitle( $ns, $title ) {		$t =& new Title();		$t->mInterwiki = '';		$t->mFragment = '';		$t->mNamespace = intval( $ns );		$t->mDbkeyform = str_replace( ' ', '_', $title );		$t->mArticleID = ( $ns >= 0 ) ? -1 : 0;		$t->mUrlform = wfUrlencode( $t->mDbkeyform );		$t->mTextform = str_replace( '_', ' ', $title );		return $t;	}	/**	 * Create a new Title frrom a namespace index and a DB key.	 * The parameters will be checked for validity, which is a bit slower	 * than makeTitle() but safer for user-provided data.	 *	 * @param int $ns the namespace of the article	 * @param string $title the database key form	 * @return Title the new object, or NULL on an error	 * @static	 * @access public	 */	function makeTitleSafe( $ns, $title ) {		$t = new Title();		$t->mDbkeyform = Title::makeName( $ns, $title );		if( $t->secureAndSplit() ) {			return $t;		} else {			return NULL;		} 	}	/**	 * Create a new Title for the Main Page	 *	 * @static	 * @return Title the new object	 * @access public	 */	function newMainPage() {		return Title::newFromText( wfMsgForContent( 'mainpage' ) );	}	/**	 * Create a new Title for a redirect	 * @param string $text the redirect title text	 * @return Title the new object, or NULL if the text is not a	 *	valid redirect	 * @static	 * @access public	 */	function newFromRedirect( $text ) {		$mwRedir = MagicWord::get( MAG_REDIRECT );		$rt = NULL;		if ( $mwRedir->matchStart( $text ) ) {			if ( preg_match( '/\[{2}(.*?)(?:\||\]{2})/', $text, $m ) ) {				# categories are escaped using : for example one can enter:				# #REDIRECT [[:Category:Music]]. Need to remove it.				if ( substr($m[1],0,1) == ':') {					# We don't want to keep the ':'					$m[1] = substr( $m[1], 1 );				}				$rt = Title::newFromText( $m[1] );				# Disallow redirects to Special:Userlogout				if ( !is_null($rt) && $rt->getNamespace() == NS_SPECIAL && preg_match( '/^Userlogout/i', $rt->getText() ) ) {					$rt = NULL;				}			}		}		return $rt;	}#----------------------------------------------------------------------------#	Static functions#----------------------------------------------------------------------------	/**	 * Get the prefixed DB key associated with an ID	 * @param int $id the page_id of the article	 * @return Title an object representing the article, or NULL	 * 	if no such article was found	 * @static	 * @access public	 */	function nameOf( $id ) {		$fname = 'Title::nameOf';		$dbr =& wfGetDB( DB_SLAVE );		$s = $dbr->selectRow( 'page', array( 'page_namespace','page_title' ),  array( 'page_id' => $id ), $fname );		if ( $s === false ) { return NULL; }		$n = Title::makeName( $s->page_namespace, $s->page_title );		return $n;	}	/**	 * Get a regex character class describing the legal characters in a link	 * @return string the list of characters, not delimited	 * @static	 * @access public	 */	function legalChars() {		global $wgLegalTitleChars;		return $wgLegalTitleChars;	}	/**	 * Get a string representation of a title suitable for	 * including in a search index	 *	 * @param int $ns a namespace index	 * @param string $title text-form main part	 * @return string a stripped-down title string ready for the	 * 	search index	 */	/* static */ function indexTitle( $ns, $title ) {		global $wgContLang;		$lc = SearchEngine::legalSearchChars() . '&#;';		$t = $wgContLang->stripForSearch( $title );		$t = preg_replace( "/[^{$lc}]+/", ' ', $t );		$t = strtolower( $t );		# Handle 's, s'		$t = preg_replace( "/([{$lc}]+)'s( |$)/", "\\1 \\1's ", $t );		$t = preg_replace( "/([{$lc}]+)s'( |$)/", "\\1s ", $t );		$t = preg_replace( "/\\s+/", ' ', $t );		if ( $ns == NS_IMAGE ) {			$t = preg_replace( "/ (png|gif|jpg|jpeg|ogg)$/", "", $t );		}		return trim( $t );	}	/*	 * Make a prefixed DB key from a DB key and a namespace index	 * @param int $ns numerical representation of the namespace	 * @param string $title the DB key form the title	 * @return string the prefixed form of the title	 */	/* static */ function makeName( $ns, $title ) {		global $wgContLang;		$n = $wgContLang->getNsText( $ns );		return $n == '' ? $title : "$n:$title";	}	/**	 * Returns the URL associated with an interwiki prefix	 * @param string $key the interwiki prefix (e.g. "MeatBall")	 * @return the associated URL, containing "$1", which should be	 * 	replaced by an article title	 * @static (arguably)	 * @access public	 */	function getInterwikiLink( $key )  {		global $wgMemc, $wgDBname, $wgInterwikiExpiry;		global $wgInterwikiCache;		$fname = 'Title::getInterwikiLink';		$key = strtolower( $key );		$k = $wgDBname.':interwiki:'.$key;		if( array_key_exists( $k, Title::$interwikiCache ) ) {			return Title::$interwikiCache[$k]->iw_url;		}		if ($wgInterwikiCache) {			return Title::getInterwikiCached( $key );		}		$s = $wgMemc->get( $k );		# Ignore old keys with no iw_local		if( $s && isset( $s->iw_local ) && isset($s->iw_trans)) {			Title::$interwikiCache[$k] = $s;			return $s->iw_url;		}		$dbr =& wfGetDB( DB_SLAVE );		$res = $dbr->select( 'interwiki',			array( 'iw_url', 'iw_local', 'iw_trans' ),			array( 'iw_prefix' => $key ), $fname );		if( !$res ) {			return '';		}		$s = $dbr->fetchObject( $res );		if( !$s ) {			# Cache non-existence: create a blank object and save it to memcached			$s = (object)false;			$s->iw_url = '';			$s->iw_local = 0;			$s->iw_trans = 0;		}		$wgMemc->set( $k, $s, $wgInterwikiExpiry );		Title::$interwikiCache[$k] = $s;		return $s->iw_url;	}		/**	 * Fetch interwiki prefix data from local cache in constant database	 *	 * More logic is explained in DefaultSettings	 *	 * @return string URL of interwiki site	 * @access public	 */	function getInterwikiCached( $key ) {		global $wgDBname, $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite;		static $db, $site;		if (!$db)			$db=dba_open($wgInterwikiCache,'r','cdb');		/* Resolve site name */		if ($wgInterwikiScopes>=3 and !$site) {			$site = dba_fetch("__sites:{$wgDBname}", $db);			if ($site=="")				$site = $wgInterwikiFallbackSite;		}		$value = dba_fetch("{$wgDBname}:{$key}", $db);		if ($value=='' and $wgInterwikiScopes>=3) {			/* try site-level */			$value = dba_fetch("_{$site}:{$key}", $db);

⌨️ 快捷键说明

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