article.php
来自「php 开发的内容管理系统」· PHP 代码 · 共 2,311 行 · 第 1/5 页
PHP
2,311 行
<?php/** * File for articles * @package MediaWiki *//** * Need the CacheManager to be loaded */require_once( 'CacheManager.php' );/** * Class representing a MediaWiki article and history. * * See design.txt for an overview. * Note: edit user interface and cache support functions have been * moved to separate EditPage and CacheManager classes. * * @package MediaWiki */class Article { /**@{{ * @private */ var $mComment; //!< var $mContent; //!< var $mContentLoaded; //!< var $mCounter; //!< var $mForUpdate; //!< var $mGoodAdjustment; //!< var $mLatest; //!< var $mMinorEdit; //!< var $mOldId; //!< var $mRedirectedFrom; //!< var $mRedirectUrl; //!< var $mRevIdFetched; //!< var $mRevision; //!< var $mTimestamp; //!< var $mTitle; //!< var $mTotalAdjustment; //!< var $mTouched; //!< var $mUser; //!< var $mUserText; //!< /**@}}*/ /** * Constructor and clear the article * @param $title Reference to a Title object. * @param $oldId Integer revision ID, null to fetch from request, zero for current */ function Article( &$title, $oldId = null ) { $this->mTitle =& $title; $this->mOldId = $oldId; $this->clear(); } /** * Tell the page view functions that this view was redirected * from another page on the wiki. * @param $from Title object. */ function setRedirectedFrom( $from ) { $this->mRedirectedFrom = $from; } /** * @return mixed false, Title of in-wiki target, or string with URL */ function followRedirect() { $text = $this->getContent(); $rt = Title::newFromRedirect( $text ); # process if title object is valid and not special:userlogout if( $rt ) { if( $rt->getInterwiki() != '' ) { if( $rt->isLocal() ) { // Offsite wikis need an HTTP redirect. // // This can be hard to reverse and may produce loops, // so they may be disabled in the site configuration. $source = $this->mTitle->getFullURL( 'redirect=no' ); return $rt->getFullURL( 'rdfrom=' . urlencode( $source ) ); } } else { if( $rt->getNamespace() == NS_SPECIAL ) { // Gotta hand redirects to special pages differently: // Fill the HTTP response "Location" header and ignore // the rest of the page we're on. // // This can be hard to reverse, so they may be disabled. if( $rt->getNamespace() == NS_SPECIAL && $rt->getText() == 'Userlogout' ) { // rolleyes } else { return $rt->getFullURL(); } } return $rt; } } // No or invalid redirect return false; } /** * get the title object of the article */ function getTitle() { return $this->mTitle; } /** * Clear the object * @private */ function clear() { $this->mDataLoaded = false; $this->mContentLoaded = false; $this->mCurID = $this->mUser = $this->mCounter = -1; # Not loaded $this->mRedirectedFrom = null; # Title object if set $this->mUserText = $this->mTimestamp = $this->mComment = ''; $this->mGoodAdjustment = $this->mTotalAdjustment = 0; $this->mTouched = '19700101000000'; $this->mForUpdate = false; $this->mIsRedirect = false; $this->mRevIdFetched = 0; $this->mRedirectUrl = false; $this->mLatest = false; } /** * Note that getContent/loadContent do not follow redirects anymore. * If you need to fetch redirectable content easily, try * the shortcut in Article::followContent() * FIXME * @todo There are still side-effects in this! * In general, you should use the Revision class, not Article, * to fetch text for purposes other than page views. * * @return Return the text of this revision */ function getContent() { global $wgRequest, $wgUser, $wgOut; wfProfileIn( __METHOD__ ); if ( 0 == $this->getID() ) { wfProfileOut( __METHOD__ ); $wgOut->setRobotpolicy( 'noindex,nofollow' ); if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { $ret = wfMsgWeirdKey ( $this->mTitle->getText() ) ; } else { $ret = wfMsg( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon' ); } return "<div class='noarticletext'>$ret</div>"; } else { $this->loadContent(); wfProfileOut( __METHOD__ ); return $this->mContent; } } /** * This function returns the text of a section, specified by a number ($section). * A section is text under a heading like == Heading == or \<h1\>Heading\</h1\>, or * the first section before any such heading (section 0). * * If a section contains subsections, these are also returned. * * @param $text String: text to look in * @param $section Integer: section number * @return string text of the requested section * @deprecated */ function getSection($text,$section) { global $wgParser; return $wgParser->getSection( $text, $section ); } /** * @return int The oldid of the article that is to be shown, 0 for the * current revision */ function getOldID() { if ( is_null( $this->mOldId ) ) { $this->mOldId = $this->getOldIDFromRequest(); } return $this->mOldId; } /** * Sets $this->mRedirectUrl to a correct URL if the query parameters are incorrect * * @return int The old id for the request */ function getOldIDFromRequest() { global $wgRequest; $this->mRedirectUrl = false; $oldid = $wgRequest->getVal( 'oldid' ); if ( isset( $oldid ) ) { $oldid = intval( $oldid ); if ( $wgRequest->getVal( 'direction' ) == 'next' ) { $nextid = $this->mTitle->getNextRevisionID( $oldid ); if ( $nextid ) { $oldid = $nextid; } else { $this->mRedirectUrl = $this->mTitle->getFullURL( 'redirect=no' ); } } elseif ( $wgRequest->getVal( 'direction' ) == 'prev' ) { $previd = $this->mTitle->getPreviousRevisionID( $oldid ); if ( $previd ) { $oldid = $previd; } else { # TODO } } # unused: # $lastid = $oldid; } if ( !$oldid ) { $oldid = 0; } return $oldid; } /** * Load the revision (including text) into this object */ function loadContent() { if ( $this->mContentLoaded ) return; # Query variables :P $oldid = $this->getOldID(); # Pre-fill content with error message so that if something # fails we'll have something telling us what we intended. $t = $this->mTitle->getPrefixedText(); $this->mOldId = $oldid; $this->fetchContent( $oldid ); } /** * Fetch a page record with the given conditions * @param Database $dbr * @param array $conditions * @private */ function pageData( &$dbr, $conditions ) { $fields = array( 'page_id', 'page_namespace', 'page_title', 'page_restrictions', 'page_counter', 'page_is_redirect', 'page_is_new', 'page_random', 'page_touched', 'page_latest', 'page_len' ) ; wfRunHooks( 'ArticlePageDataBefore', array( &$this , &$fields ) ) ; $row = $dbr->selectRow( 'page', $fields, $conditions, 'Article::pageData' ); wfRunHooks( 'ArticlePageDataAfter', array( &$this , &$row ) ) ; return $row ; } /** * @param Database $dbr * @param Title $title */ function pageDataFromTitle( &$dbr, $title ) { return $this->pageData( $dbr, array( 'page_namespace' => $title->getNamespace(), 'page_title' => $title->getDBkey() ) ); } /** * @param Database $dbr * @param int $id */ function pageDataFromId( &$dbr, $id ) { return $this->pageData( $dbr, array( 'page_id' => $id ) ); } /** * Set the general counter, title etc data loaded from * some source. * * @param object $data * @private */ function loadPageData( $data = 'fromdb' ) { if ( $data === 'fromdb' ) { $dbr =& $this->getDB(); $data = $this->pageDataFromId( $dbr, $this->getId() ); } $lc =& LinkCache::singleton(); if ( $data ) { $lc->addGoodLinkObj( $data->page_id, $this->mTitle ); $this->mTitle->mArticleID = $data->page_id; $this->mTitle->loadRestrictions( $data->page_restrictions ); $this->mTitle->mRestrictionsLoaded = true; $this->mCounter = $data->page_counter; $this->mTouched = wfTimestamp( TS_MW, $data->page_touched ); $this->mIsRedirect = $data->page_is_redirect; $this->mLatest = $data->page_latest; } else { if ( is_object( $this->mTitle ) ) { $lc->addBadLinkObj( $this->mTitle ); } $this->mTitle->mArticleID = 0; } $this->mDataLoaded = true; } /** * Get text of an article from database * Does *NOT* follow redirects. * @param int $oldid 0 for whatever the latest revision is * @return string */ function fetchContent( $oldid = 0 ) { if ( $this->mContentLoaded ) { return $this->mContent; } $dbr =& $this->getDB(); # Pre-fill content with error message so that if something # fails we'll have something telling us what we intended. $t = $this->mTitle->getPrefixedText(); if( $oldid ) { $t .= ',oldid='.$oldid; } $this->mContent = wfMsg( 'missingarticle', $t ) ; if( $oldid ) { $revision = Revision::newFromId( $oldid ); if( is_null( $revision ) ) { wfDebug( __METHOD__." failed to retrieve specified revision, id $oldid\n" ); return false; } $data = $this->pageDataFromId( $dbr, $revision->getPage() ); if( !$data ) { wfDebug( __METHOD__." failed to get page data linked to revision id $oldid\n" ); return false; } $this->mTitle = Title::makeTitle( $data->page_namespace, $data->page_title ); $this->loadPageData( $data ); } else { if( !$this->mDataLoaded ) { $data = $this->pageDataFromTitle( $dbr, $this->mTitle ); if( !$data ) { wfDebug( __METHOD__." failed to find page data for title " . $this->mTitle->getPrefixedText() . "\n" ); return false; } $this->loadPageData( $data ); } $revision = Revision::newFromId( $this->mLatest ); if( is_null( $revision ) ) { wfDebug( __METHOD__." failed to retrieve current page, rev_id {$data->page_latest}\n" ); return false; } } // FIXME: Horrible, horrible! This content-loading interface just plain sucks. // We should instead work with the Revision object when we need it... $this->mContent = $revision->userCan( Revision::DELETED_TEXT ) ? $revision->getRawText() : ""; //$this->mContent = $revision->getText(); $this->mUser = $revision->getUser(); $this->mUserText = $revision->getUserText(); $this->mComment = $revision->getComment(); $this->mTimestamp = wfTimestamp( TS_MW, $revision->getTimestamp() ); $this->mRevIdFetched = $revision->getID(); $this->mContentLoaded = true; $this->mRevision =& $revision; wfRunHooks( 'ArticleAfterFetchContent', array( &$this, &$this->mContent ) ) ; return $this->mContent; } /** * Read/write accessor to select FOR UPDATE * * @param $x Mixed: FIXME */ function forUpdate( $x = NULL ) { return wfSetVar( $this->mForUpdate, $x ); } /** * Get the database which should be used for reads * * @return Database */ function &getDB() { $ret =& wfGetDB( DB_MASTER ); return $ret; } /** * Get options for all SELECT statements * * @param $options Array: an optional options array which'll be appended to * the default * @return Array: options */ function getSelectOptions( $options = '' ) { if ( $this->mForUpdate ) { if ( is_array( $options ) ) { $options[] = 'FOR UPDATE'; } else { $options = 'FOR UPDATE'; } } return $options; } /** * @return int Page ID */ function getID() { if( $this->mTitle ) { return $this->mTitle->getArticleID(); } else { return 0; } } /** * @return bool Whether or not the page exists in the database */ function exists() { return $this->getId() != 0; } /** * @return int The view count for the page */ function getCount() { if ( -1 == $this->mCounter ) { $id = $this->getID(); if ( $id == 0 ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?