MediaWiki  REL1_24
MWNamespace.php
Go to the documentation of this file.
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 }