Index: trunk/phase3/t/inc/SearchUpdate.t |
— | — | @@ -1,61 +1,61 @@ |
2 | | -#!/usr/bin/env php
|
3 | | -<?php
|
4 | | -
|
5 | | -require 't/Test.php';
|
6 | | -
|
7 | | -plan( 4 );
|
8 | | -
|
9 | | -define( 'MEDIAWIKI', 1 );
|
10 | | -require 'includes/Defines.php';
|
11 | | -require 'includes/ProfilerStub.php';
|
12 | | -require 'includes/AutoLoader.php';
|
13 | | -require 'LocalSettings.php';
|
14 | | -
|
15 | | -require 't/DatabaseMock.inc';
|
16 | | -
|
17 | | -$wgSearchType = 'MockSearch';
|
18 | | -
|
19 | | -require 'includes/Setup.php';
|
20 | | -
|
21 | | -
|
22 | | -class MockSearch extends SearchEngine {
|
23 | | - public static $id;
|
24 | | - public static $title;
|
25 | | - public static $text;
|
26 | | -
|
27 | | - public function __construct( $db ) {
|
28 | | - }
|
29 | | -
|
30 | | - public function update( $id, $title, $text ) {
|
31 | | - self::$id = $id;
|
32 | | - self::$title = $title;
|
33 | | - self::$text = $text;
|
34 | | - }
|
35 | | -}
|
36 | | -
|
37 | | -function update( $text, $title = 'Test', $id = 1 ) {
|
38 | | - $u = new SearchUpdate( $id, $title, $text );
|
39 | | - $u->doUpdate();
|
40 | | - return array( MockSearch::$title, MockSearch::$text );
|
41 | | -}
|
42 | | -
|
43 | | -function updateText( $text ) {
|
44 | | - list( $title, $resultText ) = update( $text );
|
45 | | - $resultText = trim( $resultText ); // abstract from some implementation details
|
46 | | - return $resultText;
|
47 | | -}
|
48 | | -
|
49 | | -is( updateText( '<div>TeSt</div>' ), 'test', 'HTML stripped, text lowercased' );
|
50 | | -
|
51 | | -is( updateText( <<<EOT
|
52 | | -<table style="color:red; font-size:100px">
|
53 | | - <tr class="scary"><td><div>foo</div></td><tr>bar</td></tr>
|
54 | | - <tr><td>boz</td><tr>quux</td></tr>
|
55 | | -</table>
|
56 | | -EOT
|
57 | | -), 'foo bar boz quux', 'Stripping HTML tables' );
|
58 | | -
|
59 | | -is( updateText( 'a > b' ), 'a b', 'Handle unclosed tags' );
|
60 | | -
|
61 | | -$text = str_pad( "foo <barbarbar \n", 10000, 'x' );
|
| 2 | +#!/usr/bin/env php |
| 3 | +<?php |
| 4 | + |
| 5 | +require 't/Test.php'; |
| 6 | + |
| 7 | +plan( 4 ); |
| 8 | + |
| 9 | +define( 'MEDIAWIKI', 1 ); |
| 10 | +require 'includes/Defines.php'; |
| 11 | +require 'includes/ProfilerStub.php'; |
| 12 | +require 'includes/AutoLoader.php'; |
| 13 | +require 'LocalSettings.php'; |
| 14 | + |
| 15 | +require 't/DatabaseMock.inc'; |
| 16 | + |
| 17 | +$wgSearchType = 'MockSearch'; |
| 18 | + |
| 19 | +require 'includes/Setup.php'; |
| 20 | + |
| 21 | + |
| 22 | +class MockSearch extends SearchEngine { |
| 23 | + public static $id; |
| 24 | + public static $title; |
| 25 | + public static $text; |
| 26 | + |
| 27 | + public function __construct( $db ) { |
| 28 | + } |
| 29 | + |
| 30 | + public function update( $id, $title, $text ) { |
| 31 | + self::$id = $id; |
| 32 | + self::$title = $title; |
| 33 | + self::$text = $text; |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +function update( $text, $title = 'Test', $id = 1 ) { |
| 38 | + $u = new SearchUpdate( $id, $title, $text ); |
| 39 | + $u->doUpdate(); |
| 40 | + return array( MockSearch::$title, MockSearch::$text ); |
| 41 | +} |
| 42 | + |
| 43 | +function updateText( $text ) { |
| 44 | + list( $title, $resultText ) = update( $text ); |
| 45 | + $resultText = trim( $resultText ); // abstract from some implementation details |
| 46 | + return $resultText; |
| 47 | +} |
| 48 | + |
| 49 | +is( updateText( '<div>TeSt</div>' ), 'test', 'HTML stripped, text lowercased' ); |
| 50 | + |
| 51 | +is( updateText( <<<EOT |
| 52 | +<table style="color:red; font-size:100px"> |
| 53 | + <tr class="scary"><td><div>foo</div></td><tr>bar</td></tr> |
| 54 | + <tr><td>boz</td><tr>quux</td></tr> |
| 55 | +</table> |
| 56 | +EOT |
| 57 | +), 'foo bar boz quux', 'Stripping HTML tables' ); |
| 58 | + |
| 59 | +is( updateText( 'a > b' ), 'a b', 'Handle unclosed tags' ); |
| 60 | + |
| 61 | +$text = str_pad( "foo <barbarbar \n", 10000, 'x' ); |
62 | 62 | ok( updateText( $text ) != '', 'Bug 18609' ); |
\ No newline at end of file |
Property changes on: trunk/phase3/t/inc/SearchUpdate.t |
___________________________________________________________________ |
Name: svn:eol-style |
63 | 63 | + native |
Index: trunk/extensions/FlaggedRevs/FlaggedArticleView.php |
— | — | @@ -1,1522 +1,1522 @@ |
2 | | -<?php
|
3 | | -
|
4 | | -class FlaggedArticleView {
|
5 | | - protected $isDiffFromStable = false;
|
6 | | - protected $isMultiPageDiff = false;
|
7 | | - protected $reviewNotice = '';
|
8 | | - protected $reviewNotes = '';
|
9 | | - protected $article = null;
|
10 | | - protected $loaded = false;
|
11 | | -
|
12 | | - protected static $instance = null;
|
13 | | -
|
14 | | - /*
|
15 | | - * Get the FlaggedArticleView for this request
|
16 | | - */
|
17 | | - public static function singleton() {
|
18 | | - if( self::$instance == null ) {
|
19 | | - self::$instance = new self();
|
20 | | - }
|
21 | | - return self::$instance;
|
22 | | - }
|
23 | | - protected function __construct() {}
|
24 | | -
|
25 | | - /*
|
26 | | - * Load the global FlaggedArticle instance
|
27 | | - */
|
28 | | - protected function load() {
|
29 | | - if( !$this->loaded ) {
|
30 | | - $this->article = self::globalArticleInstance();
|
31 | | - if( $this->article == null ) {
|
32 | | - throw new MWException( 'FlaggedArticleViewer has no context article!' );
|
33 | | - }
|
34 | | - }
|
35 | | - }
|
36 | | -
|
37 | | - /**
|
38 | | - * Get the FlaggedArticle instance associated with $wgArticle/$wgTitle,
|
39 | | - * or false if there isn't such a title
|
40 | | - */
|
41 | | - public static function globalArticleInstance() {
|
42 | | - global $wgTitle;
|
43 | | - if( !empty( $wgTitle ) ) {
|
44 | | - return FlaggedArticle::getTitleInstance( $wgTitle );
|
45 | | - }
|
46 | | - return null;
|
47 | | - }
|
48 | | -
|
49 | | - /**
|
50 | | - * Does the config and current URL params allow
|
51 | | - * for overriding by stable revisions?
|
52 | | - */
|
53 | | - public function pageOverride() {
|
54 | | - global $wgUser, $wgRequest;
|
55 | | - $this->load();
|
56 | | - # This only applies to viewing content pages
|
57 | | - $action = $wgRequest->getVal( 'action', 'view' );
|
58 | | - if( !self::isViewAction($action) || !$this->article->isReviewable() )
|
59 | | - return false;
|
60 | | - # Does not apply to diffs/old revision...
|
61 | | - if( $wgRequest->getVal('oldid') || $wgRequest->getVal('diff') )
|
62 | | - return false;
|
63 | | - # Explicit requests for a certain stable version handled elsewhere...
|
64 | | - if( $wgRequest->getVal('stableid') )
|
65 | | - return false;
|
66 | | - # Check user preferences
|
67 | | - if( $wgUser->getOption('flaggedrevsstable') )
|
68 | | - return !( $wgRequest->getIntOrNull('stable') === 0 );
|
69 | | - # Get page configuration
|
70 | | - $config = $this->article->getVisibilitySettings();
|
71 | | - # Does the stable version override the current one?
|
72 | | - if( $config['override'] ) {
|
73 | | - if( FlaggedRevs::ignoreDefaultVersion() ) {
|
74 | | - return ( $wgRequest->getIntOrNull('stable') === 1 );
|
75 | | - }
|
76 | | - # Viewer sees stable by default
|
77 | | - return !( $wgRequest->getIntOrNull('stable') === 0 );
|
78 | | - # We are explicity requesting the stable version?
|
79 | | - } elseif( $wgRequest->getIntOrNull('stable') === 1 ) {
|
80 | | - return true;
|
81 | | - }
|
82 | | - return false;
|
83 | | - }
|
84 | | -
|
85 | | - /**
|
86 | | - * Is this user shown the stable version by default for this page?
|
87 | | - * @returns bool
|
88 | | - */
|
89 | | - public function showStableByDefaultUser() {
|
90 | | - $this->load();
|
91 | | - $config = $this->article->getVisibilitySettings(); // page configuration
|
92 | | - return ( $config['override'] && !FlaggedRevs::ignoreDefaultVersion() );
|
93 | | - }
|
94 | | -
|
95 | | - /**
|
96 | | - * Is this user shown the diff-to-stable on edit for this page?
|
97 | | - * @returns bool
|
98 | | - */
|
99 | | - public function showDiffOnEditUser() {
|
100 | | - global $wgUser;
|
101 | | - $this->load();
|
102 | | - return ( $wgUser->isAllowed('review') || $this->showStableByDefaultUser() );
|
103 | | - }
|
104 | | -
|
105 | | - /**
|
106 | | - * Is this a view page action?
|
107 | | - * @param $action string
|
108 | | - * @returns bool
|
109 | | - */
|
110 | | - protected static function isViewAction( $action ) {
|
111 | | - return ( $action == 'view' || $action == 'purge' || $action == 'render' || $action == 'historysubmit' );
|
112 | | - }
|
113 | | -
|
114 | | - /**
|
115 | | - * Output review notice
|
116 | | - */
|
117 | | - protected function displayTag() {
|
118 | | - global $wgOut, $wgRequest;
|
119 | | - $this->load();
|
120 | | - // UI may be limited to unobtrusive patrolling system
|
121 | | - if( $wgRequest->getVal('stableid') || !$this->article->limitedUI() ) {
|
122 | | - $wgOut->appendSubtitle( $this->reviewNotice );
|
123 | | - }
|
124 | | - return true;
|
125 | | - }
|
126 | | -
|
127 | | -
|
128 | | - /**
|
129 | | - * Add a stable link when viewing old versions of an article that
|
130 | | - * have been reviewed. (e.g. for &oldid=x urls)
|
131 | | - */
|
132 | | - public function addStableLink() {
|
133 | | - global $wgRequest, $wgOut, $wgLang;
|
134 | | - $this->load();
|
135 | | - # Only for viewing old versions. UI may be limited to unobtrusive patrolling system.
|
136 | | - if( !$wgRequest->getVal('oldid') || $this->article->limitedUI() )
|
137 | | - return true;
|
138 | | - # We may have nav links like "direction=prev&oldid=x"
|
139 | | - $revID = $this->article->getOldIDFromRequest();
|
140 | | - $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $revID );
|
141 | | - # Give a notice if this rev ID corresponds to a reviewed version...
|
142 | | - if( !is_null($frev) ) {
|
143 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
144 | | - $time = $wgLang->date( $frev->getTimestamp(), true );
|
145 | | - $flags = $frev->getTags();
|
146 | | - $quality = FlaggedRevs::isQuality( $flags );
|
147 | | - $msg = $quality ? 'revreview-quality-source' : 'revreview-basic-source';
|
148 | | - $tag = wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time );
|
149 | | - # Hide clutter
|
150 | | - if( !FlaggedRevs::useSimpleUI() && !empty($flags) ) {
|
151 | | - $tag .= " " . FlaggedRevsXML::ratingToggle() .
|
152 | | - "<span id='mw-revisionratings' style='display:block;'><br/>" .
|
153 | | - wfMsgHtml('revreview-oldrating') .
|
154 | | - FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
|
155 | | - }
|
156 | | - $tag = "<div id='mw-revisiontag-old' class='flaggedrevs_notice plainlinks noprint'>$tag</div>";
|
157 | | - $wgOut->addHTML( $tag );
|
158 | | - }
|
159 | | - return true;
|
160 | | - }
|
161 | | -
|
162 | | - /**
|
163 | | - * Replaces a page with the last stable version if possible
|
164 | | - * Adds stable version status/info tags and notes
|
165 | | - * Adds a quick review form on the bottom if needed
|
166 | | - */
|
167 | | - public function setPageContent( &$outputDone, &$pcache ) {
|
168 | | - global $wgRequest, $wgOut, $wgUser, $wgLang, $wgContLang;
|
169 | | - $this->load();
|
170 | | - # Only trigger on article view for content pages, not for protect/delete/hist...
|
171 | | - $action = $wgRequest->getVal( 'action', 'view' );
|
172 | | - if( !self::isViewAction($action) || !$this->article->exists() )
|
173 | | - return true;
|
174 | | - # Do not clutter up diffs any further and leave archived versions alone...
|
175 | | - if( $wgRequest->getVal('diff') || $wgRequest->getVal('oldid') ) {
|
176 | | - return true;
|
177 | | - }
|
178 | | - # Only trigger for reviewable pages
|
179 | | - if( !$this->article->isReviewable() ) {
|
180 | | - return true;
|
181 | | - }
|
182 | | - # Load required messages
|
183 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
184 | | - $simpleTag = $old = $stable = false;
|
185 | | - $tag = $prot = '';
|
186 | | - # Check the newest stable version.
|
187 | | - $frev = $srev = $this->article->getStableRev();
|
188 | | - $stableId = $frev ? $frev->getRevId() : 0;
|
189 | | - # Also, check for any explicitly requested old stable version...
|
190 | | - $reqId = $wgRequest->getVal('stableid');
|
191 | | - if( $reqId === "best" ) {
|
192 | | - $reqId = FlaggedRevs::getPrimeFlaggedRevId( $this->article );
|
193 | | - }
|
194 | | - if( $stableId && $reqId ) {
|
195 | | - # Treat requesting the stable version by ID as &stable=1
|
196 | | - if( $reqId != $stableId ) {
|
197 | | - $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId, FR_TEXT );
|
198 | | - $old = true; // old reviewed version requested by ID
|
199 | | - if( !$frev ) {
|
200 | | - $wgOut->addWikiText( wfMsg('revreview-invalid') );
|
201 | | - $wgOut->returnToMain( false, $this->article->getTitle() );
|
202 | | - # Tell MW that parser output is done
|
203 | | - $outputDone = true;
|
204 | | - $pcache = false;
|
205 | | - return true;
|
206 | | - }
|
207 | | - } else {
|
208 | | - $stable = true; // stable version requested by ID
|
209 | | - }
|
210 | | - }
|
211 | | - // Is the page config altered?
|
212 | | - if( $this->article->isPageLocked() ) {
|
213 | | - $prot = "<span class='fr-icon-locked' title=\"".
|
214 | | - wfMsgHtml('revreview-locked-title')."\"></span>";
|
215 | | - } elseif( $this->article->isPageUnlocked() ) {
|
216 | | - $prot = "<span class='fr-icon-unlocked' title=\"".
|
217 | | - wfMsgHtml('revreview-unlocked-title')."\"></span>";
|
218 | | - }
|
219 | | - // RTL langauges
|
220 | | - $rtl = $wgContLang->isRTL() ? " rtl" : "";
|
221 | | - // Is there no stable version?
|
222 | | - if( is_null($frev) ) {
|
223 | | - // Add "no reviewed version" tag, but not for printable output.
|
224 | | - if( !$wgOut->isPrintable() ) {
|
225 | | - // Simple icon-based UI
|
226 | | - if( FlaggedRevs::useSimpleUI() ) {
|
227 | | - $msg = $old ? 'revreview-quick-invalid' : 'revreview-quick-none';
|
228 | | - $tag .= "{$prot}<span class='fr-icon-current plainlinks'></span>" .
|
229 | | - wfMsgExt($msg,array('parseinline'));
|
230 | | - $tag = "<div id='mw-revisiontag' class='flaggedrevs_short{$rtl} plainlinks noprint'>$tag</div>";
|
231 | | - $this->reviewNotice .= $tag;
|
232 | | - // Standard UI
|
233 | | - } else {
|
234 | | - $msg = $old ? 'revreview-invalid' : 'revreview-noflagged';
|
235 | | - $tag = "<div id='mw-revisiontag' class='flaggedrevs_notice plainlinks noprint'>" .
|
236 | | - "{$prot}<span class='fr-icon-current plainlinks'></span>" .
|
237 | | - wfMsgExt($msg, array('parseinline')) . "</div>";
|
238 | | - $this->reviewNotice .= $tag;
|
239 | | - }
|
240 | | - }
|
241 | | - # Show notice bar/icon
|
242 | | - $this->displayTag();
|
243 | | - return true;
|
244 | | - }
|
245 | | - # Get flags and date
|
246 | | - $time = $wgLang->date( $frev->getTimestamp(), true );
|
247 | | - $flags = $frev->getTags();
|
248 | | - # Get quality level
|
249 | | - $quality = FlaggedRevs::isQuality( $flags );
|
250 | | - $pristine = FlaggedRevs::isPristine( $flags );
|
251 | | - // Looking at some specific old stable revision ("&stableid=x")
|
252 | | - // set to override given the relevant conditions. If the user is
|
253 | | - // requesting the stable revision ("&stableid=x"), defer to override
|
254 | | - // behavior below, since it is the same as ("&stable=1").
|
255 | | - if( $old ) {
|
256 | | - $this->showOldReviewedVersion( $srev, $frev, $tag, $prot );
|
257 | | - $outputDone = true; # Tell MW that parser output is done
|
258 | | - $pcache = false;
|
259 | | - // Looking at some specific old revision (&oldid=x) or if FlaggedRevs is not
|
260 | | - // set to override given the relevant conditions (like &stable=0).
|
261 | | - } elseif( !$stable && !$this->pageOverride() ) {
|
262 | | - $this->showRegularVersion( $srev, $tag, $prot );
|
263 | | - // The relevant conditions are met to override the page with the stable version.
|
264 | | - } else {
|
265 | | - $this->showStableVersion( $srev, $tag, $prot );
|
266 | | - $outputDone = true; # Tell MW that parser output is done
|
267 | | - $pcache = false;
|
268 | | - }
|
269 | | - # Some checks for which tag CSS to use
|
270 | | - if( FlaggedRevs::useSimpleUI() ) $tagClass = 'flaggedrevs_short';
|
271 | | - elseif( $simpleTag ) $tagClass = 'flaggedrevs_notice';
|
272 | | - elseif( $pristine ) $tagClass = 'flaggedrevs_pristine';
|
273 | | - elseif( $quality ) $tagClass = 'flaggedrevs_quality';
|
274 | | - else $tagClass = 'flaggedrevs_basic';
|
275 | | - # Wrap tag contents in a div
|
276 | | - if( $tag != '' ) {
|
277 | | - $tag = "<div id='mw-revisiontag' class='{$tagClass}{$rtl} plainlinks noprint'>$tag</div>";
|
278 | | - $this->reviewNotice .= $tag;
|
279 | | - }
|
280 | | - # Show notice bar/icon
|
281 | | - $this->displayTag();
|
282 | | -
|
283 | | - return true;
|
284 | | - }
|
285 | | -
|
286 | | - /**
|
287 | | - * @param $srev stable version
|
288 | | - * @param $tag review box/bar info
|
289 | | - * @param $prot protection notice
|
290 | | - * Tag output function must be called by caller
|
291 | | - * Parser cache control deferred to caller
|
292 | | - */
|
293 | | - protected function showRegularVersion( $srev, &$tag, $prot ) {
|
294 | | - global $wgUser, $wgOut, $wgLang, $wgRequest;
|
295 | | - $this->load();
|
296 | | - $flags = $srev->getTags();
|
297 | | - $time = $wgLang->date( $srev->getTimestamp(), true );
|
298 | | - # Get quality level
|
299 | | - $quality = FlaggedRevs::isQuality( $flags );
|
300 | | - $pristine = FlaggedRevs::isPristine( $flags );
|
301 | | - $revsSince = FlaggedRevs::getRevCountSince( $this->article, $srev->getRevId() );
|
302 | | - # Get stable version sync status
|
303 | | - $synced = FlaggedRevs::stableVersionIsSynced( $srev, $this->article );
|
304 | | - if( $synced ) {
|
305 | | - $this->getReviewNotes( $srev ); // Still the same
|
306 | | - } else {
|
307 | | - $this->maybeShowTopDiff( $srev, $quality ); // user may want diff (via prefs)
|
308 | | - }
|
309 | | - $pending = '';
|
310 | | - # Give notice to newer users if an unreviewed edit was completed...
|
311 | | - if( !$synced && $wgRequest->getVal('shownotice') && !$wgUser->isAllowed('review') ) {
|
312 | | - $tooltip = wfMsgHtml('revreview-draft-title');
|
313 | | - $pending = "{$prot}<span class='fr-icon-current' title=\"{$tooltip}\"></span>" .
|
314 | | - wfMsgExt('revreview-edited',array('parseinline'),$srev->getRevId(),$revsSince);
|
315 | | - $pending = "<div id='mw-reviewnotice' class='flaggedrevs_preview plainlinks'>$pending</div>";
|
316 | | - # Notice should always use subtitle
|
317 | | - $this->reviewNotice = $pending;
|
318 | | - }
|
319 | | - # If they are synced, do special styling
|
320 | | - $simpleTag = !$synced;
|
321 | | - # Construct some tagging for non-printable outputs. Note that the pending
|
322 | | - # notice has all this info already, so don't do this if we added that already.
|
323 | | - if( !$wgOut->isPrintable() && !$pending && !($this->article->lowProfileUI() && $synced) ) {
|
324 | | - $class = 'fr-icon-current'; // default
|
325 | | - $tooltip = 'revreview-draft-title';
|
326 | | - // Simple icon-based UI
|
327 | | - if( FlaggedRevs::useSimpleUI() ) {
|
328 | | - if( $synced ) {
|
329 | | - $msg = $quality ? 'revreview-quick-quality-same' : 'revreview-quick-basic-same';
|
330 | | - $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
|
331 | | - $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
|
332 | | - $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince );
|
333 | | - } else {
|
334 | | - $msg = $quality ? 'revreview-quick-see-quality' : 'revreview-quick-see-basic';
|
335 | | - $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince );
|
336 | | - }
|
337 | | - $tooltip = wfMsgHtml($tooltip);
|
338 | | - $msgHTML = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>$msgHTML";
|
339 | | - $tag .= FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML, $revsSince,
|
340 | | - $synced, $synced, false );
|
341 | | - // Standard UI
|
342 | | - } else {
|
343 | | - if( $synced ) {
|
344 | | - $msg = $quality ? 'revreview-quality-same' : 'revreview-basic-same';
|
345 | | - $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
|
346 | | - $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
|
347 | | - $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(),
|
348 | | - $time, $revsSince );
|
349 | | - } else {
|
350 | | - $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic';
|
351 | | - $msg .= ($revsSince == 0) ? '-i' : '';
|
352 | | - $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(),
|
353 | | - $time, $revsSince );
|
354 | | - }
|
355 | | - $tooltip = wfMsgHtml($tooltip);
|
356 | | - $tag .= "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" . $msgHTML;
|
357 | | - # Hide clutter
|
358 | | - if( !empty($flags) ) {
|
359 | | - $tag .= " " . FlaggedRevsXML::ratingToggle();
|
360 | | - $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" .
|
361 | | - wfMsgHtml('revreview-oldrating') . FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
|
362 | | - }
|
363 | | - }
|
364 | | - }
|
365 | | - # Index the stable version only if it is the default
|
366 | | - if( $this->article->showStableByDefault() ) {
|
367 | | - $wgOut->setRobotPolicy( 'noindex,nofollow' );
|
368 | | - }
|
369 | | - }
|
370 | | -
|
371 | | - /**
|
372 | | - * @param $srev stable version
|
373 | | - * @param $frev selected flagged revision
|
374 | | - * @param $tag review box/bar info
|
375 | | - * @param $prot protection notice
|
376 | | - * Tag output function must be called by caller
|
377 | | - * Parser cache control deferred to caller
|
378 | | - */
|
379 | | - protected function showOldReviewedVersion( $srev, $frev, &$tag, $prot ) {
|
380 | | - global $wgOut, $wgLang;
|
381 | | - $this->load();
|
382 | | - $flags = $frev->getTags();
|
383 | | - $time = $wgLang->date( $frev->getTimestamp(), true );
|
384 | | - # Set display revision ID
|
385 | | - $wgOut->setRevisionId( $frev->getRevId() );
|
386 | | - # Get quality level
|
387 | | - $quality = FlaggedRevs::isQuality( $flags );
|
388 | | - $pristine = FlaggedRevs::isPristine( $flags );
|
389 | | - $revsSince = FlaggedRevs::getRevCountSince( $this->article, $srev->getRevId() );
|
390 | | - $text = $frev->getRevText();
|
391 | | - $parserOut = FlaggedRevs::parseStableText( $this->article, $text, $frev->getRevId() );
|
392 | | - # Construct some tagging for non-printable outputs. Note that the pending
|
393 | | - # notice has all this info already, so don't do this if we added that already.
|
394 | | - if( !$wgOut->isPrintable() ) {
|
395 | | - $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
|
396 | | - $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
|
397 | | - $tooltip = wfMsgHtml($tooltip);
|
398 | | - // Simple icon-based UI
|
399 | | - if( FlaggedRevs::useSimpleUI() ) {
|
400 | | - $msg = $quality ? 'revreview-quick-quality-old' : 'revreview-quick-basic-old';
|
401 | | - $html = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" .
|
402 | | - wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time );
|
403 | | - $tag = FlaggedRevsXML::prettyRatingBox( $frev, $html, $revsSince,
|
404 | | - true, false, true );
|
405 | | - // Standard UI
|
406 | | - } else {
|
407 | | - $msg = $quality ? 'revreview-quality-old' : 'revreview-basic-old';
|
408 | | - $tag = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" .
|
409 | | - wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time );
|
410 | | - # Hide clutter
|
411 | | - if( !empty($flags) ) {
|
412 | | - $tag .= " " . FlaggedRevsXML::ratingToggle();
|
413 | | - $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" .
|
414 | | - wfMsgHtml('revreview-oldrating') .
|
415 | | - FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
|
416 | | - }
|
417 | | - }
|
418 | | - }
|
419 | | - # Output HTML
|
420 | | - $this->getReviewNotes( $frev );
|
421 | | - $wgOut->addParserOutput( $parserOut );
|
422 | | - # Index the stable version only
|
423 | | - $wgOut->setRobotPolicy( 'noindex,nofollow' );
|
424 | | - }
|
425 | | -
|
426 | | - /**
|
427 | | - * @param $srev stable version
|
428 | | - * @param $tag review box/bar info
|
429 | | - * @param $prot protection notice
|
430 | | - * Tag output function must be called by caller
|
431 | | - * Parser cache control deferred to caller
|
432 | | - */
|
433 | | - protected function showStableVersion( $srev, &$tag, $prot ) {
|
434 | | - global $wgOut, $wgLang, $wgUser;
|
435 | | - $this->load();
|
436 | | - $flags = $srev->getTags();
|
437 | | - $time = $wgLang->date( $srev->getTimestamp(), true );
|
438 | | - # Set display revision ID
|
439 | | - $wgOut->setRevisionId( $srev->getRevId() );
|
440 | | - # Get quality level
|
441 | | - $quality = FlaggedRevs::isQuality( $flags );
|
442 | | - $pristine = FlaggedRevs::isPristine( $flags );
|
443 | | - # We will be looking at the reviewed revision...
|
444 | | - $revsSince = FlaggedRevs::getRevCountSince( $this->article, $srev->getRevId() );
|
445 | | - # Get parsed stable version
|
446 | | - $parserOut = FlaggedRevs::getPageCache( $this->article, $wgUser );
|
447 | | - if( $parserOut == false ) {
|
448 | | - $text = $srev->getRevText();
|
449 | | - $parserOut = FlaggedRevs::parseStableText( $this->article, $text, $srev->getRevId() );
|
450 | | - # Update the stable version cache
|
451 | | - FlaggedRevs::updatePageCache( $this->article, $wgUser, $parserOut );
|
452 | | - }
|
453 | | - $synced = FlaggedRevs::stableVersionIsSynced( $srev, $this->article, $parserOut, null );
|
454 | | - # Construct some tagging
|
455 | | - if( !$wgOut->isPrintable() && !($this->article->lowProfileUI() && $synced) ) {
|
456 | | - $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable';
|
457 | | - $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
|
458 | | - $tooltip = wfMsgHtml($tooltip);
|
459 | | - // Simple icon-based UI
|
460 | | - if( FlaggedRevs::useSimpleUI() ) {
|
461 | | - $msg = $quality ? 'revreview-quick-quality' : 'revreview-quick-basic';
|
462 | | - # uses messages 'revreview-quick-quality-same', 'revreview-quick-basic-same'
|
463 | | - $msg = $synced ? "{$msg}-same" : $msg;
|
464 | | - $html = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" .
|
465 | | - wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince );
|
466 | | - $tag = FlaggedRevsXML::prettyRatingBox( $srev, $html, $revsSince, true, $synced );
|
467 | | - // Standard UI
|
468 | | - } else {
|
469 | | - $msg = $quality ? 'revreview-quality' : 'revreview-basic';
|
470 | | - if( $synced ) {
|
471 | | - # uses messages 'revreview-quality-same', 'revreview-basic-same'
|
472 | | - $msg .= '-same';
|
473 | | - } elseif( $revsSince == 0 ) {
|
474 | | - # uses messages 'revreview-quality-i', 'revreview-basic-i'
|
475 | | - $msg .= '-i';
|
476 | | - }
|
477 | | - $tag = "{$prot}<span class='{$class} plainlinks' title=\"{$tooltip}\"></span>" .
|
478 | | - wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $time, $revsSince );
|
479 | | - if( !empty($flags) ) {
|
480 | | - $tag .= " " . FlaggedRevsXML::ratingToggle();
|
481 | | - $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" .
|
482 | | - FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
|
483 | | - }
|
484 | | - }
|
485 | | - }
|
486 | | - # Output HTML
|
487 | | - $this->getReviewNotes( $srev );
|
488 | | - $wgOut->addParserOutput( $parserOut );
|
489 | | - }
|
490 | | -
|
491 | | - /**
|
492 | | - * @param FlaggedRevision $srev, stable version
|
493 | | - * @param bool $quality, revision is quality
|
494 | | - * @returns bool, diff added to output
|
495 | | - */
|
496 | | - protected function maybeShowTopDiff( $srev, $quality ) {
|
497 | | - global $wgUser, $wgOut, $wgMemc;
|
498 | | - $this->load();
|
499 | | - if( !$wgUser->getBoolOption('flaggedrevsviewdiffs') )
|
500 | | - return false; // nothing to do here
|
501 | | - if( !$wgUser->isAllowed('review') )
|
502 | | - return false; // does not apply to this user
|
503 | | - # Diff should only show for the draft
|
504 | | - $oldid = $this->article->getOldIDFromRequest();
|
505 | | - $latest = $this->article->getLatest();
|
506 | | - if( $oldid && $oldid != $latest ) {
|
507 | | - return false; // not viewing the draft
|
508 | | - }
|
509 | | - # Conditions are met to show diff...
|
510 | | - wfLoadExtensionMessages( 'FlaggedRevs' ); // load required messages
|
511 | | - $leftNote = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
|
512 | | - $rClass = FlaggedRevsXML::getQualityColor( false );
|
513 | | - $lClass = FlaggedRevsXML::getQualityColor( (int)$quality );
|
514 | | - $rightNote = "<span class='$rClass'>[".wfMsgHtml('revreview-draft-title')."]</span>";
|
515 | | - $leftNote = "<span class='$lClass'>[".wfMsgHtml($leftNote)."]</span>";
|
516 | | - # Fetch the stable and draft revision text
|
517 | | - $oText = $srev->getRevText();
|
518 | | - if( $oText === false )
|
519 | | - return false; // deleted revision or something?
|
520 | | - $nText = $this->article->getContent();
|
521 | | - if( $nText === false )
|
522 | | - return false; // deleted revision or something?
|
523 | | - # Build diff at the top of the page
|
524 | | - if( strcmp($oText,$nText) !== 0 ) {
|
525 | | - $diffEngine = new DifferenceEngine();
|
526 | | - $diffEngine->showDiffStyle();
|
527 | | - $n = $this->article->getTitle()->countRevisionsBetween( $srev->getRevId(), $latest );
|
528 | | - if( $n ) {
|
529 | | - $multiNotice = "<tr><td colspan='4' align='center' class='diff-multi'>" .
|
530 | | - wfMsgExt( 'diff-multi', array( 'parse' ), $n )."</td></tr>";
|
531 | | - } else {
|
532 | | - $multiNotice = '';
|
533 | | - }
|
534 | | - $wgOut->addHTML(
|
535 | | - "<div>" .
|
536 | | - "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" .
|
537 | | - "<col class='diff-marker' />" .
|
538 | | - "<col class='diff-content' />" .
|
539 | | - "<col class='diff-marker' />" .
|
540 | | - "<col class='diff-content' />" .
|
541 | | - "<tr>" .
|
542 | | - "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" .
|
543 | | - $leftNote . "</b></td>" .
|
544 | | - "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" .
|
545 | | - $rightNote . "</b></td>" .
|
546 | | - "</tr>" .
|
547 | | - $multiNotice .
|
548 | | - $diffEngine->generateDiffBody( $oText, $nText ) .
|
549 | | - "</table>" .
|
550 | | - "</div>\n"
|
551 | | - );
|
552 | | - $this->isDiffFromStable = true;
|
553 | | - return true;
|
554 | | - }
|
555 | | - return false;
|
556 | | - }
|
557 | | -
|
558 | | - /**
|
559 | | - * Get the normal and display files for the underlying ImagePage.
|
560 | | - * If the a stable version needs to be displayed, this will set $normalFile
|
561 | | - * to the current version, and $displayFile to the desired version.
|
562 | | - *
|
563 | | - * If no stable version is required, the reference parameters will not be set
|
564 | | - *
|
565 | | - * Depends on $wgRequest
|
566 | | - */
|
567 | | - public function imagePageFindFile( &$normalFile, &$displayFile ) {
|
568 | | - global $wgRequest, $wgArticle;
|
569 | | - $this->load();
|
570 | | - # Determine timestamp. A reviewed version may have explicitly been requested...
|
571 | | - $frev = null;
|
572 | | - $time = false;
|
573 | | - if( $reqId = $wgRequest->getVal('stableid') ) {
|
574 | | - $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId );
|
575 | | - } elseif( $this->pageOverride() ) {
|
576 | | - $frev = $this->article->getStableRev();
|
577 | | - }
|
578 | | - if( !is_null($frev) ) {
|
579 | | - $time = $frev->getFileTimestamp();
|
580 | | - // B/C, may be stored in associated image version metadata table
|
581 | | - if( !$time ) {
|
582 | | - $dbr = wfGetDB( DB_SLAVE );
|
583 | | - $time = $dbr->selectField( 'flaggedimages',
|
584 | | - 'fi_img_timestamp',
|
585 | | - array( 'fi_rev_id' => $frev->getRevId(),
|
586 | | - 'fi_name' => $this->article->getTitle()->getDBkey() ),
|
587 | | - __METHOD__
|
588 | | - );
|
589 | | - }
|
590 | | - # NOTE: if not found, this will use the current
|
591 | | - $wgArticle = new ImagePage( $this->article->getTitle(), $time );
|
592 | | - }
|
593 | | - if( !$time ) {
|
594 | | - # Try request parameter
|
595 | | - $time = $wgRequest->getVal( 'filetimestamp', false );
|
596 | | - }
|
597 | | -
|
598 | | - if( !$time ) {
|
599 | | - return; // Use the default behaviour
|
600 | | - }
|
601 | | -
|
602 | | - $title = $this->article->getTitle();
|
603 | | - $displayFile = wfFindFile( $title, array( 'time' => $time ) );
|
604 | | - # If none found, try current
|
605 | | - if( !$displayFile ) {
|
606 | | - wfDebug( __METHOD__.": {$title->getPrefixedDBkey()}: $time not found, using current\n" );
|
607 | | - $displayFile = wfFindFile( $title );
|
608 | | - # If none found, use a valid local placeholder
|
609 | | - if( !$displayFile ) {
|
610 | | - $displayFile = wfLocalFile( $title ); // fallback to current
|
611 | | - }
|
612 | | - $normalFile = $displayFile;
|
613 | | - # If found, set $normalFile
|
614 | | - } else {
|
615 | | - wfDebug( __METHOD__.": {$title->getPrefixedDBkey()}: using timestamp $time\n" );
|
616 | | - $normalFile = wfFindFile( $title );
|
617 | | - }
|
618 | | - }
|
619 | | -
|
620 | | - /**
|
621 | | - * Adds latest stable version tag to page when editing
|
622 | | - */
|
623 | | - public function addToEditView( $editPage ) {
|
624 | | - global $wgRequest, $wgOut;
|
625 | | - $this->load();
|
626 | | - # Must be reviewable. UI may be limited to unobtrusive patrolling system.
|
627 | | - if( !$this->article->isReviewable() || $this->article->limitedUI() )
|
628 | | - return true;
|
629 | | - # Show stabilization log
|
630 | | - $this->showStabilityLog();
|
631 | | - # Set new body html text as that of now
|
632 | | - $tag = $warning = $prot = '';
|
633 | | - # Check the newest stable version
|
634 | | - $quality = 0;
|
635 | | - if( $frev = $this->article->getStableRev() ) {
|
636 | | - global $wgLang, $wgUser, $wgFlaggedRevsAutoReview;
|
637 | | - # Find out revision id
|
638 | | - $revId = $editPage->oldid ?
|
639 | | - $editPage->oldid : $this->article->getLatest();
|
640 | | - # If this will be autoreviewed, notify the user...
|
641 | | - if( !FlaggedRevs::lowProfileUI() && $wgFlaggedRevsAutoReview && $wgUser->isAllowed('review') ) {
|
642 | | - # If we are editing some reviewed revision, any changes this user
|
643 | | - # makes will be autoreviewed...
|
644 | | - $ofrev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $revId );
|
645 | | - if( !is_null($ofrev) ) {
|
646 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
647 | | - $msg = ( $revId==$frev->getRevId() ) ? 'revreview-auto-w' : 'revreview-auto-w-old';
|
648 | | - $warning = "<div id='mw-autoreviewtag' class='flaggedrevs_warning plainlinks'>" .
|
649 | | - wfMsgExt($msg,array('parseinline')) . "</div>";
|
650 | | - }
|
651 | | - # Let new users know about review procedure a tag
|
652 | | - } elseif( !$wgUser->getId() && $this->article->showStableByDefault() ) {
|
653 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
654 | | - $warning = "<div id='mw-editwarningtag' class='flaggedrevs_editnotice plainlinks'>" .
|
655 | | - wfMsgExt('revreview-editnotice',array('parseinline')) . "</div>";
|
656 | | - }
|
657 | | - if( $frev->getRevId() != $revId ) {
|
658 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
659 | | - $time = $wgLang->date( $frev->getTimestamp(), true );
|
660 | | - $flags = $frev->getTags();
|
661 | | - if( FlaggedRevs::isQuality($flags) ) {
|
662 | | - $quality = FlaggedRevs::isPristine($flags) ? 2 : 1;
|
663 | | - }
|
664 | | - $revsSince = FlaggedRevs::getRevCountSince( $this->article, $frev->getRevId() );
|
665 | | - // Is the page config altered?
|
666 | | - if( $this->article->isPageLocked() ) {
|
667 | | - $prot = "<span class='fr-icon-locked' title=\"".
|
668 | | - wfMsgHtml('revreview-locked-title')."\"></span>";
|
669 | | - } elseif( $this->article->isPageUnlocked() ) {
|
670 | | - $prot = "<span class='fr-icon-unlocked' title=\"".
|
671 | | - wfMsgHtml('revreview-unlocked-title')."\"></span>";
|
672 | | - }
|
673 | | - # Streamlined UI
|
674 | | - if( FlaggedRevs::useSimpleUI() ) {
|
675 | | - $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic';
|
676 | | - $msg .= ($revsSince == 0) ? '-i' : '';
|
677 | | - $tag = "{$prot}<span class='fr-checkbox'></span>" .
|
678 | | - wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time, $revsSince );
|
679 | | - $tag = "<div id='mw-revisiontag-edit' class='flaggedrevs_editnotice plainlinks'>$tag</div>";
|
680 | | - # Standard UI
|
681 | | - } else {
|
682 | | - $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic';
|
683 | | - $msg .= ($revsSince == 0) ? '-i' : '';
|
684 | | - $tag = "{$prot}<span class='fr-checkbox'></span>" .
|
685 | | - wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time, $revsSince );
|
686 | | - # Hide clutter
|
687 | | - if( !empty($flags) ) {
|
688 | | - $tag .= " " . FlaggedRevsXML::ratingToggle();
|
689 | | - $tag .= '<span id="mw-revisionratings" style="display:block;"><br/>' .
|
690 | | - wfMsg('revreview-oldrating') . FlaggedRevsXML::addTagRatings( $flags ) . '</span>';
|
691 | | - }
|
692 | | - $tag = "<div id='mw-revisiontag-edit' class='flaggedrevs_editnotice plainlinks'>$tag</div>";
|
693 | | - }
|
694 | | - }
|
695 | | - # Output notice and warning for editors
|
696 | | - if( $tag || $warning ) {
|
697 | | - $wgOut->addHTML( $tag . $warning );
|
698 | | - }
|
699 | | -
|
700 | | - # Show diff to stable, to make things less confusing...
|
701 | | - # This can be disabled via user preferences
|
702 | | - if( $frev->getRevId() < $revId // changes were made
|
703 | | - && $this->showDiffOnEditUser() // stable default and user cannot review
|
704 | | - && $wgUser->getBoolOption('flaggedrevseditdiffs') // not disable via prefs
|
705 | | - ) {
|
706 | | - # Don't show for old revisions, diff, preview, or undo.
|
707 | | - if( $editPage->oldid || $editPage->section === "new"
|
708 | | - || in_array($editPage->formtype,array('diff','preview')) )
|
709 | | - {
|
710 | | - return true; // nothing to show here
|
711 | | - }
|
712 | | -
|
713 | | - # Conditions are met to show diff...
|
714 | | - wfLoadExtensionMessages( 'FlaggedRevs' ); // load required messages
|
715 | | - $leftNote = $quality ? 'revreview-quality-title' : 'revreview-stable-title';
|
716 | | - $rClass = FlaggedRevsXML::getQualityColor( false );
|
717 | | - $lClass = FlaggedRevsXML::getQualityColor( (int)$quality );
|
718 | | - $rightNote = "<span class='$rClass'>[".wfMsgHtml('revreview-draft-title')."]</span>";
|
719 | | - $leftNote = "<span class='$lClass'>[".wfMsgHtml($leftNote)."]</span>";
|
720 | | - $text = $frev->getRevText();
|
721 | | - # Are we editing a section?
|
722 | | - $section = ($editPage->section == "") ? false : intval($editPage->section);
|
723 | | - if( $section !== false ) {
|
724 | | - $text = $this->article->getSection( $text, $section );
|
725 | | - }
|
726 | | - if( $text !== false && strcmp($text,$editPage->textbox1) !== 0 ) {
|
727 | | - $diffEngine = new DifferenceEngine();
|
728 | | - $diffEngine->showDiffStyle();
|
729 | | - $wgOut->addHTML(
|
730 | | - "<div>" .
|
731 | | - "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" .
|
732 | | - "<col class='diff-marker' />" .
|
733 | | - "<col class='diff-content' />" .
|
734 | | - "<col class='diff-marker' />" .
|
735 | | - "<col class='diff-content' />" .
|
736 | | - "<tr>" .
|
737 | | - "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" .
|
738 | | - $leftNote . "</b></td>" .
|
739 | | - "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" .
|
740 | | - $rightNote . "</b></td>" .
|
741 | | - "</tr>" .
|
742 | | - $diffEngine->generateDiffBody( $text, $editPage->textbox1 ) .
|
743 | | - "</table>" .
|
744 | | - "</div>\n"
|
745 | | - );
|
746 | | - }
|
747 | | - }
|
748 | | - }
|
749 | | - return true;
|
750 | | - }
|
751 | | -
|
752 | | - protected function showStabilityLog() {
|
753 | | - global $wgOut;
|
754 | | - $this->load();
|
755 | | - # Only for pages manually made to be stable...
|
756 | | - if( $this->article->isPageLocked() ) {
|
757 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
758 | | - $wgOut->addHTML( "<div class='mw-warning-with-logexcerpt'>" );
|
759 | | - $wgOut->addWikiMsg( 'revreview-locked' );
|
760 | | - LogEventsList::showLogExtract( $wgOut, 'stable',
|
761 | | - $this->article->getTitle()->getPrefixedText(), '', array('lim'=>1) );
|
762 | | - $wgOut->addHTML( "</div>" );
|
763 | | - # ...or unstable
|
764 | | - } elseif( $this->article->isPageUnlocked() ) {
|
765 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
766 | | - $wgOut->addHTML( "<div class='mw-warning-with-logexcerpt'>" );
|
767 | | - $wgOut->addWikiMsg( 'revreview-unlocked' );
|
768 | | - LogEventsList::showLogExtract( $wgOut, 'stable',
|
769 | | - $this->article->getTitle()->getPrefixedText(), '', array('lim'=>1) );
|
770 | | - $wgOut->addHTML( "</div>" );
|
771 | | - }
|
772 | | - return true;
|
773 | | - }
|
774 | | -
|
775 | | - /**
|
776 | | - * Add unreviewed pages links
|
777 | | - */
|
778 | | - public function addToCategoryView() {
|
779 | | - global $wgOut, $wgUser;
|
780 | | - $this->load();
|
781 | | - if( !$wgUser->isAllowed( 'review' ) ) {
|
782 | | - return true;
|
783 | | - }
|
784 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
785 | | - # Load special page names
|
786 | | - wfLoadExtensionMessages( 'OldReviewedPages' );
|
787 | | - wfLoadExtensionMessages( 'UnreviewedPages' );
|
788 | | -
|
789 | | - $category = $this->article->getTitle()->getText();
|
790 | | -
|
791 | | - $unreviewed = SpecialPage::getTitleFor( 'UnreviewedPages' );
|
792 | | - $unreviewedLink = $wgUser->getSkin()->makeKnownLinkObj( $unreviewed,
|
793 | | - wfMsgHtml('unreviewedpages'), 'category=' . urlencode($category) );
|
794 | | -
|
795 | | - $oldreviewed = SpecialPage::getTitleFor( 'OldReviewedPages' );
|
796 | | - $oldreviewedLink = $wgUser->getSkin()->makeKnownLinkObj( $oldreviewed,
|
797 | | - wfMsgHtml('oldreviewedpages'), 'category=' . urlencode($category) );
|
798 | | -
|
799 | | - $wgOut->appendSubtitle("<span id='mw-category-oldreviewed'>$unreviewedLink / $oldreviewedLink</span>");
|
800 | | -
|
801 | | - return true;
|
802 | | - }
|
803 | | -
|
804 | | - /**
|
805 | | - * Add review form to pages when necessary
|
806 | | - */
|
807 | | - public function addReviewForm( &$data ) {
|
808 | | - global $wgRequest, $wgUser, $wgOut;
|
809 | | - $this->load();
|
810 | | - # User must have review rights and page must be reviewable
|
811 | | - if( !$wgUser->isAllowed('review') || !$this->article->exists() || !$this->article->isReviewable() ) {
|
812 | | - return true;
|
813 | | - }
|
814 | | - # Unobtrusive patrolling UI only shows forms if requested
|
815 | | - if( !$wgRequest->getInt('reviewform') && $this->article->limitedUI() ) {
|
816 | | - return true;
|
817 | | - }
|
818 | | - # Avoid multi-page diffs that are useless and misbehave (bug 19327)
|
819 | | - if( $this->isMultiPageDiff ) {
|
820 | | - return true;
|
821 | | - }
|
822 | | - # Check action and if page is protected
|
823 | | - $action = $wgRequest->getVal( 'action', 'view' );
|
824 | | - # Must be view/diff action...
|
825 | | - if( !self::isViewAction($action) ) {
|
826 | | - return true;
|
827 | | - }
|
828 | | - # Place the form at the top or bottom as most convenient
|
829 | | - $onTop = $wgRequest->getVal('diff') || $this->isDiffFromStable;
|
830 | | - $this->addQuickReview( $data, $onTop, false );
|
831 | | - return true;
|
832 | | - }
|
833 | | -
|
834 | | - /**
|
835 | | - * Add link to stable version setting to protection form
|
836 | | - */
|
837 | | - public function addVisibilityLink( &$data ) {
|
838 | | - global $wgUser, $wgRequest, $wgOut;
|
839 | | - $this->load();
|
840 | | - if( FlaggedRevs::getProtectionLevels() )
|
841 | | - return true; // simple custom levels set for action=protect
|
842 | | - # Check only if the title is reviewable
|
843 | | - if( !$this->article->isReviewable(true) ) {
|
844 | | - return true;
|
845 | | - }
|
846 | | - $action = $wgRequest->getVal( 'action', 'view' );
|
847 | | - if( $action == 'protect' || $action == 'unprotect' ) {
|
848 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
849 | | - wfLoadExtensionMessages( 'Stabilization' ); // Load special page name
|
850 | | - $title = SpecialPage::getTitleFor( 'Stabilization' );
|
851 | | - # Give a link to the page to configure the stable version
|
852 | | - $frev = $this->article->getStableRev();
|
853 | | - if( $frev && $frev->getRevId() == $this->article->getLatest() ) {
|
854 | | - $wgOut->prependHTML( "<span class='plainlinks'>" .
|
855 | | - wfMsgExt( 'revreview-visibility',array('parseinline'),
|
856 | | - $title->getPrefixedText() ) . "</span>" );
|
857 | | - } elseif( $frev ) {
|
858 | | - $wgOut->prependHTML( "<span class='plainlinks'>" .
|
859 | | - wfMsgExt( 'revreview-visibility2',array('parseinline'),
|
860 | | - $title->getPrefixedText() ) . "</span>" );
|
861 | | - } else {
|
862 | | - $wgOut->prependHTML( "<span class='plainlinks'>" .
|
863 | | - wfMsgExt( 'revreview-visibility3',array('parseinline'),
|
864 | | - $title->getPrefixedText() ) . "</span>" );
|
865 | | - }
|
866 | | - }
|
867 | | - return true;
|
868 | | - }
|
869 | | -
|
870 | | - /**
|
871 | | - * Modify an array of action links, as used by SkinTemplateNavigation and
|
872 | | - * SkinTemplateTabs, to inlude flagged revs UI elements
|
873 | | - */
|
874 | | - public function setActionTabs( $skin, &$actions ) {
|
875 | | - global $wgRequest, $wgUser;
|
876 | | - $this->load();
|
877 | | - if( FlaggedRevs::getProtectionLevels() ) {
|
878 | | - return true; // simple custom levels set for action=protect
|
879 | | - }
|
880 | | - $title = $this->article->getTitle()->getSubjectPage();
|
881 | | - if ( !FlaggedRevs::isPageReviewable( $title ) ) {
|
882 | | - return true; // Only reviewable pages need these tabs
|
883 | | - }
|
884 | | - // Check if we should show a stabilization tab
|
885 | | - if (
|
886 | | - !$skin->mTitle->isTalkPage() &&
|
887 | | - is_array( $actions ) &&
|
888 | | - !isset( $actions['protect'] ) &&
|
889 | | - !isset( $actions['unprotect'] ) &&
|
890 | | - $wgUser->isAllowed( 'stablesettings' ) &&
|
891 | | - $title->exists()
|
892 | | - ) {
|
893 | | - wfLoadExtensionMessages( 'Stabilization' );
|
894 | | - $stableTitle = SpecialPage::getTitleFor( 'Stabilization' );
|
895 | | - // Add a tab
|
896 | | - $actions['default'] = array(
|
897 | | - 'class' => false,
|
898 | | - 'text' => wfMsg( 'stabilization-tab' ),
|
899 | | - 'href' => $stableTitle->getLocalUrl(
|
900 | | - 'page=' . $title->getPrefixedUrl()
|
901 | | - )
|
902 | | - );
|
903 | | - }
|
904 | | - return true;
|
905 | | - }
|
906 | | -
|
907 | | - /**
|
908 | | - * Modify an array of view links, as used by SkinTemplateNavigation and
|
909 | | - * SkinTemplateTabs, to inlude flagged revs UI elements
|
910 | | - */
|
911 | | - public function setViewTabs( $skin, &$views ) {
|
912 | | - global $wgRequest, $wgUser, $wgFlaggedRevTabs;
|
913 | | - $this->load();
|
914 | | -
|
915 | | - $title = $this->article->getTitle()->getSubjectPage(); // Get the actual content page
|
916 | | - $article = new Article( $title );
|
917 | | - $action = $wgRequest->getVal( 'action', 'view' );
|
918 | | - $fa = FlaggedArticle::getTitleInstance( $title );
|
919 | | - if ( !$fa->isReviewable() || $this->article->limitedUI() ) {
|
920 | | - // This isn't a reviewable page or the UI is hidden
|
921 | | - return true;
|
922 | | - }
|
923 | | - $srev = $this->article->getStableRev( $action == 'rollback' ? FR_MASTER : 0 );
|
924 | | - if( is_null( $srev ) ) {
|
925 | | - return true; // No stable revision exists
|
926 | | - }
|
927 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
928 | | - $synced = FlaggedRevs::stableVersionIsSynced( $srev, $article );
|
929 | | - // Set draft tab as needed...
|
930 | | - if ( !$skin->mTitle->isTalkPage() && !$synced ) {
|
931 | | - if ( isset( $views['edit'] ) ) {
|
932 | | - if ( $this->article->showStableByDefault() ) {
|
933 | | - $views['edit']['text'] = wfMsg('revreview-edit');
|
934 | | - }
|
935 | | - if ( $this->pageOverride() ) {
|
936 | | - $views['edit']['href'] = $title->getLocalUrl( 'action=edit' );
|
937 | | - }
|
938 | | - }
|
939 | | - if ( isset( $views['viewsource'] ) ) {
|
940 | | - if ( $this->article->showStableByDefault() ) {
|
941 | | - $views['viewsource']['text'] = wfMsg('revreview-source');
|
942 | | - }
|
943 | | - if ( $this->pageOverride() ) {
|
944 | | - $views['viewsource']['href'] = $title->getLocalUrl( 'action=edit' );
|
945 | | - }
|
946 | | - }
|
947 | | - }
|
948 | | - if ( !$wgFlaggedRevTabs || $synced ) {
|
949 | | - // Exit, since either the stable/draft tabs should not be shown
|
950 | | - // or the page is already the most current revision
|
951 | | - return true;
|
952 | | - }
|
953 | | - $tabs = array(
|
954 | | - 'stable' => array(
|
955 | | - 'text' => wfMsg( 'revreview-stable' ), // unused
|
956 | | - 'href' => $title->getLocalUrl( 'stable=1' ),
|
957 | | - 'class' => ''
|
958 | | - ),
|
959 | | - 'current' => array(
|
960 | | - 'text' => wfMsg( 'revreview-current' ),
|
961 | | - 'href' => $title->getLocalUrl( 'stable=0&redirect=no' ),
|
962 | | - 'class' => ''
|
963 | | - ),
|
964 | | - );
|
965 | | - if ( $this->pageOverride() || $wgRequest->getVal( 'stableid' ) ) {
|
966 | | - // We are looking a the stable version
|
967 | | - $tabs['stable']['class'] = 'selected';
|
968 | | - } elseif (
|
969 | | - ( self::isViewAction( $action ) || $action == 'edit' ) &&
|
970 | | - !$skin->mTitle->isTalkPage()
|
971 | | - ) {
|
972 | | - // We are looking at the current revision or in edit mode
|
973 | | - $tabs['current']['class'] = 'selected';
|
974 | | - }
|
975 | | - $first = true;
|
976 | | - $newViews = array();
|
977 | | - foreach ( $views as $tabAction => $data ) {
|
978 | | - // Very first tab (page link)
|
979 | | - if( $first ) {
|
980 | | - if( $synced ) {
|
981 | | - // Use existing first tabs when synced
|
982 | | - $newViews[$tabAction] = $data;
|
983 | | - } else {
|
984 | | - // Use split current and stable tabs when not synced
|
985 | | - $newViews[$tabAction]['text'] = $data['text']; // keep tab name
|
986 | | - $newViews[$tabAction]['href'] = $tabs['stable']['href'];
|
987 | | - $newViews[$tabAction]['class'] = $tabs['stable']['class'];
|
988 | | - $newViews['current'] = $tabs['current'];
|
989 | | - }
|
990 | | - $first = false;
|
991 | | - } else {
|
992 | | - $newViews[$tabAction] = $data;
|
993 | | - }
|
994 | | - }
|
995 | | - // Replaces old tabs with new tabs
|
996 | | - $views = $newViews;
|
997 | | - return true;
|
998 | | - }
|
999 | | -
|
1000 | | - /**
|
1001 | | - * @param FlaggedRevision $frev
|
1002 | | - * @return string, revision review notes
|
1003 | | - */
|
1004 | | - public function getReviewNotes( $frev ) {
|
1005 | | - global $wgUser;
|
1006 | | - $this->load();
|
1007 | | - if( FlaggedRevs::allowComments() && $frev && $frev->getComment() ) {
|
1008 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
1009 | | - $notes = "<br/><div class='flaggedrevs_notes plainlinks'>";
|
1010 | | - $notes .= wfMsgExt('revreview-note', array('parseinline'), User::whoIs( $frev->getUser() ) );
|
1011 | | - $notes .= '<br/><i>' . $wgUser->getSkin()->formatComment( $frev->getComment() ) . '</i></div>';
|
1012 | | - $this->reviewNotes = $notes;
|
1013 | | - }
|
1014 | | - }
|
1015 | | -
|
1016 | | - /**
|
1017 | | - * When comparing the stable revision to the current after editing a page, show
|
1018 | | - * a tag with some explaination for the diff.
|
1019 | | - */
|
1020 | | - public function addDiffNoticeAndIncludes( $diff, $oldRev, $newRev ) {
|
1021 | | - global $wgRequest, $wgUser, $wgOut, $wgMemc;
|
1022 | | - $this->load();
|
1023 | | - # Page must be reviewable. Exempt printer-friendly output.
|
1024 | | - # UI may be limited to unobtrusive patrolling system
|
1025 | | - if( $wgOut->isPrintable() || !$this->article->isReviewable() || $this->article->limitedUI() )
|
1026 | | - return true;
|
1027 | | - # Load required messages
|
1028 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
1029 | | - # Check if this might be the diff to stable. If so, enhance it.
|
1030 | | - if( $newRev->isCurrent() && $oldRev ) {
|
1031 | | - $article = new Article( $newRev->getTitle() );
|
1032 | | - # Try the sync value cache...
|
1033 | | - $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $article->getId() );
|
1034 | | - $value = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article );
|
1035 | | - $synced = ($value === "true") ? true : false; // default as false to trigger query
|
1036 | | - $frev = $this->article->getStableRev();
|
1037 | | - if( $frev && $frev->getRevId() == $oldRev->getID() ) {
|
1038 | | - global $wgParserCacheExpireTime;
|
1039 | | -
|
1040 | | - $changeList = array();
|
1041 | | - $skin = $wgUser->getSkin();
|
1042 | | -
|
1043 | | - # Try the cache. Uses format <page ID>-<UNIX timestamp>.
|
1044 | | - $key = wfMemcKey( 'stableDiffs', 'templates', $article->getId() );
|
1045 | | - $tmpChanges = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article );
|
1046 | | - if( empty($tmpChanges) && !$synced ) {
|
1047 | | - $tmpChanges = false; // don't use cache
|
1048 | | - }
|
1049 | | -
|
1050 | | - # Make a list of each changed template...
|
1051 | | - if( $tmpChanges === false ) {
|
1052 | | - $dbr = wfGetDB( DB_SLAVE );
|
1053 | | - // Get templates where the current and stable are not the same revision
|
1054 | | - $ret = $dbr->select( array('flaggedtemplates','page','flaggedpages'),
|
1055 | | - array( 'ft_namespace', 'ft_title', 'fp_stable','ft_tmp_rev_id', 'page_latest' ),
|
1056 | | - array( 'ft_rev_id' => $frev->getRevId(),
|
1057 | | - 'page_namespace = ft_namespace',
|
1058 | | - 'page_title = ft_title' ),
|
1059 | | - __METHOD__,
|
1060 | | - array(), /* OPTIONS */
|
1061 | | - array( 'flaggedpages' => array('LEFT JOIN','fp_page_id = page_id') )
|
1062 | | - );
|
1063 | | - $tmpChanges = array();
|
1064 | | - while( $row = $dbr->fetchObject( $ret ) ) {
|
1065 | | - $title = Title::makeTitleSafe( $row->ft_namespace, $row->ft_title );
|
1066 | | - $revIdDraft = $row->page_latest;
|
1067 | | - // stable time -> time when reviewed (unless the other is newer)
|
1068 | | - $revIdStable = isset($row->fp_stable) && $row->fp_stable >= $row->ft_tmp_rev_id ?
|
1069 | | - $row->fp_stable : $row->ft_tmp_rev_id;
|
1070 | | - // compare to current
|
1071 | | - if( $revIdDraft > $revIdStable ) {
|
1072 | | - $tmpChanges[] = $skin->makeKnownLinkObj( $title, $title->getPrefixedText(),
|
1073 | | - "diff=cur&oldid={$revIdStable}" );
|
1074 | | - }
|
1075 | | - }
|
1076 | | - $wgMemc->set( $key, FlaggedRevs::makeMemcObj($tmpChanges), $wgParserCacheExpireTime );
|
1077 | | - }
|
1078 | | - # Add set to list
|
1079 | | - if( $tmpChanges )
|
1080 | | - $changeList += $tmpChanges;
|
1081 | | -
|
1082 | | - # Try the cache. Uses format <page ID>-<UNIX timestamp>.
|
1083 | | - $key = wfMemcKey( 'stableDiffs', 'images', $article->getId() );
|
1084 | | - $imgChanges = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article );
|
1085 | | - if( empty($imgChanges) && !$synced ) {
|
1086 | | - $imgChanges = false; // don't use cache
|
1087 | | - }
|
1088 | | -
|
1089 | | - // Get list of each changed image...
|
1090 | | - if( $imgChanges === false ) {
|
1091 | | - $dbr = wfGetDB( DB_SLAVE );
|
1092 | | - // Get images where the current and stable are not the same revision
|
1093 | | - $ret = $dbr->select( array('flaggedimages','page','image','flaggedpages','flaggedrevs'),
|
1094 | | - array( 'fi_name', 'fi_img_timestamp', 'fr_img_timestamp' ),
|
1095 | | - array( 'fi_rev_id' => $frev->getRevId() ),
|
1096 | | - __METHOD__,
|
1097 | | - array(), /* OPTIONS */
|
1098 | | - array( 'page' => array('LEFT JOIN','page_namespace = '. NS_FILE .' AND page_title = fi_name'),
|
1099 | | - 'image' => array('LEFT JOIN','img_name = fi_name'),
|
1100 | | - 'flaggedpages' => array('LEFT JOIN','fp_page_id = page_id'),
|
1101 | | - 'flaggedrevs' => array('LEFT JOIN','fr_page_id = fp_page_id AND fr_rev_id = fp_stable') )
|
1102 | | - );
|
1103 | | - $imgChanges = array();
|
1104 | | - while( $row = $dbr->fetchObject( $ret ) ) {
|
1105 | | - $title = Title::makeTitleSafe( NS_FILE, $row->fi_name );
|
1106 | | - // stable time -> time when reviewed (unless the other is newer)
|
1107 | | - $timestamp = isset($row->fr_img_timestamp) && $row->fr_img_timestamp >= $row->fi_img_timestamp ?
|
1108 | | - $row->fr_img_timestamp : $row->fi_img_timestamp;
|
1109 | | - // compare to current
|
1110 | | - $file = wfFindFile( $title );
|
1111 | | - if( $file && $file->getTimestamp() > $timestamp )
|
1112 | | - $imgChanges[] = $skin->makeKnownLinkObj( $title, $title->getPrefixedText() );
|
1113 | | - }
|
1114 | | - $wgMemc->set( $key, FlaggedRevs::makeMemcObj($imgChanges), $wgParserCacheExpireTime );
|
1115 | | - }
|
1116 | | - if( $imgChanges )
|
1117 | | - $changeList += $imgChanges;
|
1118 | | -
|
1119 | | - # Some important information...
|
1120 | | - $notice = '';
|
1121 | | - if( count($changeList) > 0 ) {
|
1122 | | - $notice = '<br/>' . wfMsgExt('revreview-update-use', array('parseinline'));
|
1123 | | - } elseif( !$synced ) {
|
1124 | | - $diff->mTitle->invalidateCache(); // bad cache, said they were not synced
|
1125 | | - }
|
1126 | | -
|
1127 | | - # If the user is allowed to review, prompt them!
|
1128 | | - if( empty($changeList) && $wgUser->isAllowed('review') ) {
|
1129 | | - $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" .
|
1130 | | - wfMsgExt('revreview-update-none', array('parseinline')).$notice.'</div>' );
|
1131 | | - } elseif( !empty($changeList) && $wgUser->isAllowed('review') ) {
|
1132 | | - $changeList = implode(', ',$changeList);
|
1133 | | - $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" .
|
1134 | | - wfMsgExt('revreview-update', array('parseinline')).' '.
|
1135 | | - $changeList.$notice.'</div>' );
|
1136 | | - } elseif( !empty($changeList) ) {
|
1137 | | - $changeList = implode(', ',$changeList);
|
1138 | | - $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" .
|
1139 | | - wfMsgExt('revreview-update-includes', array('parseinline')).' '.
|
1140 | | - $changeList.$notice.'</div>' );
|
1141 | | - }
|
1142 | | - # Set flag for review form to tell it to autoselect tag settings from the
|
1143 | | - # old revision unless the current one is tagged to.
|
1144 | | - if( !FlaggedRevision::newFromTitle( $diff->mTitle, $newRev->getID() ) ) {
|
1145 | | - $this->isDiffFromStable = true;
|
1146 | | - }
|
1147 | | -
|
1148 | | - # Set a key to note that someone is viewing this
|
1149 | | - if( $wgUser->isAllowed('review') ) {
|
1150 | | - $key = wfMemcKey( 'stableDiffs', 'underReview', $oldRev->getID(), $newRev->getID() );
|
1151 | | - $wgMemc->set( $key, '1', 10*60 ); // 10 min
|
1152 | | - }
|
1153 | | - }
|
1154 | | - }
|
1155 | | - $newRevQ = FlaggedRevs::getRevQuality( $newRev->getPage(), $newRev->getId() );
|
1156 | | - $oldRevQ = $oldRev ? FlaggedRevs::getRevQuality( $newRev->getPage(), $oldRev->getId() ) : false;
|
1157 | | - # Diff between two revisions
|
1158 | | - if( $oldRev ) {
|
1159 | | - $wgOut->addHTML( "<table class='fr-diff-ratings'><tr>" );
|
1160 | | -
|
1161 | | - $class = FlaggedRevsXML::getQualityColor( $oldRevQ );
|
1162 | | - if( $oldRevQ !== false ) {
|
1163 | | - $msg = $oldRevQ ? 'hist-quality' : 'hist-stable';
|
1164 | | - } else {
|
1165 | | - $msg = 'hist-draft';
|
1166 | | - }
|
1167 | | - $wgOut->addHTML( "<td width='50%' align='center'>" );
|
1168 | | - $wgOut->addHTML( "<span class='$class'><b>[" . wfMsgHtml( $msg ) . "]</b></span>" );
|
1169 | | -
|
1170 | | - $class = FlaggedRevsXML::getQualityColor( $newRevQ );
|
1171 | | - if( $newRevQ !== false ) {
|
1172 | | - $msg = $newRevQ ? 'hist-quality' : 'hist-stable';
|
1173 | | - } else {
|
1174 | | - $msg = 'hist-draft';
|
1175 | | - }
|
1176 | | - $wgOut->addHTML( "</td><td width='50%' align='center'>" );
|
1177 | | - $wgOut->addHTML( "<span class='$class'><b>[" . wfMsgHtml( $msg ) . "]</b></span>" );
|
1178 | | -
|
1179 | | - $wgOut->addHTML( '</td></tr></table>' );
|
1180 | | - # New page "diffs" - just one rev
|
1181 | | - } else {
|
1182 | | - if( $newRevQ !== false ) {
|
1183 | | - $msg = $newRevQ ? 'hist-quality' : 'hist-stable';
|
1184 | | - } else {
|
1185 | | - $msg = 'hist-draft';
|
1186 | | - }
|
1187 | | - $wgOut->addHTML( "<table class='fr-diff-ratings'><tr><td class='fr-$msg' align='center'>" );
|
1188 | | - $wgOut->addHTML( "<b>[" . wfMsgHtml( $msg ) . "]</b>" );
|
1189 | | - $wgOut->addHTML( '</td></tr></table>' );
|
1190 | | - }
|
1191 | | - return true;
|
1192 | | - }
|
1193 | | -
|
1194 | | - /**
|
1195 | | - * Set $this->isDiffFromStable and $this->isMultiPageDiff fields
|
1196 | | - */
|
1197 | | - public function setViewFlags( $diff, $oldRev, $newRev ) {
|
1198 | | - $this->load();
|
1199 | | - if( $newRev && $oldRev ) {
|
1200 | | - // Is this a diff between two pages?
|
1201 | | - if( $newRev->getPage() != $oldRev->getPage() ) {
|
1202 | | - $this->isMultiPageDiff = true;
|
1203 | | - // Is there a stable version?
|
1204 | | - } else if( $this->article->isReviewable() ) {
|
1205 | | - $frev = $this->article->getStableRev();
|
1206 | | - // Is this a diff of the draft rev against the stable rev?
|
1207 | | - if( $frev && $frev->getRevId() == $oldRev->getId() && $newRev->isCurrent() ) {
|
1208 | | - $this->isDiffFromStable = true;
|
1209 | | - }
|
1210 | | - }
|
1211 | | - }
|
1212 | | - return true;
|
1213 | | - }
|
1214 | | -
|
1215 | | - /**
|
1216 | | - * Add a link to patrol non-reviewable pages.
|
1217 | | - * Also add a diff-to-stable for other pages if possible.
|
1218 | | - */
|
1219 | | - public function addDiffLink( $diff, $oldRev, $newRev ) {
|
1220 | | - global $wgUser, $wgOut;
|
1221 | | - $this->load();
|
1222 | | - // Is there a stable version?
|
1223 | | - if( $newRev && $oldRev && $this->article->isReviewable() ) {
|
1224 | | - $frev = $this->article->getStableRev();
|
1225 | | - # Give a link to the diff-to-stable if needed
|
1226 | | - if( $frev && !$this->isDiffFromStable ) {
|
1227 | | - $article = new Article( $newRev->getTitle() );
|
1228 | | - # Is the stable revision using the same revision as the current?
|
1229 | | - if( $article->getLatest() != $frev->getRevId() ) {
|
1230 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
1231 | | - $patrol = '(' . $wgUser->getSkin()->makeKnownLinkObj( $newRev->getTitle(),
|
1232 | | - wfMsgHtml( 'review-diff2stable' ), "oldid={$frev->getRevId()}&diff=cur&diffonly=0" ) . ')';
|
1233 | | - $wgOut->addHTML( "<div class='fr-diff-to-stable' align='center'>$patrol</div>" );
|
1234 | | - }
|
1235 | | - }
|
1236 | | - }
|
1237 | | - return true;
|
1238 | | - }
|
1239 | | -
|
1240 | | - /**
|
1241 | | - * Redirect users out to review the changes to the stable version.
|
1242 | | - * Only for people who can review and for pages that have a stable version.
|
1243 | | - */
|
1244 | | - public function injectReviewDiffURLParams( &$sectionAnchor, &$extraQuery ) {
|
1245 | | - global $wgUser, $wgReviewChangesAfterEdit;
|
1246 | | - $this->load();
|
1247 | | - # Don't show this for pages that are not reviewable
|
1248 | | - if( !$this->article->isReviewable() || $this->article->getTitle()->isTalkPage() )
|
1249 | | - return true;
|
1250 | | - # We may want to skip some UI elements
|
1251 | | - if( $this->article->limitedUI() ) return true;
|
1252 | | - # Get the stable version, from master
|
1253 | | - $frev = $this->article->getStableRev( FR_MASTER );
|
1254 | | - if( !$frev )
|
1255 | | - return true;
|
1256 | | - $latest = $this->article->getTitle()->getLatestRevID(GAID_FOR_UPDATE);
|
1257 | | - // If we are supposed to review after edit, and it was not autoreviewed,
|
1258 | | - // and the user can actually make new stable version, take us to the diff...
|
1259 | | - if( $wgReviewChangesAfterEdit && $frev && $latest > $frev->getRevId() && $frev->userCanSetFlags() ) {
|
1260 | | - $extraQuery .= $extraQuery ? '&' : '';
|
1261 | | - $extraQuery .= "oldid={$frev->getRevId()}&diff=cur&diffonly=0"; // override diff-only
|
1262 | | - // ...otherwise, go to the current revision after completing an edit.
|
1263 | | - } else {
|
1264 | | - if( $frev && $latest != $frev->getRevId() ) {
|
1265 | | - $extraQuery .= "stable=0";
|
1266 | | - if( !$wgUser->isAllowed('review') && $this->article->showStableByDefault() ) {
|
1267 | | - $extraQuery .= "&shownotice=1";
|
1268 | | - }
|
1269 | | - }
|
1270 | | - }
|
1271 | | - return true;
|
1272 | | - }
|
1273 | | -
|
1274 | | - /**
|
1275 | | - * Add a hidden revision ID field to edit form.
|
1276 | | - * Needed for autoreview so it can select the flags from said revision.
|
1277 | | - */
|
1278 | | - public function addRevisionIDField( $editPage, $out ) {
|
1279 | | - global $wgRequest;
|
1280 | | - $this->load();
|
1281 | | - # Find out revision id
|
1282 | | - if( $this->article->mRevision ) {
|
1283 | | - $revId = $this->article->mRevision->mId;
|
1284 | | - } else {
|
1285 | | - $latest = $this->article->getTitle()->getLatestRevID(GAID_FOR_UPDATE);
|
1286 | | - $revId = $latest;
|
1287 | | - wfDebug( 'FlaggedArticle::addRevisionIDField - ID not specified, assumed current' );
|
1288 | | - }
|
1289 | | - # If undoing a few consecutive top edits, we know the base ID
|
1290 | | - if( $undo = $wgRequest->getIntOrNull('undo') ) {
|
1291 | | - $undoAfter = $wgRequest->getIntOrNull('undoafter');
|
1292 | | - $latest = isset($latest) ?
|
1293 | | - $latest : $this->article->getTitle()->getLatestRevID(GAID_FOR_UPDATE);
|
1294 | | - if( $undoAfter && $undo == $this->article->getLatest() ) {
|
1295 | | - $revId = $undoAfter;
|
1296 | | - }
|
1297 | | - }
|
1298 | | - $out->addHTML( "\n" . Xml::hidden( 'baseRevId', $revId ) );
|
1299 | | - $out->addHTML( "\n" . Xml::hidden( 'undidRev',
|
1300 | | - empty($editPage->undidRev) ? 0 : $editPage->undidRev )
|
1301 | | - );
|
1302 | | - return true;
|
1303 | | - }
|
1304 | | -
|
1305 | | - /**
|
1306 | | - * Adds brief review notes to a page.
|
1307 | | - * @param OutputPage $out
|
1308 | | - */
|
1309 | | - public function addReviewNotes( &$data ) {
|
1310 | | - $this->load();
|
1311 | | - if( $this->reviewNotes ) {
|
1312 | | - $data .= $this->reviewNotes;
|
1313 | | - }
|
1314 | | - return true;
|
1315 | | - }
|
1316 | | -
|
1317 | | - /**
|
1318 | | - * Adds a brief review form to a page.
|
1319 | | - * @param string $data
|
1320 | | - * @param bool $top
|
1321 | | - * @param bool hide
|
1322 | | - * @param bool $top, should this form always go on top?
|
1323 | | - */
|
1324 | | - public function addQuickReview( &$data, $top = false, $hide = false ) {
|
1325 | | - global $wgOut, $wgUser, $wgRequest;
|
1326 | | - $this->load();
|
1327 | | - # Get the revision being displayed
|
1328 | | - $id = $wgOut->getRevisionId();
|
1329 | | - if( !$id ) {
|
1330 | | - if( !$this->isDiffFromStable ) {
|
1331 | | - return false; // only safe to assume current if diff-to-stable
|
1332 | | - } else {
|
1333 | | - $rev = Revision::newFromTitle( $this->article->getTitle() );
|
1334 | | - $id = $rev->getId();
|
1335 | | - }
|
1336 | | - } else {
|
1337 | | - $rev = Revision::newFromTitle( $this->article->getTitle(), $id );
|
1338 | | - }
|
1339 | | - # Load required messages
|
1340 | | - wfLoadExtensionMessages( 'FlaggedRevs' );
|
1341 | | - # Must be a valid non-printable output and revision must be public
|
1342 | | - if( $wgOut->isPrintable() || !$rev || $rev->isDeleted(Revision::DELETED_TEXT) ) {
|
1343 | | - return false;
|
1344 | | - }
|
1345 | | - $useCurrent = false;
|
1346 | | - if( !isset($wgOut->mTemplateIds) || !isset($wgOut->fr_ImageSHA1Keys) ) {
|
1347 | | - $useCurrent = true;
|
1348 | | - }
|
1349 | | - $skin = $wgUser->getSkin();
|
1350 | | -
|
1351 | | - $config = $this->article->getVisibilitySettings();
|
1352 | | - # Variable for sites with no flags, otherwise discarded
|
1353 | | - $approve = $wgRequest->getBool('wpApprove');
|
1354 | | - # See if the version being displayed is flagged...
|
1355 | | - $oldFlags = $this->article->getFlagsForRevision( $id );
|
1356 | | - # If we are reviewing updates to a page, start off with the stable revision's
|
1357 | | - # flags. Otherwise, we just fill them in with the selected revision's flags.
|
1358 | | - if( $this->isDiffFromStable ) {
|
1359 | | - $srev = $this->article->getStableRev();
|
1360 | | - $flags = $srev->getTags();
|
1361 | | - # Check if user is allowed to renew the stable version.
|
1362 | | - # If not, then get the flags for the new revision itself.
|
1363 | | - if( !RevisionReview::userCanSetFlags( $oldFlags ) ) {
|
1364 | | - $flags = $oldFlags;
|
1365 | | - }
|
1366 | | - $encNotes = $srev->getComment();
|
1367 | | - } else {
|
1368 | | - $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $id );
|
1369 | | - $flags = $oldFlags;
|
1370 | | - $encNotes = $frev ? $frev->getComment() : ""; // pre-fill notes
|
1371 | | - }
|
1372 | | -
|
1373 | | - $reviewTitle = SpecialPage::getTitleFor( 'RevisionReview' );
|
1374 | | - $action = $reviewTitle->getLocalUrl( 'action=submit' );
|
1375 | | - $params = array( 'method' => 'post', 'action' => $action, 'id' => 'mw-reviewform' );
|
1376 | | - if( $hide ) {
|
1377 | | - $params['class'] = 'fr-hiddenform';
|
1378 | | - }
|
1379 | | - $form = Xml::openElement( 'form', $params );
|
1380 | | - $form .= Xml::openElement( 'fieldset', array('class' => 'flaggedrevs_reviewform noprint') );
|
1381 | | - $form .= "<legend><strong>" . wfMsgHtml( 'revreview-flag', $id ) . "</strong></legend>\n";
|
1382 | | -
|
1383 | | - # Show explanatory text
|
1384 | | - if( !FlaggedRevs::lowProfileUI() ) {
|
1385 | | - $msg = FlaggedRevs::showStableByDefault() ? 'revreview-text' : 'revreview-text2';
|
1386 | | - $form .= wfMsgExt( $msg, array('parse') );
|
1387 | | - }
|
1388 | | -
|
1389 | | - # Current user has too few rights to change at least one flag, thus entire form disabled
|
1390 | | - $uneditable = !$this->article->getTitle()->quickUserCan('edit');
|
1391 | | - $disabled = !RevisionReview::userCanSetFlags( $flags ) || $uneditable;
|
1392 | | - if( $disabled ) {
|
1393 | | - $form .= Xml::openElement( 'div', array('class' => 'fr-rating-controls-disabled',
|
1394 | | - 'id' => 'fr-rating-controls-disabled') );
|
1395 | | - $toggle = array( 'disabled' => "disabled" );
|
1396 | | - } else {
|
1397 | | - $form .= Xml::openElement( 'div', array('class' => 'fr-rating-controls',
|
1398 | | - 'id' => 'fr-rating-controls') );
|
1399 | | - $toggle = array();
|
1400 | | - }
|
1401 | | - # Add main checkboxes/selects
|
1402 | | - $form .= Xml::openElement( 'span', array('id' => 'mw-ratingselects') );
|
1403 | | - $form .= FlaggedRevsXML::ratingInputs( $flags, $config, $disabled );
|
1404 | | - $form .= Xml::closeElement( 'span' );
|
1405 | | -
|
1406 | | - if( FlaggedRevs::allowComments() && $wgUser->isAllowed( 'validate' ) ) {
|
1407 | | - $form .= "<div id='mw-notebox'>\n";
|
1408 | | - $form .= "<p>".wfMsgHtml( 'revreview-notes' ) . "</p>\n";
|
1409 | | - $form .= Xml::openElement( 'textarea', array('name' => 'wpNotes', 'id' => 'wpNotes',
|
1410 | | - 'class' => 'fr-notes-box', 'rows' => '2', 'cols' => '80') ) .
|
1411 | | - htmlspecialchars( $encNotes ) .
|
1412 | | - Xml::closeElement('textarea') . "\n";
|
1413 | | - $form .= "</div>\n";
|
1414 | | - }
|
1415 | | - # Get versions of templates/files used
|
1416 | | - $imageParams = $templateParams = $fileVersion = '';
|
1417 | | - if( $useCurrent ) {
|
1418 | | - # Get parsed current version
|
1419 | | - $parserCache = ParserCache::singleton();
|
1420 | | - $article = $this->article;
|
1421 | | - $currentOutput = $parserCache->get( $article, $wgUser );
|
1422 | | - if( $currentOutput == false ) {
|
1423 | | - global $wgParser, $wgEnableParserCache;
|
1424 | | - $text = $article->getContent();
|
1425 | | - $title = $article->getTitle();
|
1426 | | - $options = FlaggedRevs::makeParserOptions();
|
1427 | | - $currentOutput = $wgParser->parse( $text, $title, $options );
|
1428 | | - # Might as well save the cache while we're at it
|
1429 | | - if( $wgEnableParserCache )
|
1430 | | - $parserCache->save( $currentOutput, $article, $wgUser );
|
1431 | | - }
|
1432 | | - $templateIDs = $currentOutput->mTemplateIds;
|
1433 | | - $imageSHA1Keys = $currentOutput->fr_ImageSHA1Keys;
|
1434 | | - } else {
|
1435 | | - $templateIDs = $wgOut->mTemplateIds;
|
1436 | | - $imageSHA1Keys = $wgOut->fr_ImageSHA1Keys;
|
1437 | | - }
|
1438 | | - list($templateParams,$imageParams,$fileVersion) =
|
1439 | | - FlaggedRevs::getIncludeParams( $this->article, $templateIDs, $imageSHA1Keys );
|
1440 | | -
|
1441 | | - $form .= Xml::openElement( 'span', array('style' => 'white-space: nowrap;') );
|
1442 | | - # Hide comment if needed
|
1443 | | - if( !$disabled ) {
|
1444 | | - if( count(FlaggedRevs::getDimensions()) > 1 )
|
1445 | | - $form .= "<br/>"; // Don't put too much on one line
|
1446 | | - $form .= "<span id='mw-commentbox' style='clear:both'>" .
|
1447 | | - Xml::inputLabel( wfMsg('revreview-log'), 'wpReason', 'wpReason', 40, '',
|
1448 | | - array('class' => 'fr-comment-box') ) . " </span>";
|
1449 | | - }
|
1450 | | - $form .= Xml::submitButton( wfMsg('revreview-submit'),
|
1451 | | - array(
|
1452 | | - 'id' => 'submitreview', 'accesskey' => wfMsg('revreview-ak-review'),
|
1453 | | - 'title' => wfMsg('revreview-tt-review').' ['.wfMsg('revreview-ak-review').']'
|
1454 | | - ) + $toggle
|
1455 | | - );
|
1456 | | - $form .= Xml::closeElement( 'span' );
|
1457 | | -
|
1458 | | - $form .= Xml::closeElement( 'div' ) . "\n";
|
1459 | | -
|
1460 | | - # Show stability log if there is anything interesting...
|
1461 | | - if( $this->article->isPageLocked() ) {
|
1462 | | - $loglist = new LogEventsList( $wgUser->getSkin(), $wgOut, LogEventsList::NO_ACTION_LINK );
|
1463 | | - $pager = new LogPager( $loglist, 'stable', '', $this->article->getTitle()->getPrefixedDBKey() );
|
1464 | | - $pager->mLimit = 1; // top item
|
1465 | | - if( ($logBody = $pager->getBody()) ) {
|
1466 | | - $form .= "<div><ul style='list-style:none; margin: 0;'>$logBody</ul></div>";
|
1467 | | - }
|
1468 | | - }
|
1469 | | -
|
1470 | | - # Hidden params
|
1471 | | - $form .= Xml::hidden( 'title', $reviewTitle->getPrefixedText() ) . "\n";
|
1472 | | - $form .= Xml::hidden( 'target', $this->article->getTitle()->getPrefixedDBKey() ) . "\n";
|
1473 | | - $form .= Xml::hidden( 'oldid', $id ) . "\n";
|
1474 | | - $form .= Xml::hidden( 'action', 'submit') . "\n";
|
1475 | | - $form .= Xml::hidden( 'wpEditToken', $wgUser->editToken() ) . "\n";
|
1476 | | - # Add review parameters
|
1477 | | - $form .= Xml::hidden( 'templateParams', $templateParams ) . "\n";
|
1478 | | - $form .= Xml::hidden( 'imageParams', $imageParams ) . "\n";
|
1479 | | - $form .= Xml::hidden( 'fileVersion', $fileVersion ) . "\n";
|
1480 | | - # Pass this in if given; useful for new page patrol
|
1481 | | - $form .= Xml::hidden( 'rcid', $wgRequest->getVal('rcid') ) . "\n";
|
1482 | | - # Special token to discourage fiddling...
|
1483 | | - $checkCode = RevisionReview::validationKey( $templateParams, $imageParams, $fileVersion, $id );
|
1484 | | - $form .= Xml::hidden( 'validatedParams', $checkCode ) . "\n";
|
1485 | | -
|
1486 | | - $form .= Xml::closeElement( 'fieldset' );
|
1487 | | - $form .= Xml::closeElement( 'form' );
|
1488 | | - # Place form at the correct position specified by $top
|
1489 | | - if( $top ) {
|
1490 | | - $wgOut->prependHTML( $form );
|
1491 | | - } else {
|
1492 | | - $data .= $form;
|
1493 | | - }
|
1494 | | - return true;
|
1495 | | - }
|
1496 | | -
|
1497 | | - /**
|
1498 | | - * Updates parser cache output to included needed versioning params.
|
1499 | | - */
|
1500 | | - public function maybeUpdateMainCache( &$outputDone, &$pcache ) {
|
1501 | | - global $wgUser, $wgRequest;
|
1502 | | - $this->load();
|
1503 | | -
|
1504 | | - $action = $wgRequest->getVal( 'action', 'view' );
|
1505 | | - if( $action == 'purge' )
|
1506 | | - return true; // already purging!
|
1507 | | - # Only trigger on article view for content pages, not for protect/delete/hist
|
1508 | | - if( !self::isViewAction($action) || !$wgUser->isAllowed( 'review' ) )
|
1509 | | - return true;
|
1510 | | - if( !$this->article->exists() || !$this->article->isReviewable() )
|
1511 | | - return true;
|
1512 | | -
|
1513 | | - $parserCache = ParserCache::singleton();
|
1514 | | - $parserOut = $parserCache->get( $this->article, $wgUser );
|
1515 | | - if( $parserOut ) {
|
1516 | | - # Clear older, incomplete, cached versions
|
1517 | | - # We need the IDs of templates and timestamps of images used
|
1518 | | - if( !isset($parserOut->fr_newestTemplateID) || !isset($parserOut->fr_newestImageTime) )
|
1519 | | - $this->article->getTitle()->invalidateCache();
|
1520 | | - }
|
1521 | | - return true;
|
1522 | | - }
|
1523 | | -}
|
| 2 | +<?php |
| 3 | + |
| 4 | +class FlaggedArticleView { |
| 5 | + protected $isDiffFromStable = false; |
| 6 | + protected $isMultiPageDiff = false; |
| 7 | + protected $reviewNotice = ''; |
| 8 | + protected $reviewNotes = ''; |
| 9 | + protected $article = null; |
| 10 | + protected $loaded = false; |
| 11 | + |
| 12 | + protected static $instance = null; |
| 13 | + |
| 14 | + /* |
| 15 | + * Get the FlaggedArticleView for this request |
| 16 | + */ |
| 17 | + public static function singleton() { |
| 18 | + if( self::$instance == null ) { |
| 19 | + self::$instance = new self(); |
| 20 | + } |
| 21 | + return self::$instance; |
| 22 | + } |
| 23 | + protected function __construct() {} |
| 24 | + |
| 25 | + /* |
| 26 | + * Load the global FlaggedArticle instance |
| 27 | + */ |
| 28 | + protected function load() { |
| 29 | + if( !$this->loaded ) { |
| 30 | + $this->article = self::globalArticleInstance(); |
| 31 | + if( $this->article == null ) { |
| 32 | + throw new MWException( 'FlaggedArticleViewer has no context article!' ); |
| 33 | + } |
| 34 | + } |
| 35 | + } |
| 36 | + |
| 37 | + /** |
| 38 | + * Get the FlaggedArticle instance associated with $wgArticle/$wgTitle, |
| 39 | + * or false if there isn't such a title |
| 40 | + */ |
| 41 | + public static function globalArticleInstance() { |
| 42 | + global $wgTitle; |
| 43 | + if( !empty( $wgTitle ) ) { |
| 44 | + return FlaggedArticle::getTitleInstance( $wgTitle ); |
| 45 | + } |
| 46 | + return null; |
| 47 | + } |
| 48 | + |
| 49 | + /** |
| 50 | + * Does the config and current URL params allow |
| 51 | + * for overriding by stable revisions? |
| 52 | + */ |
| 53 | + public function pageOverride() { |
| 54 | + global $wgUser, $wgRequest; |
| 55 | + $this->load(); |
| 56 | + # This only applies to viewing content pages |
| 57 | + $action = $wgRequest->getVal( 'action', 'view' ); |
| 58 | + if( !self::isViewAction($action) || !$this->article->isReviewable() ) |
| 59 | + return false; |
| 60 | + # Does not apply to diffs/old revision... |
| 61 | + if( $wgRequest->getVal('oldid') || $wgRequest->getVal('diff') ) |
| 62 | + return false; |
| 63 | + # Explicit requests for a certain stable version handled elsewhere... |
| 64 | + if( $wgRequest->getVal('stableid') ) |
| 65 | + return false; |
| 66 | + # Check user preferences |
| 67 | + if( $wgUser->getOption('flaggedrevsstable') ) |
| 68 | + return !( $wgRequest->getIntOrNull('stable') === 0 ); |
| 69 | + # Get page configuration |
| 70 | + $config = $this->article->getVisibilitySettings(); |
| 71 | + # Does the stable version override the current one? |
| 72 | + if( $config['override'] ) { |
| 73 | + if( FlaggedRevs::ignoreDefaultVersion() ) { |
| 74 | + return ( $wgRequest->getIntOrNull('stable') === 1 ); |
| 75 | + } |
| 76 | + # Viewer sees stable by default |
| 77 | + return !( $wgRequest->getIntOrNull('stable') === 0 ); |
| 78 | + # We are explicity requesting the stable version? |
| 79 | + } elseif( $wgRequest->getIntOrNull('stable') === 1 ) { |
| 80 | + return true; |
| 81 | + } |
| 82 | + return false; |
| 83 | + } |
| 84 | + |
| 85 | + /** |
| 86 | + * Is this user shown the stable version by default for this page? |
| 87 | + * @returns bool |
| 88 | + */ |
| 89 | + public function showStableByDefaultUser() { |
| 90 | + $this->load(); |
| 91 | + $config = $this->article->getVisibilitySettings(); // page configuration |
| 92 | + return ( $config['override'] && !FlaggedRevs::ignoreDefaultVersion() ); |
| 93 | + } |
| 94 | + |
| 95 | + /** |
| 96 | + * Is this user shown the diff-to-stable on edit for this page? |
| 97 | + * @returns bool |
| 98 | + */ |
| 99 | + public function showDiffOnEditUser() { |
| 100 | + global $wgUser; |
| 101 | + $this->load(); |
| 102 | + return ( $wgUser->isAllowed('review') || $this->showStableByDefaultUser() ); |
| 103 | + } |
| 104 | + |
| 105 | + /** |
| 106 | + * Is this a view page action? |
| 107 | + * @param $action string |
| 108 | + * @returns bool |
| 109 | + */ |
| 110 | + protected static function isViewAction( $action ) { |
| 111 | + return ( $action == 'view' || $action == 'purge' || $action == 'render' || $action == 'historysubmit' ); |
| 112 | + } |
| 113 | + |
| 114 | + /** |
| 115 | + * Output review notice |
| 116 | + */ |
| 117 | + protected function displayTag() { |
| 118 | + global $wgOut, $wgRequest; |
| 119 | + $this->load(); |
| 120 | + // UI may be limited to unobtrusive patrolling system |
| 121 | + if( $wgRequest->getVal('stableid') || !$this->article->limitedUI() ) { |
| 122 | + $wgOut->appendSubtitle( $this->reviewNotice ); |
| 123 | + } |
| 124 | + return true; |
| 125 | + } |
| 126 | + |
| 127 | + |
| 128 | + /** |
| 129 | + * Add a stable link when viewing old versions of an article that |
| 130 | + * have been reviewed. (e.g. for &oldid=x urls) |
| 131 | + */ |
| 132 | + public function addStableLink() { |
| 133 | + global $wgRequest, $wgOut, $wgLang; |
| 134 | + $this->load(); |
| 135 | + # Only for viewing old versions. UI may be limited to unobtrusive patrolling system. |
| 136 | + if( !$wgRequest->getVal('oldid') || $this->article->limitedUI() ) |
| 137 | + return true; |
| 138 | + # We may have nav links like "direction=prev&oldid=x" |
| 139 | + $revID = $this->article->getOldIDFromRequest(); |
| 140 | + $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $revID ); |
| 141 | + # Give a notice if this rev ID corresponds to a reviewed version... |
| 142 | + if( !is_null($frev) ) { |
| 143 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 144 | + $time = $wgLang->date( $frev->getTimestamp(), true ); |
| 145 | + $flags = $frev->getTags(); |
| 146 | + $quality = FlaggedRevs::isQuality( $flags ); |
| 147 | + $msg = $quality ? 'revreview-quality-source' : 'revreview-basic-source'; |
| 148 | + $tag = wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time ); |
| 149 | + # Hide clutter |
| 150 | + if( !FlaggedRevs::useSimpleUI() && !empty($flags) ) { |
| 151 | + $tag .= " " . FlaggedRevsXML::ratingToggle() . |
| 152 | + "<span id='mw-revisionratings' style='display:block;'><br/>" . |
| 153 | + wfMsgHtml('revreview-oldrating') . |
| 154 | + FlaggedRevsXML::addTagRatings( $flags ) . '</span>'; |
| 155 | + } |
| 156 | + $tag = "<div id='mw-revisiontag-old' class='flaggedrevs_notice plainlinks noprint'>$tag</div>"; |
| 157 | + $wgOut->addHTML( $tag ); |
| 158 | + } |
| 159 | + return true; |
| 160 | + } |
| 161 | + |
| 162 | + /** |
| 163 | + * Replaces a page with the last stable version if possible |
| 164 | + * Adds stable version status/info tags and notes |
| 165 | + * Adds a quick review form on the bottom if needed |
| 166 | + */ |
| 167 | + public function setPageContent( &$outputDone, &$pcache ) { |
| 168 | + global $wgRequest, $wgOut, $wgUser, $wgLang, $wgContLang; |
| 169 | + $this->load(); |
| 170 | + # Only trigger on article view for content pages, not for protect/delete/hist... |
| 171 | + $action = $wgRequest->getVal( 'action', 'view' ); |
| 172 | + if( !self::isViewAction($action) || !$this->article->exists() ) |
| 173 | + return true; |
| 174 | + # Do not clutter up diffs any further and leave archived versions alone... |
| 175 | + if( $wgRequest->getVal('diff') || $wgRequest->getVal('oldid') ) { |
| 176 | + return true; |
| 177 | + } |
| 178 | + # Only trigger for reviewable pages |
| 179 | + if( !$this->article->isReviewable() ) { |
| 180 | + return true; |
| 181 | + } |
| 182 | + # Load required messages |
| 183 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 184 | + $simpleTag = $old = $stable = false; |
| 185 | + $tag = $prot = ''; |
| 186 | + # Check the newest stable version. |
| 187 | + $frev = $srev = $this->article->getStableRev(); |
| 188 | + $stableId = $frev ? $frev->getRevId() : 0; |
| 189 | + # Also, check for any explicitly requested old stable version... |
| 190 | + $reqId = $wgRequest->getVal('stableid'); |
| 191 | + if( $reqId === "best" ) { |
| 192 | + $reqId = FlaggedRevs::getPrimeFlaggedRevId( $this->article ); |
| 193 | + } |
| 194 | + if( $stableId && $reqId ) { |
| 195 | + # Treat requesting the stable version by ID as &stable=1 |
| 196 | + if( $reqId != $stableId ) { |
| 197 | + $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId, FR_TEXT ); |
| 198 | + $old = true; // old reviewed version requested by ID |
| 199 | + if( !$frev ) { |
| 200 | + $wgOut->addWikiText( wfMsg('revreview-invalid') ); |
| 201 | + $wgOut->returnToMain( false, $this->article->getTitle() ); |
| 202 | + # Tell MW that parser output is done |
| 203 | + $outputDone = true; |
| 204 | + $pcache = false; |
| 205 | + return true; |
| 206 | + } |
| 207 | + } else { |
| 208 | + $stable = true; // stable version requested by ID |
| 209 | + } |
| 210 | + } |
| 211 | + // Is the page config altered? |
| 212 | + if( $this->article->isPageLocked() ) { |
| 213 | + $prot = "<span class='fr-icon-locked' title=\"". |
| 214 | + wfMsgHtml('revreview-locked-title')."\"></span>"; |
| 215 | + } elseif( $this->article->isPageUnlocked() ) { |
| 216 | + $prot = "<span class='fr-icon-unlocked' title=\"". |
| 217 | + wfMsgHtml('revreview-unlocked-title')."\"></span>"; |
| 218 | + } |
| 219 | + // RTL langauges |
| 220 | + $rtl = $wgContLang->isRTL() ? " rtl" : ""; |
| 221 | + // Is there no stable version? |
| 222 | + if( is_null($frev) ) { |
| 223 | + // Add "no reviewed version" tag, but not for printable output. |
| 224 | + if( !$wgOut->isPrintable() ) { |
| 225 | + // Simple icon-based UI |
| 226 | + if( FlaggedRevs::useSimpleUI() ) { |
| 227 | + $msg = $old ? 'revreview-quick-invalid' : 'revreview-quick-none'; |
| 228 | + $tag .= "{$prot}<span class='fr-icon-current plainlinks'></span>" . |
| 229 | + wfMsgExt($msg,array('parseinline')); |
| 230 | + $tag = "<div id='mw-revisiontag' class='flaggedrevs_short{$rtl} plainlinks noprint'>$tag</div>"; |
| 231 | + $this->reviewNotice .= $tag; |
| 232 | + // Standard UI |
| 233 | + } else { |
| 234 | + $msg = $old ? 'revreview-invalid' : 'revreview-noflagged'; |
| 235 | + $tag = "<div id='mw-revisiontag' class='flaggedrevs_notice plainlinks noprint'>" . |
| 236 | + "{$prot}<span class='fr-icon-current plainlinks'></span>" . |
| 237 | + wfMsgExt($msg, array('parseinline')) . "</div>"; |
| 238 | + $this->reviewNotice .= $tag; |
| 239 | + } |
| 240 | + } |
| 241 | + # Show notice bar/icon |
| 242 | + $this->displayTag(); |
| 243 | + return true; |
| 244 | + } |
| 245 | + # Get flags and date |
| 246 | + $time = $wgLang->date( $frev->getTimestamp(), true ); |
| 247 | + $flags = $frev->getTags(); |
| 248 | + # Get quality level |
| 249 | + $quality = FlaggedRevs::isQuality( $flags ); |
| 250 | + $pristine = FlaggedRevs::isPristine( $flags ); |
| 251 | + // Looking at some specific old stable revision ("&stableid=x") |
| 252 | + // set to override given the relevant conditions. If the user is |
| 253 | + // requesting the stable revision ("&stableid=x"), defer to override |
| 254 | + // behavior below, since it is the same as ("&stable=1"). |
| 255 | + if( $old ) { |
| 256 | + $this->showOldReviewedVersion( $srev, $frev, $tag, $prot ); |
| 257 | + $outputDone = true; # Tell MW that parser output is done |
| 258 | + $pcache = false; |
| 259 | + // Looking at some specific old revision (&oldid=x) or if FlaggedRevs is not |
| 260 | + // set to override given the relevant conditions (like &stable=0). |
| 261 | + } elseif( !$stable && !$this->pageOverride() ) { |
| 262 | + $this->showRegularVersion( $srev, $tag, $prot ); |
| 263 | + // The relevant conditions are met to override the page with the stable version. |
| 264 | + } else { |
| 265 | + $this->showStableVersion( $srev, $tag, $prot ); |
| 266 | + $outputDone = true; # Tell MW that parser output is done |
| 267 | + $pcache = false; |
| 268 | + } |
| 269 | + # Some checks for which tag CSS to use |
| 270 | + if( FlaggedRevs::useSimpleUI() ) $tagClass = 'flaggedrevs_short'; |
| 271 | + elseif( $simpleTag ) $tagClass = 'flaggedrevs_notice'; |
| 272 | + elseif( $pristine ) $tagClass = 'flaggedrevs_pristine'; |
| 273 | + elseif( $quality ) $tagClass = 'flaggedrevs_quality'; |
| 274 | + else $tagClass = 'flaggedrevs_basic'; |
| 275 | + # Wrap tag contents in a div |
| 276 | + if( $tag != '' ) { |
| 277 | + $tag = "<div id='mw-revisiontag' class='{$tagClass}{$rtl} plainlinks noprint'>$tag</div>"; |
| 278 | + $this->reviewNotice .= $tag; |
| 279 | + } |
| 280 | + # Show notice bar/icon |
| 281 | + $this->displayTag(); |
| 282 | + |
| 283 | + return true; |
| 284 | + } |
| 285 | + |
| 286 | + /** |
| 287 | + * @param $srev stable version |
| 288 | + * @param $tag review box/bar info |
| 289 | + * @param $prot protection notice |
| 290 | + * Tag output function must be called by caller |
| 291 | + * Parser cache control deferred to caller |
| 292 | + */ |
| 293 | + protected function showRegularVersion( $srev, &$tag, $prot ) { |
| 294 | + global $wgUser, $wgOut, $wgLang, $wgRequest; |
| 295 | + $this->load(); |
| 296 | + $flags = $srev->getTags(); |
| 297 | + $time = $wgLang->date( $srev->getTimestamp(), true ); |
| 298 | + # Get quality level |
| 299 | + $quality = FlaggedRevs::isQuality( $flags ); |
| 300 | + $pristine = FlaggedRevs::isPristine( $flags ); |
| 301 | + $revsSince = FlaggedRevs::getRevCountSince( $this->article, $srev->getRevId() ); |
| 302 | + # Get stable version sync status |
| 303 | + $synced = FlaggedRevs::stableVersionIsSynced( $srev, $this->article ); |
| 304 | + if( $synced ) { |
| 305 | + $this->getReviewNotes( $srev ); // Still the same |
| 306 | + } else { |
| 307 | + $this->maybeShowTopDiff( $srev, $quality ); // user may want diff (via prefs) |
| 308 | + } |
| 309 | + $pending = ''; |
| 310 | + # Give notice to newer users if an unreviewed edit was completed... |
| 311 | + if( !$synced && $wgRequest->getVal('shownotice') && !$wgUser->isAllowed('review') ) { |
| 312 | + $tooltip = wfMsgHtml('revreview-draft-title'); |
| 313 | + $pending = "{$prot}<span class='fr-icon-current' title=\"{$tooltip}\"></span>" . |
| 314 | + wfMsgExt('revreview-edited',array('parseinline'),$srev->getRevId(),$revsSince); |
| 315 | + $pending = "<div id='mw-reviewnotice' class='flaggedrevs_preview plainlinks'>$pending</div>"; |
| 316 | + # Notice should always use subtitle |
| 317 | + $this->reviewNotice = $pending; |
| 318 | + } |
| 319 | + # If they are synced, do special styling |
| 320 | + $simpleTag = !$synced; |
| 321 | + # Construct some tagging for non-printable outputs. Note that the pending |
| 322 | + # notice has all this info already, so don't do this if we added that already. |
| 323 | + if( !$wgOut->isPrintable() && !$pending && !($this->article->lowProfileUI() && $synced) ) { |
| 324 | + $class = 'fr-icon-current'; // default |
| 325 | + $tooltip = 'revreview-draft-title'; |
| 326 | + // Simple icon-based UI |
| 327 | + if( FlaggedRevs::useSimpleUI() ) { |
| 328 | + if( $synced ) { |
| 329 | + $msg = $quality ? 'revreview-quick-quality-same' : 'revreview-quick-basic-same'; |
| 330 | + $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable'; |
| 331 | + $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title'; |
| 332 | + $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince ); |
| 333 | + } else { |
| 334 | + $msg = $quality ? 'revreview-quick-see-quality' : 'revreview-quick-see-basic'; |
| 335 | + $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince ); |
| 336 | + } |
| 337 | + $tooltip = wfMsgHtml($tooltip); |
| 338 | + $msgHTML = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>$msgHTML"; |
| 339 | + $tag .= FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML, $revsSince, |
| 340 | + $synced, $synced, false ); |
| 341 | + // Standard UI |
| 342 | + } else { |
| 343 | + if( $synced ) { |
| 344 | + $msg = $quality ? 'revreview-quality-same' : 'revreview-basic-same'; |
| 345 | + $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable'; |
| 346 | + $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title'; |
| 347 | + $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), |
| 348 | + $time, $revsSince ); |
| 349 | + } else { |
| 350 | + $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic'; |
| 351 | + $msg .= ($revsSince == 0) ? '-i' : ''; |
| 352 | + $msgHTML = wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), |
| 353 | + $time, $revsSince ); |
| 354 | + } |
| 355 | + $tooltip = wfMsgHtml($tooltip); |
| 356 | + $tag .= "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" . $msgHTML; |
| 357 | + # Hide clutter |
| 358 | + if( !empty($flags) ) { |
| 359 | + $tag .= " " . FlaggedRevsXML::ratingToggle(); |
| 360 | + $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" . |
| 361 | + wfMsgHtml('revreview-oldrating') . FlaggedRevsXML::addTagRatings( $flags ) . '</span>'; |
| 362 | + } |
| 363 | + } |
| 364 | + } |
| 365 | + # Index the stable version only if it is the default |
| 366 | + if( $this->article->showStableByDefault() ) { |
| 367 | + $wgOut->setRobotPolicy( 'noindex,nofollow' ); |
| 368 | + } |
| 369 | + } |
| 370 | + |
| 371 | + /** |
| 372 | + * @param $srev stable version |
| 373 | + * @param $frev selected flagged revision |
| 374 | + * @param $tag review box/bar info |
| 375 | + * @param $prot protection notice |
| 376 | + * Tag output function must be called by caller |
| 377 | + * Parser cache control deferred to caller |
| 378 | + */ |
| 379 | + protected function showOldReviewedVersion( $srev, $frev, &$tag, $prot ) { |
| 380 | + global $wgOut, $wgLang; |
| 381 | + $this->load(); |
| 382 | + $flags = $frev->getTags(); |
| 383 | + $time = $wgLang->date( $frev->getTimestamp(), true ); |
| 384 | + # Set display revision ID |
| 385 | + $wgOut->setRevisionId( $frev->getRevId() ); |
| 386 | + # Get quality level |
| 387 | + $quality = FlaggedRevs::isQuality( $flags ); |
| 388 | + $pristine = FlaggedRevs::isPristine( $flags ); |
| 389 | + $revsSince = FlaggedRevs::getRevCountSince( $this->article, $srev->getRevId() ); |
| 390 | + $text = $frev->getRevText(); |
| 391 | + $parserOut = FlaggedRevs::parseStableText( $this->article, $text, $frev->getRevId() ); |
| 392 | + # Construct some tagging for non-printable outputs. Note that the pending |
| 393 | + # notice has all this info already, so don't do this if we added that already. |
| 394 | + if( !$wgOut->isPrintable() ) { |
| 395 | + $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable'; |
| 396 | + $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title'; |
| 397 | + $tooltip = wfMsgHtml($tooltip); |
| 398 | + // Simple icon-based UI |
| 399 | + if( FlaggedRevs::useSimpleUI() ) { |
| 400 | + $msg = $quality ? 'revreview-quick-quality-old' : 'revreview-quick-basic-old'; |
| 401 | + $html = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" . |
| 402 | + wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time ); |
| 403 | + $tag = FlaggedRevsXML::prettyRatingBox( $frev, $html, $revsSince, |
| 404 | + true, false, true ); |
| 405 | + // Standard UI |
| 406 | + } else { |
| 407 | + $msg = $quality ? 'revreview-quality-old' : 'revreview-basic-old'; |
| 408 | + $tag = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" . |
| 409 | + wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time ); |
| 410 | + # Hide clutter |
| 411 | + if( !empty($flags) ) { |
| 412 | + $tag .= " " . FlaggedRevsXML::ratingToggle(); |
| 413 | + $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" . |
| 414 | + wfMsgHtml('revreview-oldrating') . |
| 415 | + FlaggedRevsXML::addTagRatings( $flags ) . '</span>'; |
| 416 | + } |
| 417 | + } |
| 418 | + } |
| 419 | + # Output HTML |
| 420 | + $this->getReviewNotes( $frev ); |
| 421 | + $wgOut->addParserOutput( $parserOut ); |
| 422 | + # Index the stable version only |
| 423 | + $wgOut->setRobotPolicy( 'noindex,nofollow' ); |
| 424 | + } |
| 425 | + |
| 426 | + /** |
| 427 | + * @param $srev stable version |
| 428 | + * @param $tag review box/bar info |
| 429 | + * @param $prot protection notice |
| 430 | + * Tag output function must be called by caller |
| 431 | + * Parser cache control deferred to caller |
| 432 | + */ |
| 433 | + protected function showStableVersion( $srev, &$tag, $prot ) { |
| 434 | + global $wgOut, $wgLang, $wgUser; |
| 435 | + $this->load(); |
| 436 | + $flags = $srev->getTags(); |
| 437 | + $time = $wgLang->date( $srev->getTimestamp(), true ); |
| 438 | + # Set display revision ID |
| 439 | + $wgOut->setRevisionId( $srev->getRevId() ); |
| 440 | + # Get quality level |
| 441 | + $quality = FlaggedRevs::isQuality( $flags ); |
| 442 | + $pristine = FlaggedRevs::isPristine( $flags ); |
| 443 | + # We will be looking at the reviewed revision... |
| 444 | + $revsSince = FlaggedRevs::getRevCountSince( $this->article, $srev->getRevId() ); |
| 445 | + # Get parsed stable version |
| 446 | + $parserOut = FlaggedRevs::getPageCache( $this->article, $wgUser ); |
| 447 | + if( $parserOut == false ) { |
| 448 | + $text = $srev->getRevText(); |
| 449 | + $parserOut = FlaggedRevs::parseStableText( $this->article, $text, $srev->getRevId() ); |
| 450 | + # Update the stable version cache |
| 451 | + FlaggedRevs::updatePageCache( $this->article, $wgUser, $parserOut ); |
| 452 | + } |
| 453 | + $synced = FlaggedRevs::stableVersionIsSynced( $srev, $this->article, $parserOut, null ); |
| 454 | + # Construct some tagging |
| 455 | + if( !$wgOut->isPrintable() && !($this->article->lowProfileUI() && $synced) ) { |
| 456 | + $class = $quality ? 'fr-icon-quality' : 'fr-icon-stable'; |
| 457 | + $tooltip = $quality ? 'revreview-quality-title' : 'revreview-stable-title'; |
| 458 | + $tooltip = wfMsgHtml($tooltip); |
| 459 | + // Simple icon-based UI |
| 460 | + if( FlaggedRevs::useSimpleUI() ) { |
| 461 | + $msg = $quality ? 'revreview-quick-quality' : 'revreview-quick-basic'; |
| 462 | + # uses messages 'revreview-quick-quality-same', 'revreview-quick-basic-same' |
| 463 | + $msg = $synced ? "{$msg}-same" : $msg; |
| 464 | + $html = "{$prot}<span class='{$class}' title=\"{$tooltip}\"></span>" . |
| 465 | + wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $revsSince ); |
| 466 | + $tag = FlaggedRevsXML::prettyRatingBox( $srev, $html, $revsSince, true, $synced ); |
| 467 | + // Standard UI |
| 468 | + } else { |
| 469 | + $msg = $quality ? 'revreview-quality' : 'revreview-basic'; |
| 470 | + if( $synced ) { |
| 471 | + # uses messages 'revreview-quality-same', 'revreview-basic-same' |
| 472 | + $msg .= '-same'; |
| 473 | + } elseif( $revsSince == 0 ) { |
| 474 | + # uses messages 'revreview-quality-i', 'revreview-basic-i' |
| 475 | + $msg .= '-i'; |
| 476 | + } |
| 477 | + $tag = "{$prot}<span class='{$class} plainlinks' title=\"{$tooltip}\"></span>" . |
| 478 | + wfMsgExt( $msg, array('parseinline'), $srev->getRevId(), $time, $revsSince ); |
| 479 | + if( !empty($flags) ) { |
| 480 | + $tag .= " " . FlaggedRevsXML::ratingToggle(); |
| 481 | + $tag .= "<span id='mw-revisionratings' style='display:block;'><br/>" . |
| 482 | + FlaggedRevsXML::addTagRatings( $flags ) . '</span>'; |
| 483 | + } |
| 484 | + } |
| 485 | + } |
| 486 | + # Output HTML |
| 487 | + $this->getReviewNotes( $srev ); |
| 488 | + $wgOut->addParserOutput( $parserOut ); |
| 489 | + } |
| 490 | + |
| 491 | + /** |
| 492 | + * @param FlaggedRevision $srev, stable version |
| 493 | + * @param bool $quality, revision is quality |
| 494 | + * @returns bool, diff added to output |
| 495 | + */ |
| 496 | + protected function maybeShowTopDiff( $srev, $quality ) { |
| 497 | + global $wgUser, $wgOut, $wgMemc; |
| 498 | + $this->load(); |
| 499 | + if( !$wgUser->getBoolOption('flaggedrevsviewdiffs') ) |
| 500 | + return false; // nothing to do here |
| 501 | + if( !$wgUser->isAllowed('review') ) |
| 502 | + return false; // does not apply to this user |
| 503 | + # Diff should only show for the draft |
| 504 | + $oldid = $this->article->getOldIDFromRequest(); |
| 505 | + $latest = $this->article->getLatest(); |
| 506 | + if( $oldid && $oldid != $latest ) { |
| 507 | + return false; // not viewing the draft |
| 508 | + } |
| 509 | + # Conditions are met to show diff... |
| 510 | + wfLoadExtensionMessages( 'FlaggedRevs' ); // load required messages |
| 511 | + $leftNote = $quality ? 'revreview-quality-title' : 'revreview-stable-title'; |
| 512 | + $rClass = FlaggedRevsXML::getQualityColor( false ); |
| 513 | + $lClass = FlaggedRevsXML::getQualityColor( (int)$quality ); |
| 514 | + $rightNote = "<span class='$rClass'>[".wfMsgHtml('revreview-draft-title')."]</span>"; |
| 515 | + $leftNote = "<span class='$lClass'>[".wfMsgHtml($leftNote)."]</span>"; |
| 516 | + # Fetch the stable and draft revision text |
| 517 | + $oText = $srev->getRevText(); |
| 518 | + if( $oText === false ) |
| 519 | + return false; // deleted revision or something? |
| 520 | + $nText = $this->article->getContent(); |
| 521 | + if( $nText === false ) |
| 522 | + return false; // deleted revision or something? |
| 523 | + # Build diff at the top of the page |
| 524 | + if( strcmp($oText,$nText) !== 0 ) { |
| 525 | + $diffEngine = new DifferenceEngine(); |
| 526 | + $diffEngine->showDiffStyle(); |
| 527 | + $n = $this->article->getTitle()->countRevisionsBetween( $srev->getRevId(), $latest ); |
| 528 | + if( $n ) { |
| 529 | + $multiNotice = "<tr><td colspan='4' align='center' class='diff-multi'>" . |
| 530 | + wfMsgExt( 'diff-multi', array( 'parse' ), $n )."</td></tr>"; |
| 531 | + } else { |
| 532 | + $multiNotice = ''; |
| 533 | + } |
| 534 | + $wgOut->addHTML( |
| 535 | + "<div>" . |
| 536 | + "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" . |
| 537 | + "<col class='diff-marker' />" . |
| 538 | + "<col class='diff-content' />" . |
| 539 | + "<col class='diff-marker' />" . |
| 540 | + "<col class='diff-content' />" . |
| 541 | + "<tr>" . |
| 542 | + "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" . |
| 543 | + $leftNote . "</b></td>" . |
| 544 | + "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" . |
| 545 | + $rightNote . "</b></td>" . |
| 546 | + "</tr>" . |
| 547 | + $multiNotice . |
| 548 | + $diffEngine->generateDiffBody( $oText, $nText ) . |
| 549 | + "</table>" . |
| 550 | + "</div>\n" |
| 551 | + ); |
| 552 | + $this->isDiffFromStable = true; |
| 553 | + return true; |
| 554 | + } |
| 555 | + return false; |
| 556 | + } |
| 557 | + |
| 558 | + /** |
| 559 | + * Get the normal and display files for the underlying ImagePage. |
| 560 | + * If the a stable version needs to be displayed, this will set $normalFile |
| 561 | + * to the current version, and $displayFile to the desired version. |
| 562 | + * |
| 563 | + * If no stable version is required, the reference parameters will not be set |
| 564 | + * |
| 565 | + * Depends on $wgRequest |
| 566 | + */ |
| 567 | + public function imagePageFindFile( &$normalFile, &$displayFile ) { |
| 568 | + global $wgRequest, $wgArticle; |
| 569 | + $this->load(); |
| 570 | + # Determine timestamp. A reviewed version may have explicitly been requested... |
| 571 | + $frev = null; |
| 572 | + $time = false; |
| 573 | + if( $reqId = $wgRequest->getVal('stableid') ) { |
| 574 | + $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId ); |
| 575 | + } elseif( $this->pageOverride() ) { |
| 576 | + $frev = $this->article->getStableRev(); |
| 577 | + } |
| 578 | + if( !is_null($frev) ) { |
| 579 | + $time = $frev->getFileTimestamp(); |
| 580 | + // B/C, may be stored in associated image version metadata table |
| 581 | + if( !$time ) { |
| 582 | + $dbr = wfGetDB( DB_SLAVE ); |
| 583 | + $time = $dbr->selectField( 'flaggedimages', |
| 584 | + 'fi_img_timestamp', |
| 585 | + array( 'fi_rev_id' => $frev->getRevId(), |
| 586 | + 'fi_name' => $this->article->getTitle()->getDBkey() ), |
| 587 | + __METHOD__ |
| 588 | + ); |
| 589 | + } |
| 590 | + # NOTE: if not found, this will use the current |
| 591 | + $wgArticle = new ImagePage( $this->article->getTitle(), $time ); |
| 592 | + } |
| 593 | + if( !$time ) { |
| 594 | + # Try request parameter |
| 595 | + $time = $wgRequest->getVal( 'filetimestamp', false ); |
| 596 | + } |
| 597 | + |
| 598 | + if( !$time ) { |
| 599 | + return; // Use the default behaviour |
| 600 | + } |
| 601 | + |
| 602 | + $title = $this->article->getTitle(); |
| 603 | + $displayFile = wfFindFile( $title, array( 'time' => $time ) ); |
| 604 | + # If none found, try current |
| 605 | + if( !$displayFile ) { |
| 606 | + wfDebug( __METHOD__.": {$title->getPrefixedDBkey()}: $time not found, using current\n" ); |
| 607 | + $displayFile = wfFindFile( $title ); |
| 608 | + # If none found, use a valid local placeholder |
| 609 | + if( !$displayFile ) { |
| 610 | + $displayFile = wfLocalFile( $title ); // fallback to current |
| 611 | + } |
| 612 | + $normalFile = $displayFile; |
| 613 | + # If found, set $normalFile |
| 614 | + } else { |
| 615 | + wfDebug( __METHOD__.": {$title->getPrefixedDBkey()}: using timestamp $time\n" ); |
| 616 | + $normalFile = wfFindFile( $title ); |
| 617 | + } |
| 618 | + } |
| 619 | + |
| 620 | + /** |
| 621 | + * Adds latest stable version tag to page when editing |
| 622 | + */ |
| 623 | + public function addToEditView( $editPage ) { |
| 624 | + global $wgRequest, $wgOut; |
| 625 | + $this->load(); |
| 626 | + # Must be reviewable. UI may be limited to unobtrusive patrolling system. |
| 627 | + if( !$this->article->isReviewable() || $this->article->limitedUI() ) |
| 628 | + return true; |
| 629 | + # Show stabilization log |
| 630 | + $this->showStabilityLog(); |
| 631 | + # Set new body html text as that of now |
| 632 | + $tag = $warning = $prot = ''; |
| 633 | + # Check the newest stable version |
| 634 | + $quality = 0; |
| 635 | + if( $frev = $this->article->getStableRev() ) { |
| 636 | + global $wgLang, $wgUser, $wgFlaggedRevsAutoReview; |
| 637 | + # Find out revision id |
| 638 | + $revId = $editPage->oldid ? |
| 639 | + $editPage->oldid : $this->article->getLatest(); |
| 640 | + # If this will be autoreviewed, notify the user... |
| 641 | + if( !FlaggedRevs::lowProfileUI() && $wgFlaggedRevsAutoReview && $wgUser->isAllowed('review') ) { |
| 642 | + # If we are editing some reviewed revision, any changes this user |
| 643 | + # makes will be autoreviewed... |
| 644 | + $ofrev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $revId ); |
| 645 | + if( !is_null($ofrev) ) { |
| 646 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 647 | + $msg = ( $revId==$frev->getRevId() ) ? 'revreview-auto-w' : 'revreview-auto-w-old'; |
| 648 | + $warning = "<div id='mw-autoreviewtag' class='flaggedrevs_warning plainlinks'>" . |
| 649 | + wfMsgExt($msg,array('parseinline')) . "</div>"; |
| 650 | + } |
| 651 | + # Let new users know about review procedure a tag |
| 652 | + } elseif( !$wgUser->getId() && $this->article->showStableByDefault() ) { |
| 653 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 654 | + $warning = "<div id='mw-editwarningtag' class='flaggedrevs_editnotice plainlinks'>" . |
| 655 | + wfMsgExt('revreview-editnotice',array('parseinline')) . "</div>"; |
| 656 | + } |
| 657 | + if( $frev->getRevId() != $revId ) { |
| 658 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 659 | + $time = $wgLang->date( $frev->getTimestamp(), true ); |
| 660 | + $flags = $frev->getTags(); |
| 661 | + if( FlaggedRevs::isQuality($flags) ) { |
| 662 | + $quality = FlaggedRevs::isPristine($flags) ? 2 : 1; |
| 663 | + } |
| 664 | + $revsSince = FlaggedRevs::getRevCountSince( $this->article, $frev->getRevId() ); |
| 665 | + // Is the page config altered? |
| 666 | + if( $this->article->isPageLocked() ) { |
| 667 | + $prot = "<span class='fr-icon-locked' title=\"". |
| 668 | + wfMsgHtml('revreview-locked-title')."\"></span>"; |
| 669 | + } elseif( $this->article->isPageUnlocked() ) { |
| 670 | + $prot = "<span class='fr-icon-unlocked' title=\"". |
| 671 | + wfMsgHtml('revreview-unlocked-title')."\"></span>"; |
| 672 | + } |
| 673 | + # Streamlined UI |
| 674 | + if( FlaggedRevs::useSimpleUI() ) { |
| 675 | + $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic'; |
| 676 | + $msg .= ($revsSince == 0) ? '-i' : ''; |
| 677 | + $tag = "{$prot}<span class='fr-checkbox'></span>" . |
| 678 | + wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time, $revsSince ); |
| 679 | + $tag = "<div id='mw-revisiontag-edit' class='flaggedrevs_editnotice plainlinks'>$tag</div>"; |
| 680 | + # Standard UI |
| 681 | + } else { |
| 682 | + $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic'; |
| 683 | + $msg .= ($revsSince == 0) ? '-i' : ''; |
| 684 | + $tag = "{$prot}<span class='fr-checkbox'></span>" . |
| 685 | + wfMsgExt( $msg, array('parseinline'), $frev->getRevId(), $time, $revsSince ); |
| 686 | + # Hide clutter |
| 687 | + if( !empty($flags) ) { |
| 688 | + $tag .= " " . FlaggedRevsXML::ratingToggle(); |
| 689 | + $tag .= '<span id="mw-revisionratings" style="display:block;"><br/>' . |
| 690 | + wfMsg('revreview-oldrating') . FlaggedRevsXML::addTagRatings( $flags ) . '</span>'; |
| 691 | + } |
| 692 | + $tag = "<div id='mw-revisiontag-edit' class='flaggedrevs_editnotice plainlinks'>$tag</div>"; |
| 693 | + } |
| 694 | + } |
| 695 | + # Output notice and warning for editors |
| 696 | + if( $tag || $warning ) { |
| 697 | + $wgOut->addHTML( $tag . $warning ); |
| 698 | + } |
| 699 | + |
| 700 | + # Show diff to stable, to make things less confusing... |
| 701 | + # This can be disabled via user preferences |
| 702 | + if( $frev->getRevId() < $revId // changes were made |
| 703 | + && $this->showDiffOnEditUser() // stable default and user cannot review |
| 704 | + && $wgUser->getBoolOption('flaggedrevseditdiffs') // not disable via prefs |
| 705 | + ) { |
| 706 | + # Don't show for old revisions, diff, preview, or undo. |
| 707 | + if( $editPage->oldid || $editPage->section === "new" |
| 708 | + || in_array($editPage->formtype,array('diff','preview')) ) |
| 709 | + { |
| 710 | + return true; // nothing to show here |
| 711 | + } |
| 712 | + |
| 713 | + # Conditions are met to show diff... |
| 714 | + wfLoadExtensionMessages( 'FlaggedRevs' ); // load required messages |
| 715 | + $leftNote = $quality ? 'revreview-quality-title' : 'revreview-stable-title'; |
| 716 | + $rClass = FlaggedRevsXML::getQualityColor( false ); |
| 717 | + $lClass = FlaggedRevsXML::getQualityColor( (int)$quality ); |
| 718 | + $rightNote = "<span class='$rClass'>[".wfMsgHtml('revreview-draft-title')."]</span>"; |
| 719 | + $leftNote = "<span class='$lClass'>[".wfMsgHtml($leftNote)."]</span>"; |
| 720 | + $text = $frev->getRevText(); |
| 721 | + # Are we editing a section? |
| 722 | + $section = ($editPage->section == "") ? false : intval($editPage->section); |
| 723 | + if( $section !== false ) { |
| 724 | + $text = $this->article->getSection( $text, $section ); |
| 725 | + } |
| 726 | + if( $text !== false && strcmp($text,$editPage->textbox1) !== 0 ) { |
| 727 | + $diffEngine = new DifferenceEngine(); |
| 728 | + $diffEngine->showDiffStyle(); |
| 729 | + $wgOut->addHTML( |
| 730 | + "<div>" . |
| 731 | + "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" . |
| 732 | + "<col class='diff-marker' />" . |
| 733 | + "<col class='diff-content' />" . |
| 734 | + "<col class='diff-marker' />" . |
| 735 | + "<col class='diff-content' />" . |
| 736 | + "<tr>" . |
| 737 | + "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" . |
| 738 | + $leftNote . "</b></td>" . |
| 739 | + "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" . |
| 740 | + $rightNote . "</b></td>" . |
| 741 | + "</tr>" . |
| 742 | + $diffEngine->generateDiffBody( $text, $editPage->textbox1 ) . |
| 743 | + "</table>" . |
| 744 | + "</div>\n" |
| 745 | + ); |
| 746 | + } |
| 747 | + } |
| 748 | + } |
| 749 | + return true; |
| 750 | + } |
| 751 | + |
| 752 | + protected function showStabilityLog() { |
| 753 | + global $wgOut; |
| 754 | + $this->load(); |
| 755 | + # Only for pages manually made to be stable... |
| 756 | + if( $this->article->isPageLocked() ) { |
| 757 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 758 | + $wgOut->addHTML( "<div class='mw-warning-with-logexcerpt'>" ); |
| 759 | + $wgOut->addWikiMsg( 'revreview-locked' ); |
| 760 | + LogEventsList::showLogExtract( $wgOut, 'stable', |
| 761 | + $this->article->getTitle()->getPrefixedText(), '', array('lim'=>1) ); |
| 762 | + $wgOut->addHTML( "</div>" ); |
| 763 | + # ...or unstable |
| 764 | + } elseif( $this->article->isPageUnlocked() ) { |
| 765 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 766 | + $wgOut->addHTML( "<div class='mw-warning-with-logexcerpt'>" ); |
| 767 | + $wgOut->addWikiMsg( 'revreview-unlocked' ); |
| 768 | + LogEventsList::showLogExtract( $wgOut, 'stable', |
| 769 | + $this->article->getTitle()->getPrefixedText(), '', array('lim'=>1) ); |
| 770 | + $wgOut->addHTML( "</div>" ); |
| 771 | + } |
| 772 | + return true; |
| 773 | + } |
| 774 | + |
| 775 | + /** |
| 776 | + * Add unreviewed pages links |
| 777 | + */ |
| 778 | + public function addToCategoryView() { |
| 779 | + global $wgOut, $wgUser; |
| 780 | + $this->load(); |
| 781 | + if( !$wgUser->isAllowed( 'review' ) ) { |
| 782 | + return true; |
| 783 | + } |
| 784 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 785 | + # Load special page names |
| 786 | + wfLoadExtensionMessages( 'OldReviewedPages' ); |
| 787 | + wfLoadExtensionMessages( 'UnreviewedPages' ); |
| 788 | + |
| 789 | + $category = $this->article->getTitle()->getText(); |
| 790 | + |
| 791 | + $unreviewed = SpecialPage::getTitleFor( 'UnreviewedPages' ); |
| 792 | + $unreviewedLink = $wgUser->getSkin()->makeKnownLinkObj( $unreviewed, |
| 793 | + wfMsgHtml('unreviewedpages'), 'category=' . urlencode($category) ); |
| 794 | + |
| 795 | + $oldreviewed = SpecialPage::getTitleFor( 'OldReviewedPages' ); |
| 796 | + $oldreviewedLink = $wgUser->getSkin()->makeKnownLinkObj( $oldreviewed, |
| 797 | + wfMsgHtml('oldreviewedpages'), 'category=' . urlencode($category) ); |
| 798 | + |
| 799 | + $wgOut->appendSubtitle("<span id='mw-category-oldreviewed'>$unreviewedLink / $oldreviewedLink</span>"); |
| 800 | + |
| 801 | + return true; |
| 802 | + } |
| 803 | + |
| 804 | + /** |
| 805 | + * Add review form to pages when necessary |
| 806 | + */ |
| 807 | + public function addReviewForm( &$data ) { |
| 808 | + global $wgRequest, $wgUser, $wgOut; |
| 809 | + $this->load(); |
| 810 | + # User must have review rights and page must be reviewable |
| 811 | + if( !$wgUser->isAllowed('review') || !$this->article->exists() || !$this->article->isReviewable() ) { |
| 812 | + return true; |
| 813 | + } |
| 814 | + # Unobtrusive patrolling UI only shows forms if requested |
| 815 | + if( !$wgRequest->getInt('reviewform') && $this->article->limitedUI() ) { |
| 816 | + return true; |
| 817 | + } |
| 818 | + # Avoid multi-page diffs that are useless and misbehave (bug 19327) |
| 819 | + if( $this->isMultiPageDiff ) { |
| 820 | + return true; |
| 821 | + } |
| 822 | + # Check action and if page is protected |
| 823 | + $action = $wgRequest->getVal( 'action', 'view' ); |
| 824 | + # Must be view/diff action... |
| 825 | + if( !self::isViewAction($action) ) { |
| 826 | + return true; |
| 827 | + } |
| 828 | + # Place the form at the top or bottom as most convenient |
| 829 | + $onTop = $wgRequest->getVal('diff') || $this->isDiffFromStable; |
| 830 | + $this->addQuickReview( $data, $onTop, false ); |
| 831 | + return true; |
| 832 | + } |
| 833 | + |
| 834 | + /** |
| 835 | + * Add link to stable version setting to protection form |
| 836 | + */ |
| 837 | + public function addVisibilityLink( &$data ) { |
| 838 | + global $wgUser, $wgRequest, $wgOut; |
| 839 | + $this->load(); |
| 840 | + if( FlaggedRevs::getProtectionLevels() ) |
| 841 | + return true; // simple custom levels set for action=protect |
| 842 | + # Check only if the title is reviewable |
| 843 | + if( !$this->article->isReviewable(true) ) { |
| 844 | + return true; |
| 845 | + } |
| 846 | + $action = $wgRequest->getVal( 'action', 'view' ); |
| 847 | + if( $action == 'protect' || $action == 'unprotect' ) { |
| 848 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 849 | + wfLoadExtensionMessages( 'Stabilization' ); // Load special page name |
| 850 | + $title = SpecialPage::getTitleFor( 'Stabilization' ); |
| 851 | + # Give a link to the page to configure the stable version |
| 852 | + $frev = $this->article->getStableRev(); |
| 853 | + if( $frev && $frev->getRevId() == $this->article->getLatest() ) { |
| 854 | + $wgOut->prependHTML( "<span class='plainlinks'>" . |
| 855 | + wfMsgExt( 'revreview-visibility',array('parseinline'), |
| 856 | + $title->getPrefixedText() ) . "</span>" ); |
| 857 | + } elseif( $frev ) { |
| 858 | + $wgOut->prependHTML( "<span class='plainlinks'>" . |
| 859 | + wfMsgExt( 'revreview-visibility2',array('parseinline'), |
| 860 | + $title->getPrefixedText() ) . "</span>" ); |
| 861 | + } else { |
| 862 | + $wgOut->prependHTML( "<span class='plainlinks'>" . |
| 863 | + wfMsgExt( 'revreview-visibility3',array('parseinline'), |
| 864 | + $title->getPrefixedText() ) . "</span>" ); |
| 865 | + } |
| 866 | + } |
| 867 | + return true; |
| 868 | + } |
| 869 | + |
| 870 | + /** |
| 871 | + * Modify an array of action links, as used by SkinTemplateNavigation and |
| 872 | + * SkinTemplateTabs, to inlude flagged revs UI elements |
| 873 | + */ |
| 874 | + public function setActionTabs( $skin, &$actions ) { |
| 875 | + global $wgRequest, $wgUser; |
| 876 | + $this->load(); |
| 877 | + if( FlaggedRevs::getProtectionLevels() ) { |
| 878 | + return true; // simple custom levels set for action=protect |
| 879 | + } |
| 880 | + $title = $this->article->getTitle()->getSubjectPage(); |
| 881 | + if ( !FlaggedRevs::isPageReviewable( $title ) ) { |
| 882 | + return true; // Only reviewable pages need these tabs |
| 883 | + } |
| 884 | + // Check if we should show a stabilization tab |
| 885 | + if ( |
| 886 | + !$skin->mTitle->isTalkPage() && |
| 887 | + is_array( $actions ) && |
| 888 | + !isset( $actions['protect'] ) && |
| 889 | + !isset( $actions['unprotect'] ) && |
| 890 | + $wgUser->isAllowed( 'stablesettings' ) && |
| 891 | + $title->exists() |
| 892 | + ) { |
| 893 | + wfLoadExtensionMessages( 'Stabilization' ); |
| 894 | + $stableTitle = SpecialPage::getTitleFor( 'Stabilization' ); |
| 895 | + // Add a tab |
| 896 | + $actions['default'] = array( |
| 897 | + 'class' => false, |
| 898 | + 'text' => wfMsg( 'stabilization-tab' ), |
| 899 | + 'href' => $stableTitle->getLocalUrl( |
| 900 | + 'page=' . $title->getPrefixedUrl() |
| 901 | + ) |
| 902 | + ); |
| 903 | + } |
| 904 | + return true; |
| 905 | + } |
| 906 | + |
| 907 | + /** |
| 908 | + * Modify an array of view links, as used by SkinTemplateNavigation and |
| 909 | + * SkinTemplateTabs, to inlude flagged revs UI elements |
| 910 | + */ |
| 911 | + public function setViewTabs( $skin, &$views ) { |
| 912 | + global $wgRequest, $wgUser, $wgFlaggedRevTabs; |
| 913 | + $this->load(); |
| 914 | + |
| 915 | + $title = $this->article->getTitle()->getSubjectPage(); // Get the actual content page |
| 916 | + $article = new Article( $title ); |
| 917 | + $action = $wgRequest->getVal( 'action', 'view' ); |
| 918 | + $fa = FlaggedArticle::getTitleInstance( $title ); |
| 919 | + if ( !$fa->isReviewable() || $this->article->limitedUI() ) { |
| 920 | + // This isn't a reviewable page or the UI is hidden |
| 921 | + return true; |
| 922 | + } |
| 923 | + $srev = $this->article->getStableRev( $action == 'rollback' ? FR_MASTER : 0 ); |
| 924 | + if( is_null( $srev ) ) { |
| 925 | + return true; // No stable revision exists |
| 926 | + } |
| 927 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 928 | + $synced = FlaggedRevs::stableVersionIsSynced( $srev, $article ); |
| 929 | + // Set draft tab as needed... |
| 930 | + if ( !$skin->mTitle->isTalkPage() && !$synced ) { |
| 931 | + if ( isset( $views['edit'] ) ) { |
| 932 | + if ( $this->article->showStableByDefault() ) { |
| 933 | + $views['edit']['text'] = wfMsg('revreview-edit'); |
| 934 | + } |
| 935 | + if ( $this->pageOverride() ) { |
| 936 | + $views['edit']['href'] = $title->getLocalUrl( 'action=edit' ); |
| 937 | + } |
| 938 | + } |
| 939 | + if ( isset( $views['viewsource'] ) ) { |
| 940 | + if ( $this->article->showStableByDefault() ) { |
| 941 | + $views['viewsource']['text'] = wfMsg('revreview-source'); |
| 942 | + } |
| 943 | + if ( $this->pageOverride() ) { |
| 944 | + $views['viewsource']['href'] = $title->getLocalUrl( 'action=edit' ); |
| 945 | + } |
| 946 | + } |
| 947 | + } |
| 948 | + if ( !$wgFlaggedRevTabs || $synced ) { |
| 949 | + // Exit, since either the stable/draft tabs should not be shown |
| 950 | + // or the page is already the most current revision |
| 951 | + return true; |
| 952 | + } |
| 953 | + $tabs = array( |
| 954 | + 'stable' => array( |
| 955 | + 'text' => wfMsg( 'revreview-stable' ), // unused |
| 956 | + 'href' => $title->getLocalUrl( 'stable=1' ), |
| 957 | + 'class' => '' |
| 958 | + ), |
| 959 | + 'current' => array( |
| 960 | + 'text' => wfMsg( 'revreview-current' ), |
| 961 | + 'href' => $title->getLocalUrl( 'stable=0&redirect=no' ), |
| 962 | + 'class' => '' |
| 963 | + ), |
| 964 | + ); |
| 965 | + if ( $this->pageOverride() || $wgRequest->getVal( 'stableid' ) ) { |
| 966 | + // We are looking a the stable version |
| 967 | + $tabs['stable']['class'] = 'selected'; |
| 968 | + } elseif ( |
| 969 | + ( self::isViewAction( $action ) || $action == 'edit' ) && |
| 970 | + !$skin->mTitle->isTalkPage() |
| 971 | + ) { |
| 972 | + // We are looking at the current revision or in edit mode |
| 973 | + $tabs['current']['class'] = 'selected'; |
| 974 | + } |
| 975 | + $first = true; |
| 976 | + $newViews = array(); |
| 977 | + foreach ( $views as $tabAction => $data ) { |
| 978 | + // Very first tab (page link) |
| 979 | + if( $first ) { |
| 980 | + if( $synced ) { |
| 981 | + // Use existing first tabs when synced |
| 982 | + $newViews[$tabAction] = $data; |
| 983 | + } else { |
| 984 | + // Use split current and stable tabs when not synced |
| 985 | + $newViews[$tabAction]['text'] = $data['text']; // keep tab name |
| 986 | + $newViews[$tabAction]['href'] = $tabs['stable']['href']; |
| 987 | + $newViews[$tabAction]['class'] = $tabs['stable']['class']; |
| 988 | + $newViews['current'] = $tabs['current']; |
| 989 | + } |
| 990 | + $first = false; |
| 991 | + } else { |
| 992 | + $newViews[$tabAction] = $data; |
| 993 | + } |
| 994 | + } |
| 995 | + // Replaces old tabs with new tabs |
| 996 | + $views = $newViews; |
| 997 | + return true; |
| 998 | + } |
| 999 | + |
| 1000 | + /** |
| 1001 | + * @param FlaggedRevision $frev |
| 1002 | + * @return string, revision review notes |
| 1003 | + */ |
| 1004 | + public function getReviewNotes( $frev ) { |
| 1005 | + global $wgUser; |
| 1006 | + $this->load(); |
| 1007 | + if( FlaggedRevs::allowComments() && $frev && $frev->getComment() ) { |
| 1008 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 1009 | + $notes = "<br/><div class='flaggedrevs_notes plainlinks'>"; |
| 1010 | + $notes .= wfMsgExt('revreview-note', array('parseinline'), User::whoIs( $frev->getUser() ) ); |
| 1011 | + $notes .= '<br/><i>' . $wgUser->getSkin()->formatComment( $frev->getComment() ) . '</i></div>'; |
| 1012 | + $this->reviewNotes = $notes; |
| 1013 | + } |
| 1014 | + } |
| 1015 | + |
| 1016 | + /** |
| 1017 | + * When comparing the stable revision to the current after editing a page, show |
| 1018 | + * a tag with some explaination for the diff. |
| 1019 | + */ |
| 1020 | + public function addDiffNoticeAndIncludes( $diff, $oldRev, $newRev ) { |
| 1021 | + global $wgRequest, $wgUser, $wgOut, $wgMemc; |
| 1022 | + $this->load(); |
| 1023 | + # Page must be reviewable. Exempt printer-friendly output. |
| 1024 | + # UI may be limited to unobtrusive patrolling system |
| 1025 | + if( $wgOut->isPrintable() || !$this->article->isReviewable() || $this->article->limitedUI() ) |
| 1026 | + return true; |
| 1027 | + # Load required messages |
| 1028 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 1029 | + # Check if this might be the diff to stable. If so, enhance it. |
| 1030 | + if( $newRev->isCurrent() && $oldRev ) { |
| 1031 | + $article = new Article( $newRev->getTitle() ); |
| 1032 | + # Try the sync value cache... |
| 1033 | + $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $article->getId() ); |
| 1034 | + $value = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article ); |
| 1035 | + $synced = ($value === "true") ? true : false; // default as false to trigger query |
| 1036 | + $frev = $this->article->getStableRev(); |
| 1037 | + if( $frev && $frev->getRevId() == $oldRev->getID() ) { |
| 1038 | + global $wgParserCacheExpireTime; |
| 1039 | + |
| 1040 | + $changeList = array(); |
| 1041 | + $skin = $wgUser->getSkin(); |
| 1042 | + |
| 1043 | + # Try the cache. Uses format <page ID>-<UNIX timestamp>. |
| 1044 | + $key = wfMemcKey( 'stableDiffs', 'templates', $article->getId() ); |
| 1045 | + $tmpChanges = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article ); |
| 1046 | + if( empty($tmpChanges) && !$synced ) { |
| 1047 | + $tmpChanges = false; // don't use cache |
| 1048 | + } |
| 1049 | + |
| 1050 | + # Make a list of each changed template... |
| 1051 | + if( $tmpChanges === false ) { |
| 1052 | + $dbr = wfGetDB( DB_SLAVE ); |
| 1053 | + // Get templates where the current and stable are not the same revision |
| 1054 | + $ret = $dbr->select( array('flaggedtemplates','page','flaggedpages'), |
| 1055 | + array( 'ft_namespace', 'ft_title', 'fp_stable','ft_tmp_rev_id', 'page_latest' ), |
| 1056 | + array( 'ft_rev_id' => $frev->getRevId(), |
| 1057 | + 'page_namespace = ft_namespace', |
| 1058 | + 'page_title = ft_title' ), |
| 1059 | + __METHOD__, |
| 1060 | + array(), /* OPTIONS */ |
| 1061 | + array( 'flaggedpages' => array('LEFT JOIN','fp_page_id = page_id') ) |
| 1062 | + ); |
| 1063 | + $tmpChanges = array(); |
| 1064 | + while( $row = $dbr->fetchObject( $ret ) ) { |
| 1065 | + $title = Title::makeTitleSafe( $row->ft_namespace, $row->ft_title ); |
| 1066 | + $revIdDraft = $row->page_latest; |
| 1067 | + // stable time -> time when reviewed (unless the other is newer) |
| 1068 | + $revIdStable = isset($row->fp_stable) && $row->fp_stable >= $row->ft_tmp_rev_id ? |
| 1069 | + $row->fp_stable : $row->ft_tmp_rev_id; |
| 1070 | + // compare to current |
| 1071 | + if( $revIdDraft > $revIdStable ) { |
| 1072 | + $tmpChanges[] = $skin->makeKnownLinkObj( $title, $title->getPrefixedText(), |
| 1073 | + "diff=cur&oldid={$revIdStable}" ); |
| 1074 | + } |
| 1075 | + } |
| 1076 | + $wgMemc->set( $key, FlaggedRevs::makeMemcObj($tmpChanges), $wgParserCacheExpireTime ); |
| 1077 | + } |
| 1078 | + # Add set to list |
| 1079 | + if( $tmpChanges ) |
| 1080 | + $changeList += $tmpChanges; |
| 1081 | + |
| 1082 | + # Try the cache. Uses format <page ID>-<UNIX timestamp>. |
| 1083 | + $key = wfMemcKey( 'stableDiffs', 'images', $article->getId() ); |
| 1084 | + $imgChanges = FlaggedRevs::getMemcValue( $wgMemc->get($key), $article ); |
| 1085 | + if( empty($imgChanges) && !$synced ) { |
| 1086 | + $imgChanges = false; // don't use cache |
| 1087 | + } |
| 1088 | + |
| 1089 | + // Get list of each changed image... |
| 1090 | + if( $imgChanges === false ) { |
| 1091 | + $dbr = wfGetDB( DB_SLAVE ); |
| 1092 | + // Get images where the current and stable are not the same revision |
| 1093 | + $ret = $dbr->select( array('flaggedimages','page','image','flaggedpages','flaggedrevs'), |
| 1094 | + array( 'fi_name', 'fi_img_timestamp', 'fr_img_timestamp' ), |
| 1095 | + array( 'fi_rev_id' => $frev->getRevId() ), |
| 1096 | + __METHOD__, |
| 1097 | + array(), /* OPTIONS */ |
| 1098 | + array( 'page' => array('LEFT JOIN','page_namespace = '. NS_FILE .' AND page_title = fi_name'), |
| 1099 | + 'image' => array('LEFT JOIN','img_name = fi_name'), |
| 1100 | + 'flaggedpages' => array('LEFT JOIN','fp_page_id = page_id'), |
| 1101 | + 'flaggedrevs' => array('LEFT JOIN','fr_page_id = fp_page_id AND fr_rev_id = fp_stable') ) |
| 1102 | + ); |
| 1103 | + $imgChanges = array(); |
| 1104 | + while( $row = $dbr->fetchObject( $ret ) ) { |
| 1105 | + $title = Title::makeTitleSafe( NS_FILE, $row->fi_name ); |
| 1106 | + // stable time -> time when reviewed (unless the other is newer) |
| 1107 | + $timestamp = isset($row->fr_img_timestamp) && $row->fr_img_timestamp >= $row->fi_img_timestamp ? |
| 1108 | + $row->fr_img_timestamp : $row->fi_img_timestamp; |
| 1109 | + // compare to current |
| 1110 | + $file = wfFindFile( $title ); |
| 1111 | + if( $file && $file->getTimestamp() > $timestamp ) |
| 1112 | + $imgChanges[] = $skin->makeKnownLinkObj( $title, $title->getPrefixedText() ); |
| 1113 | + } |
| 1114 | + $wgMemc->set( $key, FlaggedRevs::makeMemcObj($imgChanges), $wgParserCacheExpireTime ); |
| 1115 | + } |
| 1116 | + if( $imgChanges ) |
| 1117 | + $changeList += $imgChanges; |
| 1118 | + |
| 1119 | + # Some important information... |
| 1120 | + $notice = ''; |
| 1121 | + if( count($changeList) > 0 ) { |
| 1122 | + $notice = '<br/>' . wfMsgExt('revreview-update-use', array('parseinline')); |
| 1123 | + } elseif( !$synced ) { |
| 1124 | + $diff->mTitle->invalidateCache(); // bad cache, said they were not synced |
| 1125 | + } |
| 1126 | + |
| 1127 | + # If the user is allowed to review, prompt them! |
| 1128 | + if( empty($changeList) && $wgUser->isAllowed('review') ) { |
| 1129 | + $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" . |
| 1130 | + wfMsgExt('revreview-update-none', array('parseinline')).$notice.'</div>' ); |
| 1131 | + } elseif( !empty($changeList) && $wgUser->isAllowed('review') ) { |
| 1132 | + $changeList = implode(', ',$changeList); |
| 1133 | + $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" . |
| 1134 | + wfMsgExt('revreview-update', array('parseinline')).' '. |
| 1135 | + $changeList.$notice.'</div>' ); |
| 1136 | + } elseif( !empty($changeList) ) { |
| 1137 | + $changeList = implode(', ',$changeList); |
| 1138 | + $wgOut->addHTML( "<div id='mw-difftostable' class='flaggedrevs_diffnotice plainlinks'>" . |
| 1139 | + wfMsgExt('revreview-update-includes', array('parseinline')).' '. |
| 1140 | + $changeList.$notice.'</div>' ); |
| 1141 | + } |
| 1142 | + # Set flag for review form to tell it to autoselect tag settings from the |
| 1143 | + # old revision unless the current one is tagged to. |
| 1144 | + if( !FlaggedRevision::newFromTitle( $diff->mTitle, $newRev->getID() ) ) { |
| 1145 | + $this->isDiffFromStable = true; |
| 1146 | + } |
| 1147 | + |
| 1148 | + # Set a key to note that someone is viewing this |
| 1149 | + if( $wgUser->isAllowed('review') ) { |
| 1150 | + $key = wfMemcKey( 'stableDiffs', 'underReview', $oldRev->getID(), $newRev->getID() ); |
| 1151 | + $wgMemc->set( $key, '1', 10*60 ); // 10 min |
| 1152 | + } |
| 1153 | + } |
| 1154 | + } |
| 1155 | + $newRevQ = FlaggedRevs::getRevQuality( $newRev->getPage(), $newRev->getId() ); |
| 1156 | + $oldRevQ = $oldRev ? FlaggedRevs::getRevQuality( $newRev->getPage(), $oldRev->getId() ) : false; |
| 1157 | + # Diff between two revisions |
| 1158 | + if( $oldRev ) { |
| 1159 | + $wgOut->addHTML( "<table class='fr-diff-ratings'><tr>" ); |
| 1160 | + |
| 1161 | + $class = FlaggedRevsXML::getQualityColor( $oldRevQ ); |
| 1162 | + if( $oldRevQ !== false ) { |
| 1163 | + $msg = $oldRevQ ? 'hist-quality' : 'hist-stable'; |
| 1164 | + } else { |
| 1165 | + $msg = 'hist-draft'; |
| 1166 | + } |
| 1167 | + $wgOut->addHTML( "<td width='50%' align='center'>" ); |
| 1168 | + $wgOut->addHTML( "<span class='$class'><b>[" . wfMsgHtml( $msg ) . "]</b></span>" ); |
| 1169 | + |
| 1170 | + $class = FlaggedRevsXML::getQualityColor( $newRevQ ); |
| 1171 | + if( $newRevQ !== false ) { |
| 1172 | + $msg = $newRevQ ? 'hist-quality' : 'hist-stable'; |
| 1173 | + } else { |
| 1174 | + $msg = 'hist-draft'; |
| 1175 | + } |
| 1176 | + $wgOut->addHTML( "</td><td width='50%' align='center'>" ); |
| 1177 | + $wgOut->addHTML( "<span class='$class'><b>[" . wfMsgHtml( $msg ) . "]</b></span>" ); |
| 1178 | + |
| 1179 | + $wgOut->addHTML( '</td></tr></table>' ); |
| 1180 | + # New page "diffs" - just one rev |
| 1181 | + } else { |
| 1182 | + if( $newRevQ !== false ) { |
| 1183 | + $msg = $newRevQ ? 'hist-quality' : 'hist-stable'; |
| 1184 | + } else { |
| 1185 | + $msg = 'hist-draft'; |
| 1186 | + } |
| 1187 | + $wgOut->addHTML( "<table class='fr-diff-ratings'><tr><td class='fr-$msg' align='center'>" ); |
| 1188 | + $wgOut->addHTML( "<b>[" . wfMsgHtml( $msg ) . "]</b>" ); |
| 1189 | + $wgOut->addHTML( '</td></tr></table>' ); |
| 1190 | + } |
| 1191 | + return true; |
| 1192 | + } |
| 1193 | + |
| 1194 | + /** |
| 1195 | + * Set $this->isDiffFromStable and $this->isMultiPageDiff fields |
| 1196 | + */ |
| 1197 | + public function setViewFlags( $diff, $oldRev, $newRev ) { |
| 1198 | + $this->load(); |
| 1199 | + if( $newRev && $oldRev ) { |
| 1200 | + // Is this a diff between two pages? |
| 1201 | + if( $newRev->getPage() != $oldRev->getPage() ) { |
| 1202 | + $this->isMultiPageDiff = true; |
| 1203 | + // Is there a stable version? |
| 1204 | + } else if( $this->article->isReviewable() ) { |
| 1205 | + $frev = $this->article->getStableRev(); |
| 1206 | + // Is this a diff of the draft rev against the stable rev? |
| 1207 | + if( $frev && $frev->getRevId() == $oldRev->getId() && $newRev->isCurrent() ) { |
| 1208 | + $this->isDiffFromStable = true; |
| 1209 | + } |
| 1210 | + } |
| 1211 | + } |
| 1212 | + return true; |
| 1213 | + } |
| 1214 | + |
| 1215 | + /** |
| 1216 | + * Add a link to patrol non-reviewable pages. |
| 1217 | + * Also add a diff-to-stable for other pages if possible. |
| 1218 | + */ |
| 1219 | + public function addDiffLink( $diff, $oldRev, $newRev ) { |
| 1220 | + global $wgUser, $wgOut; |
| 1221 | + $this->load(); |
| 1222 | + // Is there a stable version? |
| 1223 | + if( $newRev && $oldRev && $this->article->isReviewable() ) { |
| 1224 | + $frev = $this->article->getStableRev(); |
| 1225 | + # Give a link to the diff-to-stable if needed |
| 1226 | + if( $frev && !$this->isDiffFromStable ) { |
| 1227 | + $article = new Article( $newRev->getTitle() ); |
| 1228 | + # Is the stable revision using the same revision as the current? |
| 1229 | + if( $article->getLatest() != $frev->getRevId() ) { |
| 1230 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 1231 | + $patrol = '(' . $wgUser->getSkin()->makeKnownLinkObj( $newRev->getTitle(), |
| 1232 | + wfMsgHtml( 'review-diff2stable' ), "oldid={$frev->getRevId()}&diff=cur&diffonly=0" ) . ')'; |
| 1233 | + $wgOut->addHTML( "<div class='fr-diff-to-stable' align='center'>$patrol</div>" ); |
| 1234 | + } |
| 1235 | + } |
| 1236 | + } |
| 1237 | + return true; |
| 1238 | + } |
| 1239 | + |
| 1240 | + /** |
| 1241 | + * Redirect users out to review the changes to the stable version. |
| 1242 | + * Only for people who can review and for pages that have a stable version. |
| 1243 | + */ |
| 1244 | + public function injectReviewDiffURLParams( &$sectionAnchor, &$extraQuery ) { |
| 1245 | + global $wgUser, $wgReviewChangesAfterEdit; |
| 1246 | + $this->load(); |
| 1247 | + # Don't show this for pages that are not reviewable |
| 1248 | + if( !$this->article->isReviewable() || $this->article->getTitle()->isTalkPage() ) |
| 1249 | + return true; |
| 1250 | + # We may want to skip some UI elements |
| 1251 | + if( $this->article->limitedUI() ) return true; |
| 1252 | + # Get the stable version, from master |
| 1253 | + $frev = $this->article->getStableRev( FR_MASTER ); |
| 1254 | + if( !$frev ) |
| 1255 | + return true; |
| 1256 | + $latest = $this->article->getTitle()->getLatestRevID(GAID_FOR_UPDATE); |
| 1257 | + // If we are supposed to review after edit, and it was not autoreviewed, |
| 1258 | + // and the user can actually make new stable version, take us to the diff... |
| 1259 | + if( $wgReviewChangesAfterEdit && $frev && $latest > $frev->getRevId() && $frev->userCanSetFlags() ) { |
| 1260 | + $extraQuery .= $extraQuery ? '&' : ''; |
| 1261 | + $extraQuery .= "oldid={$frev->getRevId()}&diff=cur&diffonly=0"; // override diff-only |
| 1262 | + // ...otherwise, go to the current revision after completing an edit. |
| 1263 | + } else { |
| 1264 | + if( $frev && $latest != $frev->getRevId() ) { |
| 1265 | + $extraQuery .= "stable=0"; |
| 1266 | + if( !$wgUser->isAllowed('review') && $this->article->showStableByDefault() ) { |
| 1267 | + $extraQuery .= "&shownotice=1"; |
| 1268 | + } |
| 1269 | + } |
| 1270 | + } |
| 1271 | + return true; |
| 1272 | + } |
| 1273 | + |
| 1274 | + /** |
| 1275 | + * Add a hidden revision ID field to edit form. |
| 1276 | + * Needed for autoreview so it can select the flags from said revision. |
| 1277 | + */ |
| 1278 | + public function addRevisionIDField( $editPage, $out ) { |
| 1279 | + global $wgRequest; |
| 1280 | + $this->load(); |
| 1281 | + # Find out revision id |
| 1282 | + if( $this->article->mRevision ) { |
| 1283 | + $revId = $this->article->mRevision->mId; |
| 1284 | + } else { |
| 1285 | + $latest = $this->article->getTitle()->getLatestRevID(GAID_FOR_UPDATE); |
| 1286 | + $revId = $latest; |
| 1287 | + wfDebug( 'FlaggedArticle::addRevisionIDField - ID not specified, assumed current' ); |
| 1288 | + } |
| 1289 | + # If undoing a few consecutive top edits, we know the base ID |
| 1290 | + if( $undo = $wgRequest->getIntOrNull('undo') ) { |
| 1291 | + $undoAfter = $wgRequest->getIntOrNull('undoafter'); |
| 1292 | + $latest = isset($latest) ? |
| 1293 | + $latest : $this->article->getTitle()->getLatestRevID(GAID_FOR_UPDATE); |
| 1294 | + if( $undoAfter && $undo == $this->article->getLatest() ) { |
| 1295 | + $revId = $undoAfter; |
| 1296 | + } |
| 1297 | + } |
| 1298 | + $out->addHTML( "\n" . Xml::hidden( 'baseRevId', $revId ) ); |
| 1299 | + $out->addHTML( "\n" . Xml::hidden( 'undidRev', |
| 1300 | + empty($editPage->undidRev) ? 0 : $editPage->undidRev ) |
| 1301 | + ); |
| 1302 | + return true; |
| 1303 | + } |
| 1304 | + |
| 1305 | + /** |
| 1306 | + * Adds brief review notes to a page. |
| 1307 | + * @param OutputPage $out |
| 1308 | + */ |
| 1309 | + public function addReviewNotes( &$data ) { |
| 1310 | + $this->load(); |
| 1311 | + if( $this->reviewNotes ) { |
| 1312 | + $data .= $this->reviewNotes; |
| 1313 | + } |
| 1314 | + return true; |
| 1315 | + } |
| 1316 | + |
| 1317 | + /** |
| 1318 | + * Adds a brief review form to a page. |
| 1319 | + * @param string $data |
| 1320 | + * @param bool $top |
| 1321 | + * @param bool hide |
| 1322 | + * @param bool $top, should this form always go on top? |
| 1323 | + */ |
| 1324 | + public function addQuickReview( &$data, $top = false, $hide = false ) { |
| 1325 | + global $wgOut, $wgUser, $wgRequest; |
| 1326 | + $this->load(); |
| 1327 | + # Get the revision being displayed |
| 1328 | + $id = $wgOut->getRevisionId(); |
| 1329 | + if( !$id ) { |
| 1330 | + if( !$this->isDiffFromStable ) { |
| 1331 | + return false; // only safe to assume current if diff-to-stable |
| 1332 | + } else { |
| 1333 | + $rev = Revision::newFromTitle( $this->article->getTitle() ); |
| 1334 | + $id = $rev->getId(); |
| 1335 | + } |
| 1336 | + } else { |
| 1337 | + $rev = Revision::newFromTitle( $this->article->getTitle(), $id ); |
| 1338 | + } |
| 1339 | + # Load required messages |
| 1340 | + wfLoadExtensionMessages( 'FlaggedRevs' ); |
| 1341 | + # Must be a valid non-printable output and revision must be public |
| 1342 | + if( $wgOut->isPrintable() || !$rev || $rev->isDeleted(Revision::DELETED_TEXT) ) { |
| 1343 | + return false; |
| 1344 | + } |
| 1345 | + $useCurrent = false; |
| 1346 | + if( !isset($wgOut->mTemplateIds) || !isset($wgOut->fr_ImageSHA1Keys) ) { |
| 1347 | + $useCurrent = true; |
| 1348 | + } |
| 1349 | + $skin = $wgUser->getSkin(); |
| 1350 | + |
| 1351 | + $config = $this->article->getVisibilitySettings(); |
| 1352 | + # Variable for sites with no flags, otherwise discarded |
| 1353 | + $approve = $wgRequest->getBool('wpApprove'); |
| 1354 | + # See if the version being displayed is flagged... |
| 1355 | + $oldFlags = $this->article->getFlagsForRevision( $id ); |
| 1356 | + # If we are reviewing updates to a page, start off with the stable revision's |
| 1357 | + # flags. Otherwise, we just fill them in with the selected revision's flags. |
| 1358 | + if( $this->isDiffFromStable ) { |
| 1359 | + $srev = $this->article->getStableRev(); |
| 1360 | + $flags = $srev->getTags(); |
| 1361 | + # Check if user is allowed to renew the stable version. |
| 1362 | + # If not, then get the flags for the new revision itself. |
| 1363 | + if( !RevisionReview::userCanSetFlags( $oldFlags ) ) { |
| 1364 | + $flags = $oldFlags; |
| 1365 | + } |
| 1366 | + $encNotes = $srev->getComment(); |
| 1367 | + } else { |
| 1368 | + $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $id ); |
| 1369 | + $flags = $oldFlags; |
| 1370 | + $encNotes = $frev ? $frev->getComment() : ""; // pre-fill notes |
| 1371 | + } |
| 1372 | + |
| 1373 | + $reviewTitle = SpecialPage::getTitleFor( 'RevisionReview' ); |
| 1374 | + $action = $reviewTitle->getLocalUrl( 'action=submit' ); |
| 1375 | + $params = array( 'method' => 'post', 'action' => $action, 'id' => 'mw-reviewform' ); |
| 1376 | + if( $hide ) { |
| 1377 | + $params['class'] = 'fr-hiddenform'; |
| 1378 | + } |
| 1379 | + $form = Xml::openElement( 'form', $params ); |
| 1380 | + $form .= Xml::openElement( 'fieldset', array('class' => 'flaggedrevs_reviewform noprint') ); |
| 1381 | + $form .= "<legend><strong>" . wfMsgHtml( 'revreview-flag', $id ) . "</strong></legend>\n"; |
| 1382 | + |
| 1383 | + # Show explanatory text |
| 1384 | + if( !FlaggedRevs::lowProfileUI() ) { |
| 1385 | + $msg = FlaggedRevs::showStableByDefault() ? 'revreview-text' : 'revreview-text2'; |
| 1386 | + $form .= wfMsgExt( $msg, array('parse') ); |
| 1387 | + } |
| 1388 | + |
| 1389 | + # Current user has too few rights to change at least one flag, thus entire form disabled |
| 1390 | + $uneditable = !$this->article->getTitle()->quickUserCan('edit'); |
| 1391 | + $disabled = !RevisionReview::userCanSetFlags( $flags ) || $uneditable; |
| 1392 | + if( $disabled ) { |
| 1393 | + $form .= Xml::openElement( 'div', array('class' => 'fr-rating-controls-disabled', |
| 1394 | + 'id' => 'fr-rating-controls-disabled') ); |
| 1395 | + $toggle = array( 'disabled' => "disabled" ); |
| 1396 | + } else { |
| 1397 | + $form .= Xml::openElement( 'div', array('class' => 'fr-rating-controls', |
| 1398 | + 'id' => 'fr-rating-controls') ); |
| 1399 | + $toggle = array(); |
| 1400 | + } |
| 1401 | + # Add main checkboxes/selects |
| 1402 | + $form .= Xml::openElement( 'span', array('id' => 'mw-ratingselects') ); |
| 1403 | + $form .= FlaggedRevsXML::ratingInputs( $flags, $config, $disabled ); |
| 1404 | + $form .= Xml::closeElement( 'span' ); |
| 1405 | + |
| 1406 | + if( FlaggedRevs::allowComments() && $wgUser->isAllowed( 'validate' ) ) { |
| 1407 | + $form .= "<div id='mw-notebox'>\n"; |
| 1408 | + $form .= "<p>".wfMsgHtml( 'revreview-notes' ) . "</p>\n"; |
| 1409 | + $form .= Xml::openElement( 'textarea', array('name' => 'wpNotes', 'id' => 'wpNotes', |
| 1410 | + 'class' => 'fr-notes-box', 'rows' => '2', 'cols' => '80') ) . |
| 1411 | + htmlspecialchars( $encNotes ) . |
| 1412 | + Xml::closeElement('textarea') . "\n"; |
| 1413 | + $form .= "</div>\n"; |
| 1414 | + } |
| 1415 | + # Get versions of templates/files used |
| 1416 | + $imageParams = $templateParams = $fileVersion = ''; |
| 1417 | + if( $useCurrent ) { |
| 1418 | + # Get parsed current version |
| 1419 | + $parserCache = ParserCache::singleton(); |
| 1420 | + $article = $this->article; |
| 1421 | + $currentOutput = $parserCache->get( $article, $wgUser ); |
| 1422 | + if( $currentOutput == false ) { |
| 1423 | + global $wgParser, $wgEnableParserCache; |
| 1424 | + $text = $article->getContent(); |
| 1425 | + $title = $article->getTitle(); |
| 1426 | + $options = FlaggedRevs::makeParserOptions(); |
| 1427 | + $currentOutput = $wgParser->parse( $text, $title, $options ); |
| 1428 | + # Might as well save the cache while we're at it |
| 1429 | + if( $wgEnableParserCache ) |
| 1430 | + $parserCache->save( $currentOutput, $article, $wgUser ); |
| 1431 | + } |
| 1432 | + $templateIDs = $currentOutput->mTemplateIds; |
| 1433 | + $imageSHA1Keys = $currentOutput->fr_ImageSHA1Keys; |
| 1434 | + } else { |
| 1435 | + $templateIDs = $wgOut->mTemplateIds; |
| 1436 | + $imageSHA1Keys = $wgOut->fr_ImageSHA1Keys; |
| 1437 | + } |
| 1438 | + list($templateParams,$imageParams,$fileVersion) = |
| 1439 | + FlaggedRevs::getIncludeParams( $this->article, $templateIDs, $imageSHA1Keys ); |
| 1440 | + |
| 1441 | + $form .= Xml::openElement( 'span', array('style' => 'white-space: nowrap;') ); |
| 1442 | + # Hide comment if needed |
| 1443 | + if( !$disabled ) { |
| 1444 | + if( count(FlaggedRevs::getDimensions()) > 1 ) |
| 1445 | + $form .= "<br/>"; // Don't put too much on one line |
| 1446 | + $form .= "<span id='mw-commentbox' style='clear:both'>" . |
| 1447 | + Xml::inputLabel( wfMsg('revreview-log'), 'wpReason', 'wpReason', 40, '', |
| 1448 | + array('class' => 'fr-comment-box') ) . " </span>"; |
| 1449 | + } |
| 1450 | + $form .= Xml::submitButton( wfMsg('revreview-submit'), |
| 1451 | + array( |
| 1452 | + 'id' => 'submitreview', 'accesskey' => wfMsg('revreview-ak-review'), |
| 1453 | + 'title' => wfMsg('revreview-tt-review').' ['.wfMsg('revreview-ak-review').']' |
| 1454 | + ) + $toggle |
| 1455 | + ); |
| 1456 | + $form .= Xml::closeElement( 'span' ); |
| 1457 | + |
| 1458 | + $form .= Xml::closeElement( 'div' ) . "\n"; |
| 1459 | + |
| 1460 | + # Show stability log if there is anything interesting... |
| 1461 | + if( $this->article->isPageLocked() ) { |
| 1462 | + $loglist = new LogEventsList( $wgUser->getSkin(), $wgOut, LogEventsList::NO_ACTION_LINK ); |
| 1463 | + $pager = new LogPager( $loglist, 'stable', '', $this->article->getTitle()->getPrefixedDBKey() ); |
| 1464 | + $pager->mLimit = 1; // top item |
| 1465 | + if( ($logBody = $pager->getBody()) ) { |
| 1466 | + $form .= "<div><ul style='list-style:none; margin: 0;'>$logBody</ul></div>"; |
| 1467 | + } |
| 1468 | + } |
| 1469 | + |
| 1470 | + # Hidden params |
| 1471 | + $form .= Xml::hidden( 'title', $reviewTitle->getPrefixedText() ) . "\n"; |
| 1472 | + $form .= Xml::hidden( 'target', $this->article->getTitle()->getPrefixedDBKey() ) . "\n"; |
| 1473 | + $form .= Xml::hidden( 'oldid', $id ) . "\n"; |
| 1474 | + $form .= Xml::hidden( 'action', 'submit') . "\n"; |
| 1475 | + $form .= Xml::hidden( 'wpEditToken', $wgUser->editToken() ) . "\n"; |
| 1476 | + # Add review parameters |
| 1477 | + $form .= Xml::hidden( 'templateParams', $templateParams ) . "\n"; |
| 1478 | + $form .= Xml::hidden( 'imageParams', $imageParams ) . "\n"; |
| 1479 | + $form .= Xml::hidden( 'fileVersion', $fileVersion ) . "\n"; |
| 1480 | + # Pass this in if given; useful for new page patrol |
| 1481 | + $form .= Xml::hidden( 'rcid', $wgRequest->getVal('rcid') ) . "\n"; |
| 1482 | + # Special token to discourage fiddling... |
| 1483 | + $checkCode = RevisionReview::validationKey( $templateParams, $imageParams, $fileVersion, $id ); |
| 1484 | + $form .= Xml::hidden( 'validatedParams', $checkCode ) . "\n"; |
| 1485 | + |
| 1486 | + $form .= Xml::closeElement( 'fieldset' ); |
| 1487 | + $form .= Xml::closeElement( 'form' ); |
| 1488 | + # Place form at the correct position specified by $top |
| 1489 | + if( $top ) { |
| 1490 | + $wgOut->prependHTML( $form ); |
| 1491 | + } else { |
| 1492 | + $data .= $form; |
| 1493 | + } |
| 1494 | + return true; |
| 1495 | + } |
| 1496 | + |
| 1497 | + /** |
| 1498 | + * Updates parser cache output to included needed versioning params. |
| 1499 | + */ |
| 1500 | + public function maybeUpdateMainCache( &$outputDone, &$pcache ) { |
| 1501 | + global $wgUser, $wgRequest; |
| 1502 | + $this->load(); |
| 1503 | + |
| 1504 | + $action = $wgRequest->getVal( 'action', 'view' ); |
| 1505 | + if( $action == 'purge' ) |
| 1506 | + return true; // already purging! |
| 1507 | + # Only trigger on article view for content pages, not for protect/delete/hist |
| 1508 | + if( !self::isViewAction($action) || !$wgUser->isAllowed( 'review' ) ) |
| 1509 | + return true; |
| 1510 | + if( !$this->article->exists() || !$this->article->isReviewable() ) |
| 1511 | + return true; |
| 1512 | + |
| 1513 | + $parserCache = ParserCache::singleton(); |
| 1514 | + $parserOut = $parserCache->get( $this->article, $wgUser ); |
| 1515 | + if( $parserOut ) { |
| 1516 | + # Clear older, incomplete, cached versions |
| 1517 | + # We need the IDs of templates and timestamps of images used |
| 1518 | + if( !isset($parserOut->fr_newestTemplateID) || !isset($parserOut->fr_newestImageTime) ) |
| 1519 | + $this->article->getTitle()->invalidateCache(); |
| 1520 | + } |
| 1521 | + return true; |
| 1522 | + } |
| 1523 | +} |
Property changes on: trunk/extensions/FlaggedRevs/FlaggedArticleView.php |
___________________________________________________________________ |
Name: svn:eol-style |
1524 | 1524 | + native |