* @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() != '' ) {
if( wfEmptyMsg( $message, $text ) )
$text = '';
} else {
- $text = wfMsg( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon' );
+ $text = wfMsgExt( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon', 'parsemag' );
}
wfProfileOut( __METHOD__ );
return $text;
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).
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
}
// Apparently loadPageData was never called
$this->loadContent();
- $titleObj = Title::newFromRedirect( $this->fetchContent() );
+ $titleObj = Title::newFromRedirectRecurse( $this->fetchContent() );
} else {
$titleObj = Title::newFromRedirect( $text );
}
}
$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 );
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 );
$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' );
}
}
// for better machine handling of broken links.
$return404 = true;
}
- }
+ }
if( $return404 ) {
$wgRequest->response()->header( "HTTP/1.x 404 Not Found" );
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 ) ) {
// 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__ );
$wgOut->addHTML( htmlspecialchars( $this->mContent ) );
$wgOut->addHTML( "\n</pre>\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));
# If we have been passed an &rcid= parameter, we want to give the user a
# chance to mark this new article as patrolled.
- if( !empty($rcid) && $this->mTitle->exists() && $this->mTitle->userCan('patrol') ) {
+ if( !empty($rcid) && $this->mTitle->exists() && $this->mTitle->quickUserCan('patrol') ) {
$wgOut->addHTML(
"<div class='patrollink'>" .
wfMsgHtml( 'markaspatrolledlink',
/**
* View redirect
- * @param $target Title object of destination to redirect
+ * @param $target Title object or Array of destination(s) to redirect
* @param $appendSubtitle Boolean [optional]
* @param $forceKnown Boolean: should the image be shown as a bluelink regardless of existence?
*/
public function viewRedirect( $target, $appendSubtitle = true, $forceKnown = false ) {
global $wgParser, $wgOut, $wgContLang, $wgStylePath, $wgUser;
# Display redirect
+ if( !is_array( $target ) ) {
+ $target = array( $target );
+ }
$imageDir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
- $imageUrl = $wgStylePath.'/common/images/redirect' . $imageDir . '.png';
-
+ $imageUrl = $wgStylePath . '/common/images/redirect' . $imageDir . '.png';
+ $imageUrl2 = $wgStylePath . '/common/images/nextredirect' . $imageDir . '.png';
+ $alt2 = $wgContLang->isRTL() ? '←' : '→'; // should -> and <- be used instead of entities?
+
if( $appendSubtitle ) {
$wgOut->appendSubtitle( wfMsgHtml( 'redirectpagesub' ) );
}
$sk = $wgUser->getSkin();
+ // the loop prepends the arrow image before the link, so the first case needs to be outside
+ $title = array_shift( $target );
if( $forceKnown ) {
- $link = $sk->makeKnownLinkObj( $target, htmlspecialchars( $target->getFullText() ) );
+ $link = $sk->makeKnownLinkObj( $title, htmlspecialchars( $title->getFullText() ) );
} else {
- $link = $sk->makeLinkObj( $target, htmlspecialchars( $target->getFullText() ) );
+ $link = $sk->makeLinkObj( $title, htmlspecialchars( $title->getFullText() ) );
+ }
+ // automatically append redirect=no to each link, since most of them are redirect pages themselves
+ foreach( $target as $rt ) {
+ if( $forceKnown ) {
+ $link .= '<img src="'.$imageUrl2.'" alt="'.$alt2.' " />'
+ . $sk->makeKnownLinkObj( $rt, htmlspecialchars( $rt->getFullText() ) );
+ } else {
+ $link .= '<img src="'.$imageUrl2.'" alt="'.$alt2.' " />'
+ . $sk->makeLinkObj( $rt, htmlspecialchars( $rt->getFullText() ) );
+ }
}
return '<img src="'.$imageUrl.'" alt="#REDIRECT " />' .
'<span class="redirectText">'.$link.'</span>';
if( $this->getID() == 0 ) {
$text = false;
} else {
- $text = $this->getContent();
+ $text = $this->getRawText();
}
$wgMessageCache->replace( $this->mTitle->getDBkey(), $text );
}
$isminor = ( $flags & EDIT_MINOR ) && $user->isAllowed('minoredit');
$bot = $flags & EDIT_FORCE_BOT;
- $oldtext = $this->getContent();
+ $oldtext = $this->getRawText(); // current revision
$oldsize = strlen( $oldtext );
# Provide autosummaries if one is not provided and autosummaries are enabled.
# Update recentchanges
if( !( $flags & EDIT_SUPPRESS_RC ) ) {
# Mark as patrolled if the user can do so
- $patrolled = $wgUseRCPatrol && $user->isAllowed('autopatrol');
+ $patrolled = $wgUseRCPatrol && $this->mTitle->userCan('autopatrol');
# Add RC row to the DB
$rc = RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $user, $summary,
$this->mLatest, $this->getTimestamp(), $bot, '', $oldsize, $newsize,
if( !( $flags & EDIT_SUPPRESS_RC ) ) {
global $wgUseRCPatrol, $wgUseNPPatrol;
# Mark as patrolled if the user can do so
- $patrolled = ($wgUseRCPatrol || $wgUseNPPatrol) && $user->isAllowed('autopatrol');
+ $patrolled = ($wgUseRCPatrol || $wgUseNPPatrol) && $this->mTitle->userCan('autopatrol');
# Add RC row to the DB
$rc = RecentChange::notifyNew( $now, $this->mTitle, $isminor, $user, $summary, $bot,
'', strlen($text), $revisionId, $patrolled );
}
#It would be nice to see where the user had actually come from, but for now just guess
- $returnto = $rc->getAttribute( 'rc_type' ) == RC_NEW ? 'Newpages' : 'Recentchanges';
- $return = Title::makeTitle( NS_SPECIAL, $returnto );
+ $returnto = $rc->getAttribute( 'rc_type' ) == RC_NEW ? 'newpages' : 'recentchanges';
+ $return = SpecialPage::getTitleFor( $returnto );
$dbw = wfGetDB( DB_MASTER );
$errors = $rc->doMarkPatrolled();
$protect_description .= "[$action=$restrictions] (";
if( $encodedExpiry[$action] != 'infinity' ) {
$protect_description .= wfMsgForContent( 'protect-expiring',
- $wgContLang->timeanddate( $expiry[$action], false, false ) );
+ $wgContLang->timeanddate( $expiry[$action], false, false ) ,
+ $wgContLang->date( $expiry[$action], false, false ) ,
+ $wgContLang->time( $expiry[$action], false, false ) );
} else {
$protect_description .= wfMsgForContent( 'protect-expiry-indefinite' );
}
if( $reason != 'other' && $this->DeleteReason != '' ) {
// Entry from drop down menu + additional comment
- $reason .= ': ' . $this->DeleteReason;
+ $reason .= wfMsgForContent( 'colon-separator' ) . $this->DeleteReason;
} elseif( $reason == 'other' ) {
$reason = $this->DeleteReason;
}
$latest = $dbw->selectField( 'page', 'page_latest', $conds, __METHOD__ );
if( $latest === false ) {
$wgOut->showFatalError( wfMsgExt( 'cannotdelete', array( 'parse' ) ) );
+ $wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
+ LogEventsList::showLogExtract( $wgOut, 'delete', $this->mTitle->getPrefixedText() );
return;
}
$wgOut->returnToMain( false );
wfRunHooks('ArticleDeleteComplete', array(&$this, &$wgUser, $reason, $id));
} else {
- if( $error == '' )
+ if( $error == '' ) {
$wgOut->showFatalError( wfMsgExt( 'cannotdelete', array( 'parse' ) ) );
- else
+ $wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
+ LogEventsList::showLogExtract( $wgOut, 'delete', $this->mTitle->getPrefixedText() );
+ } else {
$wgOut->showFatalError( $error );
+ }
}
}
}
return false;
}
- $u = new SiteStatsUpdate( 0, 1, -(int)$this->isCountable( $this->getContent() ), -1 );
+ $u = new SiteStatsUpdate( 0, 1, -(int)$this->isCountable( $this->getRawText() ), -1 );
array_push( $wgDeferredUpdateList, $u );
// Bitfields to further suppress the content
$revId = false;
}
- wfRunHooks( 'ArticleRollbackComplete', array( $this, $wgUser, $target ) );
+ wfRunHooks( 'ArticleRollbackComplete', array( $this, $wgUser, $target, $current ) );
$resultDetails = array(
'summary' => $summary,
* @param $oldid String: revision ID of this article revision
*/
public function setOldSubtitle( $oldid = 0 ) {
- global $wgLang, $wgOut, $wgUser;
+ global $wgLang, $wgOut, $wgUser, $wgRequest;
if( !wfRunHooks( 'DisplayOldSubtitle', array( &$this, &$oldid ) ) ) {
return;
}
$cdel = "(<small>$cdel</small>) ";
}
- # Show user links if allowed to see them. Normally they
- # are hidden regardless, but since we can already see the text here...
- $userlinks = $sk->revUserTools( $revision, false );
+ $unhide = $wgRequest->getInt('unhide') == 1 && $wgUser->matchEditToken( $wgRequest->getVal('token'), $oldid );
+ # 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 != '-'
? 'revision-info-current'
: 'revision-info';
- $r = "\n\t\t\t\t<div id=\"mw-{$infomsg}\">" . wfMsgExt( $infomsg, array( 'parseinline', 'replaceafter' ), $td, $userlinks, $revision->getID() ) . "</div>\n" .
+ $r = "\n\t\t\t\t<div id=\"mw-{$infomsg}\">" . wfMsgExt( $infomsg, array( 'parseinline', 'replaceafter' ),
+ $td, $userlinks, $revision->getID() ) . "</div>\n" .
"\n\t\t\t\t<div id=\"mw-revision-nav\">" . $cdel . wfMsgHtml( 'revision-nav', $prevdiff,
$prevlink, $lnk, $curdiff, $nextlink, $nextdiff ) . "</div>\n\t\t\t";
}
public static function onArticleDelete( $title ) {
- global $wgUseFileCache, $wgMessageCache;
+ global $wgMessageCache;
# Update existence markers on article/talk tabs...
if( $title->isTalkPage() ) {
$other = $title->getSubjectPage();
$title->purgeSquid();
# File cache
- if( $wgUseFileCache ) {
- $cm = new HTMLFileCache( $title );
- @unlink( $cm->fileCacheName() );
- }
+ HTMLFileCache::clearFileCache( $title );
# Messages
if( $title->getNamespace() == NS_MEDIAWIKI ) {
* Purge caches on page update etc
*/
public static function onArticleEdit( $title, $transclusions = 'transclusions' ) {
- global $wgDeferredUpdateList, $wgUseFileCache;
+ global $wgDeferredUpdateList;
// Invalidate caches of articles which include this page
if( $transclusions !== 'skiptransclusions' )
$title->purgeSquid();
# Clear file cache for this page only
- if( $wgUseFileCache ) {
- $cm = new HTMLFileCache( $title );
- @unlink( $cm->fileCacheName() );
- }
+ HTMLFileCache::clearFileCache( $title );
}
/**#@-*/