title.php

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

PHP
2,308
字号
	/* private */ function prefix( $name ) {		global $wgContLang;		$p = '';		if ( '' != $this->mInterwiki ) {			$p = $this->mInterwiki . ':';		}		if ( 0 != $this->mNamespace ) {			$p .= $wgContLang->getNsText( $this->mNamespace ) . ':';		}		return $p . $name;	}	/**	 * Secure and split - main initialisation function for this object	 *	 * Assumes that mDbkeyform has been set, and is urldecoded	 * and uses underscores, but not otherwise munged.  This function	 * removes illegal characters, splits off the interwiki and	 * namespace prefixes, sets the other forms, and canonicalizes	 * everything.	 * @return bool true on success	 * @private	 */	/* private */ function secureAndSplit() {		global $wgContLang, $wgLocalInterwiki, $wgCapitalLinks;		$fname = 'Title::secureAndSplit';		# Initialisation		static $rxTc = false;		if( !$rxTc ) {			# % is needed as well			$rxTc = '/[^' . Title::legalChars() . ']|%[0-9A-Fa-f]{2}/S';		}		$this->mInterwiki = $this->mFragment = '';		$this->mNamespace = $this->mDefaultNamespace; # Usually NS_MAIN		# Clean up whitespace		#		$t = preg_replace( '/[ _]+/', '_', $this->mDbkeyform );		$t = trim( $t, '_' );		if ( '' == $t ) {			return false;		}		if( false !== strpos( $t, UTF8_REPLACEMENT ) ) {			# Contained illegal UTF-8 sequences or forbidden Unicode chars.			return false;		}		$this->mDbkeyform = $t;		# Initial colon indicates main namespace rather than specified default		# but should not create invalid {ns,title} pairs such as {0,Project:Foo}		if ( ':' == $t{0} ) {			$this->mNamespace = NS_MAIN;			$t = substr( $t, 1 ); # remove the colon but continue processing		}		# Namespace or interwiki prefix		$firstPass = true;		do {			if ( preg_match( "/^(.+?)_*:_*(.*)$/S", $t, $m ) ) {				$p = $m[1];				$lowerNs = strtolower( $p );				if ( $ns = Namespace::getCanonicalIndex( $lowerNs ) ) {					# Canonical namespace					$t = $m[2];					$this->mNamespace = $ns;				} elseif ( $ns = $wgContLang->getNsIndex( $lowerNs )) {					# Ordinary namespace					$t = $m[2];					$this->mNamespace = $ns;				} elseif( $this->getInterwikiLink( $p ) ) {					if( !$firstPass ) {						# Can't make a local interwiki link to an interwiki link.						# That's just crazy!						return false;					}					# Interwiki link					$t = $m[2];					$this->mInterwiki = strtolower( $p );					# Redundant interwiki prefix to the local wiki					if ( 0 == strcasecmp( $this->mInterwiki, $wgLocalInterwiki ) ) {						if( $t == '' ) {							# Can't have an empty self-link							return false;						}						$this->mInterwiki = '';						$firstPass = false;						# Do another namespace split...						continue;					}					# If there's an initial colon after the interwiki, that also					# resets the default namespace					if ( $t !== '' && $t[0] == ':' ) {						$this->mNamespace = NS_MAIN;						$t = substr( $t, 1 );					}				}				# If there's no recognized interwiki or namespace,				# then let the colon expression be part of the title.			}			break;		} while( true );		$r = $t;		# We already know that some pages won't be in the database!		#		if ( '' != $this->mInterwiki || -1 == $this->mNamespace ) {			$this->mArticleID = 0;		}		$f = strstr( $r, '#' );		if ( false !== $f ) {			$this->mFragment = substr( $f, 1 );			$r = substr( $r, 0, strlen( $r ) - strlen( $f ) );			# remove whitespace again: prevents "Foo_bar_#"			# becoming "Foo_bar_"			$r = preg_replace( '/_*$/', '', $r );		}		# Reject illegal characters.		#		if( preg_match( $rxTc, $r ) ) {			return false;		}		/**		 * Pages with "/./" or "/../" appearing in the URLs will		 * often be unreachable due to the way web browsers deal		 * with 'relative' URLs. Forbid them explicitly.		 */		if ( strpos( $r, '.' ) !== false &&		     ( $r === '.' || $r === '..' ||		       strpos( $r, './' ) === 0  ||		       strpos( $r, '../' ) === 0 ||		       strpos( $r, '/./' ) !== false ||		       strpos( $r, '/../' ) !== false ) )		{			return false;		}		# We shouldn't need to query the DB for the size.		#$maxSize = $dbr->textFieldSize( 'page', 'page_title' );		if ( strlen( $r ) > 255 ) {			return false;		}		/**		 * Normally, all wiki links are forced to have		 * an initial capital letter so [[foo]] and [[Foo]]		 * point to the same place.		 *		 * Don't force it for interwikis, since the other		 * site might be case-sensitive.		 */		if( $wgCapitalLinks && $this->mInterwiki == '') {			$t = $wgContLang->ucfirst( $r );		} else {			$t = $r;		}		/**		 * Can't make a link to a namespace alone...		 * "empty" local links can only be self-links		 * with a fragment identifier.		 */		if( $t == '' &&			$this->mInterwiki == '' &&			$this->mNamespace != NS_MAIN ) {			return false;		}		// Any remaining initial :s are illegal.		if ( $t !== '' && ':' == $t{0} ) {			return false;		}				# Fill fields		$this->mDbkeyform = $t;		$this->mUrlform = wfUrlencode( $t );		$this->mTextform = str_replace( '_', ' ', $t );		return true;	}	/**	 * Get a Title object associated with the talk page of this article	 * @return Title the object for the talk page	 * @access public	 */	function getTalkPage() {		return Title::makeTitle( Namespace::getTalk( $this->getNamespace() ), $this->getDBkey() );	}	/**	 * Get a title object associated with the subject page of this	 * talk page	 *	 * @return Title the object for the subject page	 * @access public	 */	function getSubjectPage() {		return Title::makeTitle( Namespace::getSubject( $this->getNamespace() ), $this->getDBkey() );	}	/**	 * Get an array of Title objects linking to this Title	 * Also stores the IDs in the link cache.	 *	 * WARNING: do not use this function on arbitrary user-supplied titles!	 * On heavily-used templates it will max out the memory.	 *	 * @param string $options may be FOR UPDATE	 * @return array the Title objects linking here	 * @access public	 */	function getLinksTo( $options = '', $table = 'pagelinks', $prefix = 'pl' ) {		$linkCache =& LinkCache::singleton();		$id = $this->getArticleID();		if ( $options ) {			$db =& wfGetDB( DB_MASTER );		} else {			$db =& wfGetDB( DB_SLAVE );		}		$res = $db->select( array( 'page', $table ),			array( 'page_namespace', 'page_title', 'page_id' ),			array(				"{$prefix}_from=page_id",				"{$prefix}_namespace" => $this->getNamespace(),				"{$prefix}_title"     => $this->getDbKey() ),			'Title::getLinksTo',			$options );		$retVal = array();		if ( $db->numRows( $res ) ) {			while ( $row = $db->fetchObject( $res ) ) {				if ( $titleObj = Title::makeTitle( $row->page_namespace, $row->page_title ) ) {					$linkCache->addGoodLinkObj( $row->page_id, $titleObj );					$retVal[] = $titleObj;				}			}		}		$db->freeResult( $res );		return $retVal;	}	/**	 * Get an array of Title objects using this Title as a template	 * Also stores the IDs in the link cache.	 *	 * WARNING: do not use this function on arbitrary user-supplied titles!	 * On heavily-used templates it will max out the memory.	 *	 * @param string $options may be FOR UPDATE	 * @return array the Title objects linking here	 * @access public	 */	function getTemplateLinksTo( $options = '' ) {		return $this->getLinksTo( $options, 'templatelinks', 'tl' );	}	/**	 * Get an array of Title objects referring to non-existent articles linked from this page	 *	 * @param string $options may be FOR UPDATE	 * @return array the Title objects	 * @access public	 */	function getBrokenLinksFrom( $options = '' ) {		if ( $options ) {			$db =& wfGetDB( DB_MASTER );		} else {			$db =& wfGetDB( DB_SLAVE );		}		$res = $db->safeQuery(			  "SELECT pl_namespace, pl_title			     FROM !			LEFT JOIN !			       ON pl_namespace=page_namespace			      AND pl_title=page_title			    WHERE pl_from=?			      AND page_namespace IS NULL				  !",			$db->tableName( 'pagelinks' ),			$db->tableName( 'page' ),			$this->getArticleId(),			$options );		$retVal = array();		if ( $db->numRows( $res ) ) {			while ( $row = $db->fetchObject( $res ) ) {				$retVal[] = Title::makeTitle( $row->pl_namespace, $row->pl_title );			}		}		$db->freeResult( $res );		return $retVal;	}	/**	 * Get a list of URLs to purge from the Squid cache when this	 * page changes	 *	 * @return array the URLs	 * @access public	 */	function getSquidURLs() {		return array(			$this->getInternalURL(),			$this->getInternalURL( 'action=history' )		);	}	function purgeSquid() {		global $wgUseSquid;		if ( $wgUseSquid ) {			$urls = $this->getSquidURLs();			$u = new SquidUpdate( $urls );			$u->doUpdate();		}	}	/**	 * Move this page without authentication	 * @param Title &$nt the new page Title	 * @access public	 */	function moveNoAuth( &$nt ) {		return $this->moveTo( $nt, false );	}	/**	 * Check whether a given move operation would be valid.	 * Returns true if ok, or a message key string for an error message	 * if invalid. (Scarrrrry ugly interface this.)	 * @param Title &$nt the new title	 * @param bool $auth indicates whether $wgUser's permissions	 * 	should be checked	 * @return mixed true on success, message name on failure	 * @access public	 */	function isValidMoveOperation( &$nt, $auth = true ) {		if( !$this or !$nt ) {			return 'badtitletext';		}		if( $this->equals( $nt ) ) {			return 'selfmove';		}		if( !$this->isMovable() || !$nt->isMovable() ) {			return 'immobile_namespace';		}		$oldid = $this->getArticleID();		$newid = $nt->getArticleID();		if ( strlen( $nt->getDBkey() ) < 1 ) {			return 'articleexists';		}		if ( ( '' == $this->getDBkey() ) ||			 ( !$oldid ) ||		     ( '' == $nt->getDBkey() ) ) {			return 'badarticleerror';		}		if ( $auth && (				!$this->userCanEdit() || !$nt->userCanEdit() ||				!$this->userCanMove() || !$nt->userCanMove() ) ) {			return 'protectedpage';		}		# The move is allowed only if (1) the target doesn't exist, or		# (2) the target is a redirect to the source, and has no history		# (so we can undo bad moves right after they're done).		if ( 0 != $newid ) { # Target exists; check for validity			if ( ! $this->isValidMoveTarget( $nt ) ) {				return 'articleexists';			}		}		return true;	}	/**	 * Move a title to a new location	 * @param Title &$nt the new title	 * @param bool $auth indicates whether $wgUser's permissions	 * 	should be checked	 * @return mixed true on success, message name on failure	 * @access public	 */	function moveTo( &$nt, $auth = true, $reason = '' ) {		$err = $this->isValidMoveOperation( $nt, $auth );		if( is_string( $err ) ) {			return $err;		}		$pageid = $this->getArticleID();		if( $nt->exists() ) {			$this->moveOverExistingRedirect( $nt, $reason );			$pageCountChange = 0;		} else { # Target didn't exist, do normal move.			$this->moveToNewTitle( $nt, $reason );			$pageCountChange = 1;		}		$redirid = $this->getArticleID();		# Fixing category links (those without piped 'alternate' names) to be sorted under the new title		$dbw =& wfGetDB( DB_MASTER );		$categorylinks = $dbw->tableName( 'categorylinks' );		$sql = "UPDATE $categorylinks SET cl_sortkey=" . $dbw->addQuotes( $nt->getPrefixedText() ) .			" WHERE cl_from=" . $dbw->addQuotes( $pageid ) .			" AND cl_sortkey=" . $dbw->addQuotes( $this->getPrefixedText() );		$dbw->query( $sql, 'SpecialMovepage::doSubmit' );		# Update watchlists		$oldnamespace = $this->getNamespace() & ~1;		$newnamespace = $nt->getNamespace() & ~1;		$oldtitle = $this->getDBkey();		$newtitle = $nt->getDBkey();		if( $oldnamespace != $newnamespace || $oldtitle != $newtitle ) {			WatchedItem::duplicateEntries( $this, $nt );		}		# Update search engine		$u = new SearchUpdate( $pageid, $nt->getPrefixedDBkey() );		$u->doUpdate();		$u = new SearchUpdate( $redirid, $this->getPrefixedDBkey(), '' );		$u->doUpdate();		# Update site_stats		if ( $this->getNamespace() == NS_MAIN and $nt->getNamespace() != NS_MAIN ) {			# Moved out of main namespace			# not viewed, edited, removing			$u = new SiteStatsUpdate( 0, 1, -1, $pageCountChange);		} elseif ( $this->getNamespace() != NS_MAIN and $nt->getNamespace() == NS_MAIN ) {			# Moved into main namespace			# not viewed, edited, adding			$u = new SiteStatsUpdate( 0, 1, +1, $pageCountChange );		} elseif ( $pageCountChange ) {			# Added redirect			$u = new SiteStatsUpdate( 0, 0, 0, 1 );		} else{			$u = false;		}		if ( $u ) {			$u->doUpdate();		}		global $wgUser;		wfRunHooks( 'TitleMoveComplete', array( &$this, &$nt, &$wgUser, $pageid, $redirid ) );

⌨️ 快捷键说明

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