username = $username;
$this->dbr =& wfGetDB(DB_SLAVE);
}
function set_limit($limit) {
$this->limit = $limit;
}
function set_offset($offset) {
$this->offset = $offset;
}
function set_namespace($namespace, $invert = false) {
$this->namespace = $namespace;
$this->invert = $invert;
}
function set_hide_minor($hm) {
$this->hide_minor = $hm;
}
function get_edit_limits() {
list($index, $usercond) = $this->get_user_cond();
$use_index = $this->dbr->useIndexClause($index);
$sql = "SELECT MIN(rev_timestamp) as earliest, MAX(rev_timestamp) as latest " .
"FROM page, revision $use_index WHERE page_id = rev_page " .
"AND ";
$sql .= $usercond;
$sql .= $this->get_namespace_cond();
$sql .= $this->get_minor_cond();
$res = $this->dbr->query($sql, "contribs_finder::get_edit_limits");
$rows = array();
while ($o = $this->dbr->fetchObject($res))
$rows[] = $o;
$row = $rows[count($rows) - 1];
return array($row->earliest, $row->latest);
}
function get_user_cond() {
$condition = "";
if ($this->username == 'newbies') {
$max = $this->dbr->selectField('user', 'max(user_id)', false, "make_sql");
$condition = '>' . ($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_minor_cond() {
if ($this->hide_minor)
return ' AND rev_minor_edit=0';
return '';
}
function get_namespace_cond() {
$nsQuery = $nsinvert = "";
if ($this->invert)
$nsinvert = "!";
if (!is_null($this->namespace))
$nsQuery .= "AND page_namespace {$nsinvert}= {$this->namespace}";
return $nsQuery;
}
function get_previous_offset_for_paging() {
list($index, $usercond) = $this->get_user_cond();
$use_index = $this->dbr->useIndexClause($index);
$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);
$sql .= $this->get_namespace_cond();
$sql .= $this->get_minor_cond();
$sql .= " ORDER BY rev_timestamp ASC LIMIT " . $this->limit;
$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;
}
function get_first_offset_for_paging() {
list($index, $usercond) = $this->get_user_cond();
$use_index = $this->dbr->useIndexClause($index);
$sql = "SELECT rev_timestamp FROM page, revision $use_index " .
"WHERE page_id = rev_page AND " .
"rev_user_text = " . $this->dbr->addQuotes($this->username);
$sql .= $this->get_namespace_cond();
$sql .= $this->get_minor_cond();
$sql .= " ORDER BY rev_timestamp ASC LIMIT " . ($this->limit + 1);
$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 = $minorQuery = $nsQuery
= $offsetQuery = $limitQuery = $nsinvert = "";
$minorQuery = $this->get_minor_cond();
$nsQuery = $this->get_namespace_cond();
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}";
$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 $minorQuery $nsQuery $offsetQuery
ORDER BY rev_timestamp DESC $limitQuery";
return $sql;
}
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;
$fname = 'wfSpecialContributions';
$target = isset($par) ? $par : $wgRequest->getVal( 'target' );
if (!strlen($target)) {
$wgOut->errorpage('notargettitle', 'notargettext');
return;
}
$nt = Title::newFromURL( $target );
if (!$nt) {
$wgOut->errorpage( 'notargettitle', 'notargettext' );
return;
}
$nt =& Title::makeTitle(NS_USER, $nt->getDBkey());
$namespace = $wgRequest->getIntOrNull('namespace');
$invert = $wgRequest->getBool('invert');
$hideminor = $wgRequest->getBool('hideminor');
$limit = min($wgRequest->getInt('limit', 50), 500);
$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 = "hideminor=$hideminor&namespace=$namespace&invert=$invert&target=" . wfUrlEncode($target);
$myurl = $title->escapeLocalURL($urlbits);
$finder = new contribs_finder($nt->getText());
$finder->set_namespace($namespace, $invert);
$finder->set_hide_minor($hideminor);
$finder->set_limit($limit);
$finder->set_offset($offset);
if ($wgRequest->getText('go') == "prev") {
$prevts = $finder->get_previous_offset_for_paging();
$prevurl = $title->getLocalURL($urlbits . "&offset=$prevts&limit=$limit");
$wgOut->redirect($prevurl);
return;
}
if ($wgRequest->getText('go') == "first") {
$prevts = $finder->get_first_offset_for_paging();
$prevurl = $title->getLocalURL($urlbits . "&offset=$prevts&limit=$limit");
$wgOut->redirect($prevurl);
return;
}
$sk = $wgUser->getSkin();
$id = User::idFromName($nt->getText());
if ( 0 == $id ) {
$ul = $nt->getText();
} else {
$ul = $sk->makeLinkObj( $nt, htmlspecialchars( $nt->getText() ) );
$userCond = '=' . $id;
}
$talk = $nt->getTalkPage();
if( $talk ) {
$ul .= ' (' . $sk->makeLinkObj( $talk, $wgLang->getNsText( NS_TALK ) ) . ')';
}
if ($target == 'newbies') {
$ul = wfMsg ('newbies');
}
$wgOut->setSubtitle( wfMsgHtml( 'contribsub', $ul ) );
$contribsPage = Title::makeTitle( NS_SPECIAL, 'Contributions' );
$mlink = $sk->makeKnownLinkObj( $contribsPage,
$hideminor ? wfMsgHtml( 'show' ) : wfMsgHtml( 'hide' ),
wfArrayToCGI( array(
'target' => $nt->getPrefixedDbKey(),
'offset' => $offset,
'limit' => $limit,
'hideminor' => $hideminor ? 0 : 1,
'namespace' => $namespace ) ) );
$contribs = $finder->find();
if (count($contribs) == 0) {
$wgOut->addWikiText( wfMsg( "nocontribs" ) );
return;
}
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);
wfdebug("early=$early late=$late lastts=$lastts\n");
$wgOut->addHTML(ucNamespaceForm($target, $hideminor, $namespace, $invert));
$lasturl = $wgTitle->escapeLocalURL("action=history&limit={$limit}");
$firsttext = wfMsgHtml("histfirst");
$lasttext = wfMsgHtml("histlast");
$prevtext = wfMsg("prevn", $limit);
if ($atstart) {
$lastlink = $lasttext;
$prevlink = $prevtext;
} else {
$lastlink = "$lasttext";
$prevlink = "$prevtext";
}
$nexttext = wfMsg("nextn", $limit);
if ($atend) {
$firstlink = $firsttext;
$nextlink = $nexttext;
} else {
$firstlink = "$firsttext";
$nextlink = "$nexttext";
}
$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);
$shm = wfMsgHtml( "contribs-showhideminor", $mlink );
$wgOut->addHTML( "
{$prevnextbits} ($shm)