X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FArticle.php;h=5c33c75e12e5303be0d5242bded4bf4a5bd1b33a;hb=252ef37028af515326bf281bf40ad80792540a2d;hp=88b182e140952de411fa47c1da038db4d1d4ae39;hpb=5acfd2e095dae1b5fbbd7506f907a9ee5072a84f;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Article.php b/includes/Article.php index 88b182e140..5c33c75e12 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -135,7 +135,7 @@ class Article { * @return mixed false, Title of in-wiki target, or string with URL */ public function followRedirectText( $text ) { - $rt = Title::newFromRedirect( $text ); + $rt = Title::newFromRedirectRecurse( $text ); // recurse through to only get the final target # process if title object is valid and not special:userlogout if( $rt ) { if( $rt->getInterwiki() != '' ) { @@ -218,7 +218,7 @@ class Article { if( wfEmptyMsg( $message, $text ) ) $text = ''; } else { - $text = wfMsg( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon' ); + $text = wfMsgExt( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon', 'parsemag' ); } wfProfileOut( __METHOD__ ); return $text; @@ -228,6 +228,21 @@ class Article { return $this->mContent; } } + + /** + * Get the text of the current revision. No side-effects... + * + * @return Return the text of the current revision + */ + public function getRawText() { + // Check process cache for current revision + if( $this->mContentLoaded && $this->mOldId == 0 ) { + return $this->mContent; + } + $rev = Revision::newFromTitle( $this->mTitle ); + $text = $rev ? $rev->getRawText() : false; + return $text; + } /** * This function returns the text of a section, specified by a number ($section). @@ -245,6 +260,28 @@ class Article { global $wgParser; return $wgParser->getSection( $text, $section ); } + + /** + * Get the text that needs to be saved in order to undo all revisions + * between $undo and $undoafter. Revisions must belong to the same page, + * must exist and must not be deleted + * @param $undo Revision + * @param $undoafter Revision Must be an earlier revision than $undo + * @return mixed string on success, false on failure + */ + public function getUndoText( Revision $undo, Revision $undoafter = null ) { + $undo_text = $undo->getText(); + $undoafter_text = $undoafter->getText(); + $cur_text = $this->getContent(); + if ( $cur_text == $undo_text ) { + # No use doing a merge if it's just a straight revert. + return $undoafter_text; + } + $undone_text = ''; + if ( !wfMerge( $undo_text, $undoafter_text, $cur_text, $undone_text ) ) + return false; + return $undone_text; + } /** * @return int The oldid of the article that is to be shown, 0 for the @@ -369,11 +406,9 @@ class Article { $lc->addGoodLinkObj( $data->page_id, $this->mTitle, $data->page_len, $data->page_is_redirect ); $this->mTitle->mArticleID = $data->page_id; - $this->mTitle->mTouched = wfTimestamp( TS_MW, $data->page_touched ); # Old-fashioned restrictions - if( $data->page_restrictions ) - $this->mTitle->loadRestrictions( $data->page_restrictions ); + $this->mTitle->loadRestrictions( $data->page_restrictions ); $this->mCounter = $data->page_counter; $this->mTouched = wfTimestamp( TS_MW, $data->page_touched ); @@ -510,6 +545,18 @@ class Article { public function exists() { return $this->getId() > 0; } + + /** + * Check if this page is something we're going to be showing + * some sort of sensible content for. If we return false, page + * views (plain action=view) will return an HTTP 404 response, + * so spiders and robots can know they're following a bad link. + * + * @return bool + */ + public function hasViewableContent() { + return $this->exists() || $this->mTitle->isAlwaysKnown(); + } /** * @return int The view count for the page @@ -559,7 +606,7 @@ class Article { } // Apparently loadPageData was never called $this->loadContent(); - $titleObj = Title::newFromRedirect( $this->fetchContent() ); + $titleObj = Title::newFromRedirectRecurse( $this->fetchContent() ); } else { $titleObj = Title::newFromRedirect( $text ); } @@ -679,16 +726,17 @@ class Article { wfProfileIn( __METHOD__ ); - $parserCache = ParserCache::singleton(); - $ns = $this->mTitle->getNamespace(); # shortcut - # Get variables from query string $oldid = $this->getOldID(); # Try file cache if( $oldid === 0 && $this->checkTouched() ) { - $wgOut->setETag( $parserCache->getETag($this,$wgUser) ); - if( $wgOut->checkLastModified( $this->getTouched() ) ){ + global $wgUseETag; + if( $wgUseETag ) { + $parserCache = ParserCache::singleton(); + $wgOut->setETag( $parserCache->getETag($this,$wgUser) ); + } + if( $wgOut->checkLastModified( $this->getTouched() ) ) { wfProfileOut( __METHOD__ ); return; } else if( $this->tryFileCache() ) { @@ -700,6 +748,7 @@ class Article { } } + $ns = $this->mTitle->getNamespace(); # shortcut $sk = $wgUser->getSkin(); # getOldID may want us to redirect somewhere else @@ -714,6 +763,7 @@ class Article { $rdfrom = $wgRequest->getVal( 'rdfrom' ); $diffOnly = $wgRequest->getBool( 'diffonly', $wgUser->getOption( 'diffonly' ) ); $purge = $wgRequest->getVal( 'action' ) == 'purge'; + $return404 = false; $wgOut->setArticleFlag( true ); @@ -730,15 +780,17 @@ class Article { } $wgOut->setRobotPolicy( $policy ); + # Allow admins to see deleted content if explicitly requested + $delId = $diff ? $diff : $oldid; + $unhide = $wgRequest->getInt('unhide') == 1 && $wgUser->matchEditToken( $wgRequest->getVal('token'), $delId ); # If we got diff and oldid in the query, we want to see a # diff page instead of the article. if( !is_null( $diff ) ) { $wgOut->setPageTitle( $this->mTitle->getPrefixedText() ); - $diff = $wgRequest->getVal( 'diff' ); $htmldiff = $wgRequest->getVal( 'htmldiff' , false); - $de = new DifferenceEngine( $this->mTitle, $oldid, $diff, $rcid, $purge, $htmldiff); + $de = new DifferenceEngine( $this->mTitle, $oldid, $diff, $rcid, $purge, $htmldiff, $unhide ); // DifferenceEngine directly fetched the revision: $this->mRevIdFetched = $de->mNewid; $de->showDiffPage( $diffOnly ); @@ -752,6 +804,16 @@ class Article { wfProfileOut( __METHOD__ ); return; } + + if( $ns == NS_USER || $ns == NS_USER_TALK ) { + # User/User_talk subpages are not modified. (bug 11443) + if( !$this->mTitle->isSubpage() ) { + $block = new Block(); + if( $block->load( $this->mTitle->getBaseText() ) ) { + $wgOut->setRobotpolicy( 'noindex,nofollow' ); + } + } + } # Should the parser cache be used? $pcache = $this->useParserCache( $oldid ); @@ -766,7 +828,7 @@ class Article { // We'll need a backlink to the source page for navigation. if( wfRunHooks( 'ArticleViewRedirect', array( &$this ) ) ) { $redir = $sk->makeKnownLinkObj( $this->mRedirectedFrom, '', 'redirect=no' ); - $s = wfMsg( 'redirectedfrom', $redir ); + $s = wfMsgExt( 'redirectedfrom', array( 'parseinline', 'replaceafter' ), $redir ); $wgOut->setSubtitle( $s ); // Set the fragment if one was specified in the redirect @@ -782,7 +844,7 @@ class Article { global $wgRedirectSources; if( $wgRedirectSources && preg_match( $wgRedirectSources, $rdfrom ) ) { $redir = $sk->makeExternalLink( $rdfrom, $rdfrom ); - $s = wfMsg( 'redirectedfrom', $redir ); + $s = wfMsgExt( 'redirectedfrom', array( 'parseinline', 'replaceafter' ), $redir ); $wgOut->setSubtitle( $s ); $wasRedirected = true; } @@ -803,29 +865,48 @@ class Article { $this->showDeletionLog(); } $text = $this->getContent(); - if( $text === false ) { + // For now, check also for ID until getContent actually returns + // false for pages that do not exists + if( $text === false || $this->getID() === 0 ) { # Failed to load, replace text with error message $t = $this->mTitle->getPrefixedText(); if( $oldid ) { - $d = wfMsgExt( 'missingarticle-rev', array( 'escape' ), $oldid ); - $text = wfMsg( 'missing-article', $t, $d ); - } else { - $text = wfMsg( 'noarticletext' ); + $d = wfMsgExt( 'missingarticle-rev', 'escape', $oldid ); + $text = wfMsgExt( 'missing-article', 'parsemag', $t, $d ); + // Always use page content for pages in the MediaWiki namespace + // since it contains the default message + } elseif ( $this->mTitle->getNamespace() != NS_MEDIAWIKI ) { + $text = wfMsgExt( 'noarticletext', 'parsemag' ); } } + # Non-existent pages if( $this->getID() === 0 ) { $wgOut->setRobotPolicy( 'noindex,nofollow' ); $text = "
\n$text\n
"; - } + if( !$this->hasViewableContent() ) { + // If there's no backing content, send a 404 Not Found + // for better machine handling of broken links. + $return404 = true; + } + } + + if( $return404 ) { + $wgRequest->response()->header( "HTTP/1.x 404 Not Found" ); + } # Another whitelist check in case oldid is altering the title if( !$this->mTitle->userCanRead() ) { $wgOut->loginToUse(); $wgOut->output(); + $wgOut->disable(); wfProfileOut( __METHOD__ ); - exit; + return; } + + # For ?curid=x urls, disallow indexing + if( $wgRequest->getInt('curid') ) + $wgOut->setRobotPolicy( 'noindex,follow' ); # We're looking at an old revision if( !empty( $oldid ) ) { @@ -834,8 +915,9 @@ class Article { // FIXME: This would be a nice place to load the 'no such page' text. } else { $this->setOldSubtitle( isset($this->mOldId) ? $this->mOldId : $oldid ); + # Allow admins to see deleted content if explicitly requested if( $this->mRevision->isDeleted( Revision::DELETED_TEXT ) ) { - if( !$this->mRevision->userCan( Revision::DELETED_TEXT ) ) { + if( !$unhide || !$this->mRevision->userCan(Revision::DELETED_TEXT) ) { $wgOut->addWikiMsg( 'rev-deleted-text-permission' ); $wgOut->setPageTitle( $this->mTitle->getPrefixedText() ); wfProfileOut( __METHOD__ ); @@ -862,7 +944,7 @@ class Article { $wgOut->addHTML( htmlspecialchars( $this->mContent ) ); $wgOut->addHTML( "\n\n" ); } - } else if( $rt = Title::newFromRedirect( $text ) ) { + } else if( $rt = Title::newFromRedirectArray( $text ) ) { # get an array of redirect targets # Don't append the subtitle if this was an old revision $wgOut->addHTML( $this->viewRedirect( $rt, !$wasRedirected && $this->isCurrent() ) ); $parseout = $wgParser->parse($text, $this->mTitle, ParserOptions::newFromUser($wgUser)); @@ -914,7 +996,7 @@ class Article { # If we have been passed an &rcid= parameter, we want to give the user a # chance to mark this new article as patrolled. - if( !is_null( $rcid ) && $rcid != 0 && $wgUser->isAllowed( 'patrol' ) && $this->mTitle->exists() ) { + if( !empty($rcid) && $this->mTitle->exists() && $this->mTitle->quickUserCan('patrol') ) { $wgOut->addHTML( "