X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Ftitle%2FNamespaceInfo.php;h=7cfadc01441e04df3b55a1606d25b34b208e9ee9;hp=f9cab244580b288b902a2b5617e2b50f764b1e1e;hb=a3cd158d8433e41cbeb299f0e268dfef363b2afd;hpb=27a6845c2a675990b04dfead674c0d46d140aa17 diff --git a/includes/title/NamespaceInfo.php b/includes/title/NamespaceInfo.php index f9cab24458..7cfadc0144 100644 --- a/includes/title/NamespaceInfo.php +++ b/includes/title/NamespaceInfo.php @@ -20,6 +20,9 @@ * @file */ +use MediaWiki\Config\ServiceOptions; +use MediaWiki\Linker\LinkTarget; + /** * 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. @@ -44,14 +47,36 @@ 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; } /** @@ -80,8 +105,8 @@ class NamespaceInfo { * @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 @@ -125,6 +150,18 @@ class NamespaceInfo { : $index + 1; } + /** + * @param LinkTarget $target + * @return LinkTarget Talk page for $target + * @throws MWException if $target's namespace doesn't have talk pages (e.g., NS_SPECIAL) + */ + public function getTalkPage( LinkTarget $target ) : LinkTarget { + if ( $this->isTalk( $target->getNamespace() ) ) { + return $target; + } + return new TitleValue( $this->getTalk( $target->getNamespace() ), $target->getDbKey() ); + } + /** * Get the subject namespace index for a given namespace * Special namespaces (NS_MEDIA, NS_SPECIAL) are always the subject. @@ -143,24 +180,44 @@ class NamespaceInfo { : $index; } + /** + * @param LinkTarget $target + * @return LinkTarget Subject page for $target + */ + public function getSubjectPage( LinkTarget $target ) : LinkTarget { + if ( $this->isSubject( $target->getNamespace() ) ) { + return $target; + } + return new TitleValue( $this->getSubject( $target->getNamespace() ), $target->getDbKey() ); + } + /** * Get the associated namespace. * For talk namespaces, returns the subject (non-talk) namespace * 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 + * @throws MWException if called on a namespace that has no talk pages (e.g., NS_SPECIAL) */ 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 ); + } + + /** + * @param LinkTarget $target + * @return LinkTarget Talk page for $target if it's a subject page, subject page if it's a talk + * page + * @throws MWException if $target's namespace doesn't have talk pages (e.g., NS_SPECIAL) + */ + public function getAssociatedPage( LinkTarget $target ) : LinkTarget { + return new TitleValue( + $this->getAssociated( $target->getNamespace() ), $target->getDbKey() ); } /** @@ -215,11 +272,11 @@ class NamespaceInfo { 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 ] ); } @@ -242,7 +299,7 @@ class NamespaceInfo { * 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 ) { @@ -259,8 +316,8 @@ class NamespaceInfo { } /** - * 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() { @@ -297,7 +354,7 @@ class NamespaceInfo { * @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' ) ); } /** @@ -309,7 +366,7 @@ class NamespaceInfo { */ public function wantSignatures( $index ) { return $this->isTalk( $index ) || - in_array( $index, $this->config->get( 'ExtraSignatureNamespaces' ) ); + in_array( $index, $this->options->get( 'ExtraSignatureNamespaces' ) ); } /** @@ -329,7 +386,7 @@ class NamespaceInfo { * @return bool */ public function hasSubpages( $index ) { - return !empty( $this->config->get( 'NamespacesWithSubpages' )[$index] ); + return !empty( $this->options->get( 'NamespacesWithSubpages' )[$index] ); } /** @@ -337,7 +394,7 @@ class NamespaceInfo { * @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 ) ) { @@ -391,13 +448,13 @@ class NamespaceInfo { 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' ); } /** @@ -418,7 +475,7 @@ class NamespaceInfo { * @return bool */ public function isNonincludable( $index ) { - $namespaces = $this->config->get( 'NonincludableNamespaces' ); + $namespaces = $this->options->get( 'NonincludableNamespaces' ); return $namespaces && in_array( $index, $namespaces ); } @@ -433,22 +490,25 @@ class NamespaceInfo { * @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; @@ -467,7 +527,7 @@ class NamespaceInfo { // 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 } @@ -485,7 +545,7 @@ class NamespaceInfo { // 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