r85956 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r85955‎ | r85956 | r85957 >
Date:16:46, 13 April 2011
Author:aaron
Status:ok
Tags:
Comment:
Various cleanups:
* Renamed FlaggedArticle -> FlaggedPage
* Renamed FlaggedArticleView -> FlaggedPageView
* Replaced "@returns" with "@return", and "@return Array" with "@return array"
* Changed "mixed" param docs to be more specific
* Changed "Array" type hints to "array"
Modified paths:
  • /trunk/extensions/FlaggedRevs/FRDependencyUpdate.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FRInclusionManager.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FRUserActivity.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FRUserCounters.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedArticle.php (deleted) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedPage.php (added) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedPageConfig.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedRevision.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedRevs.class.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedRevs.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedRevsLog.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/api/actions/ApiReview.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/business/PageStabilityForm.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/business/RevisionReviewForm.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/maintenance/purgeReviewablePages.inc (modified) (history)
  • /trunk/extensions/FlaggedRevs/maintenance/updateTracking.inc (modified) (history)
  • /trunk/extensions/FlaggedRevs/presentation/FlaggedArticleView.php (deleted) (history)
  • /trunk/extensions/FlaggedRevs/presentation/FlaggedPageView.php (added) (history)
  • /trunk/extensions/FlaggedRevs/presentation/FlaggedRevsLogView.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/presentation/FlaggedRevsXML.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/presentation/RejectConfirmationFormGUI.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/presentation/RevisionReviewFormGUI.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/presentation/modules/review.js (modified) (history)
  • /trunk/extensions/FlaggedRevs/presentation/specialpages/reports/QualityOversight_body.php (modified) (history)

Diff [purge]

Index: trunk/extensions/FlaggedRevs/FlaggedArticle.php
@@ -1,541 +0,0 @@
2 -<?php
3 -/**
4 - * Class representing a MediaWiki article and history
5 - *
6 - * FlaggedArticle::getTitleInstance() is preferred over constructor calls
7 - */
8 -class FlaggedArticle extends Article {
9 - /* Process cache variables */
10 - protected $stable = 0;
11 - protected $stableRev = null;
12 - protected $revsArePending = null;
13 - protected $pendingRevCount = null;
14 - protected $pageConfig = null;
15 - protected $syncedInTracking = null;
16 -
17 - protected $imagePage = null; // for file pages
18 -
19 - /**
20 - * Get a FlaggedArticle for a given title
21 - * @param Title
22 - * @return FlaggedArticle
23 - */
24 - public static function getTitleInstance( Title $title ) {
25 - // Check if there is already an instance on this title
26 - if ( !isset( $title->flaggedRevsArticle ) ) {
27 - $title->flaggedRevsArticle = new self( $title );
28 - }
29 - return $title->flaggedRevsArticle;
30 - }
31 -
32 - /**
33 - * Get a FlaggedArticle for a given article
34 - * @param Article
35 - * @return FlaggedArticle
36 - */
37 - public static function getArticleInstance( Article $article ) {
38 - return self::getTitleInstance( $article->mTitle );
39 - }
40 -
41 - /**
42 - * Clear object process cache values
43 - * @return void
44 - */
45 - public function clear() {
46 - $this->stable = 0;
47 - $this->stableRev = null;
48 - $this->revsArePending = null;
49 - $this->pendingRevCount = null;
50 - $this->pageConfig = null;
51 - $this->syncedInTracking = null;
52 - $this->imagePage = null;
53 - parent::clear(); // call super!
54 - }
55 -
56 - /**
57 - * Get the current file version of this file page
58 - * @TODO: kind of hacky
59 - * @return mixed (File/false)
60 - */
61 - public function getFile() {
62 - if ( $this->mTitle->getNamespace() != NS_FILE ) {
63 - return false; // not a file page
64 - }
65 - if ( is_null( $this->imagePage ) ) {
66 - $this->imagePage = new ImagePage( $this->mTitle );
67 - }
68 - return $this->imagePage->getFile();
69 - }
70 -
71 - /**
72 - * Get the displayed file version of this file page
73 - * @TODO: kind of hacky
74 - * @return mixed (File/false)
75 - */
76 - public function getDisplayedFile() {
77 - if ( $this->mTitle->getNamespace() != NS_FILE ) {
78 - return false; // not a file page
79 - }
80 - if ( is_null( $this->imagePage ) ) {
81 - $this->imagePage = new ImagePage( $this->mTitle );
82 - }
83 - return $this->imagePage->getDisplayedFile();
84 - }
85 -
86 - /**
87 - * Is the stable version shown by default for this page?
88 - * @return bool
89 - */
90 - public function isStableShownByDefault() {
91 - if ( !$this->isReviewable() ) {
92 - return false; // no stable versions can exist
93 - }
94 - $config = $this->getStabilitySettings(); // page configuration
95 - return (bool)$config['override'];
96 - }
97 -
98 - /**
99 - * Do edits have to be reviewed before being shown by default (going live)?
100 - * @return bool
101 - */
102 - public function editsRequireReview() {
103 - return (
104 - $this->isReviewable() && // reviewable page
105 - $this->isStableShownByDefault() && // and stable versions override
106 - $this->getStableRev() // and there is a stable version
107 - );
108 - }
109 -
110 - /**
111 - * Are edits to this page currently pending?
112 - * @return bool
113 - */
114 - public function revsArePending() {
115 - if ( !$this->mDataLoaded ) {
116 - $this->loadPageData();
117 - }
118 - return $this->revsArePending;
119 - }
120 -
121 - /**
122 - * Get number of revs since the stable revision
123 - * Note: slower than revsArePending()
124 - * @param int $flags FR_MASTER (be sure to use loadFromDB( FR_MASTER ) if set)
125 - * @return int
126 - */
127 - public function getPendingRevCount( $flags = 0 ) {
128 - global $wgMemc, $wgParserCacheExpireTime;
129 - if ( !$this->mDataLoaded ) {
130 - $this->loadPageData();
131 - }
132 - # Pending count deferred even after page data load
133 - if ( $this->pendingRevCount !== null ) {
134 - return $this->pendingRevCount; // use process cache
135 - }
136 - $srev = $this->getStableRev();
137 - if ( !$srev ) {
138 - return 0; // none
139 - }
140 - $count = null;
141 - $sRevId = $srev->getRevId();
142 - # Try the cache...
143 - $key = wfMemcKey( 'flaggedrevs', 'countPending', $this->getId() );
144 - if ( !( $flags & FR_MASTER ) ) {
145 - $tuple = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $this );
146 - # Items is cached and newer that page_touched...
147 - if ( $tuple !== false ) {
148 - # Confirm that cache value was made against the same stable rev Id.
149 - # This avoids lengthy cache pollution if $sRevId is outdated.
150 - list( $cRevId, $cPending ) = explode( '-', $tuple, 2 );
151 - if ( $cRevId == $sRevId ) {
152 - $count = (int)$cPending;
153 - }
154 - }
155 - }
156 - # Otherwise, fetch result from DB as needed...
157 - if ( is_null( $count ) ) {
158 - $db = ( $flags & FR_MASTER ) ?
159 - wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
160 - $srevTS = $db->timestamp( $srev->getRevTimestamp() );
161 - $count = $db->selectField( 'revision', 'COUNT(*)',
162 - array( 'rev_page' => $this->getId(),
163 - 'rev_timestamp > ' . $db->addQuotes( $srevTS ) ), // bug 15515
164 - __METHOD__ );
165 - # Save result to cache...
166 - $data = FlaggedRevs::makeMemcObj( "{$sRevId}-{$count}" );
167 - $wgMemc->set( $key, $data, $wgParserCacheExpireTime );
168 - }
169 - $this->pendingRevCount = $count;
170 - return $this->pendingRevCount;
171 - }
172 -
173 - /**
174 - * Checks if the stable version is synced with the current revision
175 - * Note: slower than getPendingRevCount()
176 - * @return bool
177 - */
178 - public function stableVersionIsSynced() {
179 - global $wgMemc, $wgParserCacheExpireTime;
180 - $srev = $this->getStableRev();
181 - if ( !$srev ) {
182 - return true;
183 - }
184 - # Stable text revision must be the same as the current
185 - if ( $this->revsArePending() ) {
186 - return false;
187 - # Stable file revision must be the same as the current
188 - } elseif ( $this->mTitle->getNamespace() == NS_FILE ) {
189 - $file = $this->getFile(); // current upload version
190 - if ( $file && $file->getTimestamp() > $srev->getFileTimestamp() ) {
191 - return false;
192 - }
193 - }
194 - # If using the current version of includes, there is nothing else to check.
195 - if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_CURRENT ) {
196 - return true; // short-circuit
197 - }
198 - # Try the cache...
199 - $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $this->getId() );
200 - $value = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $this );
201 - if ( $value === "true" ) {
202 - return true;
203 - } elseif ( $value === "false" ) {
204 - return false;
205 - }
206 - # Since the stable and current revisions have the same text and only outputs,
207 - # the only other things to check for are template and file differences in the output.
208 - # (a) Check if the current output has a newer template/file used
209 - # (b) Check if the stable version has a file/template that was deleted
210 - $synced = ( !$srev->findPendingTemplateChanges()
211 - && !$srev->findPendingFileChanges( 'noForeign' ) );
212 - # Save to cache. This will be updated whenever the page is touched.
213 - $data = FlaggedRevs::makeMemcObj( $synced ? "true" : "false" );
214 - $wgMemc->set( $key, $data, $wgParserCacheExpireTime );
215 -
216 - return $synced;
217 - }
218 -
219 - /**
220 - * Are template/file changes and ONLY template/file changes pending?
221 - * @return bool
222 - */
223 - public function onlyTemplatesOrFilesPending() {
224 - return ( !$this->revsArePending() && !$this->stableVersionIsSynced() );
225 - }
226 -
227 - /**
228 - * Is this page less open than the site defaults?
229 - * @return bool
230 - */
231 - public function isPageLocked() {
232 - return ( !FlaggedRevs::isStableShownByDefault() && $this->isStableShownByDefault() );
233 - }
234 -
235 - /**
236 - * Is this page more open than the site defaults?
237 - * @return bool
238 - */
239 - public function isPageUnlocked() {
240 - return ( FlaggedRevs::isStableShownByDefault() && !$this->isStableShownByDefault() );
241 - }
242 -
243 - /**
244 - * Tags are only shown for unreviewed content and this page is not locked/unlocked?
245 - * @return bool
246 - */
247 - public function lowProfileUI() {
248 - return FlaggedRevs::lowProfileUI() &&
249 - FlaggedRevs::isStableShownByDefault() == $this->isStableShownByDefault();
250 - }
251 -
252 - /**
253 - * Is this article reviewable?
254 - * @return bool
255 - */
256 - public function isReviewable() {
257 - if ( !FlaggedRevs::inReviewNamespace( $this->mTitle ) ) {
258 - return false;
259 - }
260 - # Check if flagging is disabled for this page via config
261 - if ( FlaggedRevs::useOnlyIfProtected() ) {
262 - $config = $this->getStabilitySettings(); // page configuration
263 - return (bool)$config['override']; // stable is default or flagging disabled
264 - }
265 - return true;
266 - }
267 -
268 - /**
269 - * Is this page in patrollable?
270 - * @return bool
271 - */
272 - public function isPatrollable() {
273 - if ( !FlaggedRevs::inPatrolNamespace( $this->mTitle ) ) {
274 - return false;
275 - }
276 - return !$this->isReviewable(); // pages that are reviewable are not patrollable
277 - }
278 -
279 - /**
280 - * Get the stable revision ID
281 - * @return int
282 - */
283 - public function getStable() {
284 - if ( !$this->mDataLoaded ) {
285 - $this->loadPageData();
286 - }
287 - return (int)$this->stable;
288 - }
289 -
290 - /**
291 - * Get the stable revision
292 - * @return mixed (FlaggedRevision/null)
293 - */
294 - public function getStableRev() {
295 - if ( !$this->mDataLoaded ) {
296 - $this->loadPageData();
297 - }
298 - # Stable rev deferred even after page data load
299 - if ( $this->stableRev === null ) {
300 - $srev = FlaggedRevision::newFromTitle( $this->mTitle, $this->stable );
301 - $this->stableRev = $srev ? $srev : false; // cache negative hits too
302 - }
303 - return $this->stableRev ? $this->stableRev : null; // false => null
304 - }
305 -
306 - /**
307 - * Get visiblity restrictions on page
308 - * @return Array (select,override)
309 - */
310 - public function getStabilitySettings() {
311 - if ( !$this->mDataLoaded ) {
312 - $this->loadPageData();
313 - }
314 - return $this->pageConfig;
315 - }
316 -
317 - /*
318 - * Get the fp_reviewed value for this page
319 - * @return bool
320 - */
321 - public function syncedInTracking() {
322 - if ( !$this->mDataLoaded ) {
323 - $this->loadPageData();
324 - }
325 - return $this->syncedInTracking;
326 - }
327 -
328 - /**
329 - * Fetch a page record with the given conditions
330 - * @param $dbr Database object
331 - * @param $conditions Array
332 - * @return mixed Database result resource, or false on failure
333 - */
334 - protected function pageData( $dbr, $conditions ) {
335 - $row = $dbr->selectRow(
336 - array( 'page', 'flaggedpages', 'flaggedpage_config' ),
337 - array_merge(
338 - Article::selectFields(),
339 - FlaggedPageConfig::selectFields(),
340 - array( 'fp_pending_since', 'fp_stable', 'fp_reviewed' ) ),
341 - $conditions,
342 - __METHOD__,
343 - array(),
344 - array(
345 - 'flaggedpages' => array( 'LEFT JOIN', 'fp_page_id = page_id' ),
346 - 'flaggedpage_config' => array( 'LEFT JOIN', 'fpc_page_id = page_id' ) )
347 - );
348 - return $row;
349 - }
350 -
351 - /**
352 - * Set the page field data loaded from some source
353 - * @param $data Database row object or "fromdb"
354 - * @return void
355 - */
356 - public function loadPageData( $data = 'fromdb' ) {
357 - $this->mDataLoaded = true; // sanity
358 - # Fetch data from DB as needed...
359 - if ( $data === 'fromdb' ) {
360 - $data = $this->pageDataFromTitle( wfGetDB( DB_SLAVE ), $this->mTitle );
361 - }
362 - # Load in primary page data...
363 - parent::loadPageData( $data /* Row obj */ );
364 - # Load in FlaggedRevs page data...
365 - $this->stable = 0; // 0 => "found nothing"
366 - $this->stableRev = null; // defer this one...
367 - $this->revsArePending = false; // false => "found nothing" or "none pending"
368 - $this->pendingRevCount = null; // defer this one...
369 - $this->pageConfig = FlaggedPageConfig::getDefaultVisibilitySettings(); // default
370 - $this->syncedInTracking = true; // false => "unreviewed" or "synced"
371 - # Load in Row data if the page exists...
372 - if ( $data ) {
373 - if ( $data->fpc_override !== null ) { // page config row found
374 - $this->pageConfig = FlaggedPageConfig::getVisibilitySettingsFromRow( $data );
375 - }
376 - if ( $data->fp_stable !== null ) { // stable rev found
377 - $this->stable = (int)$data->fp_stable;
378 - $this->revsArePending = ( $data->fp_pending_since !== null ); // revs await review
379 - $this->syncedInTracking = (bool)$data->fp_reviewed;
380 - }
381 - }
382 - }
383 -
384 - /**
385 - * Set the page field data loaded from the DB
386 - * @param int $flags FR_MASTER
387 - * @param $data Database row object or "fromdb"
388 - */
389 - public function loadFromDB( $flags = 0 ) {
390 - $db = ( $flags & FR_MASTER ) ?
391 - wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
392 - $this->loadPageData( $this->pageDataFromTitle( $db, $this->mTitle ) );
393 - }
394 -
395 - /**
396 - * Updates the flagging tracking tables for this page
397 - * @param FlaggedRevision $srev The new stable version
398 - * @param mixed $latest The latest rev ID (optional)
399 - * @return bool Updates were done
400 - */
401 - public function updateStableVersion( FlaggedRevision $srev, $latest = null ) {
402 - $rev = $srev->getRevision();
403 - if ( !$this->exists() || !$rev ) {
404 - return false; // no bogus entries
405 - }
406 - # Get the latest revision ID if not set
407 - if ( !$latest ) {
408 - $latest = $this->mTitle->getLatestRevID( Title::GAID_FOR_UPDATE );
409 - }
410 - $dbw = wfGetDB( DB_MASTER );
411 - # Get the highest quality revision (not necessarily this one)...
412 - if ( $srev->getQuality() === FlaggedRevs::highestReviewTier() ) {
413 - $maxQuality = $srev->getQuality(); // save a query
414 - } else {
415 - $maxQuality = $dbw->selectField( array( 'flaggedrevs', 'revision' ),
416 - 'fr_quality',
417 - array( 'fr_page_id' => $this->getId(),
418 - 'rev_id = fr_rev_id',
419 - 'rev_page = fr_page_id',
420 - 'rev_deleted & ' . Revision::DELETED_TEXT => 0
421 - ),
422 - __METHOD__,
423 - array( 'ORDER BY' => 'fr_quality DESC', 'LIMIT' => 1 )
424 - );
425 - $maxQuality = max( $maxQuality, $srev->getQuality() ); // sanity
426 - }
427 - # Get the timestamp of the first edit after the stable version (if any)...
428 - $nextTimestamp = null;
429 - if ( $rev->getId() != $latest ) {
430 - $timestamp = $dbw->timestamp( $rev->getTimestamp() );
431 - $nextEditTS = $dbw->selectField( 'revision',
432 - 'rev_timestamp',
433 - array(
434 - 'rev_page' => $this->getId(),
435 - "rev_timestamp > " . $dbw->addQuotes( $timestamp ) ),
436 - __METHOD__,
437 - array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1 )
438 - );
439 - if ( $nextEditTS ) { // sanity check
440 - $nextTimestamp = $nextEditTS;
441 - }
442 - }
443 - # Get the new page sync status...
444 - $synced = !(
445 - $nextTimestamp !== null || // edits pending
446 - $srev->findPendingTemplateChanges() || // template changes pending
447 - $srev->findPendingFileChanges( 'noForeign' ) // file changes pending
448 - );
449 - # Alter table metadata
450 - $dbw->replace( 'flaggedpages',
451 - array( 'fp_page_id' ),
452 - array(
453 - 'fp_page_id' => $this->getId(),
454 - 'fp_stable' => $rev->getId(),
455 - 'fp_reviewed' => $synced ? 1 : 0,
456 - 'fp_quality' => ( $maxQuality === false ) ? null : $maxQuality,
457 - 'fp_pending_since' => $dbw->timestampOrNull( $nextTimestamp )
458 - ),
459 - __METHOD__
460 - );
461 - # Update pending edit tracking table
462 - self::updatePendingList( $this->getId(), $latest );
463 - return true;
464 - }
465 -
466 - /**
467 - * Updates the flagging tracking tables for this page
468 - * @return void
469 - */
470 - public function clearStableVersion() {
471 - if ( !$this->exists() ) {
472 - return; // nothing to do
473 - }
474 - $dbw = wfGetDB( DB_MASTER );
475 - $dbw->delete( 'flaggedpages',
476 - array( 'fp_page_id' => $this->getId() ), __METHOD__ );
477 - $dbw->delete( 'flaggedpage_pending',
478 - array( 'fpp_page_id' => $this->getId() ), __METHOD__ );
479 - }
480 -
481 - /**
482 - * Updates the flaggedpage_pending table
483 - * @param int $pageId Page ID
484 - * @abstract int $latest Latest revision
485 - * @return void
486 - */
487 - protected static function updatePendingList( $pageId, $latest ) {
488 - $data = array();
489 - $level = FlaggedRevs::highestReviewTier();
490 - # Update pending times for each level, going from highest to lowest
491 - $dbw = wfGetDB( DB_MASTER );
492 - $higherLevelId = 0;
493 - $higherLevelTS = '';
494 - while ( $level >= 0 ) {
495 - # Get the latest revision of this level...
496 - $row = $dbw->selectRow( array( 'flaggedrevs', 'revision' ),
497 - array( 'fr_rev_id', 'rev_timestamp' ),
498 - array( 'fr_page_id' => $pageId,
499 - 'fr_quality' => $level,
500 - 'rev_id = fr_rev_id',
501 - 'rev_page = fr_page_id',
502 - 'rev_deleted & ' . Revision::DELETED_TEXT => 0,
503 - 'rev_id > ' . intval( $higherLevelId )
504 - ),
505 - __METHOD__,
506 - array( 'ORDER BY' => 'fr_rev_id DESC', 'LIMIT' => 1 )
507 - );
508 - # If there is a revision of this level, track it...
509 - # Revisions reviewed to one level count as reviewed
510 - # at the lower levels (i.e. quality -> checked).
511 - if ( $row ) {
512 - $id = $row->fr_rev_id;
513 - $ts = $row->rev_timestamp;
514 - } else {
515 - $id = $higherLevelId; // use previous (quality -> checked)
516 - $ts = $higherLevelTS; // use previous (quality -> checked)
517 - }
518 - # Get edits that actually are pending...
519 - if ( $id && $latest > $id ) {
520 - # Get the timestamp of the edit after this version (if any)
521 - $nextTimestamp = $dbw->selectField( 'revision',
522 - 'rev_timestamp',
523 - array( 'rev_page' => $pageId, "rev_timestamp > " . $dbw->addQuotes( $ts ) ),
524 - __METHOD__,
525 - array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1 )
526 - );
527 - $data[] = array(
528 - 'fpp_page_id' => $pageId,
529 - 'fpp_quality' => $level,
530 - 'fpp_rev_id' => $id,
531 - 'fpp_pending_since' => $nextTimestamp
532 - );
533 - $higherLevelId = $id;
534 - $higherLevelTS = $ts;
535 - }
536 - $level--;
537 - }
538 - # Clear any old junk, and insert new rows
539 - $dbw->delete( 'flaggedpage_pending', array( 'fpp_page_id' => $pageId ), __METHOD__ );
540 - $dbw->insert( 'flaggedpage_pending', $data, __METHOD__ );
541 - }
542 -}
Index: trunk/extensions/FlaggedRevs/FRUserCounters.php
@@ -8,7 +8,7 @@
99 * @param int $uid
1010 * @param int $flags FR_MASTER, FR_FOR_UPDATE
1111 * @param string $dBName, optional wiki name
12 - * @returns array
 12+ * @return array
1313 */
1414 public static function getUserParams( $uid, $flags = 0, $dBName = false ) {
1515 $p = array();
@@ -44,7 +44,7 @@
4545 * @param int $uid
4646 * @param int $flags FR_MASTER, FR_FOR_UPDATE
4747 * @param string $dBName, optional wiki name
48 - * @returns mixed (false or Row)
 48+ * @return mixed (false or Row)
4949 */
5050 protected static function fetchParamsRow( $uid, $flags = 0, $dBName = false ) {
5151 $options = array();
@@ -67,7 +67,7 @@
6868 * @param int $uid
6969 * @param array $params
7070 * @param string $dBName, optional wiki name
71 - * @returns bool success
 71+ * @return bool success
7272 */
7373 public static function saveUserParams( $uid, array $params, $dBName = false ) {
7474 $dbw = wfGetDB( DB_MASTER, array(), $dBName );
@@ -84,7 +84,7 @@
8585 * Flatten params for a user for DB storage
8686 * Note: param values must be integers
8787 * @param array $params
88 - * @returns string
 88+ * @return string
8989 */
9090 protected static function flattenParams( array $params ) {
9191 $flatRows = array();
@@ -105,7 +105,7 @@
106106 /**
107107 * Expand params for a user from DB storage
108108 * @param string $flatPars
109 - * @returns array
 109+ * @return array
110110 */
111111 protected static function expandParams( $flatPars ) {
112112 $p = array(); // init
@@ -131,7 +131,7 @@
132132 * @param &array $p user params
133133 * @param Article $article the article just edited
134134 * @param string $summary edit summary
135 - * @returns bool anything changed
 135+ * @return bool anything changed
136136 */
137137 public static function updateUserParams( array &$p, Article $article, $summary ) {
138138 global $wgFlaggedRevsAutoconfirm, $wgFlaggedRevsAutopromote;
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.php
@@ -258,7 +258,7 @@
259259 $wgAutoloadClasses['FRSquidUpdate'] = $dir . 'FRExtraCacheUpdate.php';
260260 $wgAutoloadClasses['FRDependencyUpdate'] = $dir . 'FRDependencyUpdate.php';
261261 $wgAutoloadClasses['FRInclusionManager'] = $dir . 'FRInclusionManager.php';
262 -$wgAutoloadClasses['FlaggedArticle'] = $dir . 'FlaggedArticle.php';
 262+$wgAutoloadClasses['FlaggedPage'] = $dir . 'FlaggedPage.php';
263263 $wgAutoloadClasses['FlaggedRevision'] = $dir . 'FlaggedRevision.php';
264264
265265 # Business object classes
@@ -269,7 +269,7 @@
270270 $wgAutoloadClasses['PageStabilityProtectForm'] = $dir . 'business/PageStabilityForm.php';
271271
272272 # Presentation classes...
273 -$wgAutoloadClasses['FlaggedArticleView'] = $dir . 'presentation/FlaggedArticleView.php';
 273+$wgAutoloadClasses['FlaggedPageView'] = $dir . 'presentation/FlaggedPageView.php';
274274 $wgAutoloadClasses['FlaggedRevsLogView'] = $dir . 'presentation/FlaggedRevsLogView.php';
275275 $wgAutoloadClasses['FlaggedRevsXML'] = $dir . 'presentation/FlaggedRevsXML.php';
276276 $wgAutoloadClasses['RevisionReviewFormGUI'] = $dir . 'presentation/RevisionReviewFormGUI.php';
@@ -626,7 +626,7 @@
627627
628628 # AJAX functions
629629 $wgAjaxExportList[] = 'RevisionReview::AjaxReview';
630 -$wgAjaxExportList[] = 'FlaggedArticleView::AjaxBuildDiffHeaderItems';
 630+$wgAjaxExportList[] = 'FlaggedPageView::AjaxBuildDiffHeaderItems';
631631
632632 # Cache update
633633 $wgSpecialPageCacheUpdates[] = 'efFlaggedRevsUnreviewedPagesUpdate';
@@ -640,4 +640,4 @@
641641 }
642642
643643 # B/C ...
644 -$wgLogActions['rights/erevoke'] = 'rights-editor-revoke';
\ No newline at end of file
 644+$wgLogActions['rights/erevoke'] = 'rights-editor-revoke';
Index: trunk/extensions/FlaggedRevs/FlaggedRevsLog.php
@@ -3,7 +3,7 @@
44 class FlaggedRevsLog {
55 /**
66 * $action is a valid review log action
7 - * @returns bool
 7+ * @return bool
88 */
99 public static function isReviewAction( $action ) {
1010 return preg_match( '/^(approve2?(-i|-a|-ia)?|unapprove2?)$/', $action );
@@ -11,7 +11,7 @@
1212
1313 /**
1414 * $action is a valid stability log action
15 - * @returns bool
 15+ * @return bool
1616 */
1717 public static function isStabilityAction( $action ) {
1818 return preg_match( '/^(config|modify|reset)$/', $action );
@@ -19,7 +19,7 @@
2020
2121 /**
2222 * $action is a valid review log deprecate action
23 - * @returns bool
 23+ * @return bool
2424 */
2525 public static function isReviewDeapproval( $action ) {
2626 return ( $action == 'unapprove' || $action == 'unapprove2' );
@@ -116,7 +116,7 @@
117117 /**
118118 * Get log params (associate array) from a stability config
119119 * @param array $config
120 - * @returns array (associative)
 120+ * @return array (associative)
121121 */
122122 public static function stabilityLogParams( array $config ) {
123123 $params = $config;
@@ -129,9 +129,9 @@
130130 /**
131131 * Collapse an associate array into a string
132132 * @param array $pars
133 - * @returns string
 133+ * @return string
134134 */
135 - public static function collapseParams( Array $pars ) {
 135+ public static function collapseParams( array $pars ) {
136136 $res = array();
137137 foreach ( $pars as $param => $value ) {
138138 // Sanity check...
@@ -148,9 +148,9 @@
149149 /**
150150 * Expand a list of log params into an associative array
151151 * @params array $pars
152 - * @returns array (associative)
 152+ * @return array (associative)
153153 */
154 - public static function expandParams( Array $pars ) {
 154+ public static function expandParams( array $pars ) {
155155 $res = array();
156156 foreach ( $pars as $paramAndValue ) {
157157 list( $param, $value ) = explode( '=', $paramAndValue, 2 );
Index: trunk/extensions/FlaggedRevs/maintenance/purgeReviewablePages.inc
@@ -33,7 +33,7 @@
3434 # Go through and append each purgeable page...
3535 foreach ( $res as $row ) {
3636 $title = Title::newFromRow( $row );
37 - $fa = FlaggedArticle::getTitleInstance( $title );
 37+ $fa = FlaggedPage::getTitleInstance( $title );
3838 if ( $fa->isReviewable() ) {
3939 # Need to purge this page - add to list
4040 fwrite( $fileHandle, $title->getPrefixedDBKey() . "\n" );
Index: trunk/extensions/FlaggedRevs/maintenance/updateTracking.inc
@@ -123,7 +123,7 @@
124124 $db->begin();
125125 foreach ( $res as $row ) {
126126 $title = Title::newFromRow( $row );
127 - $article = new FlaggedArticle( $title );
 127+ $article = new FlaggedPage( $title );
128128 $oldFrev = FlaggedRevision::newFromStable( $title, FR_MASTER );
129129 $frev = FlaggedRevision::determineStable( $title, FR_MASTER );
130130 # Update fp_stable, fp_quality, and fp_reviewed
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.class.php
@@ -132,7 +132,7 @@
133133
134134 /**
135135 * Is there only one tag and it has only one level?
136 - * @returns bool
 136+ * @return bool
137137 */
138138 public static function binaryFlagging() {
139139 self::load();
@@ -141,7 +141,7 @@
142142
143143 /**
144144 * If there only one tag and it has only one level, return it
145 - * @returns string
 145+ * @return string
146146 */
147147 public static function binaryTagName() {
148148 self::load();
@@ -154,7 +154,7 @@
155155
156156 /**
157157 * Are quality versions enabled?
158 - * @returns bool
 158+ * @return bool
159159 */
160160 public static function qualityVersions() {
161161 self::load();
@@ -163,7 +163,7 @@
164164
165165 /**
166166 * Are pristine versions enabled?
167 - * @returns bool
 167+ * @return bool
168168 */
169169 public static function pristineVersions() {
170170 self::load();
@@ -172,7 +172,7 @@
173173
174174 /**
175175 * Get the highest review tier that is enabled
176 - * @returns int One of FR_PRISTINE,FR_QUALITY,FR_CHECKED
 176+ * @return int One of FR_PRISTINE,FR_QUALITY,FR_CHECKED
177177 */
178178 public static function highestReviewTier() {
179179 self::load();
@@ -186,7 +186,7 @@
187187
188188 /**
189189 * Allow auto-review edits directly to the stable version by reviewers?
190 - * @returns bool
 190+ * @return bool
191191 */
192192 public static function autoReviewEdits() {
193193 self::load();
@@ -195,7 +195,7 @@
196196
197197 /**
198198 * Auto-review new pages with the minimal level?
199 - * @returns bool
 199+ * @return bool
200200 */
201201 public static function autoReviewNewPages() {
202202 self::load();
@@ -204,7 +204,7 @@
205205
206206 /**
207207 * Auto-review of new pages or edits to pages enabled?
208 - * @returns bool
 208+ * @return bool
209209 */
210210 public static function autoReviewEnabled() {
211211 return self::autoReviewEdits() || self::autoReviewNewPages();
@@ -213,7 +213,7 @@
214214 /**
215215 * Get the maximum level that $tag can be autoreviewed to
216216 * @param string $tag
217 - * @returns int
 217+ * @return int
218218 */
219219 public static function maxAutoReviewLevel( $tag ) {
220220 global $wgFlaggedRevsTagsAuto;
@@ -231,7 +231,7 @@
232232 /**
233233 * Is a "stable version" used as the default display
234234 * version for all pages in reviewable namespaces?
235 - * @returns bool
 235+ * @return bool
236236 */
237237 public static function isStableShownByDefault() {
238238 global $wgFlaggedRevsOverride;
@@ -244,7 +244,7 @@
245245 /**
246246 * Are pages reviewable only if they have been manually
247247 * configured by an admin to use a "stable version" as the default?
248 - * @returns bool
 248+ * @return bool
249249 */
250250 public static function useOnlyIfProtected() {
251251 global $wgFlaggedRevsProtection;
@@ -253,7 +253,7 @@
254254
255255 /**
256256 * Return the include handling configuration
257 - * @returns int
 257+ * @return int
258258 */
259259 public static function inclusionSetting() {
260260 global $wgFlaggedRevsHandleIncludes;
@@ -262,7 +262,7 @@
263263
264264 /**
265265 * Should tags only be shown for unreviewed content for this user?
266 - * @returns bool
 266+ * @return bool
267267 */
268268 public static function lowProfileUI() {
269269 global $wgFlaggedRevsLowProfile;
@@ -271,7 +271,7 @@
272272
273273 /**
274274 * Are there site defined protection levels for review
275 - * @returns bool
 275+ * @return bool
276276 */
277277 public static function useProtectionLevels() {
278278 global $wgFlaggedRevsProtection;
@@ -280,7 +280,7 @@
281281
282282 /**
283283 * Get the autoreview restriction levels available
284 - * @returns array
 284+ * @return array
285285 */
286286 public static function getRestrictionLevels() {
287287 self::load();
@@ -289,7 +289,7 @@
290290
291291 /**
292292 * Get the array of tag dimensions and level messages
293 - * @returns array
 293+ * @return array
294294 */
295295 public static function getDimensions() {
296296 self::load();
@@ -299,7 +299,7 @@
300300 /**
301301 * Get the associative array of tag dimensions
302302 * (tags => array(levels => msgkey))
303 - * @returns array
 303+ * @return array
304304 */
305305 public static function getTags() {
306306 self::load();
@@ -309,7 +309,7 @@
310310 /**
311311 * Get the associative array of tag restrictions
312312 * (tags => array(rights => levels))
313 - * @returns array
 313+ * @return array
314314 */
315315 public static function getTagRestrictions() {
316316 self::load();
@@ -319,7 +319,7 @@
320320 /**
321321 * Get the UI name for a tag
322322 * @param string $tag
323 - * @returns string
 323+ * @return string
324324 */
325325 public static function getTagMsg( $tag ) {
326326 return wfMsgExt( "revreview-$tag", array( 'escapenoentities' ) );
@@ -328,7 +328,7 @@
329329 /**
330330 * Get the levels for a tag. Gives map of level to message name.
331331 * @param string $tag
332 - * @returns associative array (integer -> string)
 332+ * @return associative array (integer -> string)
333333 */
334334 public static function getTagLevels( $tag ) {
335335 self::load();
@@ -340,7 +340,7 @@
341341 * Get the the UI name for a value of a tag
342342 * @param string $tag
343343 * @param int $value
344 - * @returns string
 344+ * @return string
345345 */
346346 public static function getTagValueMsg( $tag, $value ) {
347347 self::load();
@@ -356,7 +356,7 @@
357357
358358 /**
359359 * Are there no actual dimensions?
360 - * @returns bool
 360+ * @return bool
361361 */
362362 public static function dimensionsEmpty() {
363363 self::load();
@@ -411,7 +411,7 @@
412412 /**
413413 * Check if all of the required site flags have a valid value
414414 * @param array $flags
415 - * @returns bool
 415+ * @return bool
416416 */
417417 public static function flagsAreValid( array $flags ) {
418418 foreach ( self::getDimensions() as $qal => $levels ) {
@@ -427,7 +427,7 @@
428428 * @param User $user
429429 * @param string $tag
430430 * @param int $value
431 - * @returns bool
 431+ * @return bool
432432 */
433433 public static function userCanSetTag( $user, $tag, $value ) {
434434 # Sanity check tag and value
@@ -459,7 +459,7 @@
460460 * @param User $user
461461 * @param array $flags, suggested flags
462462 * @param array $oldflags, pre-existing flags
463 - * @returns bool
 463+ * @return bool
464464 */
465465 public static function userCanSetFlags( $user, array $flags, $oldflags = array() ) {
466466 if ( !$user->isAllowed( 'review' ) ) {
@@ -485,7 +485,7 @@
486486 * Check if a user can set the autoreview restiction level to $right
487487 * @param User $user
488488 * @param string $right the level
489 - * @returns bool
 489+ * @return bool
490490 */
491491 public static function userCanSetAutoreviewLevel( $user, $right ) {
492492 if ( $right == '' ) {
@@ -513,7 +513,7 @@
514514 * @param Title $title
515515 * @param string $text wikitext
516516 * @param int $id Source revision Id
517 - * @return Array( string wikitext, array of template versions )
 517+ * @return array( string wikitext, array of template versions )
518518 */
519519 public static function expandText( Title $title, $text, $id ) {
520520 global $wgParser;
@@ -577,7 +577,7 @@
578578 /**
579579 * Get standard parser options
580580 * @param User $user (optional)
581 - * @returns ParserOptions
 581+ * @return ParserOptions
582582 */
583583 public static function makeParserOptions( $user = null ) {
584584 global $wgUser;
@@ -722,8 +722,8 @@
723723 /**
724724 * Update the page tables with a new stable version.
725725 * @param Title $title
726 - * @param mixed $sv, the new stable version (optional)
727 - * @param mixed $oldSv, the old stable version (optional)
 726+ * @param FlaggedRevision|null $sv, the new stable version (optional)
 727+ * @param FlaggedRevision|null $oldSv, the old stable version (optional)
728728 * @return bool stable version text/file changed and FR_INCLUDES_STABLE
729729 */
730730 public static function stableVersionUpdates( Title $title, $sv = null, $oldSv = null ) {
@@ -734,7 +734,7 @@
735735 if ( $sv === null ) { // optional
736736 $sv = FlaggedRevision::determineStable( $title, FR_MASTER );
737737 }
738 - $article = new FlaggedArticle( $title );
 738+ $article = new FlaggedPage( $title );
739739 if ( !$sv ) {
740740 # Empty flaggedrevs data for this page if there is no stable version
741741 $article->clearStableVersion();
@@ -804,7 +804,7 @@
805805 * @param Title $title
806806 * @param int $rev_id
807807 * @param $flags, FR_MASTER
808 - * @return Array
 808+ * @return array
809809 */
810810 public static function getRevisionTags( Title $title, $rev_id, $flags = 0 ) {
811811 $db = ( $flags & FR_MASTER ) ?
@@ -822,7 +822,7 @@
823823 * @param int $page_id
824824 * @param int $rev_id
825825 * @param $flags, FR_MASTER
826 - * @returns mixed (int or false)
 826+ * @return mixed (int or false)
827827 * Get quality of a revision
828828 */
829829 public static function getRevQuality( $page_id, $rev_id, $flags = 0 ) {
@@ -840,7 +840,7 @@
841841 * @param Title $title
842842 * @param int $rev_id
843843 * @param $flags, FR_MASTER
844 - * @returns bool
 844+ * @return bool
845845 * Useful for quickly pinging to see if a revision is flagged
846846 */
847847 public static function revIsFlagged( Title $title, $rev_id, $flags = 0 ) {
@@ -851,7 +851,7 @@
852852 /**
853853 * Get the "prime" flagged revision of a page
854854 * @param Article $article
855 - * @returns mixed (integer/false)
 855+ * @return mixed (integer/false)
856856 * Will not return a revision if deleted
857857 */
858858 public static function getPrimeFlaggedRevId( Article $article ) {
@@ -876,7 +876,7 @@
877877 /**
878878 * Mark a revision as patrolled if needed
879879 * @param Revision $rev
880 - * @returns bool DB write query used
 880+ * @return bool DB write query used
881881 */
882882 public static function markRevisionPatrolled( Revision $rev ) {
883883 $rcid = $rev->isUnpatrolled();
@@ -908,7 +908,7 @@
909909 }
910910
911911 /**
912 - * @param mixed $data makeMemcObj() tuple (false/Object)
 912+ * @param object|false $data makeMemcObj() tuple
913913 * @param Article $article
914914 * @return mixed
915915 * Return memc value if not expired
@@ -980,7 +980,7 @@
981981 /**
982982 * Get minimum level tags for a tier
983983 * @param int $tier FR_PRISTINE/FR_QUALITY/FR_CHECKED
984 - * @return Array
 984+ * @return array
985985 */
986986 public static function quickTags( $tier ) {
987987 self::load();
@@ -1022,7 +1022,7 @@
10231023
10241024 /**
10251025 * Get the list of reviewable namespaces
1026 - * @return Array
 1026+ * @return array
10271027 */
10281028 public static function getReviewNamespaces() {
10291029 self::load(); // validates namespaces
@@ -1031,7 +1031,7 @@
10321032
10331033 /**
10341034 * Get the list of patrollable namespaces
1035 - * @return Array
 1035+ * @return array
10361036 */
10371037 public static function getPatrolNamespaces() {
10381038 self::load(); // validates namespaces
@@ -1071,7 +1071,7 @@
10721072
10731073 /**
10741074 * Clear FlaggedRevs tracking tables for this page
1075 - * @param mixed $pageId (int or array)
 1075+ * @param int|array $pageId (int or array)
10761076 */
10771077 public static function clearTrackingRows( $pageId ) {
10781078 $dbw = wfGetDB( DB_MASTER );
@@ -1082,7 +1082,7 @@
10831083
10841084 /**
10851085 * Clear tracking table of stable-only links for this page
1086 - * @param mixed $pageId (int or array)
 1086+ * @param int|array $pageId (int or array)
10871087 */
10881088 public static function clearStableOnlyDeps( $pageId ) {
10891089 $dbw = wfGetDB( DB_MASTER );
Index: trunk/extensions/FlaggedRevs/business/RevisionReviewForm.php
@@ -138,7 +138,7 @@
139139 * @return mixed (true on success, error string on failure)
140140 */
141141 protected function doBuildOnReady() {
142 - $this->article = FlaggedArticle::getTitleInstance( $this->page );
 142+ $this->article = FlaggedPage::getTitleInstance( $this->page );
143143 return true;
144144 }
145145
@@ -320,7 +320,7 @@
321321 * Adds or updates the flagged revision table for this page/id set
322322 * @param Revision $rev The revision to be accepted
323323 * @param FlaggedRevision $oldFrev Currently accepted version of $rev or null
324 - * @returns true on success, array of errors on failure
 324+ * @return true on success, array of errors on failure
325325 */
326326 private function approveRevision( Revision $rev, FlaggedRevision $oldFrev = null ) {
327327 wfProfileIn( __METHOD__ );
@@ -486,13 +486,13 @@
487487
488488 /**
489489 * Get template and image parameters from parser output to use on forms.
490 - * @param FlaggedArticle $article
 490+ * @param FlaggedPage $article
491491 * @param array $templateIDs (from ParserOutput/OutputPage->mTemplateIds)
492492 * @param array $imageSHA1Keys (from ParserOutput/OutputPage->mImageTimeKeys)
493 - * @returns array( templateParams, imageParams, fileVersion )
 493+ * @return array( templateParams, imageParams, fileVersion )
494494 */
495495 public static function getIncludeParams(
496 - FlaggedArticle $article, array $templateIDs, array $imageSHA1Keys
 496+ FlaggedPage $article, array $templateIDs, array $imageSHA1Keys
497497 ) {
498498 $templateParams = $imageParams = $fileVersion = '';
499499 # NS -> title -> rev ID mapping
@@ -520,7 +520,7 @@
521521 * Get template and image versions from form value for parser output.
522522 * @param string $templateParams
523523 * @param string $imageParams
524 - * @returns array( templateIds, fileSHA1Keys )
 524+ * @return array( templateIds, fileSHA1Keys )
525525 * templateIds like ParserOutput->mTemplateIds
526526 * fileSHA1Keys like ParserOutput->mImageTimeKeys
527527 */
@@ -575,7 +575,7 @@
576576 * Get template and image versions from parsing a revision.
577577 * @param Article $article
578578 * @param Revision $rev
579 - * @returns array( templateIds, fileSHA1Keys )
 579+ * @return array( templateIds, fileSHA1Keys )
580580 * templateIds like ParserOutput->mTemplateIds
581581 * fileSHA1Keys like ParserOutput->mImageTimeKeys
582582 */
Index: trunk/extensions/FlaggedRevs/business/PageStabilityForm.php
@@ -224,7 +224,7 @@
225225 $changed = FlaggedPageConfig::setStabilitySettings( $this->page, $this->getNewConfig() );
226226 # Log if this actually changed anything...
227227 if ( $changed ) {
228 - $article = new FlaggedArticle( $this->page );
 228+ $article = new FlaggedPage( $this->page );
229229 if ( FlaggedRevs::useOnlyIfProtected() ) {
230230 # Config may have changed to allow stable versions, so refresh
231231 # the tracking table to account for any hidden reviewed versions...
@@ -268,7 +268,7 @@
269269 * (b) Add a null edit like the log entry
270270 * @return Revision
271271 */
272 - protected function updateLogsAndHistory( FlaggedArticle $article ) {
 272+ protected function updateLogsAndHistory( FlaggedPage $article ) {
273273 global $wgContLang;
274274 $newConfig = $this->getNewConfig();
275275 $oldConfig = $this->getOldConfig();
@@ -312,7 +312,7 @@
313313
314314 /*
315315 * Get current stability config array
316 - * @return Array
 316+ * @return array
317317 */
318318 public function getOldConfig() {
319319 if ( $this->getState() == self::FORM_UNREADY ) {
@@ -326,7 +326,7 @@
327327
328328 /*
329329 * Get proposed stability config array
330 - * @return Array
 330+ * @return array
331331 */
332332 public function getNewConfig() {
333333 return array(
Index: trunk/extensions/FlaggedRevs/FlaggedRevision.php
@@ -327,7 +327,7 @@
328328
329329 /**
330330 * Get select fields for FlaggedRevision DB row (flaggedrevs/revision tables)
331 - * @return Array
 331+ * @return array
332332 */
333333 public static function selectFields() {
334334 return array_merge(
@@ -418,7 +418,7 @@
419419 }
420420
421421 /**
422 - * @return Array tag metadata
 422+ * @return array tag metadata
423423 */
424424 public function getTags() {
425425 return $this->mTags;
@@ -459,7 +459,7 @@
460460 /**
461461 * Get original template versions at time of review
462462 * @param int $flags FR_MASTER
463 - * @return Array template versions (ns -> dbKey -> rev Id)
 463+ * @return array template versions (ns -> dbKey -> rev Id)
464464 * Note: 0 used for template rev Id if it didn't exist
465465 */
466466 public function getTemplateVersions( $flags = 0 ) {
@@ -485,7 +485,7 @@
486486 /**
487487 * Get original template versions at time of review
488488 * @param int $flags FR_MASTER
489 - * @return Array file versions (dbKey => array('time' => MW timestamp,'sha1' => sha1) )
 489+ * @return array file versions (dbKey => array('time' => MW timestamp,'sha1' => sha1) )
490490 * Note: false used for file timestamp/sha1 if it didn't exist
491491 */
492492 public function getFileVersions( $flags = 0 ) {
@@ -516,7 +516,7 @@
517517 /**
518518 * Get the current stable version of the templates used at time of review
519519 * @param int $flags FR_MASTER
520 - * @return Array template versions (ns -> dbKey -> rev Id)
 520+ * @return array template versions (ns -> dbKey -> rev Id)
521521 * Note: 0 used for template rev Id if it doesn't exist
522522 */
523523 public function getStableTemplateVersions( $flags = 0 ) {
@@ -550,7 +550,7 @@
551551 /**
552552 * Get the current stable version of the files used at time of review
553553 * @param int $flags FR_MASTER
554 - * @return Array file versions (dbKey => array('time' => MW timestamp,'sha1' => sha1) )
 554+ * @return array file versions (dbKey => array('time' => MW timestamp,'sha1' => sha1) )
555555 * Note: false used for file timestamp/sha1 if it didn't exist
556556 */
557557 public function getStableFileVersions( $flags = 0 ) {
@@ -598,7 +598,7 @@
599599 * (b) Current template exists and the "version used" was non-existing (created)
600600 * (c) Current template doesn't exist and the "version used" existed (deleted)
601601 *
602 - * @return Array of (template title, rev ID in reviewed version) tuples
 602+ * @return array of (template title, rev ID in reviewed version) tuples
603603 */
604604 public function findPendingTemplateChanges() {
605605 if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_CURRENT ) {
@@ -668,7 +668,7 @@
669669 * (c) Current file doesn't exist and the "version used" existed (deleted)
670670 *
671671 * @param string $noForeign Using 'noForeign' skips foreign file updates (bug 15748)
672 - * @return Array of (file title, MW file timestamp in reviewed version) tuples
 672+ * @return array of (file title, MW file timestamp in reviewed version) tuples
673673 */
674674 public function findPendingFileChanges( $noForeign = false ) {
675675 if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_CURRENT ) {
@@ -749,7 +749,7 @@
750750 /**
751751 * Get flags for a revision
752752 * @param string $tags
753 - * @return Array
 753+ * @return array
754754 */
755755 public static function expandRevisionTags( $tags ) {
756756 $flags = array();
Index: trunk/extensions/FlaggedRevs/FRDependencyUpdate.php
@@ -76,7 +76,7 @@
7777 /*
7878 * Get existing cache dependancies
7979 * @param int $flags FR_MASTER
80 - * @return Array (ns => dbKey => 1)
 80+ * @return array (ns => dbKey => 1)
8181 */
8282 protected function getExistingDeps( $flags = 0 ) {
8383 $db = ( $flags & FR_MASTER ) ?
@@ -98,7 +98,7 @@
9999
100100 /*
101101 * Get INSERT rows for cache dependancies in $new but not in $existing
102 - * @return Array
 102+ * @return array
103103 */
104104 protected function getDepInsertions( array $existing, array $new ) {
105105 $arr = array();
@@ -157,7 +157,7 @@
158158
159159 /**
160160 * Get an array of existing links, as a 2-D array
161 - * @return Array (ns => dbKey => 1)
 161+ * @return array (ns => dbKey => 1)
162162 */
163163 protected function getCurrentVersionLinks() {
164164 $dbr = wfGetDB( DB_SLAVE );
@@ -178,7 +178,7 @@
179179
180180 /**
181181 * Get an array of existing templates, as a 2-D array
182 - * @return Array (ns => dbKey => 1)
 182+ * @return array (ns => dbKey => 1)
183183 */
184184 protected function getCurrentVersionTemplates() {
185185 $dbr = wfGetDB( DB_SLAVE );
@@ -199,7 +199,7 @@
200200
201201 /**
202202 * Get an array of existing images, image names in the keys
203 - * @return Array (dbKey => 1)
 203+ * @return array (dbKey => 1)
204204 */
205205 protected function getCurrentVersionImages() {
206206 $dbr = wfGetDB( DB_SLAVE );
@@ -217,7 +217,7 @@
218218
219219 /**
220220 * Get an array of existing categories, with the name in the key and sort key in the value.
221 - * @return Array (category => sortkey)
 221+ * @return array (category => sortkey)
222222 */
223223 protected function getCurrentVersionCategories() {
224224 $dbr = wfGetDB( DB_SLAVE );
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php
@@ -46,7 +46,7 @@
4747 return true; // don't double-load
4848 }
4949 $loadedModules = true;
50 - $fa = FlaggedArticleView::globalArticleInstance();
 50+ $fa = FlaggedPageView::globalArticleInstance();
5151 # Try to only add to relevant pages
5252 if ( !$fa || !$fa->isReviewable() ) {
5353 return true;
@@ -66,7 +66,7 @@
6767 $rTags = FlaggedRevs::getJSTagParams();
6868 $globalVars['wgFlaggedRevsParams'] = $rTags;
6969 # Get page-specific meta-data
70 - $fa = FlaggedArticleView::globalArticleInstance();
 70+ $fa = FlaggedPageView::globalArticleInstance();
7171 # Try to only add to relevant pages
7272 if ( $fa && $fa->isReviewable() ) {
7373 $frev = $fa->getStableRev();
@@ -108,7 +108,7 @@
109109 */
110110 public static function onBeforePageDisplay( &$out, &$skin ) {
111111 if ( $out->isArticleRelated() ) {
112 - $view = FlaggedArticleView::singleton();
 112+ $view = FlaggedPageView::singleton();
113113 $view->displayTag(); // show notice bar/icon in subtitle
114114 $view->setRobotPolicy(); // set indexing policy
115115 self::injectStyleAndJS(); // full CSS/JS
@@ -123,13 +123,13 @@
124124 public static function onMediaWikiPerformAction(
125125 $output, $article, Title $title, $user, $request
126126 ) {
127 - $fa = FlaggedArticle::getTitleInstance( $title );
 127+ $fa = FlaggedPage::getTitleInstance( $title );
128128 self::maybeMarkUnderReview( $fa, $request );
129129 return true;
130130 }
131131
132132 // Mark when an unreviewed page is being reviewed
133 - protected static function maybeMarkUnderReview( FlaggedArticle $fa, WebRequest $request ) {
 133+ protected static function maybeMarkUnderReview( FlaggedPage $fa, WebRequest $request ) {
134134 global $wgUser;
135135 if ( !$request->getInt( 'reviewing' ) && !$request->getInt( 'rcid' ) ) {
136136 return true; // not implied by URL
@@ -203,7 +203,7 @@
204204 public static function onTitleMoveComplete(
205205 Title $otitle, Title $ntitle, $user, $pageId
206206 ) {
207 - $fa = FlaggedArticle::getTitleInstance( $ntitle );
 207+ $fa = FlaggedPage::getTitleInstance( $ntitle );
208208 $fa->loadFromDB( FR_MASTER );
209209 // Re-validate NS/config (new title may not be reviewable)
210210 if ( $fa->isReviewable() ) {
@@ -431,7 +431,7 @@
432432 if ( !FlaggedRevs::inReviewNamespace( $title ) || !$title->exists() ) {
433433 return true; // extra short-circuit
434434 }
435 - $flaggedArticle = FlaggedArticle::getTitleInstance( $title );
 435+ $flaggedArticle = FlaggedPage::getTitleInstance( $title );
436436 # If the draft shows by default anyway, nothing to do...
437437 if ( !$flaggedArticle->isStableShownByDefault() ) {
438438 return true;
@@ -444,7 +444,7 @@
445445 }
446446 # Don't let users patrol pages not in $wgFlaggedRevsPatrolNamespaces
447447 } else if ( $action === 'patrol' || $action === 'autopatrol' ) {
448 - $flaggedArticle = FlaggedArticle::getTitleInstance( $title );
 448+ $flaggedArticle = FlaggedPage::getTitleInstance( $title );
449449 # For a page to be patrollable it must not be reviewable.
450450 # Note: normally, edits to non-reviewable, non-patrollable, pages are
451451 # silently marked patrolled automatically. With $wgUseNPPatrol on, the
@@ -456,7 +456,7 @@
457457 # Enforce autoreview/review restrictions
458458 } else if ( $action === 'autoreview' || $action === 'review' ) {
459459 # Get autoreview restriction settings...
460 - $fa = FlaggedArticle::getTitleInstance( $title );
 460+ $fa = FlaggedPage::getTitleInstance( $title );
461461 $config = $fa->getStabilitySettings();
462462 # Convert Sysop -> protect
463463 $right = ( $config['autoreview'] === 'sysop' ) ?
@@ -485,7 +485,7 @@
486486 ) {
487487 global $wgRequest;
488488 # Edit must be non-null, to a reviewable page, with $user set
489 - $fa = FlaggedArticle::getArticleInstance( $article );
 489+ $fa = FlaggedPage::getArticleInstance( $article );
490490 $fa->loadFromDB( FR_MASTER );
491491 if ( !$rev || !$user || !$fa->isReviewable() ) {
492492 return true;
@@ -661,7 +661,7 @@
662662 if ( !$user || $rev !== null ) {
663663 return true;
664664 }
665 - $fa = FlaggedArticle::getArticleInstance( $article );
 665+ $fa = FlaggedPage::getArticleInstance( $article );
666666 $fa->loadFromDB( FR_MASTER );
667667 if ( !$fa->isReviewable() ) {
668668 return true; // page is not reviewable
@@ -726,7 +726,7 @@
727727 if ( empty( $rc->mAttribs['rc_this_oldid'] ) ) {
728728 return true;
729729 }
730 - $fa = FlaggedArticle::getTitleInstance( $rc->getTitle() );
 730+ $fa = FlaggedPage::getTitleInstance( $rc->getTitle() );
731731 $fa->loadFromDB( FR_MASTER );
732732 // Is the page reviewable?
733733 if ( $fa->isReviewable() ) {
@@ -821,7 +821,7 @@
822822 * @param int $spacingReq days apart (of edit points)
823823 * @param int $pointsReq number of edit points
824824 * @param User $user
825 - * @returns mixed (true if passed, int seconds on failure)
 825+ * @return mixed (true if passed, int seconds on failure)
826826 */
827827 protected static function editSpacingCheck( $spacingReq, $pointsReq, $user ) {
828828 $benchmarks = 0; // actual edit points
@@ -1197,7 +1197,7 @@
11981198 }
11991199
12001200 public static function onImagePageFindFile( $imagePage, &$normalFile, &$displayFile ) {
1201 - $view = FlaggedArticleView::singleton();
 1201+ $view = FlaggedPageView::singleton();
12021202 $view->imagePageFindFile( $normalFile, $displayFile );
12031203 return true;
12041204 }
@@ -1210,8 +1210,8 @@
12111211 return true;
12121212 }
12131213 // Note: $wgArticle sometimes not set here
1214 - if ( FlaggedArticleView::globalArticleInstance() != null ) {
1215 - $view = FlaggedArticleView::singleton();
 1214+ if ( FlaggedPageView::globalArticleInstance() != null ) {
 1215+ $view = FlaggedPageView::singleton();
12161216 $view->setActionTabs( $skin, $contentActions );
12171217 $view->setViewTabs( $skin, $contentActions, 'flat' );
12181218 }
@@ -1221,8 +1221,8 @@
12221222 // Vector et al: $links is all the tabs (2 levels)
12231223 public static function onSkinTemplateNavigation( Skin $skin, array &$links ) {
12241224 // Note: $wgArticle sometimes not set here
1225 - if ( FlaggedArticleView::globalArticleInstance() != null ) {
1226 - $view = FlaggedArticleView::singleton();
 1225+ if ( FlaggedPageView::globalArticleInstance() != null ) {
 1226+ $view = FlaggedPageView::singleton();
12271227 $view->setActionTabs( $skin, $links['actions'] );
12281228 $view->setViewTabs( $skin, $links['views'], 'nav' );
12291229 }
@@ -1230,7 +1230,7 @@
12311231 }
12321232
12331233 public static function onArticleViewHeader( &$article, &$outputDone, &$useParserCache ) {
1234 - $view = FlaggedArticleView::singleton();
 1234+ $view = FlaggedPageView::singleton();
12351235 $view->addStableLink( $outputDone, $useParserCache );
12361236 $view->setPageContent( $outputDone, $useParserCache );
12371237 return true;
@@ -1240,7 +1240,7 @@
12411241 Title $title, WebRequest $request, &$ignoreRedirect, &$target, Article &$article
12421242 ) {
12431243 global $wgMemc, $wgParserCacheExpireTime;
1244 - $fa = FlaggedArticle::getTitleInstance( $title ); // on $wgTitle
 1244+ $fa = FlaggedPage::getTitleInstance( $title ); // on $wgTitle
12451245 if ( !$fa->isReviewable() ) {
12461246 return true; // nothing to do
12471247 }
@@ -1250,7 +1250,7 @@
12511251 return true;
12521252 }
12531253 $srev = $fa->getStableRev();
1254 - $view = FlaggedArticleView::singleton();
 1254+ $view = FlaggedPageView::singleton();
12551255 # Check if we are viewing an unsynced stable version...
12561256 if ( $srev && $view->showingStable() && $srev->getRevId() != $article->getLatest() ) {
12571257 # Check the stable redirect properties from the cache...
@@ -1282,31 +1282,31 @@
12831283 }
12841284
12851285 public static function addToEditView( &$editPage ) {
1286 - $view = FlaggedArticleView::singleton();
 1286+ $view = FlaggedPageView::singleton();
12871287 $view->addToEditView( $editPage );
12881288 return true;
12891289 }
12901290
12911291 public static function onBeforeEditButtons( &$editPage, &$buttons ) {
1292 - $view = FlaggedArticleView::singleton();
 1292+ $view = FlaggedPageView::singleton();
12931293 $view->changeSaveButton( $editPage, $buttons );
12941294 return true;
12951295 }
12961296
12971297 public static function onNoSuchSection( &$editPage, &$s ) {
1298 - $view = FlaggedArticleView::singleton();
 1298+ $view = FlaggedPageView::singleton();
12991299 $view->addToNoSuchSection( $editPage, $s );
13001300 return true;
13011301 }
13021302
13031303 public static function addToHistView( &$article ) {
1304 - $view = FlaggedArticleView::singleton();
 1304+ $view = FlaggedPageView::singleton();
13051305 $view->addToHistView();
13061306 return true;
13071307 }
13081308
13091309 public static function onCategoryPageView( &$category ) {
1310 - $view = FlaggedArticleView::singleton();
 1310+ $view = FlaggedPageView::singleton();
13111311 $view->addToCategoryView();
13121312 return true;
13131313 }
@@ -1314,9 +1314,9 @@
13151315 public static function onSkinAfterContent( &$data ) {
13161316 global $wgOut;
13171317 if ( $wgOut->isArticleRelated()
1318 - && FlaggedArticleView::globalArticleInstance() != null )
 1318+ && FlaggedPageView::globalArticleInstance() != null )
13191319 {
1320 - $view = FlaggedArticleView::singleton();
 1320+ $view = FlaggedPageView::singleton();
13211321 $view->addReviewNotes( $data );
13221322 $view->addReviewForm( $data );
13231323 $view->addVisibilityLink( $data );
@@ -1325,7 +1325,7 @@
13261326 }
13271327
13281328 public static function addToHistQuery( HistoryPager $pager, array &$queryInfo ) {
1329 - $flaggedArticle = FlaggedArticle::getArticleInstance( $pager->getArticle() );
 1329+ $flaggedArticle = FlaggedPage::getArticleInstance( $pager->getArticle() );
13301330 # Non-content pages cannot be validated. Stable version must exist.
13311331 if ( $flaggedArticle->isReviewable() && $flaggedArticle->getStableRev() ) {
13321332 # Highlight flaggedrevs
@@ -1351,7 +1351,7 @@
13521352 if ( !$file->isLocal() ) {
13531353 return true; // local files only
13541354 }
1355 - $flaggedArticle = FlaggedArticle::getTitleInstance( $file->getTitle() );
 1355+ $flaggedArticle = FlaggedPage::getTitleInstance( $file->getTitle() );
13561356 # Non-content pages cannot be validated. Stable version must exist.
13571357 if ( $flaggedArticle->isReviewable() && $flaggedArticle->getStableRev() ) {
13581358 $tables[] = 'flaggedrevs';
@@ -1415,7 +1415,7 @@
14161416 }
14171417
14181418 public static function addToHistLine( HistoryPager $history, $row, &$s, &$liClasses ) {
1419 - $fa = FlaggedArticle::getArticleInstance( $history->getArticle() );
 1419+ $fa = FlaggedPage::getArticleInstance( $history->getArticle() );
14201420 if ( !$fa->isReviewable() ) {
14211421 return true; // nothing to do here
14221422 }
@@ -1462,7 +1462,7 @@
14631463 * Make stable version link and return the css
14641464 * @param Title $title
14651465 * @param Row $row, from history page
1466 - * @returns array (string,string)
 1466+ * @return array (string,string)
14671467 */
14681468 protected static function markHistoryRow( Title $title, $row ) {
14691469 if ( !isset( $row->fr_quality ) ) {
@@ -1570,8 +1570,8 @@
15711571
15721572 public static function injectPostEditURLParams( $article, &$sectionAnchor, &$extraQuery ) {
15731573 // Note: $wgArticle sometimes not set here
1574 - if ( FlaggedArticleView::globalArticleInstance() != null ) {
1575 - $view = FlaggedArticleView::singleton();
 1574+ if ( FlaggedPageView::globalArticleInstance() != null ) {
 1575+ $view = FlaggedPageView::singleton();
15761576 $view->injectPostEditURLParams( $sectionAnchor, $extraQuery );
15771577 }
15781578 return true;
@@ -1591,33 +1591,33 @@
15921592
15931593 public static function onDiffViewHeader( $diff, $oldRev, $newRev ) {
15941594 self::injectStyleAndJS();
1595 - $view = FlaggedArticleView::singleton();
 1595+ $view = FlaggedPageView::singleton();
15961596 $view->setViewFlags( $diff, $oldRev, $newRev );
15971597 $view->addToDiffView( $diff, $oldRev, $newRev );
15981598 return true;
15991599 }
16001600
16011601 /*
1602 - * If an article is reviewable, get custom article contents from the FlaggedArticleView
 1602+ * If an article is reviewable, get custom article contents from the FlaggedPageView
16031603 */
16041604 public static function onArticleContentOnDiff( $diffEngine, $out ) {
1605 - $fa = FlaggedArticle::getTitleInstance( $out->getTitle() );
 1605+ $fa = FlaggedPage::getTitleInstance( $out->getTitle() );
16061606 if ( !$fa->isReviewable() ) {
16071607 return true; // nothing to do
16081608 }
1609 - $view = FlaggedArticleView::singleton();
 1609+ $view = FlaggedPageView::singleton();
16101610 $view->addCustomContentHtml( $out, $diffEngine->getNewid() );
16111611 return false;
16121612 }
16131613
16141614 public static function addRevisionIDField( $editPage, $out ) {
1615 - $view = FlaggedArticleView::singleton();
 1615+ $view = FlaggedPageView::singleton();
16161616 $view->addRevisionIDField( $editPage, $out );
16171617 return true;
16181618 }
16191619
16201620 public static function addReviewCheck( $editPage, &$checkboxes, &$tabindex ) {
1621 - $view = FlaggedArticleView::singleton();
 1621+ $view = FlaggedPageView::singleton();
16221622 $view->addReviewCheck( $editPage, $checkboxes, $tabindex );
16231623 return true;
16241624 }
Index: trunk/extensions/FlaggedRevs/FlaggedPageConfig.php
@@ -7,7 +7,7 @@
88 * Get visibility settings/restrictions for a page
99 * @param Title $title, page title
1010 * @param int $flags, FR_MASTER
11 - * @returns array (associative) (select,override,autoreview,expiry)
 11+ * @return array (associative) (select,override,autoreview,expiry)
1212 */
1313 public static function getStabilitySettings( Title $title, $flags = 0 ) {
1414 $db = ( $flags & FR_MASTER ) ?
@@ -21,7 +21,7 @@
2222 }
2323
2424 /**
25 - * @return Array basic select fields for FlaggedPageConfig DB row
 25+ * @return array basic select fields for FlaggedPageConfig DB row
2626 */
2727 public static function selectFields() {
2828 return array( 'fpc_override', 'fpc_level', 'fpc_expiry' );
@@ -82,7 +82,7 @@
8383 /**
8484 * Set the stability configuration settings for a page
8585 * @param Title $title
86 - * @param Array $config
 86+ * @param array $config
8787 * @return bool Row changed
8888 */
8989 public static function setStabilitySettings( Title $title, array $config ) {
@@ -131,7 +131,7 @@
132132 /**
133133 * Does this config equal the default settings?
134134 * @param array $config
135 - * @returns bool
 135+ * @return bool
136136 */
137137 public static function configIsReset( array $config ) {
138138 if ( FlaggedRevs::useOnlyIfProtected() ) {
@@ -145,7 +145,7 @@
146146 /**
147147 * Find what protection level a config is in
148148 * @param array $config
149 - * @returns string
 149+ * @return string
150150 */
151151 public static function getProtectionLevel( array $config ) {
152152 if ( !FlaggedRevs::useProtectionLevels() ) {
Index: trunk/extensions/FlaggedRevs/api/actions/ApiReview.php
@@ -66,7 +66,7 @@
6767 $form->setDim( $tag, (int)$params['flag_' . $tag] );
6868 }
6969 if ( $form->getAction() === 'approve' ) {
70 - $article = new FlaggedArticle( $title );
 70+ $article = new FlaggedPage( $title );
7171 // Now get the template and image parameters needed
7272 list( $templateIds, $fileTimeKeys ) =
7373 RevisionReviewForm::currentIncludeVersions( $article, $rev );
Index: trunk/extensions/FlaggedRevs/FRUserActivity.php
@@ -42,7 +42,7 @@
4343 /*
4444 * Get who is currently reviewing a page
4545 * @param int $pageId
46 - * @return Array (username or null, MW timestamp or null)
 46+ * @return array (username or null, MW timestamp or null)
4747 */
4848 public static function getUserReviewingPage( $pageId ) {
4949 global $wgMemc;
@@ -109,7 +109,7 @@
110110 * Get who is currently reviewing a diff
111111 * @param int $oldId
112112 * @param int $newId
113 - * @return Array (username or null, MW timestamp or null)
 113+ * @return array (username or null, MW timestamp or null)
114114 */
115115 public static function getUserReviewingDiff( $oldId, $newId ) {
116116 global $wgMemc;
Index: trunk/extensions/FlaggedRevs/presentation/FlaggedArticleView.php
@@ -1,1845 +0,0 @@
2 -<?php
3 -/**
4 - * Class representing a web view of a MediaWiki page
5 - */
6 -class FlaggedArticleView {
7 - protected $article = null;
8 -
9 - protected $diffRevs = null; // assoc array of old and new Revisions for diffs
10 - protected $isReviewableDiff = false;
11 - protected $isDiffFromStable = false;
12 - protected $isMultiPageDiff = false;
13 - protected $reviewNotice = '';
14 - protected $reviewNotes = '';
15 - protected $diffNoticeBox = '';
16 - protected $reviewFormRev = false;
17 -
18 - protected $loaded = false;
19 -
20 - protected static $instance = null;
21 -
22 - /*
23 - * Get the FlaggedArticleView for this request
24 - */
25 - public static function singleton() {
26 - if ( self::$instance == null ) {
27 - self::$instance = new self();
28 - }
29 - return self::$instance;
30 - }
31 - protected function __construct() { }
32 - protected function __clone() { }
33 -
34 - /*
35 - * Clear the FlaggedArticleView for this request.
36 - * Only needed when page redirection changes the environment.
37 - */
38 - public function clear() {
39 - self::$instance = null;
40 - }
41 -
42 - /*
43 - * Load the global FlaggedArticle instance
44 - */
45 - protected function load() {
46 - if ( !$this->loaded ) {
47 - $this->loaded = true;
48 - $this->article = self::globalArticleInstance();
49 - if ( $this->article == null ) {
50 - throw new MWException( 'FlaggedArticleView has no context article!' );
51 - }
52 - }
53 - }
54 -
55 - /**
56 - * Get the FlaggedArticle instance associated with $wgArticle/$wgTitle,
57 - * or false if there isn't such a title
58 - */
59 - public static function globalArticleInstance() {
60 - global $wgTitle;
61 - if ( !empty( $wgTitle ) ) {
62 - return FlaggedArticle::getTitleInstance( $wgTitle );
63 - }
64 - return null;
65 - }
66 -
67 - /**
68 - * Is this web response for a request to view a page where both:
69 - * (a) no specific page version was requested via URL params
70 - * (b) a stable version exists and is to be displayed
71 - * This factors in site/page config, user preferences, and web request params.
72 - * @returns bool
73 - */
74 - protected function showingStableAsDefault() {
75 - global $wgUser, $wgRequest;
76 - $this->load();
77 - # This only applies to viewing the default version of pages...
78 - if ( !$this->isDefaultPageView( $wgRequest ) ) {
79 - return false;
80 - # ...and the page must be reviewable and have a stable version
81 - } elseif ( !$this->article->getStableRev() ) {
82 - return false;
83 - }
84 - # Check user preferences ("show stable by default?")
85 - if ( $wgUser->getOption( 'flaggedrevsstable' ) ) {
86 - return true;
87 - }
88 - # Viewer may be in a group that sees the draft by default
89 - if ( $this->userViewsDraftByDefault( $wgUser ) ) {
90 - return false;
91 - }
92 - # Does the stable version override the draft?
93 - $config = $this->article->getStabilitySettings();
94 - return (bool)$config['override'];
95 - }
96 -
97 - /**
98 - * Is this web response for a request to view a page where both:
99 - * (a) the stable version of a page was requested (?stable=1)
100 - * (b) the stable version exists and is to be displayed
101 - * @returns bool
102 - */
103 - protected function showingStableByRequest() {
104 - global $wgRequest;
105 - $this->load();
106 - # Are we explicity requesting the stable version?
107 - if ( $wgRequest->getIntOrNull( 'stable' ) === 1 ) {
108 - # This only applies to viewing a version of the page...
109 - if ( !$this->isPageView( $wgRequest ) ) {
110 - return false;
111 - # ...with no version parameters other than ?stable=1...
112 - } elseif ( $wgRequest->getVal( 'oldid' ) || $wgRequest->getVal( 'stableid' ) ) {
113 - return false; // over-determined
114 - # ...and the page must be reviewable and have a stable version
115 - } elseif ( !$this->article->getStableRev() ) {
116 - return false;
117 - }
118 - return true; // show stable version
119 - }
120 - return false;
121 - }
122 -
123 - /**
124 - * Is this web response for a request to view a page
125 - * where a stable version exists and is to be displayed
126 - * @returns bool
127 - */
128 - public function showingStable() {
129 - return $this->showingStableByRequest() || $this->showingStableAsDefault();
130 - }
131 -
132 - /**
133 - * Should this be using a simple icon-based UI?
134 - * Check the user's preferences first, using the site settings as the default.
135 - * @returns bool
136 - */
137 - public function useSimpleUI() {
138 - global $wgUser, $wgSimpleFlaggedRevsUI;
139 - return $wgUser->getOption( 'flaggedrevssimpleui', intval( $wgSimpleFlaggedRevsUI ) );
140 - }
141 -
142 - /**
143 - * Should this user see the draft revision of pages by default?
144 - * @param $user User
145 - * @returns bool
146 - */
147 - protected function userViewsDraftByDefault( $user ) {
148 - global $wgFlaggedRevsExceptions;
149 - # Check user preferences ("show stable by default?")
150 - if ( $user->getOption( 'flaggedrevsstable' ) ) {
151 - return false;
152 - }
153 - # Viewer sees current by default (editors, insiders, ect...) ?
154 - foreach ( $wgFlaggedRevsExceptions as $group ) {
155 - if ( $group == 'user' ) {
156 - if ( $user->getId() ) {
157 - return true;
158 - }
159 - } elseif ( in_array( $group, $user->getGroups() ) ) {
160 - return true;
161 - }
162 - }
163 - return false;
164 - }
165 -
166 - /**
167 - * Is this a view page action (including diffs)?
168 - * @param $request WebRequest
169 - * @returns bool
170 - */
171 - protected function isPageViewOrDiff( WebRequest $request ) {
172 - global $mediaWiki;
173 - $action = isset( $mediaWiki )
174 - ? $mediaWiki->getAction( $request )
175 - : $request->getVal( 'action', 'view' ); // cli
176 - return self::isViewAction( $action );
177 - }
178 -
179 - /**
180 - * Is this a view page action (not including diffs)?
181 - * @param $request WebRequest
182 - * @returns bool
183 - */
184 - protected function isPageView( WebRequest $request ) {
185 - return $this->isPageViewOrDiff( $request )
186 - && $request->getVal( 'diff' ) === null;
187 - }
188 -
189 - /**
190 - * Is this a web request to just *view* the *default* version of a page?
191 - * @param $request WebRequest
192 - * @returns bool
193 - */
194 - protected function isDefaultPageView( WebRequest $request ) {
195 - global $mediaWiki;
196 - $action = isset( $mediaWiki )
197 - ? $mediaWiki->getAction( $request )
198 - : $request->getVal( 'action', 'view' ); // cli
199 - return ( self::isViewAction( $action )
200 - && $request->getVal( 'oldid' ) === null
201 - && $request->getVal( 'stable' ) === null
202 - && $request->getVal( 'stableid' ) === null
203 - && $request->getVal( 'diff' ) === null
204 - );
205 - }
206 -
207 - /**
208 - * Is this a view page action?
209 - * @param $action string from MediaWiki::getAction()
210 - * @returns bool
211 - */
212 - protected static function isViewAction( $action ) {
213 - return ( $action == 'view' || $action == 'purge' || $action == 'render' );
214 - }
215 -
216 - /**
217 - * Output review notice
218 - */
219 - public function displayTag() {
220 - global $wgOut;
221 - $this->load();
222 - // Sanity check that this is a reviewable page
223 - if ( $this->article->isReviewable() ) {
224 - $wgOut->appendSubtitle( $this->reviewNotice );
225 - }
226 - return true;
227 - }
228 -
229 - /**
230 - * Add a stable link when viewing old versions of an article that
231 - * have been reviewed. (e.g. for &oldid=x urls)
232 - */
233 - public function addStableLink() {
234 - global $wgRequest, $wgOut, $wgLang;
235 - $this->load();
236 - if ( !$this->article->isReviewable() || !$wgRequest->getVal( 'oldid' ) ) {
237 - return true;
238 - }
239 - # We may have nav links like "direction=prev&oldid=x"
240 - $revID = $this->article->getOldIDFromRequest();
241 - $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $revID );
242 - # Give a notice if this rev ID corresponds to a reviewed version...
243 - if ( $frev ) {
244 - $time = $wgLang->date( $frev->getTimestamp(), true );
245 - $flags = $frev->getTags();
246 - $quality = FlaggedRevs::isQuality( $flags );
247 - $msg = $quality ? 'revreview-quality-source' : 'revreview-basic-source';
248 - $tag = wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $time );
249 - # Hide clutter
250 - if ( !$this->useSimpleUI() && !empty( $flags ) ) {
251 - $tag .= FlaggedRevsXML::ratingToggle() .
252 - "<div id='mw-fr-revisiondetails' style='display:block;'>" .
253 - wfMsgHtml( 'revreview-oldrating' ) .
254 - FlaggedRevsXML::addTagRatings( $flags ) . '</div>';
255 - }
256 - $css = 'flaggedrevs_notice plainlinks noprint';
257 - $tag = "<div id='mw-fr-revisiontag-old' class='$css'>$tag</div>";
258 - $wgOut->addHTML( $tag );
259 - }
260 - return true;
261 - }
262 -
263 - /**
264 - * @returns mixed int/false/null
265 - */
266 - protected function getRequestedStableId() {
267 - global $wgRequest;
268 - $reqId = $wgRequest->getVal( 'stableid' );
269 - if ( $reqId === "best" ) {
270 - $reqId = FlaggedRevs::getPrimeFlaggedRevId( $this->article );
271 - }
272 - return $reqId;
273 - }
274 -
275 - /**
276 - * Replaces a page with the last stable version if possible
277 - * Adds stable version status/info tags and notes
278 - * Adds a quick review form on the bottom if needed
279 - */
280 - public function setPageContent( &$outputDone, &$useParserCache ) {
281 - global $wgRequest, $wgOut, $wgContLang;
282 - $this->load();
283 - # Only trigger on page views with no oldid=x param
284 - if ( !$this->isPageView( $wgRequest ) || $wgRequest->getVal( 'oldid' ) ) {
285 - return true;
286 - # Only trigger for reviewable pages that exist
287 - } elseif ( !$this->article->exists() || !$this->article->isReviewable() ) {
288 - return true;
289 - }
290 - $tag = '';
291 - $old = $stable = false;
292 - # Check the newest stable version.
293 - $srev = $this->article->getStableRev();
294 - $stableId = $srev ? $srev->getRevId() : 0;
295 - $frev = $srev; // $frev is the revision we are looking at
296 - # Check for any explicitly requested reviewed version (stableid=X)...
297 - $reqId = $this->getRequestedStableId();
298 - if ( $reqId ) {
299 - if ( !$stableId ) {
300 - $reqId = false; // must be invalid
301 - # Treat requesting the stable version by ID as &stable=1
302 - } else if ( $reqId != $stableId ) {
303 - $old = true; // old reviewed version requested by ID
304 - $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId );
305 - if ( !$frev ) {
306 - $reqId = false; // invalid ID given
307 - }
308 - } else {
309 - $stable = true; // stable version requested by ID
310 - }
311 - }
312 - // $reqId is null if nothing requested, false if invalid
313 - if ( $reqId === false ) {
314 - $wgOut->addWikiText( wfMsg( 'revreview-invalid' ) );
315 - $wgOut->returnToMain( false, $this->article->getTitle() );
316 - # Tell MW that parser output is done
317 - $outputDone = true;
318 - $useParserCache = false;
319 - return true;
320 - }
321 - // Is the page config altered?
322 - $prot = FlaggedRevsXML::lockStatusIcon( $this->article );
323 - // Is there no stable version?
324 - if ( !$frev ) {
325 - # Add "no reviewed version" tag, but not for printable output
326 - $this->showUnreviewedPage( $tag, $prot );
327 - return true;
328 - }
329 - # Get flags and date
330 - $flags = $frev->getTags();
331 - # Get quality level
332 - $quality = FlaggedRevs::isQuality( $flags );
333 - $pristine = FlaggedRevs::isPristine( $flags );
334 - // Looking at some specific old stable revision ("&stableid=x")
335 - // set to override given the relevant conditions. If the user is
336 - // requesting the stable revision ("&stableid=x"), defer to override
337 - // behavior below, since it is the same as ("&stable=1").
338 - if ( $old ) {
339 - $this->showOldReviewedVersion( $srev, $frev, $tag, $prot );
340 - $outputDone = true; # Tell MW that parser output is done
341 - $useParserCache = false;
342 - // Stable version requested by ID or relevant conditions met to
343 - // to override page view with the stable version.
344 - } else if ( $stable || $this->showingStable() ) {
345 - $this->showStableVersion( $srev, $tag, $prot );
346 - $outputDone = true; # Tell MW that parser output is done
347 - $useParserCache = false;
348 - // Looking at some specific old revision (&oldid=x) or if FlaggedRevs is not
349 - // set to override given the relevant conditions (like &stable=0) or there
350 - // is no stable version.
351 - } else {
352 - $this->showDraftVersion( $srev, $tag, $prot );
353 - }
354 - $encJS = ''; // JS events to use
355 - # Some checks for which tag CSS to use
356 - if ( $this->useSimpleUI() ) {
357 - $tagClass = 'flaggedrevs_short';
358 - # Collapse the box details on mouseOut
359 - $encJS .= ' onmouseout="FlaggedRevs.onBoxMouseOut(event)"';
360 - } elseif ( $pristine ) {
361 - $tagClass = 'flaggedrevs_pristine';
362 - } elseif ( $quality ) {
363 - $tagClass = 'flaggedrevs_quality';
364 - } else {
365 - $tagClass = 'flaggedrevs_basic';
366 - }
367 - # Wrap tag contents in a div
368 - if ( $tag != '' ) {
369 - $rtl = $wgContLang->isRTL() ? " rtl" : ""; // RTL langauges
370 - $css = "{$tagClass}{$rtl} plainlinks noprint";
371 - $notice = "<div id=\"mw-fr-revisiontag\" class=\"{$css}\"{$encJS}>{$tag}</div>\n";
372 - $this->reviewNotice .= $notice;
373 - }
374 - return true;
375 - }
376 -
377 - /**
378 - * If the page has a stable version and it shows by default,
379 - * tell search crawlers to index only that version of the page.
380 - * Also index the draft as well if they are synced (bug 27173).
381 - * However, any URL with ?stableid=x should not be indexed (as with ?oldid=x).
382 - */
383 - public function setRobotPolicy() {
384 - global $wgRequest, $wgOut;
385 - if ( $this->article->getStableRev() && $this->article->isStableShownByDefault() ) {
386 - if ( $this->showingStable() ) {
387 - return; // stable version - index this
388 - } elseif ( !$wgRequest->getVal( 'stableid' )
389 - && $wgOut->getRevisionId() == $this->article->getStable()
390 - && $this->article->stableVersionIsSynced() )
391 - {
392 - return; // draft that is synced with the stable version - index this
393 - }
394 - $wgOut->setRobotPolicy( 'noindex,nofollow' ); // don't index this version
395 - }
396 - }
397 -
398 - /**
399 - * @param $tag review box/bar info
400 - * @param $prot protection notice
401 - * Tag output function must be called by caller
402 - */
403 - protected function showUnreviewedPage( $tag, $prot ) {
404 - global $wgOut, $wgContLang;
405 - if ( $wgOut->isPrintable() ) {
406 - return; // all this function does is add notices; don't show them
407 - }
408 - $icon = FlaggedRevsXML::draftStatusIcon();
409 - // Simple icon-based UI
410 - if ( $this->useSimpleUI() ) {
411 - // RTL langauges
412 - $rtl = $wgContLang->isRTL() ? " rtl" : "";
413 - $tag .= $prot . $icon . wfMsgExt( 'revreview-quick-none', 'parseinline' );
414 - $css = "flaggedrevs_short{$rtl} plainlinks noprint";
415 - $this->reviewNotice .= "<div id='mw-fr-revisiontag' class='$css'>$tag</div>";
416 - // Standard UI
417 - } else {
418 - $css = 'flaggedrevs_notice plainlinks noprint';
419 - $tag = "<div id='mw-fr-revisiontag' class='$css'>" .
420 - $prot . $icon . wfMsgExt( 'revreview-noflagged', 'parseinline' ) .
421 - "</div>";
422 - $this->reviewNotice .= $tag;
423 - }
424 - }
425 -
426 - /**
427 - * @param $srev stable version
428 - * @param $tag review box/bar info
429 - * @param $prot protection notice icon
430 - * Tag output function must be called by caller
431 - * Parser cache control deferred to caller
432 - */
433 - protected function showDraftVersion( FlaggedRevision $srev, &$tag, $prot ) {
434 - global $wgUser, $wgOut, $wgLang, $wgRequest;
435 - $this->load();
436 - if ( $wgOut->isPrintable() ) {
437 - return; // all this function does is add notices; don't show them
438 - }
439 - $flags = $srev->getTags();
440 - $time = $wgLang->date( $srev->getTimestamp(), true );
441 - # Get quality level
442 - $quality = FlaggedRevs::isQuality( $flags );
443 - # Get stable version sync status
444 - $synced = $this->article->stableVersionIsSynced();
445 - if ( $synced ) { // draft == stable
446 - $diffToggle = ''; // no diff to show
447 - } else { // draft != stable
448 - # The user may want the diff (via prefs)
449 - $diffToggle = $this->getTopDiffToggle( $srev, $quality );
450 - if ( $diffToggle != '' ) $diffToggle = " $diffToggle";
451 - # Make sure there is always a notice bar when viewing the draft.
452 - if ( $this->useSimpleUI() ) { // we already one for detailed UI
453 - $this->setPendingNotice( $srev, $diffToggle );
454 - }
455 - }
456 - # Give a "your edit is pending" notice to newer users if
457 - # an unreviewed edit was completed...
458 - if ( $wgRequest->getVal( 'shownotice' )
459 - && $this->article->getUserText( Revision::RAW ) == $wgUser->getName()
460 - && $this->article->revsArePending()
461 - && !$wgUser->isAllowed( 'review' ) )
462 - {
463 - $revsSince = $this->article->getPendingRevCount();
464 - $pending = $prot;
465 - if ( $this->showRatingIcon() ) {
466 - $pending .= FlaggedRevsXML::draftStatusIcon();
467 - }
468 - $pending .= wfMsgExt( 'revreview-edited',
469 - 'parseinline', $srev->getRevId(), $revsSince );
470 - $anchor = $wgRequest->getVal( 'fromsection' );
471 - if ( $anchor != null ) {
472 - $section = str_replace( '_', ' ', $anchor ); // prettify
473 - $pending .= wfMsgExt( 'revreview-edited-section', 'parse', $anchor, $section );
474 - }
475 - # Notice should always use subtitle
476 - $this->reviewNotice = "<div id='mw-fr-reviewnotice' " .
477 - "class='flaggedrevs_preview plainlinks'>$pending</div>";
478 - # Otherwise, construct some tagging info for non-printable outputs.
479 - # Also, if low profile UI is enabled and the page is synced, skip the tag.
480 - # Note: the "your edit is pending" notice has all this info, so we never add both.
481 - } else if ( !( $this->article->lowProfileUI() && $synced ) ) {
482 - $revsSince = $this->article->getPendingRevCount();
483 - // Simple icon-based UI
484 - if ( $this->useSimpleUI() ) {
485 - if ( !$wgUser->getId() ) {
486 - $msgHTML = ''; // Anons just see simple icons
487 - } else if ( $synced ) {
488 - $msg = $quality
489 - ? 'revreview-quick-quality-same'
490 - : 'revreview-quick-basic-same';
491 - $msgHTML = wfMsgExt( $msg, 'parseinline',
492 - $srev->getRevId(), $revsSince );
493 - } else {
494 - $msg = $quality
495 - ? 'revreview-quick-see-quality'
496 - : 'revreview-quick-see-basic';
497 - $msgHTML = wfMsgExt( $msg, 'parseinline',
498 - $srev->getRevId(), $revsSince );
499 - }
500 - $icon = '';
501 - # For protection based configs, show lock only if it's not redundant.
502 - if ( $this->showRatingIcon() ) {
503 - $icon = $synced
504 - ? FlaggedRevsXML::stableStatusIcon( $quality )
505 - : FlaggedRevsXML::draftStatusIcon();
506 - }
507 - $msgHTML = $prot . $icon . $msgHTML;
508 - $tag .= FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML,
509 - $revsSince, 'draft', $synced, false );
510 - // Standard UI
511 - } else {
512 - if ( $synced ) {
513 - if ( $quality ) {
514 - $msg = 'revreview-quality-same';
515 - } else {
516 - $msg = 'revreview-basic-same';
517 - }
518 - $msgHTML = wfMsgExt( $msg, 'parseinline',
519 - $srev->getRevId(), $time, $revsSince );
520 - } else {
521 - $msg = $quality
522 - ? 'revreview-newest-quality'
523 - : 'revreview-newest-basic';
524 - $msg .= ( $revsSince == 0 ) ? '-i' : '';
525 - $msgHTML = wfMsgExt( $msg, 'parseinline',
526 - $srev->getRevId(), $time, $revsSince );
527 - }
528 - $icon = $synced
529 - ? FlaggedRevsXML::stableStatusIcon( $quality )
530 - : FlaggedRevsXML::draftStatusIcon();
531 - $tag .= $prot . $icon . $msgHTML . $diffToggle;
532 - }
533 - }
534 - }
535 -
536 - /**
537 - * @param $srev stable version
538 - * @param $frev selected flagged revision
539 - * @param $tag review box/bar info
540 - * @param $prot protection notice icon
541 - * Tag output function must be called by caller
542 - * Parser cache control deferred to caller
543 - */
544 - protected function showOldReviewedVersion(
545 - FlaggedRevision $srev, FlaggedRevision $frev, &$tag, $prot
546 - ) {
547 - global $wgUser, $wgOut, $wgLang;
548 - $this->load();
549 - $flags = $frev->getTags();
550 - $time = $wgLang->date( $frev->getTimestamp(), true );
551 - # Set display revision ID
552 - $wgOut->setRevisionId( $frev->getRevId() );
553 - # Get quality level
554 - $quality = FlaggedRevs::isQuality( $flags );
555 -
556 - # Construct some tagging for non-printable outputs. Note that the pending
557 - # notice has all this info already, so don't do this if we added that already.
558 - if ( !$wgOut->isPrintable() ) {
559 - // Simple icon-based UI
560 - if ( $this->useSimpleUI() ) {
561 - $icon = '';
562 - # For protection based configs, show lock only if it's not redundant.
563 - if ( $this->showRatingIcon() ) {
564 - $icon = FlaggedRevsXML::stableStatusIcon( $quality );
565 - }
566 - $revsSince = $this->article->getPendingRevCount();
567 - if ( !$wgUser->getId() ) {
568 - $msgHTML = ''; // Anons just see simple icons
569 - } else {
570 - $msg = $quality
571 - ? 'revreview-quick-quality-old'
572 - : 'revreview-quick-basic-old';
573 - $msgHTML = wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $revsSince );
574 - }
575 - $msgHTML = $prot . $icon . $msgHTML;
576 - $tag = FlaggedRevsXML::prettyRatingBox( $frev, $msgHTML,
577 - $revsSince, 'oldstable', false /*synced*/ );
578 - // Standard UI
579 - } else {
580 - $icon = FlaggedRevsXML::stableStatusIcon( $quality );
581 - $msg = $quality
582 - ? 'revreview-quality-old'
583 - : 'revreview-basic-old';
584 - $tag = $prot . $icon;
585 - $tag .= wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $time );
586 - # Hide clutter
587 - if ( !empty( $flags ) ) {
588 - $tag .= FlaggedRevsXML::ratingToggle();
589 - $tag .= "<div id='mw-fr-revisiondetails' style='display:block;'>" .
590 - wfMsgHtml( 'revreview-oldrating' ) .
591 - FlaggedRevsXML::addTagRatings( $flags ) . '</div>';
592 - }
593 - }
594 - }
595 -
596 - # Check if this is a redirect...
597 - $text = $frev->getRevText();
598 - $redirHtml = $this->getRedirectHtml( $text );
599 -
600 - # Parse and output HTML
601 - if ( $redirHtml == '' ) {
602 - $parserOptions = FlaggedRevs::makeParserOptions();
603 - $parserOut = FlaggedRevs::parseStableText(
604 - $this->article->getTitle(), $text, $frev->getRevId(), $parserOptions );
605 - $this->addParserOutput( $parserOut );
606 - } else {
607 - $wgOut->addHtml( $redirHtml );
608 - }
609 - }
610 -
611 - /**
612 - * @param $srev stable version
613 - * @param $tag review box/bar info
614 - * @param $prot protection notice
615 - * Tag output function must be called by caller
616 - * Parser cache control deferred to caller
617 - */
618 - protected function showStableVersion( FlaggedRevision $srev, &$tag, $prot ) {
619 - global $wgOut, $wgLang, $wgUser;
620 - $this->load();
621 - $flags = $srev->getTags();
622 - $time = $wgLang->date( $srev->getTimestamp(), true );
623 - # Set display revision ID
624 - $wgOut->setRevisionId( $srev->getRevId() );
625 - # Get quality level
626 - $quality = FlaggedRevs::isQuality( $flags );
627 -
628 - $synced = $this->article->stableVersionIsSynced();
629 - # Construct some tagging
630 - if ( !$wgOut->isPrintable() && !( $this->article->lowProfileUI() && $synced ) ) {
631 - $revsSince = $this->article->getPendingRevCount();
632 - // Simple icon-based UI
633 - if ( $this->useSimpleUI() ) {
634 - $icon = '';
635 - # For protection based configs, show lock only if it's not redundant.
636 - if ( $this->showRatingIcon() ) {
637 - $icon = FlaggedRevsXML::stableStatusIcon( $quality );
638 - }
639 - if ( !$wgUser->getId() ) {
640 - $msgHTML = ''; // Anons just see simple icons
641 - } else {
642 - $msg = $quality
643 - ? 'revreview-quick-quality'
644 - : 'revreview-quick-basic';
645 - # Uses messages 'revreview-quick-quality-same', 'revreview-quick-basic-same'
646 - $msg = $synced ? "{$msg}-same" : $msg;
647 - $msgHTML = wfMsgExt( $msg, 'parseinline',
648 - $srev->getRevId(), $revsSince );
649 - }
650 - $msgHTML = $prot . $icon . $msgHTML;
651 - $tag = FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML,
652 - $revsSince, 'stable', $synced );
653 - // Standard UI
654 - } else {
655 - $icon = FlaggedRevsXML::stableStatusIcon( $quality );
656 - $msg = $quality ? 'revreview-quality' : 'revreview-basic';
657 - if ( $synced ) {
658 - # uses messages 'revreview-quality-same', 'revreview-basic-same'
659 - $msg .= '-same';
660 - } elseif ( $revsSince == 0 ) {
661 - # uses messages 'revreview-quality-i', 'revreview-basic-i'
662 - $msg .= '-i';
663 - }
664 - $tag = $prot . $icon;
665 - $tag .= wfMsgExt( $msg, 'parseinline', $srev->getRevId(), $time, $revsSince );
666 - if ( !empty( $flags ) ) {
667 - $tag .= FlaggedRevsXML::ratingToggle();
668 - $tag .= "<div id='mw-fr-revisiondetails' style='display:block;'>" .
669 - FlaggedRevsXML::addTagRatings( $flags ) . '</div>';
670 - }
671 - }
672 - }
673 -
674 - # Get parsed stable version and output HTML
675 - $parserOut = FlaggedRevs::getPageCache( $this->article, $wgUser );
676 - if ( $parserOut ) {
677 - $this->addParserOutput( $parserOut );
678 - } else {
679 - $text = $srev->getRevText();
680 - # Check if this is a redirect...
681 - $redirHtml = $this->getRedirectHtml( $text );
682 - # Don't parse redirects, use separate handling...
683 - if ( $redirHtml == '' ) {
684 - # Get the new stable output
685 - $parserOptions = FlaggedRevs::makeParserOptions();
686 - $parserOut = FlaggedRevs::parseStableText(
687 - $this->article->getTitle(), $text, $srev->getRevId(), $parserOptions );
688 - # Update the stable version cache
689 - FlaggedRevs::updatePageCache( $this->article, $parserOptions, $parserOut );
690 - # Add the stable output to the page view
691 - $this->addParserOutput( $parserOut );
692 -
693 - # Update the stable version dependancies
694 - FlaggedRevs::updateCacheTracking( $this->article, $parserOut );
695 - } else {
696 - $wgOut->addHtml( $redirHtml );
697 - }
698 - }
699 -
700 - # Update page sync status for tracking purposes.
701 - # NOTE: avoids master hits and doesn't have to be perfect for what it does
702 - if ( $this->article->syncedInTracking() != $synced ) {
703 - if ( wfGetDB( DB_SLAVE )->getLag() <= 5 ) { // avoid write-delay cycles
704 - FlaggedRevs::updateSyncStatus( $this->article, $synced );
705 - }
706 - }
707 - }
708 -
709 - // Add parser output and update title
710 - // @TODO: refactor MW core to move this back
711 - protected function addParserOutput( ParserOutput $parserOut ) {
712 - global $wgOut;
713 - $wgOut->addParserOutput( $parserOut );
714 - # Adjust the title if it was set by displaytitle, -{T|}- or language conversion
715 - $titleText = $parserOut->getTitleText();
716 - if ( strval( $titleText ) !== '' ) {
717 - $wgOut->setPageTitle( $titleText );
718 - }
719 - }
720 -
721 - // Get fancy redirect arrow and link HTML
722 - protected function getRedirectHtml( $text ) {
723 - $rTargets = Title::newFromRedirectArray( $text );
724 - if ( $rTargets ) {
725 - return $this->article->viewRedirect( $rTargets );
726 - }
727 - return '';
728 - }
729 -
730 - // Show icons for draft/stable/old reviewed versions
731 - protected function showRatingIcon() {
732 - if ( FlaggedRevs::useOnlyIfProtected() ) {
733 - // If there is only one quality level and we have tabs to know
734 - // which version we are looking at, then just use the lock icon...
735 - return FlaggedRevs::qualityVersions();
736 - }
737 - return true;
738 - }
739 -
740 - /**
741 - * Get collapsible diff-to-stable html to add to the review notice as needed
742 - * @param FlaggedRevision $srev, stable version
743 - * @param bool $quality, revision is quality
744 - * @returns string, the html line (either "" or "<diff toggle><diff div>")
745 - */
746 - protected function getTopDiffToggle( FlaggedRevision $srev, $quality ) {
747 - global $wgUser;
748 - $this->load();
749 - if ( !$wgUser->getBoolOption( 'flaggedrevsviewdiffs' ) ) {
750 - return false; // nothing to do here
751 - }
752 - # Diff should only show for the draft
753 - $oldid = $this->article->getOldIDFromRequest();
754 - $latest = $this->article->getLatest();
755 - if ( $oldid && $oldid != $latest ) {
756 - return false; // not viewing the draft
757 - }
758 - $revsSince = $this->article->getPendingRevCount();
759 - if ( !$revsSince ) {
760 - return false; // no pending changes
761 - }
762 - $title = $this->article->getTitle(); // convenience
763 - # Review status of left diff revision...
764 - $leftNote = $quality
765 - ? 'revreview-hist-quality'
766 - : 'revreview-hist-basic';
767 - $lClass = FlaggedRevsXML::getQualityColor( (int)$quality );
768 - $leftNote = "<span class='$lClass'>[" . wfMsgHtml( $leftNote ) . "]</span>";
769 - # Review status of right diff revision...
770 - $rClass = FlaggedRevsXML::getQualityColor( false );
771 - $rightNote = "<span class='$rClass'>[" .
772 - wfMsgHtml( 'revreview-hist-pending' ) . "]</span>";
773 - # Get the actual body of the diff...
774 - $diffEngine = new DifferenceEngine( $title, $srev->getRevId(), $latest );
775 - $diffBody = $diffEngine->getDiffBody();
776 - if ( strlen( $diffBody ) > 0 ) {
777 - $nEdits = $revsSince - 1; // full diff-to-stable, no need for query
778 - if ( $nEdits ) {
779 - $limit = 100;
780 - $nUsers = $title->countAuthorsBetween( $srev->getRevId(), $latest, $limit );
781 - $multiNotice = DifferenceEngine::intermediateEditsMsg( $nEdits, $nUsers, $limit );
782 - } else {
783 - $multiNotice = '';
784 - }
785 - $diffEngine->showDiffStyle(); // add CSS
786 - $this->isDiffFromStable = true; // alter default review form tags
787 - return
788 - FlaggedRevsXML::diffToggle() .
789 - "<div id='mw-fr-stablediff'>\n" .
790 - self::getFormattedDiff( $diffBody, $multiNotice, $leftNote, $rightNote ) .
791 - "</div>\n";;
792 - }
793 - return '';
794 - }
795 -
796 - // $n number of in-between revs
797 - protected static function getFormattedDiff(
798 - $diffBody, $multiNotice, $leftStatus, $rightStatus
799 - ) {
800 - if ( $multiNotice != '' ) {
801 - $multiNotice = "<tr><td colspan='4' align='center' class='diff-multi'>" .
802 - $multiNotice . "</td></tr>";
803 - }
804 - return
805 - "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" .
806 - "<col class='diff-marker' />" .
807 - "<col class='diff-content' />" .
808 - "<col class='diff-marker' />" .
809 - "<col class='diff-content' />" .
810 - "<tr>" .
811 - "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" .
812 - $leftStatus . "</b></td>" .
813 - "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" .
814 - $rightStatus . "</b></td>" .
815 - "</tr>" .
816 - $multiNotice .
817 - $diffBody .
818 - "</table>";
819 - }
820 -
821 - /**
822 - * Get the normal and display files for the underlying ImagePage.
823 - * If the a stable version needs to be displayed, this will set $normalFile
824 - * to the current version, and $displayFile to the desired version.
825 - *
826 - * If no stable version is required, the reference parameters will not be set
827 - *
828 - * Depends on $wgRequest
829 - */
830 - public function imagePageFindFile( &$normalFile, &$displayFile ) {
831 - global $wgRequest;
832 - $this->load();
833 - # Determine timestamp. A reviewed version may have explicitly been requested...
834 - $frev = null;
835 - $time = false;
836 - $reqId = $wgRequest->getVal( 'stableid' );
837 - if ( $reqId ) {
838 - $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId );
839 - } elseif ( $this->showingStable() ) {
840 - $frev = $this->article->getStableRev();
841 - }
842 - if ( $frev ) {
843 - $time = $frev->getFileTimestamp();
844 - // B/C, may be stored in associated image version metadata table
845 - // @TODO: remove, updateTracking.php does this
846 - if ( !$time ) {
847 - $dbr = wfGetDB( DB_SLAVE );
848 - $time = $dbr->selectField( 'flaggedimages',
849 - 'fi_img_timestamp',
850 - array( 'fi_rev_id' => $frev->getRevId(),
851 - 'fi_name' => $this->article->getTitle()->getDBkey() ),
852 - __METHOD__
853 - );
854 - $time = trim( $time ); // remove garbage
855 - $time = $time ? wfTimestamp( TS_MW, $time ) : false;
856 - }
857 - }
858 - if ( !$time ) {
859 - # Try request parameter
860 - $time = $wgRequest->getVal( 'filetimestamp', false );
861 - }
862 -
863 - if ( !$time ) {
864 - return; // Use the default behaviour
865 - }
866 -
867 - $title = $this->article->getTitle();
868 - $displayFile = wfFindFile( $title, array( 'time' => $time ) );
869 - # If none found, try current
870 - if ( !$displayFile ) {
871 - wfDebug( __METHOD__ . ": {$title->getPrefixedDBkey()}: $time not found, using current\n" );
872 - $displayFile = wfFindFile( $title );
873 - # If none found, use a valid local placeholder
874 - if ( !$displayFile ) {
875 - $displayFile = wfLocalFile( $title ); // fallback to current
876 - }
877 - $normalFile = $displayFile;
878 - # If found, set $normalFile
879 - } else {
880 - wfDebug( __METHOD__ . ": {$title->getPrefixedDBkey()}: using timestamp $time\n" );
881 - $normalFile = wfFindFile( $title );
882 - }
883 - }
884 -
885 - /**
886 - * Adds stable version tags to page when viewing history
887 - */
888 - public function addToHistView() {
889 - global $wgOut;
890 - $this->load();
891 - # Add a notice if there are pending edits...
892 - $srev = $this->article->getStableRev();
893 - if ( $srev && $this->article->revsArePending() ) {
894 - $revsSince = $this->article->getPendingRevCount();
895 - $tag = "<div id='mw-fr-revisiontag-edit' class='flaggedrevs_notice plainlinks'>" .
896 - FlaggedRevsXML::lockStatusIcon( $this->article ) . # flag protection icon as needed
897 - FlaggedRevsXML::pendingEditNotice( $this->article, $srev, $revsSince ) . "</div>";
898 - $wgOut->addHTML( $tag );
899 - }
900 - return true;
901 - }
902 -
903 - /**
904 - * Adds stable version tags to page when editing
905 - */
906 - public function addToEditView( EditPage $editPage ) {
907 - global $wgOut, $wgUser;
908 - $this->load();
909 - # Must be reviewable. UI may be limited to unobtrusive patrolling system.
910 - if ( !$this->article->isReviewable() ) {
911 - return true;
912 - }
913 - $items = array();
914 - # Show stabilization log
915 - $log = $this->stabilityLogNotice();
916 - if ( $log ) $items[] = $log;
917 - # Check the newest stable version
918 - $frev = $this->article->getStableRev();
919 - if ( $frev ) {
920 - $quality = $frev->getQuality();
921 - # Find out revision id of base version
922 - $latestId = $this->article->getLatest();
923 - $revId = $editPage->oldid ? $editPage->oldid : $latestId;
924 - # Let new users know about review procedure a tag.
925 - # If the log excerpt was shown this is redundant.
926 - if ( !$log && !$wgUser->getId() && $this->article->isStableShownByDefault() ) {
927 - $items[] = wfMsgExt( 'revreview-editnotice', 'parseinline' );
928 - }
929 - # Add a notice if there are pending edits...
930 - if ( $this->article->revsArePending() ) {
931 - $revsSince = $this->article->getPendingRevCount();
932 - $items[] = FlaggedRevsXML::pendingEditNotice( $this->article, $frev, $revsSince );
933 - }
934 - # Show diff to stable, to make things less confusing.
935 - # This can be disabled via user preferences and other conditions...
936 - if ( $frev->getRevId() < $latestId // changes were made
937 - && $wgUser->getBoolOption( 'flaggedrevseditdiffs' ) // not disable via prefs
938 - && $revId == $latestId // only for current rev
939 - && $editPage->section != 'new' // not for new sections
940 - && $editPage->formtype != 'diff' // not "show changes"
941 - ) {
942 - # Left diff side...
943 - $leftNote = $quality
944 - ? 'revreview-hist-quality'
945 - : 'revreview-hist-basic';
946 - $lClass = FlaggedRevsXML::getQualityColor( (int)$quality );
947 - $leftNote = "<span class='$lClass'>[" .
948 - wfMsgHtml( $leftNote ) . "]</span>";
949 - # Right diff side...
950 - $rClass = FlaggedRevsXML::getQualityColor( false );
951 - $rightNote = "<span class='$rClass'>[" .
952 - wfMsgHtml( 'revreview-hist-pending' ) . "]</span>";
953 - # Get the stable version source
954 - $text = $frev->getRevText();
955 - # Are we editing a section?
956 - $section = ( $editPage->section == "" ) ?
957 - false : intval( $editPage->section );
958 - if ( $section !== false ) {
959 - $text = $this->article->getSection( $text, $section );
960 - }
961 - if ( $text !== false && strcmp( $text, $editPage->textbox1 ) !== 0 ) {
962 - $diffEngine = new DifferenceEngine( $this->article->getTitle() );
963 - $diffBody = $diffEngine->generateDiffBody( $text, $editPage->textbox1 );
964 - $diffHtml =
965 - wfMsgExt( 'review-edit-diff', 'parseinline' ) . ' ' .
966 - FlaggedRevsXML::diffToggle() .
967 - "<div id='mw-fr-stablediff'>" .
968 - self::getFormattedDiff( $diffBody, '', $leftNote, $rightNote ) .
969 - "</div>\n";
970 - $items[] = $diffHtml;
971 - $diffEngine->showDiffStyle(); // add CSS
972 - }
973 - }
974 - # Output items
975 - if ( count( $items ) ) {
976 - $html = "<table class='flaggedrevs_editnotice plainlinks'>";
977 - foreach ( $items as $item ) {
978 - $html .= '<tr><td>' . $item . '</td></tr>';
979 - }
980 - $html .= '</table>';
981 - $wgOut->addHTML( $html );
982 - }
983 - }
984 - return true;
985 - }
986 -
987 - protected function stabilityLogNotice() {
988 - $this->load();
989 - $s = '';
990 - # Only for pages manually made to be stable...
991 - if ( $this->article->isPageLocked() ) {
992 - $s = wfMsgExt( 'revreview-locked', 'parseinline' );
993 - $s .= ' ' . FlaggedRevsXML::logDetailsToggle();
994 - $s .= FlaggedRevsXML::stabilityLogExcerpt( $this->article );
995 - # ...or unstable
996 - } elseif ( $this->article->isPageUnlocked() ) {
997 - $s = wfMsgExt( 'revreview-unlocked', 'parseinline' );
998 - $s .= ' ' . FlaggedRevsXML::logDetailsToggle();
999 - $s .= FlaggedRevsXML::stabilityLogExcerpt( $this->article );
1000 - }
1001 - return $s;
1002 - }
1003 -
1004 - public function addToNoSuchSection( EditPage $editPage, &$s ) {
1005 - $this->load();
1006 - $srev = $this->article->getStableRev();
1007 - # Add notice for users that may have clicked "edit" for a
1008 - # section in the stable version that isn't in the draft.
1009 - if ( $srev && $this->article->revsArePending() ) {
1010 - $revsSince = $this->article->getPendingRevCount();
1011 - if ( $revsSince ) {
1012 - $s .= "<div class='flaggedrevs_editnotice plainlinks'>" .
1013 - wfMsgExt( 'revreview-pending-nosection', 'parseinline',
1014 - $srev->getRevId(), $revsSince ) . "</div>";
1015 - }
1016 - }
1017 - return true;
1018 - }
1019 -
1020 - /**
1021 - * Add unreviewed pages links
1022 - */
1023 - public function addToCategoryView() {
1024 - global $wgOut, $wgUser;
1025 - $this->load();
1026 - if ( !$wgUser->isAllowed( 'review' ) ) {
1027 - return true;
1028 - }
1029 - if ( !FlaggedRevs::useOnlyIfProtected() ) {
1030 - # Add links to lists of unreviewed pages and pending changes in this category
1031 - $category = $this->article->getTitle()->getText();
1032 - $wgOut->appendSubtitle(
1033 - Html::rawElement(
1034 - 'span',
1035 - array( 'class' => 'plainlinks', 'id' => 'mw-fr-category-oldreviewed' ),
1036 - wfMsgExt( 'flaggedrevs-categoryview', 'parseinline', urlencode( $category ) )
1037 - )
1038 - );
1039 - }
1040 - return true;
1041 - }
1042 -
1043 - /**
1044 - * Add review form to pages when necessary
1045 - * on a regular page view (action=view)
1046 - */
1047 - public function addReviewForm( &$data ) {
1048 - global $wgRequest, $wgUser, $wgOut;
1049 - $this->load();
1050 - if ( $wgOut->isPrintable() ) {
1051 - return false; // Must be on non-printable output
1052 - }
1053 - # User must have review rights
1054 - if ( !$wgUser->isAllowed( 'review' ) ) {
1055 - return true;
1056 - }
1057 - # Page must exist and be reviewable
1058 - if ( !$this->article->exists() || !$this->article->isReviewable() ) {
1059 - return true;
1060 - }
1061 - # Must be a page view action...
1062 - if ( !$this->isPageViewOrDiff( $wgRequest ) ) {
1063 - return true;
1064 - }
1065 - # Get the revision being displayed
1066 - $rev = false;
1067 - if ( $this->reviewFormRev ) {
1068 - $rev = $this->reviewFormRev; // $newRev for diffs stored here
1069 - } elseif ( $wgOut->getRevisionId() ) {
1070 - $rev = Revision::newFromId( $wgOut->getRevisionId() );
1071 - }
1072 - # Build the review form as needed
1073 - if ( $rev && ( !$this->diffRevs || $this->isReviewableDiff ) ) {
1074 - $form = new RevisionReviewFormGUI( $wgUser, $this->article, $rev );
1075 - # Default tags and existence of "reject" button depend on context
1076 - if ( $this->diffRevs ) {
1077 - $form->setDiffPriorRev( $this->diffRevs['old'] );
1078 - }
1079 - # Review notice box goes in top of form
1080 - $form->setTopNotice( $this->diffNoticeBox );
1081 - # $wgOut may not already have the inclusion IDs, such as for diffonly=1.
1082 - # RevisionReviewForm will fetch them as needed however.
1083 - if ( $wgOut->getRevisionId() == $rev->getId() ) {
1084 - $form->setIncludeVersions( $wgOut->getTemplateIds(), $wgOut->getImageTimeKeys() );
1085 - }
1086 - list( $html, $status ) = $form->getHtml();
1087 - # Diff action: place the form at the top of the page
1088 - if ( $this->diffRevs ) {
1089 - $wgOut->prependHTML( $html );
1090 - # View action: place the form at the bottom of the page
1091 - } else {
1092 - $data .= $html;
1093 - }
1094 - }
1095 - return true;
1096 - }
1097 -
1098 - /**
1099 - * Add link to stable version setting to protection form
1100 - */
1101 - public function addVisibilityLink( &$data ) {
1102 - global $wgRequest, $wgOut;
1103 - $this->load();
1104 - if ( FlaggedRevs::useProtectionLevels() ) {
1105 - return true; // simple custom levels set for action=protect
1106 - }
1107 - # Check only if the title is reviewable
1108 - if ( !FlaggedRevs::inReviewNamespace( $this->article->getTitle() ) ) {
1109 - return true;
1110 - }
1111 - $action = $wgRequest->getVal( 'action', 'view' );
1112 - if ( $action == 'protect' || $action == 'unprotect' ) {
1113 - $title = SpecialPage::getTitleFor( 'Stabilization' );
1114 - # Give a link to the page to configure the stable version
1115 - $frev = $this->article->getStableRev();
1116 - if ( $frev && $frev->getRevId() == $this->article->getLatest() ) {
1117 - $wgOut->prependHTML( "<span class='plainlinks'>" .
1118 - wfMsgExt( 'revreview-visibility-synced', 'parseinline',
1119 - $title->getPrefixedText() ) . "</span>" );
1120 - } elseif ( $frev ) {
1121 - $wgOut->prependHTML( "<span class='plainlinks'>" .
1122 - wfMsgExt( 'revreview-visibility-outdated', 'parseinline',
1123 - $title->getPrefixedText() ) . "</span>" );
1124 - } else {
1125 - $wgOut->prependHTML( "<span class='plainlinks'>" .
1126 - wfMsgExt( 'revreview-visibility-nostable', 'parseinline',
1127 - $title->getPrefixedText() ) . "</span>" );
1128 - }
1129 - }
1130 - return true;
1131 - }
1132 -
1133 - /**
1134 - * Modify an array of action links, as used by SkinTemplateNavigation and
1135 - * SkinTemplateTabs, to inlude flagged revs UI elements
1136 - */
1137 - public function setActionTabs( $skin, array &$actions ) {
1138 - global $wgUser;
1139 - $this->load();
1140 - if ( FlaggedRevs::useProtectionLevels() ) {
1141 - return true; // simple custom levels set for action=protect
1142 - }
1143 - $title = $this->article->getTitle()->getSubjectPage();
1144 - if ( !FlaggedRevs::inReviewNamespace( $title ) ) {
1145 - return true; // Only reviewable pages need these tabs
1146 - }
1147 - // Check if we should show a stabilization tab
1148 - if (
1149 - !$this->article->getTitle()->isTalkPage() &&
1150 - is_array( $actions ) &&
1151 - !isset( $actions['protect'] ) &&
1152 - !isset( $actions['unprotect'] ) &&
1153 - $wgUser->isAllowed( 'stablesettings' ) &&
1154 - $title->exists() )
1155 - {
1156 - $stableTitle = SpecialPage::getTitleFor( 'Stabilization' );
1157 - // Add the tab
1158 - $actions['default'] = array(
1159 - 'class' => false,
1160 - 'text' => wfMsg( 'stabilization-tab' ),
1161 - 'href' => $stableTitle->getLocalUrl(
1162 - 'page=' . $title->getPrefixedUrl()
1163 - )
1164 - );
1165 - }
1166 - return true;
1167 - }
1168 -
1169 - /**
1170 - * Modify an array of tab links to include flagged revs UI elements
1171 - * @param string $type ('flat' for SkinTemplateTabs, 'nav' for SkinTemplateNavigation)
1172 - */
1173 - public function setViewTabs( Skin $skin, array &$views, $type ) {
1174 - global $wgRequest;
1175 - $this->load();
1176 - if ( $this->article->getTitle()->isTalkPage() ) {
1177 - return true; // leave talk pages alone
1178 - }
1179 - if ( !$this->article->isReviewable() ) {
1180 - return true; // Not a reviewable page or the UI is hidden
1181 - }
1182 - $srev = $this->article->getStableRev();
1183 - if ( !$srev ) {
1184 - return true; // No stable revision exists
1185 - }
1186 - $synced = $this->article->stableVersionIsSynced();
1187 - $pendingEdits = !$synced && $this->article->isStableShownByDefault();
1188 - // Set the edit tab names as needed...
1189 - if ( $pendingEdits ) {
1190 - if ( isset( $views['edit'] ) ) {
1191 - $views['edit']['text'] = wfMsg( 'revreview-edit' );
1192 - }
1193 - if ( isset( $views['viewsource'] ) ) {
1194 - $views['viewsource']['text'] = wfMsg( 'revreview-source' );
1195 - }
1196 - }
1197 - # Add "pending changes" tab if the page is not synced
1198 - if ( !$synced ) {
1199 - $this->addDraftTab( $views, $srev, $type );
1200 - }
1201 - return true;
1202 - }
1203 -
1204 - // Add "pending changes" tab and set tab selection CSS
1205 - protected function addDraftTab( array &$views, FlaggedRevision $srev, $type ) {
1206 - global $wgRequest, $wgOut;
1207 - $title = $this->article->getTitle(); // convenience
1208 - $tabs = array(
1209 - 'read' => array( // view stable
1210 - 'text' => '', // unused
1211 - 'href' => $title->getLocalUrl( 'stable=1' ),
1212 - 'class' => ''
1213 - ),
1214 - 'draft' => array( // view draft
1215 - 'text' => wfMsg( 'revreview-current' ),
1216 - 'href' => $title->getLocalUrl( 'stable=0&redirect=no' ),
1217 - 'class' => 'collapsible'
1218 - ),
1219 - );
1220 - // Set tab selection CSS
1221 - if ( $this->showingStable() || $wgRequest->getVal( 'stableid' ) ) {
1222 - // We are looking a the stable version or an old reviewed one
1223 - $tabs['read']['class'] = 'selected';
1224 - } elseif ( $this->isPageViewOrDiff( $wgRequest ) ) {
1225 - $ts = null;
1226 - if ( $wgOut->getRevisionId() ) { // @TODO: avoid same query in Skin.php
1227 - $ts = ( $wgOut->getRevisionId() == $this->article->getLatest() )
1228 - ? $this->article->getTimestamp() // skip query
1229 - : Revision::getTimestampFromId( $title, $wgOut->getRevisionId() );
1230 - }
1231 - // Are we looking at a pending revision?
1232 - if ( $ts > $srev->getRevTimestamp() ) { // bug 15515
1233 - $tabs['draft']['class'] .= ' selected';
1234 - // Are there *just* pending template/file changes.
1235 - } elseif ( $this->article->onlyTemplatesOrFilesPending()
1236 - && $wgOut->getRevisionId() == $this->article->getStable() )
1237 - {
1238 - $tabs['draft']['class'] .= ' selected';
1239 - // Otherwise, fallback to regular tab behavior
1240 - } else {
1241 - $tabs['read']['class'] = 'selected';
1242 - }
1243 - }
1244 - $newViews = array();
1245 - // Rebuild tabs array. Deals with Monobook vs Vector differences.
1246 - if ( $type == 'nav' ) { // Vector et al
1247 - foreach ( $views as $tabAction => $data ) {
1248 - // The 'view' tab. Make it go to the stable version...
1249 - if ( $tabAction == 'view' ) {
1250 - // 'view' for content page; make it go to the stable version
1251 - $newViews[$tabAction]['text'] = $data['text']; // keep tab name
1252 - $newViews[$tabAction]['href'] = $tabs['read']['href'];
1253 - $newViews[$tabAction]['class'] = $tabs['read']['class'];
1254 - // All other tabs...
1255 - } else {
1256 - // Add 'draft' tab to content page to the left of 'edit'...
1257 - if ( $tabAction == 'edit' || $tabAction == 'viewsource' ) {
1258 - $newViews['current'] = $tabs['draft'];
1259 - }
1260 - $newViews[$tabAction] = $data;
1261 - }
1262 - }
1263 - } elseif ( $type == 'flat' ) { // MonoBook et al
1264 - $first = true;
1265 - foreach ( $views as $tabAction => $data ) {
1266 - // The first tab ('page'). Make it go to the stable version...
1267 - if ( $first ) {
1268 - $first = false;
1269 - $newViews[$tabAction]['text'] = $data['text']; // keep tab name
1270 - $newViews[$tabAction]['href'] = $tabs['read']['href'];
1271 - $newViews[$tabAction]['class'] = $data['class']; // keep tab class
1272 - // All other tabs...
1273 - } else {
1274 - // Add 'draft' tab to content page to the left of 'edit'...
1275 - if ( $tabAction == 'edit' || $tabAction == 'viewsource' ) {
1276 - $newViews['current'] = $tabs['draft'];
1277 - }
1278 - $newViews[$tabAction] = $data;
1279 - }
1280 - }
1281 - }
1282 - // Replaces old tabs with new tabs
1283 - $views = $newViews;
1284 - }
1285 -
1286 - /**
1287 - * Adds a notice saying that this revision is pending review
1288 - * @param FlaggedRevision $srev The stable version
1289 - * @param string $diffToggle either "" or " <diff toggle><diff div>"
1290 - * @return void
1291 - */
1292 - public function setPendingNotice( FlaggedRevision $srev, $diffToggle = '' ) {
1293 - global $wgLang;
1294 - $this->load();
1295 - $time = $wgLang->date( $srev->getTimestamp(), true );
1296 - $revsSince = $this->article->getPendingRevCount();
1297 - $msg = $srev->getQuality()
1298 - ? 'revreview-newest-quality'
1299 - : 'revreview-newest-basic';
1300 - $msg .= ( $revsSince == 0 ) ? '-i' : '';
1301 - # Add bar msg to the top of the page...
1302 - $css = 'flaggedrevs_preview plainlinks';
1303 - $msgHTML = wfMsgExt( $msg, 'parseinline', $srev->getRevId(), $time, $revsSince );
1304 - $this->reviewNotice .= "<div id='mw-fr-reviewnotice' class='$css'>" .
1305 - "$msgHTML$diffToggle</div>";
1306 - }
1307 -
1308 - /**
1309 - * When viewing a diff:
1310 - * (a) Add the review form to the top of the page
1311 - * (b) Mark off which versions are checked or not
1312 - * (c) When comparing the stable revision to the current:
1313 - * (i) Show a tag with some explanation for the diff
1314 - * (ii) List any template/file changes pending review
1315 - */
1316 - public function addToDiffView( $diff, $oldRev, $newRev ) {
1317 - global $wgRequest, $wgUser, $wgOut, $wgMemc;
1318 - $this->load();
1319 - # Exempt printer-friendly output
1320 - if ( $wgOut->isPrintable() ) {
1321 - return true;
1322 - # Multi-page diffs are useless and misbehave (bug 19327). Sanity check $newRev.
1323 - } elseif ( $this->isMultiPageDiff || !$newRev ) {
1324 - return true;
1325 - # Page must be reviewable.
1326 - } elseif ( !$this->article->isReviewable() ) {
1327 - return true;
1328 - }
1329 - $srev = $this->article->getStableRev();
1330 - # Check if this is a diff-to-stable. If so:
1331 - # (a) prompt reviewers to review the changes
1332 - # (b) list template/file changes if only includes are pending
1333 - if ( $srev
1334 - && $this->isDiffFromStable
1335 - && !$this->article->stableVersionIsSynced() ) // pending changes
1336 - {
1337 - $changeDiv = '';
1338 - $this->reviewFormRev = $newRev;
1339 - $changeList = array();
1340 - # Page not synced only due to includes?
1341 - if ( !$this->article->revsArePending() ) {
1342 - # Add a list of links to each changed template...
1343 - $changeList = self::fetchTemplateChanges( $srev );
1344 - # Add a list of links to each changed file...
1345 - $changeList = array_merge( $changeList, self::fetchFileChanges( $srev ) );
1346 - # Correct bad cache which said they were not synced...
1347 - if ( !count( $changeList ) ) {
1348 - global $wgParserCacheExpireTime;
1349 - $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $this->article->getId() );
1350 - $data = FlaggedRevs::makeMemcObj( "true" );
1351 - $wgMemc->set( $key, $data, $wgParserCacheExpireTime );
1352 - }
1353 - }
1354 - # If there are pending revs or templates/files changes, notify the user...
1355 - if ( $this->article->revsArePending() || count( $changeList ) ) {
1356 - $changeDiv = '';
1357 - # If the user can review then prompt them to review them...
1358 - if ( $wgUser->isAllowed( 'review' ) ) {
1359 - # Set a key to note that someone is viewing this
1360 - FRUserActivity::setUserReviewingDiff(
1361 - $wgUser, $oldRev->getId(), $newRev->getId() );
1362 - // Reviewer just edited...
1363 - if ( $wgRequest->getInt( 'shownotice' )
1364 - && $newRev->isCurrent()
1365 - && $newRev->getRawUserText() == $wgUser->getName() )
1366 - {
1367 - $title = $this->article->getTitle(); // convenience
1368 - // @TODO: make diff class cache this
1369 - $n = $title->countRevisionsBetween( $oldRev, $newRev );
1370 - if ( $n ) {
1371 - $msg = 'revreview-update-edited-prev'; // previous pending edits
1372 - } else {
1373 - $msg = 'revreview-update-edited'; // just couldn't autoreview
1374 - }
1375 - // All other cases...
1376 - } else {
1377 - $msg = 'revreview-update'; // generic "please review" notice...
1378 - }
1379 - $changeDiv .= wfMsgExt( $msg, 'parse' );
1380 - }
1381 - # Add include change list...
1382 - if ( count( $changeList ) ) {
1383 - $changeDiv .= '<p>' .
1384 - wfMsgExt( 'revreview-update-includes', 'parseinline' ) .
1385 - '&#160;' . implode( ', ', $changeList ) . '</p>';
1386 - # Add include usage notice...
1387 - if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE ) {
1388 - $changeDiv .= wfMsgExt( 'revreview-update-use', 'parse' );
1389 - }
1390 - }
1391 - }
1392 - if ( $changeDiv != '' ) {
1393 - if ( $wgUser->isAllowed( 'review' ) ) {
1394 - $this->diffNoticeBox = $changeDiv; // add as part of form
1395 - } else {
1396 - $css = 'flaggedrevs_diffnotice plainlinks';
1397 - $wgOut->addHTML(
1398 - "<div id='mw-fr-difftostable' class='$css'>$changeDiv</div>\n"
1399 - );
1400 - }
1401 - }
1402 - }
1403 - # Add a link to diff from stable to current as needed.
1404 - # Show review status of the diff revision(s). Uses a <table>.
1405 - $wgOut->addHTML(
1406 - '<div id="mw-fr-diff-headeritems">' .
1407 - self::diffLinkAndMarkers( $this->article, $oldRev, $newRev ) .
1408 - '</div>'
1409 - );
1410 - return true;
1411 - }
1412 -
1413 - // get new diff header items for in-place AJAX page review
1414 - public static function AjaxBuildDiffHeaderItems() {
1415 - $args = func_get_args(); // <oldid, newid>
1416 - if ( count( $args ) >= 2 ) {
1417 - $oldid = (int)$args[0];
1418 - $newid = (int)$args[1];
1419 - $oldRev = Revision::newFromId( $oldid );
1420 - $newRev = Revision::newFromId( $newid );
1421 - if ( $newRev && $newRev->getTitle() ) {
1422 - $fa = FlaggedArticle::getTitleInstance( $newRev->getTitle() );
1423 - return self::diffLinkAndMarkers( $fa, $oldRev, $newRev );
1424 - }
1425 - }
1426 - return '';
1427 - }
1428 -
1429 - /**
1430 - * (a) Add a link to diff from stable to current as needed
1431 - * (b) Show review status of the diff revision(s). Uses a <table>.
1432 - * Note: used by ajax function to rebuild diff page
1433 - */
1434 - public static function diffLinkAndMarkers( FlaggedArticle $article, $oldRev, $newRev ) {
1435 - $s = '<form id="mw-fr-diff-dataform">';
1436 - $s .= Html::hidden( 'oldid', $oldRev ? $oldRev->getId() : 0 );
1437 - $s .= Html::hidden( 'newid', $newRev ? $newRev->getId() : 0 );
1438 - $s .= "</form>\n";
1439 - if ( $newRev ) { // sanity check
1440 - $s .= self::diffToStableLink( $article, $oldRev, $newRev );
1441 - $s .= self::diffReviewMarkers( $article, $oldRev, $newRev );
1442 - }
1443 - return $s;
1444 - }
1445 -
1446 - /**
1447 - * Add a link to diff-to-stable for reviewable pages
1448 - */
1449 - protected static function diffToStableLink(
1450 - FlaggedArticle $article, $oldRev, Revision $newRev
1451 - ) {
1452 - global $wgUser;
1453 - $srev = $article->getStableRev();
1454 - if ( !$srev ) {
1455 - return ''; // nothing to do
1456 - }
1457 - $review = '';
1458 - # Is this already the full diff-to-stable?
1459 - $fullStableDiff = $newRev->isCurrent()
1460 - && self::isDiffToStable( $srev, $oldRev, $newRev );
1461 - # Make a link to the full diff-to-stable if:
1462 - # (a) Actual revs are pending and (b) We are not viewing the full diff-to-stable
1463 - if ( $article->revsArePending() && !$fullStableDiff ) {
1464 - $review = $wgUser->getSkin()->makeKnownLinkObj(
1465 - $article->getTitle(),
1466 - wfMsgHtml( 'review-diff2stable' ),
1467 - 'oldid=' . $srev->getRevId() . '&diff=cur&diffonly=0'
1468 - );
1469 - $review = wfMsgHtml( 'parentheses', $review );
1470 - $review = "<div class='fr-diff-to-stable' align='center'>$review</div>";
1471 - }
1472 - return $review;
1473 - }
1474 -
1475 - /**
1476 - * Add [checked version] and such to left and right side of diff
1477 - */
1478 - protected static function diffReviewMarkers( FlaggedArticle $article, $oldRev, $newRev ) {
1479 - $table = '';
1480 - $srev = $article->getStableRev();
1481 - # Diff between two revisions
1482 - if ( $oldRev && $newRev ) {
1483 - list( $msg, $class ) = self::getDiffRevMsgAndClass( $oldRev, $srev );
1484 - $table .= "<table class='fr-diff-ratings'><tr>";
1485 - $table .= "<td width='50%' align='center'>";
1486 - $table .= "<span class='$class'>[" .
1487 - wfMsgHtml( $msg ) . "]</span>";
1488 -
1489 - list( $msg, $class ) = self::getDiffRevMsgAndClass( $newRev, $srev );
1490 - $table .= "</td><td width='50%' align='center'>";
1491 - $table .= "<span class='$class'>[" .
1492 - wfMsgHtml( $msg ) . "]</span>";
1493 -
1494 - $table .= "</td></tr></table>\n";
1495 - # New page "diffs" - just one rev
1496 - } elseif ( $newRev ) {
1497 - list( $msg, $class ) = self::getDiffRevMsgAndClass( $newRev, $srev );
1498 - $table .= "<table class='fr-diff-ratings'>";
1499 - $table .= "<tr><td align='center'><span class='$class'>";
1500 - $table .= '[' . wfMsgHtml( $msg ) . ']';
1501 - $table .= "</span></td></tr></table>\n";
1502 - }
1503 - return $table;
1504 - }
1505 -
1506 - protected static function getDiffRevMsgAndClass(
1507 - Revision $rev, FlaggedRevision $srev = null
1508 - ) {
1509 - $tier = FlaggedRevs::getRevQuality( $rev->getPage(), $rev->getId() );
1510 - if ( $tier !== false ) {
1511 - $msg = $tier
1512 - ? 'revreview-hist-quality'
1513 - : 'revreview-hist-basic';
1514 - } else {
1515 - $msg = ( $srev && $rev->getTimestamp() > $srev->getRevTimestamp() ) // bug 15515
1516 - ? 'revreview-hist-pending'
1517 - : 'revreview-hist-draft';
1518 - }
1519 - $css = FlaggedRevsXML::getQualityColor( $tier );
1520 - return array( $msg, $css );
1521 - }
1522 -
1523 - // Fetch template changes for a reviewed revision since review
1524 - // @returns array
1525 - protected static function fetchTemplateChanges( FlaggedRevision $frev ) {
1526 - global $wgUser;
1527 - $skin = $wgUser->getSkin();
1528 - $diffLinks = array();
1529 - $changes = $frev->findPendingTemplateChanges();
1530 - foreach ( $changes as $tuple ) {
1531 - list( $title, $revIdStable ) = $tuple;
1532 - $diffLinks[] = $skin->makeLinkObj( $title,
1533 - $title->getPrefixedText(),
1534 - 'diff=cur&oldid=' . (int)$revIdStable );
1535 - }
1536 - return $diffLinks;
1537 - }
1538 -
1539 - // Fetch file changes for a reviewed revision since review
1540 - // @returns array
1541 - protected static function fetchFileChanges( FlaggedRevision $frev ) {
1542 - global $wgUser;
1543 - $skin = $wgUser->getSkin();
1544 - $diffLinks = array();
1545 - $changes = $frev->findPendingFileChanges( 'noForeign' );
1546 - foreach ( $changes as $tuple ) {
1547 - list( $title, $revIdStable ) = $tuple;
1548 - // @TODO: change when MW has file diffs
1549 - $diffLinks[] = $skin->makeLinkObj( $title, $title->getPrefixedText() );
1550 - }
1551 - return $diffLinks;
1552 - }
1553 -
1554 - /**
1555 - * Set $this->isDiffFromStable and $this->isMultiPageDiff fields
1556 - * Note: $oldRev could be false
1557 - */
1558 - public function setViewFlags( $diff, $oldRev, $newRev ) {
1559 - $this->load();
1560 - // We only want valid diffs that actually make sense...
1561 - if ( $newRev && $oldRev && $newRev->getTimestamp() >= $oldRev->getTimestamp() ) {
1562 - // Is this a diff between two pages?
1563 - if ( $newRev->getPage() != $oldRev->getPage() ) {
1564 - $this->isMultiPageDiff = true;
1565 - // Is there a stable version?
1566 - } elseif ( $this->article->isReviewable() ) {
1567 - $srev = $this->article->getStableRev();
1568 - // Is this a diff of a draft rev against the stable rev?
1569 - if ( self::isDiffToStable( $srev, $oldRev, $newRev ) ) {
1570 - $this->isDiffFromStable = true;
1571 - $this->isReviewableDiff = true;
1572 - // Is this a diff of a draft rev against a reviewed rev?
1573 - } elseif (
1574 - FlaggedRevision::newFromTitle( $diff->getTitle(), $oldRev->getId() ) ||
1575 - FlaggedRevision::newFromTitle( $diff->getTitle(), $newRev->getId() )
1576 - ) {
1577 - $this->isReviewableDiff = true;
1578 - }
1579 - }
1580 - $this->diffRevs = array( 'old' => $oldRev, 'new' => $newRev );
1581 - }
1582 - return true;
1583 - }
1584 -
1585 - // Is a diff from $oldRev to $newRev a diff-to-stable?
1586 - protected static function isDiffToStable( $srev, $oldRev, $newRev ) {
1587 - return ( $srev && $oldRev && $newRev
1588 - && $oldRev->getPage() == $newRev->getPage() // no multipage diffs
1589 - && $oldRev->getId() == $srev->getRevId()
1590 - && $newRev->getTimestamp() >= $oldRev->getTimestamp() // no backwards diffs
1591 - );
1592 - }
1593 -
1594 - /**
1595 - * Redirect users out to review the changes to the stable version.
1596 - * Only for people who can review and for pages that have a stable version.
1597 - */
1598 - public function injectPostEditURLParams( &$sectionAnchor, &$extraQuery ) {
1599 - global $wgUser;
1600 - $this->load();
1601 - $this->article->loadFromDB( FR_MASTER );
1602 - # Get the stable version from the master
1603 - $frev = $this->article->getStableRev();
1604 - if ( !$frev || !$this->article->revsArePending() ) {
1605 - return true; // only for pages with pending edits
1606 - }
1607 - // If the edit was not autoreviewed, and the user can actually make a
1608 - // new stable version, then go to the diff...
1609 - if ( $frev->userCanSetFlags( $wgUser ) ) {
1610 - $extraQuery .= $extraQuery ? '&' : '';
1611 - // Override diffonly setting to make sure the content is shown
1612 - $extraQuery .= 'oldid=' . $frev->getRevId() . '&diff=cur&diffonly=0&shownotice=1';
1613 - // ...otherwise, go to the draft revision after completing an edit.
1614 - // This allows for users to immediately see their changes.
1615 - } else {
1616 - $extraQuery .= $extraQuery ? '&' : '';
1617 - $extraQuery .= 'stable=0';
1618 - // Show a notice at the top of the page for non-reviewers...
1619 - if ( !$wgUser->isAllowed( 'review' ) && $this->article->isStableShownByDefault() ) {
1620 - $extraQuery .= '&shownotice=1';
1621 - if ( $sectionAnchor ) {
1622 - // Pass a section parameter in the URL as needed to add a link to
1623 - // the "your changes are pending" box on the top of the page...
1624 - $section = str_replace(
1625 - array( ':' , '.' ), array( '%3A', '%' ), // hack: reverse encoding
1626 - substr( $sectionAnchor, 1 ) // remove the '#'
1627 - );
1628 - $extraQuery .= '&fromsection=' . $section;
1629 - $sectionAnchor = ''; // go to the top of the page to see notice
1630 - }
1631 - }
1632 - }
1633 - return true;
1634 - }
1635 -
1636 - /**
1637 - * If submitting the edit will leave it pending, then change the button text
1638 - * Note: interacts with 'review pending changes' checkbox
1639 - * @TODO: would be nice if hook passed in button attribs, not XML
1640 - */
1641 - public function changeSaveButton( EditPage $editPage, array &$buttons ) {
1642 - if ( !$this->editWillRequireReview( $editPage ) ) {
1643 - return true; // edit will go live or be reviewed on save
1644 - }
1645 - if ( extension_loaded( 'domxml' ) ) {
1646 - wfDebug( "Warning: you have the obsolete domxml extension for PHP. Please remove it!\n" );
1647 - return true; # PECL extension conflicts with the core DOM extension (see bug 13770)
1648 - } elseif ( isset( $buttons['save'] ) && extension_loaded( 'dom' ) ) {
1649 - $dom = new DOMDocument();
1650 - $dom->loadXML( $buttons['save'] ); // load button XML from hook
1651 - foreach ( $dom->getElementsByTagName( 'input' ) as $input ) { // one <input>
1652 - $input->setAttribute( 'value', wfMsg( 'revreview-submitedit' ) );
1653 - $input->setAttribute( 'title', // keep accesskey
1654 - wfMsgExt( 'revreview-submitedit-title', 'parsemag' ) .
1655 - ' [' . wfMsg( 'accesskey-save' ) . ']' );
1656 - # Change submit button text & title
1657 - $buttons['save'] = $dom->saveXML( $dom->documentElement );
1658 - }
1659 - }
1660 - return true;
1661 - }
1662 -
1663 - /**
1664 - * If this edit will not go live on submit (accounting for wpReviewEdit)
1665 - * @param EditPage $editPage
1666 - * @return bool
1667 - */
1668 - protected function editWillRequireReview( EditPage $editPage ) {
1669 - global $wgRequest;
1670 - $title = $this->article->getTitle(); // convenience
1671 - if ( !$this->editRequiresReview( $editPage ) ) {
1672 - return false; // edit will go live immediatly
1673 - } elseif ( $wgRequest->getCheck( 'wpReviewEdit' ) && $title->userCan( 'review' ) ) {
1674 - return false; // edit checked off to be reviewed on save
1675 - }
1676 - return true; // edit needs review
1677 - }
1678 -
1679 - /**
1680 - * If this edit will not go live on submit unless wpReviewEdit is checked
1681 - * @param EditPage $editPage
1682 - * @return bool
1683 - */
1684 - protected function editRequiresReview( EditPage $editPage ) {
1685 - if ( !$this->article->editsRequireReview() ) {
1686 - return false; // edits go live immediatly
1687 - } elseif ( $this->editWillBeAutoreviewed( $editPage ) ) {
1688 - return false; // edit will be autoreviewed anyway
1689 - }
1690 - return true; // edit needs review
1691 - }
1692 -
1693 - /**
1694 - * If this edit will be auto-reviewed on submit
1695 - * Note: checking wpReviewEdit does not count as auto-reviewed
1696 - * @param EditPage $editPage
1697 - * @return bool
1698 - */
1699 - protected function editWillBeAutoreviewed( EditPage $editPage ) {
1700 - $title = $this->article->getTitle(); // convenience
1701 - if ( !$this->article->isReviewable() ) {
1702 - return false;
1703 - }
1704 - if ( $title->userCan( 'autoreview' ) ) {
1705 - if ( FlaggedRevs::autoReviewNewPages() && !$this->article->exists() ) {
1706 - return true; // edit will be autoreviewed
1707 - }
1708 - if ( !isset( $editPage->fr_baseFRev ) ) {
1709 - $baseRevId = self::getBaseRevId( $editPage );
1710 - $editPage->fr_baseFRev = FlaggedRevision::newFromTitle( $title, $baseRevId );
1711 - }
1712 - if ( $editPage->fr_baseFRev ) {
1713 - return true; // edit will be autoreviewed
1714 - }
1715 - }
1716 - return false; // edit won't be autoreviewed
1717 - }
1718 -
1719 - /**
1720 - * Add a "review pending changes" checkbox to the edit form iff:
1721 - * (a) there are currently any revisions pending (bug 16713)
1722 - * (b) this is an unreviewed page (bug 23970)
1723 - */
1724 - public function addReviewCheck( EditPage $editPage, array &$checkboxes, &$tabindex ) {
1725 - global $wgRequest;
1726 - $title = $this->article->getTitle(); // convenience
1727 - if ( !$this->article->isReviewable() || !$title->userCan( 'review' ) ) {
1728 - return true; // not needed
1729 - } elseif ( $this->editWillBeAutoreviewed( $editPage ) ) {
1730 - return true; // edit will be auto-reviewed
1731 - }
1732 - if ( self::getBaseRevId( $editPage ) == $this->article->getLatest() ) {
1733 - # For pages with either no stable version, or an outdated one, let
1734 - # the user decide if he/she wants it reviewed on the spot. One might
1735 - # do this if he/she just saw the diff-to-stable and *then* decided to edit.
1736 - # Note: check not shown when editing old revisions, which is confusing.
1737 - $checkbox = Xml::check(
1738 - 'wpReviewEdit',
1739 - $wgRequest->getCheck( 'wpReviewEdit' ),
1740 - array( 'tabindex' => ++$tabindex, 'id' => 'wpReviewEdit' )
1741 - );
1742 - $attribs = array( 'for' => 'wpReviewEdit' );
1743 - // For reviewed pages...
1744 - if ( $this->article->getStable() ) {
1745 - // For pending changes...
1746 - if ( $this->article->revsArePending() ) {
1747 - $n = $this->article->getPendingRevCount();
1748 - $attribs['title'] = wfMsg( 'revreview-check-flag-p-title' );
1749 - $labelMsg = wfMsgExt( 'revreview-check-flag-p', 'parseinline', $n );
1750 - // For just the user's changes...
1751 - } else {
1752 - $attribs['title'] = wfMsgExt( 'revreview-check-flag-y-title', 'parsemag' );
1753 - $labelMsg = wfMsgExt( 'revreview-check-flag-y', 'parseinline' );
1754 - }
1755 - // For unreviewed pages...
1756 - } else {
1757 - $attribs['title'] = wfMsg( 'revreview-check-flag-u-title' );
1758 - $labelMsg = wfMsgExt( 'revreview-check-flag-u', 'parseinline' );
1759 - }
1760 - $label = Xml::element( 'label', $attribs, $labelMsg );
1761 - $checkboxes['reviewed'] = $checkbox . '&#160;' . $label;
1762 - }
1763 - return true;
1764 - }
1765 -
1766 - /**
1767 - * (a) Add a hidden field that has the rev ID the text is based off.
1768 - * (b) If an edit was undone, add a hidden field that has the rev ID of that edit.
1769 - * Needed for autoreview and user stats (for autopromote).
1770 - * Note: baseRevId trusted for Reviewers - text checked for others.
1771 - */
1772 - public function addRevisionIDField( EditPage $editPage, OutputPage $out ) {
1773 - $this->load();
1774 - $revId = self::getBaseRevId( $editPage );
1775 - $out->addHTML( "\n" . Html::hidden( 'baseRevId', $revId ) );
1776 - $out->addHTML( "\n" . Html::hidden( 'undidRev',
1777 - empty( $editPage->undidRev ) ? 0 : $editPage->undidRev )
1778 - );
1779 - return true;
1780 - }
1781 -
1782 - /**
1783 - * Guess the rev ID the text of this form is based off
1784 - * Note: baseRevId trusted for Reviewers - check text for others.
1785 - * @return int
1786 - */
1787 - protected static function getBaseRevId( EditPage $editPage ) {
1788 - global $wgRequest;
1789 - if ( !isset( $editPage->fr_baseRevId ) ) {
1790 - $article = $editPage->getArticle(); // convenience
1791 - $latestId = $article->getLatest(); // current rev
1792 - $undo = $wgRequest->getIntOrNull( 'undo' );
1793 - # Undoing consecutive top edits...
1794 - if ( $undo && $undo === $latestId ) {
1795 - # Treat this like a revert to a base revision.
1796 - # We are undoing all edits *after* some rev ID (undoafter).
1797 - # If undoafter is not given, then it is the previous rev ID.
1798 - $revId = $wgRequest->getInt( 'undoafter',
1799 - $article->getTitle()->getPreviousRevisionID( $latestId, Title::GAID_FOR_UPDATE ) );
1800 - # Undoing other edits...
1801 - } elseif ( $undo ) {
1802 - $revId = $latestId; // current rev is the base rev
1803 - # Other edits...
1804 - } else {
1805 - # If we are editing via oldid=X, then use that rev ID.
1806 - # Otherwise, check if the client specified the ID (bug 23098).
1807 - $revId = $article->getOldID()
1808 - ? $article->getOldID()
1809 - : $wgRequest->getInt( 'baseRevId' ); // e.g. "show changes"/"preview"
1810 - }
1811 - # Zero oldid => draft revision
1812 - if ( !$revId ) {
1813 - $revId = $latestId;
1814 - }
1815 - $editPage->fr_baseRevId = $revId;
1816 - }
1817 - return $editPage->fr_baseRevId;
1818 - }
1819 -
1820 - /**
1821 - * Adds brief review notes to a page.
1822 - * @param OutputPage $out
1823 - */
1824 - public function addReviewNotes( &$data ) {
1825 - $this->load();
1826 - if ( $this->reviewNotes ) {
1827 - $data .= $this->reviewNotes;
1828 - }
1829 - return true;
1830 - }
1831 -
1832 - /*
1833 - * If this is a diff page then replace the article contents with a link
1834 - * to the specific revision. This will be replaced with article content
1835 - * using javascript and an api call.
1836 - */
1837 - public function addCustomContentHtml( OutputPage $out, $newRevId ) {
1838 - $this->load();
1839 - if ( $newRevId ) {
1840 - $out->addHTML( "<div id='mw-fr-revisioncontents'><span class='plainlinks'>" );
1841 - $out->addWikiMsg( 'revcontents-getcontents',
1842 - $this->article->getTitle()->getPrefixedDBKey(), $newRevId );
1843 - $out->addHTML( "</span></div>" );
1844 - }
1845 - }
1846 -}
Index: trunk/extensions/FlaggedRevs/presentation/RevisionReviewFormGUI.php
@@ -13,10 +13,10 @@
1414 /**
1515 * Generates a brief review form for a page
1616 * @param User $user
17 - * @param FlaggedArticle $article
 17+ * @param FlaggedPage $article
1818 * @param Revision $rev
1919 */
20 - public function __construct( User $user, FlaggedArticle $article, Revision $rev ) {
 20+ public function __construct( User $user, FlaggedPage $article, Revision $rev ) {
2121 $this->user = $user;
2222 $this->article = $article;
2323 $this->rev = $rev;
@@ -51,7 +51,7 @@
5252
5353 /**
5454 * Generates a brief review form for a page
55 - * @return Array (html string, error string or true)
 55+ * @return array (html string, error string or true)
5656 */
5757 public function getHtml() {
5858 global $wgOut, $wgLang, $wgParser, $wgEnableParserCache;
@@ -220,7 +220,7 @@
221221 * @param array $flags, selected flags
222222 * @param bool $disabled, form disabled
223223 * @param bool $reviewed, rev already reviewed
224 - * @returns string
 224+ * @return string
225225 * Generates a main tag inputs (checkboxes/radios/selects) for review form
226226 */
227227 protected static function ratingInputs( $user, $flags, $disabled, $reviewed ) {
@@ -328,7 +328,7 @@
329329 * @param FlaggedRevision $frev, the flagged revision, if any
330330 * @param bool $disabled, is the form disabled?
331331 * @param bool $reviewIncludes, force the review button to be usable?
332 - * @returns string
 332+ * @return string
333333 */
334334 protected static function submitButtons(
335335 $rejectId, $frev, $disabled, $reviewIncludes = false
Index: trunk/extensions/FlaggedRevs/presentation/FlaggedRevsXML.php
@@ -8,7 +8,7 @@
99 * Get a selector of reviewable namespaces
1010 * @param int $selected, namespace selected
1111 * @param $all Mixed: Value of an item denoting all namespaces, or null to omit
12 - * @returns string
 12+ * @return string
1313 */
1414 public static function getNamespaceMenu( $selected = null, $all = null ) {
1515 global $wgContLang;
@@ -50,7 +50,7 @@
5151 * @param int $selected, selected level
5252 * @param string $all, all selector msg?
5353 * @param int $max max level?
54 - * @returns string
 54+ * @return string
5555 */
5656 public static function getLevelMenu(
5757 $selected = null, $all = 'revreview-filter-all', $max = 2
@@ -72,7 +72,7 @@
7373 /**
7474 * Get a <select> of default page version (stable or draft). Used for filters.
7575 * @param int $selected (0=draft, 1=stable, null=either )
76 - * @returns string
 76+ * @return string
7777 */
7878 public static function getDefaultFilterMenu( $selected = null ) {
7979 if ( is_null( $selected ) ) {
@@ -91,7 +91,7 @@
9292 /**
9393 * Get a <select> of options of 'autoreview' restriction levels. Used for filters.
9494 * @param string $selected ('' for "any", 'none' for none)
95 - * @returns string
 95+ * @return string
9696 */
9797 public static function getRestrictionFilterMenu( $selected = '' ) {
9898 if ( is_null( $selected ) ) {
@@ -121,7 +121,7 @@
122122 /**
123123 * Get a selector of "approved"/"unapproved". Used for filters.
124124 * @param int $selected, selected level
125 - * @returns string
 125+ * @return string
126126 */
127127 public static function getStatusFilterMenu( $selected = null ) {
128128 $s = "<label for='wpStatus'>" . wfMsgHtml( 'revreview-statusfilter' ) . "</label>\n";
@@ -137,7 +137,7 @@
138138 /**
139139 * Get a selector of "auto"/"manual". Used for filters.
140140 * @param int $selected, selected level
141 - * @returns string
 141+ * @return string
142142 */
143143 public static function getAutoFilterMenu( $selected = null ) {
144144 $s = "<label for='wpApproved'>" . wfMsgHtml( 'revreview-typefilter' ) . "</label>\n";
@@ -151,7 +151,7 @@
152152
153153 /**
154154 * @param int $quality
155 - * @returns string, css color for this quality
 155+ * @return string, css color for this quality
156156 */
157157 public static function getQualityColor( $quality ) {
158158 if ( $quality === false )
@@ -174,7 +174,7 @@
175175 * @param array $flags
176176 * @param bool $prettybox
177177 * @param string $css, class to wrap box in
178 - * @returns string
 178+ * @return string
179179 * Generates a review box/tag
180180 */
181181 public static function addTagRatings( $flags, $prettyBox = false, $css = '' ) {
@@ -213,7 +213,7 @@
214214 * @param string $type (stable/draft/oldstable)
215215 * @param bool $stable, are we referring to the stable revision?
216216 * @param bool $synced, does stable=current and this is one of them?
217 - * @returns string
 217+ * @return string
218218 * Generates a review box using a table using FlaggedRevsXML::addTagRatings()
219219 */
220220 public static function prettyRatingBox(
@@ -284,7 +284,7 @@
285285
286286 /**
287287 * Generates JS toggle arrow icon
288 - * @returns string
 288+ * @return string
289289 */
290290 public static function ratingArrow() {
291291 $encPath = htmlspecialchars( FlaggedRevs::styleUrlPath() . '/img' );
@@ -297,7 +297,7 @@
298298
299299 /**
300300 * Generates (+/-) JS toggle HTML (monospace to keep things in place)
301 - * @returns string
 301+ * @return string
302302 */
303303 public static function ratingToggle() {
304304 return '<a id="mw-fr-revisiontoggle" class="fr-toggle-symbol"' .
@@ -308,7 +308,7 @@
309309
310310 /**
311311 * Generates (show/hide) JS toggle HTML
312 - * @returns string
 312+ * @return string
313313 */
314314 public static function diffToggle() {
315315 $toggle = '<a class="fr-toggle-text" ' .
@@ -321,7 +321,7 @@
322322
323323 /**
324324 * Generates (show/hide) JS toggle HTML
325 - * @returns string
 325+ * @return string
326326 */
327327 public static function logToggle() {
328328 $toggle = '<a class="fr-toggle-text" ' .
@@ -334,7 +334,7 @@
335335
336336 /**
337337 * Generates (show/hide) JS toggle HTML
338 - * @returns string
 338+ * @return string
339339 */
340340 public static function logDetailsToggle() {
341341 $toggle = '<a class="fr-toggle-text" ' .
@@ -347,7 +347,7 @@
348348
349349 /*
350350 * Creates CSS draft page icon
351 - * @returns string
 351+ * @return string
352352 */
353353 public static function draftStatusIcon() {
354354 $encPath = htmlspecialchars( FlaggedRevs::styleUrlPath() . '/img' );
@@ -359,7 +359,7 @@
360360 /*
361361 * Creates CSS stable page icon
362362 * @param bool $isQuality
363 - * @returns string
 363+ * @return string
364364 */
365365 public static function stableStatusIcon( $isQuality ) {
366366 $encPath = htmlspecialchars( FlaggedRevs::styleUrlPath() . '/img' );
@@ -373,8 +373,8 @@
374374
375375 /*
376376 * Creates CSS lock icon if page is locked/unlocked
377 - * @param FlaggedArticle $flaggedArticle
378 - * @returns string
 377+ * @param FlaggedPage $flaggedArticle
 378+ * @return string
379379 */
380380 public static function lockStatusIcon( $flaggedArticle ) {
381381 $encPath = htmlspecialchars( FlaggedRevs::styleUrlPath() . '/img' );
@@ -390,10 +390,10 @@
391391 }
392392
393393 /*
394 - * @param FlaggedArticle $flaggedArticle
 394+ * @param FlaggedPage $flaggedArticle
395395 * @param FlaggedRevision $frev
396396 * @param int $revsSince
397 - * @returns string
 397+ * @return string
398398 * Creates "stable rev reviewed on"/"x pending edits" message
399399 */
400400 public static function pendingEditNotice( $flaggedArticle, $frev, $revsSince ) {
@@ -410,7 +410,7 @@
411411
412412 /*
413413 * @param Article $article
414 - * @returns string
 414+ * @return string
415415 * Creates a stability log excerpt
416416 */
417417 public static function stabilityLogExcerpt( $article ) {
Index: trunk/extensions/FlaggedRevs/presentation/specialpages/reports/QualityOversight_body.php
@@ -86,7 +86,7 @@
8787
8888 /*
8989 * Get actions for IN clause
90 - * @returns array
 90+ * @return array
9191 */
9292 private function getActions() {
9393 $actions = array(
Index: trunk/extensions/FlaggedRevs/presentation/RejectConfirmationFormGUI.php
@@ -13,7 +13,7 @@
1414
1515 /**
1616 * Get the "are you sure you want to reject these changes?" form
17 - * @return Array (html string, error string or true)
 17+ * @return array (html string, error string or true)
1818 */
1919 public function getHtml() {
2020 global $wgLang, $wgContLang;
Index: trunk/extensions/FlaggedRevs/presentation/FlaggedPageView.php
@@ -0,0 +1,1845 @@
 2+<?php
 3+/**
 4+ * Class representing a web view of a MediaWiki page
 5+ */
 6+class FlaggedPageView {
 7+ protected $article = null;
 8+
 9+ protected $diffRevs = null; // assoc array of old and new Revisions for diffs
 10+ protected $isReviewableDiff = false;
 11+ protected $isDiffFromStable = false;
 12+ protected $isMultiPageDiff = false;
 13+ protected $reviewNotice = '';
 14+ protected $reviewNotes = '';
 15+ protected $diffNoticeBox = '';
 16+ protected $reviewFormRev = false;
 17+
 18+ protected $loaded = false;
 19+
 20+ protected static $instance = null;
 21+
 22+ /*
 23+ * Get the FlaggedPageView for this request
 24+ */
 25+ public static function singleton() {
 26+ if ( self::$instance == null ) {
 27+ self::$instance = new self();
 28+ }
 29+ return self::$instance;
 30+ }
 31+ protected function __construct() { }
 32+ protected function __clone() { }
 33+
 34+ /*
 35+ * Clear the FlaggedPageView for this request.
 36+ * Only needed when page redirection changes the environment.
 37+ */
 38+ public function clear() {
 39+ self::$instance = null;
 40+ }
 41+
 42+ /*
 43+ * Load the global FlaggedPage instance
 44+ */
 45+ protected function load() {
 46+ if ( !$this->loaded ) {
 47+ $this->loaded = true;
 48+ $this->article = self::globalArticleInstance();
 49+ if ( $this->article == null ) {
 50+ throw new MWException( 'FlaggedPageView has no context article!' );
 51+ }
 52+ }
 53+ }
 54+
 55+ /**
 56+ * Get the FlaggedPage instance associated with $wgArticle/$wgTitle,
 57+ * or false if there isn't such a title
 58+ */
 59+ public static function globalArticleInstance() {
 60+ global $wgTitle;
 61+ if ( !empty( $wgTitle ) ) {
 62+ return FlaggedPage::getTitleInstance( $wgTitle );
 63+ }
 64+ return null;
 65+ }
 66+
 67+ /**
 68+ * Is this web response for a request to view a page where both:
 69+ * (a) no specific page version was requested via URL params
 70+ * (b) a stable version exists and is to be displayed
 71+ * This factors in site/page config, user preferences, and web request params.
 72+ * @return bool
 73+ */
 74+ protected function showingStableAsDefault() {
 75+ global $wgUser, $wgRequest;
 76+ $this->load();
 77+ # This only applies to viewing the default version of pages...
 78+ if ( !$this->isDefaultPageView( $wgRequest ) ) {
 79+ return false;
 80+ # ...and the page must be reviewable and have a stable version
 81+ } elseif ( !$this->article->getStableRev() ) {
 82+ return false;
 83+ }
 84+ # Check user preferences ("show stable by default?")
 85+ if ( $wgUser->getOption( 'flaggedrevsstable' ) ) {
 86+ return true;
 87+ }
 88+ # Viewer may be in a group that sees the draft by default
 89+ if ( $this->userViewsDraftByDefault( $wgUser ) ) {
 90+ return false;
 91+ }
 92+ # Does the stable version override the draft?
 93+ $config = $this->article->getStabilitySettings();
 94+ return (bool)$config['override'];
 95+ }
 96+
 97+ /**
 98+ * Is this web response for a request to view a page where both:
 99+ * (a) the stable version of a page was requested (?stable=1)
 100+ * (b) the stable version exists and is to be displayed
 101+ * @return bool
 102+ */
 103+ protected function showingStableByRequest() {
 104+ global $wgRequest;
 105+ $this->load();
 106+ # Are we explicity requesting the stable version?
 107+ if ( $wgRequest->getIntOrNull( 'stable' ) === 1 ) {
 108+ # This only applies to viewing a version of the page...
 109+ if ( !$this->isPageView( $wgRequest ) ) {
 110+ return false;
 111+ # ...with no version parameters other than ?stable=1...
 112+ } elseif ( $wgRequest->getVal( 'oldid' ) || $wgRequest->getVal( 'stableid' ) ) {
 113+ return false; // over-determined
 114+ # ...and the page must be reviewable and have a stable version
 115+ } elseif ( !$this->article->getStableRev() ) {
 116+ return false;
 117+ }
 118+ return true; // show stable version
 119+ }
 120+ return false;
 121+ }
 122+
 123+ /**
 124+ * Is this web response for a request to view a page
 125+ * where a stable version exists and is to be displayed
 126+ * @return bool
 127+ */
 128+ public function showingStable() {
 129+ return $this->showingStableByRequest() || $this->showingStableAsDefault();
 130+ }
 131+
 132+ /**
 133+ * Should this be using a simple icon-based UI?
 134+ * Check the user's preferences first, using the site settings as the default.
 135+ * @return bool
 136+ */
 137+ public function useSimpleUI() {
 138+ global $wgUser, $wgSimpleFlaggedRevsUI;
 139+ return $wgUser->getOption( 'flaggedrevssimpleui', intval( $wgSimpleFlaggedRevsUI ) );
 140+ }
 141+
 142+ /**
 143+ * Should this user see the draft revision of pages by default?
 144+ * @param $user User
 145+ * @return bool
 146+ */
 147+ protected function userViewsDraftByDefault( $user ) {
 148+ global $wgFlaggedRevsExceptions;
 149+ # Check user preferences ("show stable by default?")
 150+ if ( $user->getOption( 'flaggedrevsstable' ) ) {
 151+ return false;
 152+ }
 153+ # Viewer sees current by default (editors, insiders, ect...) ?
 154+ foreach ( $wgFlaggedRevsExceptions as $group ) {
 155+ if ( $group == 'user' ) {
 156+ if ( $user->getId() ) {
 157+ return true;
 158+ }
 159+ } elseif ( in_array( $group, $user->getGroups() ) ) {
 160+ return true;
 161+ }
 162+ }
 163+ return false;
 164+ }
 165+
 166+ /**
 167+ * Is this a view page action (including diffs)?
 168+ * @param $request WebRequest
 169+ * @return bool
 170+ */
 171+ protected function isPageViewOrDiff( WebRequest $request ) {
 172+ global $mediaWiki;
 173+ $action = isset( $mediaWiki )
 174+ ? $mediaWiki->getAction( $request )
 175+ : $request->getVal( 'action', 'view' ); // cli
 176+ return self::isViewAction( $action );
 177+ }
 178+
 179+ /**
 180+ * Is this a view page action (not including diffs)?
 181+ * @param $request WebRequest
 182+ * @return bool
 183+ */
 184+ protected function isPageView( WebRequest $request ) {
 185+ return $this->isPageViewOrDiff( $request )
 186+ && $request->getVal( 'diff' ) === null;
 187+ }
 188+
 189+ /**
 190+ * Is this a web request to just *view* the *default* version of a page?
 191+ * @param $request WebRequest
 192+ * @return bool
 193+ */
 194+ protected function isDefaultPageView( WebRequest $request ) {
 195+ global $mediaWiki;
 196+ $action = isset( $mediaWiki )
 197+ ? $mediaWiki->getAction( $request )
 198+ : $request->getVal( 'action', 'view' ); // cli
 199+ return ( self::isViewAction( $action )
 200+ && $request->getVal( 'oldid' ) === null
 201+ && $request->getVal( 'stable' ) === null
 202+ && $request->getVal( 'stableid' ) === null
 203+ && $request->getVal( 'diff' ) === null
 204+ );
 205+ }
 206+
 207+ /**
 208+ * Is this a view page action?
 209+ * @param $action string from MediaWiki::getAction()
 210+ * @return bool
 211+ */
 212+ protected static function isViewAction( $action ) {
 213+ return ( $action == 'view' || $action == 'purge' || $action == 'render' );
 214+ }
 215+
 216+ /**
 217+ * Output review notice
 218+ */
 219+ public function displayTag() {
 220+ global $wgOut;
 221+ $this->load();
 222+ // Sanity check that this is a reviewable page
 223+ if ( $this->article->isReviewable() ) {
 224+ $wgOut->appendSubtitle( $this->reviewNotice );
 225+ }
 226+ return true;
 227+ }
 228+
 229+ /**
 230+ * Add a stable link when viewing old versions of an article that
 231+ * have been reviewed. (e.g. for &oldid=x urls)
 232+ */
 233+ public function addStableLink() {
 234+ global $wgRequest, $wgOut, $wgLang;
 235+ $this->load();
 236+ if ( !$this->article->isReviewable() || !$wgRequest->getVal( 'oldid' ) ) {
 237+ return true;
 238+ }
 239+ # We may have nav links like "direction=prev&oldid=x"
 240+ $revID = $this->article->getOldIDFromRequest();
 241+ $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $revID );
 242+ # Give a notice if this rev ID corresponds to a reviewed version...
 243+ if ( $frev ) {
 244+ $time = $wgLang->date( $frev->getTimestamp(), true );
 245+ $flags = $frev->getTags();
 246+ $quality = FlaggedRevs::isQuality( $flags );
 247+ $msg = $quality ? 'revreview-quality-source' : 'revreview-basic-source';
 248+ $tag = wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $time );
 249+ # Hide clutter
 250+ if ( !$this->useSimpleUI() && !empty( $flags ) ) {
 251+ $tag .= FlaggedRevsXML::ratingToggle() .
 252+ "<div id='mw-fr-revisiondetails' style='display:block;'>" .
 253+ wfMsgHtml( 'revreview-oldrating' ) .
 254+ FlaggedRevsXML::addTagRatings( $flags ) . '</div>';
 255+ }
 256+ $css = 'flaggedrevs_notice plainlinks noprint';
 257+ $tag = "<div id='mw-fr-revisiontag-old' class='$css'>$tag</div>";
 258+ $wgOut->addHTML( $tag );
 259+ }
 260+ return true;
 261+ }
 262+
 263+ /**
 264+ * @return mixed int/false/null
 265+ */
 266+ protected function getRequestedStableId() {
 267+ global $wgRequest;
 268+ $reqId = $wgRequest->getVal( 'stableid' );
 269+ if ( $reqId === "best" ) {
 270+ $reqId = FlaggedRevs::getPrimeFlaggedRevId( $this->article );
 271+ }
 272+ return $reqId;
 273+ }
 274+
 275+ /**
 276+ * Replaces a page with the last stable version if possible
 277+ * Adds stable version status/info tags and notes
 278+ * Adds a quick review form on the bottom if needed
 279+ */
 280+ public function setPageContent( &$outputDone, &$useParserCache ) {
 281+ global $wgRequest, $wgOut, $wgContLang;
 282+ $this->load();
 283+ # Only trigger on page views with no oldid=x param
 284+ if ( !$this->isPageView( $wgRequest ) || $wgRequest->getVal( 'oldid' ) ) {
 285+ return true;
 286+ # Only trigger for reviewable pages that exist
 287+ } elseif ( !$this->article->exists() || !$this->article->isReviewable() ) {
 288+ return true;
 289+ }
 290+ $tag = '';
 291+ $old = $stable = false;
 292+ # Check the newest stable version.
 293+ $srev = $this->article->getStableRev();
 294+ $stableId = $srev ? $srev->getRevId() : 0;
 295+ $frev = $srev; // $frev is the revision we are looking at
 296+ # Check for any explicitly requested reviewed version (stableid=X)...
 297+ $reqId = $this->getRequestedStableId();
 298+ if ( $reqId ) {
 299+ if ( !$stableId ) {
 300+ $reqId = false; // must be invalid
 301+ # Treat requesting the stable version by ID as &stable=1
 302+ } else if ( $reqId != $stableId ) {
 303+ $old = true; // old reviewed version requested by ID
 304+ $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId );
 305+ if ( !$frev ) {
 306+ $reqId = false; // invalid ID given
 307+ }
 308+ } else {
 309+ $stable = true; // stable version requested by ID
 310+ }
 311+ }
 312+ // $reqId is null if nothing requested, false if invalid
 313+ if ( $reqId === false ) {
 314+ $wgOut->addWikiText( wfMsg( 'revreview-invalid' ) );
 315+ $wgOut->returnToMain( false, $this->article->getTitle() );
 316+ # Tell MW that parser output is done
 317+ $outputDone = true;
 318+ $useParserCache = false;
 319+ return true;
 320+ }
 321+ // Is the page config altered?
 322+ $prot = FlaggedRevsXML::lockStatusIcon( $this->article );
 323+ // Is there no stable version?
 324+ if ( !$frev ) {
 325+ # Add "no reviewed version" tag, but not for printable output
 326+ $this->showUnreviewedPage( $tag, $prot );
 327+ return true;
 328+ }
 329+ # Get flags and date
 330+ $flags = $frev->getTags();
 331+ # Get quality level
 332+ $quality = FlaggedRevs::isQuality( $flags );
 333+ $pristine = FlaggedRevs::isPristine( $flags );
 334+ // Looking at some specific old stable revision ("&stableid=x")
 335+ // set to override given the relevant conditions. If the user is
 336+ // requesting the stable revision ("&stableid=x"), defer to override
 337+ // behavior below, since it is the same as ("&stable=1").
 338+ if ( $old ) {
 339+ $this->showOldReviewedVersion( $srev, $frev, $tag, $prot );
 340+ $outputDone = true; # Tell MW that parser output is done
 341+ $useParserCache = false;
 342+ // Stable version requested by ID or relevant conditions met to
 343+ // to override page view with the stable version.
 344+ } else if ( $stable || $this->showingStable() ) {
 345+ $this->showStableVersion( $srev, $tag, $prot );
 346+ $outputDone = true; # Tell MW that parser output is done
 347+ $useParserCache = false;
 348+ // Looking at some specific old revision (&oldid=x) or if FlaggedRevs is not
 349+ // set to override given the relevant conditions (like &stable=0) or there
 350+ // is no stable version.
 351+ } else {
 352+ $this->showDraftVersion( $srev, $tag, $prot );
 353+ }
 354+ $encJS = ''; // JS events to use
 355+ # Some checks for which tag CSS to use
 356+ if ( $this->useSimpleUI() ) {
 357+ $tagClass = 'flaggedrevs_short';
 358+ # Collapse the box details on mouseOut
 359+ $encJS .= ' onmouseout="FlaggedRevs.onBoxMouseOut(event)"';
 360+ } elseif ( $pristine ) {
 361+ $tagClass = 'flaggedrevs_pristine';
 362+ } elseif ( $quality ) {
 363+ $tagClass = 'flaggedrevs_quality';
 364+ } else {
 365+ $tagClass = 'flaggedrevs_basic';
 366+ }
 367+ # Wrap tag contents in a div
 368+ if ( $tag != '' ) {
 369+ $rtl = $wgContLang->isRTL() ? " rtl" : ""; // RTL langauges
 370+ $css = "{$tagClass}{$rtl} plainlinks noprint";
 371+ $notice = "<div id=\"mw-fr-revisiontag\" class=\"{$css}\"{$encJS}>{$tag}</div>\n";
 372+ $this->reviewNotice .= $notice;
 373+ }
 374+ return true;
 375+ }
 376+
 377+ /**
 378+ * If the page has a stable version and it shows by default,
 379+ * tell search crawlers to index only that version of the page.
 380+ * Also index the draft as well if they are synced (bug 27173).
 381+ * However, any URL with ?stableid=x should not be indexed (as with ?oldid=x).
 382+ */
 383+ public function setRobotPolicy() {
 384+ global $wgRequest, $wgOut;
 385+ if ( $this->article->getStableRev() && $this->article->isStableShownByDefault() ) {
 386+ if ( $this->showingStable() ) {
 387+ return; // stable version - index this
 388+ } elseif ( !$wgRequest->getVal( 'stableid' )
 389+ && $wgOut->getRevisionId() == $this->article->getStable()
 390+ && $this->article->stableVersionIsSynced() )
 391+ {
 392+ return; // draft that is synced with the stable version - index this
 393+ }
 394+ $wgOut->setRobotPolicy( 'noindex,nofollow' ); // don't index this version
 395+ }
 396+ }
 397+
 398+ /**
 399+ * @param $tag review box/bar info
 400+ * @param $prot protection notice
 401+ * Tag output function must be called by caller
 402+ */
 403+ protected function showUnreviewedPage( $tag, $prot ) {
 404+ global $wgOut, $wgContLang;
 405+ if ( $wgOut->isPrintable() ) {
 406+ return; // all this function does is add notices; don't show them
 407+ }
 408+ $icon = FlaggedRevsXML::draftStatusIcon();
 409+ // Simple icon-based UI
 410+ if ( $this->useSimpleUI() ) {
 411+ // RTL langauges
 412+ $rtl = $wgContLang->isRTL() ? " rtl" : "";
 413+ $tag .= $prot . $icon . wfMsgExt( 'revreview-quick-none', 'parseinline' );
 414+ $css = "flaggedrevs_short{$rtl} plainlinks noprint";
 415+ $this->reviewNotice .= "<div id='mw-fr-revisiontag' class='$css'>$tag</div>";
 416+ // Standard UI
 417+ } else {
 418+ $css = 'flaggedrevs_notice plainlinks noprint';
 419+ $tag = "<div id='mw-fr-revisiontag' class='$css'>" .
 420+ $prot . $icon . wfMsgExt( 'revreview-noflagged', 'parseinline' ) .
 421+ "</div>";
 422+ $this->reviewNotice .= $tag;
 423+ }
 424+ }
 425+
 426+ /**
 427+ * @param $srev stable version
 428+ * @param $tag review box/bar info
 429+ * @param $prot protection notice icon
 430+ * Tag output function must be called by caller
 431+ * Parser cache control deferred to caller
 432+ */
 433+ protected function showDraftVersion( FlaggedRevision $srev, &$tag, $prot ) {
 434+ global $wgUser, $wgOut, $wgLang, $wgRequest;
 435+ $this->load();
 436+ if ( $wgOut->isPrintable() ) {
 437+ return; // all this function does is add notices; don't show them
 438+ }
 439+ $flags = $srev->getTags();
 440+ $time = $wgLang->date( $srev->getTimestamp(), true );
 441+ # Get quality level
 442+ $quality = FlaggedRevs::isQuality( $flags );
 443+ # Get stable version sync status
 444+ $synced = $this->article->stableVersionIsSynced();
 445+ if ( $synced ) { // draft == stable
 446+ $diffToggle = ''; // no diff to show
 447+ } else { // draft != stable
 448+ # The user may want the diff (via prefs)
 449+ $diffToggle = $this->getTopDiffToggle( $srev, $quality );
 450+ if ( $diffToggle != '' ) $diffToggle = " $diffToggle";
 451+ # Make sure there is always a notice bar when viewing the draft.
 452+ if ( $this->useSimpleUI() ) { // we already one for detailed UI
 453+ $this->setPendingNotice( $srev, $diffToggle );
 454+ }
 455+ }
 456+ # Give a "your edit is pending" notice to newer users if
 457+ # an unreviewed edit was completed...
 458+ if ( $wgRequest->getVal( 'shownotice' )
 459+ && $this->article->getUserText( Revision::RAW ) == $wgUser->getName()
 460+ && $this->article->revsArePending()
 461+ && !$wgUser->isAllowed( 'review' ) )
 462+ {
 463+ $revsSince = $this->article->getPendingRevCount();
 464+ $pending = $prot;
 465+ if ( $this->showRatingIcon() ) {
 466+ $pending .= FlaggedRevsXML::draftStatusIcon();
 467+ }
 468+ $pending .= wfMsgExt( 'revreview-edited',
 469+ 'parseinline', $srev->getRevId(), $revsSince );
 470+ $anchor = $wgRequest->getVal( 'fromsection' );
 471+ if ( $anchor != null ) {
 472+ $section = str_replace( '_', ' ', $anchor ); // prettify
 473+ $pending .= wfMsgExt( 'revreview-edited-section', 'parse', $anchor, $section );
 474+ }
 475+ # Notice should always use subtitle
 476+ $this->reviewNotice = "<div id='mw-fr-reviewnotice' " .
 477+ "class='flaggedrevs_preview plainlinks'>$pending</div>";
 478+ # Otherwise, construct some tagging info for non-printable outputs.
 479+ # Also, if low profile UI is enabled and the page is synced, skip the tag.
 480+ # Note: the "your edit is pending" notice has all this info, so we never add both.
 481+ } else if ( !( $this->article->lowProfileUI() && $synced ) ) {
 482+ $revsSince = $this->article->getPendingRevCount();
 483+ // Simple icon-based UI
 484+ if ( $this->useSimpleUI() ) {
 485+ if ( !$wgUser->getId() ) {
 486+ $msgHTML = ''; // Anons just see simple icons
 487+ } else if ( $synced ) {
 488+ $msg = $quality
 489+ ? 'revreview-quick-quality-same'
 490+ : 'revreview-quick-basic-same';
 491+ $msgHTML = wfMsgExt( $msg, 'parseinline',
 492+ $srev->getRevId(), $revsSince );
 493+ } else {
 494+ $msg = $quality
 495+ ? 'revreview-quick-see-quality'
 496+ : 'revreview-quick-see-basic';
 497+ $msgHTML = wfMsgExt( $msg, 'parseinline',
 498+ $srev->getRevId(), $revsSince );
 499+ }
 500+ $icon = '';
 501+ # For protection based configs, show lock only if it's not redundant.
 502+ if ( $this->showRatingIcon() ) {
 503+ $icon = $synced
 504+ ? FlaggedRevsXML::stableStatusIcon( $quality )
 505+ : FlaggedRevsXML::draftStatusIcon();
 506+ }
 507+ $msgHTML = $prot . $icon . $msgHTML;
 508+ $tag .= FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML,
 509+ $revsSince, 'draft', $synced, false );
 510+ // Standard UI
 511+ } else {
 512+ if ( $synced ) {
 513+ if ( $quality ) {
 514+ $msg = 'revreview-quality-same';
 515+ } else {
 516+ $msg = 'revreview-basic-same';
 517+ }
 518+ $msgHTML = wfMsgExt( $msg, 'parseinline',
 519+ $srev->getRevId(), $time, $revsSince );
 520+ } else {
 521+ $msg = $quality
 522+ ? 'revreview-newest-quality'
 523+ : 'revreview-newest-basic';
 524+ $msg .= ( $revsSince == 0 ) ? '-i' : '';
 525+ $msgHTML = wfMsgExt( $msg, 'parseinline',
 526+ $srev->getRevId(), $time, $revsSince );
 527+ }
 528+ $icon = $synced
 529+ ? FlaggedRevsXML::stableStatusIcon( $quality )
 530+ : FlaggedRevsXML::draftStatusIcon();
 531+ $tag .= $prot . $icon . $msgHTML . $diffToggle;
 532+ }
 533+ }
 534+ }
 535+
 536+ /**
 537+ * @param $srev stable version
 538+ * @param $frev selected flagged revision
 539+ * @param $tag review box/bar info
 540+ * @param $prot protection notice icon
 541+ * Tag output function must be called by caller
 542+ * Parser cache control deferred to caller
 543+ */
 544+ protected function showOldReviewedVersion(
 545+ FlaggedRevision $srev, FlaggedRevision $frev, &$tag, $prot
 546+ ) {
 547+ global $wgUser, $wgOut, $wgLang;
 548+ $this->load();
 549+ $flags = $frev->getTags();
 550+ $time = $wgLang->date( $frev->getTimestamp(), true );
 551+ # Set display revision ID
 552+ $wgOut->setRevisionId( $frev->getRevId() );
 553+ # Get quality level
 554+ $quality = FlaggedRevs::isQuality( $flags );
 555+
 556+ # Construct some tagging for non-printable outputs. Note that the pending
 557+ # notice has all this info already, so don't do this if we added that already.
 558+ if ( !$wgOut->isPrintable() ) {
 559+ // Simple icon-based UI
 560+ if ( $this->useSimpleUI() ) {
 561+ $icon = '';
 562+ # For protection based configs, show lock only if it's not redundant.
 563+ if ( $this->showRatingIcon() ) {
 564+ $icon = FlaggedRevsXML::stableStatusIcon( $quality );
 565+ }
 566+ $revsSince = $this->article->getPendingRevCount();
 567+ if ( !$wgUser->getId() ) {
 568+ $msgHTML = ''; // Anons just see simple icons
 569+ } else {
 570+ $msg = $quality
 571+ ? 'revreview-quick-quality-old'
 572+ : 'revreview-quick-basic-old';
 573+ $msgHTML = wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $revsSince );
 574+ }
 575+ $msgHTML = $prot . $icon . $msgHTML;
 576+ $tag = FlaggedRevsXML::prettyRatingBox( $frev, $msgHTML,
 577+ $revsSince, 'oldstable', false /*synced*/ );
 578+ // Standard UI
 579+ } else {
 580+ $icon = FlaggedRevsXML::stableStatusIcon( $quality );
 581+ $msg = $quality
 582+ ? 'revreview-quality-old'
 583+ : 'revreview-basic-old';
 584+ $tag = $prot . $icon;
 585+ $tag .= wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $time );
 586+ # Hide clutter
 587+ if ( !empty( $flags ) ) {
 588+ $tag .= FlaggedRevsXML::ratingToggle();
 589+ $tag .= "<div id='mw-fr-revisiondetails' style='display:block;'>" .
 590+ wfMsgHtml( 'revreview-oldrating' ) .
 591+ FlaggedRevsXML::addTagRatings( $flags ) . '</div>';
 592+ }
 593+ }
 594+ }
 595+
 596+ # Check if this is a redirect...
 597+ $text = $frev->getRevText();
 598+ $redirHtml = $this->getRedirectHtml( $text );
 599+
 600+ # Parse and output HTML
 601+ if ( $redirHtml == '' ) {
 602+ $parserOptions = FlaggedRevs::makeParserOptions();
 603+ $parserOut = FlaggedRevs::parseStableText(
 604+ $this->article->getTitle(), $text, $frev->getRevId(), $parserOptions );
 605+ $this->addParserOutput( $parserOut );
 606+ } else {
 607+ $wgOut->addHtml( $redirHtml );
 608+ }
 609+ }
 610+
 611+ /**
 612+ * @param $srev stable version
 613+ * @param $tag review box/bar info
 614+ * @param $prot protection notice
 615+ * Tag output function must be called by caller
 616+ * Parser cache control deferred to caller
 617+ */
 618+ protected function showStableVersion( FlaggedRevision $srev, &$tag, $prot ) {
 619+ global $wgOut, $wgLang, $wgUser;
 620+ $this->load();
 621+ $flags = $srev->getTags();
 622+ $time = $wgLang->date( $srev->getTimestamp(), true );
 623+ # Set display revision ID
 624+ $wgOut->setRevisionId( $srev->getRevId() );
 625+ # Get quality level
 626+ $quality = FlaggedRevs::isQuality( $flags );
 627+
 628+ $synced = $this->article->stableVersionIsSynced();
 629+ # Construct some tagging
 630+ if ( !$wgOut->isPrintable() && !( $this->article->lowProfileUI() && $synced ) ) {
 631+ $revsSince = $this->article->getPendingRevCount();
 632+ // Simple icon-based UI
 633+ if ( $this->useSimpleUI() ) {
 634+ $icon = '';
 635+ # For protection based configs, show lock only if it's not redundant.
 636+ if ( $this->showRatingIcon() ) {
 637+ $icon = FlaggedRevsXML::stableStatusIcon( $quality );
 638+ }
 639+ if ( !$wgUser->getId() ) {
 640+ $msgHTML = ''; // Anons just see simple icons
 641+ } else {
 642+ $msg = $quality
 643+ ? 'revreview-quick-quality'
 644+ : 'revreview-quick-basic';
 645+ # Uses messages 'revreview-quick-quality-same', 'revreview-quick-basic-same'
 646+ $msg = $synced ? "{$msg}-same" : $msg;
 647+ $msgHTML = wfMsgExt( $msg, 'parseinline',
 648+ $srev->getRevId(), $revsSince );
 649+ }
 650+ $msgHTML = $prot . $icon . $msgHTML;
 651+ $tag = FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML,
 652+ $revsSince, 'stable', $synced );
 653+ // Standard UI
 654+ } else {
 655+ $icon = FlaggedRevsXML::stableStatusIcon( $quality );
 656+ $msg = $quality ? 'revreview-quality' : 'revreview-basic';
 657+ if ( $synced ) {
 658+ # uses messages 'revreview-quality-same', 'revreview-basic-same'
 659+ $msg .= '-same';
 660+ } elseif ( $revsSince == 0 ) {
 661+ # uses messages 'revreview-quality-i', 'revreview-basic-i'
 662+ $msg .= '-i';
 663+ }
 664+ $tag = $prot . $icon;
 665+ $tag .= wfMsgExt( $msg, 'parseinline', $srev->getRevId(), $time, $revsSince );
 666+ if ( !empty( $flags ) ) {
 667+ $tag .= FlaggedRevsXML::ratingToggle();
 668+ $tag .= "<div id='mw-fr-revisiondetails' style='display:block;'>" .
 669+ FlaggedRevsXML::addTagRatings( $flags ) . '</div>';
 670+ }
 671+ }
 672+ }
 673+
 674+ # Get parsed stable version and output HTML
 675+ $parserOut = FlaggedRevs::getPageCache( $this->article, $wgUser );
 676+ if ( $parserOut ) {
 677+ $this->addParserOutput( $parserOut );
 678+ } else {
 679+ $text = $srev->getRevText();
 680+ # Check if this is a redirect...
 681+ $redirHtml = $this->getRedirectHtml( $text );
 682+ # Don't parse redirects, use separate handling...
 683+ if ( $redirHtml == '' ) {
 684+ # Get the new stable output
 685+ $parserOptions = FlaggedRevs::makeParserOptions();
 686+ $parserOut = FlaggedRevs::parseStableText(
 687+ $this->article->getTitle(), $text, $srev->getRevId(), $parserOptions );
 688+ # Update the stable version cache
 689+ FlaggedRevs::updatePageCache( $this->article, $parserOptions, $parserOut );
 690+ # Add the stable output to the page view
 691+ $this->addParserOutput( $parserOut );
 692+
 693+ # Update the stable version dependancies
 694+ FlaggedRevs::updateCacheTracking( $this->article, $parserOut );
 695+ } else {
 696+ $wgOut->addHtml( $redirHtml );
 697+ }
 698+ }
 699+
 700+ # Update page sync status for tracking purposes.
 701+ # NOTE: avoids master hits and doesn't have to be perfect for what it does
 702+ if ( $this->article->syncedInTracking() != $synced ) {
 703+ if ( wfGetDB( DB_SLAVE )->getLag() <= 5 ) { // avoid write-delay cycles
 704+ FlaggedRevs::updateSyncStatus( $this->article, $synced );
 705+ }
 706+ }
 707+ }
 708+
 709+ // Add parser output and update title
 710+ // @TODO: refactor MW core to move this back
 711+ protected function addParserOutput( ParserOutput $parserOut ) {
 712+ global $wgOut;
 713+ $wgOut->addParserOutput( $parserOut );
 714+ # Adjust the title if it was set by displaytitle, -{T|}- or language conversion
 715+ $titleText = $parserOut->getTitleText();
 716+ if ( strval( $titleText ) !== '' ) {
 717+ $wgOut->setPageTitle( $titleText );
 718+ }
 719+ }
 720+
 721+ // Get fancy redirect arrow and link HTML
 722+ protected function getRedirectHtml( $text ) {
 723+ $rTargets = Title::newFromRedirectArray( $text );
 724+ if ( $rTargets ) {
 725+ return $this->article->viewRedirect( $rTargets );
 726+ }
 727+ return '';
 728+ }
 729+
 730+ // Show icons for draft/stable/old reviewed versions
 731+ protected function showRatingIcon() {
 732+ if ( FlaggedRevs::useOnlyIfProtected() ) {
 733+ // If there is only one quality level and we have tabs to know
 734+ // which version we are looking at, then just use the lock icon...
 735+ return FlaggedRevs::qualityVersions();
 736+ }
 737+ return true;
 738+ }
 739+
 740+ /**
 741+ * Get collapsible diff-to-stable html to add to the review notice as needed
 742+ * @param FlaggedRevision $srev, stable version
 743+ * @param bool $quality, revision is quality
 744+ * @return string, the html line (either "" or "<diff toggle><diff div>")
 745+ */
 746+ protected function getTopDiffToggle( FlaggedRevision $srev, $quality ) {
 747+ global $wgUser;
 748+ $this->load();
 749+ if ( !$wgUser->getBoolOption( 'flaggedrevsviewdiffs' ) ) {
 750+ return false; // nothing to do here
 751+ }
 752+ # Diff should only show for the draft
 753+ $oldid = $this->article->getOldIDFromRequest();
 754+ $latest = $this->article->getLatest();
 755+ if ( $oldid && $oldid != $latest ) {
 756+ return false; // not viewing the draft
 757+ }
 758+ $revsSince = $this->article->getPendingRevCount();
 759+ if ( !$revsSince ) {
 760+ return false; // no pending changes
 761+ }
 762+ $title = $this->article->getTitle(); // convenience
 763+ # Review status of left diff revision...
 764+ $leftNote = $quality
 765+ ? 'revreview-hist-quality'
 766+ : 'revreview-hist-basic';
 767+ $lClass = FlaggedRevsXML::getQualityColor( (int)$quality );
 768+ $leftNote = "<span class='$lClass'>[" . wfMsgHtml( $leftNote ) . "]</span>";
 769+ # Review status of right diff revision...
 770+ $rClass = FlaggedRevsXML::getQualityColor( false );
 771+ $rightNote = "<span class='$rClass'>[" .
 772+ wfMsgHtml( 'revreview-hist-pending' ) . "]</span>";
 773+ # Get the actual body of the diff...
 774+ $diffEngine = new DifferenceEngine( $title, $srev->getRevId(), $latest );
 775+ $diffBody = $diffEngine->getDiffBody();
 776+ if ( strlen( $diffBody ) > 0 ) {
 777+ $nEdits = $revsSince - 1; // full diff-to-stable, no need for query
 778+ if ( $nEdits ) {
 779+ $limit = 100;
 780+ $nUsers = $title->countAuthorsBetween( $srev->getRevId(), $latest, $limit );
 781+ $multiNotice = DifferenceEngine::intermediateEditsMsg( $nEdits, $nUsers, $limit );
 782+ } else {
 783+ $multiNotice = '';
 784+ }
 785+ $diffEngine->showDiffStyle(); // add CSS
 786+ $this->isDiffFromStable = true; // alter default review form tags
 787+ return
 788+ FlaggedRevsXML::diffToggle() .
 789+ "<div id='mw-fr-stablediff'>\n" .
 790+ self::getFormattedDiff( $diffBody, $multiNotice, $leftNote, $rightNote ) .
 791+ "</div>\n";;
 792+ }
 793+ return '';
 794+ }
 795+
 796+ // $n number of in-between revs
 797+ protected static function getFormattedDiff(
 798+ $diffBody, $multiNotice, $leftStatus, $rightStatus
 799+ ) {
 800+ if ( $multiNotice != '' ) {
 801+ $multiNotice = "<tr><td colspan='4' align='center' class='diff-multi'>" .
 802+ $multiNotice . "</td></tr>";
 803+ }
 804+ return
 805+ "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" .
 806+ "<col class='diff-marker' />" .
 807+ "<col class='diff-content' />" .
 808+ "<col class='diff-marker' />" .
 809+ "<col class='diff-content' />" .
 810+ "<tr>" .
 811+ "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" .
 812+ $leftStatus . "</b></td>" .
 813+ "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" .
 814+ $rightStatus . "</b></td>" .
 815+ "</tr>" .
 816+ $multiNotice .
 817+ $diffBody .
 818+ "</table>";
 819+ }
 820+
 821+ /**
 822+ * Get the normal and display files for the underlying ImagePage.
 823+ * If the a stable version needs to be displayed, this will set $normalFile
 824+ * to the current version, and $displayFile to the desired version.
 825+ *
 826+ * If no stable version is required, the reference parameters will not be set
 827+ *
 828+ * Depends on $wgRequest
 829+ */
 830+ public function imagePageFindFile( &$normalFile, &$displayFile ) {
 831+ global $wgRequest;
 832+ $this->load();
 833+ # Determine timestamp. A reviewed version may have explicitly been requested...
 834+ $frev = null;
 835+ $time = false;
 836+ $reqId = $wgRequest->getVal( 'stableid' );
 837+ if ( $reqId ) {
 838+ $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId );
 839+ } elseif ( $this->showingStable() ) {
 840+ $frev = $this->article->getStableRev();
 841+ }
 842+ if ( $frev ) {
 843+ $time = $frev->getFileTimestamp();
 844+ // B/C, may be stored in associated image version metadata table
 845+ // @TODO: remove, updateTracking.php does this
 846+ if ( !$time ) {
 847+ $dbr = wfGetDB( DB_SLAVE );
 848+ $time = $dbr->selectField( 'flaggedimages',
 849+ 'fi_img_timestamp',
 850+ array( 'fi_rev_id' => $frev->getRevId(),
 851+ 'fi_name' => $this->article->getTitle()->getDBkey() ),
 852+ __METHOD__
 853+ );
 854+ $time = trim( $time ); // remove garbage
 855+ $time = $time ? wfTimestamp( TS_MW, $time ) : false;
 856+ }
 857+ }
 858+ if ( !$time ) {
 859+ # Try request parameter
 860+ $time = $wgRequest->getVal( 'filetimestamp', false );
 861+ }
 862+
 863+ if ( !$time ) {
 864+ return; // Use the default behaviour
 865+ }
 866+
 867+ $title = $this->article->getTitle();
 868+ $displayFile = wfFindFile( $title, array( 'time' => $time ) );
 869+ # If none found, try current
 870+ if ( !$displayFile ) {
 871+ wfDebug( __METHOD__ . ": {$title->getPrefixedDBkey()}: $time not found, using current\n" );
 872+ $displayFile = wfFindFile( $title );
 873+ # If none found, use a valid local placeholder
 874+ if ( !$displayFile ) {
 875+ $displayFile = wfLocalFile( $title ); // fallback to current
 876+ }
 877+ $normalFile = $displayFile;
 878+ # If found, set $normalFile
 879+ } else {
 880+ wfDebug( __METHOD__ . ": {$title->getPrefixedDBkey()}: using timestamp $time\n" );
 881+ $normalFile = wfFindFile( $title );
 882+ }
 883+ }
 884+
 885+ /**
 886+ * Adds stable version tags to page when viewing history
 887+ */
 888+ public function addToHistView() {
 889+ global $wgOut;
 890+ $this->load();
 891+ # Add a notice if there are pending edits...
 892+ $srev = $this->article->getStableRev();
 893+ if ( $srev && $this->article->revsArePending() ) {
 894+ $revsSince = $this->article->getPendingRevCount();
 895+ $tag = "<div id='mw-fr-revisiontag-edit' class='flaggedrevs_notice plainlinks'>" .
 896+ FlaggedRevsXML::lockStatusIcon( $this->article ) . # flag protection icon as needed
 897+ FlaggedRevsXML::pendingEditNotice( $this->article, $srev, $revsSince ) . "</div>";
 898+ $wgOut->addHTML( $tag );
 899+ }
 900+ return true;
 901+ }
 902+
 903+ /**
 904+ * Adds stable version tags to page when editing
 905+ */
 906+ public function addToEditView( EditPage $editPage ) {
 907+ global $wgOut, $wgUser;
 908+ $this->load();
 909+ # Must be reviewable. UI may be limited to unobtrusive patrolling system.
 910+ if ( !$this->article->isReviewable() ) {
 911+ return true;
 912+ }
 913+ $items = array();
 914+ # Show stabilization log
 915+ $log = $this->stabilityLogNotice();
 916+ if ( $log ) $items[] = $log;
 917+ # Check the newest stable version
 918+ $frev = $this->article->getStableRev();
 919+ if ( $frev ) {
 920+ $quality = $frev->getQuality();
 921+ # Find out revision id of base version
 922+ $latestId = $this->article->getLatest();
 923+ $revId = $editPage->oldid ? $editPage->oldid : $latestId;
 924+ # Let new users know about review procedure a tag.
 925+ # If the log excerpt was shown this is redundant.
 926+ if ( !$log && !$wgUser->getId() && $this->article->isStableShownByDefault() ) {
 927+ $items[] = wfMsgExt( 'revreview-editnotice', 'parseinline' );
 928+ }
 929+ # Add a notice if there are pending edits...
 930+ if ( $this->article->revsArePending() ) {
 931+ $revsSince = $this->article->getPendingRevCount();
 932+ $items[] = FlaggedRevsXML::pendingEditNotice( $this->article, $frev, $revsSince );
 933+ }
 934+ # Show diff to stable, to make things less confusing.
 935+ # This can be disabled via user preferences and other conditions...
 936+ if ( $frev->getRevId() < $latestId // changes were made
 937+ && $wgUser->getBoolOption( 'flaggedrevseditdiffs' ) // not disable via prefs
 938+ && $revId == $latestId // only for current rev
 939+ && $editPage->section != 'new' // not for new sections
 940+ && $editPage->formtype != 'diff' // not "show changes"
 941+ ) {
 942+ # Left diff side...
 943+ $leftNote = $quality
 944+ ? 'revreview-hist-quality'
 945+ : 'revreview-hist-basic';
 946+ $lClass = FlaggedRevsXML::getQualityColor( (int)$quality );
 947+ $leftNote = "<span class='$lClass'>[" .
 948+ wfMsgHtml( $leftNote ) . "]</span>";
 949+ # Right diff side...
 950+ $rClass = FlaggedRevsXML::getQualityColor( false );
 951+ $rightNote = "<span class='$rClass'>[" .
 952+ wfMsgHtml( 'revreview-hist-pending' ) . "]</span>";
 953+ # Get the stable version source
 954+ $text = $frev->getRevText();
 955+ # Are we editing a section?
 956+ $section = ( $editPage->section == "" ) ?
 957+ false : intval( $editPage->section );
 958+ if ( $section !== false ) {
 959+ $text = $this->article->getSection( $text, $section );
 960+ }
 961+ if ( $text !== false && strcmp( $text, $editPage->textbox1 ) !== 0 ) {
 962+ $diffEngine = new DifferenceEngine( $this->article->getTitle() );
 963+ $diffBody = $diffEngine->generateDiffBody( $text, $editPage->textbox1 );
 964+ $diffHtml =
 965+ wfMsgExt( 'review-edit-diff', 'parseinline' ) . ' ' .
 966+ FlaggedRevsXML::diffToggle() .
 967+ "<div id='mw-fr-stablediff'>" .
 968+ self::getFormattedDiff( $diffBody, '', $leftNote, $rightNote ) .
 969+ "</div>\n";
 970+ $items[] = $diffHtml;
 971+ $diffEngine->showDiffStyle(); // add CSS
 972+ }
 973+ }
 974+ # Output items
 975+ if ( count( $items ) ) {
 976+ $html = "<table class='flaggedrevs_editnotice plainlinks'>";
 977+ foreach ( $items as $item ) {
 978+ $html .= '<tr><td>' . $item . '</td></tr>';
 979+ }
 980+ $html .= '</table>';
 981+ $wgOut->addHTML( $html );
 982+ }
 983+ }
 984+ return true;
 985+ }
 986+
 987+ protected function stabilityLogNotice() {
 988+ $this->load();
 989+ $s = '';
 990+ # Only for pages manually made to be stable...
 991+ if ( $this->article->isPageLocked() ) {
 992+ $s = wfMsgExt( 'revreview-locked', 'parseinline' );
 993+ $s .= ' ' . FlaggedRevsXML::logDetailsToggle();
 994+ $s .= FlaggedRevsXML::stabilityLogExcerpt( $this->article );
 995+ # ...or unstable
 996+ } elseif ( $this->article->isPageUnlocked() ) {
 997+ $s = wfMsgExt( 'revreview-unlocked', 'parseinline' );
 998+ $s .= ' ' . FlaggedRevsXML::logDetailsToggle();
 999+ $s .= FlaggedRevsXML::stabilityLogExcerpt( $this->article );
 1000+ }
 1001+ return $s;
 1002+ }
 1003+
 1004+ public function addToNoSuchSection( EditPage $editPage, &$s ) {
 1005+ $this->load();
 1006+ $srev = $this->article->getStableRev();
 1007+ # Add notice for users that may have clicked "edit" for a
 1008+ # section in the stable version that isn't in the draft.
 1009+ if ( $srev && $this->article->revsArePending() ) {
 1010+ $revsSince = $this->article->getPendingRevCount();
 1011+ if ( $revsSince ) {
 1012+ $s .= "<div class='flaggedrevs_editnotice plainlinks'>" .
 1013+ wfMsgExt( 'revreview-pending-nosection', 'parseinline',
 1014+ $srev->getRevId(), $revsSince ) . "</div>";
 1015+ }
 1016+ }
 1017+ return true;
 1018+ }
 1019+
 1020+ /**
 1021+ * Add unreviewed pages links
 1022+ */
 1023+ public function addToCategoryView() {
 1024+ global $wgOut, $wgUser;
 1025+ $this->load();
 1026+ if ( !$wgUser->isAllowed( 'review' ) ) {
 1027+ return true;
 1028+ }
 1029+ if ( !FlaggedRevs::useOnlyIfProtected() ) {
 1030+ # Add links to lists of unreviewed pages and pending changes in this category
 1031+ $category = $this->article->getTitle()->getText();
 1032+ $wgOut->appendSubtitle(
 1033+ Html::rawElement(
 1034+ 'span',
 1035+ array( 'class' => 'plainlinks', 'id' => 'mw-fr-category-oldreviewed' ),
 1036+ wfMsgExt( 'flaggedrevs-categoryview', 'parseinline', urlencode( $category ) )
 1037+ )
 1038+ );
 1039+ }
 1040+ return true;
 1041+ }
 1042+
 1043+ /**
 1044+ * Add review form to pages when necessary
 1045+ * on a regular page view (action=view)
 1046+ */
 1047+ public function addReviewForm( &$data ) {
 1048+ global $wgRequest, $wgUser, $wgOut;
 1049+ $this->load();
 1050+ if ( $wgOut->isPrintable() ) {
 1051+ return false; // Must be on non-printable output
 1052+ }
 1053+ # User must have review rights
 1054+ if ( !$wgUser->isAllowed( 'review' ) ) {
 1055+ return true;
 1056+ }
 1057+ # Page must exist and be reviewable
 1058+ if ( !$this->article->exists() || !$this->article->isReviewable() ) {
 1059+ return true;
 1060+ }
 1061+ # Must be a page view action...
 1062+ if ( !$this->isPageViewOrDiff( $wgRequest ) ) {
 1063+ return true;
 1064+ }
 1065+ # Get the revision being displayed
 1066+ $rev = false;
 1067+ if ( $this->reviewFormRev ) {
 1068+ $rev = $this->reviewFormRev; // $newRev for diffs stored here
 1069+ } elseif ( $wgOut->getRevisionId() ) {
 1070+ $rev = Revision::newFromId( $wgOut->getRevisionId() );
 1071+ }
 1072+ # Build the review form as needed
 1073+ if ( $rev && ( !$this->diffRevs || $this->isReviewableDiff ) ) {
 1074+ $form = new RevisionReviewFormGUI( $wgUser, $this->article, $rev );
 1075+ # Default tags and existence of "reject" button depend on context
 1076+ if ( $this->diffRevs ) {
 1077+ $form->setDiffPriorRev( $this->diffRevs['old'] );
 1078+ }
 1079+ # Review notice box goes in top of form
 1080+ $form->setTopNotice( $this->diffNoticeBox );
 1081+ # $wgOut may not already have the inclusion IDs, such as for diffonly=1.
 1082+ # RevisionReviewForm will fetch them as needed however.
 1083+ if ( $wgOut->getRevisionId() == $rev->getId() ) {
 1084+ $form->setIncludeVersions( $wgOut->getTemplateIds(), $wgOut->getImageTimeKeys() );
 1085+ }
 1086+ list( $html, $status ) = $form->getHtml();
 1087+ # Diff action: place the form at the top of the page
 1088+ if ( $this->diffRevs ) {
 1089+ $wgOut->prependHTML( $html );
 1090+ # View action: place the form at the bottom of the page
 1091+ } else {
 1092+ $data .= $html;
 1093+ }
 1094+ }
 1095+ return true;
 1096+ }
 1097+
 1098+ /**
 1099+ * Add link to stable version setting to protection form
 1100+ */
 1101+ public function addVisibilityLink( &$data ) {
 1102+ global $wgRequest, $wgOut;
 1103+ $this->load();
 1104+ if ( FlaggedRevs::useProtectionLevels() ) {
 1105+ return true; // simple custom levels set for action=protect
 1106+ }
 1107+ # Check only if the title is reviewable
 1108+ if ( !FlaggedRevs::inReviewNamespace( $this->article->getTitle() ) ) {
 1109+ return true;
 1110+ }
 1111+ $action = $wgRequest->getVal( 'action', 'view' );
 1112+ if ( $action == 'protect' || $action == 'unprotect' ) {
 1113+ $title = SpecialPage::getTitleFor( 'Stabilization' );
 1114+ # Give a link to the page to configure the stable version
 1115+ $frev = $this->article->getStableRev();
 1116+ if ( $frev && $frev->getRevId() == $this->article->getLatest() ) {
 1117+ $wgOut->prependHTML( "<span class='plainlinks'>" .
 1118+ wfMsgExt( 'revreview-visibility-synced', 'parseinline',
 1119+ $title->getPrefixedText() ) . "</span>" );
 1120+ } elseif ( $frev ) {
 1121+ $wgOut->prependHTML( "<span class='plainlinks'>" .
 1122+ wfMsgExt( 'revreview-visibility-outdated', 'parseinline',
 1123+ $title->getPrefixedText() ) . "</span>" );
 1124+ } else {
 1125+ $wgOut->prependHTML( "<span class='plainlinks'>" .
 1126+ wfMsgExt( 'revreview-visibility-nostable', 'parseinline',
 1127+ $title->getPrefixedText() ) . "</span>" );
 1128+ }
 1129+ }
 1130+ return true;
 1131+ }
 1132+
 1133+ /**
 1134+ * Modify an array of action links, as used by SkinTemplateNavigation and
 1135+ * SkinTemplateTabs, to inlude flagged revs UI elements
 1136+ */
 1137+ public function setActionTabs( $skin, array &$actions ) {
 1138+ global $wgUser;
 1139+ $this->load();
 1140+ if ( FlaggedRevs::useProtectionLevels() ) {
 1141+ return true; // simple custom levels set for action=protect
 1142+ }
 1143+ $title = $this->article->getTitle()->getSubjectPage();
 1144+ if ( !FlaggedRevs::inReviewNamespace( $title ) ) {
 1145+ return true; // Only reviewable pages need these tabs
 1146+ }
 1147+ // Check if we should show a stabilization tab
 1148+ if (
 1149+ !$this->article->getTitle()->isTalkPage() &&
 1150+ is_array( $actions ) &&
 1151+ !isset( $actions['protect'] ) &&
 1152+ !isset( $actions['unprotect'] ) &&
 1153+ $wgUser->isAllowed( 'stablesettings' ) &&
 1154+ $title->exists() )
 1155+ {
 1156+ $stableTitle = SpecialPage::getTitleFor( 'Stabilization' );
 1157+ // Add the tab
 1158+ $actions['default'] = array(
 1159+ 'class' => false,
 1160+ 'text' => wfMsg( 'stabilization-tab' ),
 1161+ 'href' => $stableTitle->getLocalUrl(
 1162+ 'page=' . $title->getPrefixedUrl()
 1163+ )
 1164+ );
 1165+ }
 1166+ return true;
 1167+ }
 1168+
 1169+ /**
 1170+ * Modify an array of tab links to include flagged revs UI elements
 1171+ * @param string $type ('flat' for SkinTemplateTabs, 'nav' for SkinTemplateNavigation)
 1172+ */
 1173+ public function setViewTabs( Skin $skin, array &$views, $type ) {
 1174+ global $wgRequest;
 1175+ $this->load();
 1176+ if ( $this->article->getTitle()->isTalkPage() ) {
 1177+ return true; // leave talk pages alone
 1178+ }
 1179+ if ( !$this->article->isReviewable() ) {
 1180+ return true; // Not a reviewable page or the UI is hidden
 1181+ }
 1182+ $srev = $this->article->getStableRev();
 1183+ if ( !$srev ) {
 1184+ return true; // No stable revision exists
 1185+ }
 1186+ $synced = $this->article->stableVersionIsSynced();
 1187+ $pendingEdits = !$synced && $this->article->isStableShownByDefault();
 1188+ // Set the edit tab names as needed...
 1189+ if ( $pendingEdits ) {
 1190+ if ( isset( $views['edit'] ) ) {
 1191+ $views['edit']['text'] = wfMsg( 'revreview-edit' );
 1192+ }
 1193+ if ( isset( $views['viewsource'] ) ) {
 1194+ $views['viewsource']['text'] = wfMsg( 'revreview-source' );
 1195+ }
 1196+ }
 1197+ # Add "pending changes" tab if the page is not synced
 1198+ if ( !$synced ) {
 1199+ $this->addDraftTab( $views, $srev, $type );
 1200+ }
 1201+ return true;
 1202+ }
 1203+
 1204+ // Add "pending changes" tab and set tab selection CSS
 1205+ protected function addDraftTab( array &$views, FlaggedRevision $srev, $type ) {
 1206+ global $wgRequest, $wgOut;
 1207+ $title = $this->article->getTitle(); // convenience
 1208+ $tabs = array(
 1209+ 'read' => array( // view stable
 1210+ 'text' => '', // unused
 1211+ 'href' => $title->getLocalUrl( 'stable=1' ),
 1212+ 'class' => ''
 1213+ ),
 1214+ 'draft' => array( // view draft
 1215+ 'text' => wfMsg( 'revreview-current' ),
 1216+ 'href' => $title->getLocalUrl( 'stable=0&redirect=no' ),
 1217+ 'class' => 'collapsible'
 1218+ ),
 1219+ );
 1220+ // Set tab selection CSS
 1221+ if ( $this->showingStable() || $wgRequest->getVal( 'stableid' ) ) {
 1222+ // We are looking a the stable version or an old reviewed one
 1223+ $tabs['read']['class'] = 'selected';
 1224+ } elseif ( $this->isPageViewOrDiff( $wgRequest ) ) {
 1225+ $ts = null;
 1226+ if ( $wgOut->getRevisionId() ) { // @TODO: avoid same query in Skin.php
 1227+ $ts = ( $wgOut->getRevisionId() == $this->article->getLatest() )
 1228+ ? $this->article->getTimestamp() // skip query
 1229+ : Revision::getTimestampFromId( $title, $wgOut->getRevisionId() );
 1230+ }
 1231+ // Are we looking at a pending revision?
 1232+ if ( $ts > $srev->getRevTimestamp() ) { // bug 15515
 1233+ $tabs['draft']['class'] .= ' selected';
 1234+ // Are there *just* pending template/file changes.
 1235+ } elseif ( $this->article->onlyTemplatesOrFilesPending()
 1236+ && $wgOut->getRevisionId() == $this->article->getStable() )
 1237+ {
 1238+ $tabs['draft']['class'] .= ' selected';
 1239+ // Otherwise, fallback to regular tab behavior
 1240+ } else {
 1241+ $tabs['read']['class'] = 'selected';
 1242+ }
 1243+ }
 1244+ $newViews = array();
 1245+ // Rebuild tabs array. Deals with Monobook vs Vector differences.
 1246+ if ( $type == 'nav' ) { // Vector et al
 1247+ foreach ( $views as $tabAction => $data ) {
 1248+ // The 'view' tab. Make it go to the stable version...
 1249+ if ( $tabAction == 'view' ) {
 1250+ // 'view' for content page; make it go to the stable version
 1251+ $newViews[$tabAction]['text'] = $data['text']; // keep tab name
 1252+ $newViews[$tabAction]['href'] = $tabs['read']['href'];
 1253+ $newViews[$tabAction]['class'] = $tabs['read']['class'];
 1254+ // All other tabs...
 1255+ } else {
 1256+ // Add 'draft' tab to content page to the left of 'edit'...
 1257+ if ( $tabAction == 'edit' || $tabAction == 'viewsource' ) {
 1258+ $newViews['current'] = $tabs['draft'];
 1259+ }
 1260+ $newViews[$tabAction] = $data;
 1261+ }
 1262+ }
 1263+ } elseif ( $type == 'flat' ) { // MonoBook et al
 1264+ $first = true;
 1265+ foreach ( $views as $tabAction => $data ) {
 1266+ // The first tab ('page'). Make it go to the stable version...
 1267+ if ( $first ) {
 1268+ $first = false;
 1269+ $newViews[$tabAction]['text'] = $data['text']; // keep tab name
 1270+ $newViews[$tabAction]['href'] = $tabs['read']['href'];
 1271+ $newViews[$tabAction]['class'] = $data['class']; // keep tab class
 1272+ // All other tabs...
 1273+ } else {
 1274+ // Add 'draft' tab to content page to the left of 'edit'...
 1275+ if ( $tabAction == 'edit' || $tabAction == 'viewsource' ) {
 1276+ $newViews['current'] = $tabs['draft'];
 1277+ }
 1278+ $newViews[$tabAction] = $data;
 1279+ }
 1280+ }
 1281+ }
 1282+ // Replaces old tabs with new tabs
 1283+ $views = $newViews;
 1284+ }
 1285+
 1286+ /**
 1287+ * Adds a notice saying that this revision is pending review
 1288+ * @param FlaggedRevision $srev The stable version
 1289+ * @param string $diffToggle either "" or " <diff toggle><diff div>"
 1290+ * @return void
 1291+ */
 1292+ public function setPendingNotice( FlaggedRevision $srev, $diffToggle = '' ) {
 1293+ global $wgLang;
 1294+ $this->load();
 1295+ $time = $wgLang->date( $srev->getTimestamp(), true );
 1296+ $revsSince = $this->article->getPendingRevCount();
 1297+ $msg = $srev->getQuality()
 1298+ ? 'revreview-newest-quality'
 1299+ : 'revreview-newest-basic';
 1300+ $msg .= ( $revsSince == 0 ) ? '-i' : '';
 1301+ # Add bar msg to the top of the page...
 1302+ $css = 'flaggedrevs_preview plainlinks';
 1303+ $msgHTML = wfMsgExt( $msg, 'parseinline', $srev->getRevId(), $time, $revsSince );
 1304+ $this->reviewNotice .= "<div id='mw-fr-reviewnotice' class='$css'>" .
 1305+ "$msgHTML$diffToggle</div>";
 1306+ }
 1307+
 1308+ /**
 1309+ * When viewing a diff:
 1310+ * (a) Add the review form to the top of the page
 1311+ * (b) Mark off which versions are checked or not
 1312+ * (c) When comparing the stable revision to the current:
 1313+ * (i) Show a tag with some explanation for the diff
 1314+ * (ii) List any template/file changes pending review
 1315+ */
 1316+ public function addToDiffView( $diff, $oldRev, $newRev ) {
 1317+ global $wgRequest, $wgUser, $wgOut, $wgMemc;
 1318+ $this->load();
 1319+ # Exempt printer-friendly output
 1320+ if ( $wgOut->isPrintable() ) {
 1321+ return true;
 1322+ # Multi-page diffs are useless and misbehave (bug 19327). Sanity check $newRev.
 1323+ } elseif ( $this->isMultiPageDiff || !$newRev ) {
 1324+ return true;
 1325+ # Page must be reviewable.
 1326+ } elseif ( !$this->article->isReviewable() ) {
 1327+ return true;
 1328+ }
 1329+ $srev = $this->article->getStableRev();
 1330+ # Check if this is a diff-to-stable. If so:
 1331+ # (a) prompt reviewers to review the changes
 1332+ # (b) list template/file changes if only includes are pending
 1333+ if ( $srev
 1334+ && $this->isDiffFromStable
 1335+ && !$this->article->stableVersionIsSynced() ) // pending changes
 1336+ {
 1337+ $changeDiv = '';
 1338+ $this->reviewFormRev = $newRev;
 1339+ $changeList = array();
 1340+ # Page not synced only due to includes?
 1341+ if ( !$this->article->revsArePending() ) {
 1342+ # Add a list of links to each changed template...
 1343+ $changeList = self::fetchTemplateChanges( $srev );
 1344+ # Add a list of links to each changed file...
 1345+ $changeList = array_merge( $changeList, self::fetchFileChanges( $srev ) );
 1346+ # Correct bad cache which said they were not synced...
 1347+ if ( !count( $changeList ) ) {
 1348+ global $wgParserCacheExpireTime;
 1349+ $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $this->article->getId() );
 1350+ $data = FlaggedRevs::makeMemcObj( "true" );
 1351+ $wgMemc->set( $key, $data, $wgParserCacheExpireTime );
 1352+ }
 1353+ }
 1354+ # If there are pending revs or templates/files changes, notify the user...
 1355+ if ( $this->article->revsArePending() || count( $changeList ) ) {
 1356+ $changeDiv = '';
 1357+ # If the user can review then prompt them to review them...
 1358+ if ( $wgUser->isAllowed( 'review' ) ) {
 1359+ # Set a key to note that someone is viewing this
 1360+ FRUserActivity::setUserReviewingDiff(
 1361+ $wgUser, $oldRev->getId(), $newRev->getId() );
 1362+ // Reviewer just edited...
 1363+ if ( $wgRequest->getInt( 'shownotice' )
 1364+ && $newRev->isCurrent()
 1365+ && $newRev->getRawUserText() == $wgUser->getName() )
 1366+ {
 1367+ $title = $this->article->getTitle(); // convenience
 1368+ // @TODO: make diff class cache this
 1369+ $n = $title->countRevisionsBetween( $oldRev, $newRev );
 1370+ if ( $n ) {
 1371+ $msg = 'revreview-update-edited-prev'; // previous pending edits
 1372+ } else {
 1373+ $msg = 'revreview-update-edited'; // just couldn't autoreview
 1374+ }
 1375+ // All other cases...
 1376+ } else {
 1377+ $msg = 'revreview-update'; // generic "please review" notice...
 1378+ }
 1379+ $changeDiv .= wfMsgExt( $msg, 'parse' );
 1380+ }
 1381+ # Add include change list...
 1382+ if ( count( $changeList ) ) {
 1383+ $changeDiv .= '<p>' .
 1384+ wfMsgExt( 'revreview-update-includes', 'parseinline' ) .
 1385+ '&#160;' . implode( ', ', $changeList ) . '</p>';
 1386+ # Add include usage notice...
 1387+ if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE ) {
 1388+ $changeDiv .= wfMsgExt( 'revreview-update-use', 'parse' );
 1389+ }
 1390+ }
 1391+ }
 1392+ if ( $changeDiv != '' ) {
 1393+ if ( $wgUser->isAllowed( 'review' ) ) {
 1394+ $this->diffNoticeBox = $changeDiv; // add as part of form
 1395+ } else {
 1396+ $css = 'flaggedrevs_diffnotice plainlinks';
 1397+ $wgOut->addHTML(
 1398+ "<div id='mw-fr-difftostable' class='$css'>$changeDiv</div>\n"
 1399+ );
 1400+ }
 1401+ }
 1402+ }
 1403+ # Add a link to diff from stable to current as needed.
 1404+ # Show review status of the diff revision(s). Uses a <table>.
 1405+ $wgOut->addHTML(
 1406+ '<div id="mw-fr-diff-headeritems">' .
 1407+ self::diffLinkAndMarkers( $this->article, $oldRev, $newRev ) .
 1408+ '</div>'
 1409+ );
 1410+ return true;
 1411+ }
 1412+
 1413+ // get new diff header items for in-place AJAX page review
 1414+ public static function AjaxBuildDiffHeaderItems() {
 1415+ $args = func_get_args(); // <oldid, newid>
 1416+ if ( count( $args ) >= 2 ) {
 1417+ $oldid = (int)$args[0];
 1418+ $newid = (int)$args[1];
 1419+ $oldRev = Revision::newFromId( $oldid );
 1420+ $newRev = Revision::newFromId( $newid );
 1421+ if ( $newRev && $newRev->getTitle() ) {
 1422+ $fa = FlaggedPage::getTitleInstance( $newRev->getTitle() );
 1423+ return self::diffLinkAndMarkers( $fa, $oldRev, $newRev );
 1424+ }
 1425+ }
 1426+ return '';
 1427+ }
 1428+
 1429+ /**
 1430+ * (a) Add a link to diff from stable to current as needed
 1431+ * (b) Show review status of the diff revision(s). Uses a <table>.
 1432+ * Note: used by ajax function to rebuild diff page
 1433+ */
 1434+ public static function diffLinkAndMarkers( FlaggedPage $article, $oldRev, $newRev ) {
 1435+ $s = '<form id="mw-fr-diff-dataform">';
 1436+ $s .= Html::hidden( 'oldid', $oldRev ? $oldRev->getId() : 0 );
 1437+ $s .= Html::hidden( 'newid', $newRev ? $newRev->getId() : 0 );
 1438+ $s .= "</form>\n";
 1439+ if ( $newRev ) { // sanity check
 1440+ $s .= self::diffToStableLink( $article, $oldRev, $newRev );
 1441+ $s .= self::diffReviewMarkers( $article, $oldRev, $newRev );
 1442+ }
 1443+ return $s;
 1444+ }
 1445+
 1446+ /**
 1447+ * Add a link to diff-to-stable for reviewable pages
 1448+ */
 1449+ protected static function diffToStableLink(
 1450+ FlaggedPage $article, $oldRev, Revision $newRev
 1451+ ) {
 1452+ global $wgUser;
 1453+ $srev = $article->getStableRev();
 1454+ if ( !$srev ) {
 1455+ return ''; // nothing to do
 1456+ }
 1457+ $review = '';
 1458+ # Is this already the full diff-to-stable?
 1459+ $fullStableDiff = $newRev->isCurrent()
 1460+ && self::isDiffToStable( $srev, $oldRev, $newRev );
 1461+ # Make a link to the full diff-to-stable if:
 1462+ # (a) Actual revs are pending and (b) We are not viewing the full diff-to-stable
 1463+ if ( $article->revsArePending() && !$fullStableDiff ) {
 1464+ $review = $wgUser->getSkin()->makeKnownLinkObj(
 1465+ $article->getTitle(),
 1466+ wfMsgHtml( 'review-diff2stable' ),
 1467+ 'oldid=' . $srev->getRevId() . '&diff=cur&diffonly=0'
 1468+ );
 1469+ $review = wfMsgHtml( 'parentheses', $review );
 1470+ $review = "<div class='fr-diff-to-stable' align='center'>$review</div>";
 1471+ }
 1472+ return $review;
 1473+ }
 1474+
 1475+ /**
 1476+ * Add [checked version] and such to left and right side of diff
 1477+ */
 1478+ protected static function diffReviewMarkers( FlaggedPage $article, $oldRev, $newRev ) {
 1479+ $table = '';
 1480+ $srev = $article->getStableRev();
 1481+ # Diff between two revisions
 1482+ if ( $oldRev && $newRev ) {
 1483+ list( $msg, $class ) = self::getDiffRevMsgAndClass( $oldRev, $srev );
 1484+ $table .= "<table class='fr-diff-ratings'><tr>";
 1485+ $table .= "<td width='50%' align='center'>";
 1486+ $table .= "<span class='$class'>[" .
 1487+ wfMsgHtml( $msg ) . "]</span>";
 1488+
 1489+ list( $msg, $class ) = self::getDiffRevMsgAndClass( $newRev, $srev );
 1490+ $table .= "</td><td width='50%' align='center'>";
 1491+ $table .= "<span class='$class'>[" .
 1492+ wfMsgHtml( $msg ) . "]</span>";
 1493+
 1494+ $table .= "</td></tr></table>\n";
 1495+ # New page "diffs" - just one rev
 1496+ } elseif ( $newRev ) {
 1497+ list( $msg, $class ) = self::getDiffRevMsgAndClass( $newRev, $srev );
 1498+ $table .= "<table class='fr-diff-ratings'>";
 1499+ $table .= "<tr><td align='center'><span class='$class'>";
 1500+ $table .= '[' . wfMsgHtml( $msg ) . ']';
 1501+ $table .= "</span></td></tr></table>\n";
 1502+ }
 1503+ return $table;
 1504+ }
 1505+
 1506+ protected static function getDiffRevMsgAndClass(
 1507+ Revision $rev, FlaggedRevision $srev = null
 1508+ ) {
 1509+ $tier = FlaggedRevs::getRevQuality( $rev->getPage(), $rev->getId() );
 1510+ if ( $tier !== false ) {
 1511+ $msg = $tier
 1512+ ? 'revreview-hist-quality'
 1513+ : 'revreview-hist-basic';
 1514+ } else {
 1515+ $msg = ( $srev && $rev->getTimestamp() > $srev->getRevTimestamp() ) // bug 15515
 1516+ ? 'revreview-hist-pending'
 1517+ : 'revreview-hist-draft';
 1518+ }
 1519+ $css = FlaggedRevsXML::getQualityColor( $tier );
 1520+ return array( $msg, $css );
 1521+ }
 1522+
 1523+ // Fetch template changes for a reviewed revision since review
 1524+ // @return array
 1525+ protected static function fetchTemplateChanges( FlaggedRevision $frev ) {
 1526+ global $wgUser;
 1527+ $skin = $wgUser->getSkin();
 1528+ $diffLinks = array();
 1529+ $changes = $frev->findPendingTemplateChanges();
 1530+ foreach ( $changes as $tuple ) {
 1531+ list( $title, $revIdStable ) = $tuple;
 1532+ $diffLinks[] = $skin->makeLinkObj( $title,
 1533+ $title->getPrefixedText(),
 1534+ 'diff=cur&oldid=' . (int)$revIdStable );
 1535+ }
 1536+ return $diffLinks;
 1537+ }
 1538+
 1539+ // Fetch file changes for a reviewed revision since review
 1540+ // @return array
 1541+ protected static function fetchFileChanges( FlaggedRevision $frev ) {
 1542+ global $wgUser;
 1543+ $skin = $wgUser->getSkin();
 1544+ $diffLinks = array();
 1545+ $changes = $frev->findPendingFileChanges( 'noForeign' );
 1546+ foreach ( $changes as $tuple ) {
 1547+ list( $title, $revIdStable ) = $tuple;
 1548+ // @TODO: change when MW has file diffs
 1549+ $diffLinks[] = $skin->makeLinkObj( $title, $title->getPrefixedText() );
 1550+ }
 1551+ return $diffLinks;
 1552+ }
 1553+
 1554+ /**
 1555+ * Set $this->isDiffFromStable and $this->isMultiPageDiff fields
 1556+ * Note: $oldRev could be false
 1557+ */
 1558+ public function setViewFlags( $diff, $oldRev, $newRev ) {
 1559+ $this->load();
 1560+ // We only want valid diffs that actually make sense...
 1561+ if ( $newRev && $oldRev && $newRev->getTimestamp() >= $oldRev->getTimestamp() ) {
 1562+ // Is this a diff between two pages?
 1563+ if ( $newRev->getPage() != $oldRev->getPage() ) {
 1564+ $this->isMultiPageDiff = true;
 1565+ // Is there a stable version?
 1566+ } elseif ( $this->article->isReviewable() ) {
 1567+ $srev = $this->article->getStableRev();
 1568+ // Is this a diff of a draft rev against the stable rev?
 1569+ if ( self::isDiffToStable( $srev, $oldRev, $newRev ) ) {
 1570+ $this->isDiffFromStable = true;
 1571+ $this->isReviewableDiff = true;
 1572+ // Is this a diff of a draft rev against a reviewed rev?
 1573+ } elseif (
 1574+ FlaggedRevision::newFromTitle( $diff->getTitle(), $oldRev->getId() ) ||
 1575+ FlaggedRevision::newFromTitle( $diff->getTitle(), $newRev->getId() )
 1576+ ) {
 1577+ $this->isReviewableDiff = true;
 1578+ }
 1579+ }
 1580+ $this->diffRevs = array( 'old' => $oldRev, 'new' => $newRev );
 1581+ }
 1582+ return true;
 1583+ }
 1584+
 1585+ // Is a diff from $oldRev to $newRev a diff-to-stable?
 1586+ protected static function isDiffToStable( $srev, $oldRev, $newRev ) {
 1587+ return ( $srev && $oldRev && $newRev
 1588+ && $oldRev->getPage() == $newRev->getPage() // no multipage diffs
 1589+ && $oldRev->getId() == $srev->getRevId()
 1590+ && $newRev->getTimestamp() >= $oldRev->getTimestamp() // no backwards diffs
 1591+ );
 1592+ }
 1593+
 1594+ /**
 1595+ * Redirect users out to review the changes to the stable version.
 1596+ * Only for people who can review and for pages that have a stable version.
 1597+ */
 1598+ public function injectPostEditURLParams( &$sectionAnchor, &$extraQuery ) {
 1599+ global $wgUser;
 1600+ $this->load();
 1601+ $this->article->loadFromDB( FR_MASTER );
 1602+ # Get the stable version from the master
 1603+ $frev = $this->article->getStableRev();
 1604+ if ( !$frev || !$this->article->revsArePending() ) {
 1605+ return true; // only for pages with pending edits
 1606+ }
 1607+ // If the edit was not autoreviewed, and the user can actually make a
 1608+ // new stable version, then go to the diff...
 1609+ if ( $frev->userCanSetFlags( $wgUser ) ) {
 1610+ $extraQuery .= $extraQuery ? '&' : '';
 1611+ // Override diffonly setting to make sure the content is shown
 1612+ $extraQuery .= 'oldid=' . $frev->getRevId() . '&diff=cur&diffonly=0&shownotice=1';
 1613+ // ...otherwise, go to the draft revision after completing an edit.
 1614+ // This allows for users to immediately see their changes.
 1615+ } else {
 1616+ $extraQuery .= $extraQuery ? '&' : '';
 1617+ $extraQuery .= 'stable=0';
 1618+ // Show a notice at the top of the page for non-reviewers...
 1619+ if ( !$wgUser->isAllowed( 'review' ) && $this->article->isStableShownByDefault() ) {
 1620+ $extraQuery .= '&shownotice=1';
 1621+ if ( $sectionAnchor ) {
 1622+ // Pass a section parameter in the URL as needed to add a link to
 1623+ // the "your changes are pending" box on the top of the page...
 1624+ $section = str_replace(
 1625+ array( ':' , '.' ), array( '%3A', '%' ), // hack: reverse encoding
 1626+ substr( $sectionAnchor, 1 ) // remove the '#'
 1627+ );
 1628+ $extraQuery .= '&fromsection=' . $section;
 1629+ $sectionAnchor = ''; // go to the top of the page to see notice
 1630+ }
 1631+ }
 1632+ }
 1633+ return true;
 1634+ }
 1635+
 1636+ /**
 1637+ * If submitting the edit will leave it pending, then change the button text
 1638+ * Note: interacts with 'review pending changes' checkbox
 1639+ * @TODO: would be nice if hook passed in button attribs, not XML
 1640+ */
 1641+ public function changeSaveButton( EditPage $editPage, array &$buttons ) {
 1642+ if ( !$this->editWillRequireReview( $editPage ) ) {
 1643+ return true; // edit will go live or be reviewed on save
 1644+ }
 1645+ if ( extension_loaded( 'domxml' ) ) {
 1646+ wfDebug( "Warning: you have the obsolete domxml extension for PHP. Please remove it!\n" );
 1647+ return true; # PECL extension conflicts with the core DOM extension (see bug 13770)
 1648+ } elseif ( isset( $buttons['save'] ) && extension_loaded( 'dom' ) ) {
 1649+ $dom = new DOMDocument();
 1650+ $dom->loadXML( $buttons['save'] ); // load button XML from hook
 1651+ foreach ( $dom->getElementsByTagName( 'input' ) as $input ) { // one <input>
 1652+ $input->setAttribute( 'value', wfMsg( 'revreview-submitedit' ) );
 1653+ $input->setAttribute( 'title', // keep accesskey
 1654+ wfMsgExt( 'revreview-submitedit-title', 'parsemag' ) .
 1655+ ' [' . wfMsg( 'accesskey-save' ) . ']' );
 1656+ # Change submit button text & title
 1657+ $buttons['save'] = $dom->saveXML( $dom->documentElement );
 1658+ }
 1659+ }
 1660+ return true;
 1661+ }
 1662+
 1663+ /**
 1664+ * If this edit will not go live on submit (accounting for wpReviewEdit)
 1665+ * @param EditPage $editPage
 1666+ * @return bool
 1667+ */
 1668+ protected function editWillRequireReview( EditPage $editPage ) {
 1669+ global $wgRequest;
 1670+ $title = $this->article->getTitle(); // convenience
 1671+ if ( !$this->editRequiresReview( $editPage ) ) {
 1672+ return false; // edit will go live immediatly
 1673+ } elseif ( $wgRequest->getCheck( 'wpReviewEdit' ) && $title->userCan( 'review' ) ) {
 1674+ return false; // edit checked off to be reviewed on save
 1675+ }
 1676+ return true; // edit needs review
 1677+ }
 1678+
 1679+ /**
 1680+ * If this edit will not go live on submit unless wpReviewEdit is checked
 1681+ * @param EditPage $editPage
 1682+ * @return bool
 1683+ */
 1684+ protected function editRequiresReview( EditPage $editPage ) {
 1685+ if ( !$this->article->editsRequireReview() ) {
 1686+ return false; // edits go live immediatly
 1687+ } elseif ( $this->editWillBeAutoreviewed( $editPage ) ) {
 1688+ return false; // edit will be autoreviewed anyway
 1689+ }
 1690+ return true; // edit needs review
 1691+ }
 1692+
 1693+ /**
 1694+ * If this edit will be auto-reviewed on submit
 1695+ * Note: checking wpReviewEdit does not count as auto-reviewed
 1696+ * @param EditPage $editPage
 1697+ * @return bool
 1698+ */
 1699+ protected function editWillBeAutoreviewed( EditPage $editPage ) {
 1700+ $title = $this->article->getTitle(); // convenience
 1701+ if ( !$this->article->isReviewable() ) {
 1702+ return false;
 1703+ }
 1704+ if ( $title->userCan( 'autoreview' ) ) {
 1705+ if ( FlaggedRevs::autoReviewNewPages() && !$this->article->exists() ) {
 1706+ return true; // edit will be autoreviewed
 1707+ }
 1708+ if ( !isset( $editPage->fr_baseFRev ) ) {
 1709+ $baseRevId = self::getBaseRevId( $editPage );
 1710+ $editPage->fr_baseFRev = FlaggedRevision::newFromTitle( $title, $baseRevId );
 1711+ }
 1712+ if ( $editPage->fr_baseFRev ) {
 1713+ return true; // edit will be autoreviewed
 1714+ }
 1715+ }
 1716+ return false; // edit won't be autoreviewed
 1717+ }
 1718+
 1719+ /**
 1720+ * Add a "review pending changes" checkbox to the edit form iff:
 1721+ * (a) there are currently any revisions pending (bug 16713)
 1722+ * (b) this is an unreviewed page (bug 23970)
 1723+ */
 1724+ public function addReviewCheck( EditPage $editPage, array &$checkboxes, &$tabindex ) {
 1725+ global $wgRequest;
 1726+ $title = $this->article->getTitle(); // convenience
 1727+ if ( !$this->article->isReviewable() || !$title->userCan( 'review' ) ) {
 1728+ return true; // not needed
 1729+ } elseif ( $this->editWillBeAutoreviewed( $editPage ) ) {
 1730+ return true; // edit will be auto-reviewed
 1731+ }
 1732+ if ( self::getBaseRevId( $editPage ) == $this->article->getLatest() ) {
 1733+ # For pages with either no stable version, or an outdated one, let
 1734+ # the user decide if he/she wants it reviewed on the spot. One might
 1735+ # do this if he/she just saw the diff-to-stable and *then* decided to edit.
 1736+ # Note: check not shown when editing old revisions, which is confusing.
 1737+ $checkbox = Xml::check(
 1738+ 'wpReviewEdit',
 1739+ $wgRequest->getCheck( 'wpReviewEdit' ),
 1740+ array( 'tabindex' => ++$tabindex, 'id' => 'wpReviewEdit' )
 1741+ );
 1742+ $attribs = array( 'for' => 'wpReviewEdit' );
 1743+ // For reviewed pages...
 1744+ if ( $this->article->getStable() ) {
 1745+ // For pending changes...
 1746+ if ( $this->article->revsArePending() ) {
 1747+ $n = $this->article->getPendingRevCount();
 1748+ $attribs['title'] = wfMsg( 'revreview-check-flag-p-title' );
 1749+ $labelMsg = wfMsgExt( 'revreview-check-flag-p', 'parseinline', $n );
 1750+ // For just the user's changes...
 1751+ } else {
 1752+ $attribs['title'] = wfMsgExt( 'revreview-check-flag-y-title', 'parsemag' );
 1753+ $labelMsg = wfMsgExt( 'revreview-check-flag-y', 'parseinline' );
 1754+ }
 1755+ // For unreviewed pages...
 1756+ } else {
 1757+ $attribs['title'] = wfMsg( 'revreview-check-flag-u-title' );
 1758+ $labelMsg = wfMsgExt( 'revreview-check-flag-u', 'parseinline' );
 1759+ }
 1760+ $label = Xml::element( 'label', $attribs, $labelMsg );
 1761+ $checkboxes['reviewed'] = $checkbox . '&#160;' . $label;
 1762+ }
 1763+ return true;
 1764+ }
 1765+
 1766+ /**
 1767+ * (a) Add a hidden field that has the rev ID the text is based off.
 1768+ * (b) If an edit was undone, add a hidden field that has the rev ID of that edit.
 1769+ * Needed for autoreview and user stats (for autopromote).
 1770+ * Note: baseRevId trusted for Reviewers - text checked for others.
 1771+ */
 1772+ public function addRevisionIDField( EditPage $editPage, OutputPage $out ) {
 1773+ $this->load();
 1774+ $revId = self::getBaseRevId( $editPage );
 1775+ $out->addHTML( "\n" . Html::hidden( 'baseRevId', $revId ) );
 1776+ $out->addHTML( "\n" . Html::hidden( 'undidRev',
 1777+ empty( $editPage->undidRev ) ? 0 : $editPage->undidRev )
 1778+ );
 1779+ return true;
 1780+ }
 1781+
 1782+ /**
 1783+ * Guess the rev ID the text of this form is based off
 1784+ * Note: baseRevId trusted for Reviewers - check text for others.
 1785+ * @return int
 1786+ */
 1787+ protected static function getBaseRevId( EditPage $editPage ) {
 1788+ global $wgRequest;
 1789+ if ( !isset( $editPage->fr_baseRevId ) ) {
 1790+ $article = $editPage->getArticle(); // convenience
 1791+ $latestId = $article->getLatest(); // current rev
 1792+ $undo = $wgRequest->getIntOrNull( 'undo' );
 1793+ # Undoing consecutive top edits...
 1794+ if ( $undo && $undo === $latestId ) {
 1795+ # Treat this like a revert to a base revision.
 1796+ # We are undoing all edits *after* some rev ID (undoafter).
 1797+ # If undoafter is not given, then it is the previous rev ID.
 1798+ $revId = $wgRequest->getInt( 'undoafter',
 1799+ $article->getTitle()->getPreviousRevisionID( $latestId, Title::GAID_FOR_UPDATE ) );
 1800+ # Undoing other edits...
 1801+ } elseif ( $undo ) {
 1802+ $revId = $latestId; // current rev is the base rev
 1803+ # Other edits...
 1804+ } else {
 1805+ # If we are editing via oldid=X, then use that rev ID.
 1806+ # Otherwise, check if the client specified the ID (bug 23098).
 1807+ $revId = $article->getOldID()
 1808+ ? $article->getOldID()
 1809+ : $wgRequest->getInt( 'baseRevId' ); // e.g. "show changes"/"preview"
 1810+ }
 1811+ # Zero oldid => draft revision
 1812+ if ( !$revId ) {
 1813+ $revId = $latestId;
 1814+ }
 1815+ $editPage->fr_baseRevId = $revId;
 1816+ }
 1817+ return $editPage->fr_baseRevId;
 1818+ }
 1819+
 1820+ /**
 1821+ * Adds brief review notes to a page.
 1822+ * @param OutputPage $out
 1823+ */
 1824+ public function addReviewNotes( &$data ) {
 1825+ $this->load();
 1826+ if ( $this->reviewNotes ) {
 1827+ $data .= $this->reviewNotes;
 1828+ }
 1829+ return true;
 1830+ }
 1831+
 1832+ /*
 1833+ * If this is a diff page then replace the article contents with a link
 1834+ * to the specific revision. This will be replaced with article content
 1835+ * using javascript and an api call.
 1836+ */
 1837+ public function addCustomContentHtml( OutputPage $out, $newRevId ) {
 1838+ $this->load();
 1839+ if ( $newRevId ) {
 1840+ $out->addHTML( "<div id='mw-fr-revisioncontents'><span class='plainlinks'>" );
 1841+ $out->addWikiMsg( 'revcontents-getcontents',
 1842+ $this->article->getTitle()->getPrefixedDBKey(), $newRevId );
 1843+ $out->addHTML( "</span></div>" );
 1844+ }
 1845+ }
 1846+}
Property changes on: trunk/extensions/FlaggedRevs/presentation/FlaggedPageView.php
___________________________________________________________________
Added: svn:eol-style
11847 + native
Index: trunk/extensions/FlaggedRevs/presentation/modules/review.js
@@ -265,7 +265,7 @@
266266 requestArgs.push( diffUIParams.getElementsByTagName('input')[0].value );
267267 requestArgs.push( diffUIParams.getElementsByTagName('input')[1].value );
268268 // Send encoded function plus all arguments...
269 - url_pars = '?action=ajax&rs=FlaggedArticleView::AjaxBuildDiffHeaderItems';
 269+ url_pars = '?action=ajax&rs=FlaggedPageView::AjaxBuildDiffHeaderItems';
270270 for( var i=0; i<requestArgs.length; i++ ) {
271271 url_pars += '&rsargs[]=' + encodeURIComponent(requestArgs[i]);
272272 }
Index: trunk/extensions/FlaggedRevs/presentation/FlaggedRevsLogView.php
@@ -3,7 +3,7 @@
44 class FlaggedRevsLogView {
55 /**
66 * Add setting change description to log line
7 - * @returns string
 7+ * @return string
88 */
99 public static function stabilityLogText(
1010 $type, $action, $title = null, $skin = null, $params = array()
@@ -31,7 +31,7 @@
3232 * @param Title $title
3333 * @param string $timestamp
3434 * @param array $params
35 - * @returns string
 35+ * @return string
3636 */
3737 public static function stabilityLogLinks( $title, $timestamp, $params ) {
3838 global $wgUser;
@@ -51,9 +51,9 @@
5252 *
5353 * @param array $pars assoc array
5454 * @param bool $forContent
55 - * @returns string
 55+ * @return string
5656 */
57 - public static function stabilitySettings( Array $pars, $forContent ) {
 57+ public static function stabilitySettings( array $pars, $forContent ) {
5858 global $wgLang, $wgContLang;
5959 $set = array();
6060 $settings = '';
Index: trunk/extensions/FlaggedRevs/FlaggedPage.php
@@ -0,0 +1,541 @@
 2+<?php
 3+/**
 4+ * Class representing a MediaWiki article and history
 5+ *
 6+ * FlaggedPage::getTitleInstance() is preferred over constructor calls
 7+ */
 8+class FlaggedPage extends Article {
 9+ /* Process cache variables */
 10+ protected $stable = 0;
 11+ protected $stableRev = null;
 12+ protected $revsArePending = null;
 13+ protected $pendingRevCount = null;
 14+ protected $pageConfig = null;
 15+ protected $syncedInTracking = null;
 16+
 17+ protected $imagePage = null; // for file pages
 18+
 19+ /**
 20+ * Get a FlaggedPage for a given title
 21+ * @param Title
 22+ * @return FlaggedPage
 23+ */
 24+ public static function getTitleInstance( Title $title ) {
 25+ // Check if there is already an instance on this title
 26+ if ( !isset( $title->flaggedRevsArticle ) ) {
 27+ $title->flaggedRevsArticle = new self( $title );
 28+ }
 29+ return $title->flaggedRevsArticle;
 30+ }
 31+
 32+ /**
 33+ * Get a FlaggedPage for a given article
 34+ * @param Article
 35+ * @return FlaggedPage
 36+ */
 37+ public static function getArticleInstance( Article $article ) {
 38+ return self::getTitleInstance( $article->mTitle );
 39+ }
 40+
 41+ /**
 42+ * Clear object process cache values
 43+ * @return void
 44+ */
 45+ public function clear() {
 46+ $this->stable = 0;
 47+ $this->stableRev = null;
 48+ $this->revsArePending = null;
 49+ $this->pendingRevCount = null;
 50+ $this->pageConfig = null;
 51+ $this->syncedInTracking = null;
 52+ $this->imagePage = null;
 53+ parent::clear(); // call super!
 54+ }
 55+
 56+ /**
 57+ * Get the current file version of this file page
 58+ * @TODO: kind of hacky
 59+ * @return mixed (File/false)
 60+ */
 61+ public function getFile() {
 62+ if ( $this->mTitle->getNamespace() != NS_FILE ) {
 63+ return false; // not a file page
 64+ }
 65+ if ( is_null( $this->imagePage ) ) {
 66+ $this->imagePage = new ImagePage( $this->mTitle );
 67+ }
 68+ return $this->imagePage->getFile();
 69+ }
 70+
 71+ /**
 72+ * Get the displayed file version of this file page
 73+ * @TODO: kind of hacky
 74+ * @return mixed (File/false)
 75+ */
 76+ public function getDisplayedFile() {
 77+ if ( $this->mTitle->getNamespace() != NS_FILE ) {
 78+ return false; // not a file page
 79+ }
 80+ if ( is_null( $this->imagePage ) ) {
 81+ $this->imagePage = new ImagePage( $this->mTitle );
 82+ }
 83+ return $this->imagePage->getDisplayedFile();
 84+ }
 85+
 86+ /**
 87+ * Is the stable version shown by default for this page?
 88+ * @return bool
 89+ */
 90+ public function isStableShownByDefault() {
 91+ if ( !$this->isReviewable() ) {
 92+ return false; // no stable versions can exist
 93+ }
 94+ $config = $this->getStabilitySettings(); // page configuration
 95+ return (bool)$config['override'];
 96+ }
 97+
 98+ /**
 99+ * Do edits have to be reviewed before being shown by default (going live)?
 100+ * @return bool
 101+ */
 102+ public function editsRequireReview() {
 103+ return (
 104+ $this->isReviewable() && // reviewable page
 105+ $this->isStableShownByDefault() && // and stable versions override
 106+ $this->getStableRev() // and there is a stable version
 107+ );
 108+ }
 109+
 110+ /**
 111+ * Are edits to this page currently pending?
 112+ * @return bool
 113+ */
 114+ public function revsArePending() {
 115+ if ( !$this->mDataLoaded ) {
 116+ $this->loadPageData();
 117+ }
 118+ return $this->revsArePending;
 119+ }
 120+
 121+ /**
 122+ * Get number of revs since the stable revision
 123+ * Note: slower than revsArePending()
 124+ * @param int $flags FR_MASTER (be sure to use loadFromDB( FR_MASTER ) if set)
 125+ * @return int
 126+ */
 127+ public function getPendingRevCount( $flags = 0 ) {
 128+ global $wgMemc, $wgParserCacheExpireTime;
 129+ if ( !$this->mDataLoaded ) {
 130+ $this->loadPageData();
 131+ }
 132+ # Pending count deferred even after page data load
 133+ if ( $this->pendingRevCount !== null ) {
 134+ return $this->pendingRevCount; // use process cache
 135+ }
 136+ $srev = $this->getStableRev();
 137+ if ( !$srev ) {
 138+ return 0; // none
 139+ }
 140+ $count = null;
 141+ $sRevId = $srev->getRevId();
 142+ # Try the cache...
 143+ $key = wfMemcKey( 'flaggedrevs', 'countPending', $this->getId() );
 144+ if ( !( $flags & FR_MASTER ) ) {
 145+ $tuple = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $this );
 146+ # Items is cached and newer that page_touched...
 147+ if ( $tuple !== false ) {
 148+ # Confirm that cache value was made against the same stable rev Id.
 149+ # This avoids lengthy cache pollution if $sRevId is outdated.
 150+ list( $cRevId, $cPending ) = explode( '-', $tuple, 2 );
 151+ if ( $cRevId == $sRevId ) {
 152+ $count = (int)$cPending;
 153+ }
 154+ }
 155+ }
 156+ # Otherwise, fetch result from DB as needed...
 157+ if ( is_null( $count ) ) {
 158+ $db = ( $flags & FR_MASTER ) ?
 159+ wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
 160+ $srevTS = $db->timestamp( $srev->getRevTimestamp() );
 161+ $count = $db->selectField( 'revision', 'COUNT(*)',
 162+ array( 'rev_page' => $this->getId(),
 163+ 'rev_timestamp > ' . $db->addQuotes( $srevTS ) ), // bug 15515
 164+ __METHOD__ );
 165+ # Save result to cache...
 166+ $data = FlaggedRevs::makeMemcObj( "{$sRevId}-{$count}" );
 167+ $wgMemc->set( $key, $data, $wgParserCacheExpireTime );
 168+ }
 169+ $this->pendingRevCount = $count;
 170+ return $this->pendingRevCount;
 171+ }
 172+
 173+ /**
 174+ * Checks if the stable version is synced with the current revision
 175+ * Note: slower than getPendingRevCount()
 176+ * @return bool
 177+ */
 178+ public function stableVersionIsSynced() {
 179+ global $wgMemc, $wgParserCacheExpireTime;
 180+ $srev = $this->getStableRev();
 181+ if ( !$srev ) {
 182+ return true;
 183+ }
 184+ # Stable text revision must be the same as the current
 185+ if ( $this->revsArePending() ) {
 186+ return false;
 187+ # Stable file revision must be the same as the current
 188+ } elseif ( $this->mTitle->getNamespace() == NS_FILE ) {
 189+ $file = $this->getFile(); // current upload version
 190+ if ( $file && $file->getTimestamp() > $srev->getFileTimestamp() ) {
 191+ return false;
 192+ }
 193+ }
 194+ # If using the current version of includes, there is nothing else to check.
 195+ if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_CURRENT ) {
 196+ return true; // short-circuit
 197+ }
 198+ # Try the cache...
 199+ $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $this->getId() );
 200+ $value = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $this );
 201+ if ( $value === "true" ) {
 202+ return true;
 203+ } elseif ( $value === "false" ) {
 204+ return false;
 205+ }
 206+ # Since the stable and current revisions have the same text and only outputs,
 207+ # the only other things to check for are template and file differences in the output.
 208+ # (a) Check if the current output has a newer template/file used
 209+ # (b) Check if the stable version has a file/template that was deleted
 210+ $synced = ( !$srev->findPendingTemplateChanges()
 211+ && !$srev->findPendingFileChanges( 'noForeign' ) );
 212+ # Save to cache. This will be updated whenever the page is touched.
 213+ $data = FlaggedRevs::makeMemcObj( $synced ? "true" : "false" );
 214+ $wgMemc->set( $key, $data, $wgParserCacheExpireTime );
 215+
 216+ return $synced;
 217+ }
 218+
 219+ /**
 220+ * Are template/file changes and ONLY template/file changes pending?
 221+ * @return bool
 222+ */
 223+ public function onlyTemplatesOrFilesPending() {
 224+ return ( !$this->revsArePending() && !$this->stableVersionIsSynced() );
 225+ }
 226+
 227+ /**
 228+ * Is this page less open than the site defaults?
 229+ * @return bool
 230+ */
 231+ public function isPageLocked() {
 232+ return ( !FlaggedRevs::isStableShownByDefault() && $this->isStableShownByDefault() );
 233+ }
 234+
 235+ /**
 236+ * Is this page more open than the site defaults?
 237+ * @return bool
 238+ */
 239+ public function isPageUnlocked() {
 240+ return ( FlaggedRevs::isStableShownByDefault() && !$this->isStableShownByDefault() );
 241+ }
 242+
 243+ /**
 244+ * Tags are only shown for unreviewed content and this page is not locked/unlocked?
 245+ * @return bool
 246+ */
 247+ public function lowProfileUI() {
 248+ return FlaggedRevs::lowProfileUI() &&
 249+ FlaggedRevs::isStableShownByDefault() == $this->isStableShownByDefault();
 250+ }
 251+
 252+ /**
 253+ * Is this article reviewable?
 254+ * @return bool
 255+ */
 256+ public function isReviewable() {
 257+ if ( !FlaggedRevs::inReviewNamespace( $this->mTitle ) ) {
 258+ return false;
 259+ }
 260+ # Check if flagging is disabled for this page via config
 261+ if ( FlaggedRevs::useOnlyIfProtected() ) {
 262+ $config = $this->getStabilitySettings(); // page configuration
 263+ return (bool)$config['override']; // stable is default or flagging disabled
 264+ }
 265+ return true;
 266+ }
 267+
 268+ /**
 269+ * Is this page in patrollable?
 270+ * @return bool
 271+ */
 272+ public function isPatrollable() {
 273+ if ( !FlaggedRevs::inPatrolNamespace( $this->mTitle ) ) {
 274+ return false;
 275+ }
 276+ return !$this->isReviewable(); // pages that are reviewable are not patrollable
 277+ }
 278+
 279+ /**
 280+ * Get the stable revision ID
 281+ * @return int
 282+ */
 283+ public function getStable() {
 284+ if ( !$this->mDataLoaded ) {
 285+ $this->loadPageData();
 286+ }
 287+ return (int)$this->stable;
 288+ }
 289+
 290+ /**
 291+ * Get the stable revision
 292+ * @return mixed (FlaggedRevision/null)
 293+ */
 294+ public function getStableRev() {
 295+ if ( !$this->mDataLoaded ) {
 296+ $this->loadPageData();
 297+ }
 298+ # Stable rev deferred even after page data load
 299+ if ( $this->stableRev === null ) {
 300+ $srev = FlaggedRevision::newFromTitle( $this->mTitle, $this->stable );
 301+ $this->stableRev = $srev ? $srev : false; // cache negative hits too
 302+ }
 303+ return $this->stableRev ? $this->stableRev : null; // false => null
 304+ }
 305+
 306+ /**
 307+ * Get visiblity restrictions on page
 308+ * @return array (select,override)
 309+ */
 310+ public function getStabilitySettings() {
 311+ if ( !$this->mDataLoaded ) {
 312+ $this->loadPageData();
 313+ }
 314+ return $this->pageConfig;
 315+ }
 316+
 317+ /*
 318+ * Get the fp_reviewed value for this page
 319+ * @return bool
 320+ */
 321+ public function syncedInTracking() {
 322+ if ( !$this->mDataLoaded ) {
 323+ $this->loadPageData();
 324+ }
 325+ return $this->syncedInTracking;
 326+ }
 327+
 328+ /**
 329+ * Fetch a page record with the given conditions
 330+ * @param $dbr Database object
 331+ * @param $conditions Array
 332+ * @return mixed Database result resource, or false on failure
 333+ */
 334+ protected function pageData( $dbr, $conditions ) {
 335+ $row = $dbr->selectRow(
 336+ array( 'page', 'flaggedpages', 'flaggedpage_config' ),
 337+ array_merge(
 338+ Article::selectFields(),
 339+ FlaggedPageConfig::selectFields(),
 340+ array( 'fp_pending_since', 'fp_stable', 'fp_reviewed' ) ),
 341+ $conditions,
 342+ __METHOD__,
 343+ array(),
 344+ array(
 345+ 'flaggedpages' => array( 'LEFT JOIN', 'fp_page_id = page_id' ),
 346+ 'flaggedpage_config' => array( 'LEFT JOIN', 'fpc_page_id = page_id' ) )
 347+ );
 348+ return $row;
 349+ }
 350+
 351+ /**
 352+ * Set the page field data loaded from some source
 353+ * @param $data Database row object or "fromdb"
 354+ * @return void
 355+ */
 356+ public function loadPageData( $data = 'fromdb' ) {
 357+ $this->mDataLoaded = true; // sanity
 358+ # Fetch data from DB as needed...
 359+ if ( $data === 'fromdb' ) {
 360+ $data = $this->pageDataFromTitle( wfGetDB( DB_SLAVE ), $this->mTitle );
 361+ }
 362+ # Load in primary page data...
 363+ parent::loadPageData( $data /* Row obj */ );
 364+ # Load in FlaggedRevs page data...
 365+ $this->stable = 0; // 0 => "found nothing"
 366+ $this->stableRev = null; // defer this one...
 367+ $this->revsArePending = false; // false => "found nothing" or "none pending"
 368+ $this->pendingRevCount = null; // defer this one...
 369+ $this->pageConfig = FlaggedPageConfig::getDefaultVisibilitySettings(); // default
 370+ $this->syncedInTracking = true; // false => "unreviewed" or "synced"
 371+ # Load in Row data if the page exists...
 372+ if ( $data ) {
 373+ if ( $data->fpc_override !== null ) { // page config row found
 374+ $this->pageConfig = FlaggedPageConfig::getVisibilitySettingsFromRow( $data );
 375+ }
 376+ if ( $data->fp_stable !== null ) { // stable rev found
 377+ $this->stable = (int)$data->fp_stable;
 378+ $this->revsArePending = ( $data->fp_pending_since !== null ); // revs await review
 379+ $this->syncedInTracking = (bool)$data->fp_reviewed;
 380+ }
 381+ }
 382+ }
 383+
 384+ /**
 385+ * Set the page field data loaded from the DB
 386+ * @param int $flags FR_MASTER
 387+ * @param $data Database row object or "fromdb"
 388+ */
 389+ public function loadFromDB( $flags = 0 ) {
 390+ $db = ( $flags & FR_MASTER ) ?
 391+ wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
 392+ $this->loadPageData( $this->pageDataFromTitle( $db, $this->mTitle ) );
 393+ }
 394+
 395+ /**
 396+ * Updates the flagging tracking tables for this page
 397+ * @param FlaggedRevision $srev The new stable version
 398+ * @param int|null $latest The latest rev ID (optional)
 399+ * @return bool Updates were done
 400+ */
 401+ public function updateStableVersion( FlaggedRevision $srev, $latest = null ) {
 402+ $rev = $srev->getRevision();
 403+ if ( !$this->exists() || !$rev ) {
 404+ return false; // no bogus entries
 405+ }
 406+ # Get the latest revision ID if not set
 407+ if ( !$latest ) {
 408+ $latest = $this->mTitle->getLatestRevID( Title::GAID_FOR_UPDATE );
 409+ }
 410+ $dbw = wfGetDB( DB_MASTER );
 411+ # Get the highest quality revision (not necessarily this one)...
 412+ if ( $srev->getQuality() === FlaggedRevs::highestReviewTier() ) {
 413+ $maxQuality = $srev->getQuality(); // save a query
 414+ } else {
 415+ $maxQuality = $dbw->selectField( array( 'flaggedrevs', 'revision' ),
 416+ 'fr_quality',
 417+ array( 'fr_page_id' => $this->getId(),
 418+ 'rev_id = fr_rev_id',
 419+ 'rev_page = fr_page_id',
 420+ 'rev_deleted & ' . Revision::DELETED_TEXT => 0
 421+ ),
 422+ __METHOD__,
 423+ array( 'ORDER BY' => 'fr_quality DESC', 'LIMIT' => 1 )
 424+ );
 425+ $maxQuality = max( $maxQuality, $srev->getQuality() ); // sanity
 426+ }
 427+ # Get the timestamp of the first edit after the stable version (if any)...
 428+ $nextTimestamp = null;
 429+ if ( $rev->getId() != $latest ) {
 430+ $timestamp = $dbw->timestamp( $rev->getTimestamp() );
 431+ $nextEditTS = $dbw->selectField( 'revision',
 432+ 'rev_timestamp',
 433+ array(
 434+ 'rev_page' => $this->getId(),
 435+ "rev_timestamp > " . $dbw->addQuotes( $timestamp ) ),
 436+ __METHOD__,
 437+ array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1 )
 438+ );
 439+ if ( $nextEditTS ) { // sanity check
 440+ $nextTimestamp = $nextEditTS;
 441+ }
 442+ }
 443+ # Get the new page sync status...
 444+ $synced = !(
 445+ $nextTimestamp !== null || // edits pending
 446+ $srev->findPendingTemplateChanges() || // template changes pending
 447+ $srev->findPendingFileChanges( 'noForeign' ) // file changes pending
 448+ );
 449+ # Alter table metadata
 450+ $dbw->replace( 'flaggedpages',
 451+ array( 'fp_page_id' ),
 452+ array(
 453+ 'fp_page_id' => $this->getId(),
 454+ 'fp_stable' => $rev->getId(),
 455+ 'fp_reviewed' => $synced ? 1 : 0,
 456+ 'fp_quality' => ( $maxQuality === false ) ? null : $maxQuality,
 457+ 'fp_pending_since' => $dbw->timestampOrNull( $nextTimestamp )
 458+ ),
 459+ __METHOD__
 460+ );
 461+ # Update pending edit tracking table
 462+ self::updatePendingList( $this->getId(), $latest );
 463+ return true;
 464+ }
 465+
 466+ /**
 467+ * Updates the flagging tracking tables for this page
 468+ * @return void
 469+ */
 470+ public function clearStableVersion() {
 471+ if ( !$this->exists() ) {
 472+ return; // nothing to do
 473+ }
 474+ $dbw = wfGetDB( DB_MASTER );
 475+ $dbw->delete( 'flaggedpages',
 476+ array( 'fp_page_id' => $this->getId() ), __METHOD__ );
 477+ $dbw->delete( 'flaggedpage_pending',
 478+ array( 'fpp_page_id' => $this->getId() ), __METHOD__ );
 479+ }
 480+
 481+ /**
 482+ * Updates the flaggedpage_pending table
 483+ * @param int $pageId Page ID
 484+ * @abstract int $latest Latest revision
 485+ * @return void
 486+ */
 487+ protected static function updatePendingList( $pageId, $latest ) {
 488+ $data = array();
 489+ $level = FlaggedRevs::highestReviewTier();
 490+ # Update pending times for each level, going from highest to lowest
 491+ $dbw = wfGetDB( DB_MASTER );
 492+ $higherLevelId = 0;
 493+ $higherLevelTS = '';
 494+ while ( $level >= 0 ) {
 495+ # Get the latest revision of this level...
 496+ $row = $dbw->selectRow( array( 'flaggedrevs', 'revision' ),
 497+ array( 'fr_rev_id', 'rev_timestamp' ),
 498+ array( 'fr_page_id' => $pageId,
 499+ 'fr_quality' => $level,
 500+ 'rev_id = fr_rev_id',
 501+ 'rev_page = fr_page_id',
 502+ 'rev_deleted & ' . Revision::DELETED_TEXT => 0,
 503+ 'rev_id > ' . intval( $higherLevelId )
 504+ ),
 505+ __METHOD__,
 506+ array( 'ORDER BY' => 'fr_rev_id DESC', 'LIMIT' => 1 )
 507+ );
 508+ # If there is a revision of this level, track it...
 509+ # Revisions reviewed to one level count as reviewed
 510+ # at the lower levels (i.e. quality -> checked).
 511+ if ( $row ) {
 512+ $id = $row->fr_rev_id;
 513+ $ts = $row->rev_timestamp;
 514+ } else {
 515+ $id = $higherLevelId; // use previous (quality -> checked)
 516+ $ts = $higherLevelTS; // use previous (quality -> checked)
 517+ }
 518+ # Get edits that actually are pending...
 519+ if ( $id && $latest > $id ) {
 520+ # Get the timestamp of the edit after this version (if any)
 521+ $nextTimestamp = $dbw->selectField( 'revision',
 522+ 'rev_timestamp',
 523+ array( 'rev_page' => $pageId, "rev_timestamp > " . $dbw->addQuotes( $ts ) ),
 524+ __METHOD__,
 525+ array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1 )
 526+ );
 527+ $data[] = array(
 528+ 'fpp_page_id' => $pageId,
 529+ 'fpp_quality' => $level,
 530+ 'fpp_rev_id' => $id,
 531+ 'fpp_pending_since' => $nextTimestamp
 532+ );
 533+ $higherLevelId = $id;
 534+ $higherLevelTS = $ts;
 535+ }
 536+ $level--;
 537+ }
 538+ # Clear any old junk, and insert new rows
 539+ $dbw->delete( 'flaggedpage_pending', array( 'fpp_page_id' => $pageId ), __METHOD__ );
 540+ $dbw->insert( 'flaggedpage_pending', $data, __METHOD__ );
 541+ }
 542+}
Property changes on: trunk/extensions/FlaggedRevs/FlaggedPage.php
___________________________________________________________________
Added: svn:eol-style
1543 + native
Index: trunk/extensions/FlaggedRevs/FRInclusionManager.php
@@ -60,7 +60,7 @@
6161 /**
6262 * Clean up a template version array
6363 * @param array $tmpParams (ns => dbKey => revId )
64 - * @returns Array
 64+ * @return array
6565 */
6666 protected function formatTemplateArray( array $params ) {
6767 $res = array();
@@ -76,7 +76,7 @@
7777 /**
7878 * Clean up a file version array
7979 * @param array $imgParams (dbKey => array('time' => MW timestamp,'sha1' => sha1) )
80 - * @returns Array
 80+ * @return array
8181 */
8282 protected function formatFileArray( array $params ) {
8383 $res = array();
@@ -124,7 +124,7 @@
125125 /**
126126 * Get the "review time" template version for parser
127127 * @param Title $title
128 - * @returns mixed (int/null)
 128+ * @return mixed (int/null)
129129 */
130130 public function getReviewedTemplateVersion( Title $title ) {
131131 if ( !is_array( $this->reviewedVersions ) ) {
@@ -141,7 +141,7 @@
142142 /**
143143 * Get the "review time" file version for parser
144144 * @param Title $title
145 - * @returns array (MW timestamp/'0'/null, sha1/''/null )
 145+ * @return array (MW timestamp/'0'/null, sha1/''/null )
146146 */
147147 public function getReviewedFileVersion( Title $title ) {
148148 if ( !is_array( $this->reviewedVersions ) ) {
@@ -160,7 +160,7 @@
161161 /**
162162 * Get the stable version of a template
163163 * @param Title $title
164 - * @returns int
 164+ * @return int
165165 */
166166 public function getStableTemplateVersion( Title $title ) {
167167 $dbKey = $title->getDBkey();
@@ -180,7 +180,7 @@
181181 /**
182182 * Get the stable version of a file
183183 * @param Title $title
184 - * @returns array (MW timestamp/'0', sha1/'')
 184+ * @return array (MW timestamp/'0', sha1/'')
185185 */
186186 public function getStableFileVersion( Title $title ) {
187187 $dbKey = $title->getDBkey();

Status & tagging log