Index: trunk/extensions/FlaggedRevs/FlaggedRevs.php |
— | — | @@ -32,6 +32,8 @@ |
33 | 33 | |
34 | 34 | # Allowed namespaces of reviewable pages |
35 | 35 | $wgFlaggedRevsNamespaces = array( NS_MAIN ); |
| 36 | +# Patrollable namespaces |
| 37 | +$wgFlaggedRevsPatrolNamespaces = array( NS_CATEGORY, NS_IMAGE, NS_TEMPLATE ); |
36 | 38 | |
37 | 39 | # Do flagged revs override the default view? |
38 | 40 | $wgFlaggedRevsOverride = true; |
— | — | @@ -181,6 +183,9 @@ |
182 | 184 | # Show reviews in recentchanges? Disabled by default, often spammy... |
183 | 185 | $wgFlaggedRevsLogInRC = false; |
184 | 186 | |
| 187 | +# How far the logs for overseeing quality revisions and depreciations go |
| 188 | +$wgFlaggedRevsOversightAge = 7 * 24 * 3600; |
| 189 | + |
185 | 190 | # End of configuration variables. |
186 | 191 | ######### |
187 | 192 | |
— | — | @@ -222,6 +227,9 @@ |
223 | 228 | # To oversee quality revisions |
224 | 229 | $wgSpecialPages['QualityOversight'] = 'QualityOversight'; |
225 | 230 | $wgAutoloadClasses['QualityOversight'] = $dir . 'FlaggedRevsPage.php'; |
| 231 | +# To oversee depreciations |
| 232 | +$wgSpecialPages['DepreciationOversight'] = 'DepreciationOversight'; |
| 233 | +$wgAutoloadClasses['DepreciationOversight'] = $dir . 'FlaggedRevsPage.php'; |
226 | 234 | |
227 | 235 | # Remove stand-alone patrolling |
228 | 236 | $wgHooks['UserGetRights'][] = 'FlaggedRevs::stripPatrolRights'; |
— | — | @@ -289,9 +297,10 @@ |
290 | 298 | |
291 | 299 | function wfInitFlaggedArticle( $output, $article, $title, $user, $request ) { |
292 | 300 | global $wgFlaggedArticle, $wgHooks; |
293 | | - if( !FlaggedRevs::isPageReviewable($title) ) |
| 301 | + # Load when needed |
| 302 | + if( !FlaggedRevs::isPageReviewable($title) && !FlaggedRevs::isPagePatrollable($title) ) |
294 | 303 | return true; |
295 | | - # Initialize and set article hooks |
| 304 | + # Initialize object and set article hooks |
296 | 305 | $wgFlaggedArticle = new FlaggedArticle( $title ); |
297 | 306 | # Set image version |
298 | 307 | $wgFlaggedArticle->setImageVersion(); |
— | — | @@ -673,14 +682,15 @@ |
674 | 683 | /** |
675 | 684 | * @param Title $title |
676 | 685 | * @param int $rev_id |
677 | | - * @param Database $db, optional |
| 686 | + * @param $flags, GAID_FOR_UPDATE |
678 | 687 | * @returns mixed (int or false) |
| 688 | + * Get quality of a revision |
679 | 689 | */ |
680 | | - public static function getRevQuality( $title, $rev_id, $db = NULL ) { |
681 | | - $db = $db ? $db : wfGetDB( DB_SLAVE ); |
| 690 | + public static function getRevQuality( $title, $rev_id, $flags=0 ) { |
| 691 | + $db = ($flags & GAID_FOR_UPDATE) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE ); |
682 | 692 | $quality = $db->selectField( 'flaggedrevs', |
683 | 693 | 'fr_quality', |
684 | | - array( 'fr_page_id' => $title->getArticleID(), |
| 694 | + array( 'fr_page_id' => $title->getArticleID( $flags ), |
685 | 695 | 'fr_rev_id' => $rev_id ), |
686 | 696 | __METHOD__, |
687 | 697 | array( 'FORCE INDEX' => 'PRIMARY' ) |
— | — | @@ -689,6 +699,18 @@ |
690 | 700 | } |
691 | 701 | |
692 | 702 | /** |
| 703 | + * @param Title $title |
| 704 | + * @param int $rev_id |
| 705 | + * @param $flags, GAID_FOR_UPDATE |
| 706 | + * @returns bool |
| 707 | + * Useful for quickly pinging to see if a revision is flagged |
| 708 | + */ |
| 709 | + public static function revIsFlagged( $title, $rev_id, $flags=0 ) { |
| 710 | + $quality = self::getRevQuality( $title, $rev_id, $flags=0 ); |
| 711 | + return ($quality !== false); |
| 712 | + } |
| 713 | + |
| 714 | + /** |
693 | 715 | * Make stable version link and return the css |
694 | 716 | * @param Title $title |
695 | 717 | * @param int $rev_id |
— | — | @@ -992,10 +1014,26 @@ |
993 | 1015 | */ |
994 | 1016 | public static function isPageReviewable( $title ) { |
995 | 1017 | global $wgFlaggedRevsNamespaces; |
996 | | - # Treat NS_MEDIA as NS_IMAGE |
| 1018 | + # FIXME: Treat NS_MEDIA as NS_IMAGE |
997 | 1019 | $ns = ( $title->getNamespace() == NS_MEDIA ) ? NS_IMAGE : $title->getNamespace(); |
998 | 1020 | return ( in_array($ns,$wgFlaggedRevsNamespaces) && !$title->isTalkPage() ); |
999 | 1021 | } |
| 1022 | + |
| 1023 | + /** |
| 1024 | + * Is this page in patrolable namespace? |
| 1025 | + * @param Title, $title |
| 1026 | + * @return bool |
| 1027 | + */ |
| 1028 | + public static function isPagePatrollable( $title ) { |
| 1029 | + global $wgFlaggedRevsPatrolNamespaces; |
| 1030 | + # No collisions! |
| 1031 | + if( self::isPageReviewable($title) ) { |
| 1032 | + return false; |
| 1033 | + } |
| 1034 | + # FIXME: Treat NS_MEDIA as NS_IMAGE |
| 1035 | + $ns = ( $title->getNamespace() == NS_MEDIA ) ? NS_IMAGE : $title->getNamespace(); |
| 1036 | + return ( in_array($ns,$wgFlaggedRevsPatrolNamespaces) && !$title->isTalkPage() ); |
| 1037 | + } |
1000 | 1038 | |
1001 | 1039 | /** |
1002 | 1040 | * @param Article $article |
— | — | @@ -1913,10 +1951,21 @@ |
1914 | 1952 | * are autopatrolled. |
1915 | 1953 | */ |
1916 | 1954 | public static function autoMarkPatrolled( $article, $user, $text, $c, $m, $a, $b, $flags, $rev ) { |
1917 | | - if( !$rev ) |
1918 | | - return true; |
1919 | | - |
1920 | | - if( !self::isPageReviewable( $article->getTitle() ) && $user->isAllowed('autopatrolother') ) { |
| 1955 | + if( !$rev ) { |
| 1956 | + return true; // NULL edit |
| 1957 | + } |
| 1958 | + $title = $article->getTitle(); |
| 1959 | + $patrol = false; |
| 1960 | + // Is the page reviewable? |
| 1961 | + if( self::isPageReviewable($title) ) { |
| 1962 | + $patrol = self::revIsFlagged($title, $rev->getId(), GAID_FOR_UPDATE ); |
| 1963 | + // Can this be patrolled? |
| 1964 | + } else if( self::isPagePatrollable($title) ) { |
| 1965 | + $patrol = $user->isAllowed('autopatrolother'); |
| 1966 | + } else { |
| 1967 | + $patrol = true; // mark by default |
| 1968 | + } |
| 1969 | + if( $patrol ) { |
1921 | 1970 | $dbw = wfGetDB( DB_MASTER ); |
1922 | 1971 | $dbw->update( 'recentchanges', |
1923 | 1972 | array( 'rc_patrolled' => 1 ), |
Index: trunk/extensions/FlaggedRevs/FlaggedArticle.php |
— | — | @@ -499,7 +499,7 @@ |
500 | 500 | public function addPatrolLink( $article, &$outputDone, &$pcache ) { |
501 | 501 | global $wgRequest, $wgOut, $wgUser, $wgLang; |
502 | 502 | # For unreviewable pages, allow for basic patrolling |
503 | | - if( !FlaggedRevs::isPageReviewable( $article->getTitle() ) ) { |
| 503 | + if( FlaggedRevs::isPagePatrollable( $article->getTitle() ) ) { |
504 | 504 | # If we have been passed an &rcid= parameter, we want to give the user a |
505 | 505 | # chance to mark this new article as patrolled. |
506 | 506 | $rcid = $wgRequest->getIntOrNull( 'rcid' ); |
— | — | @@ -802,7 +802,7 @@ |
803 | 803 | } |
804 | 804 | } |
805 | 805 | // Prepare a change patrol link, if applicable |
806 | | - } else if( $wgUser->isAllowed( 'review' ) ) { |
| 806 | + } else if( FlaggedRevs::isPagePatrollable( $NewRev->getTitle() ) && $wgUser->isAllowed( 'review' ) ) { |
807 | 807 | // If we've been given an explicit change identifier, use it; saves time |
808 | 808 | if( $diff->mRcidMarkPatrolled ) { |
809 | 809 | $rcid = $diff->mRcidMarkPatrolled; |
Index: trunk/extensions/FlaggedRevs/FlaggedRevsPage.i18n.php |
— | — | @@ -243,6 +243,9 @@ |
244 | 244 | 'qualityoversight' => 'Quality oversight', |
245 | 245 | 'qualityoversight-list' => 'This page lists recent approvals of quality revisions as well as depreciations of quality revisions.', |
246 | 246 | |
| 247 | + 'depreciationoversight' => 'Depreciation oversight', |
| 248 | + 'depreciationoversight-list' => 'This page lists recent depreciations of revisions.', |
| 249 | + |
247 | 250 | 'rights-editor-autosum' => 'autopromoted', |
248 | 251 | 'rights-editor-revoke' => 'removed editor status from [[$1]]', |
249 | 252 | |
Index: trunk/extensions/FlaggedRevs/FlaggedRevsPage.php |
— | — | @@ -1671,12 +1671,12 @@ |
1672 | 1672 | } |
1673 | 1673 | |
1674 | 1674 | function execute( $par ) { |
1675 | | - global $wgOut, $wgUser, $wgRCMaxAge; |
| 1675 | + global $wgOut, $wgUser, $wgFlaggedRevsOversightAge; |
1676 | 1676 | $this->setHeaders(); |
1677 | 1677 | $wgOut->addHTML( wfMsgExt('qualityoversight-list', array('parse') ) ); |
1678 | 1678 | # Create a LogPager item to get the results and a LogEventsList |
1679 | 1679 | # item to format them... |
1680 | | - $cutoff = time() - $wgRCMaxAge; |
| 1680 | + $cutoff = time() - $wgFlaggedRevsOversightAge; |
1681 | 1681 | $loglist = new LogEventsList( $wgUser->getSkin(), $wgOut, 0 ); |
1682 | 1682 | $pager = new LogPager( $loglist, 'review', '', '', '', |
1683 | 1683 | array('log_action' => array('approve2','unapprove2'), "log_timestamp > '$cutoff'" ) ); |
— | — | @@ -1695,3 +1695,35 @@ |
1696 | 1696 | } |
1697 | 1697 | } |
1698 | 1698 | } |
| 1699 | + |
| 1700 | +class DepreciationOversight extends SpecialPage |
| 1701 | +{ |
| 1702 | + function __construct() { |
| 1703 | + SpecialPage::SpecialPage( 'DepreciationOversight' ); |
| 1704 | + } |
| 1705 | + |
| 1706 | + function execute( $par ) { |
| 1707 | + global $wgOut, $wgUser, $wgFlaggedRevsOversightAge; |
| 1708 | + $this->setHeaders(); |
| 1709 | + $wgOut->addHTML( wfMsgExt('depreciationoversight-list', array('parse') ) ); |
| 1710 | + # Create a LogPager item to get the results and a LogEventsList |
| 1711 | + # item to format them... |
| 1712 | + $cutoff = time() - $wgFlaggedRevsOversightAge; |
| 1713 | + $loglist = new LogEventsList( $wgUser->getSkin(), $wgOut, 0 ); |
| 1714 | + $pager = new LogPager( $loglist, 'review', '', '', '', |
| 1715 | + array('log_action' => array('unapprove','unapprove2'), "log_timestamp > '$cutoff'" ) ); |
| 1716 | + # Insert list |
| 1717 | + $logBody = $pager->getBody(); |
| 1718 | + if( $logBody ) { |
| 1719 | + $wgOut->addHTML( |
| 1720 | + $pager->getNavigationBar() . |
| 1721 | + $loglist->beginLogEventsList() . |
| 1722 | + $logBody . |
| 1723 | + $loglist->endLogEventsList() . |
| 1724 | + $pager->getNavigationBar() |
| 1725 | + ); |
| 1726 | + } else { |
| 1727 | + $wgOut->addWikiMsg( 'logempty' ); |
| 1728 | + } |
| 1729 | + } |
| 1730 | +} |