X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FSpecialContributions.php;h=d2d9b03f8f2113660ce38af5e37d264eb89e6bce;hb=e66412fc34f5f3a0721062c00545be78833bf3cd;hp=bc448882a241942878af1e0362dcf1eecd3a6986;hpb=1be20cc1be746c5b5c29da2aa8dd3c7fd9649f6f;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/SpecialContributions.php b/includes/SpecialContributions.php index bc448882a2..d2d9b03f8f 100644 --- a/includes/SpecialContributions.php +++ b/includes/SpecialContributions.php @@ -1,186 +1,173 @@ username = $username; - $this->namespace = false; - $this->dbr = wfGetDB( DB_SLAVE, 'contributions' ); - } - - function setNamespace( $ns ) { - $this->namespace = $ns; - } - - function setLimit( $limit ) { - $this->limit = $limit; + function __construct( $target, $namespace = 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; + $this->mDb = wfGetDB( DB_SLAVE, 'contributions' ); } - function setOffset( $offset ) { - $this->offset = $offset; + function getDefaultQuery() { + $query = parent::getDefaultQuery(); + $query['target'] = $this->target; + return $query; } - /** - * Get timestamp of either first or last contribution made by the user. - * @todo Maybe it should be private ? - * @param $dir string 'ASC' or 'DESC'. - * @return Revision timestamp (rev_timestamp). - */ - function getEditLimit( $dir ) { - list( $index, $usercond ) = $this->getUserCond(); - $nscond = $this->getNamespaceCond(); - $use_index = $this->dbr->useIndexClause( $index ); - list( $revision, $page) = $this->dbr->tableNamesN( 'revision', 'page' ); - $sql = "SELECT rev_timestamp " . - " FROM $page,$revision $use_index " . - " WHERE rev_page=page_id AND $usercond $nscond" . - " ORDER BY rev_timestamp $dir LIMIT 1"; - - $res = $this->dbr->query( $sql, __METHOD__ ); - $row = $this->dbr->fetchObject( $res ); - if ( $row ) { - return $row->rev_timestamp; - } else { - return false; - } - } + function getQueryInfo() { + list( $index, $userCond ) = $this->getUserCond(); + $conds = array_merge( array( 'page_id=rev_page' ), $userCond, $this->getNamespaceCond() ); - /** - * Get timestamps of first and last contributions made by the user. - * @return Array containing first rev_timestamp and last rev_timestamp. - */ - function getEditLimits() { return array( - $this->getEditLimit( "ASC" ), - $this->getEditLimit( "DESC" ) + '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 ) ); } function getUserCond() { - $condition = ''; - - if ( $this->username == 'newbies' ) { - $max = $this->dbr->selectField( 'user', 'max(user_id)', false, 'make_sql' ); - $condition = '>' . (int)($max - $max / 100); - } + $condition = array(); - if ( $condition == '' ) { - $condition = ' rev_user_text=' . $this->dbr->addQuotes( $this->username ); - $index = 'usertext_timestamp'; - } else { - $condition = ' rev_user '.$condition ; + 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 ); } function getNamespaceCond() { - if ( $this->namespace !== false ) - return ' AND page_namespace = ' . (int)$this->namespace; - return ''; + if ( $this->namespace !== '' ) { + return array( 'page_namespace' => (int)$this->namespace ); + } else { + return array(); + } } - /** - * @return Timestamp of first entry in previous page. - */ - function getPreviousOffsetForPaging() { - list( $index, $usercond ) = $this->getUserCond(); - $nscond = $this->getNamespaceCond(); - - $use_index = $this->dbr->useIndexClause( $index ); - list( $page, $revision ) = $this->dbr->tableNamesN( 'page', 'revision' ); - - $sql = "SELECT rev_timestamp FROM $page, $revision $use_index " . - "WHERE page_id = rev_page AND rev_timestamp > '" . $this->offset . "' AND " . - $usercond . $nscond; - $sql .= " ORDER BY rev_timestamp ASC"; - $sql = $this->dbr->limitResult( $sql, $this->limit, 0 ); - $res = $this->dbr->query( $sql ); - - $numRows = $this->dbr->numRows( $res ); - if ( $numRows ) { - $this->dbr->dataSeek( $res, $numRows - 1 ); - $row = $this->dbr->fetchObject( $res ); - $offset = $row->rev_timestamp; - } else { - $offset = false; + function getIndexField() { + return 'rev_timestamp'; + } + + function getStartBody() { + return "\n"; + } + + function getNavigationBar() { + if ( isset( $this->mNavigationBar ) ) { + return $this->mNavigationBar; } - $this->dbr->freeResult( $res ); - return $offset; + $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; } /** - * @return Timestamp of first entry in next page. - */ - function getFirstOffsetForPaging() { - list( $index, $usercond ) = $this->getUserCond(); - $use_index = $this->dbr->useIndexClause( $index ); - list( $page, $revision ) = $this->dbr->tableNamesN( 'page', 'revision' ); - $nscond = $this->getNamespaceCond(); - $sql = "SELECT rev_timestamp FROM $page, $revision $use_index " . - "WHERE page_id = rev_page AND " . - $usercond . $nscond; - $sql .= " ORDER BY rev_timestamp ASC"; - $sql = $this->dbr->limitResult( $sql, $this->limit, 0 ); - $res = $this->dbr->query( $sql ); - - $numRows = $this->dbr->numRows( $res ); - if ( $numRows ) { - $this->dbr->dataSeek( $res, $numRows - 1 ); - $row = $this->dbr->fetchObject( $res ); - $offset = $row->rev_timestamp; + * 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 formatRow( $row ) { + wfProfileIn( __METHOD__ ); + + global $wgLang, $wgUser; + + $sk = $this->getSkin(); + $rev = new Revision( $row ); + + $page = Title::makeTitle( $row->page_namespace, $row->page_title ); + $link = $sk->makeKnownLinkObj( $page ); + $difftext = $topmarktext = ''; + if( $row->rev_id == $row->page_latest ) { + $topmarktext .= '' . $this->messages['uctop'] . ''; + if( !$row->page_is_new ) { + $difftext .= '(' . $sk->makeKnownLinkObj( $page, $this->messages['diff'], 'diff=0' ) . ')'; + } else { + $difftext .= $this->messages['newarticle']; + } + + if( $wgUser->isAllowed( 'rollback' ) ) { + $topmarktext .= ' '.$sk->generateRollback( $rev ); + } + + } + if( $rev->userCan( Revision::DELETED_TEXT ) ) { + $difftext = '(' . $sk->makeKnownLinkObj( $page, $this->messages['diff'], 'diff=prev&oldid='.$row->rev_id ) . ')'; } else { - $offset = false; + $difftext = '(' . $this->messages['diff'] . ')'; } - $this->dbr->freeResult( $res ); - return $offset; - } + $histlink='('.$sk->makeKnownLinkObj( $page, $this->messages['hist'], 'action=history' ) . ')'; - /* private */ function makeSql() { - $offsetQuery = ''; + $comment = $sk->revComment( $rev ); + $d = $wgLang->timeanddate( wfTimestamp( TS_MW, $row->rev_timestamp ), true ); - list( $page, $revision ) = $this->dbr->tableNamesN( 'page', 'revision' ); - list( $index, $userCond ) = $this->getUserCond(); + if( $rev->isDeleted( Revision::DELETED_TEXT ) ) { + $d = '' . $d . ''; + } - if ( $this->offset ) - $offsetQuery = "AND rev_timestamp < '{$this->offset}'"; - - $nscond = $this->getNamespaceCond(); - $use_index = $this->dbr->useIndexClause( $index ); - $sql = 'SELECT ' . - '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 ' . - "FROM $page,$revision $use_index " . - "WHERE page_id=rev_page AND $userCond $nscond $offsetQuery " . - 'ORDER BY rev_timestamp DESC'; - $sql = $this->dbr->limitResult( $sql, $this->limit, 0 ); - return $sql; - } + if( $row->rev_minor_edit ) { + $mflag = '' . $this->messages['minoreditletter'] . ' '; + } else { + $mflag = ''; + } - /** - * This do the search for the user given when creating the object. - * It should probably be the only public function in this class. - * @return Array of contributions. - */ - function find() { - $contribs = array(); - $res = $this->dbr->query( $this->makeSql(), __METHOD__ ); - while ( $c = $this->dbr->fetchObject( $res ) ) - $contribs[] = $c; - $this->dbr->freeResult( $res ); - return $contribs; + $ret = "{$d} {$histlink} {$difftext} {$mflag} {$link} {$comment} {$topmarktext}"; + if( $rev->isDeleted( Revision::DELETED_TEXT ) ) { + $ret .= ' ' . wfMsgHtml( 'deletedrev' ); + } + $ret = "
  • $ret
  • \n"; + wfProfileOut( __METHOD__ ); + return $ret; } -}; + + /** + * Get the Database object in use + * + * @return Database + */ + public function getDatabase() { + return $this->mDb; + } + +} /** * Special page "user contributions". @@ -192,154 +179,110 @@ class ContribsFinder { function wfSpecialContributions( $par = null ) { global $wgUser, $wgOut, $wgLang, $wgRequest; - $target = isset( $par ) ? $par : $wgRequest->getVal( 'target' ); - if ( !strlen( $target ) ) { - $wgOut->showErrorPage( 'notargettitle', 'notargettext' ); - return; + $options = array(); + + if ( isset( $par ) && $par == 'newbies' ) { + $target = 'newbies'; + $options['contribs'] = 'newbie'; + } elseif ( isset( $par ) ) { + $target = $par; + } else { + $target = $wgRequest->getVal( 'target' ); } - $nt = Title::newFromURL( $target ); - if ( !$nt ) { - $wgOut->showErrorPage( 'notargettitle', 'notargettext' ); - return; + // check for radiobox + if ( $wgRequest->getVal( 'contribs' ) == 'newbie' ) { + $target = 'newbies'; + $options['contribs'] = 'newbie'; } - $options = array(); - - list( $options['limit'], $options['offset']) = wfCheckLimits(); - $options['offset'] = $wgRequest->getVal( 'offset' ); - /* Offset must be an integral. */ - if ( !strlen( $options['offset'] ) || !preg_match( '/^[0-9]+$/', $options['offset'] ) ) - $options['offset'] = ''; + if ( !strlen( $target ) ) { + $wgOut->addHTML( contributionsForm( '' ) ); + return; + } - $title = SpecialPage::getTitleFor( 'Contributions' ); + $options['limit'] = $wgRequest->getInt( 'limit', 50 ); $options['target'] = $target; - $nt =& Title::makeTitle( NS_USER, $nt->getDBkey() ); - $finder = new ContribsFinder( ( $target == 'newbies' ) ? 'newbies' : $nt->getText() ); - $finder->setLimit( $options['limit'] ); - $finder->setOffset( $options['offset'] ); + $nt = Title::makeTitleSafe( NS_USER, $target ); + if ( !$nt ) { + $wgOut->addHTML( contributionsForm( '' ) ); + return; + } + $id = User::idFromName( $nt->getText() ); + 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 ); - $finder->setNamespace( $options['namespace'] ); } else { $options['namespace'] = ''; } - if ( $wgUser->isAllowed( 'rollback' ) && $wgRequest->getBool( 'bot' ) ) { $options['bot'] = '1'; } - if ( $wgRequest->getText( 'go' ) == 'prev' ) { - $offset = $finder->getPreviousOffsetForPaging(); - if ( $offset !== false ) { - $options['offset'] = $offset; - $prevurl = $title->getLocalURL( wfArrayToCGI( $options ) ); - $wgOut->redirect( $prevurl ); - return; - } - } - - if ( $wgRequest->getText( 'go' ) == 'first' && $target != 'newbies') { - $offset = $finder->getFirstOffsetForPaging(); - if ( $offset !== false ) { - $options['offset'] = $offset; - $prevurl = $title->getLocalURL( wfArrayToCGI( $options ) ); - $wgOut->redirect( $prevurl ); - return; - } - } - - if ( $target == 'newbies' ) { - $wgOut->setSubtitle( wfMsgHtml( 'sp-contributions-newbies-sub') ); - } else { - $wgOut->setSubtitle( wfMsgHtml( 'contribsub', contributionsSub( $nt ) ) ); - } - - $id = User::idFromName( $nt->getText() ); wfRunHooks( 'SpecialContributionsBeforeMainOutput', $id ); - $wgOut->addHTML( contributionsForm( $options) ); - - $contribs = $finder->find(); + $wgOut->addHTML( contributionsForm( $options ) ); - if ( count( $contribs ) == 0) { + $pager = new ContribsPager( $target, $options['namespace'] ); + if ( !$pager->getNumRows() ) { $wgOut->addWikiText( wfMsg( 'nocontribs' ) ); return; } - list( $early, $late ) = $finder->getEditLimits(); - $lastts = count( $contribs ) ? $contribs[count( $contribs ) - 1]->rev_timestamp : 0; - $atstart = ( !count( $contribs ) || $late == $contribs[0]->rev_timestamp ); - $atend = ( !count( $contribs ) || $early == $lastts ); - - // These four are defaults - $newestlink = wfMsgHtml( 'sp-contributions-newest' ); - $oldestlink = wfMsgHtml( 'sp-contributions-oldest' ); - $newerlink = wfMsgHtml( 'sp-contributions-newer', $options['limit'] ); - $olderlink = wfMsgHtml( 'sp-contributions-older', $options['limit'] ); - - if ( !$atstart ) { - $stuff = $title->escapeLocalURL( wfArrayToCGI( array( 'offset' => '' ), $options ) ); - $newestlink = "$newestlink"; - $stuff = $title->escapeLocalURL( wfArrayToCGI( array( 'go' => 'prev' ), $options ) ); - $newerlink = "$newerlink"; - } - - if ( !$atend ) { - $stuff = $title->escapeLocalURL( wfArrayToCGI( array( 'go' => 'first' ), $options ) ); - $oldestlink = "$oldestlink"; - $stuff = $title->escapeLocalURL( wfArrayToCGI( array( 'offset' => $lastts ), $options ) ); - $olderlink = "$olderlink"; - } - - if ( $target == 'newbies' ) { - $firstlast ="($newestlink)"; - } else { - $firstlast = "($newestlink | $oldestlink)"; - } - - $urls = array(); - foreach ( array( 20, 50, 100, 250, 500 ) as $num ) { - $stuff = $title->escapeLocalURL( wfArrayToCGI( array( 'limit' => $num ), $options ) ); - $urls[] = "".$wgLang->formatNum( $num ).""; + # Show a message about slave lag, if applicable + if( ( $lag = $pager->getDatabase()->getLag() ) > 0 ) + $wgOut->showLagWarning( $lag ); + + $wgOut->addHTML( + '

    ' . $pager->getNavigationBar() . '

    ' . + $pager->getBody() . + '

    ' . $pager->getNavigationBar() . '

    ' ); + + # 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( '' ); + } } - $bits = implode( $urls, ' | ' ); - - $prevnextbits = $firstlast .' '. wfMsgHtml( 'viewprevnext', $newerlink, $olderlink, $bits ); - - $wgOut->addHTML( "

    {$prevnextbits}

    \n" ); - - $wgOut->addHTML( "\n" ); - $wgOut->addHTML( "

    {$prevnextbits}

    \n" ); } /** * Generates the subheading with links - * @param $nt @see Title object for the target + * @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 ) { +function contributionsSub( $nt, $id ) { global $wgSysopUserBans, $wgLang, $wgUser; $sk = $wgUser->getSkin(); - $id = User::idFromName( $nt->getText() ); if ( 0 == $id ) { - $ul = $nt->getText(); + $user = $nt->getText(); } else { - $ul = $sk->makeLinkObj( $nt, htmlspecialchars( $nt->getText() ) ); + $user = $sk->makeLinkObj( $nt, htmlspecialchars( $nt->getText() ) ); } $talk = $nt->getTalkPage(); if( $talk ) { # Talk page link - $tools[] = $sk->makeLinkObj( $talk, $wgLang->getNsText( NS_TALK ) ); + $tools[] = $sk->makeLinkObj( $talk, wfMsgHtml( 'talkpagelinktext' ) ); if( ( $id != 0 && $wgSysopUserBans ) || ( $id == 0 && User::isIP( $nt->getText() ) ) ) { # Block link if( $wgUser->isAllowed( 'block' ) ) @@ -349,9 +292,18 @@ function contributionsSub( $nt ) { } # Other logs link $tools[] = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'Log' ), wfMsgHtml( 'log' ), 'user=' . $nt->getPartialUrl() ); - $ul .= ' (' . implode( ' | ', $tools ) . ')'; + $links = implode( ' | ', $tools ); + } + + // 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)" ); } - return $ul; } /** @@ -359,97 +311,48 @@ function contributionsSub( $nt ) { * @param $options Array: the options to be included. */ function contributionsForm( $options ) { - global $wgScript, $wgTitle; + global $wgScript, $wgTitle, $wgRequest; $options['title'] = $wgTitle->getPrefixedText(); - - $f = "
    \n"; - foreach ( $options as $name => $value ) { - if( $name === 'namespace') continue; - $f .= "\t" . wfElement( 'input', array( - 'name' => $name, - 'type' => 'hidden', - 'value' => $value ) ) . "\n"; + if ( !isset( $options['target'] ) ) { + $options['target'] = ''; + } else { + $options['target'] = str_replace( '_' , ' ' , $options['target'] ); } - $f .= '

    ' . wfMsgHtml( 'namespace' ) . ' ' . - HTMLnamespaceselector( $options['namespace'], '' ) . - wfElement( 'input', array( - 'type' => 'submit', - 'value' => wfMsg( 'allpagessubmit' ) ) - ) . - "

    \n"; - - return $f; -} - -/** - * 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 ucListEdit( $sk, $row ) { - $fname = 'ucListEdit'; - wfProfileIn( $fname ); - - global $wgLang, $wgUser, $wgRequest; - static $messages; - if( !isset( $messages ) ) { - foreach( explode( ' ', 'uctop diff newarticle rollbacklink diff hist minoreditletter' ) as $msg ) { - $messages[$msg] = wfMsgExt( $msg, array( 'escape') ); - } + if ( !isset( $options['namespace'] ) ) { + $options['namespace'] = ''; } - $rev = new Revision( $row ); - - $page = Title::makeTitle( $row->page_namespace, $row->page_title ); - $link = $sk->makeKnownLinkObj( $page ); - $difftext = $topmarktext = ''; - if( $row->rev_id == $row->page_latest ) { - $topmarktext .= '' . $messages['uctop'] . ''; - if( !$row->page_is_new ) { - $difftext .= '(' . $sk->makeKnownLinkObj( $page, $messages['diff'], 'diff=0' ) . ')'; - } else { - $difftext .= $messages['newarticle']; - } - - if( $wgUser->isAllowed( 'rollback' ) ) { - $topmarktext .= ' '.$sk->generateRollback( $rev ); - } - - } - if( $rev->userCan( Revision::DELETED_TEXT ) ) { - $difftext = '(' . $sk->makeKnownLinkObj( $page, $messages['diff'], 'diff=prev&oldid='.$row->rev_id ) . ')'; - } else { - $difftext = '(' . $messages['diff'] . ')'; + if ( !isset( $options['contribs'] ) ) { + $options['contribs'] = 'user'; } - $histlink='('.$sk->makeKnownLinkObj( $page, $messages['hist'], 'action=history' ) . ')'; - - $comment = $sk->revComment( $rev ); - $d = $wgLang->timeanddate( wfTimestamp( TS_MW, $row->rev_timestamp ), true ); - if( $rev->isDeleted( Revision::DELETED_TEXT ) ) { - $d = '' . $d . ''; + if ( $options['contribs'] == 'newbie' ) { + $options['target'] = ''; } - if( $row->rev_minor_edit ) { - $mflag = '' . $messages['minoreditletter'] . ' '; - } else { - $mflag = ''; - } + $f = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ); - $ret = "{$d} {$histlink} {$difftext} {$mflag} {$link} {$comment} {$topmarktext}"; - if( $rev->isDeleted( Revision::DELETED_TEXT ) ) { - $ret .= ' ' . wfMsgHtml( 'deletedrev' ); - } - $ret = "
  • $ret
  • \n"; - wfProfileOut( $fname ); - return $ret; + foreach ( $options as $name => $value ) { + if ( in_array( $name, array( 'namespace', 'target', 'contribs' ) ) ) { + continue; + } + $f .= "\t" . Xml::hidden( $name, $value ) . "\n"; + } + + $f .= '
    ' . + Xml::element( 'legend', array(), wfMsg( 'sp-contributions-search' ) ) . + Xml::radioLabel( wfMsgExt( 'sp-contributions-newbies', array( 'parseinline' ) ), 'contribs' , 'newbie' , 'newbie', $options['contribs'] == 'newbie' ? true : false ) . '
    ' . + 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::submitButton( wfMsg( 'sp-contributions-submit' ) ) . + '
    ' . + Xml::closeElement( 'form' ); + return $f; } + ?>