* @file
*/
+use MediaWiki\Config\ServiceOptions;
+
/**
* This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of
* them based on index. The textual names of the namespaces are handled by Language.php.
*
- * @since 1.33
+ * @since 1.34
*/
class NamespaceInfo {
/** @var int[]|null Valid namespaces cache */
private $validNamespaces = null;
- /** @var Config */
- private $config;
+ /** @var ServiceOptions */
+ private $options;
+
+ /**
+ * TODO Make this const when HHVM support is dropped (T192166)
+ *
+ * @since 1.34
+ * @var array
+ */
+ public static $constructorOptions = [
+ 'AllowImageMoving',
+ 'CanonicalNamespaceNames',
+ 'CapitalLinkOverrides',
+ 'CapitalLinks',
+ 'ContentNamespaces',
+ 'ExtraNamespaces',
+ 'ExtraSignatureNamespaces',
+ 'NamespaceContentModels',
+ 'NamespaceProtection',
+ 'NamespacesWithSubpages',
+ 'NonincludableNamespaces',
+ 'RestrictionLevels',
+ ];
/**
- * @param Config $config
+ * @param ServiceOptions $options
*/
- public function __construct( Config $config ) {
- $this->config = $config;
+ public function __construct( ServiceOptions $options ) {
+ $options->assertRequiredOptions( self::$constructorOptions );
+ $this->options = $options;
}
/**
* @return bool
*/
public function isMovable( $index ) {
- $result = !( $index < NS_MAIN ||
- ( $index == NS_FILE && !$this->config->get( 'AllowImageMoving' ) ) );
+ $result = $index >= NS_MAIN &&
+ ( $index != NS_FILE || $this->options->get( 'AllowImageMoving' ) );
/**
* @since 1.20
* For subject (non-talk) namespaces, returns the talk namespace
*
* @param int $index Namespace index
- * @return int|null If no associated namespace could be found
+ * @return int
*/
public function getAssociated( $index ) {
$this->isMethodValidFor( $index, __METHOD__ );
if ( $this->isSubject( $index ) ) {
return $this->getTalk( $index );
- } elseif ( $this->isTalk( $index ) ) {
- return $this->getSubject( $index );
- } else {
- return null;
}
+ return $this->getSubject( $index );
}
/**
public function getCanonicalNamespaces() {
if ( $this->canonicalNamespaces === null ) {
$this->canonicalNamespaces =
- [ NS_MAIN => '' ] + $this->config->get( 'CanonicalNamespaceNames' );
+ [ NS_MAIN => '' ] + $this->options->get( 'CanonicalNamespaceNames' );
$this->canonicalNamespaces +=
ExtensionRegistry::getInstance()->getAttribute( 'ExtensionNamespaces' );
- if ( is_array( $this->config->get( 'ExtraNamespaces' ) ) ) {
- $this->canonicalNamespaces += $this->config->get( 'ExtraNamespaces' );
+ if ( is_array( $this->options->get( 'ExtraNamespaces' ) ) ) {
+ $this->canonicalNamespaces += $this->options->get( 'ExtraNamespaces' );
}
Hooks::run( 'CanonicalNamespaces', [ &$this->canonicalNamespaces ] );
}
* The input *must* be converted to lower case first
*
* @param string $name Namespace name
- * @return int
+ * @return int|null
*/
public function getCanonicalIndex( $name ) {
if ( $this->namespaceIndexes === false ) {
}
/**
- * Returns an array of the namespaces (by integer id) that exist on the
- * wiki. Used primarily by the api in help documentation.
+ * Returns an array of the namespaces (by integer id) that exist on the wiki. Used primarily by
+ * the API in help documentation. The array is sorted numerically and omits negative namespaces.
* @return array
*/
public function getValidNamespaces() {
* @return bool
*/
public function isContent( $index ) {
- return $index == NS_MAIN || in_array( $index, $this->config->get( 'ContentNamespaces' ) );
+ return $index == NS_MAIN || in_array( $index, $this->options->get( 'ContentNamespaces' ) );
}
/**
*/
public function wantSignatures( $index ) {
return $this->isTalk( $index ) ||
- in_array( $index, $this->config->get( 'ExtraSignatureNamespaces' ) );
+ in_array( $index, $this->options->get( 'ExtraSignatureNamespaces' ) );
}
/**
* @return bool
*/
public function hasSubpages( $index ) {
- return !empty( $this->config->get( 'NamespacesWithSubpages' )[$index] );
+ return !empty( $this->options->get( 'NamespacesWithSubpages' )[$index] );
}
/**
* @return array Array of namespace indices
*/
public function getContentNamespaces() {
- $contentNamespaces = $this->config->get( 'ContentNamespaces' );
+ $contentNamespaces = $this->options->get( 'ContentNamespaces' );
if ( !is_array( $contentNamespaces ) || $contentNamespaces === [] ) {
return [ NS_MAIN ];
} elseif ( !in_array( NS_MAIN, $contentNamespaces ) ) {
if ( in_array( $index, $this->alwaysCapitalizedNamespaces ) ) {
return true;
}
- $overrides = $this->config->get( 'CapitalLinkOverrides' );
+ $overrides = $this->options->get( 'CapitalLinkOverrides' );
if ( isset( $overrides[$index] ) ) {
// CapitalLinkOverrides is explicitly set
return $overrides[$index];
}
// Default to the global setting
- return $this->config->get( 'CapitalLinks' );
+ return $this->options->get( 'CapitalLinks' );
}
/**
* @return bool
*/
public function isNonincludable( $index ) {
- $namespaces = $this->config->get( 'NonincludableNamespaces' );
+ $namespaces = $this->options->get( 'NonincludableNamespaces' );
return $namespaces && in_array( $index, $namespaces );
}
* @return null|string Default model name for the given namespace, if set
*/
public function getNamespaceContentModel( $index ) {
- return $this->config->get( 'NamespaceContentModels' )[$index] ?? null;
+ return $this->options->get( 'NamespaceContentModels' )[$index] ?? null;
}
/**
* Determine which restriction levels it makes sense to use in a namespace,
* optionally filtered by a user's rights.
*
+ * @todo Move this to PermissionManager and remove the dependency here on permissions-related
+ * config settings.
+ *
* @param int $index Index to check
* @param User|null $user User to check
* @return array
*/
public function getRestrictionLevels( $index, User $user = null ) {
- if ( !isset( $this->config->get( 'NamespaceProtection' )[$index] ) ) {
+ if ( !isset( $this->options->get( 'NamespaceProtection' )[$index] ) ) {
// All levels are valid if there's no namespace restriction.
// But still filter by user, if necessary
- $levels = $this->config->get( 'RestrictionLevels' );
+ $levels = $this->options->get( 'RestrictionLevels' );
if ( $user ) {
$levels = array_values( array_filter( $levels, function ( $level ) use ( $user ) {
$right = $level;
// First, get the list of groups that can edit this namespace.
$namespaceGroups = [];
$combine = 'array_merge';
- foreach ( (array)$this->config->get( 'NamespaceProtection' )[$index] as $right ) {
+ foreach ( (array)$this->options->get( 'NamespaceProtection' )[$index] as $right ) {
if ( $right == 'sysop' ) {
$right = 'editprotected'; // BC
}
// group that can edit the namespace but would be blocked by the
// restriction.
$usableLevels = [ '' ];
- foreach ( $this->config->get( 'RestrictionLevels' ) as $level ) {
+ foreach ( $this->options->get( 'RestrictionLevels' ) as $level ) {
$right = $level;
if ( $right == 'sysop' ) {
$right = 'editprotected'; // BC