$this->opts = array();
$request = $this->getRequest();
- if ( $par == 'newbies' ) {
- $target = 'newbies';
- $this->opts['contribs'] = 'newbie';
- } elseif ( $par !== null ) {
+ if ( $par !== null ) {
$target = $par;
} else {
$target = $request->getVal( 'target' );
if ( $request->getVal( 'contribs' ) == 'newbie' ) {
$target = 'newbies';
$this->opts['contribs'] = 'newbie';
+ } elseif ( $par === 'newbies' ) { // b/c for WMF
+ $target = 'newbies';
+ $this->opts['contribs'] = 'newbie';
} else {
$this->opts['contribs'] = 'user';
}
$this->opts['target'] = $target;
$this->opts['topOnly'] = $request->getBool( 'topOnly' );
- $userObj = User::newFromName( $target, false );
+ $nt = Title::makeTitleSafe( NS_USER, $target );
+ if ( !$nt ) {
+ $out->addHTML( $this->getForm() );
+ return;
+ }
+ $userObj = User::newFromName( $nt->getText(), false );
if ( !$userObj ) {
$out->addHTML( $this->getForm() );
return;
}
- $nt = $userObj->getUserPage();
$id = $userObj->getID();
if ( $this->opts['contribs'] != 'newbie' ) {
$target = $nt->getText();
$out->addSubtitle( $this->contributionsSub( $userObj ) );
- $out->setHTMLTitle( $this->msg( 'pagetitle', wfMsgExt( 'contributions-title', array( 'parsemag' ), $target ) ) );
+ $out->setHTMLTitle( $this->msg( 'pagetitle', $this->msg( 'contributions-title', $target )->plain() ) );
$this->getSkin()->setRelevantUser( $userObj );
} else {
$out->addSubtitle( $this->msg( 'sp-contributions-newbies-sub' ) );
- $out->setHTMLTitle( $this->msg( 'pagetitle', wfMsg( 'sp-contributions-newbies-title' ) ) );
+ $out->setHTMLTitle( $this->msg( 'pagetitle', $this->msg( 'sp-contributions-newbies-title' )->plain() ) );
}
if ( ( $ns = $request->getVal( 'namespace', null ) ) !== null && $ns !== '' ) {
$out->addHTML( $this->getForm() );
- $pager = new ContribsPager( array(
+ $pager = new ContribsPager( $this->getContext(), array(
'target' => $target,
'contribs' => $this->opts['contribs'],
'namespace' => $this->opts['namespace'],
}
$out->preventClickjacking( $pager->getPreventClickjacking() );
+
# Show the appropriate "footer" message - WHOIS tools, etc.
- if ( $this->opts['contribs'] != 'newbie' ) {
+ if ( $this->opts['contribs'] == 'newbie' ) {
+ $message = 'sp-contributions-footer-newbies';
+ } elseif( IP::isIPAddress( $target ) ) {
+ $message = 'sp-contributions-footer-anon';
+ } elseif( $userObj->isAnon() ) {
+ // No message for non-existing users
+ $message = '';
+ } else {
$message = 'sp-contributions-footer';
- if ( IP::isIPAddress( $target ) ) {
- $message = 'sp-contributions-footer-anon';
- } else {
- if ( $userObj->isAnon() ) {
- // No message for non-existing users
- return;
- }
- }
+ }
- if ( !wfMessage( $message, $target )->isDisabled() ) {
+ if( $message ) {
+ if ( !$this->msg( $message, $target )->isDisabled() ) {
$out->wrapWikiMsg(
"<div class='mw-contributions-footer'>\n$1\n</div>",
array( $message, $target ) );
}
$nt = $userObj->getUserPage();
$talk = $userObj->getTalkPage();
+ $links = '';
if ( $talk ) {
- $tools = self::getUserLinks( $nt, $talk, $userObj, $this->getUser() );
+ $tools = $this->getUserLinks( $nt, $talk, $userObj );
$links = $this->getLanguage()->pipeList( $tools );
// Show a note if the user is blocked and display the last block log entry.
- if ( $userObj->isBlocked() ) {
+ // Do not expose the autoblocks, since that may lead to a leak of accounts' IPs,
+ // and also this will display a totally irrelevant log entry as a current block.
+ if ( $userObj->isBlocked() && $userObj->getBlock()->getType() != Block::TYPE_AUTO ) {
$out = $this->getOutput(); // showLogExtract() wants first parameter by reference
LogEventsList::showLogExtract(
$out,
// languages that want to put the "for" bit right after $user but before
// $links. If 'contribsub' is around, use it for reverse compatibility,
// otherwise use 'contribsub2'.
+ // @todo Should this be removed at some point?
$oldMsg = $this->msg( 'contribsub' );
if ( $oldMsg->exists() ) {
- return $oldMsg->rawParams( "$user ($links)" );
+ $linksWithParentheses = $this->msg( 'parentheses' )->rawParams( $links )->escaped();
+ return $oldMsg->rawParams( "$user $linksWithParentheses" );
} else {
return $this->msg( 'contribsub2' )->rawParams( $user, $links );
}
* @param $userpage Title: Target user page
* @param $talkpage Title: Talk page
* @param $target User: Target user object
- * @param $subject User: The viewing user ($wgUser might be still checked in some cases)
+ * @return array
*/
- public static function getUserLinks( Title $userpage, Title $talkpage, User $target, User $subject ) {
+ public function getUserLinks( Title $userpage, Title $talkpage, User $target ) {
$id = $target->getId();
$username = $target->getName();
- $tools[] = Linker::link( $talkpage, wfMsgHtml( 'sp-contributions-talk' ) );
+ $tools[] = Linker::link( $talkpage, $this->msg( 'sp-contributions-talk' )->escaped() );
if ( ( $id !== null ) || ( $id === null && IP::isIPAddress( $username ) ) ) {
- if ( $subject->isAllowed( 'block' ) ) { # Block / Change block / Unblock links
+ if ( $this->getUser()->isAllowed( 'block' ) ) { # Block / Change block / Unblock links
if ( $target->isBlocked() ) {
$tools[] = Linker::linkKnown( # Change block link
SpecialPage::getTitleFor( 'Block', $username ),
- wfMsgHtml( 'change-blocklink' )
+ $this->msg( 'change-blocklink' )->escaped()
);
$tools[] = Linker::linkKnown( # Unblock link
SpecialPage::getTitleFor( 'Unblock', $username ),
- wfMsgHtml( 'unblocklink' )
+ $this->msg( 'unblocklink' )->escaped()
);
} else { # User is not blocked
$tools[] = Linker::linkKnown( # Block link
SpecialPage::getTitleFor( 'Block', $username ),
- wfMsgHtml( 'blocklink' )
+ $this->msg( 'blocklink' )->escaped()
);
}
}
# Block log link
$tools[] = Linker::linkKnown(
SpecialPage::getTitleFor( 'Log', 'block' ),
- wfMsgHtml( 'sp-contributions-blocklog' ),
+ $this->msg( 'sp-contributions-blocklog' )->escaped(),
array(),
array(
'page' => $userpage->getPrefixedText()
# Uploads
$tools[] = Linker::linkKnown(
SpecialPage::getTitleFor( 'Listfiles', $username ),
- wfMsgHtml( 'sp-contributions-uploads' )
+ $this->msg( 'sp-contributions-uploads' )->escaped()
);
# Other logs link
$tools[] = Linker::linkKnown(
SpecialPage::getTitleFor( 'Log', $username ),
- wfMsgHtml( 'sp-contributions-logs' )
+ $this->msg( 'sp-contributions-logs' )->escaped()
);
# Add link to deleted user contributions for priviledged users
- if ( $subject->isAllowed( 'deletedhistory' ) ) {
+ if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
$tools[] = Linker::linkKnown(
SpecialPage::getTitleFor( 'DeletedContributions', $username ),
- wfMsgHtml( 'sp-contributions-deleted' )
+ $this->msg( 'sp-contributions-deleted' )->escaped()
);
}
# Add a link to change user rights for privileged users
$userrightsPage = new UserrightsPage();
- $userrightsPage->getContext()->setUser( $subject );
- if ( $id !== null && $userrightsPage->userCanChangeRights( $target ) ) {
+ $userrightsPage->setContext( $this->getContext() );
+ if ( $userrightsPage->userCanChangeRights( $target ) ) {
$tools[] = Linker::linkKnown(
SpecialPage::getTitleFor( 'Userrights', $username ),
- wfMsgHtml( 'sp-contributions-userrights' )
+ $this->msg( 'sp-contributions-userrights' )->escaped()
);
}
$targetSelection = Xml::tags( 'td', array( 'colspan' => 2 ),
Xml::radioLabel(
- wfMsgExt( 'sp-contributions-newbies', array( 'parsemag' ) ),
+ $this->msg( 'sp-contributions-newbies' )->text(),
'contribs',
'newbie' ,
'newbie',
array( 'class' => 'mw-input' )
) . '<br />' .
Xml::radioLabel(
- wfMsgExt( 'sp-contributions-username', array( 'parsemag' ) ),
+ $this->msg( 'sp-contributions-username' )->text(),
'contribs',
'user',
'user',
$namespaceSelection =
Xml::tags( 'td', array( 'class' => 'mw-label' ),
Xml::label(
- wfMsg( 'namespace' ),
+ $this->msg( 'namespace' )->text(),
'namespace',
''
)
) .
Xml::tags( 'td', null,
- Xml::namespaceSelector( $this->opts['namespace'], '' ) . ' ' .
+ Html::namespaceSelector( array(
+ 'selected' => $this->opts['namespace'],
+ 'all' => '',
+ ), array(
+ 'name' => 'namespace',
+ 'id' => 'namespace',
+ 'class' => 'namespaceselector',
+ ) ) .
+ ' ' .
Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
Xml::checkLabel(
- wfMsg( 'invert' ),
+ $this->msg( 'invert' )->text(),
'nsInvert',
'nsInvert',
$this->opts['nsInvert'],
- array( 'title' => wfMsg( 'tooltip-invert' ), 'class' => 'mw-input' )
+ array( 'title' => $this->msg( 'tooltip-invert' )->text(), 'class' => 'mw-input' )
) . ' '
) .
Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
Xml::checkLabel(
- wfMsg( 'namespace_association' ),
+ $this->msg( 'namespace_association' )->text(),
'associated',
'associated',
$this->opts['associated'],
- array( 'title' => wfMsg( 'tooltip-namespace_association' ), 'class' => 'mw-input' )
+ array( 'title' => $this->msg( 'tooltip-namespace_association' )->text(), 'class' => 'mw-input' )
) . ' '
)
) ;
$extraOptions = Xml::tags( 'td', array( 'colspan' => 2 ),
Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
Xml::checkLabel(
- wfMsg( 'history-show-deleted' ),
+ $this->msg( 'history-show-deleted' )->text(),
'deletedOnly',
'mw-show-deleted-only',
$this->opts['deletedOnly'],
) .
Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
Xml::checkLabel(
- wfMsg( 'sp-contributions-toponly' ),
+ $this->msg( 'sp-contributions-toponly' )->text(),
'topOnly',
'mw-show-top-only',
$this->opts['topOnly'],
$this->opts['month']
) . ' ' .
Xml::submitButton(
- wfMsg( 'sp-contributions-submit' ),
+ $this->msg( 'sp-contributions-submit' )->text(),
array( 'class' => 'mw-submit' )
)
) ;
$form .=
- Xml::fieldset( wfMsg( 'sp-contributions-search' ) ) .
+ Xml::fieldset( $this->msg( 'sp-contributions-search' )->text() ) .
Xml::openElement( 'table', array( 'class' => 'mw-contributions-table' ) ) .
Xml::openElement( 'tr' ) .
$targetSelection .
$filterSelection .
Xml::closeElement( 'tr' ) .
Xml::openElement( 'tr' ) .
- $extraOptions .
- Xml::closeElement( 'tr' ) .
- Xml::openElement( 'tr' ) .
+ $extraOptions .
+ Xml::closeElement( 'tr' ) .
+ Xml::openElement( 'tr' ) .
$dateSelectionAndSubmit .
Xml::closeElement( 'tr' ) .
Xml::closeElement( 'table' );
- $explain = wfMessage( 'sp-contributions-explain' );
+ $explain = $this->msg( 'sp-contributions-explain' );
if ( $explain->exists() ) {
$form .= "<p id='mw-sp-contributions-explain'>{$explain}</p>";
}
var $namespace = '', $mDb;
var $preventClickjacking = false;
- function __construct( $options ) {
- parent::__construct();
+ /**
+ * @var array
+ */
+ protected $mParentLens;
+
+ function __construct( IContextSource $context, array $options ) {
+ parent::__construct( $context );
$msgs = array( 'uctop', 'diff', 'newarticle', 'rollbacklink', 'diff', 'hist', 'rev-delundel', 'pipe-separator' );
foreach ( $msgs as $msg ) {
- $this->messages[$msg] = wfMsgExt( $msg, array( 'escapenoentities' ) );
+ $this->messages[$msg] = $this->msg( $msg )->escaped();
}
$this->target = isset( $options['target'] ) ? $options['target'] : '';
# @todo FIXME: Other groups may have 'bot' rights
$join_conds['user_groups'] = array( 'LEFT JOIN', "ug_user = rev_user AND ug_group = 'bot'" );
} else {
- if ( IP::isIPAddress( $this->target ) ) {
+ $uid = User::idFromName( $this->target );
+ if ( $uid ) {
+ $condition['rev_user'] = $uid;
+ $index = 'user_timestamp';
+ } else {
$condition['rev_user_text'] = $this->target;
$index = 'usertext_timestamp';
- } else {
- $condition['rev_user'] = User::idFromName( $this->target );
- $index = 'user_timestamp';
}
}
if ( $this->deletedOnly ) {
$this->mResult->rewind();
$revIds = array();
foreach ( $this->mResult as $row ) {
- $revIds[] = $row->rev_parent_id;
+ if( $row->rev_parent_id ) {
+ $revIds[] = $row->rev_parent_id;
+ }
}
$this->mParentLens = $this->getParentLengths( $revIds );
$this->mResult->rewind(); // reset
- if ( $this->contribs === 'newbie' ) { // multiple users
- # Do a link batch query
- $this->mResult->seek( 0 );
- $batch = new LinkBatch();
- # Give some pointers to make (last) links
- foreach ( $this->mResult as $row ) {
- $batch->addObj( Title::makeTitleSafe( NS_USER, $row->user_name ) );
- $batch->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->user_name ) );
+ # Do a link batch query
+ $this->mResult->seek( 0 );
+ $batch = new LinkBatch();
+ # Give some pointers to make (last) links
+ foreach ( $this->mResult as $row ) {
+ if ( $this->contribs === 'newbie' ) { // multiple users
+ $batch->add( NS_USER, $row->user_name );
+ $batch->add( NS_USER_TALK, $row->user_name );
}
- $batch->execute();
- $this->mResult->seek( 0 );
+ $batch->add( $row->page_namespace, $row->page_title );
}
+ $batch->execute();
+ $this->mResult->seek( 0 );
}
/**
* Do a batched query to get the parent revision lengths
+ * @param $revIds array
+ * @return array
*/
private function getParentLengths( array $revIds ) {
$revLens = array();
return $revLens;
}
+ /**
+ * @return string
+ */
function getStartBody() {
return "<ul>\n";
}
+ /**
+ * @return string
+ */
function getEndBody() {
return "</ul>\n";
}
* was not written by the target user.
*
* @todo This would probably look a lot nicer in a table.
+ * @param $row
+ * @return string
*/
function formatRow( $row ) {
wfProfileIn( __METHOD__ );
array( 'action' => 'history' )
);
- if ( isset( $this->mParentLens[$row->rev_parent_id] ) ) {
- $chardiff = ' . . ' . ChangesList::showCharacterDifference(
- $this->mParentLens[$row->rev_parent_id], $row->rev_len ) . ' . . ';
+ if ( $row->rev_parent_id === null ) {
+ // For some reason rev_parent_id isn't populated for this row.
+ // Its rumoured this is true on wikipedia for some revisions (bug 34922).
+ // Next best thing is to have the total number of bytes.
+ $chardiff = ' . . ' . Linker::formatRevisionSize( $row->rev_len ) . ' . . ';
} else {
- $chardiff = ' ';
+ $parentLen = isset( $this->mParentLens[$row->rev_parent_id] ) ? $this->mParentLens[$row->rev_parent_id] : 0;
+ $chardiff = ' . . ' . ChangesList::showCharacterDifference(
+ $parentLen, $row->rev_len ) . ' . . ';
}
- $comment = $this->getLanguage()->getDirMark() . Linker::revComment( $rev, false, true );
- $date = $this->getLanguage()->timeanddate( wfTimestamp( TS_MW, $row->rev_timestamp ), true );
+ $lang = $this->getLanguage();
+ $comment = $lang->getDirMark() . Linker::revComment( $rev, false, true );
+ $date = $lang->userTimeAndDate( $row->rev_timestamp, $user );
if ( $rev->userCan( Revision::DELETED_TEXT, $user ) ) {
$d = Linker::linkKnown(
$page,
# Note that we already excluded rows with hidden user names.
if ( $this->contribs == 'newbie' ) {
$userlink = ' . . ' . Linker::userLink( $rev->getUser(), $rev->getUserText() );
- $userlink .= ' ' . wfMsg( 'parentheses',
- Linker::userTalkLink( $rev->getUser(), $rev->getUserText() ) ) . ' ';
+ $userlink .= ' ' . $this->msg( 'parentheses' )->rawParams(
+ Linker::userTalkLink( $rev->getUser(), $rev->getUserText() ) )->escaped() . ' ';
} else {
$userlink = '';
}
$mflag = '';
}
- // Don't show useless link to people who cannot hide revisions
- $canHide = $user->isAllowed( 'deleterevision' );
- if ( $canHide || ( $rev->getVisibility() && $user->isAllowed( 'deletedhistory' ) ) ) {
- if ( !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
- $del = Linker::revDeleteLinkDisabled( $canHide ); // revision was hidden from sysops
- } else {
- $query = array(
- 'type' => 'revision',
- 'target' => $page->getPrefixedDbkey(),
- 'ids' => $rev->getId()
- );
- $del = Linker::revDeleteLink( $query,
- $rev->isDeleted( Revision::DELETED_RESTRICTED ), $canHide );
- }
+ $del = Linker::getRevDeleteLink( $user, $rev, $page );
+ if ( $del !== '' ) {
$del .= ' ';
- } else {
- $del = '';
}
- $diffHistLinks = '(' . $difftext . $this->messages['pipe-separator'] . $histlink . ')';
+ $diffHistLinks = $this->msg( 'parentheses' )->rawParams( $difftext . $this->messages['pipe-separator'] . $histlink )->escaped();
$ret = "{$del}{$d} {$diffHistLinks}{$chardiff}{$nflag}{$mflag} {$link}{$userlink} {$comment} {$topmarktext}";
# Denote if username is redacted for this edit
if ( $rev->isDeleted( Revision::DELETED_USER ) ) {
- $ret .= " <strong>" . wfMsgHtml( 'rev-deleted-user-contribs' ) . "</strong>";
+ $ret .= " <strong>" . $this->msg( 'rev-deleted-user-contribs' )->escaped() . "</strong>";
}
# Tags, if any.
/**
* Overwrite Pager function and return a helpful comment
+ * @return string
*/
function getSqlComment() {
if ( $this->namespace || $this->deletedOnly ) {
$this->preventClickjacking = true;
}
+ /**
+ * @return bool
+ */
public function getPreventClickjacking() {
return $this->preventClickjacking;
}