<?php
-
/**
- * Special page allowing users to view their own contributions
- * and those of others.
- *
- * @package MediaWiki
- * @subpackage Special pages
+ * Special:Contributions, show user contributions in a paged list
+ * @addtogroup SpecialPage
*/
-class ContributionsPage extends QueryPage {
- var $user = null;
- var $namespace = null;
- var $botmode = false;
- /**
- * Constructor.
- * @param $username username to list contribs for (or "newbies" for extra magic)
- */
- function __construct( $username='' ) {
- $this->user = User::newFromName( $username, false );
- }
+class ContribsPager extends IndexPager {
+ public $mDefaultDirection = true;
+ var $messages, $target;
+ var $namespace = '', $mDb;
- /**
- * @return string Name of this special page.
- */
- function getName() {
- return 'Contributions';
+ function __construct( $target, $namespace = false, $year = false, $month = false ) {
+ parent::__construct();
+ foreach( explode( ' ', 'uctop diff newarticle rollbacklink diff hist minoreditletter' ) as $msg ) {
+ $this->messages[$msg] = wfMsgExt( $msg, array( 'escape') );
+ }
+ $this->target = $target;
+ $this->namespace = $namespace;
+
+ $year = intval($year);
+ $month = intval($month);
+
+ $this->year = ($year > 0 && $year < 10000) ? $year : false;
+ $this->month = ($month > 0 && $month < 13) ? $month : false;
+ $this->getDateCond();
+
+ $this->mDb = wfGetDB( DB_SLAVE, 'contributions' );
}
- /**
- * Not expensive, won't work with the query cache anyway.
- */
- function isExpensive() { return false; }
-
- /**
- * Should we?
- */
- function isSyndicated() { return false; }
-
- /**
- * Get target user name. May be overridden in subclasses.
- * @return string username
- */
- function getUsername() {
- return $this->user->getName();
+ function getDefaultQuery() {
+ $query = parent::getDefaultQuery();
+ $query['target'] = $this->target;
+ return $query;
}
- /**
- * @return array Extra URL params for self-links.
- */
- function linkParameters() {
- $params['target'] = $this->getUsername();
-
- if ( isset($this->namespace) )
- $params['namespace'] = $this->namespace;
+ function getQueryInfo() {
+ list( $index, $userCond ) = $this->getUserCond();
+ $conds = array_merge( array('page_id=rev_page'), $userCond, $this->getNamespaceCond() );
+
+ return array(
+ 'tables' => array( 'page', 'revision' ),
+ 'fields' => array(
+ 'page_namespace', 'page_title', 'page_is_new', 'page_latest', 'rev_id', 'rev_page',
+ 'rev_text_id', 'rev_timestamp', 'rev_comment', 'rev_minor_edit', 'rev_user',
+ 'rev_user_text', 'rev_deleted'
+ ),
+ 'conds' => $conds,
+ 'options' => array( 'FORCE INDEX' => $index )
+ );
+ }
- if ( $this->botmode )
- $params['bot'] = 1;
+ function getUserCond() {
+ $condition = array();
- return $params;
+ if ( $this->target == 'newbies' ) {
+ $max = $this->mDb->selectField( 'user', 'max(user_id)', false, __METHOD__ );
+ $condition[] = 'rev_user >' . (int)($max - $max / 100);
+ $index = 'user_timestamp';
+ } else {
+ $condition['rev_user_text'] = $this->target;
+ $index = 'usertext_timestamp';
+ }
+ return array( $index, $condition );
}
- /**
- * Build the list of links to be shown in the subtitle.
- * @return string Link list for "contribsub" UI message.
- */
- function getTargetUserLinks() {
- global $wgSysopUserBans, $wgLang, $wgUser;
+ function getNamespaceCond() {
+ if ( $this->namespace !== '' ) {
+ return array( 'page_namespace' => (int)$this->namespace );
+ } else {
+ return array();
+ }
+ }
+
+ function getDateCond() {
+ if ( $this->year || $this->month ) {
+ // Assume this year if only a month is given
+ if ( $this->year ) {
+ $year_start = $this->year;
+ } else {
+ $year_start = substr( wfTimestampNow(), 0, 4 );
+ $thisMonth = gmdate( 'n' );
+ if( $this->month > $thisMonth ) {
+ // Future contributions aren't supposed to happen. :)
+ $year_start--;
+ }
+ }
+
+ if ( $this->month ) {
+ $month_end = str_pad($this->month + 1, 2, '0', STR_PAD_LEFT);
+ $year_end = $year_start;
+ } else {
+ $month_end = 0;
+ $year_end = $year_start + 1;
+ }
+ $ts_end = str_pad($year_end . $month_end, 14, '0' );
+
+ $this->mOffset = $ts_end;
+ }
+ }
- $skin = $wgUser->getSkin();
+ function getIndexField() {
+ return 'rev_timestamp';
+ }
- $username = $this->getUsername();
- $userpage = $this->user->getUserPage();
- $userlink = $skin->makeLinkObj( $userpage, $username );
+ function getStartBody() {
+ return "<ul>\n";
+ }
- // talk page link
- $tools[] = $skin->makeLinkObj( $userpage->getTalkPage(), $wgLang->getNsText( NS_TALK ) );
+ function getEndBody() {
+ return "</ul>\n";
+ }
- // block or block log link
- $id = $this->user->getId();
- if ( ( $id != 0 && $wgSysopUserBans ) || ( $id == 0 && User::isIP( $username ) ) ) {
- if( $wgUser->isAllowed( 'block' ) )
- $tools[] = $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Blockip', $username ),
- wfMsgHtml( 'blocklink' ) );
- else
- $tools[] = $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Log' ),
- htmlspecialchars( LogPage::logName( 'block' ) ),
- 'type=block&page=' . $userpage->getPrefixedUrl() );
+ function getNavigationBar() {
+ if ( isset( $this->mNavigationBar ) ) {
+ return $this->mNavigationBar;
}
-
- // other logs link
- $tools[] = $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Log' ),
- wfMsgHtml( 'log' ),
- 'user=' . $userpage->getPartialUrl() );
-
- return $userlink . ' (' . implode( ' | ', $tools ) . ')';
+ $linkTexts = array(
+ 'prev' => wfMsgHtml( "sp-contributions-newer", $this->mLimit ),
+ 'next' => wfMsgHtml( 'sp-contributions-older', $this->mLimit ),
+ 'first' => wfMsgHtml('sp-contributions-newest'),
+ 'last' => wfMsgHtml( 'sp-contributions-oldest' )
+ );
+
+ $pagingLinks = $this->getPagingLinks( $linkTexts );
+ $limitLinks = $this->getLimitLinks();
+ $limits = implode( ' | ', $limitLinks );
+
+ $this->mNavigationBar = "({$pagingLinks['first']} | {$pagingLinks['last']}) " .
+ wfMsgHtml("viewprevnext", $pagingLinks['prev'], $pagingLinks['next'], $limits);
+ return $this->mNavigationBar;
}
/**
- * Generate "For User (...)" message in subtitle. Calls
- * getTargetUserLinks() for most of the work.
- * @return string
+ * Generates each row in the contributions list.
+ *
+ * Contributions which are marked "top" are currently on top of the history.
+ * For these contributions, a [rollback] link is shown for users with sysop
+ * privileges. The rollback link restores the most recent version that was not
+ * written by the target user.
+ *
+ * @todo This would probably look a lot nicer in a table.
*/
- function getSubtitleForTarget() {
- return wfMsgHtml( 'contribsub', $this->getTargetUserLinks() );
- }
+ function formatRow( $row ) {
+ wfProfileIn( __METHOD__ );
- /**
- * If the user has deleted contributions and we are allowed to
- * view them, generate a link to Special:DeletedContributions.
- * @return string
- */
- function getDeletedContributionsLink() {
- global $wgUser;
+ global $wgLang, $wgUser;
- if( !$wgUser->isAllowed( 'deletedhistory' ) )
- return '';
+ $sk = $this->getSkin();
+ $rev = new Revision( $row );
- $dbr = wfGetDB( DB_SLAVE );
- $n = $dbr->selectField( 'archive', 'count(*)', array( 'ar_user_text' => $this->getUsername() ), __METHOD__ );
+ $page = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $link = $sk->makeKnownLinkObj( $page );
+ $difftext = $topmarktext = '';
+ if( $row->rev_id == $row->page_latest ) {
+ $topmarktext .= '<strong>' . $this->messages['uctop'] . '</strong>';
+ if( !$row->page_is_new ) {
+ $difftext .= '(' . $sk->makeKnownLinkObj( $page, $this->messages['diff'], 'diff=0' ) . ')';
+ } else {
+ $difftext .= $this->messages['newarticle'];
+ }
- if ( $n == 0 )
- return '';
+ if( $wgUser->isAllowed( 'rollback' ) ) {
+ $topmarktext .= ' '.$sk->generateRollback( $rev );
+ }
- $msg = wfMsg( ( $wgUser->isAllowed( 'delete' ) ? 'thisisdeleted' : 'viewdeleted' ),
- $wgUser->getSkin()->makeKnownLinkObj(
- SpecialPage::getTitleFor( 'DeletedContributions', $this->getUsername() ),
- wfMsgExt( 'restorelink', array( 'parsemag', 'escape' ), $n ) ) );
+ }
+ if( $rev->userCan( Revision::DELETED_TEXT ) ) {
+ $difftext = '(' . $sk->makeKnownLinkObj( $page, $this->messages['diff'], 'diff=prev&oldid='.$row->rev_id ) . ')';
+ } else {
+ $difftext = '(' . $this->messages['diff'] . ')';
+ }
+ $histlink='('.$sk->makeKnownLinkObj( $page, $this->messages['hist'], 'action=history' ) . ')';
- return "<p>$msg</p>";
- }
+ $comment = $sk->revComment( $rev );
+ $d = $wgLang->timeanddate( wfTimestamp( TS_MW, $row->rev_timestamp ), true );
+
+ if( $this->target == 'newbies' ) {
+ $userlink = ' . . ' . $sk->userLink( $row->rev_user, $row->rev_user_text );
+ $userlink .= ' (' . $sk->userTalkLink( $row->rev_user, $row->rev_user_text ) . ') ';
+ } else {
+ $userlink = '';
+ }
- /**
- * Construct and output the page subtitle.
- */
- function outputSubtitle() {
- global $wgOut;
- $subtitle = $this->getSubtitleForTarget();
- // $subtitle .= $this->getDeletedContributionsLink(); NOT YET...
- $wgOut->setSubtitle( $subtitle );
- }
+ if( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+ $d = '<span class="history-deleted">' . $d . '</span>';
+ }
+
+ if( $row->rev_minor_edit ) {
+ $mflag = '<span class="minor">' . $this->messages['minoreditletter'] . '</span> ';
+ } else {
+ $mflag = '';
+ }
+ $ret = "{$d} {$histlink} {$difftext} {$mflag} {$link}{$userlink}{$comment} {$topmarktext}";
+ if( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+ $ret .= ' ' . wfMsgHtml( 'deletedrev' );
+ }
+ $ret = "<li>$ret</li>\n";
+ wfProfileOut( __METHOD__ );
+ return $ret;
+ }
+
/**
- * Construct the namespace selector form.
- * @return string
+ * Get the Database object in use
+ *
+ * @return Database
*/
- function getNamespaceForm() {
- $title = $this->getTitle();
-
- $ns = $this->namespace;
- if ( !isset($ns) )
- $ns = '';
+ public function getDatabase() {
+ return $this->mDb;
+ }
+
+}
- $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $title->getLocalUrl() ) );
- $form .= wfMsgHtml( 'namespace' ) . ' ';
- $form .= Xml::namespaceSelector( $ns, '' ) . ' ';
- $form .= Xml::submitButton( wfMsg( 'allpagessubmit' ) );
- $form .= Xml::hidden( 'offset', $this->offset );
- $form .= Xml::hidden( 'limit', $this->limit );
- $form .= Xml::hidden( 'target', $this->getUsername() );
- if ( $this->botmode )
- $form .= Xml::hidden( 'bot', 1 );
- $form .= '</form>';
+/**
+ * Special page "user contributions".
+ * Shows a list of the contributions of a user.
+ *
+ * @return none
+ * @param $par String: (optional) user name of the user for which to show the contributions
+ */
+function wfSpecialContributions( $par = null ) {
+ global $wgUser, $wgOut, $wgLang, $wgRequest;
- return '<p>' . $form . '</p>';
+ $options = array();
+
+ if ( isset( $par ) && $par == 'newbies' ) {
+ $target = 'newbies';
+ $options['contribs'] = 'newbie';
+ } elseif ( isset( $par ) ) {
+ $target = $par;
+ } else {
+ $target = $wgRequest->getVal( 'target' );
}
- /**
- * Build the page header. Also calls outputSubtitle().
- * @return string
- */
- function getPageHeader() {
- $this->outputSubtitle();
- return $this->getNamespaceForm();
+ // check for radiobox
+ if ( $wgRequest->getVal( 'contribs' ) == 'newbie' ) {
+ $target = 'newbies';
+ $options['contribs'] = 'newbie';
}
- /**
- * Construct the WHERE clause of the SQL SELECT statement for
- * this query.
- * @return string
- */
- function makeSQLCond( $dbr ) {
- $cond = ' page_id = rev_page';
- $cond .= ' AND rev_user_text = ' . $dbr->addQuotes( $this->getUsername() );
+ if ( !strlen( $target ) ) {
+ $wgOut->addHTML( contributionsForm( '' ) );
+ return;
+ }
- if ( isset($this->namespace) )
- $cond .= ' AND page_namespace = ' . (int)$this->namespace;
+ $options['limit'] = $wgRequest->getInt( 'limit', 50 );
+ $options['target'] = $target;
- return $cond;
+ $nt = Title::makeTitleSafe( NS_USER, $target );
+ if ( !$nt ) {
+ $wgOut->addHTML( contributionsForm( '' ) );
+ return;
}
+ $id = User::idFromName( $nt->getText() );
- /**
- * Construct the SQL SELECT statement for this query.
- * @return string
- */
- function getSQL() {
- $dbr = wfGetDB( DB_SLAVE );
+ if ( $target != 'newbies' ) {
+ $target = $nt->getText();
+ $wgOut->setSubtitle( contributionsSub( $nt, $id ) );
+ } else {
+ $wgOut->setSubtitle( wfMsgHtml( 'sp-contributions-newbies-sub') );
+ }
+
+ if ( ( $ns = $wgRequest->getVal( 'namespace', null ) ) !== null && $ns !== '' ) {
+ $options['namespace'] = intval( $ns );
+ } else {
+ $options['namespace'] = '';
+ }
+ if ( $wgUser->isAllowed( 'rollback' ) && $wgRequest->getBool( 'bot' ) ) {
+ $options['bot'] = '1';
+ }
+
+ $skip = $wgRequest->getText( 'offset' ) || $wgRequest->getText( 'dir' ) == 'prev';
+ # Offset overrides year/month selection
+ if ( ( $month = $wgRequest->getIntOrNull( 'month' ) ) !== null && $month !== -1 ) {
+ $options['month'] = intval( $month );
+ } else {
+ $options['month'] = '';
+ }
+ if ( ( $year = $wgRequest->getIntOrNull( 'year' ) ) !== null ) {
+ $options['year'] = intval( $year );
+ } else if( $options['month'] ) {
+ $thisMonth = intval( gmdate( 'n' ) );
+ $thisYear = intval( gmdate( 'Y' ) );
+ if( intval( $options['month'] ) > $thisMonth ) {
+ $thisYear--;
+ }
+ $options['year'] = $thisYear;
+ } else {
+ $options['year'] = '';
+ }
- list( $page, $revision ) = $dbr->tableNamesN( 'page', 'revision' );
+ wfRunHooks( 'SpecialContributionsBeforeMainOutput', $id );
- // XXX: the username and userid fields aren't used for much here,
- // but some subclasses rely on them more than we do.
+ $wgOut->addHTML( contributionsForm( $options ) );
+ # Show original selected options, don't apply them so as to allow paging
+ $_GET['year'] = ''; // hack for Pager
+ $_GET['month'] = ''; // hack for Pager
+ if( $skip ) {
+ $options['year'] = '';
+ $options['month'] = '';
+ }
- return "SELECT 'Contributions' as type,
- page_namespace AS namespace,
- page_title AS title,
- rev_timestamp AS value,
- rev_user AS userid,
- rev_user_text AS username,
- rev_minor_edit AS is_minor,
- page_latest AS cur_id,
- rev_id AS rev_id,
- rev_comment AS comment,
- rev_deleted AS deleted
- FROM $page, $revision
- WHERE " . $this->makeSQLCond( $dbr );
+ $pager = new ContribsPager( $target, $options['namespace'], $options['year'], $options['month'] );
+ if ( !$pager->getNumRows() ) {
+ $wgOut->addWikiText( wfMsg( 'nocontribs' ) );
+ return;
}
- /**
- * Get user links for output row, for subclasses that may want
- * such functionality.
- *
- * @param $skin Skin to use
- * @param $row Result row
- * @return string
- */
- function getRowUserLinks( $skin, $row ) { return ''; }
+ # Show a message about slave lag, if applicable
+ if( ( $lag = $pager->getDatabase()->getLag() ) > 0 )
+ $wgOut->showLagWarning( $lag );
- /**
- * Format a row, providing the timestamp, links to the
- * page/diff/history and a comment
- *
- * @param $skin Skin to use
- * @param $row Result row
- * @return string
- */
- function formatResult( $skin, $row ) {
- global $wgLang, $wgContLang, $wgUser;
-
- $dm = $wgContLang->getDirMark();
-
- /*
- * Cache UI messages in a static array so we don't
- * have to regenerate them for each row.
- */
- static $messages;
- if( !isset( $messages ) ) {
- foreach( explode( ' ', 'uctop diff newarticle rollbacklink diff hist minoreditletter' ) as $msg )
- $messages[$msg] = wfMsgExt( $msg, array( 'escape') );
+ $wgOut->addHTML(
+ '<p>' . $pager->getNavigationBar() . '</p>' .
+ $pager->getBody() .
+ '<p>' . $pager->getNavigationBar() . '</p>' );
+
+ # If there were contributions, and it was a valid user or IP, show
+ # the appropriate "footer" message - WHOIS tools, etc.
+ if( $target != 'newbies' ) {
+ $message = IP::isIPAddress( $target )
+ ? 'sp-contributions-footer-anon'
+ : 'sp-contributions-footer';
+
+
+ $text = wfMsg( $message, $target );
+ if( !wfEmptyMsg( $message, $text ) && $text != '-' ) {
+ $wgOut->addHtml( '<div class="mw-contributions-footer">' );
+ $wgOut->addWikiText( $text );
+ $wgOut->addHtml( '</div>' );
}
+ }
+}
- $page = Title::makeTitle( $row->namespace, $row->title );
-
- /*
- * HACK: We need a revision object, so we make a very
- * heavily stripped-down one. All we really need are
- * the comment, the title and the deletion bitmask.
- */
- $rev = new Revision( array(
- 'comment' => $row->comment,
- 'deleted' => $row->deleted,
- 'user_text' => $row->username,
- 'user' => $row->userid,
- ) );
- $rev->setTitle( $page );
-
- $ts = wfTimestamp( TS_MW, $row->value );
- $time = $wgLang->timeAndDate( $ts, true );
- $hist = $skin->makeKnownLinkObj( $page, $messages['hist'], 'action=history' );
-
- if ( $rev->userCan( Revision::DELETED_TEXT ) )
- $diff = $skin->makeKnownLinkObj( $page, $messages['diff'], 'diff=prev&oldid=' . $row->rev_id );
- else
- $diff = $messages['diff'];
-
- if( $row->is_minor )
- $mflag = '<span class="minor">' . $messages['minoreditletter'] . '</span> ';
- else
- $mflag = '';
+/**
+ * Generates the subheading with links
+ * @param Title $nt Title object for the target
+ * @param integer $id User ID for the target
+ * @return String: appropriately-escaped HTML to be output literally
+ */
+function contributionsSub( $nt, $id ) {
+ global $wgSysopUserBans, $wgLang, $wgUser;
- $link = $skin->makeKnownLinkObj( $page );
- $comment = $skin->revComment( $rev );
+ $sk = $wgUser->getSkin();
- $user = $this->getRowUserLinks( $skin, $row ); // for subclasses
+ if ( 0 == $id ) {
+ $user = $nt->getText();
+ } else {
+ $user = $sk->makeLinkObj( $nt, htmlspecialchars( $nt->getText() ) );
+ }
+ $talk = $nt->getTalkPage();
+ if( $talk ) {
+ # Talk page link
+ $tools[] = $sk->makeLinkObj( $talk, wfMsgHtml( 'talkpagelinktext' ) );
+ if( ( $id != 0 && $wgSysopUserBans ) || ( $id == 0 && User::isIP( $nt->getText() ) ) ) {
+ # Block link
+ if( $wgUser->isAllowed( 'block' ) )
+ $tools[] = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'Blockip', $nt->getDBkey() ), wfMsgHtml( 'blocklink' ) );
+ # Block log link
+ $tools[] = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'Log' ), wfMsgHtml( 'sp-contributions-blocklog' ), 'type=block&page=' . $nt->getPrefixedUrl() );
+ }
+ # Other logs link
+ $tools[] = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'Log' ), wfMsgHtml( 'log' ), 'user=' . $nt->getPartialUrl() );
- $notes = '';
+ wfRunHooks( 'ContributionsToolLinks', array( $id, $nt, &$tools ) );
- if( $row->rev_id == $row->cur_id ) {
- $notes .= ' <strong>' . $messages['uctop'] . '</strong>';
+ $links = implode( ' | ', $tools );
+ }
- if( $wgUser->isAllowed( 'rollback' ) )
- $notes .= ' ' . $skin->generateRollback( $rev );
- }
-
- if( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
- $time = '<span class="history-deleted">' . $time . '</span>';
- $notes .= ' ' . wfMsgHtml( 'deletedrev' );
- }
-
- return "{$time} ({$hist}) ({$diff}) {$mflag} {$dm}{$link}{$user} {$comment}{$notes}";
+ // Old message 'contribsub' had one parameter, but that doesn't work for
+ // 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'.
+ if( wfEmptyMsg( 'contribsub', wfMsg( 'contribsub' ) ) ) {
+ return wfMsgHtml( 'contribsub2', $user, $links );
+ } else {
+ return wfMsgHtml( 'contribsub', "$user ($links)" );
}
}
/**
- * Show the special page.
+ * Generates the namespace selector form with hidden attributes.
+ * @param $options Array: the options to be included.
*/
-function wfSpecialContributions( $par = null ) {
- global $wgRequest, $wgUser, $wgOut;
+function contributionsForm( $options ) {
+ global $wgScript, $wgTitle, $wgRequest;
+
+ $options['title'] = $wgTitle->getPrefixedText();
+ if ( !isset( $options['target'] ) ) {
+ $options['target'] = '';
+ } else {
+ $options['target'] = str_replace( '_' , ' ' , $options['target'] );
+ }
- $username = ( isset($par) ? $par : $wgRequest->getVal( 'target' ) );
+ if ( !isset( $options['namespace'] ) ) {
+ $options['namespace'] = '';
+ }
- // compatibility hack
- if ( $username == 'newbies' ) {
- $wgOut->redirect( SpecialPage::getTitleFor( 'NewbieContributions' )->getFullURL() );
- return;
+ if ( !isset( $options['contribs'] ) ) {
+ $options['contribs'] = 'user';
+ }
+
+ if ( !isset( $options['year'] ) ) {
+ $options['year'] = '';
}
- $page = new ContributionsPage( $username );
+ if ( !isset( $options['month'] ) ) {
+ $options['month'] = '';
+ }
- if( !$page->user ) {
- $wgOut->showErrorPage( 'notargettitle', 'notargettext' );
- return;
+ if ( $options['contribs'] == 'newbie' ) {
+ $options['target'] = '';
}
- // hook for Contributionseditcount extension
- if ( $page->user && $page->user->isLoggedIn() )
- wfRunHooks( 'SpecialContributionsBeforeMainOutput', $page->user->getId() );
-
- $page->namespace = $wgRequest->getIntOrNull( 'namespace' );
- $page->botmode = ( $wgUser->isAllowed( 'rollback' ) && $wgRequest->getBool( 'bot' ) );
+ $f = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) );
+
+ foreach ( $options as $name => $value ) {
+ if ( in_array( $name, array( 'namespace', 'target', 'contribs', 'year', 'month' ) ) ) {
+ continue;
+ }
+ $f .= "\t" . Xml::hidden( $name, $value ) . "\n";
+ }
+
+ $f .= '<fieldset>' .
+ Xml::element( 'legend', array(), wfMsg( 'sp-contributions-search' ) ) .
+ Xml::radioLabel( wfMsgExt( 'sp-contributions-newbies', array( 'parseinline' ) ), 'contribs' , 'newbie' , 'newbie', $options['contribs'] == 'newbie' ? true : false ) . '<br />' .
+ Xml::radioLabel( wfMsgExt( 'sp-contributions-username', array( 'parseinline' ) ), 'contribs' , 'user', 'user', $options['contribs'] == 'user' ? true : false ) . ' ' .
+ Xml::input( 'target', 20, $options['target']) . ' '.
+ Xml::label( wfMsg( 'namespace' ), 'namespace' ) .
+ Xml::namespaceSelector( $options['namespace'], '' ) .
+ Xml::openElement( 'p' ) .
+ Xml::label( wfMsg( 'year' ), 'year' ) . ' '.
+ Xml::input( 'year', 4, $options['year'], array('id' => 'year', 'maxlength' => 4) ) . ' '.
+ Xml::label( wfMsg( 'month' ), 'month' ) . ' '.
+ Xml::monthSelector( $options['month'], -1 ) . ' '.
+ Xml::submitButton( wfMsg( 'sp-contributions-submit' ) ) .
+ Xml::closeElement( 'p' );
- list( $limit, $offset ) = wfCheckLimits();
- return $page->doQuery( $offset, $limit );
+ $explain = wfMsgExt( 'sp-contributions-explain', 'parseinline' );
+ if( !wfEmptyMsg( 'sp-contributions-explain', $explain ) )
+ $f .= "<p>{$explain}</p>";
+
+ $f .= '</fieldset>' .
+ Xml::closeElement( 'form' );
+ return $f;
}
-
-?>