Index: trunk/extensions/FlaggedRevs/FlaggedRevs.php |
— | — | @@ -14,7 +14,7 @@ |
15 | 15 | $wgExtensionCredits['specialpage'][] = array( |
16 | 16 | 'name' => 'Flagged Revisions', |
17 | 17 | 'author' => array( 'Aaron Schulz', 'Joerg Baach' ), |
18 | | - 'version' => '1.06', |
| 18 | + 'version' => '1.07', |
19 | 19 | 'url' => 'http://www.mediawiki.org/wiki/Extension:FlaggedRevs', |
20 | 20 | 'descriptionmsg' => 'flaggedrevs-desc', |
21 | 21 | ); |
— | — | @@ -98,8 +98,9 @@ |
99 | 99 | 'style' => array( 'review' => 3 ), |
100 | 100 | ); |
101 | 101 | |
102 | | -# Please set these as something different. |
103 | | -# There must be four, and only the first four are checked. |
| 102 | +# Please set these as something different. Any text will do, though it probably |
| 103 | +# shouldn't be very short (less secure) or very long (waste of resources). |
| 104 | +# There must be four codes, and only the first four are checked. |
104 | 105 | $wgReviewCodes = array( 'first one', 'second code', 'yet another', 'the last' ); |
105 | 106 | |
106 | 107 | # Lets some users access the review UI and set some flags |
— | — | @@ -108,12 +109,12 @@ |
109 | 110 | $wgAvailableRights[] = 'validate'; |
110 | 111 | |
111 | 112 | # Define our basic reviewer class |
112 | | -$wgGroupPermissions['editor']['review'] = true; |
113 | | -$wgGroupPermissions['editor']['unwatchedpages'] = true; |
114 | | -$wgGroupPermissions['editor']['autoconfirmed'] = true; |
115 | | -$wgGroupPermissions['editor']['patrolmarks'] = true; |
116 | | -$wgGroupPermissions['editor']['patrolother'] = true; |
117 | | -$wgGroupPermissions['editor']['unreviewedpages'] = true; |
| 113 | +$wgGroupPermissions['editor']['review'] = true; |
| 114 | +$wgGroupPermissions['editor']['unwatchedpages'] = true; |
| 115 | +$wgGroupPermissions['editor']['autoconfirmed'] = true; |
| 116 | +$wgGroupPermissions['editor']['patrolmarks'] = true; |
| 117 | +$wgGroupPermissions['editor']['patrolother'] = true; |
| 118 | +$wgGroupPermissions['editor']['unreviewedpages'] = true; |
118 | 119 | |
119 | 120 | # Defines extra rights for advanced reviewer class |
120 | 121 | $wgGroupPermissions['reviewer']['validate'] = true; |
— | — | @@ -122,15 +123,17 @@ |
123 | 124 | |
124 | 125 | # Stable version selection and default page revision selection |
125 | 126 | # can be set per page. |
126 | | -$wgGroupPermissions['sysop']['stablesettings'] = true; |
127 | | -$wgGroupPermissions['sysop']['patrolother'] = true; |
| 127 | +$wgGroupPermissions['sysop']['stablesettings'] = true; |
| 128 | +$wgGroupPermissions['sysop']['patrolother'] = true; |
128 | 129 | |
129 | 130 | # Define when users get automatically promoted to editors. Set as false to disable. |
| 131 | +# 'spacing' and 'benchmarks' require edits to be spread out. Users must have X (benchmark) |
| 132 | +# edits Y (spacing) days apart. |
130 | 133 | $wgFlaggedRevsAutopromote = array( |
131 | 134 | 'days' => 60, |
132 | 135 | 'edits' => 150, |
133 | | - 'spacing' => 5, // in days |
134 | | - 'benchmarks' => 10, // keep this small |
| 136 | + 'spacing' => 5, # in days |
| 137 | + 'benchmarks' => 10, # keep this small |
135 | 138 | 'email' => true, |
136 | 139 | 'userpage' => true |
137 | 140 | ); |
— | — | @@ -226,8 +229,8 @@ |
227 | 230 | $wgHooks['BeforeParserFetchTemplateAndtitle'][] = 'FlaggedRevs::parserFetchStableTemplate'; |
228 | 231 | $wgHooks['BeforeParserMakeImageLinkObj'][] = 'FlaggedRevs::parserMakeStableImageLink'; |
229 | 232 | # Additional parser versioning |
230 | | - $wgHooks['ParserAfterTidy'][] = 'FlaggedRevs::parserInjectImageTimestamps'; |
231 | | - $wgHooks['OutputPageParserOutput'][] = 'FlaggedRevs::outputInjectImageTimestamps'; |
| 233 | + $wgHooks['ParserAfterTidy'][] = 'FlaggedRevs::parserInjectTimestamps'; |
| 234 | + $wgHooks['OutputPageParserOutput'][] = 'FlaggedRevs::outputInjectTimestamps'; |
232 | 235 | # Page review on edit |
233 | 236 | $wgHooks['ArticleUpdateBeforeRedirect'][] = array($wgFlaggedArticle, 'injectReviewDiffURLParams'); |
234 | 237 | $wgHooks['DiffViewHeader'][] = array($wgFlaggedArticle, 'addDiffNoticeAfterEdit' ); |
— | — | @@ -360,6 +363,77 @@ |
361 | 364 | |
362 | 365 | return $parserOut; |
363 | 366 | } |
| 367 | + |
| 368 | + /** |
| 369 | + * @param FlaggedRevision $frev |
| 370 | + * @param Article $article |
| 371 | + * @param ParserOutput $flaggedOutput, will fetch if not given |
| 372 | + * @param ParserOutput $currentOutput, will fetch if not given |
| 373 | + * @return bool |
| 374 | + * See if a flagged revision is synced with the current |
| 375 | + */ |
| 376 | + public static function flaggedRevIsSynced( $frev, $article, $flaggedOutput=null, $currentOutput=null ) { |
| 377 | + # Must be the same revision |
| 378 | + if( $frev->getRevId() != $article->getLatest() ) { |
| 379 | + return false; |
| 380 | + } |
| 381 | + global $wgMemc; |
| 382 | + # Try the cache. Uses format <page ID>-<UNIX timestamp>. |
| 383 | + $key = wfMemcKey( 'flaggedrevs', 'syncStatus', $article->getId() . '-' . $article->getTouched() ); |
| 384 | + $syncData = $wgMemc->get($key); |
| 385 | + # Convert string value to boolean and return it |
| 386 | + if( $syncData ) { |
| 387 | + list($syncvalue,$timestamp) = explode('-',$syncData,2); |
| 388 | + return ( $syncvalue === 'true' ) ? true : false; |
| 389 | + } |
| 390 | + # If parseroutputs not given, fetch them... |
| 391 | + if( is_null($flaggedOutput) || !isset($flaggedOutput->fr_newestTemplateID) ) { |
| 392 | + # Get parsed stable version |
| 393 | + $flaggedOutput = FlaggedRevs::getPageCache( $article ); |
| 394 | + if( $flaggedOutput==false ) { |
| 395 | + global $wgUseStableTemplates; |
| 396 | + if( $wgUseStableTemplates ) { |
| 397 | + $rev = Revision::newFromId( $frev->getRevId() ); |
| 398 | + $text = $rev->getText(); |
| 399 | + } else { |
| 400 | + $text = $frev->getText(); |
| 401 | + } |
| 402 | + $flaggedOutput = FlaggedRevs::parseStableText( $article, $text, $frev->getRevId() ); |
| 403 | + # Update the stable version cache |
| 404 | + FlaggedRevs::updatePageCache( $article, $flaggedOutput ); |
| 405 | + } |
| 406 | + } |
| 407 | + if( is_null($currentOutput) || !isset($currentOutput->fr_newestTemplateID) ) { |
| 408 | + global $wgUser, $wgParser; |
| 409 | + # Get parsed current version |
| 410 | + $parserCache = ParserCache::singleton(); |
| 411 | + $currentOutput = $parserCache->get( $article, $wgUser ); |
| 412 | + if( $currentOutput==false ) { |
| 413 | + $text = $article->getContent(); |
| 414 | + $currentOutput = $wgParser->parse($text, $article->getTitle(), ParserOptions::newFromUser($wgUser)); |
| 415 | + # Might as well save the cache while we're at it |
| 416 | + $parserCache->save( $currentOutput, $article, $wgUser ); |
| 417 | + } |
| 418 | + } |
| 419 | + # Only current of revisions of inclusions can be reviewed. Since the stable and current revisions |
| 420 | + # have the same text, the only thing that can make them different is updating a template or image. |
| 421 | + # If this is the case, the current revision will have a newer template or image version used somewhere. |
| 422 | + if( $currentOutput->fr_newestImageTime > $flaggedOutput->fr_newestImageTime ) { |
| 423 | + $synced = false; |
| 424 | + } else if( $currentOutput->fr_newestTemplateID > $flaggedOutput->fr_newestTemplateID ) { |
| 425 | + $synced = false; |
| 426 | + } else { |
| 427 | + $synced = true; |
| 428 | + } |
| 429 | + # Save to cache. This will be updated whenever the page is re-parsed as well. This means |
| 430 | + # that MW can check a light-weight key first. Uses format <page ID>-<UNIX timestamp>. |
| 431 | + global $wgParserCacheExpireTime; |
| 432 | + $syncData = $synced ? 'true' : 'false'; |
| 433 | + $syncData .= '-' . $article->getTouched(); |
| 434 | + $wgMemc->set( $key, $syncData, $wgParserCacheExpireTime ); |
| 435 | + |
| 436 | + return $synced; |
| 437 | + } |
364 | 438 | |
365 | 439 | /** |
366 | 440 | * @param string $text |
— | — | @@ -656,6 +730,7 @@ |
657 | 731 | if( !isset($flags[$f]) || $v > $flags[$f] ) |
658 | 732 | return false; |
659 | 733 | } |
| 734 | + |
660 | 735 | return true; |
661 | 736 | } |
662 | 737 | |
— | — | @@ -673,6 +748,7 @@ |
674 | 749 | if( !isset($flags[$f]) || $flags[$f] < $wgFlaggedRevValues ) |
675 | 750 | return false; |
676 | 751 | } |
| 752 | + |
677 | 753 | return true; |
678 | 754 | } |
679 | 755 | |
— | — | @@ -684,8 +760,7 @@ |
685 | 761 | public static function isPageReviewable( $title ) { |
686 | 762 | global $wgFlaggedRevsNamespaces; |
687 | 763 | |
688 | | - return ( in_array($title->getNamespace(),$wgFlaggedRevsNamespaces) |
689 | | - && !$title->isTalkPage() ); |
| 764 | + return ( in_array($title->getNamespace(),$wgFlaggedRevsNamespaces) && !$title->isTalkPage() ); |
690 | 765 | } |
691 | 766 | |
692 | 767 | /** |
— | — | @@ -771,7 +846,7 @@ |
772 | 847 | $parserOut->mText .= "\n<!-- Saved in stable version parser cache with key $key and timestamp $now -->"; |
773 | 848 | # Set expire time |
774 | 849 | if( $parserOut->containsOldMagic() ){ |
775 | | - $expire = 3600; # 1 hour |
| 850 | + $expire = 3600; // 1 hour |
776 | 851 | } else { |
777 | 852 | $expire = $wgParserCacheExpireTime; |
778 | 853 | } |
— | — | @@ -897,7 +972,7 @@ |
898 | 973 | 'fr_comment' => "", |
899 | 974 | 'fr_quality' => $quality, |
900 | 975 | 'fr_tags' => self::flattenRevisionTags( $flags ), |
901 | | - 'fr_text' => $fulltext, // Store expanded text for speed |
| 976 | + 'fr_text' => $fulltext, # Store expanded text for speed |
902 | 977 | 'fr_flags' => $textFlags |
903 | 978 | ); |
904 | 979 | # Update flagged revisions table |
— | — | @@ -986,7 +1061,7 @@ |
987 | 1062 | public static function updateFromMerge( $sourceTitle, $destTitle ) { |
988 | 1063 | $oldPageID = $sourceTitle->getArticleID(); |
989 | 1064 | $newPageID = $destTitle->getArticleID(); |
990 | | - // Get flagged revisions from old page id that point to destination page |
| 1065 | + # Get flagged revisions from old page id that point to destination page |
991 | 1066 | $dbw = wfGetDB( DB_MASTER ); |
992 | 1067 | $result = $dbw->select( array('flaggedrevs','revision'), |
993 | 1068 | array( 'fr_rev_id' ), |
— | — | @@ -994,7 +1069,7 @@ |
995 | 1070 | 'fr_rev_id = rev_id', |
996 | 1071 | 'rev_page' => $newPageID ), |
997 | 1072 | __METHOD__ ); |
998 | | - // Update these rows |
| 1073 | + # Update these rows |
999 | 1074 | $revIDs = array(); |
1000 | 1075 | while( $row = $dbw->fetchObject($result) ) { |
1001 | 1076 | $revIDs[] = $row->fr_rev_id; |
— | — | @@ -1006,7 +1081,7 @@ |
1007 | 1082 | 'fr_rev_id' => $revIDs ), |
1008 | 1083 | __METHOD__ ); |
1009 | 1084 | } |
1010 | | - // Update pages |
| 1085 | + # Update pages |
1011 | 1086 | self::articleLinksUpdate2( $sourceTitle ); |
1012 | 1087 | self::articleLinksUpdate2( $destTitle ); |
1013 | 1088 | |
— | — | @@ -1143,7 +1218,7 @@ |
1144 | 1219 | 'ft_title' => $title->getDBkey() ), |
1145 | 1220 | __METHOD__ ); |
1146 | 1221 | } |
1147 | | - |
| 1222 | + # If none specified, see if we are allowed to use the current revision |
1148 | 1223 | if( !$id ) { |
1149 | 1224 | global $wgUseCurrentTemplates; |
1150 | 1225 | |
— | — | @@ -1190,7 +1265,7 @@ |
1191 | 1266 | 'fi_name' => $nt->getDBkey() ), |
1192 | 1267 | __METHOD__ ); |
1193 | 1268 | } |
1194 | | - |
| 1269 | + # If none specified, see if we are allowed to use the current revision |
1195 | 1270 | if( !$time ) { |
1196 | 1271 | global $wgUseCurrentImages; |
1197 | 1272 | |
— | — | @@ -1239,7 +1314,7 @@ |
1240 | 1315 | if( !$time ) { |
1241 | 1316 | global $wgUseCurrentImages; |
1242 | 1317 | |
1243 | | - $time = $wgUseCurrentImages ? $time : -1; // hack, will never find this |
| 1318 | + $time = $wgUseCurrentImages ? $time : -1; |
1244 | 1319 | } |
1245 | 1320 | |
1246 | 1321 | return true; |
— | — | @@ -1263,7 +1338,7 @@ |
1264 | 1339 | */ |
1265 | 1340 | public static function setImageVersion( $title, $article ) { |
1266 | 1341 | if( NS_MEDIA == $title->getNamespace() ) { |
1267 | | - // FIXME: where should this go? |
| 1342 | + # FIXME: where should this go? |
1268 | 1343 | $title = Title::makeTitle( NS_IMAGE, $title->getDBkey() ); |
1269 | 1344 | } |
1270 | 1345 | |
— | — | @@ -1291,8 +1366,10 @@ |
1292 | 1367 | /** |
1293 | 1368 | * Insert image timestamps/SHA-1 keys into parser output |
1294 | 1369 | */ |
1295 | | - public static function parserInjectImageTimestamps( $parser, &$text ) { |
| 1370 | + public static function parserInjectTimestamps( $parser, &$text ) { |
1296 | 1371 | $parser->mOutput->fr_ImageSHA1Keys = array(); |
| 1372 | + $maxTimestamp = "0"; |
| 1373 | + $maxRevision = 0; |
1297 | 1374 | # Fetch the timestamps of the images |
1298 | 1375 | if( !empty($parser->mOutput->mImages) ) { |
1299 | 1376 | $filenames = array_keys($parser->mOutput->mImages); |
— | — | @@ -1300,20 +1377,41 @@ |
1301 | 1378 | $file = wfFindFile( Title::makeTitle( NS_IMAGE, $filename ) ); |
1302 | 1379 | $parser->mOutput->fr_ImageSHA1Keys[$filename] = array(); |
1303 | 1380 | if( $file ) { |
| 1381 | + if( $file->getTimestamp() > $maxTimestamp ) { |
| 1382 | + $maxTimestamp = $file->getTimestamp(); |
| 1383 | + } |
1304 | 1384 | $parser->mOutput->fr_ImageSHA1Keys[$filename][$file->getTimestamp()] = $file->getSha1(); |
1305 | 1385 | } else { |
1306 | 1386 | $parser->mOutput->fr_ImageSHA1Keys[$filename][0] = ''; |
1307 | 1387 | } |
1308 | 1388 | } |
1309 | 1389 | } |
| 1390 | + # Record the max timestamp |
| 1391 | + $parser->mOutput->fr_newestImageTime = $maxTimestamp; |
| 1392 | + # Record the max template revision ID |
| 1393 | + if( !empty($parser->mOutput->mTemplateIds) ) { |
| 1394 | + foreach( $parser->mOutput->mTemplateIds as $namespace => $title_rev ) { |
| 1395 | + foreach( $title_rev as $title => $revID ) { |
| 1396 | + if( $revID > $maxRevision ) { |
| 1397 | + $maxRevision = $revID; |
| 1398 | + } |
| 1399 | + } |
| 1400 | + } |
| 1401 | + } |
| 1402 | + $parser->mOutput->fr_newestTemplateID = $maxRevision; |
| 1403 | + |
1310 | 1404 | return true; |
1311 | 1405 | } |
1312 | 1406 | |
1313 | 1407 | /** |
1314 | 1408 | * Insert image timestamps/SHA-1s into page output |
1315 | 1409 | */ |
1316 | | - public static function outputInjectImageTimestamps( $out, $parserOut ) { |
1317 | | - $out->fr_ImageSHA1Keys = $parserOut->fr_ImageSHA1Keys; |
| 1410 | + public static function outputInjectTimestamps( $out, $parserOut ) { |
| 1411 | + # Leave as defaults if missing. Relevant things will be updated only when needed. |
| 1412 | + # We don't want to go around resetting caches all over the place if avoidable... |
| 1413 | + $out->fr_ImageSHA1Keys = isset($parserOut->fr_ImageSHA1Keys) ? $parserOut->fr_ImageSHA1Keys : array(); |
| 1414 | + $out->fr_newestImageTime = isset($parserOut->fr_newestImageTime) ? $parserOut->fr_newestImageTime : "0"; |
| 1415 | + $out->fr_newestTemplateID = isset($parserOut->fr_newestTemplateID) ? $parserOut->fr_newestTemplateID : 0; |
1318 | 1416 | |
1319 | 1417 | return true; |
1320 | 1418 | } |
— | — | @@ -1328,7 +1426,7 @@ |
1329 | 1427 | $frev = self::getStablePageRev( $title ); |
1330 | 1428 | if( !$frev ) |
1331 | 1429 | return true; |
1332 | | - # Allow for only editors/reviewers to move this |
| 1430 | + # Allow for only editors/reviewers to move this |
1333 | 1431 | $right = $frev->getQuality() ? 'validate' : 'review'; |
1334 | 1432 | if( !$user->isAllowed( $right ) ) { |
1335 | 1433 | $result = false; |
— | — | @@ -1409,14 +1507,14 @@ |
1410 | 1508 | $wgMemc->set( $key, 'true', 3600*24*30 ); |
1411 | 1509 | return true; |
1412 | 1510 | } |
1413 | | - // Check for edit spacing. This lets us know that the account has |
1414 | | - // been used over N different days, rather than all in one lump. |
1415 | | - // This can be expensive... so check it last. |
| 1511 | + # Check for edit spacing. This lets us know that the account has |
| 1512 | + # been used over N different days, rather than all in one lump. |
| 1513 | + # This can be expensive... so check it last. |
1416 | 1514 | if( $wgFlaggedRevsAutopromote['spacing'] > 0 && $wgFlaggedRevsAutopromote['benchmarks'] > 1 ) { |
1417 | | - // Convert days to seconds... |
| 1515 | + # Convert days to seconds... |
1418 | 1516 | $spacing = $wgFlaggedRevsAutopromote['spacing'] * 24 * 3600; |
1419 | 1517 | |
1420 | | - // Check the oldest edit |
| 1518 | + # Check the oldest edit |
1421 | 1519 | $dbr = wfGetDB( DB_SLAVE ); |
1422 | 1520 | $lower = $dbr->selectField( 'revision', 'rev_timestamp', |
1423 | 1521 | array( 'rev_user' => $user->getID() ), |
— | — | @@ -1424,8 +1522,8 @@ |
1425 | 1523 | array( 'ORDER BY' => 'rev_timestamp ASC', |
1426 | 1524 | 'USE INDEX' => 'user_timestamp' ) ); |
1427 | 1525 | |
1428 | | - // Recursively check for an edit $spacing seconds later, until we are done. |
1429 | | - // The first edit counts, so we have one less scans to do... |
| 1526 | + # Recursively check for an edit $spacing seconds later, until we are done. |
| 1527 | + # The first edit counts, so we have one less scans to do... |
1430 | 1528 | $benchmarks = 0; |
1431 | 1529 | $needed = $wgFlaggedRevsAutopromote['benchmarks'] - 1; |
1432 | 1530 | while( $lower && $benchmarks < $needed ) { |
— | — | @@ -1468,10 +1566,10 @@ |
1469 | 1567 | $selector = "<label for='namespace'>" . wfMsgHtml('namespace') . "</label>"; |
1470 | 1568 | if( $selected !== '' ) { |
1471 | 1569 | if( is_null( $selected ) ) { |
1472 | | - // No namespace selected; let exact match work without hitting Main |
| 1570 | + # No namespace selected; let exact match work without hitting Main |
1473 | 1571 | $selected = ''; |
1474 | 1572 | } else { |
1475 | | - // Let input be numeric strings without breaking the empty match. |
| 1573 | + # Let input be numeric strings without breaking the empty match. |
1476 | 1574 | $selected = intval($selected); |
1477 | 1575 | } |
1478 | 1576 | } |
Index: trunk/extensions/FlaggedRevs/FlaggedArticle.php |
— | — | @@ -87,7 +87,12 @@ |
88 | 88 | global $wgRequest, $wgTitle, $wgOut, $wgUser; |
89 | 89 | |
90 | 90 | $skin = $wgUser->getSkin(); |
| 91 | + |
91 | 92 | $action = $wgRequest->getVal( 'action', 'view' ); |
| 93 | + # Do not clutter up diffs any further... |
| 94 | + if( $wgRequest->getVal('diff') || $wgRequest->getVal('oldid') ) { |
| 95 | + return true; |
| 96 | + } |
92 | 97 | # For unreviewable pages, allow for basic patrolling |
93 | 98 | if( !FlaggedRevs::isPageReviewable( $article->getTitle() ) ) { |
94 | 99 | # If we have been passed an &rcid= parameter, we want to give the user a |
— | — | @@ -112,84 +117,101 @@ |
113 | 118 | $revid = $article->mRevision ? $article->mRevision->mId : $article->getLatest(); |
114 | 119 | if( !$revid ) |
115 | 120 | return true; |
116 | | - |
117 | | - $vis_id = $revid; |
| 121 | + |
118 | 122 | $tag = $notes = ''; |
119 | 123 | # Check the newest stable version... |
120 | 124 | $tfrev = $this->getStableRev( true ); |
121 | 125 | $simpleTag = false; |
122 | | - if( $wgRequest->getVal('diff') || $wgRequest->getVal('oldid') ) { |
123 | | - // Do not clutter up diffs any further... |
124 | | - } else if( !is_null($tfrev) ) { |
| 126 | + // Is there a stable version? |
| 127 | + if( !is_null($tfrev) ) { |
125 | 128 | global $wgLang; |
126 | 129 | # Get flags and date |
127 | 130 | $flags = $tfrev->getTags(); |
128 | 131 | # Get quality level |
129 | 132 | $quality = FlaggedRevs::isQuality( $flags ); |
130 | 133 | $pristine = FlaggedRevs::isPristine( $flags ); |
| 134 | + |
131 | 135 | $time = $wgLang->date( $tfrev->getTimestamp(), true ); |
132 | | - # Looking at some specific old rev or if flagged revs override only for anons |
| 136 | + // Looking at some specific old rev or if flagged revs override only for anons |
133 | 137 | if( !$this->pageOverride() ) { |
134 | 138 | $revs_since = FlaggedRevs::getRevCountSince( $article, $tfrev->getRevId() ); |
135 | | - $simpleTag = true; |
| 139 | + |
| 140 | + $synced = FlaggedRevs::flaggedRevIsSynced( $tfrev, $article, null, null ); |
| 141 | + # If they are synced, do special styling |
| 142 | + $simpleTag = !$synced; |
136 | 143 | # Construct some tagging |
137 | 144 | if( !$wgOut->isPrintable() ) { |
138 | 145 | if( FlaggedRevs::useSimpleUI() ) { |
139 | | - $msg = $quality ? 'revreview-quick-see-quality' : 'revreview-quick-see-basic'; |
140 | | - $tag .= "<span class='fr-tab_current plainlinks'></span>" . |
141 | | - wfMsgExt( $msg,array('parseinline'), $tfrev->getRevId(), $revs_since ); |
142 | | - $tag .= $this->prettyRatingBox( $tfrev, $flags, $revs_since, false ); |
| 146 | + if( $synced ) { |
| 147 | + $msg = $quality ? 'revreview-quick-quality-same' : 'revreview-quick-basic-same'; |
| 148 | + $css = $quality ? 'fr-tab_quality' : 'fr-tab_stable'; |
| 149 | + } else { |
| 150 | + $msg = $quality ? 'revreview-quick-see-quality' : 'revreview-quick-see-basic'; |
| 151 | + $css = 'fr-tab_current'; |
| 152 | + } |
| 153 | + $tag .= "<span class='{$css} plainlinks'></span>" . |
| 154 | + wfMsgExt( $msg, array('parseinline'), $tfrev->getRevId(), $revs_since ); |
| 155 | + $tag .= $this->prettyRatingBox( $tfrev, $flags, $revs_since, false, $synced ); |
143 | 156 | } else { |
144 | | - $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic'; |
145 | | - $tag .= wfMsgExt ($msg, array('parseinline'), $tfrev->getRevId(), $time, $revs_since ); |
| 157 | + if( $synced ) { |
| 158 | + $msg = $quality ? 'revreview-quality-same' : 'revreview-basic-same'; |
| 159 | + } else { |
| 160 | + $msg = $quality ? 'revreview-newest-quality' : 'revreview-newest-basic'; |
| 161 | + } |
| 162 | + $tag .= wfMsgExt( $msg, array('parseinline'), $tfrev->getRevId(), $time, $revs_since ); |
146 | 163 | # Hide clutter |
147 | 164 | if( !empty($flags) ) { |
148 | | - $tag .= ' <span id="mw-revisiontoggle" class="flaggedrevs_toggle" style="display:none; cursor:pointer;"' . |
149 | | - ' onclick="javascript:toggleRevRatings()">'.wfMsg('revreview-toggle').'</span>'; |
150 | | - $tag .= '<span id="mw-revisionratings" style="display:block;">' . |
151 | | - wfMsg('revreview-oldrating') . $this->addTagRatings( $flags ) . '</span>'; |
| 165 | + $tag .= " <span id='mw-revisiontoggle' class='flaggedrevs_toggle' style='display:none; cursor:pointer;'" . |
| 166 | + " onclick='javascript:toggleRevRatings()'>".wfMsg('revreview-toggle') . "</span>"; |
| 167 | + $tag .= "<span id='mw-revisionratings' style='display:block;'>" . |
| 168 | + wfMsgHtml('revreview-oldrating') . $this->addTagRatings( $flags ) . '</span>'; |
152 | 169 | } |
153 | 170 | } |
154 | 171 | } |
155 | 172 | // Viewing the page normally: override the page |
156 | 173 | } else { |
157 | 174 | # We will be looking at the reviewed revision... |
158 | | - $vis_id = $tfrev->getRevId(); |
159 | | - $revs_since = FlaggedRevs::getRevCountSince( $article, $vis_id ); |
| 175 | + $revs_since = FlaggedRevs::getRevCountSince( $article, $tfrev->getRevId() ); |
| 176 | + |
| 177 | + # Get parsed stable version |
| 178 | + $parserOut = FlaggedRevs::getPageCache( $article ); |
| 179 | + if( $parserOut==false ) { |
| 180 | + global $wgUseStableTemplates; |
| 181 | + if( $wgUseStableTemplates ) { |
| 182 | + $rev = Revision::newFromId( $tfrev->getRevId() ); |
| 183 | + $text = $rev->getText(); |
| 184 | + } else { |
| 185 | + $text = $tfrev->getText(); |
| 186 | + } |
| 187 | + $parserOut = FlaggedRevs::parseStableText( $article, $text, $tfrev->getRevId() ); |
| 188 | + # Update the stable version cache |
| 189 | + FlaggedRevs::updatePageCache( $article, $parserOut ); |
| 190 | + } |
| 191 | + |
| 192 | + $synced = FlaggedRevs::flaggedRevIsSynced( $tfrev, $article, $parserOut, null ); |
160 | 193 | # Construct some tagging |
161 | 194 | if( !$wgOut->isPrintable() ) { |
162 | 195 | if( FlaggedRevs::useSimpleUI() ) { |
163 | 196 | $msg = $quality ? 'revreview-quick-quality' : 'revreview-quick-basic'; |
| 197 | + $msg = $synced ? $msg . '-same' : $msg; |
164 | 198 | $css = $quality ? 'fr-tab_quality' : 'fr-tab_stable'; |
165 | | - $tag = "<span class='$css plainlinks'></span>" . |
| 199 | + |
| 200 | + $tag = "<span class='{$css} plainlinks'></span>" . |
166 | 201 | wfMsgExt( $msg, array('parseinline'), $tfrev->getRevId(), $revs_since ); |
167 | | - $tag .= $this->prettyRatingBox( $tfrev, $flags, $revs_since ); |
| 202 | + $tag .= $this->prettyRatingBox( $tfrev, $flags, $revs_since, true, $synced ); |
168 | 203 | } else { |
169 | 204 | $msg = $quality ? 'revreview-quality' : 'revreview-basic'; |
170 | | - $tag = wfMsgExt( $msg, array('parseinline'), $vis_id, $time, $revs_since ); |
| 205 | + $msg = $synced ? $msg . '-same' : $msg; |
| 206 | + |
| 207 | + $tag = wfMsgExt( $msg, array('parseinline'), $tfrev->getRevId(), $time, $revs_since ); |
171 | 208 | if( !empty($flags) ) { |
172 | | - $tag = ' <span id="mw-revisiontoggle" class="flaggedrevs_toggle" style="display:none; cursor:pointer;"' . |
173 | | - ' onclick="javascript:toggleRevRatings()">'.wfMsg('revreview-toggle').'</span>'; |
174 | | - $tag .= '<span id="mw-revisionratings" style="display:block;">' . |
| 209 | + $tag = " <span id='mw-revisiontoggle' class='flaggedrevs_toggle' style='display:none; cursor:pointer;'" . |
| 210 | + " onclick='javascript:toggleRevRatings()'>" . wfMsg('revreview-toggle') . "</span>"; |
| 211 | + $tag .= "<span id='mw-revisionratings' style='display:block;'>" . |
175 | 212 | $this->addTagRatings( $flags ) . '</span>'; |
176 | 213 | } |
177 | 214 | } |
178 | 215 | } |
179 | | - # Try the stable page cache |
180 | | - $parserOut = FlaggedRevs::getPageCache( $article ); |
181 | | - # If no cache is available, get the text and parse it |
182 | | - if( $parserOut==false ) { |
183 | | - global $wgUseStableTemplates; |
184 | | - if( $wgUseStableTemplates ) { |
185 | | - $rev = Revision::newFromId( $tfrev->getRevId() ); |
186 | | - $text = $rev->getText(); |
187 | | - } else { |
188 | | - $text = $tfrev->getText(); |
189 | | - } |
190 | | - $parserOut = FlaggedRevs::parseStableText( $article, $text, $vis_id ); |
191 | | - # Update the general cache |
192 | | - FlaggedRevs::updatePageCache( $article, $parserOut ); |
193 | | - } |
194 | 216 | # Output HTML |
195 | 217 | $wgOut->addParserOutput( $parserOut ); |
196 | 218 | $notes = $this->ReviewNotes( $tfrev ); |
— | — | @@ -732,10 +754,11 @@ |
733 | 755 | * @param array $flags |
734 | 756 | * @param int $revs_since, revisions since review |
735 | 757 | * @param bool $stable, are we referring to the stable revision? |
| 758 | + * @param bool $synced, does stable=current and this is one of them? |
736 | 759 | * @return string |
737 | 760 | * Generates a review box using a table using addTagRatings() |
738 | 761 | */ |
739 | | - public function prettyRatingBox( $tfrev, $flags, $revs_since, $stable=true ) { |
| 762 | + public function prettyRatingBox( $tfrev, $flags, $revs_since, $stable=true, $synced=false ) { |
740 | 763 | global $wgLang; |
741 | 764 | # Get quality level |
742 | 765 | $quality = FlaggedRevs::isQuality( $flags ); |
— | — | @@ -749,11 +772,15 @@ |
750 | 773 | else |
751 | 774 | $tagClass = 'flaggedrevs_box1'; |
752 | 775 | # Construct some tagging |
753 | | - $msg = $stable ? 'revreview-' : 'revreview-newest-'; |
754 | | - $msg .= $quality ? 'quality' : 'basic'; |
755 | | - |
| 776 | + if( $synced ) { |
| 777 | + $msg = $quality ? 'revreview-quality-same' : 'revreview-basic-same'; |
| 778 | + } else { |
| 779 | + $msg = $stable ? 'revreview-' : 'revreview-newest-'; |
| 780 | + $msg .= $quality ? 'quality' : 'basic'; |
| 781 | + } |
| 782 | + # Make facny box... |
756 | 783 | $box = ' <span id="mw-revisiontoggle" class="flaggedrevs_toggle" style="display:none; cursor:pointer;" |
757 | | - onclick="javascript:toggleRevRatings();">'.wfMsg('revreview-toggle').'</span>'; |
| 784 | + onclick="javascript:toggleRevRatings();">'.wfMsgHtml('revreview-toggle').'</span>'; |
758 | 785 | $box .= '<div id="mw-revisionratings" style="clear: both;">' . |
759 | 786 | wfMsgExt($msg, array('parseinline'), $tfrev->getRevId(), $time, $revs_since); |
760 | 787 | |
— | — | @@ -834,7 +861,7 @@ |
835 | 862 | } else { |
836 | 863 | $changeList = implode(', ',$changeList); |
837 | 864 | $wgOut->addHTML( '<div id="mw-difftostable" class="flaggedrevs_notice plainlinks"><p>' . |
838 | | - wfMsgExt('revreview-update', array('parseinline')) . $changeList . '</div>' ); |
| 865 | + wfMsgExt('revreview-update', array('parseinline')) . ' ' . $changeList . '</div>' ); |
839 | 866 | } |
840 | 867 | # Set flag for review form to tell it to autoselect tag settings from the |
841 | 868 | # old revision unless the current one is tagged to. |
— | — | @@ -855,12 +882,16 @@ |
856 | 883 | |
857 | 884 | $frev = $this->getStableRev(); |
858 | 885 | # Was this already autoreviewed, are we allowed? |
859 | | - if( $this->skipReviewDiff || !$wgReviewChangesAfterEdit || !$wgUser->isAllowed('review') ) { |
860 | | - if( !is_null($frev) ) { |
861 | | - $extraq .= "stable=0"; |
| 886 | + if( $wgReviewChangesAfterEdit && !$this->skipReviewDiff && !is_null($frev) && $wgUser->isAllowed('review') ) { |
| 887 | + $extraq .= "oldid={$frev->getRevId()}&diff=cur&editreview=1"; |
| 888 | + } else { |
| 889 | + if( !is_null($frev) ){ |
| 890 | + if( $wgUser->isAllowed('review') ) { |
| 891 | + $extraq .= "stable=1"; |
| 892 | + } else { |
| 893 | + $extraq .= "stable=0"; |
| 894 | + } |
862 | 895 | } |
863 | | - } else if( $frev ) { |
864 | | - $extraq .= "oldid={$frev->getRevId()}&diff=cur&editreview=1"; |
865 | 896 | } |
866 | 897 | |
867 | 898 | return true; |
Index: trunk/extensions/FlaggedRevs/FlaggedRevsPage.i18n.php |
— | — | @@ -1,4 +1,4 @@ |
2 | | -<?php |
| 2 | +<?php |
3 | 3 | /** |
4 | 4 | * Internationalisation file for extension FlaggedRevs (group FlaggedRevsPage). |
5 | 5 | * |
— | — | @@ -40,13 +40,20 @@ |
41 | 41 | 'revreview-quick-see-basic' => '\'\'\'Draft\'\'\' [[{{fullurl:{{FULLPAGENAMEE}}|stable=1}} view stable article]] ($2 [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&editreview=1}} {{plural:$2|change|changes}}])', |
42 | 42 | 'revreview-quick-basic' => '\'\'\'[[{{MediaWiki:Validationpage}}|Sighted]]\'\'\' [[{{fullurl:{{FULLPAGENAMEE}}|stable=0}} view draft]] ($2 [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&editreview=1}} {{plural:$2|change|changes}}])', |
43 | 43 | 'revreview-quick-quality' => '\'\'\'[[{{MediaWiki:Validationpage}}|Quality]]\'\'\' [[{{fullurl:{{FULLPAGENAMEE}}|stable=0}} view draft]] ($2 [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&editreview=1}} {{plural:$2|change|changes}}])', |
| 44 | + 'revreview-quick-basic-same' => '\'\'\'[[{{MediaWiki:Validationpage}}|Sighted]]\'\'\' (no unreviewed changes)', |
| 45 | + 'revreview-quick-quality-same' => '\'\'\'[[{{MediaWiki:Validationpage}}|Quality]]\'\'\' (no unreviewed changes)', |
| 46 | + |
44 | 47 | 'revreview-newest-basic' => 'The [{{fullurl:{{FULLPAGENAMEE}}|stable=1}} latest sighted revision] ([{{fullurl:Special:Stableversions|page={{FULLPAGENAMEE}}}} list all]) was [{{fullurl:Special:Log|type=review&page={{FULLPAGENAMEE}}}} approved] on <i>$2</i>. [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&editreview=1}} $3 {{plural:$3|change|changes}}] {{plural:$3|needs|need}} review.', |
45 | 48 | 'revreview-newest-quality' => 'The [{{fullurl:{{FULLPAGENAMEE}}|stable=1}} latest quality revision] ([{{fullurl:Special:Stableversions|page={{FULLPAGENAMEE}}}} list all]) was [{{fullurl:Special:Log|type=review&page={{FULLPAGENAMEE}}}} approved] on <i>$2</i>. [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&editreview=1}} $3 {{plural:$3|change|changes}}] {{plural:$3|needs|need}} review.', |
46 | 49 | 'revreview-basic' => 'This is the latest [[{{MediaWiki:Validationpage}}|sighted]] revision, [{{fullurl:Special:Log|type=review&page={{FULLPAGENAMEE}}}} approved] on <i>$2</i>. The [{{fullurl:{{FULLPAGENAMEE}}|stable=0}} draft] can be [{{fullurl:{{FULLPAGENAMEE}}|action=edit}} modified]; [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&editreview=1}} $3 {{plural:$3|change|changes}}] {{plural:$3|awaits|await}} review.', |
47 | 50 | 'revreview-quality' => 'This is the latest [[{{MediaWiki:Validationpage}}|quality]] revision, [{{fullurl:Special:Log|type=review&page={{FULLPAGENAMEE}}}} approved] on <i>$2</i>. The [{{fullurl:{{FULLPAGENAMEE}}|stable=0}} draft] can be [{{fullurl:{{FULLPAGENAMEE}}|action=edit}} modified]; [{{fullurl:{{FULLPAGENAMEE}}|oldid=$1&diff=cur&editreview=1}} $3 {{plural:$3|change|changes}}] {{plural:$3|awaits|await}} review.', |
48 | | - 'revreview-static' => 'This is a [[{{MediaWiki:Validationpage}}|reviewed]] revision of \'\'\'[[:$3|$3]]\'\'\', [{{fullurl:Special:Log|type=review&page=$1}} approved] on <i>$2</i>.', |
| 51 | + 'revreview-basic-same' => 'This is the latest [[{{MediaWiki:Validationpage}}|sighted]] revision, [{{fullurl:Special:Log|type=review&page={{FULLPAGENAMEE}}}} approved] on <i>$2</i>. The page can be [{{fullurl:{{FULLPAGENAMEE}}|action=edit}} modified].', |
| 52 | + 'revreview-quality-same' => 'This is the latest [[{{MediaWiki:Validationpage}}|quality]] revision, [{{fullurl:Special:Log|type=review&page={{FULLPAGENAMEE}}}} approved] on <i>$2</i>. The page can be [{{fullurl:{{FULLPAGENAMEE}}|action=edit}} modified].', |
49 | 53 | 'revreview-toggle' => '(+/-)', |
50 | 54 | 'revreview-note' => '[[User:$1]] made the following notes [[{{MediaWiki:Validationpage}}|reviewing]] this revision:', |
| 55 | + |
| 56 | + 'revreview-static' => 'This is a [[{{MediaWiki:Validationpage}}|reviewed]] revision of \'\'\'[[:$3|$3]]\'\'\', [{{fullurl:Special:Log|type=review&page=$1}} approved] on <i>$2</i>.', |
| 57 | + |
51 | 58 | 'revreview-update' => "Please [[{{MediaWiki:Validationpage}}|review]] any changes ''(shown below)'' made since the stable revision was [{{fullurl:Special:Log|type=review&page={{FULLPAGENAMEE}}}} approved]. |
52 | 59 | |
53 | 60 | '''Some templates/images were updated:'''", |
— | — | @@ -4944,3 +4951,4 @@ |
4945 | 4952 | 'unreviewed-list' => '這一頁列示出還未複審或視察的文章修訂。', |
4946 | 4953 | ); |
4947 | 4954 | |
| 4955 | + |
Index: trunk/extensions/FlaggedRevs/FlaggedRevsPage.php |
— | — | @@ -298,7 +298,7 @@ |
299 | 299 | $this->approveRevision( $rev, $this->notes ) : $this->unapproveRevision( $frev ); |
300 | 300 | # Return to our page |
301 | 301 | if( $success ) { |
302 | | - $wgOut->redirect( $this->page->getFullUrl() ); |
| 302 | + $wgOut->redirect( $this->page->getFullUrl( 'stable=1' ) ); |
303 | 303 | } else { |
304 | 304 | $wgOut->showErrorPage( 'internalerror', 'revreview-changed', array($this->page->getPrefixedText()) ); |
305 | 305 | } |