Index: trunk/extensions/FlaggedRevs/FlaggedRevs.class.php |
— | — | @@ -1,16 +1,27 @@ |
2 | 2 | <?php |
3 | | - |
| 3 | +/** |
| 4 | + * Class containing utility functions for a FlaggedRevs environment |
| 5 | + * |
| 6 | + * Class is lazily-initialized, calling load() as needed |
| 7 | + */ |
4 | 8 | class FlaggedRevs { |
| 9 | + # Tag name/level config |
5 | 10 | protected static $dimensions = array(); |
6 | 11 | protected static $minSL = array(); |
7 | 12 | protected static $minQL = array(); |
8 | 13 | protected static $minPL = array(); |
9 | | - protected static $loaded = false; |
10 | 14 | protected static $qualityVersions = false; |
11 | 15 | protected static $pristineVersions = false; |
| 16 | + # Namespace config |
| 17 | + protected static $reviewNamespaces = array(); |
| 18 | + protected static $patrolNamespaces = array(); |
| 19 | + # Restriction levels/config |
12 | 20 | protected static $restrictionLevels = array(); |
13 | | - |
| 21 | + protected static $protectionLevels = array(); |
| 22 | + # Temporary process cache variable |
14 | 23 | protected static $includeVersionCache = array(); |
| 24 | + |
| 25 | + protected static $loaded = false; |
15 | 26 | |
16 | 27 | public static function load() { |
17 | 28 | global $wgFlaggedRevTags; |
— | — | @@ -60,15 +71,18 @@ |
61 | 72 | } |
62 | 73 | global $wgFlaggedRevsProtectLevels; |
63 | 74 | $wgFlaggedRevsProtectLevels = (array)$wgFlaggedRevsProtectLevels; |
64 | | - foreach( $wgFlaggedRevsProtectLevels as $level => &$config ) { |
| 75 | + foreach( $wgFlaggedRevsProtectLevels as $level => $config ) { |
65 | 76 | # Sanity check that the config is complete |
66 | | - if( !isset($config['select']) || !isset($config['override']) || !isset($config['autoreview']) ) { |
| 77 | + if( !isset($config['select']) || !isset($config['override']) |
| 78 | + || !isset($config['autoreview']) |
| 79 | + ) { |
67 | 80 | throw new MWException( 'FlaggedRevs given incomplete $wgFlaggedRevsProtectLevels value!' ); |
68 | 81 | # Disallow reserved level names |
69 | 82 | } else if( $level == 'invalid' || $level == 'none' ) { |
70 | 83 | throw new MWException( 'FlaggedRevs given reserved $wgFlaggedRevsProtectLevels key!' ); |
71 | 84 | } |
72 | 85 | $config['override'] = intval( $config['override'] ); // Type cleanup |
| 86 | + self::$protectionLevels[$level] = $config; |
73 | 87 | } |
74 | 88 | global $wgFlaggedRevsRestrictionLevels; |
75 | 89 | # Make sure that there is a "none" level |
— | — | @@ -76,6 +90,22 @@ |
77 | 91 | if( !in_array('',self::$restrictionLevels) ) { |
78 | 92 | self::$restrictionLevels = array('') + self::$restrictionLevels; |
79 | 93 | } |
| 94 | + # Make sure no talk namespaces are in review namespace |
| 95 | + global $wgFlaggedRevsNamespaces; |
| 96 | + foreach( $wgFlaggedRevsNamespaces as $ns ) { |
| 97 | + if( MWNamespace::isTalk($ns) ) { |
| 98 | + throw new MWException( 'FlaggedRevs given talk namespace in $wgFlaggedRevsNamespaces!' ); |
| 99 | + } else if( $ns == NS_MEDIAWIKI ) { |
| 100 | + throw new MWException( 'FlaggedRevs given NS_MEDIAWIKI in $wgFlaggedRevsNamespaces!' ); |
| 101 | + } |
| 102 | + } |
| 103 | + self::$reviewNamespaces = $wgFlaggedRevsNamespaces; |
| 104 | + # Reviewable namespaces override patrolable ones |
| 105 | + global $wgFlaggedRevsPatrolNamespaces; |
| 106 | + self::$patrolNamespaces = array_diff( |
| 107 | + $wgFlaggedRevsPatrolNamespaces, $wgFlaggedRevsNamespaces |
| 108 | + ); |
| 109 | + |
80 | 110 | self::$loaded = true; |
81 | 111 | } |
82 | 112 | |
— | — | @@ -195,9 +225,8 @@ |
196 | 226 | * @returns array (associative) |
197 | 227 | */ |
198 | 228 | public static function getProtectionLevels() { |
199 | | - global $wgFlaggedRevsProtectLevels; |
200 | 229 | self::load(); // validates levels |
201 | | - return $wgFlaggedRevsProtectLevels; |
| 230 | + return self::$protectionLevels; |
202 | 231 | } |
203 | 232 | |
204 | 233 | /** |
— | — | @@ -1075,12 +1104,16 @@ |
1076 | 1105 | # Get the highest quality revision (not necessarily this one). |
1077 | 1106 | $oldid = $dbr->selectField( array('flaggedrevs','revision'), |
1078 | 1107 | 'fr_rev_id', |
1079 | | - array( 'fr_page_id' => $article->getId(), |
| 1108 | + array( |
| 1109 | + 'fr_page_id' => $article->getId(), |
1080 | 1110 | 'rev_page = fr_page_id', |
1081 | | - 'rev_id = fr_rev_id'), |
| 1111 | + 'rev_id = fr_rev_id' |
| 1112 | + ), |
1082 | 1113 | __METHOD__, |
1083 | | - array( 'ORDER BY' => 'fr_quality DESC, fr_rev_id DESC', |
1084 | | - 'USE INDEX' => array('flaggedrevs' => 'page_qal_rev','revision' => 'PRIMARY') ) |
| 1114 | + array( |
| 1115 | + 'ORDER BY' => 'fr_quality DESC, fr_rev_id DESC', |
| 1116 | + 'USE INDEX' => array('flaggedrevs' => 'page_qal_rev','revision' => 'PRIMARY') |
| 1117 | + ) |
1085 | 1118 | ); |
1086 | 1119 | return $oldid; |
1087 | 1120 | } |
— | — | @@ -1216,21 +1249,42 @@ |
1217 | 1250 | else |
1218 | 1251 | return 0; |
1219 | 1252 | } |
| 1253 | + |
| 1254 | + /** |
| 1255 | + * Get the list of reviewable namespaces |
| 1256 | + * @return array |
| 1257 | + */ |
| 1258 | + public static function getReviewNamespaces() { |
| 1259 | + self::load(); // validates namespaces |
| 1260 | + return self::$reviewNamespaces; |
| 1261 | + } |
1220 | 1262 | |
1221 | 1263 | /** |
| 1264 | + * Get the list of patrolable namespaces |
| 1265 | + * @return array |
| 1266 | + */ |
| 1267 | + public static function getPatrolNamespaces() { |
| 1268 | + self::load(); // validates namespaces |
| 1269 | + return self::$patrolNamespaces; |
| 1270 | + } |
| 1271 | + |
| 1272 | + |
| 1273 | + /** |
1222 | 1274 | * Is this page in reviewable namespace? |
| 1275 | + * Note: this checks $wgFlaggedRevsWhitelist |
1223 | 1276 | * @param Title, $title |
1224 | 1277 | * @return bool |
1225 | 1278 | */ |
1226 | 1279 | public static function isPageReviewable( $title ) { |
1227 | | - global $wgFlaggedRevsNamespaces, $wgFlaggedRevsWhitelist; |
1228 | | - # FIXME: Treat NS_MEDIA as NS_FILE |
1229 | | - $ns = ( $title->getNamespace() == NS_MEDIA ) ? NS_FILE : $title->getNamespace(); |
| 1280 | + global $wgFlaggedRevsWhitelist; |
| 1281 | + $namespaces = self::getReviewNamespaces(); |
| 1282 | + $ns = ( $title->getNamespace() == NS_MEDIA ) ? |
| 1283 | + NS_FILE : $title->getNamespace(); // Treat NS_MEDIA as NS_FILE |
1230 | 1284 | # Check for MW: pages and whitelist for exempt pages |
1231 | | - if( $ns == NS_MEDIAWIKI || in_array( $title->getPrefixedDBKey(), $wgFlaggedRevsWhitelist ) ) { |
| 1285 | + if( in_array( $title->getPrefixedDBKey(), $wgFlaggedRevsWhitelist ) ) { |
1232 | 1286 | return false; |
1233 | 1287 | } |
1234 | | - return ( in_array($ns,$wgFlaggedRevsNamespaces) && !$title->isTalkPage() ); |
| 1288 | + return ( in_array($ns,$namespaces) ); |
1235 | 1289 | } |
1236 | 1290 | |
1237 | 1291 | /** |
— | — | @@ -1239,14 +1293,10 @@ |
1240 | 1294 | * @return bool |
1241 | 1295 | */ |
1242 | 1296 | public static function isPagePatrollable( $title ) { |
1243 | | - global $wgFlaggedRevsPatrolNamespaces; |
1244 | | - # No collisions! |
1245 | | - if( self::isPageReviewable($title) ) { |
1246 | | - return false; |
1247 | | - } |
1248 | | - # FIXME: Treat NS_MEDIA as NS_FILE |
1249 | | - $ns = ( $title->getNamespace() == NS_MEDIA ) ? NS_FILE : $title->getNamespace(); |
1250 | | - return ( in_array($ns,$wgFlaggedRevsPatrolNamespaces) ); |
| 1297 | + $namespaces = self::getPatrolNamespaces(); |
| 1298 | + $ns = ( $title->getNamespace() == NS_MEDIA ) ? |
| 1299 | + NS_FILE : $title->getNamespace(); // Treat NS_MEDIA as NS_FILE |
| 1300 | + return ( in_array($ns,$namespaces) ); |
1251 | 1301 | } |
1252 | 1302 | |
1253 | 1303 | /** |