X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FArticle.php;h=63d9bf9569930e64d84805bdfa402dcf19b5eb51;hb=6f9c5532f2e53dfda40487a0d69966a63d9c2204;hp=5a23b2a5cc722c7645f4ffa1fc993da5e0452d89;hpb=625b4216e5930dbb9a99a3f57f0b9d7fccd1bf29;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Article.php b/includes/Article.php index 5a23b2a5cc..63d9bf9569 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -21,7 +21,6 @@ class Article { var $mContent; // !< var $mContentLoaded = false; // !< var $mCounter = -1; // !< Not loaded - var $mCurID = -1; // !< Not loaded var $mDataLoaded = false; // !< var $mForUpdate = false; // !< var $mGoodAdjustment = 0; // !< @@ -34,7 +33,7 @@ class Article { var $mRedirectTarget = null; // !< Title object if set var $mRedirectUrl = false; // !< var $mRevIdFetched = 0; // !< - var $mRevision; // !< Revision object if set + var $mRevision = null; // !< Revision object if set var $mTimestamp = ''; // !< var $mTitle; // !< Title object var $mTotalAdjustment = 0; // !< @@ -58,7 +57,7 @@ class Article { /** * Constructor from an page id - * @param $id The article ID to load + * @param $id Int article ID to load */ public static function newFromID( $id ) { $t = Title::newFromID( $id ); @@ -119,7 +118,7 @@ class Article { */ public function insertRedirect() { // recurse through to only get the final target - $retval = Title::newFromRedirectRecurse( $this->getContent() ); + $retval = Title::newFromRedirectRecurse( $this->getRawText() ); if ( !$retval ) { return null; } @@ -160,7 +159,7 @@ class Article { * * @param $text string article content containing redirect info * @return mixed false, Title of in-wiki target, or string with URL - * @deprecated + * @deprecated @since 1.17 */ public function followRedirectText( $text ) { // recurse through to only get the final target @@ -224,7 +223,7 @@ class Article { $this->mDataLoaded = false; $this->mContentLoaded = false; - $this->mCurID = $this->mUser = $this->mCounter = -1; # Not loaded + $this->mUser = $this->mCounter = -1; # Not loaded $this->mRedirectedFrom = null; # Title object if set $this->mRedirectTarget = null; # Title object if set $this->mUserText = @@ -250,7 +249,7 @@ class Article { * @return Return the text of this revision */ public function getContent() { - global $wgUser, $wgContLang, $wgMessageCache; + global $wgUser; wfProfileIn( __METHOD__ ); @@ -258,12 +257,10 @@ class Article { # If this is a MediaWiki:x message, then load the messages # and return the message value for x. if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { - # If this is a system message, get the default text. - list( $message, $lang ) = $wgMessageCache->figureMessage( $wgContLang->lcfirst( $this->mTitle->getText() ) ); - $text = wfMsgGetKey( $message, false, $lang, false ); - - if ( wfEmptyMsg( $message, $text ) ) + $text = $this->mTitle->getDefaultMessageText(); + if ( $text === false ) { $text = ''; + } } else { $text = wfMsgExt( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon', 'parsemag' ); } @@ -551,10 +548,9 @@ class Article { // We should instead work with the Revision object when we need it... $this->mContent = $revision->getText( Revision::FOR_THIS_USER ); // Loads if user is allowed - $this->mUser = $revision->getUser(); - $this->mUserText = $revision->getUserText(); - $this->mComment = $revision->getComment(); - $this->mTimestamp = wfTimestamp( TS_MW, $revision->getTimestamp() ); + if ( $revision->getId() == $this->mLatest ) { + $this->setLastEdit( $revision ); + } $this->mRevIdFetched = $revision->getId(); $this->mContentLoaded = true; @@ -687,7 +683,7 @@ class Article { return true; } - return $this->exists() && isset( $this->mRevision ) && $this->mRevision->isCurrent(); + return $this->exists() && $this->mRevision && $this->mRevision->isCurrent(); } /** @@ -705,21 +701,27 @@ class Article { return; } - $this->mLastRevision = Revision::loadFromPageId( wfGetDB( DB_MASTER ), $id ); - if ( !is_null( $this->mLastRevision ) ) { - $this->mUser = $this->mLastRevision->getUser(); - $this->mUserText = $this->mLastRevision->getUserText(); - $this->mTimestamp = $this->mLastRevision->getTimestamp(); - $this->mComment = $this->mLastRevision->getComment(); - $this->mMinorEdit = $this->mLastRevision->isMinor(); - $this->mRevIdFetched = $this->mLastRevision->getId(); + $revision = Revision::loadFromPageId( wfGetDB( DB_MASTER ), $id ); + if ( !is_null( $revision ) ) { + $this->setLastEdit( $revision ); } } /** - * @return string GMT timestamp of last article revision - **/ + * Set the latest revision + */ + protected function setLastEdit( Revision $revision ) { + $this->mLastRevision = $revision; + $this->mUser = $revision->getUser(); + $this->mUserText = $revision->getUserText(); + $this->mTimestamp = $revision->getTimestamp(); + $this->mComment = $revision->getComment(); + $this->mMinorEdit = $revision->isMinor(); + } + /** + * @return string GMT timestamp of last article revision + */ public function getTimestamp() { // Check if the field has been filled by ParserCache::get() if ( !$this->mTimestamp ) { @@ -769,8 +771,11 @@ class Article { * @return int revision ID of last article revision */ public function getRevIdFetched() { - $this->loadLastEdit(); - return $this->mRevIdFetched; + if ( $this->mRevIdFetched ) { + return $this->mRevIdFetched; + } else { + return $this->getLatest(); + } } /** @@ -1028,10 +1033,11 @@ class Article { # tents of 'pagetitle-view-mainpage' instead of the default (if # that's not empty). # This message always exists because it is in the i18n files - if ( $this->mTitle->equals( Title::newMainPage() ) - && ( $m = wfMsgForContent( 'pagetitle-view-mainpage' ) ) !== '' ) - { - $wgOut->setHTMLTitle( $m ); + if ( $this->mTitle->equals( Title::newMainPage() ) ) { + $msg = wfMessage( 'pagetitle-view-mainpage' )->inContentLanguage(); + if ( !$msg->isDisabled() ) { + $wgOut->setHTMLTitle( $msg->title( $this->mTitle )->text() ); + } } # Now that we've filled $this->mParserOutput, we know whether @@ -1175,7 +1181,7 @@ class Article { * merging of several policies using array_merge(). * @param $policy Mixed, returns empty array on null/false/'', transparent * to already-converted arrays, converts String. - * @return associative Array: 'index' => , 'follow' => + * @return Array: 'index' => , 'follow' => */ public static function formatRobotPolicy( $policy ) { if ( is_array( $policy ) ) { @@ -1263,8 +1269,7 @@ class Article { global $wgOut; if ( $this->mTitle->isTalkPage() ) { - $msg = wfMsgNoTrans( 'talkpageheader' ); - if ( $msg !== '-' && !wfEmptyMsg( 'talkpageheader', $msg ) ) { + if ( !wfMessage( 'talkpageheader' )->isDisabled() ) { $wgOut->wrapWikiMsg( "
\n$1\n
", array( 'talkpageheader' ) ); } } @@ -1289,6 +1294,9 @@ class Article { if ( $wgUseTrackbacks ) { $this->addTrackbacks(); } + + wfRunHooks( 'ArticleViewFooter', array( $this ) ); + } /** @@ -1382,7 +1390,7 @@ class Article { wfMsgNoTrans( 'missingarticle-rev', $oldid ) ); } elseif ( $this->mTitle->getNamespace() === NS_MEDIAWIKI ) { // Use the default message text - $text = $this->getContent(); + $text = $this->mTitle->getDefaultMessageText(); } else { $createErrors = $this->mTitle->getUserPermissionsErrors( 'create', $wgUser ); $editErrors = $this->mTitle->getUserPermissionsErrors( 'edit', $wgUser ); @@ -1525,7 +1533,7 @@ class Article { /** * View redirect * - * @param $target Title object or Array of destination(s) to redirect + * @param $target Title|Array of destination(s) to redirect * @param $appendSubtitle Boolean [optional] * @param $forceKnown Boolean: should the image be shown as a bluelink regardless of existence? * @return string containing HMTL with redirect link @@ -1556,13 +1564,12 @@ class Article { $nextRedirect = $wgStylePath . '/common/images/nextredirect' . $imageDir . '.png'; $alt = $wgContLang->isRTL() ? '←' : '→'; // Automatically append redirect=no to each link, since most of them are redirect pages themselves. - // FIXME: where this happens? foreach ( $target as $rt ) { $link .= Html::element( 'img', array( 'src' => $nextRedirect, 'alt' => $alt ) ); if ( $forceKnown ) { - $link .= $sk->linkKnown( $rt, htmlspecialchars( $rt->getFullText() ) ); + $link .= $sk->linkKnown( $rt, htmlspecialchars( $rt->getFullText(), array(), array( 'redirect' => 'no' ) ) ); } else { - $link .= $sk->link( $rt, htmlspecialchars( $rt->getFullText() ) ); + $link .= $sk->link( $rt, htmlspecialchars( $rt->getFullText() ), array(), array( 'redirect' => 'no' ) ); } } @@ -1703,15 +1710,13 @@ class Article { } if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { - global $wgMessageCache; - if ( $this->getID() == 0 ) { $text = false; } else { $text = $this->getRawText(); } - $wgMessageCache->replace( $this->mTitle->getDBkey(), $text ); + MessageCache::singleton()->replace( $this->mTitle->getDBkey(), $text ); } } @@ -1748,7 +1753,7 @@ class Article { if ( $affected ) { $newid = $dbw->insertId(); - $this->mTitle->resetArticleId( $newid ); + $this->mTitle->resetArticleID( $newid ); } wfProfileOut( __METHOD__ ); @@ -1760,7 +1765,7 @@ class Article { * * @param $dbw DatabaseBase: object * @param $revision Revision: For ID number, and text used to set - length and redirect status fields + length and redirect status fields * @param $lastRevision Integer: if given, will not overwrite the page field * when different from the currently set value. * Giving 0 indicates the new page flag should be set @@ -1813,7 +1818,7 @@ class Article { * Add row to the redirect table if this is a redirect, remove otherwise. * * @param $dbw Database - * @param $redirectTitle a title object pointing to the redirect target, + * @param $redirectTitle Title object pointing to the redirect target, * or NULL if this is not a redirect * @param $lastRevIsRedirect If given, will optimize adding and * removing rows in redirect table. @@ -1826,25 +1831,25 @@ class Article { // Delete if changing from redirect to non-redirect $isRedirect = !is_null( $redirectTitle ); - if ( $isRedirect || is_null( $lastRevIsRedirect ) || $lastRevIsRedirect !== $isRedirect ) { - wfProfileIn( __METHOD__ ); - if ( $isRedirect ) { - $this->insertRedirectEntry( $redirectTitle ); - } else { - // This is not a redirect, remove row from redirect table - $where = array( 'rd_from' => $this->getId() ); - $dbw->delete( 'redirect', $where, __METHOD__ ); - } - - if ( $this->getTitle()->getNamespace() == NS_FILE ) { - RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect( $this->getTitle() ); - } - wfProfileOut( __METHOD__ ); + if ( !$isRedirect && !is_null( $lastRevIsRedirect ) && $lastRevIsRedirect === $isRedirect ) { + return true; + } + + wfProfileIn( __METHOD__ ); + if ( $isRedirect ) { + $this->insertRedirectEntry( $redirectTitle ); + } else { + // This is not a redirect, remove row from redirect table + $where = array( 'rd_from' => $this->getId() ); + $dbw->delete( 'redirect', $where, __METHOD__ ); + } - return ( $dbw->affectedRows() != 0 ); + if ( $this->getTitle()->getNamespace() == NS_FILE ) { + RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect( $this->getTitle() ); } + wfProfileOut( __METHOD__ ); - return true; + return ( $dbw->affectedRows() != 0 ); } /** @@ -1908,6 +1913,7 @@ class Article { if ( !$rev ) { wfDebug( "Article::replaceSection asked for bogus section (page: " . $this->getId() . "; section: $section; edittime: $edittime)\n" ); + wfProfileOut( __METHOD__ ); return null; } @@ -1932,10 +1938,11 @@ class Article { } /** - * This function is not deprecated until somebody fixes the core not to use - * it. Nevertheless, use Article::doEdit() instead. + * @deprecated @since 1.7 use Article::doEdit() */ function insertNewArticle( $text, $summary, $isminor, $watchthis, $suppressRC = false, $comment = false, $bot = false ) { + wfDeprecated( __METHOD__ ); + $flags = EDIT_NEW | EDIT_DEFER_UPDATES | EDIT_AUTOSUMMARY | ( $isminor ? EDIT_MINOR : 0 ) | ( $suppressRC ? EDIT_SUPPRESS_RC : 0 ) | @@ -1965,9 +1972,11 @@ class Article { } /** - * @deprecated use Article::doEdit() + * @deprecated @since 1.7 use Article::doEdit() */ function updateArticle( $text, $summary, $minor, $watchthis, $forceBot = false, $sectionanchor = '' ) { + wfDeprecated( __METHOD__ ); + $flags = EDIT_UPDATE | EDIT_DEFER_UPDATES | EDIT_AUTOSUMMARY | ( $minor ? EDIT_MINOR : 0 ) | ( $forceBot ? EDIT_FORCE_BOT : 0 ); @@ -2050,7 +2059,7 @@ class Article { * auto-detection due to MediaWiki's performance-optimised locking strategy. * * @param $baseRevId the revision ID this edit was based off, if any - * @param $user Optional user object, $wgUser will be used if not passed + * @param $user User (optional), $wgUser will be used if not passed * * @return Status object. Possible errors: * edit-hook-aborted: The ArticleSave hook aborted the edit but didn't set the fatal flag of $status @@ -2089,12 +2098,12 @@ class Article { $flags & EDIT_MINOR, null, null, &$flags, &$status ) ) ) { wfDebug( __METHOD__ . ": ArticleSave hook aborted save!\n" ); - wfProfileOut( __METHOD__ ); if ( $status->isOK() ) { $status->fatal( 'edit-hook-aborted' ); } + wfProfileOut( __METHOD__ ); return $status; } @@ -2203,7 +2212,7 @@ class Article { $status->warning( 'edit-no-change' ); $revision = null; // Keep the same revision ID, but do some updates on it - $revisionId = $this->getRevIdFetched(); + $revisionId = $this->getLatest(); // Update page_touched, this is usually implicit in the page update // Other cache updates are done in onArticleEdit() $this->mTitle->invalidateCache(); @@ -2261,6 +2270,8 @@ class Article { $revisionId = $revision->insertOn( $dbw ); $this->mTitle->resetArticleID( $newid ); + # Update the LinkCache. Resetting the Title ArticleID means it will rely on having that already cached (FIXME?) + LinkCache::singleton()->addGoodLinkObj( $newid, $this->mTitle, strlen( $text ), (bool)Title::newFromRedirect( $text ), $revisionId ); # Update the page record with revision data $this->updateRevisionOn( $dbw, $revision, 0 ); @@ -2311,14 +2322,6 @@ class Article { return $status; } - /** - * @deprecated wrapper for doRedirect - */ - public function showArticle( $text, $subtitle , $sectionanchor = '', $me2, $now, $summary, $oldid ) { - wfDeprecated( __METHOD__ ); - $this->doRedirect( $this->isRedirect( $text ), $sectionanchor ); - } - /** * Output a redirect back to the article. * This is typically used after an edit. @@ -2428,6 +2431,9 @@ class Article { /** * Add this page to $wgUser's watchlist + * + * This is safe to be called multiple times + * * @return bool true on successful watch operation */ public function doWatch() { @@ -2911,7 +2917,10 @@ class Article { //FIXME: lego $wgOut->addHTML( '' . wfMsgExt( 'historywarning', array( 'parseinline' ), $wgLang->formatNum( $revisions ) ) . - wfMsgHtml( 'word-separator' ) . $skin->historyLink() . + wfMsgHtml( 'word-separator' ) . $skin->link( $this->mTitle, + wfMsgHtml( 'history' ), + array( 'rel' => 'archives' ), + array( 'action' => 'history' ) ) . '' ); @@ -3022,7 +3031,7 @@ class Article { wfRunHooks( 'ArticleConfirmDelete', array( $this, $wgOut, &$reason ) ); if ( $wgUser->isAllowed( 'suppressrevision' ) ) { - $suppress = " + $suppress = " " . Xml::checkLabel( wfMsg( 'revdelete-suppress' ), @@ -3592,13 +3601,20 @@ class Article { global $wgParser; + if( $user === null ) { + global $wgUser; + $user = $wgUser; + } + $popts = ParserOptions::newFromUser( $user ); + wfRunHooks( 'ArticlePrepareTextForEdit', array( $this, $popts ) ); + $edit = (object)array(); $edit->revid = $revid; $edit->newText = $text; - $edit->pst = $this->preSaveTransform( $text, $user ); + $edit->pst = $this->preSaveTransform( $text, $user, $popts ); $edit->popts = $this->getParserOptions( true ); $edit->output = $wgParser->parse( $edit->pst, $this->mTitle, $edit->popts, true, true, $revid ); - $edit->oldText = $this->getContent(); + $edit->oldText = $this->getRawText(); $this->mPreparedEdit = $edit; @@ -3615,13 +3631,13 @@ class Article { * @param $text String: New text of the article * @param $summary String: Edit summary * @param $minoredit Boolean: Minor edit - * @param $timestamp_of_pagechange Timestamp associated with the page change + * @param $timestamp_of_pagechange String timestamp associated with the page change * @param $newid Integer: rev_id value of the new revision * @param $changed Boolean: Whether or not the content actually changed * @param $user User object: User doing the edit */ public function editUpdates( $text, $summary, $minoredit, $timestamp_of_pagechange, $newid, $changed = true, User $user = null ) { - global $wgDeferredUpdateList, $wgMessageCache, $wgUser, $wgEnableParserCache; + global $wgDeferredUpdateList, $wgUser, $wgEnableParserCache; wfProfileIn( __METHOD__ ); @@ -3699,7 +3715,7 @@ class Article { } if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { - $wgMessageCache->replace( $shortTitle, $text ); + MessageCache::singleton()->replace( $shortTitle, $text ); } wfProfileOut( __METHOD__ ); @@ -3843,8 +3859,7 @@ class Article { # Show user links if allowed to see them. If hidden, then show them only if requested... $userlinks = $sk->revUserTools( $revision, !$unhide ); - $m = wfMsg( 'revision-info-current' ); - $infomsg = $current && !wfEmptyMsg( 'revision-info-current', $m ) && $m != '-' + $infomsg = $current && !wfMessage( 'revision-info-current' )->isDisabled() ? 'revision-info-current' : 'revision-info'; @@ -3873,10 +3888,12 @@ class Article { * @param $text String article contents * @param $user User object: user doing the edit, $wgUser will be used if * null is given + * @param $popts ParserOptions object: parser options, default options for + * the user loaded if null given * @return string article contents with altered wikitext markup (signatures * converted, {{subst:}}, templates, etc.) */ - public function preSaveTransform( $text, User $user = null ) { + public function preSaveTransform( $text, User $user = null, ParserOptions $popts = null ) { global $wgParser; if ( $user === null ) { @@ -3884,7 +3901,11 @@ class Article { $user = $wgUser; } - return $wgParser->preSaveTransform( $text, $this->mTitle, $user, ParserOptions::newFromUser( $user ) ); + if ( $popts === null ) { + $popts = ParserOptions::newFromUser( $user ); + } + + return $wgParser->preSaveTransform( $text, $this->mTitle, $user, $popts ); } /* Caching functions */ @@ -4004,7 +4025,7 @@ class Article { wfProfileOut( __METHOD__ ); } - /**#@+ + /** * The onArticle*() functions are supposed to be a kind of hooks * which should be called whenever any of the specified actions * are done. @@ -4013,7 +4034,7 @@ class Article { * * This is called on page move and undelete, as well as edit * - * @param $title a title object + * @param $title Title object */ public static function onArticleCreate( $title ) { # Update existence markers on article/talk tabs... @@ -4035,8 +4056,6 @@ class Article { * Clears caches when article is deleted */ public static function onArticleDelete( $title ) { - global $wgMessageCache; - # Update existence markers on article/talk tabs... if ( $title->isTalkPage() ) { $other = $title->getSubjectPage(); @@ -4055,7 +4074,7 @@ class Article { # Messages if ( $title->getNamespace() == NS_MEDIAWIKI ) { - $wgMessageCache->replace( $title->getDBkey(), false ); + MessageCache::singleton()->replace( $title->getDBkey(), false ); } # Images @@ -4130,7 +4149,7 @@ class Article { if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { // This doesn't quite make sense; the user is asking for // information about the _page_, not the message... -- RC - $wgOut->addHTML( htmlspecialchars( wfMsgWeirdKey( $this->mTitle->getText() ) ) ); + $wgOut->addHTML( htmlspecialchars( $this->mTitle->getDefaultMessageText() ) ); } else { $msg = $wgUser->isLoggedIn() ? 'noarticletext' @@ -4270,7 +4289,7 @@ class Article { * Return an applicable autosummary if one exists for the given edit. * @param $oldtext String: the previous text of the page. * @param $newtext String: The submitted text of the page. - * @param $flags Bitmask: a bitmask of flags submitted for the edit. + * @param $flags Int bitmask: a bitmask of flags submitted for the edit. * @return string An appropriate autosummary, or an empty string. */ public static function getAutosummary( $oldtext, $newtext, $flags ) { @@ -4389,7 +4408,7 @@ class Article { $parserOptions = new ParserOptions( $user ); $parserOptions->setTidy( true ); $parserOptions->enableLimitReport(); - + if ( $canonical ) { $parserOptions->setUserLang( $wgLanguageCode ); # Must be set explicitely return $parserOptions; @@ -4524,7 +4543,7 @@ class Article { * @since 1.16 (r52326) for LiquidThreads * * @param $oldid mixed integer Revision ID or null - * @return ParserOutput + * @return ParserOutput or false if the given revsion ID is not found */ public function getParserOutput( $oldid = null ) { global $wgEnableParserCache, $wgUser; @@ -4541,31 +4560,25 @@ class Article { wfIncrStats( 'pcache_miss_stub' ); } - $parserOutput = false; if ( $useParserCache ) { $parserOutput = ParserCache::singleton()->get( $this, $this->getParserOptions() ); + if ( $parserOutput !== false ) { + return $parserOutput; + } } - if ( $parserOutput === false ) { - // Cache miss; parse and output it. - $rev = Revision::newFromTitle( $this->getTitle(), $oldid ); - - return $this->getOutputFromWikitext( $rev->getText(), $useParserCache ); + // Cache miss; parse and output it. + if ( $oldid === null ) { + $text = $this->getRawText(); } else { - return $parserOutput; + $rev = Revision::newFromTitle( $this->getTitle(), $oldid ); + if ( $rev === null ) { + return false; + } + $text = $rev->getText(); } - } - // Deprecated methods - /** - * Get the database which should be used for reads - * - * @return Database - * @deprecated - just call wfGetDB( DB_MASTER ) instead - */ - function getDB() { - wfDeprecated( __METHOD__ ); - return wfGetDB( DB_MASTER ); + return $this->getOutputFromWikitext( $text, $useParserCache ); } }