Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Wikipedia: Mediawiki-CVS

SVN: [58564] trunk/extensions/FlaggedRevs

 

 

Wikipedia mediawiki-cvs RSS feed   Index | Next | Previous | View Threaded


aaron at svn

Nov 4, 2009, 12:23 PM

Post #1 of 1 (13 views)
Permalink
SVN: [58564] trunk/extensions/FlaggedRevs

http://www.mediawiki.org/wiki/Special:Code/MediaWiki/58564

Revision: 58564
Author: aaron
Date: 2009-11-04 20:23:24 +0000 (Wed, 04 Nov 2009)

Log Message:
-----------
*Abstraction refactoring:
**Made getTitle() and such actually work for FlaggedArticle; tedious this->parent->getTitle() stuff removed
**Moved UI stuff from FlaggedArticle to FlaggedArticleView; uses singleton()
**Use "self" instead of hardcoded "FlaggedArticle"
*Other:
**Limited $this->flags cache size
**Added showDiffOnEditUser()
**Minor getReviewNotes() cleanup

Modified Paths:
--------------
trunk/extensions/FlaggedRevs/FlaggedArticle.php
trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php
trunk/extensions/FlaggedRevs/FlaggedRevs.php

Added Paths:
-----------
trunk/extensions/FlaggedRevs/FlaggedArticleView.php

Modified: trunk/extensions/FlaggedRevs/FlaggedArticle.php
===================================================================
--- trunk/extensions/FlaggedRevs/FlaggedArticle.php 2009-11-04 19:48:25 UTC (rev 58563)
+++ trunk/extensions/FlaggedRevs/FlaggedArticle.php 2009-11-04 20:23:24 UTC (rev 58564)
@@ -1,27 +1,25 @@
<?php

class FlaggedArticle extends Article {
- protected $isDiffFromStable = false;
- protected $isMultiPageDiff = false;
+ protected $parent;
+ # Process cache variables
protected $stableRev = null;
protected $pageConfig = null;
- protected $flags = null;
- protected $reviewNotice = '';
- protected $reviewNotes = '';
- protected $parent;
+ protected $flags = array();

+ # Max number of revisions in tag cache
+ const CACHE_MAX = 1000;
+
/**
- * Get the FlaggedArticle instance associated with $wgArticle/$wgTitle,
- * or false if there isn't such a title
+ * Construct a new FlaggedArticle from its Article parent
+ * Should not be called directly, use FlaggedArticle::getInstance()
+ * @param Article $parent
*/
- public static function getGlobalInstance() {
- global $wgArticle, $wgTitle;
- if( !empty( $wgArticle ) ) {
- return self::getInstance( $wgArticle );
- } elseif( !empty( $wgTitle ) ) {
- return self::getTitleInstance( $wgTitle );
- }
- return null;
+ public function __construct( $parent ) {
+ # Perform normal Article construction
+ parent::__construct( $parent->mTitle );
+ # Link to given Article/ImagePage/CategoryPage for caching
+ $this->parent =& $parent;
}

/**
@@ -31,7 +29,7 @@
public static function getTitleInstance( $title ) {
if( !isset( $title->flaggedRevsArticle ) ) {
$article = MediaWiki::articleFromTitle( $title );
- $article->flaggedRevsArticle = new FlaggedArticle( $article );
+ $article->flaggedRevsArticle = new self( $article );
$title->flaggedRevsArticle =& $article->flaggedRevsArticle;
}
return $title->flaggedRevsArticle;
@@ -52,65 +50,13 @@
$article->flaggedRevsArticle->parent =& $article;
} else {
// Create new FlaggedArticle
- $article->flaggedRevsArticle = new FlaggedArticle( $article );
+ $article->flaggedRevsArticle = new self( $article );
$article->getTitle()->flaggedRevsArticle =& $article->flaggedRevsArticle;
}
return $article->flaggedRevsArticle;
}

- /**
- * Construct a new FlaggedArticle from its Article parent
- * Should not be called directly, use FlaggedArticle::getInstance()
- */
- function __construct( $parent ) {
- $this->parent =& $parent;
- }
-
- /**
- * Does the config and current URL params allow
- * for overriding by stable revisions?
- */
- public function pageOverride() {
- global $wgUser, $wgRequest;
- # This only applies to viewing content pages
- $action = $wgRequest->getVal( 'action', 'view' );
- if( !self::isViewAction($action) || !$this->isReviewable() )
- return false;
- # Does not apply to diffs/old revision...
- if( $wgRequest->getVal('oldid') || $wgRequest->getVal('diff') )
- return false;
- # Explicit requests for a certain stable version handled elsewhere...
- if( $wgRequest->getVal('stableid') )
- return false;
- # Check user preferences
- if( $wgUser->getOption('flaggedrevsstable') )
- return !( $wgRequest->getIntOrNull('stable') === 0 );
- # Get page configuration
- $config = $this->getVisibilitySettings();
- # Does the stable version override the current one?
- if( $config['override'] ) {
- if( FlaggedRevs::ignoreDefaultVersion() ) {
- return ( $wgRequest->getIntOrNull('stable') === 1 );
- }
- # Viewer sees stable by default
- return !( $wgRequest->getIntOrNull('stable') === 0 );
- # We are explicity requesting the stable version?
- } elseif( $wgRequest->getIntOrNull('stable') === 1 ) {
- return true;
- }
- return false;
- }
-
/**
- * Is this a view page action?
- * @param $action string
- * @returns bool
- */
- protected static function isViewAction( $action ) {
- return ( $action == 'view' || $action == 'purge' || $action == 'render' || $action == 'historysubmit' );
- }
-
- /**
* Is the stable version shown by default for this page?
* @returns bool
*/
@@ -121,16 +67,6 @@
}

/**
- * Is this user shown the stable version by default for this page?
- * @returns bool
- */
- public function showStableByDefaultUser() {
- # Get page configuration
- $config = $this->getVisibilitySettings();
- return ( $config['override'] && !FlaggedRevs::ignoreDefaultVersion() );
- }
-
- /**
* Is most of the UI on this page to be hidden?
* @returns bool
*/
@@ -168,7 +104,7 @@
* @param bool $titleOnly, only check if title is in reviewable namespace
*/
public function isReviewable( $titleOnly = false ) {
- if( !FlaggedRevs::isPageReviewable( $this->parent->getTitle() ) ) {
+ if( !FlaggedRevs::isPageReviewable( $this->getTitle() ) ) {
return false;
} elseif( !$titleOnly && FlaggedRevs::forDefaultVersionOnly() && !$this->showStableByDefault() ) {
return false;
@@ -182,7 +118,7 @@
* @return bool
*/
public function isPatrollable( $titleOnly = false ) {
- if( FlaggedRevs::isPagePatrollable( $this->parent->getTitle() ) ) {
+ if( FlaggedRevs::isPagePatrollable( $this->getTitle() ) ) {
return true;
} elseif( !$titleOnly && FlaggedRevs::forDefaultVersionOnly() && !$this->showStableByDefault() ) {
return true;
@@ -190,1180 +126,12 @@
return false;
}

- /**
- * Output review notice
- */
- private function displayTag() {
- global $wgOut, $wgRequest;
- // UI may be limited to unobtrusive patrolling system
- if( $wgRequest->getVal('stableid') || !$this->limitedUI() ) {
- $wgOut->appendSubtitle( $this->reviewNotice );
- }
- return true;
- }
-
-
- /**
- * Add a stable link when viewing old versions of an article that
- * have been reviewed. (e.g. for &oldid=x urls)
- */
- public function addStableLink() {
- global $wgRequest, $wgOut, $wgLang;
- # Only for viewing old versions. UI may be limited to unobtrusive patrolling system.
- if( !$wgRequest->getVal('oldid') || $this->limitedUI() )
- return true;
- # We may have nav links like "direction=prev&oldid=x"
- $revID = $this->parent->getOldIDFromRequest();
- $frev = FlaggedRevision::newFromTitle( $this->parent->getTitle(), $revID );
- # Give a notice if this rev ID corresponds to a reviewed version...
- if( !is_null($frev) ) {
- wfLoadExtensionMessages( 'FlaggedRevs' );
- $time = $wgLang->date( $frev->getTimestamp(), true );
- $flags = $frev->getTags();
- $quality = FlaggedRevs::isQuality( $flags );
- $msg = $quality ? 'revreview-quality-source' : 'revreview-basic-source';
- $tag = wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time );
- # Hide clutter
- if( !FlaggedRevs::useSimpleUI() && !empty($flags) ) {
- $tag .= " " . FlaggedRevsXML::ratingToggle() .
- "<span id='mw-revisionratings' style='display:block;'><br/>" .
- wfMsgHtml('revreview-oldrating') .
- FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
- }
- $tag = "<div id='mw-revisiontag-old' class='flaggedrevs_notice plainlinks noprint'>$tag</div>";
- $wgOut->addHTML( $tag );
- }
- return true;
- }
-
- /**
- * Replaces a page with the last stable version if possible
- * Adds stable version status/info tags and notes
- * Adds a quick review form on the bottom if needed
- */
- public function setPageContent( &$outputDone, &$pcache ) {
- global $wgRequest, $wgOut, $wgUser, $wgLang, $wgContLang;
- # Only trigger on article view for content pages, not for protect/delete/hist...
- $action = $wgRequest->getVal( 'action', 'view' );
- if( !self::isViewAction($action) || !$this->parent->exists() )
- return true;
- # Do not clutter up diffs any further and leave archived versions alone...
- if( $wgRequest->getVal('diff') || $wgRequest->getVal('oldid') ) {
- return true;
- }
- # Only trigger for reviewable pages
- if( !$this->isReviewable() ) {
- return true;
- }
- # Load required messages
- wfLoadExtensionMessages( 'FlaggedRevs' );
- $simpleTag = $old = $stable = false;
- $tag = $prot = '';
- # Check the newest stable version.
- $frev = $srev = $this->getStableRev();
- $stableId = $frev ? $frev->getRevId() : 0;
- # Also, check for any explicitly requested old stable version...
- $reqId = $wgRequest->getVal('stableid');
- if( $reqId === "best" ) {
- $reqId = FlaggedRevs::getPrimeFlaggedRevId( $this->parent );
- }
- if( $stableId && $reqId ) {
- # Treat requesting the stable version by ID as &stable=1
- if( $reqId != $stableId ) {
- $frev = FlaggedRevision::newFromTitle( $this->parent->getTitle(), $reqId, FR_TEXT );
- $old = true; // old reviewed version requested by ID
- if( !$frev ) {
- $wgOut->addWikiText( wfMsg('revreview-invalid') );
- $wgOut->returnToMain( false, $this->parent->getTitle() );
- # Tell MW that parser output is done
- $outputDone = true;
- $pcache = false;
- return true;
- }
- } else {
- $stable = true; // stable version requested by ID
- }
- }
- // Is the page config altered?
- if( $this->isPageLocked() ) {
- $prot = "<span class='fr-icon-locked' title=\"".
- wfMsgHtml('revreview-locked-title')."\"></span>";
- } elseif( $this->isPageUnlocked() ) {
- $prot = "<span class='fr-icon-unlocked' title=\"".
- wfMsgHtml('revreview-unlocked-title')."\"></span>";
- }
- // RTL langauges
- $rtl = $wgContLang->isRTL() ? " rtl" : "";
- // Is there no stable version?
- if( is_null($frev) ) {
- // Add "no reviewed version" tag, but not for printable output.
- if( !$wgOut->isPrintable() ) {
- // Simple icon-based UI
- if( FlaggedRevs::useSimpleUI() ) {
- $msg = $old ? 'revreview-quick-invalid' : 'revreview-quick-none';
- $tag .= "{$prot}<span class='fr-icon-current plainlinks'></span>" .
- wfMsgExt($msg,array('parseinline'));
- $tag = "<div id='mw-revisiontag' class='flaggedrevs_short{$rtl} plainlinks noprint'>$tag</div>";
- $this->reviewNotice .= $tag;
- // Standard UI
- } else {
- $msg = $old ? 'revreview-invalid' : 'revreview-noflagged';
- $tag = "<div id='mw-revisiontag' class='flaggedrevs_notice plainlinks noprint'>" .
- "{$prot}<span class='fr-icon-current plainlinks'></span>" .
- wfMsgExt($msg, array('parseinline')) . "</div>";
- $this->reviewNotice .= $tag;
- }
- }
- # Show notice bar/icon
- $this->displayTag();
- return true;
- }
- # Get flags and date
- $time = $wgLang->date( $frev->getTimestamp(), true );
- $flags = $frev->getTags();
- # Get quality level
- $quality = FlaggedRevs::isQuality( $flags );
- $pristine = FlaggedRevs::isPristine( $flags );
- // Looking at some specific old stable revision ("&stableid=x")
- // set to override given the relevant conditions. If the user is
- // requesting the stable revision ("&stableid=x"), defer to override
- // behavior below, since it is the same as ("&stable=1").
- if( $old ) {
- $this->showOldReviewedVersion( $srev, $frev, $tag, $prot );
- $outputDone = true; # Tell MW that parser output is done
- $pcache = false;
- // Looking at some specific old revision (&oldid=x) or if FlaggedRevs is not
- // set to override given the relevant conditions (like &action=protect).
- } elseif( !$stable && !$this->pageOverride() ) {
- $this->showRegularVersion( $srev, $tag, $prot );
- // The relevant conditions are met to override the page with the stable version.
- } else {
- $this->showStableVersion( $srev, $tag, $prot );
- $outputDone = true; # Tell MW that parser output is done
- $pcache = false;
- }
- # Some checks for which tag CSS to use
- if( FlaggedRevs::useSimpleUI() ) $tagClass = 'flaggedrevs_short';
- elseif( $simpleTag ) $tagClass = 'flaggedrevs_notice';
- elseif( $pristine ) $tagClass = 'flaggedrevs_pristine';
- elseif( $quality ) $tagClass = 'flaggedrevs_quality';
- else $tagClass = 'flaggedrevs_basic';
- # Wrap tag contents in a div
- if( $tag !='' ) {
- $tag = "<div id='mw-revisiontag' class='{$tagClass}{$rtl} plainlinks noprint'>$tag</div>";
- $this->reviewNotice .= $tag;
- }
- # Show notice bar/icon
- $this->displayTag();
-
- return true;
- }
-
/**
- * @param $srev stable version
- * @param $tag review box/bar info
- * @param $prot protection notice
- * Tag output function must be called by caller
- * Parser cache control deferred to caller
- */
- protected function showRegularVersion( $srev, &$tag, $prot ) {
- global $wgUser, $wgOut, $wgLang, $wgRequest;
- $flags = $srev->getTags();
- $time = $wgLang->date( $srev->getTimestamp(), true );
- # Get quality level
- $quality = FlaggedRevs::isQuality( $flags );
- $pristine = FlaggedRevs::isPristine( $flags );
- $revsSince = FlaggedRevs::getRevCountSince( $this->parent, $srev->getRevId() );
- # Get stable version sync status
- $synced = FlaggedRevs::stableVersionIsSynced( $srev, $this->parent );
- if( $synced ) {
- $this->getReviewNotes( $srev ); // Still the same
- } else {
- $this->maybeShowTopDiff( $srev, $quality ); // user may want diff (via prefs)
- }
- $pending = '';
- # Give notice to newer users if an unreviewed edit was completed...
- if( !$synced && $wgRequest->getVal('shownotice') && !$wgUser->isAllowed('review') ) {
- $tooltip = wfMsgHtml('revreview-draft-title');
- $pending = "{$prot}<span class='fr-icon-current' title=\"{$tooltip}\"></span>" .
- wfMsgExt('revreview-edited',array('parseinline'),$srev->getRevId(),$revsSince);
- $pending = "<div id='mw-reviewnotice' class='flaggedrevs_preview plainlinks'>$pending</div>";
- # Notice should always use subtitle
- $this->reviewNotice = $pending;
- }
- # If they are synced, do special styling
- $simpleTag = !$synced;
- # Construct some tagging for non-printable outputs. Note that the pending
- # notice has all this info already, so don't do this if we added that already.
- if( !$wgOut->isPrintable() && !$pending && !($this->lowProfileUI() && $synced) ) {
- $class = 'fr-icon-current'; // default
- $tooltip = 'revreview-draft-title';
- // Simple icon-based UI
- if( FlaggedRevs::useSimpleUI() ) {
- if( $synced ) {
- $msg = $quality ? 'revreview-quick-quality-same' : 'revreview-quick-basic-same';
- $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
- $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
- $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince );
- } else {
- $msg = $quality ? 'revreview-quick-see-quality' : 'revreview-quick-see-basic';
- $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince );
- }
- $tooltip = wfMsgHtml($tooltip);
- $msgHTML = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>$msgHTML";
- $tag .= FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML, $revsSince,
- $synced, $synced, false );
- // Standard UI
- } else {
- if( $synced ) {
- $msg = $quality ? 'revreview-quality-same' : 'revreview-basic-same';
- $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
- $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
- $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(),
- $time, $revsSince );
- } else {
- $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic';
- $msg .= ($revsSince == 0) ? '-i' : '';
- $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(),
- $time, $revsSince );
- }
- $tooltip = wfMsgHtml($tooltip);
- $tag .= "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" . $msgHTML;
- # Hide clutter
- if( !empty($flags) ) {
- $tag .= " " . FlaggedRevsXML::ratingToggle();
- $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" .
- wfMsgHtml('revreview-oldrating') . FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
- }
- }
- }
- # Index the stable version only if it is the default
- if( $this->showStableByDefault() ) {
- $wgOut->setRobotPolicy( 'noindex,nofollow' );
- }
- }
-
- /**
- * @param $srev stable version
- * @param $frev selected flagged revision
- * @param $tag review box/bar info
- * @param $prot protection notice
- * Tag output function must be called by caller
- * Parser cache control deferred to caller
- */
- protected function showOldReviewedVersion( $srev, $frev, &$tag, $prot ) {
- global $wgOut, $wgLang;
- $flags = $frev->getTags();
- $time = $wgLang->date( $frev->getTimestamp(), true );
- # Set display revision ID
- $wgOut->setRevisionId( $frev->getRevId() );
- # Get quality level
- $quality = FlaggedRevs::isQuality( $flags );
- $pristine = FlaggedRevs::isPristine( $flags );
- $revsSince = FlaggedRevs::getRevCountSince( $this->parent, $srev->getRevId() );
- $text = $frev->getRevText();
- $parserOut = FlaggedRevs::parseStableText( $this->parent, $text, $frev->getRevId() );
- # Construct some tagging for non-printable outputs. Note that the pending
- # notice has all this info already, so don't do this if we added that already.
- if( !$wgOut->isPrintable() ) {
- $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
- $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
- $tooltip = wfMsgHtml($tooltip);
- // Simple icon-based UI
- if( FlaggedRevs::useSimpleUI() ) {
- $msg = $quality ? 'revreview-quick-quality-old' : 'revreview-quick-basic-old';
- $html = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" .
- wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time );
- $tag = FlaggedRevsXML::prettyRatingBox( $frev, $html, $revsSince,
- true, false, true );
- // Standard UI
- } else {
- $msg = $quality ? 'revreview-quality-old' : 'revreview-basic-old';
- $tag = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" .
- wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time );
- # Hide clutter
- if( !empty($flags) ) {
- $tag .= " " . FlaggedRevsXML::ratingToggle();
- $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" .
- wfMsgHtml('revreview-oldrating') .
- FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
- }
- }
- }
- # Output HTML
- $this->getReviewNotes( $frev );
- $wgOut->addParserOutput( $parserOut );
- # Index the stable version only
- $wgOut->setRobotPolicy( 'noindex,nofollow' );
- }
-
- /**
- * @param $srev stable version
- * @param $tag review box/bar info
- * @param $prot protection notice
- * Tag output function must be called by caller
- * Parser cache control deferred to caller
- */
- protected function showStableVersion( $srev, &$tag, $prot ) {
- global $wgOut, $wgLang, $wgUser;
- $flags = $srev->getTags();
- $time = $wgLang->date( $srev->getTimestamp(), true );
- # Set display revision ID
- $wgOut->setRevisionId( $srev->getRevId() );
- # Get quality level
- $quality = FlaggedRevs::isQuality( $flags );
- $pristine = FlaggedRevs::isPristine( $flags );
- # We will be looking at the reviewed revision...
- $revsSince = FlaggedRevs::getRevCountSince( $this->parent, $srev->getRevId() );
- # Get parsed stable version
- $parserOut = FlaggedRevs::getPageCache( $this->parent, $wgUser );
- if( $parserOut == false ) {
- $text = $srev->getRevText();
- $parserOut = FlaggedRevs::parseStableText( $this->parent, $text, $srev->getRevId() );
- # Update the stable version cache
- FlaggedRevs::updatePageCache( $this->parent, $wgUser, $parserOut );
- }
- $synced = FlaggedRevs::stableVersionIsSynced( $srev, $this->parent, $parserOut, null );
- # Construct some tagging
- if( !$wgOut->isPrintable() && !($this->lowProfileUI() && $synced) ) {
- $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
- $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
- $tooltip = wfMsgHtml($tooltip);
- // Simple icon-based UI
- if( FlaggedRevs::useSimpleUI() ) {
- $msg = $quality ? 'revreview-quick-quality' : 'revreview-quick-basic';
- # uses messages 'revreview-quick-quality-same', 'revreview-quick-basic-same'
- $msg = $synced ? "{$msg}-same" : $msg;
- $html = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" .
- wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince );
- $tag = FlaggedRevsXML::prettyRatingBox( $srev, $html, $revsSince, true, $synced );
- // Standard UI
- } else {
- $msg = $quality ? 'revreview-quality' : 'revreview-basic';
- if( $synced ) {
- # uses messages 'revreview-quality-same', 'revreview-basic-same'
- $msg .= '-same';
- } elseif( $revsSince == 0 ) {
- # uses messages 'revreview-quality-i', 'revreview-basic-i'
- $msg .= '-i';
- }
- $tag = "{$prot}<span class='{$class} plainlinks' title=\"{$tooltip}\"></span>" .
- wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $time, $revsSince );
- if( !empty($flags) ) {
- $tag .= " " . FlaggedRevsXML::ratingToggle();
- $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" .
- FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
- }
- }
- }
- # Output HTML
- $this->getReviewNotes( $srev );
- $wgOut->addParserOutput( $parserOut );
- }
-
- /**
- * @param FlaggedRevision $srev, stable version
- * @param bool $quality, revision is quality
- * @returns bool, diff added to output
- */
- protected function maybeShowTopDiff( $srev, $quality ) {
- global $wgUser, $wgOut, $wgMemc;
- if( !$wgUser->getBoolOption('flaggedrevsviewdiffs') )
- return false; // nothing to do here
- if( !$wgUser->isAllowed('review') )
- return false; // does not apply to this user
- # Diff should only show for the draft
- $oldid = $this->parent->getOldIDFromRequest();
- $latest = $this->parent->getLatest();
- if( $oldid && $oldid != $latest ) {
- return false; // not viewing the draft
- }
- # Conditions are met to show diff...
- wfLoadExtensionMessages( 'FlaggedRevs' ); // load required messages
- $leftNote = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
- $rClass = FlaggedRevsXML::getQualityColor( false );
- $lClass = FlaggedRevsXML::getQualityColor( (int)$quality );
- $rightNote = "<span class='$rClass'>[".wfMsgHtml('revreview-draft-title')."]</span>";
- $leftNote = "<span class='$lClass'>[".wfMsgHtml($leftNote)."]</span>";
- # Fetch the stable and draft revision text
- $oText = $srev->getRevText();
- if( $oText === false )
- return false; // deleted revision or something?
- $nText = $this->parent->getContent();
- if( $nText === false )
- return false; // deleted revision or something?
- # Build diff at the top of the page
- if( strcmp($oText,$nText) !== 0 ) {
- $diffEngine = new DifferenceEngine();
- $diffEngine->showDiffStyle();
- $n = $this->parent->getTitle()->countRevisionsBetween( $srev->getRevId(), $latest );
- if( $n ) {
- $multiNotice = "<tr><td colspan='4' align='center' class='diff-multi'>" .
- wfMsgExt( 'diff-multi', array( 'parse' ), $n )."</td></tr>";
- } else {
- $multiNotice = '';
- }
- $wgOut->addHTML(
- "<div>" .
- "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" .
- "<col class='diff-marker' />" .
- "<col class='diff-content' />" .
- "<col class='diff-marker' />" .
- "<col class='diff-content' />" .
- "<tr>" .
- "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" .
- $leftNote . "</b></td>" .
- "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" .
- $rightNote . "</b></td>" .
- "</tr>" .
- $multiNotice .
- $diffEngine->generateDiffBody( $oText, $nText ) .
- "</table>" .
- "</div>\n"
- );
- $this->isDiffFromStable = true;
- return true;
- }
- return false;
- }
-
- /**
- * Get the normal and display files for the underlying ImagePage.
- * If the a stable version needs to be displayed, this will set $normalFile
- * to the current version, and $displayFile to the desired version.
- *
- * If no stable version is required, the reference parameters will not be set
- *
- * Depends on $wgRequest
- */
- public function imagePageFindFile( &$normalFile, &$displayFile ) {
- global $wgRequest;
- # Determine timestamp. A reviewed version may have explicitly been requested...
- $frev = null;
- $time = false;
- if( $reqId = $wgRequest->getVal('stableid') ) {
- $frev = FlaggedRevision::newFromTitle( $this->parent->getTitle(), $reqId );
- } elseif( $this->pageOverride() ) {
- $frev = $this->getStableRev();
- }
- if( !is_null($frev) ) {
- $time = $frev->getFileTimestamp();
- // B/C, may be stored in associated image version metadata table
- if( !$time ) {
- $dbr = wfGetDB( DB_SLAVE );
- $time = $dbr->selectField( 'flaggedimages',
- 'fi_img_timestamp',
- array( 'fi_rev_id' => $frev->getRevId(),
- 'fi_name' => $this->parent->getTitle()->getDBkey() ),
- __METHOD__ );
- }
- # NOTE: if not found, this will use the current
- $this->parent = new ImagePage( $this->parent->getTitle(), $time );
- }
- if( !$time ) {
- # Try request parameter
- $time = $wgRequest->getVal( 'filetimestamp', false );
- }
-
- if( !$time ) {
- return; // Use the default behaviour
- }
-
- $title = $this->parent->getTitle();
- $displayFile = wfFindFile( $title, array( 'time' => $time ) );
- # If none found, try current
- if( !$displayFile ) {
- wfDebug( __METHOD__.": {$title->getPrefixedDBkey()}: $time not found, using current\n" );
- $displayFile = wfFindFile( $title );
- # If none found, use a valid local placeholder
- if( !$displayFile ) {
- $displayFile = wfLocalFile( $title ); // fallback to current
- }
- $normalFile = $displayFile;
- # If found, set $normalFile
- } else {
- wfDebug( __METHOD__.": {$title->getPrefixedDBkey()}: using timestamp $time\n" );
- $normalFile = wfFindFile( $title );
- }
- }
-
- /**
- * Adds latest stable version tag to page when editing
- */
- public function addToEditView( $editPage ) {
- global $wgRequest, $wgOut;
- # Must be reviewable. UI may be limited to unobtrusive patrolling system.
- if( !$this->isReviewable() || $this->limitedUI() )
- return true;
- # Show stabilization log
- $this->showStabilityLog();
- # Set new body html text as that of now
- $tag = $warning = $prot = '';
- # Check the newest stable version
- $quality = 0;
- if( $frev = $this->getStableRev() ) {
- global $wgLang, $wgUser, $wgFlaggedRevsAutoReview;
- # Find out revision id
- $revId = $editPage->oldid ? $editPage->oldid : $this->parent->getLatest();
- # If this will be autoreviewed, notify the user...
- if( !FlaggedRevs::lowProfileUI() && $wgFlaggedRevsAutoReview && $wgUser->isAllowed('review') ) {
- # If we are editing some reviewed revision, any changes this user
- # makes will be autoreviewed...
- $ofrev = FlaggedRevision::newFromTitle( $this->parent->getTitle(), $revId );
- if( !is_null($ofrev) ) {
- wfLoadExtensionMessages( 'FlaggedRevs' );
- $msg = ( $revId==$frev->getRevId() ) ? 'revreview-auto-w' : 'revreview-auto-w-old';
- $warning = "<div id='mw-autoreviewtag' class='flaggedrevs_warning plainlinks'>" .
- wfMsgExt($msg,array('parseinline')) . "</div>";
- }
- # Let new users know about review procedure a tag
- } elseif( !$wgUser->getId() && $this->showStableByDefault() ) {
- wfLoadExtensionMessages( 'FlaggedRevs' );
- $warning = "<div id='mw-editwarningtag' class='flaggedrevs_editnotice plainlinks'>" .
- wfMsgExt('revreview-editnotice',array('parseinline')) . "</div>";
- }
- if( $frev->getRevId() != $revId ) {
- wfLoadExtensionMessages( 'FlaggedRevs' );
- $time = $wgLang->date( $frev->getTimestamp(), true );
- $flags = $frev->getTags();
- if( FlaggedRevs::isQuality($flags) ) {
- $quality = FlaggedRevs::isPristine($flags) ? 2 : 1;
- }
- $revsSince = FlaggedRevs::getRevCountSince( $this->parent, $frev->getRevId() );
- // Is the page config altered?
- if( $this->isPageLocked() ) {
- $prot = "<span class='fr-icon-locked' title=\"".
- wfMsgHtml('revreview-locked-title')."\"></span>";
- } elseif( $this->isPageUnlocked() ) {
- $prot = "<span class='fr-icon-unlocked' title=\"".
- wfMsgHtml('revreview-unlocked-title')."\"></span>";
- }
- # Streamlined UI
- if( FlaggedRevs::useSimpleUI() ) {
- $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic';
- $msg .= ($revsSince == 0) ? '-i' : '';
- $tag = "{$prot}<span class='fr-checkbox'></span>" .
- wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time, $revsSince );
- $tag = "<div id='mw-revisiontag-edit' class='flaggedrevs_editnotice plainlinks'>$tag</div>";
- # Standard UI
- } else {
- $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic';
- $msg .= ($revsSince == 0) ? '-i' : '';
- $tag = "{$prot}<span class='fr-checkbox'></span>" .
- wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time, $revsSince );
- # Hide clutter
- if( !empty($flags) ) {
- $tag .= " " . FlaggedRevsXML::ratingToggle();
- $tag .= '<span id="mw-revisionratings" style="display:block;"><br/>' .
- wfMsg('revreview-oldrating') . FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
- }
- $tag = "<div id='mw-revisiontag-edit' class='flaggedrevs_editnotice plainlinks'>$tag</div>";
- }
- }
- # Output notice and warning for editors
- if( $tag || $warning ) {
- $wgOut->addHTML( $tag . $warning );
- }
-
- # Show diff to stable, to make things less confusing...
- # This can be disabled via user preferences
- if( $frev->getRevId() != $revId // changes were made
- && ($wgUser->isAllowed('review') || $this->showStableByDefaultUser()) // non-draft default, unless Editor
- && $wgUser->getBoolOption('flaggedrevseditdiffs') // not disable via prefs
- ) {
- # Don't show for old revisions, diff, preview, or undo.
- if( $editPage->oldid || $editPage->section === "new"
- || in_array($editPage->formtype,array('diff','preview')) )
- {
- return true; // nothing to show here
- }
-
- # Conditions are met to show diff...
- wfLoadExtensionMessages( 'FlaggedRevs' ); // load required messages
- $leftNote = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
- $rClass = FlaggedRevsXML::getQualityColor( false );
- $lClass = FlaggedRevsXML::getQualityColor( (int)$quality );
- $rightNote = "<span class='$rClass'>[".wfMsgHtml('revreview-draft-title')."]</span>";
- $leftNote = "<span class='$lClass'>[".wfMsgHtml($leftNote)."]</span>";
- $text = $frev->getRevText();
- # Are we editing a section?
- $section = ($editPage->section == "") ? false : intval($editPage->section);
- if( $section !== false ) {
- $text = $this->parent->getSection( $text, $section );
- }
- if( $text !== false && strcmp($text,$editPage->textbox1) !== 0 ) {
- $diffEngine = new DifferenceEngine();
- $diffEngine->showDiffStyle();
- $wgOut->addHTML(
- "<div>" .
- "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" .
- "<col class='diff-marker' />" .
- "<col class='diff-content' />" .
- "<col class='diff-marker' />" .
- "<col class='diff-content' />" .
- "<tr>" .
- "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" .
- $leftNote . "</b></td>" .
- "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" .
- $rightNote . "</b></td>" .
- "</tr>" .
- $diffEngine->generateDiffBody( $text, $editPage->textbox1 ) .
- "</table>" .
- "</div>\n"
- );
- }
- }
- }
- return true;
- }
-
- protected function showStabilityLog() {
- global $wgOut;
- # Only for pages manually made to be stable...
- if( $this->isPageLocked() ) {
- wfLoadExtensionMessages( 'FlaggedRevs' );
- $wgOut->addHTML( "<div class='mw-warning-with-logexcerpt'>" );
- $wgOut->addWikiMsg( 'revreview-locked' );
- LogEventsList::showLogExtract( $wgOut, 'stable',
- $this->parent->getTitle()->getPrefixedText(), '', array('lim'=>1) );
- $wgOut->addHTML( "</div>" );
- # ...or unstable
- } elseif( $this->isPageUnlocked() ) {
- wfLoadExtensionMessages( 'FlaggedRevs' );
- $wgOut->addHTML( "<div class='mw-warning-with-logexcerpt'>" );
- $wgOut->addWikiMsg( 'revreview-unlocked' );
- LogEventsList::showLogExtract( $wgOut, 'stable',
- $this->parent->getTitle()->getPrefixedText(), '', array('lim'=>1) );
- $wgOut->addHTML( "</div>" );
- }
- return true;
- }
-
- /**
- * Add unreviewed pages links
- */
- public function addToCategoryView() {
- global $wgOut, $wgUser;
- if( !$wgUser->isAllowed( 'review' ) ) {
- return true;
- }
- wfLoadExtensionMessages( 'FlaggedRevs' );
- # Load special page names
- wfLoadExtensionMessages( 'OldReviewedPages' );
- wfLoadExtensionMessages( 'UnreviewedPages' );
-
- $category = $this->parent->getTitle()->getText();
-
- $unreviewed = SpecialPage::getTitleFor( 'UnreviewedPages' );
- $unreviewedLink = $wgUser->getSkin()->makeKnownLinkObj( $unreviewed,
- wfMsgHtml('unreviewedpages'), 'category=' . urlencode($category) );
-
- $oldreviewed = SpecialPage::getTitleFor( 'OldReviewedPages' );
- $oldreviewedLink = $wgUser->getSkin()->makeKnownLinkObj( $oldreviewed,
- wfMsgHtml('oldreviewedpages'), 'category=' . urlencode($category) );
-
- $wgOut->appendSubtitle("<span id='mw-category-oldreviewed'>$unreviewedLink / $oldreviewedLink</span>");
-
- return true;
- }
-
- /**
- * Add review form to pages when necessary
- */
- public function addReviewForm( &$data ) {
- global $wgRequest, $wgUser, $wgOut;
- # User must have review rights and page must be reviewable
- if( !$wgUser->isAllowed('review') || !$this->parent->exists() || !$this->isReviewable() ) {
- return true;
- }
- # Unobtrusive patrolling UI only shows forms if requested
- if( !$wgRequest->getInt('reviewform') && $this->limitedUI() ) {
- return true;
- }
- # Avoid multi-page diffs that are useless and misbehave (bug 19327)
- if( $this->isMultiPageDiff ) {
- return true;
- }
- # Check action and if page is protected
- $action = $wgRequest->getVal( 'action', 'view' );
- # Must be view/diff action...
- if( !self::isViewAction($action) ) {
- return true;
- }
- # Place the form at the top or bottom as most convenient
- $onTop = $wgRequest->getVal('diff') || $this->isDiffFromStable;
- $this->addQuickReview( $data, $onTop, false );
- return true;
- }
-
- /**
- * Add link to stable version setting to protection form
- */
- public function addVisibilityLink( &$data ) {
- global $wgUser, $wgRequest, $wgOut;
- if( FlaggedRevs::getProtectionLevels() )
- return true; // simple custom levels set for action=protect
- # Check only if the title is reviewable
- if( !$this->isReviewable(true) ) {
- return true;
- }
- $action = $wgRequest->getVal( 'action', 'view' );
- if( $action == 'protect' || $action == 'unprotect' ) {
- wfLoadExtensionMessages( 'FlaggedRevs' );
- wfLoadExtensionMessages( 'Stabilization' ); // Load special page name
- $title = SpecialPage::getTitleFor( 'Stabilization' );
- # Give a link to the page to configure the stable version
- $frev = $this->getStableRev();
- if( $frev && $frev->getRevId() == $this->parent->getLatest() ) {
- $wgOut->prependHTML( "<span class='plainlinks'>" .
- wfMsgExt( 'revreview-visibility',array('parseinline'),
- $title->getPrefixedText() ) . "</span>" );
- } elseif( $frev ) {
- $wgOut->prependHTML( "<span class='plainlinks'>" .
- wfMsgExt( 'revreview-visibility2',array('parseinline'),
- $title->getPrefixedText() ) . "</span>" );
- } else {
- $wgOut->prependHTML( "<span class='plainlinks'>" .
- wfMsgExt( 'revreview-visibility3',array('parseinline'),
- $title->getPrefixedText() ) . "</span>" );
- }
- }
- return true;
- }
-
- /**
- * Modify an array of action links, as used by SkinTemplateNavigation and
- * SkinTemplateTabs, to inlude flagged revs UI elements
- */
- public function setActionTabs( $skin, &$actions ) {
- global $wgRequest, $wgUser;
- if( FlaggedRevs::getProtectionLevels() ) {
- return true; // simple custom levels set for action=protect
- }
- $title = $this->parent->getTitle()->getSubjectPage();
- if ( !FlaggedRevs::isPageReviewable( $title ) ) {
- return true; // Only reviewable pages need these tabs
- }
- // Check if we should show a stabilization tab
- if (
- !$skin->mTitle->isTalkPage() &&
- is_array( $actions ) &&
- !isset( $actions['protect'] ) &&
- !isset( $actions['unprotect'] ) &&
- $wgUser->isAllowed( 'stablesettings' ) &&
- $title->exists()
- ) {
- wfLoadExtensionMessages( 'Stabilization' );
- $stableTitle = SpecialPage::getTitleFor( 'Stabilization' );
- // Add a tab
- $actions['default'] = array(
- 'class' => false,
- 'text' => wfMsg( 'stabilization-tab' ),
- 'href' => $stableTitle->getLocalUrl(
- 'page=' . $title->getPrefixedUrl()
- )
- );
- }
- return true;
- }
-
- /**
- * Modify an array of view links, as used by SkinTemplateNavigation and
- * SkinTemplateTabs, to inlude flagged revs UI elements
- */
- public function setViewTabs( $skin, &$views ) {
- global $wgRequest, $wgUser, $wgFlaggedRevTabs;
-
- $title = $this->parent->getTitle()->getSubjectPage(); // Get the actual content page
- $article = new Article( $title );
- $action = $wgRequest->getVal( 'action', 'view' );
- $fa = FlaggedArticle::getTitleInstance( $title );
- if ( !$fa->isReviewable() || $this->limitedUI() ) {
- // This isn't a reviewable page or the UI is hidden
- return true;
- }
- $srev = $this->getStableRev( $action == 'rollback' ? FR_MASTER : 0 );
- if( is_null( $srev ) ) {
- return true; // No stable revision exists
- }
- wfLoadExtensionMessages( 'FlaggedRevs' );
- $synced = FlaggedRevs::stableVersionIsSynced( $srev, $article );
- // Set draft tab as needed...
- if ( !$skin->mTitle->isTalkPage() && !$synced ) {
- if ( isset( $views['edit'] ) ) {
- if ( $this->showStableByDefault() ) {
- $views['edit']['text'] = wfMsg('revreview-edit');
- }
- if ( $this->pageOverride() ) {
- $views['edit']['href'] = $title->getLocalUrl( 'action=edit' );
- }
- }
- if ( isset( $views['viewsource'] ) ) {
- if ( $this->showStableByDefault() ) {
- $views['viewsource']['text'] = wfMsg('revreview-source');
- }
- if ( $this->pageOverride() ) {
- $views['viewsource']['href'] = $title->getLocalUrl( 'action=edit' );
- }
- }
- }
- if ( !$wgFlaggedRevTabs || $synced ) {
- // Exit, since either the stable/draft tabs should not be shown
- // or the page is already the most current revision
- return true;
- }
- $tabs = array(
- 'stable' => array(
- 'text' => wfMsg( 'revreview-stable' ), // unused
- 'href' => $title->getLocalUrl( 'stable=1' ),
- 'class' => ''
- ),
- 'current' => array(
- 'text' => wfMsg( 'revreview-current' ),
- 'href' => $title->getLocalUrl( 'stable=0&redirect=no' ),
- 'class' => ''
- ),
- );
- if ( $this->pageOverride() || $wgRequest->getVal( 'stableid' ) ) {
- // We are looking a the stable version
- $tabs['stable']['class'] = 'selected';
- } elseif (
- ( self::isViewAction( $action ) || $action == 'edit' ) &&
- !$skin->mTitle->isTalkPage()
- ) {
- // We are looking at the current revision or in edit mode
- $tabs['current']['class'] = 'selected';
- }
- $first = true;
- $newViews = array();
- foreach ( $views as $tabAction => $data ) {
- // Very first tab (page link)
- if( $first ) {
- if( $synced ) {
- // Use existing first tabs when synced
- $newViews[$tabAction] = $data;
- } else {
- // Use split current and stable tabs when not synced
- $newViews[$tabAction]['text'] = $data['text']; // keep tab name
- $newViews[$tabAction]['href'] = $tabs['stable']['href'];
- $newViews[$tabAction]['class'] = $tabs['stable']['class'];
- $newViews['current'] = $tabs['current'];
- }
- $first = false;
- } else {
- $newViews[$tabAction] = $data;
- }
- }
- // Replaces old tabs with new tabs
- $views = $newViews;
- return true;
- }
-
- /**
- * @param FlaggedRevision $frev
- * @return string, revision review notes
- */
- public function getReviewNotes( $frev ) {
- global $wgUser;
- if( !FlaggedRevs::allowComments() || !$frev || !$frev->getComment() ) {
- return '';
- }
- wfLoadExtensionMessages( 'FlaggedRevs' );
- $notes = "<br/><div class='flaggedrevs_notes plainlinks'>";
- $notes .= wfMsgExt('revreview-note', array('parseinline'), User::whoIs( $frev->getUser() ) );
- $notes .= '<br/><i>' . $wgUser->getSkin()->formatComment( $frev->getComment() ) . '</i></div>';
- $this->reviewNotes = $notes;
- }
-
- /**
- * When comparing the stable revision to the current after editing a page, show
- * a tag with some explaination for the diff.
- */
- public function addDiffNoticeAndIncludes( $diff, $oldRev, $newRev ) {
- global $wgRequest, $wgUser, $wgOut, $wgMemc;
- # Page must be reviewable. Exempt printer-friendly output.
- # UI may be limited to unobtrusive patrolling system
- if( $wgOut->isPrintable() || !$this->isReviewable() || $this->limitedUI() )
- return true;
- # Load required messages
- wfLoadExtensionMessages( 'FlaggedRevs' );
- # Check if this might be the diff to stable. If so, enhance it.
- if( $newRev->isCurrent() && $oldRev ) {
- $article = new Article( $newRev->getTitle() );
- # Try the sync value cache...
- $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $article->getId() );
- $value = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article );
- $synced = ($value === "true") ? true : false; // default as false to trigger query
- $frev = $this->getStableRev();
- if( $frev && $frev->getRevId() == $oldRev->getID() ) {
- global $wgParserCacheExpireTime;
-
- $changeList = array();
- $skin = $wgUser->getSkin();
-
- # Try the cache. Uses format <page ID>-<UNIX timestamp>.
- $key = wfMemcKey( 'stableDiffs', 'templates', $article->getId() );
- $tmpChanges = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article );
- if( empty($tmpChanges) && !$synced ) {
- $tmpChanges = false; // don't use cache
- }
-
- # Make a list of each changed template...
- if( $tmpChanges === false ) {
- $dbr = wfGetDB( DB_SLAVE );
- // Get templates where the current and stable are not the same revision
- $ret = $dbr->select( array('flaggedtemplates','page','flaggedpages'),
- array( 'ft_namespace', 'ft_title', 'fp_stable','ft_tmp_rev_id', 'page_latest' ),
- array( 'ft_rev_id' => $frev->getRevId(),
- 'page_namespace = ft_namespace',
- 'page_title = ft_title' ),
- __METHOD__,
- array(), /* OPTIONS */
- array( 'flaggedpages' => array('LEFT JOIN','fp_page_id = page_id') )
- );
- $tmpChanges = array();
- while( $row = $dbr->fetchObject( $ret ) ) {
- $title = Title::makeTitleSafe( $row->ft_namespace, $row->ft_title );
- $revIdDraft = $row->page_latest;
- // stable time -> time when reviewed (unless the other is newer)
- $revIdStable = isset($row->fp_stable) && $row->fp_stable >= $row->ft_tmp_rev_id ?
- $row->fp_stable : $row->ft_tmp_rev_id;
- // compare to current
- if( $revIdDraft > $revIdStable ) {
- $tmpChanges[] = $skin->makeKnownLinkObj( $title, $title->getPrefixedText(),
- "diff=cur&oldid={$revIdStable}" );
- }
- }
- $wgMemc->set( $key, FlaggedRevs::makeMemcObj($tmpChanges), $wgParserCacheExpireTime );
- }
- # Add set to list
- if( $tmpChanges )
- $changeList += $tmpChanges;
-
- # Try the cache. Uses format <page ID>-<UNIX timestamp>.
- $key = wfMemcKey( 'stableDiffs', 'images', $article->getId() );
- $imgChanges = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article );
- if( empty($imgChanges) && !$synced ) {
- $imgChanges = false; // don't use cache
- }
-
- // Get list of each changed image...
- if( $imgChanges === false ) {
- $dbr = wfGetDB( DB_SLAVE );
- // Get images where the current and stable are not the same revision
- $ret = $dbr->select( array('flaggedimages','page','image','flaggedpages','flaggedrevs'),
- array( 'fi_name', 'fi_img_timestamp', 'fr_img_timestamp' ),
- array( 'fi_rev_id' => $frev->getRevId() ),
- __METHOD__,
- array(), /* OPTIONS */
- array( 'page' => array('LEFT JOIN','page_namespace = '. NS_FILE .' AND page_title = fi_name'),
- 'image' => array('LEFT JOIN','img_name = fi_name'),
- 'flaggedpages' => array('LEFT JOIN','fp_page_id = page_id'),
- 'flaggedrevs' => array('LEFT JOIN','fr_page_id = fp_page_id AND fr_rev_id = fp_stable') )
- );
- $imgChanges = array();
- while( $row = $dbr->fetchObject( $ret ) ) {
- $title = Title::makeTitleSafe( NS_FILE, $row->fi_name );
- // stable time -> time when reviewed (unless the other is newer)
- $timestamp = isset($row->fr_img_timestamp) && $row->fr_img_timestamp >= $row->fi_img_timestamp ?
- $row->fr_img_timestamp : $row->fi_img_timestamp;
- // compare to current
- $file = wfFindFile( $title );
- if( $file && $file->getTimestamp() > $timestamp )
- $imgChanges[] = $skin->makeKnownLinkObj( $title, $title->getPrefixedText() );
- }
- $wgMemc->set( $key, FlaggedRevs::makeMemcObj($imgChanges), $wgParserCacheExpireTime );
- }
- if( $imgChanges )
- $changeList += $imgChanges;
-
- # Some important information...
- $notice = '';
- if( count($changeList) > 0 ) {
- $notice = '<br/>' . wfMsgExt('revreview-update-use', array('parseinline'));
- } elseif( !$synced ) {
- $diff->mTitle->invalidateCache(); // bad cache, said they were not synced
- }
-
- # If the user is allowed to review, prompt them!
- if( empty($changeList) && $wgUser->isAllowed('review') ) {
- $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" .
- wfMsgExt('revreview-update-none', array('parseinline')).$notice.'</div>' );
- } elseif( !empty($changeList) && $wgUser->isAllowed('review') ) {
- $changeList = implode(', ',$changeList);
- $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" .
- wfMsgExt('revreview-update', array('parseinline')).'&nbsp;'.
- $changeList.$notice.'</div>' );
- } elseif( !empty($changeList) ) {
- $changeList = implode(', ',$changeList);
- $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" .
- wfMsgExt('revreview-update-includes', array('parseinline')).'&nbsp;'.
- $changeList.$notice.'</div>' );
- }
- # Set flag for review form to tell it to autoselect tag settings from the
- # old revision unless the current one is tagged to.
- if( !FlaggedRevision::newFromTitle( $diff->mTitle, $newRev->getID() ) ) {
- $this->isDiffFromStable = true;
- }
-
- # Set a key to note that someone is viewing this
- if( $wgUser->isAllowed('review') ) {
- $key = wfMemcKey( 'stableDiffs', 'underReview', $oldRev->getID(), $newRev->getID() );
- $wgMemc->set( $key, '1', 10*60 ); // 10 min
- }
- }
- }
- $newRevQ = FlaggedRevs::getRevQuality( $newRev->getPage(), $newRev->getId() );
- $oldRevQ = $oldRev ? FlaggedRevs::getRevQuality( $newRev->getPage(), $oldRev->getId() ) : false;
- # Diff between two revisions
- if( $oldRev ) {
- $wgOut->addHTML( "<table class='fr-diff-ratings'><tr>" );
-
- $class = FlaggedRevsXML::getQualityColor( $oldRevQ );
- if( $oldRevQ !== false ) {
- $msg = $oldRevQ ? 'hist-quality' : 'hist-stable';
- } else {
- $msg = 'hist-draft';
- }
- $wgOut->addHTML( "<td width='50%' align='center'>" );
- $wgOut->addHTML( "<span class='$class'><b>[" . wfMsgHtml( $msg ) . "]</b></span>" );
-
- $class = FlaggedRevsXML::getQualityColor( $newRevQ );
- if( $newRevQ !== false ) {
- $msg = $newRevQ ? 'hist-quality' : 'hist-stable';
- } else {
- $msg = 'hist-draft';
- }
- $wgOut->addHTML( "</td><td width='50%' align='center'>" );
- $wgOut->addHTML( "<span class='$class'><b>[" . wfMsgHtml( $msg ) . "]</b></span>" );
-
- $wgOut->addHTML( '</td></tr></table>' );
- # New page "diffs" - just one rev
- } else {
- if( $newRevQ !== false ) {
- $msg = $newRevQ ? 'hist-quality' : 'hist-stable';
- } else {
- $msg = 'hist-draft';
- }
- $wgOut->addHTML( "<table class='fr-diff-ratings'><tr><td class='fr-$msg' align='center'>" );
- $wgOut->addHTML( "<b>[" . wfMsgHtml( $msg ) . "]</b>" );
- $wgOut->addHTML( '</td></tr></table>' );
- }
- return true;
- }
-
- /**
- * Set $this->isDiffFromStable and $this->isMultiPageDiff fields
- */
- public function setViewFlags( $diff, $oldRev, $newRev ) {
- if( $newRev && $oldRev ) {
- // Is this a diff between two pages?
- if( $newRev->getPage() != $oldRev->getPage() ) {
- $this->isMultiPageDiff = true;
- // Is there a stable version?
- } else if( $this->isReviewable() ) {
- $frev = $this->getStableRev();
- // Is this a diff of the draft rev against the stable rev?
- if( $frev && $frev->getRevId() == $oldRev->getId() && $newRev->isCurrent() ) {
- $this->isDiffFromStable = true;
- }
- }
- }
- return true;
- }
-
- /**
- * Add a link to patrol non-reviewable pages.
- * Also add a diff-to-stable for other pages if possible.
- */
- public function addDiffLink( $diff, $oldRev, $newRev ) {
- global $wgUser, $wgOut;
- // Is there a stable version?
- if( $newRev && $oldRev && $this->isReviewable() ) {
- $frev = $this->getStableRev();
- # Give a link to the diff-to-stable if needed
- if( $frev && !$this->isDiffFromStable ) {
- $article = new Article( $newRev->getTitle() );
- # Is the stable revision using the same revision as the current?
- if( $article->getLatest() != $frev->getRevId() ) {
- wfLoadExtensionMessages( 'FlaggedRevs' );
- $patrol = '(' . $wgUser->getSkin()->makeKnownLinkObj( $newRev->getTitle(),
- wfMsgHtml( 'review-diff2stable' ), "oldid={$frev->getRevId()}&diff=cur&diffonly=0" ) . ')';
- $wgOut->addHTML( "<div class='fr-diff-to-stable' align='center'>$patrol</div>" );
- }
- }
- }
- return true;
- }
-
- /**
- * Redirect users out to review the changes to the stable version.
- * Only for people who can review and for pages that have a stable version.
- */
- public function injectReviewDiffURLParams( &$sectionAnchor, &$extraQuery ) {
- global $wgUser, $wgReviewChangesAfterEdit;
- # Don't show this for pages that are not reviewable
- if( !$this->isReviewable() || $this->parent->getTitle()->isTalkPage() )
- return true;
- # We may want to skip some UI elements
- if( $this->limitedUI() ) return true;
- # Get the stable version, from master
- $frev = $this->getStableRev( FR_MASTER );
- if( !$frev )
- return true;
- $latest = $this->parent->getTitle()->getLatestRevID(GAID_FOR_UPDATE);
- // If we are supposed to review after edit, and it was not autoreviewed,
- // and the user can actually make new stable version, take us to the diff...
- if( $wgReviewChangesAfterEdit && $frev && $latest > $frev->getRevId() && $frev->userCanSetFlags() ) {
- $extraQuery .= $extraQuery ? '&' : '';
- $extraQuery .= "oldid={$frev->getRevId()}&diff=cur&diffonly=0"; // override diff-only
- // ...otherwise, go to the current revision after completing an edit.
- } else {
- if( $frev && $latest != $frev->getRevId() ) {
- $extraQuery .= "stable=0";
- if( !$wgUser->isAllowed('review') && $this->showStableByDefault() ) {
- $extraQuery .= "&shownotice=1";
- }
- }
- }
- return true;
- }
-
- /**
- * Add a hidden revision ID field to edit form.
- * Needed for autoreview so it can select the flags from said revision.
- */
- public function addRevisionIDField( $editPage, $out ) {
- global $wgRequest;
- # Find out revision id
- if( $this->parent->mRevision ) {
- $revId = $this->parent->mRevision->mId;
- } else {
- $latest = $this->parent->getTitle()->getLatestRevID(GAID_FOR_UPDATE);
- $revId = $latest;
- wfDebug( 'FlaggedArticle::addRevisionIDField - ID not specified, assumed current' );
- }
- # If undoing a few consecutive top edits, we know the base ID
- if( $undo = $wgRequest->getIntOrNull('undo') ) {
- $undoAfter = $wgRequest->getIntOrNull('undoafter');
- $latest = isset($latest) ? $latest : $this->parent->getTitle()->getLatestRevID(GAID_FOR_UPDATE);
- if( $undoAfter && $undo == $this->parent->getLatest() ) {
- $revId = $undoAfter;
- }
- }
- $out->addHTML( "\n" . Xml::hidden( 'baseRevId', $revId ) );
- $out->addHTML( "\n" . Xml::hidden( 'undidRev',
- empty($editPage->undidRev) ? 0 : $editPage->undidRev )
- );
- return true;
- }
-
- /**
* Get latest quality rev, if not, the latest reviewed one
* @param int $flags
* @return Row
*/
- public function getStableRev( $flags=0 ) {
+ public function getStableRev( $flags = 0 ) {
if( $this->stableRev === false ) {
return null; // We already looked and found nothing...
}
@@ -1372,7 +140,7 @@
return $this->stableRev;
}
# Get the content page, skip talk
- $title = $this->parent->getTitle()->getSubjectPage();
+ $title = $this->getTitle()->getSubjectPage();
# Do we have one?
$srev = FlaggedRevision::newFromStable( $title, $flags );
if( $srev ) {
@@ -1396,7 +164,7 @@
return $this->pageConfig;
}
# Get the content page, skip talk
- $title = $this->parent->getTitle()->getSubjectPage();
+ $title = $this->getTitle()->getSubjectPage();
$config = FlaggedRevs::getPageVisibilitySettings( $title, $forUpdate );
$this->pageConfig = $config;
return $config;
@@ -1412,225 +180,13 @@
return $this->flags[$revId];
}
# Get the flags
- $flags = FlaggedRevs::getRevisionTags( $this->parent->getTitle(), $revId );
+ $flags = FlaggedRevs::getRevisionTags( $this->getTitle(), $revId );
+ # Don't let cache get too big
+ if( count($this->flags) >= self::CACHE_MAX ) {
+ $this->flags = array();
+ }
# Try to cache results
$this->flags[$revId] = $flags;
-
return $flags;
}
-
- /**
- * Adds brief review notes to a page.
- * @param OutputPage $out
- */
- public function addReviewNotes( &$data ) {
- if( $this->reviewNotes ) {
- $data .= $this->reviewNotes;
- }
- return true;
- }
-
- /**
- * Adds a brief review form to a page.
- * @param string $data
- * @param bool $top
- * @param bool hide
- * @param bool $top, should this form always go on top?
- */
- public function addQuickReview( &$data, $top = false, $hide = false ) {
- global $wgOut, $wgUser, $wgRequest;
- # Get the revision being displayed
- $id = $wgOut->getRevisionId();
- if( !$id ) {
- if( !$this->isDiffFromStable ) {
- return false; // only safe to assume current if diff-to-stable
- } else {
- $rev = Revision::newFromTitle( $this->parent->getTitle() );
- $id = $rev->getId();
- }
- } else {
- $rev = Revision::newFromTitle( $this->parent->getTitle(), $id );
- }
- # Load required messages
- wfLoadExtensionMessages( 'FlaggedRevs' );
- # Must be a valid non-printable output and revision must be public
- if( $wgOut->isPrintable() || !$rev || $rev->isDeleted(Revision::DELETED_TEXT) ) {
- return false;
- }
- $useCurrent = false;
- if( !isset($wgOut->mTemplateIds) || !isset($wgOut->fr_ImageSHA1Keys) ) {
- $useCurrent = true;
- }
- $skin = $wgUser->getSkin();
-
- $config = $this->getVisibilitySettings();
- # Variable for sites with no flags, otherwise discarded
- $approve = $wgRequest->getBool('wpApprove');
- # See if the version being displayed is flagged...
- $oldFlags = $this->getFlagsForRevision( $id );
- # If we are reviewing updates to a page, start off with the stable revision's
- # flags. Otherwise, we just fill them in with the selected revision's flags.
- if( $this->isDiffFromStable ) {
- $srev = $this->getStableRev();
- $flags = $srev->getTags();
- # Check if user is allowed to renew the stable version.
- # If not, then get the flags for the new revision itself.
- if( !RevisionReview::userCanSetFlags( $oldFlags ) ) {
- $flags = $oldFlags;
- }
- $encNotes = $srev->getComment();
- } else {
- $frev = FlaggedRevision::newFromTitle( $this->parent->getTitle(), $id );
- $flags = $oldFlags;
- $encNotes = $frev ? $frev->getComment() : ""; // pre-fill notes
- }
-
- $reviewTitle = SpecialPage::getTitleFor( 'RevisionReview' );
- $action = $reviewTitle->getLocalUrl( 'action=submit' );
- $params = array( 'method' => 'post', 'action' => $action, 'id' => 'mw-reviewform' );
- if( $hide ) {
- $params['class'] = 'fr-hiddenform';
- }
- $form = Xml::openElement( 'form', $params );
- $form .= Xml::openElement( 'fieldset', array('class' => 'flaggedrevs_reviewform noprint') );
- $form .= "<legend><strong>" . wfMsgHtml( 'revreview-flag', $id ) . "</strong></legend>\n";
-
- # Show explanatory text
- if( !FlaggedRevs::lowProfileUI() ) {
- $msg = FlaggedRevs::showStableByDefault() ? 'revreview-text' : 'revreview-text2';
- $form .= wfMsgExt( $msg, array('parse') );
- }
-
- # Current user has too few rights to change at least one flag, thus entire form disabled
- $uneditable = !$this->parent->getTitle()->quickUserCan('edit');
- $disabled = !RevisionReview::userCanSetFlags( $flags ) || $uneditable;
- if( $disabled ) {
- $form .= Xml::openElement( 'div', array('class' => 'fr-rating-controls-disabled',
- 'id' => 'fr-rating-controls-disabled') );
- $toggle = array( 'disabled' => "disabled" );
- } else {
- $form .= Xml::openElement( 'div', array('class' => 'fr-rating-controls',
- 'id' => 'fr-rating-controls') );
- $toggle = array();
- }
- # Add main checkboxes/selects
- $form .= Xml::openElement( 'span', array('id' => 'mw-ratingselects') );
- $form .= FlaggedRevsXML::ratingInputs( $flags, $config, $disabled );
- $form .= Xml::closeElement( 'span' );
-
- if( FlaggedRevs::allowComments() && $wgUser->isAllowed( 'validate' ) ) {
- $form .= "<div id='mw-notebox'>\n";
- $form .= "<p>".wfMsgHtml( 'revreview-notes' ) . "</p>\n";
- $form .= Xml::openElement( 'textarea', array('name' => 'wpNotes', 'id' => 'wpNotes',
- 'class' => 'fr-notes-box', 'rows' => '2', 'cols' => '80') ) .
- htmlspecialchars( $encNotes ) .
- Xml::closeElement('textarea') . "\n";
- $form .= "</div>\n";
- }
- # Get versions of templates/files used
- $imageParams = $templateParams = $fileVersion = '';
- if( $useCurrent ) {
- # Get parsed current version
- $parserCache = ParserCache::singleton();
- $article = $this->parent;
- $currentOutput = $parserCache->get( $article, $wgUser );
- if( $currentOutput == false ) {
- global $wgParser, $wgEnableParserCache;
- $text = $article->getContent();
- $title = $article->getTitle();
- $options = FlaggedRevs::makeParserOptions();
- $currentOutput = $wgParser->parse( $text, $title, $options );
- # Might as well save the cache while we're at it
- if( $wgEnableParserCache )
- $parserCache->save( $currentOutput, $article, $wgUser );
- }
- $templateIDs = $currentOutput->mTemplateIds;
- $imageSHA1Keys = $currentOutput->fr_ImageSHA1Keys;
- } else {
- $templateIDs = $wgOut->mTemplateIds;
- $imageSHA1Keys = $wgOut->fr_ImageSHA1Keys;
- }
- list($templateParams,$imageParams,$fileVersion) =
- FlaggedRevs::getIncludeParams( $this->parent, $templateIDs, $imageSHA1Keys );
-
- $form .= Xml::openElement( 'span', array('style' => 'white-space: nowrap;') );
- # Hide comment if needed
- if( !$disabled ) {
- if( count(FlaggedRevs::getDimensions()) > 1 )
- $form .= "<br/>"; // Don't put too much on one line
- $form .= "<span id='mw-commentbox' style='clear:both'>" .
- Xml::inputLabel( wfMsg('revreview-log'), 'wpReason', 'wpReason', 40, '',
- array('class' => 'fr-comment-box') ) . "&nbsp;&nbsp;&nbsp;</span>";
- }
- $form .= Xml::submitButton( wfMsg('revreview-submit'),
- array(
- 'id' => 'submitreview', 'accesskey' => wfMsg('revreview-ak-review'),
- 'title' => wfMsg('revreview-tt-review').' ['.wfMsg('revreview-ak-review').']'
- ) + $toggle
- );
- $form .= Xml::closeElement( 'span' );
-
- $form .= Xml::closeElement( 'div' ) . "\n";
-
- # Show stability log if there is anything interesting...
- if( $this->isPageLocked() ) {
- $loglist = new LogEventsList( $wgUser->getSkin(), $wgOut, LogEventsList::NO_ACTION_LINK );
- $pager = new LogPager( $loglist, 'stable', '', $this->parent->getTitle()->getPrefixedDBKey() );
- $pager->mLimit = 1; // top item
- if( ($logBody = $pager->getBody()) ) {
- $form .= "<div><ul style='list-style:none; margin: 0;'>$logBody</ul></div>";
- }
- }
-
- # Hidden params
- $form .= Xml::hidden( 'title', $reviewTitle->getPrefixedText() ) . "\n";
- $form .= Xml::hidden( 'target', $this->parent->getTitle()->getPrefixedDBKey() ) . "\n";
- $form .= Xml::hidden( 'oldid', $id ) . "\n";
- $form .= Xml::hidden( 'action', 'submit') . "\n";
- $form .= Xml::hidden( 'wpEditToken', $wgUser->editToken() ) . "\n";
- # Add review parameters
- $form .= Xml::hidden( 'templateParams', $templateParams ) . "\n";
- $form .= Xml::hidden( 'imageParams', $imageParams ) . "\n";
- $form .= Xml::hidden( 'fileVersion', $fileVersion ) . "\n";
- # Pass this in if given; useful for new page patrol
- $form .= Xml::hidden( 'rcid', $wgRequest->getVal('rcid') ) . "\n";
- # Special token to discourage fiddling...
- $checkCode = RevisionReview::validationKey( $templateParams, $imageParams, $fileVersion, $id );
- $form .= Xml::hidden( 'validatedParams', $checkCode ) . "\n";
-
- $form .= Xml::closeElement( 'fieldset' );
- $form .= Xml::closeElement( 'form' );
-
- if( $top ) {
- $wgOut->prependHTML( $form );
- } else {
- $data .= $form;
- }
- return true;
- }
-
- /**
- * Updates parser cache output to included needed versioning params.
- */
- public function maybeUpdateMainCache( &$outputDone, &$pcache ) {
- global $wgUser, $wgRequest;
-
- $action = $wgRequest->getVal( 'action', 'view' );
- if( $action == 'purge' ) return true; // already purging!
- # Only trigger on article view for content pages, not for protect/delete/hist
- if( !self::isViewAction($action) || !$wgUser->isAllowed( 'review' ) )
- return true;
- if( !$this->parent->exists() || !$this->isReviewable() )
- return true;
-
- $parserCache = ParserCache::singleton();
- $parserOut = $parserCache->get( $this->parent, $wgUser );
- if( $parserOut ) {
- # Clear older, incomplete, cached versions
- # We need the IDs of templates and timestamps of images used
- if( !isset($parserOut->fr_newestTemplateID) || !isset($parserOut->fr_newestImageTime) )
- $this->parent->getTitle()->invalidateCache();
- }
- return true;
- }
}

Added: trunk/extensions/FlaggedRevs/FlaggedArticleView.php
===================================================================
--- trunk/extensions/FlaggedRevs/FlaggedArticleView.php (rev 0)
+++ trunk/extensions/FlaggedRevs/FlaggedArticleView.php 2009-11-04 20:23:24 UTC (rev 58564)
@@ -0,0 +1,1524 @@
+<?php
+
+class FlaggedArticleView {
+ protected $isDiffFromStable = false;
+ protected $isMultiPageDiff = false;
+ protected $reviewNotice = '';
+ protected $reviewNotes = '';
+ protected $article = null;
+ protected $loaded = false;
+
+ protected static $instance = null;
+
+ /*
+ * Get the FlaggedArticleView for this request
+ */
+ public static function singleton() {
+ if( self::$instance == null ) {
+ self::$instance = new FlaggedArticleView();
+ }
+ return self::$instance;
+ }
+ protected function __construct() {}
+
+ /*
+ * Load the global FlaggedArticle instance
+ */
+ protected function load() {
+ if( !$this->loaded ) {
+ $this->article = self::globalArticleInstance();
+ if( $this->article == null ) {
+ throw new MWException( 'FlaggedArticleViewer has no context article!' );
+ }
+ }
+ }
+
+ /**
+ * Get the FlaggedArticle instance associated with $wgArticle/$wgTitle,
+ * or false if there isn't such a title
+ */
+ public static function globalArticleInstance() {
+ global $wgArticle, $wgTitle;
+ if( !empty( $wgArticle ) ) {
+ return FlaggedArticle::getInstance( $wgArticle );
+ } elseif( !empty( $wgTitle ) ) {
+ return FlaggedArticle::getTitleInstance( $wgTitle );
+ }
+ return null;
+ }
+
+ /**
+ * Does the config and current URL params allow
+ * for overriding by stable revisions?
+ */
+ public function pageOverride() {
+ global $wgUser, $wgRequest;
+ $this->load();
+ # This only applies to viewing content pages
+ $action = $wgRequest->getVal( 'action', 'view' );
+ if( !self::isViewAction($action) || !$this->article->isReviewable() )
+ return false;
+ # Does not apply to diffs/old revision...
+ if( $wgRequest->getVal('oldid') || $wgRequest->getVal('diff') )
+ return false;
+ # Explicit requests for a certain stable version handled elsewhere...
+ if( $wgRequest->getVal('stableid') )
+ return false;
+ # Check user preferences
+ if( $wgUser->getOption('flaggedrevsstable') )
+ return !( $wgRequest->getIntOrNull('stable') === 0 );
+ # Get page configuration
+ $config = $this->article->getVisibilitySettings();
+ # Does the stable version override the current one?
+ if( $config['override'] ) {
+ if( FlaggedRevs::ignoreDefaultVersion() ) {
+ return ( $wgRequest->getIntOrNull('stable') === 1 );
+ }
+ # Viewer sees stable by default
+ return !( $wgRequest->getIntOrNull('stable') === 0 );
+ # We are explicity requesting the stable version?
+ } elseif( $wgRequest->getIntOrNull('stable') === 1 ) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Is this user shown the stable version by default for this page?
+ * @returns bool
+ */
+ public function showStableByDefaultUser() {
+ $this->load();
+ $config = $this->article->getVisibilitySettings(); // page configuration
+ return ( $config['override'] && !FlaggedRevs::ignoreDefaultVersion() );
+ }
+
+ /**
+ * Is this user shown the diff-to-stable on edit for this page?
+ * @returns bool
+ */
+ public function showDiffOnEditUser() {
+ global $wgUser;
+ $this->load();
+ return ( $wgUser->isAllowed('review') || $this->showStableByDefaultUser() );
+ }
+
+ /**
+ * Is this a view page action?
+ * @param $action string
+ * @returns bool
+ */
+ protected static function isViewAction( $action ) {
+ return ( $action == 'view' || $action == 'purge' || $action == 'render' || $action == 'historysubmit' );
+ }
+
+ /**
+ * Output review notice
+ */
+ protected function displayTag() {
+ global $wgOut, $wgRequest;
+ $this->load();
+ // UI may be limited to unobtrusive patrolling system
+ if( $wgRequest->getVal('stableid') || !$this->article->limitedUI() ) {
+ $wgOut->appendSubtitle( $this->reviewNotice );
+ }
+ return true;
+ }
+
+
+ /**
+ * Add a stable link when viewing old versions of an article that
+ * have been reviewed. (e.g. for &oldid=x urls)
+ */
+ public function addStableLink() {
+ global $wgRequest, $wgOut, $wgLang;
+ $this->load();
+ # Only for viewing old versions. UI may be limited to unobtrusive patrolling system.
+ if( !$wgRequest->getVal('oldid') || $this->article->limitedUI() )
+ return true;
+ # We may have nav links like "direction=prev&oldid=x"
+ $revID = $this->article->getOldIDFromRequest();
+ $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $revID );
+ # Give a notice if this rev ID corresponds to a reviewed version...
+ if( !is_null($frev) ) {
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ $time = $wgLang->date( $frev->getTimestamp(), true );
+ $flags = $frev->getTags();
+ $quality = FlaggedRevs::isQuality( $flags );
+ $msg = $quality ? 'revreview-quality-source' : 'revreview-basic-source';
+ $tag = wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time );
+ # Hide clutter
+ if( !FlaggedRevs::useSimpleUI() && !empty($flags) ) {
+ $tag .= " " . FlaggedRevsXML::ratingToggle() .
+ "<span id='mw-revisionratings' style='display:block;'><br/>" .
+ wfMsgHtml('revreview-oldrating') .
+ FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
+ }
+ $tag = "<div id='mw-revisiontag-old' class='flaggedrevs_notice plainlinks noprint'>$tag</div>";
+ $wgOut->addHTML( $tag );
+ }
+ return true;
+ }
+
+ /**
+ * Replaces a page with the last stable version if possible
+ * Adds stable version status/info tags and notes
+ * Adds a quick review form on the bottom if needed
+ */
+ public function setPageContent( &$outputDone, &$pcache ) {
+ global $wgRequest, $wgOut, $wgUser, $wgLang, $wgContLang;
+ $this->load();
+ # Only trigger on article view for content pages, not for protect/delete/hist...
+ $action = $wgRequest->getVal( 'action', 'view' );
+ if( !self::isViewAction($action) || !$this->article->exists() )
+ return true;
+ # Do not clutter up diffs any further and leave archived versions alone...
+ if( $wgRequest->getVal('diff') || $wgRequest->getVal('oldid') ) {
+ return true;
+ }
+ # Only trigger for reviewable pages
+ if( !$this->article->isReviewable() ) {
+ return true;
+ }
+ # Load required messages
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ $simpleTag = $old = $stable = false;
+ $tag = $prot = '';
+ # Check the newest stable version.
+ $frev = $srev = $this->article->getStableRev();
+ $stableId = $frev ? $frev->getRevId() : 0;
+ # Also, check for any explicitly requested old stable version...
+ $reqId = $wgRequest->getVal('stableid');
+ if( $reqId === "best" ) {
+ $reqId = FlaggedRevs::getPrimeFlaggedRevId( $this->article );
+ }
+ if( $stableId && $reqId ) {
+ # Treat requesting the stable version by ID as &stable=1
+ if( $reqId != $stableId ) {
+ $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId, FR_TEXT );
+ $old = true; // old reviewed version requested by ID
+ if( !$frev ) {
+ $wgOut->addWikiText( wfMsg('revreview-invalid') );
+ $wgOut->returnToMain( false, $this->article->getTitle() );
+ # Tell MW that parser output is done
+ $outputDone = true;
+ $pcache = false;
+ return true;
+ }
+ } else {
+ $stable = true; // stable version requested by ID
+ }
+ }
+ // Is the page config altered?
+ if( $this->article->isPageLocked() ) {
+ $prot = "<span class='fr-icon-locked' title=\"".
+ wfMsgHtml('revreview-locked-title')."\"></span>";
+ } elseif( $this->article->isPageUnlocked() ) {
+ $prot = "<span class='fr-icon-unlocked' title=\"".
+ wfMsgHtml('revreview-unlocked-title')."\"></span>";
+ }
+ // RTL langauges
+ $rtl = $wgContLang->isRTL() ? " rtl" : "";
+ // Is there no stable version?
+ if( is_null($frev) ) {
+ // Add "no reviewed version" tag, but not for printable output.
+ if( !$wgOut->isPrintable() ) {
+ // Simple icon-based UI
+ if( FlaggedRevs::useSimpleUI() ) {
+ $msg = $old ? 'revreview-quick-invalid' : 'revreview-quick-none';
+ $tag .= "{$prot}<span class='fr-icon-current plainlinks'></span>" .
+ wfMsgExt($msg,array('parseinline'));
+ $tag = "<div id='mw-revisiontag' class='flaggedrevs_short{$rtl} plainlinks noprint'>$tag</div>";
+ $this->reviewNotice .= $tag;
+ // Standard UI
+ } else {
+ $msg = $old ? 'revreview-invalid' : 'revreview-noflagged';
+ $tag = "<div id='mw-revisiontag' class='flaggedrevs_notice plainlinks noprint'>" .
+ "{$prot}<span class='fr-icon-current plainlinks'></span>" .
+ wfMsgExt($msg, array('parseinline')) . "</div>";
+ $this->reviewNotice .= $tag;
+ }
+ }
+ # Show notice bar/icon
+ $this->displayTag();
+ return true;
+ }
+ # Get flags and date
+ $time = $wgLang->date( $frev->getTimestamp(), true );
+ $flags = $frev->getTags();
+ # Get quality level
+ $quality = FlaggedRevs::isQuality( $flags );
+ $pristine = FlaggedRevs::isPristine( $flags );
+ // Looking at some specific old stable revision ("&stableid=x")
+ // set to override given the relevant conditions. If the user is
+ // requesting the stable revision ("&stableid=x"), defer to override
+ // behavior below, since it is the same as ("&stable=1").
+ if( $old ) {
+ $this->showOldReviewedVersion( $srev, $frev, $tag, $prot );
+ $outputDone = true; # Tell MW that parser output is done
+ $pcache = false;
+ // Looking at some specific old revision (&oldid=x) or if FlaggedRevs is not
+ // set to override given the relevant conditions (like &stable=0).
+ } elseif( !$stable && !$this->pageOverride() ) {
+ $this->showRegularVersion( $srev, $tag, $prot );
+ // The relevant conditions are met to override the page with the stable version.
+ } else {
+ $this->showStableVersion( $srev, $tag, $prot );
+ $outputDone = true; # Tell MW that parser output is done
+ $pcache = false;
+ }
+ # Some checks for which tag CSS to use
+ if( FlaggedRevs::useSimpleUI() ) $tagClass = 'flaggedrevs_short';
+ elseif( $simpleTag ) $tagClass = 'flaggedrevs_notice';
+ elseif( $pristine ) $tagClass = 'flaggedrevs_pristine';
+ elseif( $quality ) $tagClass = 'flaggedrevs_quality';
+ else $tagClass = 'flaggedrevs_basic';
+ # Wrap tag contents in a div
+ if( $tag != '' ) {
+ $tag = "<div id='mw-revisiontag' class='{$tagClass}{$rtl} plainlinks noprint'>$tag</div>";
+ $this->reviewNotice .= $tag;
+ }
+ # Show notice bar/icon
+ $this->displayTag();
+
+ return true;
+ }
+
+ /**
+ * @param $srev stable version
+ * @param $tag review box/bar info
+ * @param $prot protection notice
+ * Tag output function must be called by caller
+ * Parser cache control deferred to caller
+ */
+ protected function showRegularVersion( $srev, &$tag, $prot ) {
+ global $wgUser, $wgOut, $wgLang, $wgRequest;
+ $this->load();
+ $flags = $srev->getTags();
+ $time = $wgLang->date( $srev->getTimestamp(), true );
+ # Get quality level
+ $quality = FlaggedRevs::isQuality( $flags );
+ $pristine = FlaggedRevs::isPristine( $flags );
+ $revsSince = FlaggedRevs::getRevCountSince( $this->article, $srev->getRevId() );
+ # Get stable version sync status
+ $synced = FlaggedRevs::stableVersionIsSynced( $srev, $this->article );
+ if( $synced ) {
+ $this->getReviewNotes( $srev ); // Still the same
+ } else {
+ $this->maybeShowTopDiff( $srev, $quality ); // user may want diff (via prefs)
+ }
+ $pending = '';
+ # Give notice to newer users if an unreviewed edit was completed...
+ if( !$synced && $wgRequest->getVal('shownotice') && !$wgUser->isAllowed('review') ) {
+ $tooltip = wfMsgHtml('revreview-draft-title');
+ $pending = "{$prot}<span class='fr-icon-current' title=\"{$tooltip}\"></span>" .
+ wfMsgExt('revreview-edited',array('parseinline'),$srev->getRevId(),$revsSince);
+ $pending = "<div id='mw-reviewnotice' class='flaggedrevs_preview plainlinks'>$pending</div>";
+ # Notice should always use subtitle
+ $this->reviewNotice = $pending;
+ }
+ # If they are synced, do special styling
+ $simpleTag = !$synced;
+ # Construct some tagging for non-printable outputs. Note that the pending
+ # notice has all this info already, so don't do this if we added that already.
+ if( !$wgOut->isPrintable() && !$pending && !($this->article->lowProfileUI() && $synced) ) {
+ $class = 'fr-icon-current'; // default
+ $tooltip = 'revreview-draft-title';
+ // Simple icon-based UI
+ if( FlaggedRevs::useSimpleUI() ) {
+ if( $synced ) {
+ $msg = $quality ? 'revreview-quick-quality-same' : 'revreview-quick-basic-same';
+ $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
+ $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
+ $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince );
+ } else {
+ $msg = $quality ? 'revreview-quick-see-quality' : 'revreview-quick-see-basic';
+ $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince );
+ }
+ $tooltip = wfMsgHtml($tooltip);
+ $msgHTML = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>$msgHTML";
+ $tag .= FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML, $revsSince,
+ $synced, $synced, false );
+ // Standard UI
+ } else {
+ if( $synced ) {
+ $msg = $quality ? 'revreview-quality-same' : 'revreview-basic-same';
+ $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
+ $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
+ $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(),
+ $time, $revsSince );
+ } else {
+ $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic';
+ $msg .= ($revsSince == 0) ? '-i' : '';
+ $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(),
+ $time, $revsSince );
+ }
+ $tooltip = wfMsgHtml($tooltip);
+ $tag .= "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" . $msgHTML;
+ # Hide clutter
+ if( !empty($flags) ) {
+ $tag .= " " . FlaggedRevsXML::ratingToggle();
+ $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" .
+ wfMsgHtml('revreview-oldrating') . FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
+ }
+ }
+ }
+ # Index the stable version only if it is the default
+ if( $this->article->showStableByDefault() ) {
+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
+ }
+ }
+
+ /**
+ * @param $srev stable version
+ * @param $frev selected flagged revision
+ * @param $tag review box/bar info
+ * @param $prot protection notice
+ * Tag output function must be called by caller
+ * Parser cache control deferred to caller
+ */
+ protected function showOldReviewedVersion( $srev, $frev, &$tag, $prot ) {
+ global $wgOut, $wgLang;
+ $this->load();
+ $flags = $frev->getTags();
+ $time = $wgLang->date( $frev->getTimestamp(), true );
+ # Set display revision ID
+ $wgOut->setRevisionId( $frev->getRevId() );
+ # Get quality level
+ $quality = FlaggedRevs::isQuality( $flags );
+ $pristine = FlaggedRevs::isPristine( $flags );
+ $revsSince = FlaggedRevs::getRevCountSince( $this->article, $srev->getRevId() );
+ $text = $frev->getRevText();
+ $parserOut = FlaggedRevs::parseStableText( $this->article, $text, $frev->getRevId() );
+ # Construct some tagging for non-printable outputs. Note that the pending
+ # notice has all this info already, so don't do this if we added that already.
+ if( !$wgOut->isPrintable() ) {
+ $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
+ $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
+ $tooltip = wfMsgHtml($tooltip);
+ // Simple icon-based UI
+ if( FlaggedRevs::useSimpleUI() ) {
+ $msg = $quality ? 'revreview-quick-quality-old' : 'revreview-quick-basic-old';
+ $html = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" .
+ wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time );
+ $tag = FlaggedRevsXML::prettyRatingBox( $frev, $html, $revsSince,
+ true, false, true );
+ // Standard UI
+ } else {
+ $msg = $quality ? 'revreview-quality-old' : 'revreview-basic-old';
+ $tag = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" .
+ wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time );
+ # Hide clutter
+ if( !empty($flags) ) {
+ $tag .= " " . FlaggedRevsXML::ratingToggle();
+ $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" .
+ wfMsgHtml('revreview-oldrating') .
+ FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
+ }
+ }
+ }
+ # Output HTML
+ $this->getReviewNotes( $frev );
+ $wgOut->addParserOutput( $parserOut );
+ # Index the stable version only
+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
+ }
+
+ /**
+ * @param $srev stable version
+ * @param $tag review box/bar info
+ * @param $prot protection notice
+ * Tag output function must be called by caller
+ * Parser cache control deferred to caller
+ */
+ protected function showStableVersion( $srev, &$tag, $prot ) {
+ global $wgOut, $wgLang, $wgUser;
+ $this->load();
+ $flags = $srev->getTags();
+ $time = $wgLang->date( $srev->getTimestamp(), true );
+ # Set display revision ID
+ $wgOut->setRevisionId( $srev->getRevId() );
+ # Get quality level
+ $quality = FlaggedRevs::isQuality( $flags );
+ $pristine = FlaggedRevs::isPristine( $flags );
+ # We will be looking at the reviewed revision...
+ $revsSince = FlaggedRevs::getRevCountSince( $this->article, $srev->getRevId() );
+ # Get parsed stable version
+ $parserOut = FlaggedRevs::getPageCache( $this->article, $wgUser );
+ if( $parserOut == false ) {
+ $text = $srev->getRevText();
+ $parserOut = FlaggedRevs::parseStableText( $this->article, $text, $srev->getRevId() );
+ # Update the stable version cache
+ FlaggedRevs::updatePageCache( $this->article, $wgUser, $parserOut );
+ }
+ $synced = FlaggedRevs::stableVersionIsSynced( $srev, $this->article, $parserOut, null );
+ # Construct some tagging
+ if( !$wgOut->isPrintable() && !($this->article->lowProfileUI() && $synced) ) {
+ $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
+ $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
+ $tooltip = wfMsgHtml($tooltip);
+ // Simple icon-based UI
+ if( FlaggedRevs::useSimpleUI() ) {
+ $msg = $quality ? 'revreview-quick-quality' : 'revreview-quick-basic';
+ # uses messages 'revreview-quick-quality-same', 'revreview-quick-basic-same'
+ $msg = $synced ? "{$msg}-same" : $msg;
+ $html = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" .
+ wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince );
+ $tag = FlaggedRevsXML::prettyRatingBox( $srev, $html, $revsSince, true, $synced );
+ // Standard UI
+ } else {
+ $msg = $quality ? 'revreview-quality' : 'revreview-basic';
+ if( $synced ) {
+ # uses messages 'revreview-quality-same', 'revreview-basic-same'
+ $msg .= '-same';
+ } elseif( $revsSince == 0 ) {
+ # uses messages 'revreview-quality-i', 'revreview-basic-i'
+ $msg .= '-i';
+ }
+ $tag = "{$prot}<span class='{$class} plainlinks' title=\"{$tooltip}\"></span>" .
+ wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $time, $revsSince );
+ if( !empty($flags) ) {
+ $tag .= " " . FlaggedRevsXML::ratingToggle();
+ $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" .
+ FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
+ }
+ }
+ }
+ # Output HTML
+ $this->getReviewNotes( $srev );
+ $wgOut->addParserOutput( $parserOut );
+ }
+
+ /**
+ * @param FlaggedRevision $srev, stable version
+ * @param bool $quality, revision is quality
+ * @returns bool, diff added to output
+ */
+ protected function maybeShowTopDiff( $srev, $quality ) {
+ global $wgUser, $wgOut, $wgMemc;
+ $this->load();
+ if( !$wgUser->getBoolOption('flaggedrevsviewdiffs') )
+ return false; // nothing to do here
+ if( !$wgUser->isAllowed('review') )
+ return false; // does not apply to this user
+ # Diff should only show for the draft
+ $oldid = $this->article->getOldIDFromRequest();
+ $latest = $this->article->getLatest();
+ if( $oldid && $oldid != $latest ) {
+ return false; // not viewing the draft
+ }
+ # Conditions are met to show diff...
+ wfLoadExtensionMessages( 'FlaggedRevs' ); // load required messages
+ $leftNote = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
+ $rClass = FlaggedRevsXML::getQualityColor( false );
+ $lClass = FlaggedRevsXML::getQualityColor( (int)$quality );
+ $rightNote = "<span class='$rClass'>[".wfMsgHtml('revreview-draft-title')."]</span>";
+ $leftNote = "<span class='$lClass'>[".wfMsgHtml($leftNote)."]</span>";
+ # Fetch the stable and draft revision text
+ $oText = $srev->getRevText();
+ if( $oText === false )
+ return false; // deleted revision or something?
+ $nText = $this->article->getContent();
+ if( $nText === false )
+ return false; // deleted revision or something?
+ # Build diff at the top of the page
+ if( strcmp($oText,$nText) !== 0 ) {
+ $diffEngine = new DifferenceEngine();
+ $diffEngine->showDiffStyle();
+ $n = $this->article->getTitle()->countRevisionsBetween( $srev->getRevId(), $latest );
+ if( $n ) {
+ $multiNotice = "<tr><td colspan='4' align='center' class='diff-multi'>" .
+ wfMsgExt( 'diff-multi', array( 'parse' ), $n )."</td></tr>";
+ } else {
+ $multiNotice = '';
+ }
+ $wgOut->addHTML(
+ "<div>" .
+ "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" .
+ "<col class='diff-marker' />" .
+ "<col class='diff-content' />" .
+ "<col class='diff-marker' />" .
+ "<col class='diff-content' />" .
+ "<tr>" .
+ "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" .
+ $leftNote . "</b></td>" .
+ "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" .
+ $rightNote . "</b></td>" .
+ "</tr>" .
+ $multiNotice .
+ $diffEngine->generateDiffBody( $oText, $nText ) .
+ "</table>" .
+ "</div>\n"
+ );
+ $this->isDiffFromStable = true;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Get the normal and display files for the underlying ImagePage.
+ * If the a stable version needs to be displayed, this will set $normalFile
+ * to the current version, and $displayFile to the desired version.
+ *
+ * If no stable version is required, the reference parameters will not be set
+ *
+ * Depends on $wgRequest
+ */
+ public function imagePageFindFile( &$normalFile, &$displayFile ) {
+ global $wgRequest, $wgArticle;
+ $this->load();
+ # Determine timestamp. A reviewed version may have explicitly been requested...
+ $frev = null;
+ $time = false;
+ if( $reqId = $wgRequest->getVal('stableid') ) {
+ $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId );
+ } elseif( $this->pageOverride() ) {
+ $frev = $this->article->getStableRev();
+ }
+ if( !is_null($frev) ) {
+ $time = $frev->getFileTimestamp();
+ // B/C, may be stored in associated image version metadata table
+ if( !$time ) {
+ $dbr = wfGetDB( DB_SLAVE );
+ $time = $dbr->selectField( 'flaggedimages',
+ 'fi_img_timestamp',
+ array( 'fi_rev_id' => $frev->getRevId(),
+ 'fi_name' => $this->article->getTitle()->getDBkey() ),
+ __METHOD__
+ );
+ }
+ # NOTE: if not found, this will use the current
+ $wgArticle = new ImagePage( $this->article->getTitle(), $time );
+ }
+ if( !$time ) {
+ # Try request parameter
+ $time = $wgRequest->getVal( 'filetimestamp', false );
+ }
+
+ if( !$time ) {
+ return; // Use the default behaviour
+ }
+
+ $title = $this->article->getTitle();
+ $displayFile = wfFindFile( $title, array( 'time' => $time ) );
+ # If none found, try current
+ if( !$displayFile ) {
+ wfDebug( __METHOD__.": {$title->getPrefixedDBkey()}: $time not found, using current\n" );
+ $displayFile = wfFindFile( $title );
+ # If none found, use a valid local placeholder
+ if( !$displayFile ) {
+ $displayFile = wfLocalFile( $title ); // fallback to current
+ }
+ $normalFile = $displayFile;
+ # If found, set $normalFile
+ } else {
+ wfDebug( __METHOD__.": {$title->getPrefixedDBkey()}: using timestamp $time\n" );
+ $normalFile = wfFindFile( $title );
+ }
+ }
+
+ /**
+ * Adds latest stable version tag to page when editing
+ */
+ public function addToEditView( $editPage ) {
+ global $wgRequest, $wgOut;
+ $this->load();
+ # Must be reviewable. UI may be limited to unobtrusive patrolling system.
+ if( !$this->article->isReviewable() || $this->article->limitedUI() )
+ return true;
+ # Show stabilization log
+ $this->showStabilityLog();
+ # Set new body html text as that of now
+ $tag = $warning = $prot = '';
+ # Check the newest stable version
+ $quality = 0;
+ if( $frev = $this->article->getStableRev() ) {
+ global $wgLang, $wgUser, $wgFlaggedRevsAutoReview;
+ # Find out revision id
+ $revId = $editPage->oldid ?
+ $editPage->oldid : $this->article->getLatest();
+ # If this will be autoreviewed, notify the user...
+ if( !FlaggedRevs::lowProfileUI() && $wgFlaggedRevsAutoReview && $wgUser->isAllowed('review') ) {
+ # If we are editing some reviewed revision, any changes this user
+ # makes will be autoreviewed...
+ $ofrev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $revId );
+ if( !is_null($ofrev) ) {
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ $msg = ( $revId==$frev->getRevId() ) ? 'revreview-auto-w' : 'revreview-auto-w-old';
+ $warning = "<div id='mw-autoreviewtag' class='flaggedrevs_warning plainlinks'>" .
+ wfMsgExt($msg,array('parseinline')) . "</div>";
+ }
+ # Let new users know about review procedure a tag
+ } elseif( !$wgUser->getId() && $this->article->showStableByDefault() ) {
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ $warning = "<div id='mw-editwarningtag' class='flaggedrevs_editnotice plainlinks'>" .
+ wfMsgExt('revreview-editnotice',array('parseinline')) . "</div>";
+ }
+ if( $frev->getRevId() != $revId ) {
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ $time = $wgLang->date( $frev->getTimestamp(), true );
+ $flags = $frev->getTags();
+ if( FlaggedRevs::isQuality($flags) ) {
+ $quality = FlaggedRevs::isPristine($flags) ? 2 : 1;
+ }
+ $revsSince = FlaggedRevs::getRevCountSince( $this->article, $frev->getRevId() );
+ // Is the page config altered?
+ if( $this->article->isPageLocked() ) {
+ $prot = "<span class='fr-icon-locked' title=\"".
+ wfMsgHtml('revreview-locked-title')."\"></span>";
+ } elseif( $this->article->isPageUnlocked() ) {
+ $prot = "<span class='fr-icon-unlocked' title=\"".
+ wfMsgHtml('revreview-unlocked-title')."\"></span>";
+ }
+ # Streamlined UI
+ if( FlaggedRevs::useSimpleUI() ) {
+ $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic';
+ $msg .= ($revsSince == 0) ? '-i' : '';
+ $tag = "{$prot}<span class='fr-checkbox'></span>" .
+ wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time, $revsSince );
+ $tag = "<div id='mw-revisiontag-edit' class='flaggedrevs_editnotice plainlinks'>$tag</div>";
+ # Standard UI
+ } else {
+ $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic';
+ $msg .= ($revsSince == 0) ? '-i' : '';
+ $tag = "{$prot}<span class='fr-checkbox'></span>" .
+ wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time, $revsSince );
+ # Hide clutter
+ if( !empty($flags) ) {
+ $tag .= " " . FlaggedRevsXML::ratingToggle();
+ $tag .= '<span id="mw-revisionratings" style="display:block;"><br/>' .
+ wfMsg('revreview-oldrating') . FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
+ }
+ $tag = "<div id='mw-revisiontag-edit' class='flaggedrevs_editnotice plainlinks'>$tag</div>";
+ }
+ }
+ # Output notice and warning for editors
+ if( $tag || $warning ) {
+ $wgOut->addHTML( $tag . $warning );
+ }
+
+ # Show diff to stable, to make things less confusing...
+ # This can be disabled via user preferences
+ if( $frev->getRevId() < $revId // changes were made
+ && $this->showDiffOnEditUser() // stable default and user cannot review
+ && $wgUser->getBoolOption('flaggedrevseditdiffs') // not disable via prefs
+ ) {
+ # Don't show for old revisions, diff, preview, or undo.
+ if( $editPage->oldid || $editPage->section === "new"
+ || in_array($editPage->formtype,array('diff','preview')) )
+ {
+ return true; // nothing to show here
+ }
+
+ # Conditions are met to show diff...
+ wfLoadExtensionMessages( 'FlaggedRevs' ); // load required messages
+ $leftNote = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
+ $rClass = FlaggedRevsXML::getQualityColor( false );
+ $lClass = FlaggedRevsXML::getQualityColor( (int)$quality );
+ $rightNote = "<span class='$rClass'>[".wfMsgHtml('revreview-draft-title')."]</span>";
+ $leftNote = "<span class='$lClass'>[".wfMsgHtml($leftNote)."]</span>";
+ $text = $frev->getRevText();
+ # Are we editing a section?
+ $section = ($editPage->section == "") ? false : intval($editPage->section);
+ if( $section !== false ) {
+ $text = $this->article->getSection( $text, $section );
+ }
+ if( $text !== false && strcmp($text,$editPage->textbox1) !== 0 ) {
+ $diffEngine = new DifferenceEngine();
+ $diffEngine->showDiffStyle();
+ $wgOut->addHTML(
+ "<div>" .
+ "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" .
+ "<col class='diff-marker' />" .
+ "<col class='diff-content' />" .
+ "<col class='diff-marker' />" .
+ "<col class='diff-content' />" .
+ "<tr>" .
+ "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" .
+ $leftNote . "</b></td>" .
+ "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" .
+ $rightNote . "</b></td>" .
+ "</tr>" .
+ $diffEngine->generateDiffBody( $text, $editPage->textbox1 ) .
+ "</table>" .
+ "</div>\n"
+ );
+ }
+ }
+ }
+ return true;
+ }
+
+ protected function showStabilityLog() {
+ global $wgOut;
+ $this->load();
+ # Only for pages manually made to be stable...
+ if( $this->article->isPageLocked() ) {
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ $wgOut->addHTML( "<div class='mw-warning-with-logexcerpt'>" );
+ $wgOut->addWikiMsg( 'revreview-locked' );
+ LogEventsList::showLogExtract( $wgOut, 'stable',
+ $this->article->getTitle()->getPrefixedText(), '', array('lim'=>1) );
+ $wgOut->addHTML( "</div>" );
+ # ...or unstable
+ } elseif( $this->article->isPageUnlocked() ) {
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ $wgOut->addHTML( "<div class='mw-warning-with-logexcerpt'>" );
+ $wgOut->addWikiMsg( 'revreview-unlocked' );
+ LogEventsList::showLogExtract( $wgOut, 'stable',
+ $this->article->getTitle()->getPrefixedText(), '', array('lim'=>1) );
+ $wgOut->addHTML( "</div>" );
+ }
+ return true;
+ }
+
+ /**
+ * Add unreviewed pages links
+ */
+ public function addToCategoryView() {
+ global $wgOut, $wgUser;
+ $this->load();
+ if( !$wgUser->isAllowed( 'review' ) ) {
+ return true;
+ }
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ # Load special page names
+ wfLoadExtensionMessages( 'OldReviewedPages' );
+ wfLoadExtensionMessages( 'UnreviewedPages' );
+
+ $category = $this->article->getTitle()->getText();
+
+ $unreviewed = SpecialPage::getTitleFor( 'UnreviewedPages' );
+ $unreviewedLink = $wgUser->getSkin()->makeKnownLinkObj( $unreviewed,
+ wfMsgHtml('unreviewedpages'), 'category=' . urlencode($category) );
+
+ $oldreviewed = SpecialPage::getTitleFor( 'OldReviewedPages' );
+ $oldreviewedLink = $wgUser->getSkin()->makeKnownLinkObj( $oldreviewed,
+ wfMsgHtml('oldreviewedpages'), 'category=' . urlencode($category) );
+
+ $wgOut->appendSubtitle("<span id='mw-category-oldreviewed'>$unreviewedLink / $oldreviewedLink</span>");
+
+ return true;
+ }
+
+ /**
+ * Add review form to pages when necessary
+ */
+ public function addReviewForm( &$data ) {
+ global $wgRequest, $wgUser, $wgOut;
+ $this->load();
+ # User must have review rights and page must be reviewable
+ if( !$wgUser->isAllowed('review') || !$this->article->exists() || !$this->article->isReviewable() ) {
+ return true;
+ }
+ # Unobtrusive patrolling UI only shows forms if requested
+ if( !$wgRequest->getInt('reviewform') && $this->article->limitedUI() ) {
+ return true;
+ }
+ # Avoid multi-page diffs that are useless and misbehave (bug 19327)
+ if( $this->isMultiPageDiff ) {
+ return true;
+ }
+ # Check action and if page is protected
+ $action = $wgRequest->getVal( 'action', 'view' );
+ # Must be view/diff action...
+ if( !self::isViewAction($action) ) {
+ return true;
+ }
+ # Place the form at the top or bottom as most convenient
+ $onTop = $wgRequest->getVal('diff') || $this->isDiffFromStable;
+ $this->addQuickReview( $data, $onTop, false );
+ return true;
+ }
+
+ /**
+ * Add link to stable version setting to protection form
+ */
+ public function addVisibilityLink( &$data ) {
+ global $wgUser, $wgRequest, $wgOut;
+ $this->load();
+ if( FlaggedRevs::getProtectionLevels() )
+ return true; // simple custom levels set for action=protect
+ # Check only if the title is reviewable
+ if( !$this->article->isReviewable(true) ) {
+ return true;
+ }
+ $action = $wgRequest->getVal( 'action', 'view' );
+ if( $action == 'protect' || $action == 'unprotect' ) {
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ wfLoadExtensionMessages( 'Stabilization' ); // Load special page name
+ $title = SpecialPage::getTitleFor( 'Stabilization' );
+ # Give a link to the page to configure the stable version
+ $frev = $this->article->getStableRev();
+ if( $frev && $frev->getRevId() == $this->article->getLatest() ) {
+ $wgOut->prependHTML( "<span class='plainlinks'>" .
+ wfMsgExt( 'revreview-visibility',array('parseinline'),
+ $title->getPrefixedText() ) . "</span>" );
+ } elseif( $frev ) {
+ $wgOut->prependHTML( "<span class='plainlinks'>" .
+ wfMsgExt( 'revreview-visibility2',array('parseinline'),
+ $title->getPrefixedText() ) . "</span>" );
+ } else {
+ $wgOut->prependHTML( "<span class='plainlinks'>" .
+ wfMsgExt( 'revreview-visibility3',array('parseinline'),
+ $title->getPrefixedText() ) . "</span>" );
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Modify an array of action links, as used by SkinTemplateNavigation and
+ * SkinTemplateTabs, to inlude flagged revs UI elements
+ */
+ public function setActionTabs( $skin, &$actions ) {
+ global $wgRequest, $wgUser;
+ $this->load();
+ if( FlaggedRevs::getProtectionLevels() ) {
+ return true; // simple custom levels set for action=protect
+ }
+ $title = $this->article->getTitle()->getSubjectPage();
+ if ( !FlaggedRevs::isPageReviewable( $title ) ) {
+ return true; // Only reviewable pages need these tabs
+ }
+ // Check if we should show a stabilization tab
+ if (
+ !$skin->mTitle->isTalkPage() &&
+ is_array( $actions ) &&
+ !isset( $actions['protect'] ) &&
+ !isset( $actions['unprotect'] ) &&
+ $wgUser->isAllowed( 'stablesettings' ) &&
+ $title->exists()
+ ) {
+ wfLoadExtensionMessages( 'Stabilization' );
+ $stableTitle = SpecialPage::getTitleFor( 'Stabilization' );
+ // Add a tab
+ $actions['default'] = array(
+ 'class' => false,
+ 'text' => wfMsg( 'stabilization-tab' ),
+ 'href' => $stableTitle->getLocalUrl(
+ 'page=' . $title->getPrefixedUrl()
+ )
+ );
+ }
+ return true;
+ }
+
+ /**
+ * Modify an array of view links, as used by SkinTemplateNavigation and
+ * SkinTemplateTabs, to inlude flagged revs UI elements
+ */
+ public function setViewTabs( $skin, &$views ) {
+ global $wgRequest, $wgUser, $wgFlaggedRevTabs;
+ $this->load();
+
+ $title = $this->article->getTitle()->getSubjectPage(); // Get the actual content page
+ $article = new Article( $title );
+ $action = $wgRequest->getVal( 'action', 'view' );
+ $fa = FlaggedArticle::getTitleInstance( $title );
+ if ( !$fa->isReviewable() || $this->article->limitedUI() ) {
+ // This isn't a reviewable page or the UI is hidden
+ return true;
+ }
+ $srev = $this->article->getStableRev( $action == 'rollback' ? FR_MASTER : 0 );
+ if( is_null( $srev ) ) {
+ return true; // No stable revision exists
+ }
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ $synced = FlaggedRevs::stableVersionIsSynced( $srev, $article );
+ // Set draft tab as needed...
+ if ( !$skin->mTitle->isTalkPage() && !$synced ) {
+ if ( isset( $views['edit'] ) ) {
+ if ( $this->article->showStableByDefault() ) {
+ $views['edit']['text'] = wfMsg('revreview-edit');
+ }
+ if ( $this->pageOverride() ) {
+ $views['edit']['href'] = $title->getLocalUrl( 'action=edit' );
+ }
+ }
+ if ( isset( $views['viewsource'] ) ) {
+ if ( $this->article->showStableByDefault() ) {
+ $views['viewsource']['text'] = wfMsg('revreview-source');
+ }
+ if ( $this->pageOverride() ) {
+ $views['viewsource']['href'] = $title->getLocalUrl( 'action=edit' );
+ }
+ }
+ }
+ if ( !$wgFlaggedRevTabs || $synced ) {
+ // Exit, since either the stable/draft tabs should not be shown
+ // or the page is already the most current revision
+ return true;
+ }
+ $tabs = array(
+ 'stable' => array(
+ 'text' => wfMsg( 'revreview-stable' ), // unused
+ 'href' => $title->getLocalUrl( 'stable=1' ),
+ 'class' => ''
+ ),
+ 'current' => array(
+ 'text' => wfMsg( 'revreview-current' ),
+ 'href' => $title->getLocalUrl( 'stable=0&redirect=no' ),
+ 'class' => ''
+ ),
+ );
+ if ( $this->pageOverride() || $wgRequest->getVal( 'stableid' ) ) {
+ // We are looking a the stable version
+ $tabs['stable']['class'] = 'selected';
+ } elseif (
+ ( self::isViewAction( $action ) || $action == 'edit' ) &&
+ !$skin->mTitle->isTalkPage()
+ ) {
+ // We are looking at the current revision or in edit mode
+ $tabs['current']['class'] = 'selected';
+ }
+ $first = true;
+ $newViews = array();
+ foreach ( $views as $tabAction => $data ) {
+ // Very first tab (page link)
+ if( $first ) {
+ if( $synced ) {
+ // Use existing first tabs when synced
+ $newViews[$tabAction] = $data;
+ } else {
+ // Use split current and stable tabs when not synced
+ $newViews[$tabAction]['text'] = $data['text']; // keep tab name
+ $newViews[$tabAction]['href'] = $tabs['stable']['href'];
+ $newViews[$tabAction]['class'] = $tabs['stable']['class'];
+ $newViews['current'] = $tabs['current'];
+ }
+ $first = false;
+ } else {
+ $newViews[$tabAction] = $data;
+ }
+ }
+ // Replaces old tabs with new tabs
+ $views = $newViews;
+ return true;
+ }
+
+ /**
+ * @param FlaggedRevision $frev
+ * @return string, revision review notes
+ */
+ public function getReviewNotes( $frev ) {
+ global $wgUser;
+ $this->load();
+ if( FlaggedRevs::allowComments() && $frev && $frev->getComment() ) {
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ $notes = "<br/><div class='flaggedrevs_notes plainlinks'>";
+ $notes .= wfMsgExt('revreview-note', array('parseinline'), User::whoIs( $frev->getUser() ) );
+ $notes .= '<br/><i>' . $wgUser->getSkin()->formatComment( $frev->getComment() ) . '</i></div>';
+ $this->reviewNotes = $notes;
+ }
+ }
+
+ /**
+ * When comparing the stable revision to the current after editing a page, show
+ * a tag with some explaination for the diff.
+ */
+ public function addDiffNoticeAndIncludes( $diff, $oldRev, $newRev ) {
+ global $wgRequest, $wgUser, $wgOut, $wgMemc;
+ $this->load();
+ # Page must be reviewable. Exempt printer-friendly output.
+ # UI may be limited to unobtrusive patrolling system
+ if( $wgOut->isPrintable() || !$this->article->isReviewable() || $this->article->limitedUI() )
+ return true;
+ # Load required messages
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ # Check if this might be the diff to stable. If so, enhance it.
+ if( $newRev->isCurrent() && $oldRev ) {
+ $article = new Article( $newRev->getTitle() );
+ # Try the sync value cache...
+ $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $article->getId() );
+ $value = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article );
+ $synced = ($value === "true") ? true : false; // default as false to trigger query
+ $frev = $this->article->getStableRev();
+ if( $frev && $frev->getRevId() == $oldRev->getID() ) {
+ global $wgParserCacheExpireTime;
+
+ $changeList = array();
+ $skin = $wgUser->getSkin();
+
+ # Try the cache. Uses format <page ID>-<UNIX timestamp>.
+ $key = wfMemcKey( 'stableDiffs', 'templates', $article->getId() );
+ $tmpChanges = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article );
+ if( empty($tmpChanges) && !$synced ) {
+ $tmpChanges = false; // don't use cache
+ }
+
+ # Make a list of each changed template...
+ if( $tmpChanges === false ) {
+ $dbr = wfGetDB( DB_SLAVE );
+ // Get templates where the current and stable are not the same revision
+ $ret = $dbr->select( array('flaggedtemplates','page','flaggedpages'),
+ array( 'ft_namespace', 'ft_title', 'fp_stable','ft_tmp_rev_id', 'page_latest' ),
+ array( 'ft_rev_id' => $frev->getRevId(),
+ 'page_namespace = ft_namespace',
+ 'page_title = ft_title' ),
+ __METHOD__,
+ array(), /* OPTIONS */
+ array( 'flaggedpages' => array('LEFT JOIN','fp_page_id = page_id') )
+ );
+ $tmpChanges = array();
+ while( $row = $dbr->fetchObject( $ret ) ) {
+ $title = Title::makeTitleSafe( $row->ft_namespace, $row->ft_title );
+ $revIdDraft = $row->page_latest;
+ // stable time -> time when reviewed (unless the other is newer)
+ $revIdStable = isset($row->fp_stable) && $row->fp_stable >= $row->ft_tmp_rev_id ?
+ $row->fp_stable : $row->ft_tmp_rev_id;
+ // compare to current
+ if( $revIdDraft > $revIdStable ) {
+ $tmpChanges[] = $skin->makeKnownLinkObj( $title, $title->getPrefixedText(),
+ "diff=cur&oldid={$revIdStable}" );
+ }
+ }
+ $wgMemc->set( $key, FlaggedRevs::makeMemcObj($tmpChanges), $wgParserCacheExpireTime );
+ }
+ # Add set to list
+ if( $tmpChanges )
+ $changeList += $tmpChanges;
+
+ # Try the cache. Uses format <page ID>-<UNIX timestamp>.
+ $key = wfMemcKey( 'stableDiffs', 'images', $article->getId() );
+ $imgChanges = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article );
+ if( empty($imgChanges) && !$synced ) {
+ $imgChanges = false; // don't use cache
+ }
+
+ // Get list of each changed image...
+ if( $imgChanges === false ) {
+ $dbr = wfGetDB( DB_SLAVE );
+ // Get images where the current and stable are not the same revision
+ $ret = $dbr->select( array('flaggedimages','page','image','flaggedpages','flaggedrevs'),
+ array( 'fi_name', 'fi_img_timestamp', 'fr_img_timestamp' ),
+ array( 'fi_rev_id' => $frev->getRevId() ),
+ __METHOD__,
+ array(), /* OPTIONS */
+ array( 'page' => array('LEFT JOIN','page_namespace = '. NS_FILE .' AND page_title = fi_name'),
+ 'image' => array('LEFT JOIN','img_name = fi_name'),
+ 'flaggedpages' => array('LEFT JOIN','fp_page_id = page_id'),
+ 'flaggedrevs' => array('LEFT JOIN','fr_page_id = fp_page_id AND fr_rev_id = fp_stable') )
+ );
+ $imgChanges = array();
+ while( $row = $dbr->fetchObject( $ret ) ) {
+ $title = Title::makeTitleSafe( NS_FILE, $row->fi_name );
+ // stable time -> time when reviewed (unless the other is newer)
+ $timestamp = isset($row->fr_img_timestamp) && $row->fr_img_timestamp >= $row->fi_img_timestamp ?
+ $row->fr_img_timestamp : $row->fi_img_timestamp;
+ // compare to current
+ $file = wfFindFile( $title );
+ if( $file && $file->getTimestamp() > $timestamp )
+ $imgChanges[] = $skin->makeKnownLinkObj( $title, $title->getPrefixedText() );
+ }
+ $wgMemc->set( $key, FlaggedRevs::makeMemcObj($imgChanges), $wgParserCacheExpireTime );
+ }
+ if( $imgChanges )
+ $changeList += $imgChanges;
+
+ # Some important information...
+ $notice = '';
+ if( count($changeList) > 0 ) {
+ $notice = '<br/>' . wfMsgExt('revreview-update-use', array('parseinline'));
+ } elseif( !$synced ) {
+ $diff->mTitle->invalidateCache(); // bad cache, said they were not synced
+ }
+
+ # If the user is allowed to review, prompt them!
+ if( empty($changeList) && $wgUser->isAllowed('review') ) {
+ $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" .
+ wfMsgExt('revreview-update-none', array('parseinline')).$notice.'</div>' );
+ } elseif( !empty($changeList) && $wgUser->isAllowed('review') ) {
+ $changeList = implode(', ',$changeList);
+ $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" .
+ wfMsgExt('revreview-update', array('parseinline')).'&nbsp;'.
+ $changeList.$notice.'</div>' );
+ } elseif( !empty($changeList) ) {
+ $changeList = implode(', ',$changeList);
+ $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" .
+ wfMsgExt('revreview-update-includes', array('parseinline')).'&nbsp;'.
+ $changeList.$notice.'</div>' );
+ }
+ # Set flag for review form to tell it to autoselect tag settings from the
+ # old revision unless the current one is tagged to.
+ if( !FlaggedRevision::newFromTitle( $diff->mTitle, $newRev->getID() ) ) {
+ $this->isDiffFromStable = true;
+ }
+
+ # Set a key to note that someone is viewing this
+ if( $wgUser->isAllowed('review') ) {
+ $key = wfMemcKey( 'stableDiffs', 'underReview', $oldRev->getID(), $newRev->getID() );
+ $wgMemc->set( $key, '1', 10*60 ); // 10 min
+ }
+ }
+ }
+ $newRevQ = FlaggedRevs::getRevQuality( $newRev->getPage(), $newRev->getId() );
+ $oldRevQ = $oldRev ? FlaggedRevs::getRevQuality( $newRev->getPage(), $oldRev->getId() ) : false;
+ # Diff between two revisions
+ if( $oldRev ) {
+ $wgOut->addHTML( "<table class='fr-diff-ratings'><tr>" );
+
+ $class = FlaggedRevsXML::getQualityColor( $oldRevQ );
+ if( $oldRevQ !== false ) {
+ $msg = $oldRevQ ? 'hist-quality' : 'hist-stable';
+ } else {
+ $msg = 'hist-draft';
+ }
+ $wgOut->addHTML( "<td width='50%' align='center'>" );
+ $wgOut->addHTML( "<span class='$class'><b>[" . wfMsgHtml( $msg ) . "]</b></span>" );
+
+ $class = FlaggedRevsXML::getQualityColor( $newRevQ );
+ if( $newRevQ !== false ) {
+ $msg = $newRevQ ? 'hist-quality' : 'hist-stable';
+ } else {
+ $msg = 'hist-draft';
+ }
+ $wgOut->addHTML( "</td><td width='50%' align='center'>" );
+ $wgOut->addHTML( "<span class='$class'><b>[" . wfMsgHtml( $msg ) . "]</b></span>" );
+
+ $wgOut->addHTML( '</td></tr></table>' );
+ # New page "diffs" - just one rev
+ } else {
+ if( $newRevQ !== false ) {
+ $msg = $newRevQ ? 'hist-quality' : 'hist-stable';
+ } else {
+ $msg = 'hist-draft';
+ }
+ $wgOut->addHTML( "<table class='fr-diff-ratings'><tr><td class='fr-$msg' align='center'>" );
+ $wgOut->addHTML( "<b>[" . wfMsgHtml( $msg ) . "]</b>" );
+ $wgOut->addHTML( '</td></tr></table>' );
+ }
+ return true;
+ }
+
+ /**
+ * Set $this->isDiffFromStable and $this->isMultiPageDiff fields
+ */
+ public function setViewFlags( $diff, $oldRev, $newRev ) {
+ $this->load();
+ if( $newRev && $oldRev ) {
+ // Is this a diff between two pages?
+ if( $newRev->getPage() != $oldRev->getPage() ) {
+ $this->isMultiPageDiff = true;
+ // Is there a stable version?
+ } else if( $this->article->isReviewable() ) {
+ $frev = $this->article->getStableRev();
+ // Is this a diff of the draft rev against the stable rev?
+ if( $frev && $frev->getRevId() == $oldRev->getId() && $newRev->isCurrent() ) {
+ $this->isDiffFromStable = true;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Add a link to patrol non-reviewable pages.
+ * Also add a diff-to-stable for other pages if possible.
+ */
+ public function addDiffLink( $diff, $oldRev, $newRev ) {
+ global $wgUser, $wgOut;
+ $this->load();
+ // Is there a stable version?
+ if( $newRev && $oldRev && $this->article->isReviewable() ) {
+ $frev = $this->article->getStableRev();
+ # Give a link to the diff-to-stable if needed
+ if( $frev && !$this->isDiffFromStable ) {
+ $article = new Article( $newRev->getTitle() );
+ # Is the stable revision using the same revision as the current?
+ if( $article->getLatest() != $frev->getRevId() ) {
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ $patrol = '(' . $wgUser->getSkin()->makeKnownLinkObj( $newRev->getTitle(),
+ wfMsgHtml( 'review-diff2stable' ), "oldid={$frev->getRevId()}&diff=cur&diffonly=0" ) . ')';
+ $wgOut->addHTML( "<div class='fr-diff-to-stable' align='center'>$patrol</div>" );
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Redirect users out to review the changes to the stable version.
+ * Only for people who can review and for pages that have a stable version.
+ */
+ public function injectReviewDiffURLParams( &$sectionAnchor, &$extraQuery ) {
+ global $wgUser, $wgReviewChangesAfterEdit;
+ $this->load();
+ # Don't show this for pages that are not reviewable
+ if( !$this->article->isReviewable() || $this->article->getTitle()->isTalkPage() )
+ return true;
+ # We may want to skip some UI elements
+ if( $this->article->limitedUI() ) return true;
+ # Get the stable version, from master
+ $frev = $this->article->getStableRev( FR_MASTER );
+ if( !$frev )
+ return true;
+ $latest = $this->article->getTitle()->getLatestRevID(GAID_FOR_UPDATE);
+ // If we are supposed to review after edit, and it was not autoreviewed,
+ // and the user can actually make new stable version, take us to the diff...
+ if( $wgReviewChangesAfterEdit && $frev && $latest > $frev->getRevId() && $frev->userCanSetFlags() ) {
+ $extraQuery .= $extraQuery ? '&' : '';
+ $extraQuery .= "oldid={$frev->getRevId()}&diff=cur&diffonly=0"; // override diff-only
+ // ...otherwise, go to the current revision after completing an edit.
+ } else {
+ if( $frev && $latest != $frev->getRevId() ) {
+ $extraQuery .= "stable=0";
+ if( !$wgUser->isAllowed('review') && $this->article->showStableByDefault() ) {
+ $extraQuery .= "&shownotice=1";
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Add a hidden revision ID field to edit form.
+ * Needed for autoreview so it can select the flags from said revision.
+ */
+ public function addRevisionIDField( $editPage, $out ) {
+ global $wgRequest;
+ $this->load();
+ # Find out revision id
+ if( $this->article->mRevision ) {
+ $revId = $this->article->mRevision->mId;
+ } else {
+ $latest = $this->article->getTitle()->getLatestRevID(GAID_FOR_UPDATE);
+ $revId = $latest;
+ wfDebug( 'FlaggedArticle::addRevisionIDField - ID not specified, assumed current' );
+ }
+ # If undoing a few consecutive top edits, we know the base ID
+ if( $undo = $wgRequest->getIntOrNull('undo') ) {
+ $undoAfter = $wgRequest->getIntOrNull('undoafter');
+ $latest = isset($latest) ?
+ $latest : $this->article->getTitle()->getLatestRevID(GAID_FOR_UPDATE);
+ if( $undoAfter && $undo == $this->article->getLatest() ) {
+ $revId = $undoAfter;
+ }
+ }
+ $out->addHTML( "\n" . Xml::hidden( 'baseRevId', $revId ) );
+ $out->addHTML( "\n" . Xml::hidden( 'undidRev',
+ empty($editPage->undidRev) ? 0 : $editPage->undidRev )
+ );
+ return true;
+ }
+
+ /**
+ * Adds brief review notes to a page.
+ * @param OutputPage $out
+ */
+ public function addReviewNotes( &$data ) {
+ $this->load();
+ if( $this->reviewNotes ) {
+ $data .= $this->reviewNotes;
+ }
+ return true;
+ }
+
+ /**
+ * Adds a brief review form to a page.
+ * @param string $data
+ * @param bool $top
+ * @param bool hide
+ * @param bool $top, should this form always go on top?
+ */
+ public function addQuickReview( &$data, $top = false, $hide = false ) {
+ global $wgOut, $wgUser, $wgRequest;
+ $this->load();
+ # Get the revision being displayed
+ $id = $wgOut->getRevisionId();
+ if( !$id ) {
+ if( !$this->isDiffFromStable ) {
+ return false; // only safe to assume current if diff-to-stable
+ } else {
+ $rev = Revision::newFromTitle( $this->article->getTitle() );
+ $id = $rev->getId();
+ }
+ } else {
+ $rev = Revision::newFromTitle( $this->article->getTitle(), $id );
+ }
+ # Load required messages
+ wfLoadExtensionMessages( 'FlaggedRevs' );
+ # Must be a valid non-printable output and revision must be public
+ if( $wgOut->isPrintable() || !$rev || $rev->isDeleted(Revision::DELETED_TEXT) ) {
+ return false;
+ }
+ $useCurrent = false;
+ if( !isset($wgOut->mTemplateIds) || !isset($wgOut->fr_ImageSHA1Keys) ) {
+ $useCurrent = true;
+ }
+ $skin = $wgUser->getSkin();
+
+ $config = $this->article->getVisibilitySettings();
+ # Variable for sites with no flags, otherwise discarded
+ $approve = $wgRequest->getBool('wpApprove');
+ # See if the version being displayed is flagged...
+ $oldFlags = $this->article->getFlagsForRevision( $id );
+ # If we are reviewing updates to a page, start off with the stable revision's
+ # flags. Otherwise, we just fill them in with the selected revision's flags.
+ if( $this->isDiffFromStable ) {
+ $srev = $this->article->getStableRev();
+ $flags = $srev->getTags();
+ # Check if user is allowed to renew the stable version.
+ # If not, then get the flags for the new revision itself.
+ if( !RevisionReview::userCanSetFlags( $oldFlags ) ) {
+ $flags = $oldFlags;
+ }
+ $encNotes = $srev->getComment();
+ } else {
+ $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $id );
+ $flags = $oldFlags;
+ $encNotes = $frev ? $frev->getComment() : ""; // pre-fill notes
+ }
+
+ $reviewTitle = SpecialPage::getTitleFor( 'RevisionReview' );
+ $action = $reviewTitle->getLocalUrl( 'action=submit' );
+ $params = array( 'method' => 'post', 'action' => $action, 'id' => 'mw-reviewform' );
+ if( $hide ) {
+ $params['class'] = 'fr-hiddenform';
+ }
+ $form = Xml::openElement( 'form', $params );
+ $form .= Xml::openElement( 'fieldset', array('class' => 'flaggedrevs_reviewform noprint') );
+ $form .= "<legend><strong>" . wfMsgHtml( 'revreview-flag', $id ) . "</strong></legend>\n";
+
+ # Show explanatory text
+ if( !FlaggedRevs::lowProfileUI() ) {
+ $msg = FlaggedRevs::showStableByDefault() ? 'revreview-text' : 'revreview-text2';
+ $form .= wfMsgExt( $msg, array('parse') );
+ }
+
+ # Current user has too few rights to change at least one flag, thus entire form disabled
+ $uneditable = !$this->article->getTitle()->quickUserCan('edit');
+ $disabled = !RevisionReview::userCanSetFlags( $flags ) || $uneditable;
+ if( $disabled ) {
+ $form .= Xml::openElement( 'div', array('class' => 'fr-rating-controls-disabled',
+ 'id' => 'fr-rating-controls-disabled') );
+ $toggle = array( 'disabled' => "disabled" );
+ } else {
+ $form .= Xml::openElement( 'div', array('class' => 'fr-rating-controls',
+ 'id' => 'fr-rating-controls') );
+ $toggle = array();
+ }
+ # Add main checkboxes/selects
+ $form .= Xml::openElement( 'span', array('id' => 'mw-ratingselects') );
+ $form .= FlaggedRevsXML::ratingInputs( $flags, $config, $disabled );
+ $form .= Xml::closeElement( 'span' );
+
+ if( FlaggedRevs::allowComments() && $wgUser->isAllowed( 'validate' ) ) {
+ $form .= "<div id='mw-notebox'>\n";
+ $form .= "<p>".wfMsgHtml( 'revreview-notes' ) . "</p>\n";
+ $form .= Xml::openElement( 'textarea', array('name' => 'wpNotes', 'id' => 'wpNotes',
+ 'class' => 'fr-notes-box', 'rows' => '2', 'cols' => '80') ) .
+ htmlspecialchars( $encNotes ) .
+ Xml::closeElement('textarea') . "\n";
+ $form .= "</div>\n";
+ }
+ # Get versions of templates/files used
+ $imageParams = $templateParams = $fileVersion = '';
+ if( $useCurrent ) {
+ # Get parsed current version
+ $parserCache = ParserCache::singleton();
+ $article = $this->article;
+ $currentOutput = $parserCache->get( $article, $wgUser );
+ if( $currentOutput == false ) {
+ global $wgParser, $wgEnableParserCache;
+ $text = $article->getContent();
+ $title = $article->getTitle();
+ $options = FlaggedRevs::makeParserOptions();
+ $currentOutput = $wgParser->parse( $text, $title, $options );
+ # Might as well save the cache while we're at it
+ if( $wgEnableParserCache )
+ $parserCache->save( $currentOutput, $article, $wgUser );
+ }
+ $templateIDs = $currentOutput->mTemplateIds;
+ $imageSHA1Keys = $currentOutput->fr_ImageSHA1Keys;
+ } else {
+ $templateIDs = $wgOut->mTemplateIds;
+ $imageSHA1Keys = $wgOut->fr_ImageSHA1Keys;
+ }
+ list($templateParams,$imageParams,$fileVersion) =
+ FlaggedRevs::getIncludeParams( $this->article, $templateIDs, $imageSHA1Keys );
+
+ $form .= Xml::openElement( 'span', array('style' => 'white-space: nowrap;') );
+ # Hide comment if needed
+ if( !$disabled ) {
+ if( count(FlaggedRevs::getDimensions()) > 1 )
+ $form .= "<br/>"; // Don't put too much on one line
+ $form .= "<span id='mw-commentbox' style='clear:both'>" .
+ Xml::inputLabel( wfMsg('revreview-log'), 'wpReason', 'wpReason', 40, '',
+ array('class' => 'fr-comment-box') ) . "&nbsp;&nbsp;&nbsp;</span>";
+ }
+ $form .= Xml::submitButton( wfMsg('revreview-submit'),
+ array(
+ 'id' => 'submitreview', 'accesskey' => wfMsg('revreview-ak-review'),
+ 'title' => wfMsg('revreview-tt-review').' ['.wfMsg('revreview-ak-review').']'
+ ) + $toggle
+ );
+ $form .= Xml::closeElement( 'span' );
+
+ $form .= Xml::closeElement( 'div' ) . "\n";
+
+ # Show stability log if there is anything interesting...
+ if( $this->article->isPageLocked() ) {
+ $loglist = new LogEventsList( $wgUser->getSkin(), $wgOut, LogEventsList::NO_ACTION_LINK );
+ $pager = new LogPager( $loglist, 'stable', '', $this->article->getTitle()->getPrefixedDBKey() );
+ $pager->mLimit = 1; // top item
+ if( ($logBody = $pager->getBody()) ) {
+ $form .= "<div><ul style='list-style:none; margin: 0;'>$logBody</ul></div>";
+ }
+ }
+
+ # Hidden params
+ $form .= Xml::hidden( 'title', $reviewTitle->getPrefixedText() ) . "\n";
+ $form .= Xml::hidden( 'target', $this->article->getTitle()->getPrefixedDBKey() ) . "\n";
+ $form .= Xml::hidden( 'oldid', $id ) . "\n";
+ $form .= Xml::hidden( 'action', 'submit') . "\n";
+ $form .= Xml::hidden( 'wpEditToken', $wgUser->editToken() ) . "\n";
+ # Add review parameters
+ $form .= Xml::hidden( 'templateParams', $templateParams ) . "\n";
+ $form .= Xml::hidden( 'imageParams', $imageParams ) . "\n";
+ $form .= Xml::hidden( 'fileVersion', $fileVersion ) . "\n";
+ # Pass this in if given; useful for new page patrol
+ $form .= Xml::hidden( 'rcid', $wgRequest->getVal('rcid') ) . "\n";
+ # Special token to discourage fiddling...
+ $checkCode = RevisionReview::validationKey( $templateParams, $imageParams, $fileVersion, $id );
+ $form .= Xml::hidden( 'validatedParams', $checkCode ) . "\n";
+
+ $form .= Xml::closeElement( 'fieldset' );
+ $form .= Xml::closeElement( 'form' );
+ # Place form at the correct position specified by $top
+ if( $top ) {
+ $wgOut->prependHTML( $form );
+ } else {
+ $data .= $form;
+ }
+ return true;
+ }
+
+ /**
+ * Updates parser cache output to included needed versioning params.
+ */
+ public function maybeUpdateMainCache( &$outputDone, &$pcache ) {
+ global $wgUser, $wgRequest;
+ $this->load();
+
+ $action = $wgRequest->getVal( 'action', 'view' );
+ if( $action == 'purge' )
+ return true; // already purging!
+ # Only trigger on article view for content pages, not for protect/delete/hist
+ if( !self::isViewAction($action) || !$wgUser->isAllowed( 'review' ) )
+ return true;
+ if( !$this->article->exists() || !$this->article->isReviewable() )
+ return true;
+
+ $parserCache = ParserCache::singleton();
+ $parserOut = $parserCache->get( $this->article, $wgUser );
+ if( $parserOut ) {
+ # Clear older, incomplete, cached versions
+ # We need the IDs of templates and timestamps of images used
+ if( !isset($parserOut->fr_newestTemplateID) || !isset($parserOut->fr_newestImageTime) )
+ $this->article->getTitle()->invalidateCache();
+ }
+ return true;
+ }
+}

Modified: trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php
===================================================================
--- trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php 2009-11-04 19:48:25 UTC (rev 58563)
+++ trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php 2009-11-04 20:23:24 UTC (rev 58564)
@@ -11,7 +11,7 @@
if( !$wgOut->isArticleRelated() ) {
return self::InjectStyleForSpecial(); // try special page CSS?
}
- $fa = FlaggedArticle::getGlobalInstance();
+ $fa = FlaggedArticleView::globalArticleInstance();
# Try to only add to relevant pages
if( !$fa || !$fa->isReviewable(true) ) {
return true;
@@ -31,7 +31,7 @@

public static function injectGlobalJSVars( &$globalVars ) {
global $wgJsMimeType;
- $fa = FlaggedArticle::getGlobalInstance();
+ $fa = FlaggedArticleView::globalArticleInstance();
# Try to only add to relevant pages
if( !$fa || !$fa->isReviewable(true) ) {
return true;
@@ -173,10 +173,9 @@
if( $wgFlaggedRevsAutoReviewNew && $user->isAllowed('autoreview')
&& !FlaggedRevs::isPageReviewable( $otitle ) )
{
- $article = new Article( $ntitle );
$rev = Revision::newFromTitle( $ntitle );
// Treat this kind of like a new page...
- FlaggedRevs::autoReviewEdit( $article, $user, $rev->getText(), $rev );
+ FlaggedRevs::autoReviewEdit( $fa, $user, $rev->getText(), $rev );
return true; // pending list handled
} else if( $fa->getStableRev(FR_MASTER) ) {
return true; // nothing to do
@@ -745,8 +744,9 @@
# config and URL params, the page can be overriden.
$flaggedArticle = FlaggedArticle::getTitleInstance( $title );
if( !empty($wgTitle) && $wgTitle->equals( $title ) ) {
+ $view = FlaggedArticleView::singleton();
// Cache stable version while we are at it.
- if( $flaggedArticle->pageOverride() && $flaggedArticle->getStableRev() ) {
+ if( $view->pageOverride() && $flaggedArticle->getStableRev() ) {
$result = true;
}
} else {
@@ -1490,34 +1490,36 @@
}

public static function imagePageFindFile( $imagePage, &$normalFile, &$displayFile ) {
- $fa = FlaggedArticle::getInstance( $imagePage );
- $fa->imagePageFindFile( $normalFile, $displayFile );
+ $view = FlaggedArticleView::singleton();
+ $view->imagePageFindFile( $normalFile, $displayFile );
return true;
}

public static function setActionTabs( $skin, &$contentActions ) {
- $fa = FlaggedArticle::getGlobalInstance();
- if( $fa ) {
- $fa->setActionTabs( $skin, $contentActions );
- $fa->setViewTabs( $skin, $contentActions );
+ // Note: $wgArticle sometimes not set here
+ if( FlaggedArticleView::globalArticleInstance() != null ) {
+ $view = FlaggedArticleView::singleton();
+ $view->setActionTabs( $skin, $contentActions );
+ $view->setViewTabs( $skin, $contentActions );
}
return true;
}

public static function setNavigation( $skin, &$links ) {
- $fa = FlaggedArticle::getGlobalInstance();
- if( $fa ) {
- $fa->setActionTabs( $skin, $links['actions'] );
- $fa->setViewTabs( $skin, $links['views'] );
+ // Note: $wgArticle sometimes not set here
+ if( FlaggedArticleView::globalArticleInstance() != null ) {
+ $view = FlaggedArticleView::singleton();
+ $view->setActionTabs( $skin, $links['actions'] );
+ $view->setViewTabs( $skin, $links['views'] );
}
return true;
}

public static function onArticleViewHeader( &$article, &$outputDone, &$pcache ) {
- $flaggedArticle = FlaggedArticle::getInstance( $article );
- $flaggedArticle->maybeUpdateMainCache( $outputDone, $pcache );
- $flaggedArticle->addStableLink( $outputDone, $pcache );
- $flaggedArticle->setPageContent( $outputDone, $pcache );
+ $view = FlaggedArticleView::singleton();
+ $view->maybeUpdateMainCache( $outputDone, $pcache );
+ $view->addStableLink( $outputDone, $pcache );
+ $view->setPageContent( $outputDone, $pcache );
return true;
}

@@ -1539,8 +1541,9 @@
}
$fa = FlaggedArticle::getTitleInstance( $title );
if( $srev = $fa->getStableRev() ) {
+ $view = FlaggedArticleView::singleton();
# If synced, nothing special here...
- if( $srev->getRevId() != $article->getLatest() && $fa->pageOverride() ) {
+ if( $srev->getRevId() != $article->getLatest() && $view->pageOverride() ) {
$text = $srev->getRevText();
$redirect = $fa->followRedirectText( $text );
if( $redirect ) {
@@ -1557,19 +1560,24 @@
}

public static function addToEditView( &$editPage ) {
- return FlaggedArticle::getInstance( $editPage->mArticle )->addToEditView( $editPage );
+ $view = FlaggedArticleView::singleton();
+ $view->addToEditView( $editPage );
+ return true;
}

public static function onCategoryPageView( &$category ) {
- return FlaggedArticle::getInstance( $category )->addToCategoryView();
+ $view = FlaggedArticleView::singleton();
+ $view->addToCategoryView();
+ return true;
}

public static function onSkinAfterContent( &$data ) {
global $wgOut;
- if( $wgOut->isArticleRelated() && ($fa = FlaggedArticle::getGlobalInstance()) ) {
- $fa->addReviewNotes( $data );
- $fa->addReviewForm( $data );
- $fa->addVisibilityLink( $data );
+ if( $wgOut->isArticleRelated() && FlaggedArticleView::globalArticleInstance() != null ) {
+ $view = FlaggedArticleView::singleton();
+ $view->addReviewNotes( $data );
+ $view->addReviewForm( $data );
+ $view->addVisibilityLink( $data );
}
return true;
}
@@ -1696,7 +1704,9 @@
}

public static function injectReviewDiffURLParams( $article, &$sectionAnchor, &$extraQuery ) {
- return FlaggedArticle::getInstance( $article )->injectReviewDiffURLParams( $sectionAnchor, $extraQuery );
+ $view = FlaggedArticleView::singleton();
+ $view->injectReviewDiffURLParams( $sectionAnchor, $extraQuery );
+ return true;
}

public static function checkDiffUrl( $titleObj, &$mOldid, &$mNewid, $old, $new ) {
@@ -1712,15 +1722,17 @@

public static function onDiffViewHeader( $diff, $oldRev, $newRev ) {
self::injectStyleAndJS();
- $flaggedArticle = FlaggedArticle::getTitleInstance( $diff->getTitle() );
- $flaggedArticle->setViewFlags( $diff, $oldRev, $newRev );
- $flaggedArticle->addDiffLink( $diff, $oldRev, $newRev );
- $flaggedArticle->addDiffNoticeAndIncludes( $diff, $oldRev, $newRev );
+ $view = FlaggedArticleView::singleton();
+ $view->setViewFlags( $diff, $oldRev, $newRev );
+ $view->addDiffLink( $diff, $oldRev, $newRev );
+ $view->addDiffNoticeAndIncludes( $diff, $oldRev, $newRev );
return true;
}

public static function addRevisionIDField( $editPage, $out ) {
- return FlaggedArticle::getInstance( $editPage->mArticle )->addRevisionIDField( $editPage, $out );
+ $view = FlaggedArticleView::singleton();
+ $view->addRevisionIDField( $editPage, $out );
+ return true;
}

public static function addReviewCheck( $editPage, &$checkboxes, &$tabindex ) {

Modified: trunk/extensions/FlaggedRevs/FlaggedRevs.php
===================================================================
--- trunk/extensions/FlaggedRevs/FlaggedRevs.php 2009-11-04 19:48:25 UTC (rev 58563)
+++ trunk/extensions/FlaggedRevs/FlaggedRevs.php 2009-11-04 20:23:24 UTC (rev 58564)
@@ -314,7 +314,9 @@

# Load general UI
$wgAutoloadClasses['FlaggedRevsXML'] = $dir . 'FlaggedRevsXML.php';
-# Load context article stuff
+# Load web request context article stuff
+$wgAutoloadClasses['FlaggedArticleView'] = $dir . 'FlaggedArticleView.php';
+# Load FlaggedArticle object class
$wgAutoloadClasses['FlaggedArticle'] = $dir . 'FlaggedArticle.php';
# Load FlaggedRevision object class
$wgAutoloadClasses['FlaggedRevision'] = $dir . 'FlaggedRevision.php';



_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS[at]lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Wikipedia mediawiki-cvs RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact lists@gossamer-threads.com
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.