MediaWiki
REL1_24
|
00001 <?php 00033 class MWNamespace { 00034 00040 private static $alwaysCapitalizedNamespaces = array( NS_SPECIAL, NS_USER, NS_MEDIAWIKI ); 00041 00054 private static function isMethodValidFor( $index, $method ) { 00055 if ( $index < NS_MAIN ) { 00056 throw new MWException( "$method does not make any sense for given namespace $index" ); 00057 } 00058 return true; 00059 } 00060 00067 public static function isMovable( $index ) { 00068 global $wgAllowImageMoving; 00069 00070 $result = !( $index < NS_MAIN || ( $index == NS_FILE && !$wgAllowImageMoving ) ); 00071 00075 wfRunHooks( 'NamespaceIsMovable', array( $index, &$result ) ); 00076 00077 return $result; 00078 } 00079 00087 public static function isSubject( $index ) { 00088 return !self::isTalk( $index ); 00089 } 00090 00097 public static function isTalk( $index ) { 00098 return $index > NS_MAIN 00099 && $index % 2; 00100 } 00101 00108 public static function getTalk( $index ) { 00109 self::isMethodValidFor( $index, __METHOD__ ); 00110 return self::isTalk( $index ) 00111 ? $index 00112 : $index + 1; 00113 } 00114 00122 public static function getSubject( $index ) { 00123 # Handle special namespaces 00124 if ( $index < NS_MAIN ) { 00125 return $index; 00126 } 00127 00128 return self::isTalk( $index ) 00129 ? $index - 1 00130 : $index; 00131 } 00132 00141 public static function getAssociated( $index ) { 00142 self::isMethodValidFor( $index, __METHOD__ ); 00143 00144 if ( self::isSubject( $index ) ) { 00145 return self::getTalk( $index ); 00146 } elseif ( self::isTalk( $index ) ) { 00147 return self::getSubject( $index ); 00148 } else { 00149 return null; 00150 } 00151 } 00152 00161 public static function exists( $index ) { 00162 $nslist = self::getCanonicalNamespaces(); 00163 return isset( $nslist[$index] ); 00164 } 00165 00180 public static function equals( $ns1, $ns2 ) { 00181 return $ns1 == $ns2; 00182 } 00183 00195 public static function subjectEquals( $ns1, $ns2 ) { 00196 return self::getSubject( $ns1 ) == self::getSubject( $ns2 ); 00197 } 00198 00208 public static function getCanonicalNamespaces( $rebuild = false ) { 00209 static $namespaces = null; 00210 if ( $namespaces === null || $rebuild ) { 00211 global $wgExtraNamespaces, $wgCanonicalNamespaceNames; 00212 $namespaces = array( NS_MAIN => '' ) + $wgCanonicalNamespaceNames; 00213 if ( is_array( $wgExtraNamespaces ) ) { 00214 $namespaces += $wgExtraNamespaces; 00215 } 00216 wfRunHooks( 'CanonicalNamespaces', array( &$namespaces ) ); 00217 } 00218 return $namespaces; 00219 } 00220 00227 public static function getCanonicalName( $index ) { 00228 $nslist = self::getCanonicalNamespaces(); 00229 if ( isset( $nslist[$index] ) ) { 00230 return $nslist[$index]; 00231 } else { 00232 return false; 00233 } 00234 } 00235 00243 public static function getCanonicalIndex( $name ) { 00244 static $xNamespaces = false; 00245 if ( $xNamespaces === false ) { 00246 $xNamespaces = array(); 00247 foreach ( self::getCanonicalNamespaces() as $i => $text ) { 00248 $xNamespaces[strtolower( $text )] = $i; 00249 } 00250 } 00251 if ( array_key_exists( $name, $xNamespaces ) ) { 00252 return $xNamespaces[$name]; 00253 } else { 00254 return null; 00255 } 00256 } 00257 00263 public static function getValidNamespaces() { 00264 static $mValidNamespaces = null; 00265 00266 if ( is_null( $mValidNamespaces ) ) { 00267 foreach ( array_keys( self::getCanonicalNamespaces() ) as $ns ) { 00268 if ( $ns >= 0 ) { 00269 $mValidNamespaces[] = $ns; 00270 } 00271 } 00272 } 00273 00274 return $mValidNamespaces; 00275 } 00276 00283 public static function canTalk( $index ) { 00284 return $index >= NS_MAIN; 00285 } 00286 00294 public static function isContent( $index ) { 00295 global $wgContentNamespaces; 00296 return $index == NS_MAIN || in_array( $index, $wgContentNamespaces ); 00297 } 00298 00305 public static function isWatchable( $index ) { 00306 return $index >= NS_MAIN; 00307 } 00308 00315 public static function hasSubpages( $index ) { 00316 global $wgNamespacesWithSubpages; 00317 return !empty( $wgNamespacesWithSubpages[$index] ); 00318 } 00319 00324 public static function getContentNamespaces() { 00325 global $wgContentNamespaces; 00326 if ( !is_array( $wgContentNamespaces ) || $wgContentNamespaces === array() ) { 00327 return array( NS_MAIN ); 00328 } elseif ( !in_array( NS_MAIN, $wgContentNamespaces ) ) { 00329 // always force NS_MAIN to be part of array (to match the algorithm used by isContent) 00330 return array_merge( array( NS_MAIN ), $wgContentNamespaces ); 00331 } else { 00332 return $wgContentNamespaces; 00333 } 00334 } 00335 00342 public static function getSubjectNamespaces() { 00343 return array_filter( 00344 MWNamespace::getValidNamespaces(), 00345 'MWNamespace::isSubject' 00346 ); 00347 } 00348 00355 public static function getTalkNamespaces() { 00356 return array_filter( 00357 MWNamespace::getValidNamespaces(), 00358 'MWNamespace::isTalk' 00359 ); 00360 } 00361 00368 public static function isCapitalized( $index ) { 00369 global $wgCapitalLinks, $wgCapitalLinkOverrides; 00370 // Turn NS_MEDIA into NS_FILE 00371 $index = $index === NS_MEDIA ? NS_FILE : $index; 00372 00373 // Make sure to get the subject of our namespace 00374 $index = self::getSubject( $index ); 00375 00376 // Some namespaces are special and should always be upper case 00377 if ( in_array( $index, self::$alwaysCapitalizedNamespaces ) ) { 00378 return true; 00379 } 00380 if ( isset( $wgCapitalLinkOverrides[$index] ) ) { 00381 // $wgCapitalLinkOverrides is explicitly set 00382 return $wgCapitalLinkOverrides[$index]; 00383 } 00384 // Default to the global setting 00385 return $wgCapitalLinks; 00386 } 00387 00396 public static function hasGenderDistinction( $index ) { 00397 return $index == NS_USER || $index == NS_USER_TALK; 00398 } 00399 00407 public static function isNonincludable( $index ) { 00408 global $wgNonincludableNamespaces; 00409 return $wgNonincludableNamespaces && in_array( $index, $wgNonincludableNamespaces ); 00410 } 00411 00420 public static function getNamespaceContentModel( $index ) { 00421 global $wgNamespaceContentModels; 00422 return isset( $wgNamespaceContentModels[$index] ) 00423 ? $wgNamespaceContentModels[$index] 00424 : null; 00425 } 00426 00436 public static function getRestrictionLevels( $index, User $user = null ) { 00437 global $wgNamespaceProtection, $wgRestrictionLevels; 00438 00439 if ( !isset( $wgNamespaceProtection[$index] ) ) { 00440 // All levels are valid if there's no namespace restriction. 00441 // But still filter by user, if necessary 00442 $levels = $wgRestrictionLevels; 00443 if ( $user ) { 00444 $levels = array_values( array_filter( $levels, function ( $level ) use ( $user ) { 00445 $right = $level; 00446 if ( $right == 'sysop' ) { 00447 $right = 'editprotected'; // BC 00448 } 00449 if ( $right == 'autoconfirmed' ) { 00450 $right = 'editsemiprotected'; // BC 00451 } 00452 return ( $right == '' || $user->isAllowed( $right ) ); 00453 } ) ); 00454 } 00455 return $levels; 00456 } 00457 00458 // First, get the list of groups that can edit this namespace. 00459 $namespaceGroups = array(); 00460 $combine = 'array_merge'; 00461 foreach ( (array)$wgNamespaceProtection[$index] as $right ) { 00462 if ( $right == 'sysop' ) { 00463 $right = 'editprotected'; // BC 00464 } 00465 if ( $right == 'autoconfirmed' ) { 00466 $right = 'editsemiprotected'; // BC 00467 } 00468 if ( $right != '' ) { 00469 $namespaceGroups = call_user_func( $combine, $namespaceGroups, 00470 User::getGroupsWithPermission( $right ) ); 00471 $combine = 'array_intersect'; 00472 } 00473 } 00474 00475 // Now, keep only those restriction levels where there is at least one 00476 // group that can edit the namespace but would be blocked by the 00477 // restriction. 00478 $usableLevels = array( '' ); 00479 foreach ( $wgRestrictionLevels as $level ) { 00480 $right = $level; 00481 if ( $right == 'sysop' ) { 00482 $right = 'editprotected'; // BC 00483 } 00484 if ( $right == 'autoconfirmed' ) { 00485 $right = 'editsemiprotected'; // BC 00486 } 00487 if ( $right != '' && ( !$user || $user->isAllowed( $right ) ) && 00488 array_diff( $namespaceGroups, User::getGroupsWithPermission( $right ) ) 00489 ) { 00490 $usableLevels[] = $level; 00491 } 00492 } 00493 00494 return $usableLevels; 00495 } 00496 }