$action=='view'
) {
wfProfileOut( $fname );
- return $this->mContent . "\n" .wfMsg('anontalkpagetext');
+ return $this->mContent . "\n" .wfMsg('anontalkpagetext');
} else {
if($action=='edit') {
if($section!='') {
function &getOldContentFields() {
global $wgArticleOldContentFields;
if ( !$wgArticleOldContentFields ) {
- $wgArticleOldContentFields = array( 'old_namespace','old_title','old_text','old_timestamp',
+ $wgArticleOldContentFields = array( 'old_namespace','old_title','old_text','old_timestamp',
'old_user','old_user_text','old_comment','old_flags' );
}
return $wgArticleOldContentFields;
}
-
+
# Load the revision (including cur_text) into this object
function loadContent( $noredir = false )
{
if ( 0 == $id ) return;
$s = $dbr->getArray( 'cur', $this->getCurContentFields(), array( 'cur_id' => $id ), $fname );
- if ( $s === false ) {
+ if ( $s === false ) {
return;
}
}
$s = $dbr->getArray( 'cur', $this->getCurContentFields(), array( 'cur_id' => $id ), $fname );
- if ( $s === false ) {
+ if ( $s === false ) {
return false;
}
$this->mTitle->mRestrictionsLoaded = true;
} else { # oldid set, retrieve historical version
$s = $dbr->getArray( 'old', $this->getOldContentFields(), array( 'old_id' => $oldid ) );
- if ( $s === false ) {
+ if ( $s === false ) {
return false;
}
$this->mContent = Article::getRevisionText( $s );
{
global $wgOut;
if ( -1 != $this->mUser ) return;
-
+
$fname = 'Article::loadLastEdit';
$dbr =& wfGetDB( DB_SLAVE );
- $s = $dbr->getArray( 'cur',
+ $s = $dbr->getArray( 'cur',
array( 'cur_user','cur_user_text','cur_timestamp', 'cur_comment','cur_minor_edit' ),
array( 'cur_id' => $this->getID() ), $fname );
$user = $this->getUser();
$sql = "SELECT old_user, old_user_text, user_real_name, MAX(old_timestamp) as timestamp
- FROM $oldTable LEFT JOIN $userTable ON old_user = user_id
+ FROM $oldTable LEFT JOIN $userTable ON old_user = user_id
WHERE old_namespace = $user
AND old_title = $encDBkey
AND old_user != $user
- GROUP BY old_user
+ GROUP BY old_user
ORDER BY timestamp DESC";
if ($limit > 0) {
function view()
{
- global $wgUser, $wgOut, $wgLang, $wgRequest, $wgMwRedir;
+ global $wgUser, $wgOut, $wgLang, $wgRequest, $wgMwRedir, $wgOnlySysopsCanPatrol;
global $wgLinkCache, $IP, $wgEnableParserCache, $wgStylePath;
+ $sk = $wgUser->getSkin();
$fname = 'Article::view';
wfProfileIn( $fname );
- # Get variables from query string :P
+ # Get variables from query string
$oldid = $wgRequest->getVal( 'oldid' );
$diff = $wgRequest->getVal( 'diff' );
+ $rcid = $wgRequest->getVal( 'rcid' );
$wgOut->setArticleFlag( true );
$wgOut->setRobotpolicy( 'index,follow' );
if ( !is_null( $diff ) ) {
$wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
- $de = new DifferenceEngine( intval($oldid), intval($diff) );
+ $de = new DifferenceEngine( intval($oldid), intval($diff), intval($rcid) );
$de->showDiffPage();
wfProfileOut( $fname );
if( $diff == 0 ) {
$wgOut->addHTML( '<pre>'.htmlspecialchars($this->mContent)."\n</pre>" );
} else if ( $rt = Title::newFromRedirect( $text ) ) {
# Display redirect
- $sk = $wgUser->getSkin();
$imageUrl = "$wgStylePath/images/redirect.png";
$targetUrl = $rt->escapeLocalURL();
$titleText = htmlspecialchars( $rt->getPrefixedText() );
}
$wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
+ # If we have been passed an &rcid= parameter, we want to give the user a
+ # chance to mark this new article as patrolled.
+ if ( !is_null ( $rcid ) && $rcid != 0 && $wgUser->getID() != 0 &&
+ ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) )
+ {
+ $wgOut->addHTML( wfMsg ( 'markaspatrolledlink',
+ $sk->makeKnownLinkObj ( $this->mTitle, wfMsg ( 'markaspatrolledtext' ),
+ "action=markpatrolled&rcid={$rcid}" )
+ ) );
+ }
+
# Add link titles as META keywords
$wgOut->addMetaTags() ;
$rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' );
$dbw =& wfGetDB( DB_MASTER );
- $cur_id = $dbw->nextSequenceValue( 'cur_cur_id_seq' );
+ $cur_id = $dbw->nextSequenceValue( 'cur_cur_id_seq' );
$isminor = ( $isminor && $wgUser->getID() ) ? 1 : 0;
global $wgOut, $wgUser;
global $wgDBtransactions, $wgMwRedir;
global $wgUseSquid, $wgInternalServer;
-
+
$fname = 'Article::updateArticle';
$good = true;
-
+
if ( $this->mMinorEdit ) { $me1 = 1; } else { $me1 = 0; }
if ( $minor && $wgUser->getID() ) { $me2 = 1; } else { $me2 = 0; }
if ( preg_match( "/^((" . $wgMwRedir->getBaseRegex() . ')[^\\n]+)/i', $text, $m ) ) {
# Update article, but only if changed.
- # It's important that we either rollback or complete, otherwise an attacker could
- # overwrite cur entries by sending precisely timed user aborts. Random bored users
+ # It's important that we either rollback or complete, otherwise an attacker could
+ # overwrite cur entries by sending precisely timed user aborts. Random bored users
# could conceivably have the same effect, especially if cur is locked for long periods.
if( $wgDBtransactions ) {
$dbw->query( 'BEGIN', $fname );
} else {
$userAbort = ignore_user_abort( true );
}
-
+
$oldtext = $this->getContent( true );
if ( 0 != strcmp( $text, $oldtext ) ) {
$won = wfInvertTimestamp( $now );
# First update the cur row
- $dbw->updateArray( 'cur',
- array( /* SET */
+ $dbw->updateArray( 'cur',
+ array( /* SET */
'cur_text' => $text,
'cur_comment' => $summary,
- 'cur_minor_edit' => $me2,
+ 'cur_minor_edit' => $me2,
'cur_user' => $wgUser->getID(),
'cur_timestamp' => $now,
'cur_user_text' => $wgUser->getName(),
- 'cur_is_redirect' => $redir,
+ 'cur_is_redirect' => $redir,
'cur_is_new' => 0,
- 'cur_touched' => $now,
+ 'cur_touched' => $now,
'inverse_timestamp' => $won
), array( /* WHERE */
- 'cur_id' => $this->getID(),
- 'cur_timestamp' => $this->getTimestamp()
- ), $fname
+ 'cur_id' => $this->getID(),
+ 'cur_timestamp' => $this->getTimestamp()
+ ), $fname
);
-
+
if( $dbw->affectedRows() == 0 ) {
/* Belated edit conflict! Run away!! */
$good = false;
# This overwrites $oldtext if revision compression is on
$flags = Article::compressRevisionText( $oldtext );
-
- $dbw->insertArray( 'old',
+
+ $dbw->insertArray( 'old',
array(
'old_id' => $dbw->nextSequenceValue( 'old_old_id_seq' ),
'old_namespace' => $this->mTitle->getNamespace(),
'old_minor_edit' => $me1,
'inverse_timestamp' => wfInvertTimestamp( $this->getTimestamp() ),
'old_flags' => $flags,
- ), $fname
+ ), $fname
);
-
+
$oldid = $dbw->insertId();
$bot = (int)($wgUser->isBot() || $forceBot);
- RecentChange::notifyEdit( $now, $this->mTitle, $me2, $wgUser, $summary,
+ RecentChange::notifyEdit( $now, $this->mTitle, $me2, $wgUser, $summary,
$oldid, $this->getTimestamp(), $bot );
Article::onArticleEdit( $this->mTitle );
}
$wgLinkCache = new LinkCache();
# Select for update
$wgLinkCache->forUpdate( true );
-
+
# Get old version of link table to allow incremental link updates
$wgLinkCache->preFill( $this->mTitle );
$wgLinkCache->clear();
-
+
# Switch on use of link cache in the skin
$sk =& $wgUser->getSkin();
$sk->postParseLinkColour( false );
-
+
# Now update the link cache by parsing the text
$wgOut = new OutputPage();
$wgOut->addWikiText( $text );
}
# Validate article
-
+
function validate ()
{
global $wgOut ;
return ;
}
$v = new Validation ;
- $v->validate_form ( $this->mTitle->getDBkey() ) ;
+ $v->validate_form ( $this->mTitle->getDBkey() ) ;
}
- # Add this page to my watchlist
+ # Mark this particular edit as patrolled
+ function markpatrolled()
+ {
+ global $wgOut, $wgRequest, $wgOnlySysopsCanPatrol;
+ $wgOut->setRobotpolicy( 'noindex,follow' );
+ if( $wgOnlySysopsCanPatrol && !$wgUser->isSysop() )
+ {
+ $wgOut->sysopRequired();
+ return;
+ }
+ $rcid = $wgRequest->getVal( 'rcid' );
+ if ( !is_null ( $rcid ) )
+ {
+ RecentChange::markPatrolled( $rcid );
+ $wgOut->setPagetitle( wfMsg( 'markedaspatrolled' ) );
+ $wgOut->addWikiText( wfMsg( 'markedaspatrolledtext' ) );
+ $wgOut->returnToMain( true, $this->mTitle->getPrefixedText() );
+ }
+ else
+ {
+ $wgOut->errorpage( 'markedaspatrollederror', 'markedaspatrollederrortext' );
+ }
+ }
+
+ # Add this page to my watchlist
function watch( $add = true )
{
global $wgUser, $wgOut, $wgLang;
if ( $confirm ) {
$dbw =& wfGetDB( DB_MASTER );
- $dbw->updateArray( 'cur',
+ $dbw->updateArray( 'cur',
array( /* SET */
'cur_touched' => wfTimestampNow(),
'cur_restrictions' => (string)$limit
), array( /* WHERE */
- 'cur_id' => $id
- ), 'Article::protect'
+ 'cur_id' => $id
+ ), 'Article::protect'
);
$log = new LogPage( wfMsg( 'protectlogpage' ), wfMsg( 'protectlogtext' ) );
$dbr =& wfGetDB( DB_SLAVE );
$ns = $this->mTitle->getNamespace();
$title = $this->mTitle->getDBkey();
- $old = $dbr->getArray( 'old',
- array( 'old_text', 'old_flags' ),
+ $old = $dbr->getArray( 'old',
+ array( 'old_text', 'old_flags' ),
array(
'old_namespace' => $ns,
'old_title' => $title,
- ), $fname, array( 'ORDER BY' => 'inverse_timestamp' )
+ ), $fname, array( 'ORDER BY' => 'inverse_timestamp' )
);
-
+
if( $old !== false && !$confirm ) {
$skin=$wgUser->getSkin();
$wgOut->addHTML('<b>'.wfMsg('historywarning'));
$wgOut->addHTML( $skin->historyLink() .'</b>');
}
-
+
# Fetch cur_text
- $s = $dbr->getArray( 'cur',
- array( 'cur_text' ),
- array(
- 'cur_namespace' => $ns,
+ $s = $dbr->getArray( 'cur',
+ array( 'cur_text' ),
+ array(
+ 'cur_namespace' => $ns,
'cur_title' => $title,
), $fname
);
-
+
if( $s !== false ) {
# if this is a mini-text, we can paste part of it into the deletion reason
$fname = 'Article::doDeleteArticle';
wfDebug( $fname."\n" );
-
+
$dbw =& wfGetDB( DB_MASTER );
$ns = $this->mTitle->getNamespace();
$t = $this->mTitle->getDBkey();
$recentchangesTable = $dbw->tableName( 'recentchanges' );
$linksTable = $dbw->tableName( 'links' );
$brokenlinksTable = $dbw->tableName( 'brokenlinks' );
-
- $dbw->insertSelect( 'archive', 'cur',
+
+ $dbw->insertSelect( 'archive', 'cur',
array(
'ar_namespace' => 'cur_namespace',
'ar_title' => 'cur_title',
), array(
'cur_namespace' => $ns,
'cur_title' => $t,
- ), $fname
+ ), $fname
);
-
+
$dbw->insertSelect( 'archive', 'old',
array(
'ar_namespace' => 'old_namespace',
'old_title' => $t,
), $fname
);
-
+
# Now that it's safely backed up, delete it
$dbw->delete( 'cur', array( 'cur_namespace' => $ns, 'cur_title' => $t ), $fname );
$brokenLinks[] = array( 'bl_from' => $linkID, 'bl_to' => $t );
}
$dbw->insert( 'brokenlinks', $brokenLinks, $fname, 'IGNORE' );
-
+
# Delete live links
$dbw->delete( 'links', array( 'l_to' => $id ) );
$dbw->delete( 'links', array( 'l_from' => $id ) );
{
global $wgUser, $wgLang, $wgOut, $wgRequest;
$fname = "Article::rollback";
-
+
if ( ! $wgUser->isSysop() ) {
$wgOut->sysopRequired();
return;
$n = $this->mTitle->getNamespace();
# Get the last editor, lock table exclusively
- $s = $dbw->getArray( 'cur',
+ $s = $dbw->getArray( 'cur',
array( 'cur_id','cur_user','cur_user_text','cur_comment' ),
array( 'cur_title' => $tt, 'cur_namespace' => $n ),
$fname, 'FOR UPDATE'
}
# Get the last edit not by this guy
- $s = $dbw->getArray( 'old',
+ $s = $dbw->getArray( 'old',
array( 'old_text','old_user','old_user_text','old_timestamp','old_flags' ),
- array(
- 'old_namespace' => $n,
+ array(
+ 'old_namespace' => $n,
'old_title' => $tt,
"old_user <> {$uid} OR old_user_text <> '{$ut}'"
), $fname, array( 'FOR UPDATE', 'USE INDEX' => 'name_title_timestamp' )
if ( $bot ) {
# Mark all reverted edits as bot
- $dbw->updateArray( 'recentchanges',
- array( /* SET */
- 'rc_bot' => 1
+ $dbw->updateArray( 'recentchanges',
+ array( /* SET */
+ 'rc_bot' => 1
), array( /* WHERE */
'rc_user' => $uid,
"rc_timestamp > '{$s->old_timestamp}'",
- ), $fname
+ ), $fname
);
}
{
global $wgDeferredUpdateList, $wgDBname, $wgMemc;
global $wgMessageCache;
-
+
wfSeedRandom();
if ( 0 == mt_rand( 0, 999 ) ) {
$dbw =& wfGetDB( DB_MASTER );
$id = $this->getID();
$dbr =& wfGetDB( DB_SLAVE );
- $s = $dbr->getArray( 'cur', array( 'cur_touched', 'cur_is_redirect' ),
+ $s = $dbr->getArray( 'cur', array( 'cur_touched', 'cur_is_redirect' ),
array( 'cur_id' => $id ), $fname );
if( $s !== false ) {
$this->mTouched = $s->cur_touched;
), array(
'cur_namespace' => $ns,
'cur_title' => $dbkey,
- ), $fname
+ ), $fname
);
# Use the affected row count to determine if the article is new
$curTable = $dbw->tableName( 'cur' );
$hitcounterTable = $dbw->tableName( 'hitcounter' );
$acchitsTable = $dbw->tableName( 'acchits' );
-
+
if( $wgHitcounterUpdateFreq <= 1 ){ //
$dbw->query( "UPDATE $curTable SET cur_counter = cur_counter + 1 WHERE cur_id = $id" );
return;
}
# Not important enough to warrant an error page in case of failure
- $oldignore = $dbw->ignoreErrors( true );
+ $oldignore = $dbw->ignoreErrors( true );
$dbw->query( "INSERT INTO $hitcounterTable (hc_id) VALUES ({$id})" );
{
global $wgUser, $wgTitle, $wgOut, $wgLang, $wgAllowPageInfo;
$fname = 'Article::info';
-
+
if ( !$wgAllowPageInfo ) {
$wgOut->errorpage( "nosuchaction", "nosuchactiontext" );
return;
}
-
+
$dbr =& wfGetDB( DB_SLAVE );
$basenamespace = $wgTitle->getNamespace() & (~1);
$cur_author = $dbr->selectField( 'cur', 'cur_user_text', $cur_clause, $fname );
# find number of 'old' authors excluding 'cur' author
- $authors = $dbr->selectField( 'old', 'COUNT(DISTINCT old_user_text)',
+ $authors = $dbr->selectField( 'old', 'COUNT(DISTINCT old_user_text)',
$old_clause + array( 'old_user_text<>' . $dbr->addQuotes( $cur_author ) ), $fname ) + 1;
# now for the Talk page ...
# number of authors
if ($exists > 0) {
$cur_author = $dbr->selectField( 'cur', 'cur_user_text', $cur_clause, $fname );
- $authors = $dbr->selectField( 'cur', 'COUNT(DISTINCT old_user_text)',
+ $authors = $dbr->selectField( 'cur', 'COUNT(DISTINCT old_user_text)',
$old_clause + array( 'old_user_text<>' . $dbr->addQuotes( $cur_author ) ), $fname );
$wgOut->addHTML( "<li>" . wfMsg("numtalkauthors", $authors) . "</li></ul>" );
/* private */ var $mOldUser, $mNewUser;
/* private */ var $mOldComment, $mNewComment;
/* private */ var $mOldPage, $mNewPage;
-
- function DifferenceEngine( $old, $new )
+ /* private */ var $mRcidMarkPatrolled;
+
+ function DifferenceEngine( $old, $new, $rcid = 0 )
{
$this->mOldid = $old;
$this->mNewid = $new;
+ $this->mRcidMarkPatrolled = intval($rcid); # force it to be an integer
}
function showDiffPage()
{
- global $wgUser, $wgTitle, $wgOut, $wgLang;
+ global $wgUser, $wgTitle, $wgOut, $wgLang, $wgOnlySysopsCanPatrol;
$fname = "DifferenceEngine::showDiffPage";
wfProfileIn( $fname );
-
+
$t = $wgTitle->getPrefixedText() . " (Diff: {$this->mOldid}, " .
"{$this->mNewid})";
$mtext = wfMsg( "missingarticle", $t );
return;
}
$wgOut->suppressQuickbar();
-
+
$oldTitle = $this->mOldPage->getPrefixedText();
$newTitle = $this->mNewPage->getPrefixedText();
if( $oldTitle == $newTitle ) {
}
$wgOut->setSubtitle( wfMsg( "difference" ) );
$wgOut->setRobotpolicy( "noindex,follow" );
-
+
if ( !( $this->mOldPage->userCanRead() && $this->mNewPage->userCanRead() ) ) {
$wgOut->loginToUse();
$wgOut->output();
$talk = $wgLang->getNsText( NS_TALK );
$contribs = wfMsg( "contribslink" );
-
$this->mOldComment = $sk->formatComment($this->mOldComment);
$this->mNewComment = $sk->formatComment($this->mNewComment);
-
$oldUserLink = $sk->makeLinkObj( Title::makeTitle( NS_USER, $this->mOldUser ), $this->mOldUser );
$newUserLink = $sk->makeLinkObj( Title::makeTitle( NS_USER, $this->mNewUser ), $this->mNewUser );
$oldUTLink = $sk->makeLinkObj( Title::makeTitle( NS_USER_TALK, $this->mOldUser ), $talk );
} else {
$rollback = "";
}
+ if ( $this->mRcidMarkPatrolled != 0 && $wgUser->getID() != 0 &&
+ ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) )
+ {
+ $patrol = " [" . $sk->makeKnownLinkObj( $wgTitle, wfMsg( 'markaspatrolleddiff' ),
+ "action=markpatrolled&rcid={$this->mRcidMarkPatrolled}" ) . "]";
+ } else {
+ $patrol = "";
+ }
- $oldHeader = "<strong>{$this->mOldtitle}</strong><br />$oldUserLink ($oldUTLink | $oldContribs)<br />".
- $this->mOldComment;
- $newHeader = "<strong>{$this->mNewtitle}</strong><br />$newUserLink ($newUTLink | $newContribs) $rollback<br />".
- $this->mNewComment;
+ $oldHeader = "<strong>{$this->mOldtitle}</strong><br />$oldUserLink " .
+ "($oldUTLink | $oldContribs)<br />" . $this->mOldComment;
+ $newHeader = "<strong>{$this->mNewtitle}</strong><br />$newUserLink " .
+ "($newUTLink | $newContribs) $rollback<br />" . $this->mNewComment . $patrol;
DifferenceEngine::showDiff( $this->mOldtext, $this->mNewtext,
$oldHeader, $newHeader );
$wgOut->addHTML( "<hr /><h2>{$this->mNewtitle}</h2>\n" );
$wgOut->addWikiText( $this->mNewtext );
-
+
wfProfileOut( $fname );
}
{
global $wgTitle, $wgOut, $wgLang;
$fname = "DifferenceEngine::loadText";
-
+
$dbr =& wfGetDB( DB_SLAVE );
if ( 0 == $this->mNewid || 0 == $this->mOldid ) {
$wgOut->setArticleFlag( true );
$this->mNewtitle = wfMsg( "currentrev" );
$id = $wgTitle->getArticleID();
-
- $s = $dbr->getArray( 'cur', array( 'cur_text', 'cur_user_text', 'cur_comment' ),
+
+ $s = $dbr->getArray( 'cur', array( 'cur_text', 'cur_user_text', 'cur_comment' ),
array( 'cur_id' => $id ), $fname );
- if ( $s === false ) {
- return false;
+ if ( $s === false ) {
+ return false;
}
$this->mNewPage = &$wgTitle;
$s = $dbr->getArray( 'old', array( 'old_namespace','old_title','old_timestamp', 'old_text',
'old_flags','old_user_text','old_comment' ), array( 'old_id' => $this->mNewid ), $fname );
- if ( $s === false ) {
- return false;
+ if ( $s === false ) {
+ return false;
}
$this->mNewtext = Article::getRevisionText( $s );
$this->mNewComment = $s->old_comment;
}
if ( 0 == $this->mOldid ) {
- $s = $dbr->getArray( 'old',
- array( 'old_namespace','old_title','old_timestamp','old_text', 'old_flags','old_user_text','old_comment' ),
+ $s = $dbr->getArray( 'old',
+ array( 'old_namespace','old_title','old_timestamp','old_text', 'old_flags','old_user_text','old_comment' ),
array( /* WHERE */
- 'old_namespace' => $this->mNewPage->getNamespace(),
- 'old_title' => $this->mNewPage->getDBkey()
+ 'old_namespace' => $this->mNewPage->getNamespace(),
+ 'old_title' => $this->mNewPage->getDBkey()
), $fname, array( 'ORDER BY' => 'inverse_timestamp', 'USE INDEX' => 'name_title_timestamp' )
);
} else {
- $s = $dbr->getArray( 'old',
+ $s = $dbr->getArray( 'old',
array( 'old_namespace','old_title','old_timestamp','old_text','old_flags','old_user_text','old_comment'),
- array( 'old_id' => $this->mOldid ),
+ array( 'old_id' => $this->mOldid ),
$fname
);
}
- if ( $s === false ) {
- return false;
+ if ( $s === false ) {
+ return false;
}
$this->mOldPage = Title::MakeTitle( $s->old_namespace, $s->old_title );
$this->mOldtext = Article::getRevisionText( $s );
$this->mOldtitle = wfMsg( "revisionasof", $t );
$this->mOldUser = $s->old_user_text;
$this->mOldComment = $s->old_comment;
-
+
return true;
}
}
var $type;
var $orig;
var $closing;
-
+
function reverse() {
trigger_error("pure virtual", E_USER_ERROR);
}
class _DiffOp_Copy extends _DiffOp {
var $type = 'copy';
-
+
function _DiffOp_Copy ($orig, $closing = false) {
if (!is_array($closing))
$closing = $orig;
class _DiffOp_Delete extends _DiffOp {
var $type = 'delete';
-
+
function _DiffOp_Delete ($lines) {
$this->orig = $lines;
$this->closing = false;
class _DiffOp_Add extends _DiffOp {
var $type = 'add';
-
+
function _DiffOp_Add ($lines) {
$this->closing = $lines;
$this->orig = false;
class _DiffOp_Change extends _DiffOp {
var $type = 'change';
-
+
function _DiffOp_Change ($orig, $closing) {
$this->orig = $orig;
$this->closing = $closing;
return new _DiffOp_Change($this->closing, $this->orig);
}
}
-
-
+
+
/**
* Class used internally by Diff to actually compute the diffs.
*
unset($this->seq);
unset($this->in_seq);
unset($this->lcs);
-
+
// Skip leading common lines.
for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) {
if ($from_lines[$skip] != $to_lines[$skip])
break;
$this->xchanged[$xi] = $this->ychanged[$yi] = false;
}
-
+
// Ignore lines which do not exist in both files.
for ($xi = $skip; $xi < $n_from - $endskip; $xi++)
$xhash[$from_lines[$xi]] = 1;
$add = array();
while ($yi < $n_to && $this->ychanged[$yi])
$add[] = $to_lines[$yi++];
-
+
if ($delete && $add)
$edits[] = new _DiffOp_Change($delete, $add);
elseif ($delete)
}
return $edits;
}
-
+
/* Divide the Largest Common Subsequence (LCS) of the sequences
* [XOFF, XLIM) and [YOFF, YLIM) into NCHUNKS approximately equally
*/
function _diag ($xoff, $xlim, $yoff, $ylim, $nchunks) {
$flip = false;
-
+
if ($xlim - $xoff > $ylim - $yoff) {
// Things seems faster (I'm not sure I understand why)
// when the shortest sequence in X.
$this->seq[0]= $yoff - 1;
$this->in_seq = array();
$ymids[0] = array();
-
+
$numer = $xlim - $xoff + $nchunks - 1;
$x = $xoff;
for ($chunk = 0; $chunk < $nchunks; $chunk++) {
*/
while ($j < $other_len && $other_changed[$j])
$j++;
-
+
while ($i < $len && ! $changed[$i]) {
USE_ASSERTS && assert('$j < $other_len && ! $other_changed[$j]');
$i++; $j++;
while ($j < $other_len && $other_changed[$j])
$j++;
}
-
+
if ($i == $len)
break;
/**
* Class representing a 'diff' between two sequences of strings.
*/
-class Diff
+class Diff
{
var $edits;
}
return true;
}
-
+
/**
* Compute the length of the Longest Common Subsequence (LCS).
*
*/
function orig() {
$lines = array();
-
+
foreach ($this->edits as $edit) {
if ($edit->orig)
array_splice($lines, sizeof($lines), 0, $edit->orig);
*/
function closing() {
$lines = array();
-
+
foreach ($this->edits as $edit) {
if ($edit->closing)
array_splice($lines, sizeof($lines), 0, $edit->closing);
}
/**
- * Check a Diff for validity.
+ * Check a Diff for validity.
*
* This is here only for debugging purposes.
*/
trigger_error("Diff okay: LCS = $lcs", E_USER_NOTICE);
}
}
-
+
/**
* FIXME: bad name.
*/
assert(sizeof($from_lines) == sizeof($mapped_from_lines));
assert(sizeof($to_lines) == sizeof($mapped_to_lines));
-
+
$this->Diff($mapped_from_lines, $mapped_to_lines);
$xi = $yi = 0;
$orig = array_slice($from_lines, $xi, sizeof($orig));
$xi += sizeof($orig);
}
-
+
$closing = &$this->edits[$i]->closing;
if (is_array($closing)) {
$closing = array_slice($to_lines, $yi, sizeof($closing));
return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
}
-
+
function _start_block($header) {
echo $header;
}
-
+
function _end_block() {
}
foreach ($lines as $line)
echo "$prefix $line\n";
}
-
+
function _context($lines) {
$this->_lines($lines);
}
/**
* Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3
- *
+ *
*/
define('NBSP', ' '); // iso-8859-x non-breaking space.
function _flushGroup ($new_tag) {
if ($this->_group !== '') {
- if ($this->_tag == 'mark')
+ if ($this->_tag == 'mark')
$this->_line .= '<span class="diffchange">'.$this->_group.'</span>';
else
$this->_line .= $this->_group;
$this->_group = '';
$this->_tag = $new_tag;
}
-
+
function _flushLine ($new_tag) {
$this->_flushGroup($new_tag);
if ($this->_line != '')
$this->_lines[] = $this->_line;
$this->_line = '';
}
-
+
function addWords ($words, $tag = '') {
if ($tag != $this->_tag)
$this->_flushGroup($tag);
list ($orig_words, $orig_stripped) = $this->_split($orig_lines);
list ($closing_words, $closing_stripped) = $this->_split($closing_lines);
-
+
$this->MappedDiff($orig_words, $closing_words,
$orig_stripped, $closing_stripped);
}
function orig () {
$orig = new _HWLDF_WordAccumulator;
-
+
foreach ($this->edits as $edit) {
if ($edit->type == 'copy')
$orig->addWords($edit->orig);
function closing () {
$closing = new _HWLDF_WordAccumulator;
-
+
foreach ($this->edits as $edit) {
if ($edit->type == 'copy')
$closing->addWords($edit->closing);
/**
* Wikipedia Table style diff formatter.
- *
+ *
*/
class TableDiffFormatter extends DiffFormatter
{
$this->leading_context_lines = 2;
$this->trailing_context_lines = 2;
}
-
+
function _block_header( $xbeg, $xlen, $ybeg, $ylen ) {
$l1 = wfMsg( "lineno", $xbeg );
$l2 = wfMsg( "lineno", $ybeg );
function contextLine( $line ) {
return '<td> </td><td class="diff-context">'.$line.'</td>';
}
-
+
function _added($lines) {
global $wgOut;
foreach ($lines as $line) {
function getSQL() {
return "SELECT 'sample' as type, 0 as namespace, 'Sample result' as title, 42 as value";
}
-
+
# Override to sort by increasing values
function sortDescending() {
return true;
function formatResult( $skin, $result ) {
return "";
}
-
+
# This is the actual workhorse. It does everything needed to make a
# real, honest-to-gosh query page.
-
+
function doQuery( $offset, $limit ) {
global $wgUser, $wgOut, $wgLang, $wgRequest;
global $wgMiserMode;
$wgOut->setSyndicated( true );
$res = false;
-
+
if ( $this->isExpensive() ) {
$recache = $wgRequest->getBool( "recache" );
if( $recache ) {
# Clear out any old cached data
$dbw->delete( 'querycache', array( 'qc_type' => $sname ), $fname );
-
+
# Do query on the (possibly out of date) slave server
$maxstored = 1000;
$res = $dbr->query( $sql . $this->getOrderLimit( 0, $maxstored ), $fname );
-
+
# Fetch results
$insertSql = "INSERT INTO $querycache (qc_type,qc_namespace,qc_title,qc_value) VALUES ";
$first = true;
$first = false;
} else {
$insertSql .= ",";
- }
+ }
$insertSql .= "(" .
$dbw->addQuotes( $row->type ) . "," .
$dbw->addQuotes( $row->namespace ) . "," .
$res = $dbr->query( $sql . $this->getOrderLimit( $offset, $limit ), $fname );
$num = $dbr->numRows($res);
}
-
-
+
+
$sk = $wgUser->getSkin( );
$top = wfShowingResults( $offset, $num);
# often disable 'next' link when we reach the end
if($num < $limit) { $atend = true; } else { $atend = false; }
-
+
$sl = wfViewPrevNext( $offset, $limit , $wgLang->specialPage( $sname ), "" ,$atend );
$wgOut->addHTML( "<br />{$sl}</p>\n" );
- $s = "<ol start='" . ( $offset + 1 ) . "'>";
+ $s = "<ol start='" . ( $offset + 1 ) . "' class='special'>";
# Only read at most $num rows, because $res may contain the whole 1000
for ( $i = 0; $i < $num && $obj = $dbr->fetchObject( $res ); $i++ ) {
$format = $this->formatResult( $sk, $obj );
- $s .= "<li>{$format}</li>\n";
+ $attr = ( $obj->usepatrol && $obj->patrolled == 0 ) ? ' class="not_patrolled"' : '';
+ $s .= "<li{$attr}>{$format}</li>\n";
}
$dbr->freeResult( $res );
$s .= "</ol>";
$wgOut->addHTML( $s );
$wgOut->addHTML( "<p>{$sl}</p>\n" );
}
-
+
# Similar to above, but packaging in a syndicated feed instead of a web page
function doFeed( $class = "" ) {
global $wgFeedClasses;
$this->feedDesc(),
$this->feedUrl() );
$feed->outHeader();
-
+
$dbr =& wfGetDB( DB_SLAVE );
$sql = $this->getSQL() . $this->getOrderLimit( 0, 50 );
$res = $dbr->query( $sql, "QueryPage::doFeed" );
} else {
$date = "";
}
-
+
$comments = "";
if( $title ) {
$talkpage = $title->getTalkPage();
$comments = $talkpage->getFullURL();
}
-
+
return new FeedItem(
$title->getText(),
$this->feedItemDesc( $row ),
return NULL;
}
}
-
+
function feedItemDesc( $row ) {
$text = "";
if( isset( $row->comment ) ) {
} else {
$text = "";
}
-
+
if( isset( $row->text ) ) {
$text = "<p>" . htmlspecialchars( wfMsg( "summary" ) ) . ": " . $text . "</p>\n<hr />\n<div>" .
nl2br( htmlspecialchars( $row->text ) ) . "</div>";;
}
return $text;
}
-
+
function feedItemAuthor( $row ) {
if( isset( $row->user_text ) ) {
return $row->user_text;
return "";
}
}
-
+
function feedTitle() {
global $wgLanguageCode, $wgSitename, $wgLang;
$page = SpecialPage::getPage( $this->getName() );
$desc = $page->getDescription();
return "$wgSitename - $desc [$wgLanguageCode]";
}
-
+
function feedDesc() {
return wfMsg( "fromwikipedia" );
}
-
+
function feedUrl() {
global $wgLang;
$title = Title::MakeTitle( NS_SPECIAL, $this->getName() );
/*
mAttributes:
+ rc_id id of the row in the recentchanges table
rc_timestamp time the entry was made
rc_cur_time timestamp on the cur row
rc_namespace namespace #
rc_title non-prefixed db key
- rc_type is new entry, used to determine whether updating is necessary
+ rc_type is new entry, used to determine whether updating is necessary
rc_minor is minor
rc_cur_id id of associated cur entry
rc_user user id who made the entry
rc_bot is bot, hidden
rc_ip IP address of the user in dotted quad notation
rc_new obsolete, use rc_type==RC_NEW
+ rc_patrolled boolean whether or not someone has marked this edit as patrolled
mExtra:
prefixedDBkey prefixed db key, used by external app via msg queue
var $mTitle = false, $mMovedToTitle = false;
# Factory methods
-
- /* static */ function newFromRow( $row )
+
+ /* static */ function newFromRow( $row )
{
$rc = new RecentChange;
$rc->loadFromRow( $row );
return $rc;
}
-
+
/* static */ function newFromCurRow( $row )
{
$rc = new RecentChange;
}
# Accessors
-
- function setAttribs( $attribs )
+
+ function setAttribs( $attribs )
{
$this->mAttribs = $attribs;
}
-
+
function setExtra( $extra )
{
$this->mExtra = $extra;
}
-
+
function getTitle()
{
if ( $this->mTitle === false ) {
function getMovedToTitle()
{
if ( $this->mMovedToTitle === false ) {
- $this->mMovedToTitle = Title::makeTitle( $this->mAttribs['rc_moved_to_ns'],
+ $this->mMovedToTitle = Title::makeTitle( $this->mAttribs['rc_moved_to_ns'],
$this->mAttribs['rc_moved_to_title'] );
}
return $this->mMovedToTitle;
}
# Writes the data in this object to the database
- function save()
+ function save()
{
global $wgUseRCQueue, $wgRCQueueID, $wgLocalInterwiki, $wgPutIPinRC;
$fname = "RecentChange::save";
-
+
$dbw =& wfGetDB( DB_MASTER );
if ( !is_array($this->mExtra) ) {
$this->mExtra = array();
}
$this->mExtra['lang'] = $wgLocalInterwiki;
-
+
if ( !$wgPutIPinRC ) {
$this->mAttribs['rc_ip'] = '';
}
-
+
# Insert new row
$dbw->insertArray( "recentchanges", $this->mAttribs, $fname );
-
+
# Update old rows, if necessary
if ( $this->mAttribs['rc_type'] == RC_EDIT ) {
$oldid = $this->mAttribs['rc_last_oldid'];
$lastTime = $this->mExtra['lastTimestamp'];
$now = $this->mAttribs['rc_timestamp'];
$curId = $this->mAttribs['rc_cur_id'];
-
+
# Update rc_this_oldid for the entries which were current
- $dbw->updateArray( 'recentchanges',
+ $dbw->updateArray( 'recentchanges',
array( /* SET */
'rc_this_oldid' => $oldid
- ), array( /* WHERE */
+ ), array( /* WHERE */
'rc_namespace' => $ns,
'rc_title' => $title,
'rc_timestamp' => $lastTime
);
# Update rc_cur_time
- $dbw->updateArray( 'recentchanges', array( 'rc_cur_time' => $now ),
+ $dbw->updateArray( 'recentchanges', array( 'rc_cur_time' => $now ),
array( 'rc_cur_id' => $curId ), $fname );
}
-
+
# Notify external application
if ( $wgUseRCQueue ) {
$queue = msg_get_queue( $wgRCQueueID );
- if (!msg_send( $queue, array_merge( $this->mAttribs, 1, $this->mExtra ),
- true, false, $error ))
+ if (!msg_send( $queue, array_merge( $this->mAttribs, 1, $this->mExtra ),
+ true, false, $error ))
{
wfDebug( "Error sending message to RC queue, code $error\n" );
}
}
}
-
+
+ # Marks a certain row as patrolled
+ function markPatrolled( $rcid )
+ {
+ $fname = "RecentChange::markPatrolled";
+
+ $dbw =& wfGetDB( DB_MASTER );
+
+ $dbw->updateArray( 'recentchanges',
+ array( /* SET */
+ 'rc_patrolled' => 1
+ ), array( /* WHERE */
+ 'rc_id' => $rcid
+ ), $fname
+ );
+ }
+
# Makes an entry in the database corresponding to an edit
- /*static*/ function notifyEdit( $timestamp, &$title, $minor, &$user, $comment,
- $oldId, $lastTimestamp, $bot = "default", $ip = '' )
+ /*static*/ function notifyEdit( $timestamp, &$title, $minor, &$user, $comment,
+ $oldId, $lastTimestamp, $bot = "default", $ip = '' )
{
if ( $bot == "default " ) {
$bot = $user->isBot();
global $wgIP;
$ip = empty( $wgIP ) ? '' : $wgIP;
}
-
+
$rc = new RecentChange;
$rc->mAttribs = array(
'rc_timestamp' => $timestamp,
'rc_ip' => $ip,
'rc_new' => 0 # obsolete
);
-
+
$rc->mExtra = array(
'prefixedDBkey' => $title->getPrefixedDBkey(),
'lastTimestamp' => $lastTimestamp
);
$rc->save();
}
-
+
# Makes an entry in the database corresponding to page creation
# Note: the title object must be loaded with the new id using resetArticleID()
/*static*/ function notifyNew( $timestamp, &$title, $minor, &$user, $comment, $bot = "default", $ip='' )
'rc_ip' => $ip,
'rc_new' => 1 # obsolete
);
-
+
$rc->mExtra = array(
'prefixedDBkey' => $title->getPrefixedDBkey(),
'lastTimestamp' => 0
);
$rc->save();
}
-
+
# Makes an entry in the database corresponding to a rename
/*static*/ function notifyMove( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='', $overRedir = false )
{
'rc_moved_to_ns' => $newTitle->getNamespace(),
'rc_moved_to_title' => $newTitle->getDBkey(),
'rc_ip' => $ip,
- 'rc_new' => 0 # obsolete
+ 'rc_new' => 0, # obsolete
+ 'rc_patrolled' => 1
);
-
+
$rc->mExtra = array(
'prefixedDBkey' => $oldTitle->getPrefixedDBkey(),
'lastTimestamp' => 0,
);
$rc->save();
}
-
+
/* static */ function notifyMoveToNew( $timestamp, &$oldTitle, &$newTitle, &$user, $comment, $ip='' ) {
RecentChange::notifyMove( $timestamp, $oldTitle, $newTitle, $user, $comment, $ip, false );
}
RecentChange::notifyMove( $timestamp, $oldTitle, $newTitle, $user, $comment, $ip='', true );
}
- # A log entry is different to an edit in that previous revisions are
+ # A log entry is different to an edit in that previous revisions are
# not kept
/*static*/ function notifyLog( $timestamp, &$title, &$user, $comment, $ip='' )
{
'rc_moved_to_ns' => 0,
'rc_moved_to_title' => '',
'rc_ip' => $ip,
+ 'rc_patrolled' => 1,
'rc_new' => 0 # obsolete
);
$rc->mExtra = array(
$this->mAttribs = get_object_vars( $row );
$this->mExtra = array();
}
-
+
# Makes a pseudo-RC entry from a cur row, for watchlists and things
function loadFromCurRow( $row )
{
$printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
return $printfooter . $this->doAfterContent();
}
-
+
function printSource() {
global $wgTitle;
$url = htmlspecialchars( $wgTitle->getFullURL() );
return wfMsg( "retrievedfrom", "<a href=\"$url\">$url</a>" );
}
-
+
function printFooter() {
return "<p>" . $this->printSource() .
"</p>\n\n<p>" . $this->pageStats() . "</p>\n";
$this->lastdate = $date;
$this->rclistOpen = true;
}
- $s .= '<li> ';
+
+ # If this edit has not yet been patrolled, make it stick out
+ $s .= ( $rc_patrolled ) ? '<li> ' : '<li class="not_patrolled"> ';
if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
# Diff
') . . ';
# "[[x]] moved to [[y]]"
- if ( $rc_type == RC_MOVE ) {
- $msg = '1movedto2';
- } else {
- $msg = '1movedto2_redir';
- }
+ $msg = ( $rc_type == RC_MOVE ) ? '1movedto2' : '1movedto2_redir';
$s .= wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
$this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
} else {
if ( $rc_type == RC_NEW || $rc_type == RC_LOG ) {
$diffLink = wfMsg( 'diff' );
} else {
+ if ( $rc_patrolled == 0 && $wgUser->getID() != 0 &&
+ ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) )
+ $rcidparam = "&rcid={$rc_id}";
+ else
+ $rcidparam = "";
$diffLink = $this->makeKnownLinkObj( $rc->getTitle(), wfMsg( 'diff' ),
- $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid ,'' ,'' , ' tabindex="'.$rc->counter.'"');
+ "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}{$rcidparam}",
+ '', '', ' tabindex="'.$rc->counter.'"');
}
$s .= '('.$diffLink.') (';
if ( $rc_type == RC_NEW ) { $s .= '<strong>'.$N.'</strong>'; }
# Article link
- $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
+ # If it's a new article, there is no diff link, but if it hasn't been
+ # patrolled yet, we need to give users a way to do so
+ if ( $rc_type == RC_NEW && $rc_patrolled == 0 && $wgUser->getID() != 0 &&
+ ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) )
+ $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
+ else
+ $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
if ( $watched ) {
$articleLink = '<strong>'.$articleLink.'</strong>';
# If it's a new day, add the headline and flush the cache
$date = $wgLang->date( $rc_timestamp, true);
- $ret = '' ;
+ $ret = '';
if ( $date != $this->lastdate ) {
# Process current cache
$ret = $this->recentChangesBlock () ;
# Make article link
if ( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
- if ( $rc_type == RC_MOVE ) {
- $msg = "1movedto2";
- } else {
- $msg = "1movedto2_redir";
- }
+ $msg = ( $rc_type == RC_MOVE ) ? "1movedto2" : "1movedto2_redir";
$clink = wfMsg( $msg, $this->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ),
$this->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) );
} else {
}
# Make user link (or user contributions for unregistered users)
- if ( 0 == $rc_user ) {
+ if ( $rc_user == 0 ) {
$userLink = $this->makeKnownLink( $wgLang->specialPage( 'Contributions' ),
$rc_user_text, 'target=' . $rc_user_text );
} else {
Namespace::getUser() ) . ':'.$rc_user_text, $rc_user_text );
}
- $rc->userlink = $userLink ;
- $rc->lastlink = $lastLink ;
- $rc->curlink = $curLink ;
+ $rc->userlink = $userLink;
+ $rc->lastlink = $lastLink;
+ $rc->curlink = $curLink;
$rc->difflink = $diffLink;
-
# Make user talk link
$utns=$wgLang->getNsText(NS_USER_TALK);
$talkname=$wgLang->getNsText(NS_TALK); # use the shorter name
function getName() {
return "Newpages";
}
-
+
function isExpensive() {
# Indexed on RC, and will *not* work with querycache yet.
return false;
}
function getSQL() {
+ global $wgUser, $wgOnlySysopsCanPatrol;
+ $usepatrol = ( $wgUser->getID() != 0 && ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) ) ? 1 : 0;
$dbr =& wfGetDB( DB_SLAVE );
extract( $dbr->tableNames( 'recentchanges', 'cur' ) );
rc_namespace AS namespace,
rc_title AS title,
rc_cur_id AS value,
-
rc_user AS user,
rc_user_text AS user_text,
rc_comment as comment,
rc_timestamp AS timestamp,
+ '{$usepatrol}' as usepatrol,
+ rc_patrolled AS patrolled,
+ rc_id AS rcid,
length(cur_text) as length,
cur_text as text
FROM $recentchanges,$cur
}
function formatResult( $skin, $result ) {
- global $wgLang;
+ global $wgLang, $wgUser, $wgOnlySysopsCanPatrol;
$u = $result->user;
$ut = $result->user_text;
}
$d = $wgLang->timeanddate( $result->timestamp, true );
- $link = $skin->makeKnownLink( $result->title, "" );
+
+ # If it's a new article, there is no diff link, but if it hasn't been
+ # patrolled yet, we need to give users a way to do so
+ if ( $result->usepatrol && $result->patrolled == 0 && $wgUser->getID() != 0 &&
+ ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) )
+ $link = $skin->makeKnownLink( $result->title, '', "rcid={$result->rcid}" );
+ else
+ $link = $skin->makeKnownLink( $result->title, '' );
+
$s = "{$d} {$link} ({$length}) . . {$ul}";
if ( "" != $c && "*" != $c ) {
{
global $wgRequest;
list( $limit, $offset ) = wfCheckLimits();
-
+
$npp = new NewPagesPage();
if( !$npp->doFeed( $wgRequest->getVal( 'feed' ) ) ) {
if ( !$defaultDays ) {
$defaultDays = 3;
}
-
+
$days = $wgRequest->getInt( 'days', $defaultDays );
$hideminor = $wgRequest->getBool( 'hideminor', $wgUser->getOption( 'hideminor' ) ) ? 1 : 0;
$from = $wgRequest->getText( 'from' );
$hidebots = $wgRequest->getBool( 'hidebots', true ) ? 1 : 0;
$hideliu = $wgRequest->getBool( 'hideliu', false ) ? 1 : 0;
-
+ $hidepatrolled = $wgRequest->getBool( 'hidepatrolled', false ) ? 1 : 0;
+
# Get query parameters from path
if( $par ) {
$bits = preg_split( '/\s*,\s*/', trim( $par ) );
if( in_array( "hideminor", $bits ) ) $hideminor = 1;
if( in_array( "minor", $bits ) ) $hideminor = 0;
if( in_array( "hideliu", $bits) ) $hideliu = 1;
+ if( in_array( "hidepatrolled", $bits) ) $hidepatrolled = 1;
}
-
+
$dbr =& wfGetDB( DB_SLAVE );
extract( $dbr->tableNames( 'recentchanges', 'watchlist' ) );
-
+
$lastmod = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', false, $fname );
# 10 seconds server-side caching max
$wgOut->setSquidMaxage( 10 );
}
# The next few lines can probably be commented out now that wfMsg can get text from the DB
- $rctext = $dbr->selectField( 'cur', 'cur_text',
+ $rctext = $dbr->selectField( 'cur', 'cur_text',
array( 'cur_namespace' => NS_WIKIPEDIA, 'cur_title' => 'Recentchanges' ),
$fname
);
if( !$rctext ) {
$rctext = wfMsg( "recentchangestext" );
}
-
+
$wgOut->addWikiText( $rctext );
-
+
list( $limit, $offset ) = wfCheckLimits( 100, "rclimit" );
$now = wfTimestampNow();
$cutoff_unixtime = time() - ( $days * 86400 );
$sk = $wgUser->getSkin();
$showhide = array( wfMsg( "show" ), wfMsg( "hide" ));
-
- if ( $hideminor ) {
- $hidem = "AND rc_minor=0";
- } else {
- $hidem = "";
- }
-
- if( $hidebots ) {
- $hidem .= " AND rc_bot=0";
- }
-
- if ( $hideliu ) {
- $hidem .= " AND rc_user=0";
- }
- $hideliu = ($hideliu ? 1 : 0);
- #$hideparams = "hideminor={$hideminor}&hideliu={$hideliu}&hidebots={$hidebots}";
- $urlparams = array( "hideminor" => $hideminor, "hideliu" => $hideliu, "hidebots" => $hidebots );
+
+ $hidem = ( $hideminor ) ? "AND rc_minor=0" : "";
+ $hidem .= ( $hidebots ) ? " AND rc_bot=0" : "";
+ $hidem .= ( $hideliu ) ? " AND rc_user=0" : "";
+ $hidem .= ( $hidepatrolled )? " AND rc_patrolled=0" : "";
+
+ $urlparams = array( "hideminor" => $hideminor, "hideliu" => $hideliu,
+ "hidebots" => $hidebots, "hidepatrolled" => $hidepatrolled );
$hideparams = wfArrayToCGI( $urlparams );
-
+
$minorLink = $sk->makeKnownLink( $wgLang->specialPage( "Recentchanges" ),
$showhide[1-$hideminor], wfArrayToCGI( array( "hideminor" => 1-$hideminor ), $urlparams ) );
$botLink = $sk->makeKnownLink( $wgLang->specialPage( "Recentchanges" ),
$showhide[1-$hidebots], wfArrayToCGI( array( "hidebots" => 1-$hidebots ), $urlparams ) );
$liuLink = $sk->makeKnownLink( $wgLang->specialPage( "Recentchanges" ),
$showhide[1-$hideliu], wfArrayToCGI( array( "hideliu" => 1-$hideliu ), $urlparams ) );
+ $patrLink = $sk->makeKnownLink( $wgLang->specialPage( "Recentchanges" ),
+ $showhide[1-$hidepatrolled], wfArrayToCGI( array( "hidepatrolled" => 1-$hidepatrolled ), $urlparams ) );
$uid = $wgUser->getID();
$sql2 = "SELECT $recentchanges.*" . ($uid ? ",wl_user" : "") . " FROM $recentchanges " .
$res = $dbr->query( $sql2, DB_SLAVE, $fname );
$rows = array();
- while( $row = $dbr->fetchObject( $res ) ){
- $rows[] = $row;
+ while( $row = $dbr->fetchObject( $res ) ){
+ $rows[] = $row;
}
$dbr->freeResult( $res );
-
+
if(isset($from)) {
$note = wfMsg( "rcnotefrom", $wgLang->formatNum( $limit ),
$wgLang->timeanddate( $from, true ) );
}
$wgOut->addHTML( "\n<hr />\n{$note}\n<br />" );
- $note = rcDayLimitLinks( $days, $limit, "Recentchanges", $hideparams, false, $minorLink, $botLink, $liuLink );
+ $note = rcDayLimitLinks( $days, $limit, "Recentchanges", $hideparams, false, $minorLink, $botLink, $liuLink, $patrLink );
$note .= "<br />\n" . wfMsg( "rclistfrom",
$sk->makeKnownLink( $wgLang->specialPage( "Recentchanges" ),
$counter = 1;
foreach( $rows as $obj ){
if( $limit == 0) {
- break;
+ break;
}
-
- if ( ! ( $hideminor && $obj->rc_minor ) ) {
+
+ if ( ! ( $hideminor && $obj->rc_minor ) &&
+ ! ( $hidepatrolled && $obj->rc_patrolled ) ) {
$rc = RecentChange::newFromRow( $obj );
$rc->counter = $counter++;
$s .= $sk->recentChangesLine( $rc, !empty( $obj->wl_user ) );
return $s;
}
-function rcDayLimitLinks( $days, $limit, $page="Recentchanges", $more="", $doall = false, $minorLink = "",
- $botLink = "", $liuLink = "" )
+function rcDayLimitLinks( $days, $limit, $page="Recentchanges", $more="", $doall = false, $minorLink = "",
+ $botLink = "", $liuLink = "", $patrLink = "" )
{
if ($more != "") $more .= "&";
$cl = rcCountLink( 50, $days, $page, $more ) . " | " .
rcDaysLink( $limit, 14, $page, $more ) . " | " .
rcDaysLink( $limit, 30, $page, $more ) .
( $doall ? ( " | " . rcDaysLink( $limit, 0, $page, $more ) ) : "" );
- $shm = wfMsg( "showhideminor", $minorLink, $botLink, $liuLink );
+ $shm = wfMsg( "showhideminor", $minorLink, $botLink, $liuLink, $patrLink );
$note = wfMsg( "rclinks", $cl, $dl, $shm );
return $note;
}
"numtalkauthors" => "Number of distinct authors (discussion page): $1",
# Math options
- 'mw_math_png' => 'Always render PNG',
- 'mw_math_simple' => 'HTML if very simple or else PNG',
- 'mw_math_html' => 'HTML if possible or else PNG',
- 'mw_math_source' => 'Leave it as TeX (for text browsers)',
- 'mw_math_modern' => 'Recommended for modern browsers',
- 'mw_math_mathml' => 'MathML if possible (experimental)',
+'mw_math_png' => 'Always render PNG',
+'mw_math_simple' => 'HTML if very simple or else PNG',
+'mw_math_html' => 'HTML if possible or else PNG',
+'mw_math_source' => 'Leave it as TeX (for text browsers)',
+'mw_math_modern' => 'Recommended for modern browsers',
+'mw_math_mathml' => 'MathML if possible (experimental)',
+
+# Patrolling
+'markaspatrolleddiff' => "Mark as patrolled",
+'markaspatrolledlink' => "<div class='patrollink'>[$1]</div>",
+'markaspatrolledtext' => "Mark this article as patrolled",
+'markedaspatrolled' => "Marked as patrolled",
+'markedaspatrolledtext' => "The selected revision has been marked as patrolled.",
# Monobook.js: tooltips and access keys for monobook
'Monobook.js' => '/* tooltips and access keys */
}
return $s;
}
-
+
# Crop a string from the beginning or end to a certain number of bytes.
# (Bytes are used because our storage has limited byte lengths for some
# columns in the database.) Multibyte charsets will need to make sure that
--- /dev/null
+--
+-- patch-rc-patrol.sql
+-- Adds a row to recentchanges for the patrolling feature
+-- 2004-08-09
+--
+
+ALTER TABLE recentchanges
+ ADD COLUMN rc_patrolled tinyint(3) unsigned NOT NULL default '0';
+
user_password tinyblob NOT NULL default '',
user_newpassword tinyblob NOT NULL default '',
user_email tinytext NOT NULL default '',
- user_options blob NOT NULL default '',
+ user_options blob NOT NULL default '',
user_touched char(14) binary NOT NULL default '',
UNIQUE KEY user_id (user_id)
) PACK_KEYS=1;
-
+
CREATE TABLE user_newtalk (
user_id int(5) NOT NULL default '0',
user_ip varchar(40) NOT NULL default ''
rc_type tinyint(3) unsigned NOT NULL default '0',
rc_moved_to_ns tinyint(3) unsigned NOT NULL default '0',
rc_moved_to_title varchar(255) binary NOT NULL default '',
+ rc_patrolled tinyint(3) unsigned NOT NULL default '0',
rc_ip char(15) NOT NULL default '',
PRIMARY KEY rc_id (rc_id)
) PACK_KEYS=1;
.printfooter {
display: none;
}
+
+ul.special li.not_patrolled, ol.special li.not_patrolled {
+ background-color: #ffa;
+}
+div.patrollink {
+ font-size: 75%;
+ text-align: right;
+}