62 public static $canonicalNames = [
89 public static $constructorOptions = [
91 'CanonicalNamespaceNames',
92 'CapitalLinkOverrides',
96 'ExtraSignatureNamespaces',
97 'NamespaceContentModels',
98 'NamespacesWithSubpages',
99 'NonincludableNamespaces',
107 $this->options = $options;
124 throw new MWException(
"$method does not make any sense for given namespace $index" );
137 ( $index !=
NS_FILE || $this->options->get(
'AllowImageMoving' ) );
142 Hooks::run(
'NamespaceIsMovable', [ $index, &$result ] );
154 return !$this->
isTalk( $index );
178 return $this->
isTalk( $index )
193 if ( $target->getText() ===
'' ) {
194 throw new MWException(
'Can\'t determine talk page associated with relative section link' );
197 if ( $target->getInterwiki() !==
'' ) {
198 throw new MWException(
'Can\'t determine talk page associated with interwiki link' );
201 if ( $this->
isTalk( $target->getNamespace() ) ) {
206 return new TitleValue( $this->
getTalk( $target->getNamespace() ), $target->getDBkey() );
240 # Handle special namespaces
245 return $this->isTalk( $index )
255 if ( $this->isSubject( $target->getNamespace() ) ) {
258 return new TitleValue( $this->getSubject( $target->getNamespace() ), $target->getDBkey() );
271 $this->isMethodValidFor( $index, __METHOD__ );
273 if ( $this->isSubject( $index ) ) {
274 return $this->getTalk( $index );
276 return $this->getSubject( $index );
286 if ( $target->getText() ===
'' ) {
287 throw new MWException(
'Can\'t determine talk page associated with relative section link' );
290 if ( $target->getInterwiki() !==
'' ) {
291 throw new MWException(
'Can\'t determine talk page associated with interwiki link' );
295 $this->getAssociated( $target->getNamespace() ), $target->getDBkey() );
306 $nslist = $this->getCanonicalNamespaces();
307 return isset( $nslist[$index] );
338 return $this->getSubject( $ns1 ) == $this->getSubject( $ns2 );
348 if ( $this->canonicalNamespaces ===
null ) {
349 $this->canonicalNamespaces =
350 [
NS_MAIN =>
'' ] + $this->options->get(
'CanonicalNamespaceNames' );
351 $this->canonicalNamespaces +=
352 ExtensionRegistry::getInstance()->getAttribute(
'ExtensionNamespaces' );
353 if ( is_array( $this->options->get(
'ExtraNamespaces' ) ) ) {
354 $this->canonicalNamespaces += $this->options->get(
'ExtraNamespaces' );
356 Hooks::run(
'CanonicalNamespaces', [ &$this->canonicalNamespaces ] );
358 return $this->canonicalNamespaces;
368 $nslist = $this->getCanonicalNamespaces();
369 return $nslist[$index] ??
false;
380 if ( $this->namespaceIndexes ===
false ) {
381 $this->namespaceIndexes = [];
382 foreach ( $this->getCanonicalNamespaces() as $i => $text ) {
383 $this->namespaceIndexes[strtolower( $text )] = $i;
386 if ( array_key_exists( $name, $this->namespaceIndexes ) ) {
387 return $this->namespaceIndexes[$name];
399 if ( is_null( $this->validNamespaces ) ) {
400 $this->validNamespaces = [];
401 foreach ( array_keys( $this->getCanonicalNamespaces() ) as $ns ) {
403 $this->validNamespaces[] = $ns;
407 sort( $this->validNamespaces, SORT_NUMERIC );
410 return $this->validNamespaces;
421 public function hasTalkNamespace( $index ) {
422 return $index >= NS_MAIN;
432 public function isContent( $index ) {
433 return $index == NS_MAIN || in_array( $index, $this->options->get( 'ContentNamespaces' ) );
443 public function wantSignatures( $index ) {
444 return $this->isTalk( $index ) ||
445 in_array( $index, $this->options->get( 'ExtraSignatureNamespaces' ) );
454 public function isWatchable( $index ) {
455 return $index >= NS_MAIN;
464 public function hasSubpages( $index ) {
465 return !empty( $this->options->get( 'NamespacesWithSubpages' )[$index] );
472 public function getContentNamespaces() {
473 $contentNamespaces = $this->options->get( 'ContentNamespaces' );
474 if ( !is_array( $contentNamespaces ) || $contentNamespaces === [] ) {
476 } elseif ( !in_array( NS_MAIN, $contentNamespaces ) ) {
477 // always force NS_MAIN to be part of array (to match the algorithm used by isContent)
478 return array_merge( [ NS_MAIN ], $contentNamespaces );
480 return $contentNamespaces;
490 public function getSubjectNamespaces() {
492 $this->getValidNamespaces(),
493 [ $this, 'isSubject' ]
503 public function getTalkNamespaces() {
505 $this->getValidNamespaces(),
516 public function isCapitalized( $index ) {
517 // Turn NS_MEDIA into NS_FILE
518 $index = $index === NS_MEDIA ? NS_FILE : $index;
520 // Make sure to get the subject of our namespace
521 $index = $this->getSubject( $index );
523 // Some namespaces are special and should always be upper case
524 if ( in_array( $index, $this->alwaysCapitalizedNamespaces ) ) {
527 $overrides = $this->options->get( 'CapitalLinkOverrides' );
528 if ( isset( $overrides[$index] ) ) {
529 // CapitalLinkOverrides is explicitly set
530 return $overrides[$index];
532 // Default to the global setting
533 return $this->options->get( 'CapitalLinks' );
543 public function hasGenderDistinction( $index ) {
544 return $index == NS_USER || $index == NS_USER_TALK;
553 public function isNonincludable( $index ) {
554 $namespaces = $this->options->get( 'NonincludableNamespaces' );
555 return $namespaces && in_array( $index, $namespaces );
568 public function getNamespaceContentModel( $index ) {
569 return $this->options->get( 'NamespaceContentModels' )[$index] ?? null;
581 public function getRestrictionLevels( $index, User $user = null ) {
582 // PermissionManager is not injected because adding an explicit dependency
583 // breaks MW installer by adding a dependency chain on the database before
584 // it was set up. Also, the method is deprecated and will be soon removed.
585 return MediaWikiServices::getInstance()
586 ->getPermissionManager()
587 ->getNamespaceRestrictionLevels( $index, $user );
599 public function getCategoryLinkType( $index ) {
600 $this->isMethodValidFor( $index, __METHOD__ );
602 if ( $index == NS_CATEGORY ) {
604 } elseif ( $index == NS_FILE ) {
618 public static function getCommonNamespaces() {
619 return array_keys( self::$canonicalNames );
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
getAssociatedPage(LinkTarget $target)
__construct(ServiceOptions $options)
static array $canonicalNames
Definitions of the NS_ constants are in Defines.php.
equals( $ns1, $ns2)
Returns whether the specified namespaces are the same namespace.
subjectEquals( $ns1, $ns2)
Returns whether the specified namespaces share the same subject.
getCanonicalName( $index)
Returns the canonical (English) name for a given index.
string[] null $canonicalNamespaces
Canonical namespaces cache.
isSubject( $index)
Is the given namespace is a subject (non-talk) namespace?
$alwaysCapitalizedNamespaces
These namespaces should always be first-letter capitalized, now and forevermore.
getValidNamespaces()
Returns an array of the namespaces (by integer id) that exist on the wiki.
exists( $index)
Returns whether the specified namespace exists.
getSubjectPage(LinkTarget $target)
isMethodValidFor( $index, $method)
Throw an exception when trying to get the subject or talk page for a given namespace where it does no...
int[] null $validNamespaces
Valid namespaces cache.
getCanonicalNamespaces()
Returns array of all defined namespaces with their canonical (English) names.
getSubject( $index)
Get the subject namespace index for a given namespace Special namespaces (NS_MEDIA,...
static array $constructorOptions
TODO Make this const when HHVM support is dropped (T192166)
array false $namespaceIndexes
Canonical namespaces index cache.
canHaveTalkPage(LinkTarget $target)
Can the title have a corresponding talk page?
getTalk( $index)
Get the talk namespace index for a given namespace.
isMovable( $index)
Can pages in the given namespace be moved?
getAssociated( $index)
Get the associated namespace.
getTalkPage(LinkTarget $target)
Get a LinkTarget referring to the talk page of $target.
isTalk( $index)
Is the given namespace a talk namespace?
getCanonicalIndex( $name)
Returns the index for a given canonical name, or NULL The input must be converted to lower case first...
Represents a page (or page fragment) title within MediaWiki.