Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
43 / 43
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
NamespaceDef
100.00% covered (success)
100.00%
43 / 43
100.00% covered (success)
100.00%
6 / 6
21
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 validate
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 getEnumValues
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 normalizeSettings
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 checkSettings
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
8
 getParamInfo
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3namespace MediaWiki\ParamValidator\TypeDef;
4
5use ApiResult;
6use MediaWiki\Title\NamespaceInfo;
7use Wikimedia\ParamValidator\Callbacks;
8use Wikimedia\ParamValidator\ParamValidator;
9use Wikimedia\ParamValidator\TypeDef\EnumDef;
10
11/**
12 * Type definition for namespace types
13 *
14 * A namespace type is an enum type that accepts MediaWiki namespace IDs.
15 *
16 * @since 1.35
17 */
18class NamespaceDef extends EnumDef {
19
20    /**
21     * (int[]) Additional namespace IDs to recognize.
22     *
23     * Generally this will be used to include NS_SPECIAL and/or NS_MEDIA.
24     */
25    public const PARAM_EXTRA_NAMESPACES = 'param-extra-namespaces';
26
27    /** @var NamespaceInfo */
28    private $nsInfo;
29
30    public function __construct( Callbacks $callbacks, NamespaceInfo $nsInfo ) {
31        parent::__construct( $callbacks );
32        $this->nsInfo = $nsInfo;
33    }
34
35    public function validate( $name, $value, array $settings, array $options ) {
36        if ( !is_int( $value ) && preg_match( '/^[+-]?\d+$/D', $value ) ) {
37            // Convert to int since that's what getEnumValues() returns.
38            $value = (int)$value;
39        }
40
41        return parent::validate( $name, $value, $settings, $options );
42    }
43
44    public function getEnumValues( $name, array $settings, array $options ) {
45        $namespaces = $this->nsInfo->getValidNamespaces();
46        $extra = $settings[self::PARAM_EXTRA_NAMESPACES] ?? [];
47        if ( is_array( $extra ) && $extra !== [] ) {
48            $namespaces = array_merge( $namespaces, $extra );
49        }
50        sort( $namespaces );
51        return $namespaces;
52    }
53
54    public function normalizeSettings( array $settings ) {
55        // Force PARAM_ALL
56        if ( !empty( $settings[ParamValidator::PARAM_ISMULTI] ) ) {
57            $settings[ParamValidator::PARAM_ALL] = true;
58        }
59        return parent::normalizeSettings( $settings );
60    }
61
62    public function checkSettings( string $name, $settings, array $options, array $ret ): array {
63        $ret = parent::checkSettings( $name, $settings, $options, $ret );
64
65        $ret['allowedKeys'] = array_merge( $ret['allowedKeys'], [
66            self::PARAM_EXTRA_NAMESPACES,
67        ] );
68
69        if ( !empty( $settings[ParamValidator::PARAM_ISMULTI] ) &&
70            ( $settings[ParamValidator::PARAM_ALL] ?? true ) !== true &&
71            !isset( $ret['issues'][ParamValidator::PARAM_ALL] )
72        ) {
73            $ret['issues'][ParamValidator::PARAM_ALL] =
74                'PARAM_ALL cannot be false or a string for namespace-type parameters';
75        }
76
77        $ns = $settings[self::PARAM_EXTRA_NAMESPACES] ?? [];
78        if ( !is_array( $ns ) ) {
79            $type = gettype( $ns );
80        } elseif ( $ns === [] ) {
81            $type = 'integer[]';
82        } else {
83            $types = array_unique( array_map( 'gettype', $ns ) );
84            $type = implode( '|', $types );
85            $type = count( $types ) > 1 ? "($type)[]" : "{$type}[]";
86        }
87        if ( $type !== 'integer[]' ) {
88            $ret['issues'][self::PARAM_EXTRA_NAMESPACES] =
89                "PARAM_EXTRA_NAMESPACES must be an integer[], got $type";
90        }
91
92        return $ret;
93    }
94
95    public function getParamInfo( $name, array $settings, array $options ) {
96        $info = parent::getParamInfo( $name, $settings, $options );
97
98        $info['type'] = 'namespace';
99        $extra = $settings[self::PARAM_EXTRA_NAMESPACES] ?? [];
100        if ( is_array( $extra ) && $extra !== [] ) {
101            $info['extranamespaces'] = array_values( $extra );
102            if ( isset( $options['module'] ) ) {
103                // ApiResult metadata when used with the Action API.
104                ApiResult::setIndexedTagName( $info['extranamespaces'], 'ns' );
105            }
106        }
107
108        return $info;
109    }
110
111}