X-Git-Url: https://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2FSpecialContributions.php;h=00864da5e53924187edbfa67333cfdcce10d75ba;hb=71e75ac5ead653914ec3ae100e26d186375a306e;hp=0bc00f6917ced50354303a522f2e962432cd8039;hpb=68967f0f0088723343ed645760ce804003035b50;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/SpecialContributions.php b/includes/SpecialContributions.php index 0bc00f6917..00864da5e5 100644 --- a/includes/SpecialContributions.php +++ b/includes/SpecialContributions.php @@ -1,211 +1,402 @@ username = $username; + $this->namespace = false; + $this->dbr =& wfGetDB(DB_SLAVE); + } + + function set_namespace($ns) { + $this->namespace = $ns; + } + + function set_limit($limit) { + $this->limit = $limit; + } + + function set_offset($offset) { + $this->offset = $offset; + } + + function get_edit_limit($dir) { + list($index, $usercond) = $this->get_user_cond(); + $nscond = $this->get_namespace_cond(); + $use_index = $this->dbr->useIndexClause($index); + extract($this->dbr->tableNames('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, "contribs_finder::get_edit_limit"); + while ($o = $this->dbr->fetchObject($res)) + $row = $o; + return $row->rev_timestamp; + } + + function get_edit_limits() { + return array( + $this->get_edit_limit("ASC"), + $this->get_edit_limit("DESC") + ); + } + + function get_user_cond() { + $condition = ''; + + if ($this->username == 'newbies') { + $max = $this->dbr->selectField('user', 'max(user_id)', false, 'make_sql'); + $condition = '>' . (int)($max - $max / 100); + } + + if ($condition == '') { + $condition = ' rev_user_text=' . $this->dbr->addQuotes($this->username); + $index = 'usertext_timestamp'; + } else { + $condition = ' rev_user '.$condition ; + $index = 'user_timestamp'; + } + return array($index, $condition); + } + + function get_namespace_cond() { + if ($this->namespace !== false) + return ' AND page_namespace = ' . (int)$this->namespace; + return ''; + } -function wfSpecialContributions( $par = "" ) -{ - global $wgUser, $wgOut, $wgLang, $wgRequest; - $fname = "wfSpecialContributions"; - $sysop = $wgUser->isSysop(); + function get_previous_offset_for_paging() { + list($index, $usercond) = $this->get_user_cond(); + $nscond = $this->get_namespace_cond(); + + $use_index = $this->dbr->useIndexClause($index); + extract($this->dbr->tableNames('page', 'revision')); + + $sql = "SELECT rev_timestamp FROM $page, $revision $use_index " . + "WHERE page_id = rev_page AND rev_timestamp > '" . $this->offset . "' AND " . + "rev_user_text = " . $this->dbr->addQuotes($this->username) + . $nscond; + $sql .= " ORDER BY rev_timestamp ASC"; + $sql = $this->dbr->limitResult($sql, $this->limit, 0); + $res = $this->dbr->query($sql); + $rows = array(); + while ($obj = $this->dbr->fetchObject($res)) + $rows[] = $obj; + $this->dbr->freeResult($res); + return $rows[count($rows) - 1]->rev_timestamp; + } - if( $par ) - $target = $par; - else - $target = $wgRequest->getVal( 'target' ); + function get_first_offset_for_paging() { + list($index, $usercond) = $this->get_user_cond(); + $use_index = $this->dbr->useIndexClause($index); + extract($this->dbr->tableNames('page', 'revision')); + $nscond = $this->get_namespace_cond(); + $sql = "SELECT rev_timestamp FROM $page, $revision $use_index " . + "WHERE page_id = rev_page AND " . + "rev_user_text = " . $this->dbr->addQuotes($this->username) + . $nscond; + $sql .= " ORDER BY rev_timestamp ASC"; + $sql = $this->dbr->limitResult($sql, $this->limit, 0); + $res = $this->dbr->query($sql); + $rows = array(); + while ($obj = $this->dbr->fetchObject($res)) + $rows[] = $obj; + $this->dbr->freeResult($res); + return $rows[count($rows) - 1]->rev_timestamp; + } + + /* private */ function make_sql() { + $userCond = $condition = $index = $offsetQuery = $limitQuery = ""; + + extract($this->dbr->tableNames('page', 'revision')); + list($index, $userCond) = $this->get_user_cond(); + + $limitQuery = 'LIMIT '.$this->limit; + if ($this->offset) + $offsetQuery = "AND rev_timestamp <= '{$this->offset}'"; + + $nscond = $this->get_namespace_cond(); + $use_index = $this->dbr->useIndexClause($index); + $sql = "SELECT + page_namespace,page_title,page_is_new,page_latest, + rev_id,rev_timestamp,rev_comment,rev_minor_edit,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 ( "" == $target ) { - $wgOut->errorpage( "notargettitle", "notargettext" ); + function find() { + $contribs = array(); + $res = $this->dbr->query($this->make_sql(), 'contribs_finder::find'); + while ($c = $this->dbr->fetchObject($res)) + $contribs[] = $c; + $this->dbr->freeResult($res); + return $contribs; + } +}; + +/** + * Special page "user contributions". + * Shows a list of the contributions of a user. + * + * @return none + * @param string $par (optional) user name of the user for which to show the contributions + */ +function wfSpecialContributions( $par = null ) { + global $wgUser, $wgOut, $wgLang, $wgContLang, $wgRequest, $wgTitle, + $wgScript; + $fname = 'wfSpecialContributions'; + + $target = isset($par) ? $par : $wgRequest->getVal( 'target' ); + if (!strlen($target)) { + $wgOut->errorpage('notargettitle', 'notargettext'); return; } - - # FIXME: Change from numeric offsets to date offsets - list( $limit, $offset ) = wfCheckLimits( 50, "" ); - $offlimit = $limit + $offset; - $querylimit = $offlimit + 1; - $hideminor = ($wgRequest->getVal( 'hideminor' ) ? 1 : 0); $nt = Title::newFromURL( $target ); - $nt->setNamespace( Namespace::getUser() ); + if (!$nt) { + $wgOut->errorpage( 'notargettitle', 'notargettext' ); + return; + } + $nt =& Title::makeTitle(NS_USER, $nt->getDBkey()); + + list( $limit, $offset) = wfCheckLimits(); + $offset = $wgRequest->getVal('offset'); + /* Offset must be an integral. */ + if (!strlen($offset) || !preg_match('/^[0-9]+$/', $offset)) + $offset = 0; + + $title = Title::makeTitle(NS_SPECIAL, 'Contributions'); + $urlbits = 'target=' . wfUrlEncode($target); + $myurl = $title->escapeLocalURL($urlbits); + + $finder = new contribs_finder(($target == 'newbies') ? 'newbies' : $nt->getText()); + + $finder->set_limit($limit); + $finder->set_offset($offset); + + $nsurl = $xnsurl = ''; + if (($ns = $wgRequest->getVal('namespace', null)) !== null && $ns !== '') { + $nsurl = '&namespace='.$ns; + $xnsurl = htmlspecialchars($nsurl); + $finder->set_namespace($ns); + } + + $boturl = ''; + if ($wgUser->isAllowed('rollback') && $wgRequest->getBool( 'bot' )) + $boturl = '&bot=1'; + + if ($wgRequest->getText('go') == 'prev') { + $prevts = $finder->get_previous_offset_for_paging(); + $prevurl = $title->getLocalURL($urlbits . "&offset=$prevts&limit=$limit$nsurl$boturl"); + $wgOut->redirect($prevurl); + return; + } + + if ($wgRequest->getText('go') == 'first' && $target != 'newbies') { + $prevts = $finder->get_first_offset_for_paging(); + $prevurl = $title->getLocalURL($urlbits . "&offset=$prevts&limit=$limit$nsurl$boturl"); + $wgOut->redirect($prevurl); + return; + } $sk = $wgUser->getSkin(); - $id = User::idFromName( $nt->getText() ); + + $id = User::idFromName($nt->getText()); if ( 0 == $id ) { $ul = $nt->getText(); } else { - $ul = $sk->makeLinkObj( $nt, $nt->getText() ); + $ul = $sk->makeLinkObj( $nt, htmlspecialchars( $nt->getText() ) ); + $userCond = '=' . $id; } $talk = $nt->getTalkPage(); - if( $talk ) - $ul .= " (" . $sk->makeLinkObj( $talk, $wgLang->getNsText(Namespace::getTalk(0)) ) . ")"; - else - $ul .= "brrrp"; - $wgOut->setSubtitle( wfMsg( "contribsub", $ul ) ); - - if ( $hideminor ) { - $cmq = "AND cur_minor_edit=0"; - $omq = "AND old_minor_edit=0"; - $mlink = $sk->makeKnownLink( $wgLang->specialPage( "Contributions" ), - WfMsg( "show" ), "target=" . wfEscapeHTML( $nt->getPrefixedURL() ) . - "&offset={$offset}&limit={$limit}&hideminor=0" ); - } else { - $cmq = $omq = ""; - $mlink = $sk->makeKnownLink( $wgLang->specialPage( "Contributions" ), - WfMsg( "hide" ), "target=" . wfEscapeHTML( $nt->getPrefixedURL() ) . - "&offset={$offset}&limit={$limit}&hideminor=1" ); + if( $talk ) { + $ul .= ' (' . $sk->makeLinkObj( $talk, $wgLang->getNsText( NS_TALK ) ) . ')'; } - if ( 0 == $id ) { - $sql = "SELECT cur_namespace,cur_title,cur_timestamp,cur_comment,cur_minor_edit,cur_is_new FROM cur " . - "WHERE cur_user_text='" . wfStrencode( $nt->getText() ) . "' {$cmq} " . - "ORDER BY inverse_timestamp LIMIT {$querylimit}"; - $res1 = wfQuery( $sql, DB_READ, $fname ); - - $sql = "SELECT old_namespace,old_title,old_timestamp,old_comment,old_minor_edit FROM old " . - "WHERE old_user_text='" . wfStrencode( $nt->getText() ) . "' {$omq} " . - "ORDER BY inverse_timestamp LIMIT {$querylimit}"; - $res2 = wfQuery( $sql, DB_READ, $fname ); - } else { - $sql = "SELECT cur_namespace,cur_title,cur_timestamp,cur_comment,cur_minor_edit,cur_is_new FROM cur " . - "WHERE cur_user={$id} {$cmq} ORDER BY inverse_timestamp LIMIT {$querylimit}"; - $res1 = wfQuery( $sql, DB_READ, $fname ); - - $sql = "SELECT old_namespace,old_title,old_timestamp,old_comment,old_minor_edit FROM old " . - "WHERE old_user={$id} {$omq} ORDER BY inverse_timestamp LIMIT {$querylimit}"; - $res2 = wfQuery( $sql, DB_READ, $fname ); + if ($target == 'newbies') { + $ul = wfMsg ('newbies'); } - $nCur = wfNumRows( $res1 ); - $nOld = wfNumRows( $res2 ); - $top = wfShowingResults( $offset, $limit ); - $wgOut->addHTML( "

{$top}\n" ); + $wgOut->setSubtitle( wfMsgHtml( 'contribsub', $ul ) ); + + wfRunHooks('SpecialContributionsBeforeMainOutput', $id ); + + $arr = $wgContLang->getFormattedNamespaces(); + $nsform = "

\n"; + $nsform .= wfElement('input', array( + 'name' => 'title', + 'type' => 'hidden', + 'value' => $wgTitle->getPrefixedText())); + $nsform .= wfElement('input', array( + 'name' => 'offset', + 'type' => 'hidden', + 'value' => $offset)); + $nsform .= wfElement('input', array( + 'name' => 'limit', + 'type' => 'hidden', + 'value' => $limit)); + $nsform .= wfElement('input', array( + 'name' => 'target', + 'type' => 'hidden', + 'value' => $target)); + $nsform .= '

'; + $nsform .= wfMsgHtml('namespace'); + + $nsform .= HTMLnamespaceselector( $ns, '' ); + + $nsform .= wfElement('input', array( + 'type' => 'submit', + 'value' => wfMsg('allpagessubmit'))); + $nsform .= "

\n"; + + $wgOut->addHTML($nsform); + + $contribsPage = Title::makeTitle( NS_SPECIAL, 'Contributions' ); + $contribs = $finder->find(); + + if (count($contribs) == 0) { + $wgOut->addWikiText( wfMsg( 'nocontribs' ) ); + return; + } - $sl = wfViewPrevNext( $offset, $limit, - $wgLang->specialpage( "Contributions" ), - "hideminor={$hideminor}&target=" . wfUrlEncode( $target ), - ($nCur + $nOld) <= $offlimit); + list($early, $late) = $finder->get_edit_limits(); + $lastts = count($contribs) ? $contribs[count($contribs) - 1]->rev_timestamp : 0; + $atstart = (!count($contribs) || $late == $contribs[0]->rev_timestamp); + $atend = (!count($contribs) || $early == $lastts); - $shm = wfMsg( "showhideminor", $mlink ); - $wgOut->addHTML( "
{$sl} ($shm) \n"); + $lasturl = $wgTitle->escapeLocalURL("action=history&limit={$limit}"); + $firsttext = wfMsgHtml('histfirst'); + $lasttext = wfMsgHtml('histlast'); - if ( 0 == $nCur && 0 == $nOld ) { - $wgOut->addHTML( "\n

" . wfMsg( "nocontribs" ) . "

\n" ); - return; + $prevtext = wfMsg('prevn', $limit); + if ($atstart) { + $lastlink = $lasttext; + $prevlink = $prevtext; + } else { + $lastlink = "$lasttext"; + $prevlink = "$prevtext"; } - if ( 0 != $nCur ) { $obj1 = wfFetchObject( $res1 ); } - if ( 0 != $nOld ) { $obj2 = wfFetchObject( $res2 ); } - $wgOut->addHTML( "\n" ); -} + if ($target == 'newbies') { + $firstlast ="($lastlink)"; + } else { + $firstlast = "($lastlink | $firstlink)"; + } + $urls = array(); + foreach (array(20, 50, 100, 250, 500) as $num) + $urls[] = "".$wgLang->formatNum($num).""; + $bits = implode($urls, ' | '); -/* + $prevnextbits = $firstlast .' '. wfMsgHtml('viewprevnext', $prevlink, $nextlink, $bits); -Generates each row in the contributions list. + $wgOut->addHTML( "

{$prevnextbits}

\n"); -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. + $wgOut->addHTML( "\n" ); + $wgOut->addHTML( "

{$prevnextbits}

\n"); +} + + +/** + * 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. + * + * If the contributions page is called with the parameter &bot=1, all rollback + * links also get that parameter. It causes the edit itself and the rollback + * to be marked as "bot" edits. Bot edits are hidden by default from recent + * changes, so this allows sysops to combat a busy vandal without bothering + * other users. + * + * @todo This would probably look a lot nicer in a table. + */ +function ucListEdit( $sk, $row ) { + $fname = 'ucListEdit'; + wfProfileIn( $fname ); -*/ -function ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, $isminor, $isnew ) -{ global $wgLang, $wgOut, $wgUser, $wgRequest; - $page = Title::makeName( $ns, $t ); - $link = $sk->makeKnownLink( $page, "" ); - $topmarktext=""; - if($topmark) { - if(!$isnew) { - $topmarktext .= $sk->makeKnownLink( $page, wfMsg("uctop"), "diff=0" ); - } else { - $topmarktext .= wfMsg("newarticle"); - } - $sysop = $wgUser->isSysop(); - if($sysop ) { - $extraRollback = $wgRequest->getBool( "bot" ) ? '&bot=1' : ''; - $target = $wgRequest->getText( 'target' ); - $topmarktext .= " [". $sk->makeKnownLink( $page, - wfMsg( "rollbacklink" ), - "action=rollback&from=" . urlencode( $target ) . $extraRollback ) ."]"; + static $messages; + if( !isset( $messages ) ) { + foreach( explode( ' ', 'uctop diff newarticle rollbacklink diff hist minoreditletter' ) as $msg ) { + $messages[$msg] = wfMsg( $msg ); } - } - $histlink="(".$sk->makeKnownLink($page,wfMsg("hist"),"action=history").")"; - if($comment) { + $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']; + } - $comment="(". $sk->formatComment($comment ) .") "; + if( $wgUser->isAllowed('rollback') ) { + $extraRollback = $wgRequest->getBool( 'bot' ) ? '&bot=1' : ''; + $extraRollback .= '&token=' . urlencode( + $wgUser->editToken( array( $page->getPrefixedText(), $row->rev_user_text ) ) ); + $topmarktext .= ' ['. $sk->makeKnownLinkObj( $page, + $messages['rollbacklink'], + 'action=rollback&from=' . urlencode( $row->rev_user_text ) . $extraRollback ) .']'; + } } - $d = $wgLang->timeanddate( $ts, true ); - - if ($isminor) { - $mflag = "" . wfMsg( "minoreditletter" ) . " "; + if( $row->rev_deleted && !$wgUser->isAllowed( 'undelete' ) ) { + $difftext = '(' . $messages['diff'] . ')'; } else { - $mflag = ""; + $difftext = '(' . $sk->makeKnownLinkObj( $page, $messages['diff'], 'diff=prev&oldid='.$row->rev_id ) . ')'; } + $histlink='('.$sk->makeKnownLinkObj( $page, $messages['hist'], 'action=history' ) . ')'; - $wgOut->addHTML( "
  • {$d} {$histlink} {$mflag} {$link} {$comment}{$topmarktext}
  • \n" ); -} + $comment = $sk->commentBlock( $row->rev_comment, $page ); + $d = $wgLang->timeanddate( wfTimestamp(TS_MW, $row->rev_timestamp), true ); -function ucCountLink( $lim, $d ) -{ - global $wgUser, $wgLang, $wgRequest; + if( $row->rev_minor_edit ) { + $mflag = '' . $messages['minoreditletter'] . ' '; + } else { + $mflag = ''; + } - $target = $wgRequest->getText( 'target' ); - $sk = $wgUser->getSkin(); - $s = $sk->makeKnownLink( $wgLang->specialPage( "Contributions" ), - "{$lim}", "target={$target}&days={$d}&limit={$lim}" ); - return $s; + $ret = "{$d} {$histlink} {$difftext} {$mflag} {$link} {$comment} {$topmarktext}"; + if( $row->rev_deleted ) { + $ret = '' . $ret . ' ' . htmlspecialchars( wfMsg( 'deletedrev' ) ); + } + $ret = "
  • $ret
  • \n"; + wfProfileOut( $fname ); + return $ret; } -function ucDaysLink( $lim, $d ) -{ - global $wgUser, $wgLang, $wgRequest; - - $target = $wgRequest->getText( 'target' ); - $sk = $wgUser->getSkin(); - $s = $sk->makeKnownLink( $wgLang->specialPage( "Contributions" ), - "{$d}", "target={$target}&days={$d}&limit={$lim}" ); - return $s; -} ?>