Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.11% covered (warning)
86.11%
31 / 36
77.78% covered (warning)
77.78%
7 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
MathConfig
86.11% covered (warning)
86.11%
31 / 36
77.78% covered (warning)
77.78%
7 / 9
16.69
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 texCheckDisabled
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 getValidRenderingModes
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 getValidRenderingModeKeys
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getValidRenderingModeNames
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getRenderingModeName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isValidRenderingMode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 normalizeRenderingMode
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 getMathEntitySelectorUrl
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace MediaWiki\Extension\Math;
4
5use MediaWiki\Config\ServiceOptions;
6use MediaWiki\Message\Message;
7use MediaWiki\Registration\ExtensionRegistry;
8use Wikibase\Client\WikibaseClient;
9
10class MathConfig {
11
12    /** @var string[] */
13    public const CONSTRUCTOR_OPTIONS = [
14        'MathDisableTexFilter',
15        'MathValidModes',
16        'MathEntitySelectorFallbackUrl'
17    ];
18
19    /** @var string */
20    public const ALWAYS = 'always';
21
22    /** @var string */
23    public const NEVER = 'never';
24
25    /** @var string */
26    public const NEW = 'new';
27
28    /** @var string use input tex as formula rendering */
29    public const MODE_SOURCE = 'source';
30
31    /** @var string render formula into MathML */
32    public const MODE_MATHML = 'mathml';
33
34    /** @var string render formula into LateXML */
35    public const MODE_LATEXML = 'latexml';
36
37    /** @var string render formula into MathML using PHP (currently in development) */
38    public const MODE_NATIVE_MML = 'native';
39    /** @var string render formula into MathML using PHP and output it via MathJax */
40    public const MODE_NATIVE_JAX = 'mathjax';
41
42    /** @var string[] a list of all supported rendering modes */
43    public const SUPPORTED_MODES = [
44        self::MODE_SOURCE,
45        self::MODE_LATEXML,
46        self::MODE_MATHML,
47        self::MODE_NATIVE_MML,
48        self::MODE_NATIVE_JAX
49    ];
50
51    /**
52     * @var array mapping from rendering mode to user options value
53     */
54    private const MODES_TO_USER_OPTIONS = [
55        self::MODE_SOURCE => 3,
56        self::MODE_MATHML => 5,
57        self::MODE_LATEXML => 7,
58        self::MODE_NATIVE_MML => 8,
59        self::MODE_NATIVE_JAX => 9
60    ];
61
62    public function __construct(
63        private readonly ServiceOptions $options,
64        private readonly ExtensionRegistry $registry,
65    ) {
66        $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
67    }
68
69    /**
70     * Whether the TEX filter is disabled.
71     * @return string one of self::CHECK_* constants
72     */
73    public function texCheckDisabled(): string {
74        $setting = $this->options->get( 'MathDisableTexFilter' );
75        if ( $setting === true ) {
76            // ensure backwards compatibility
77            return self::NEVER;
78        }
79        $setting = strtolower( $setting );
80        if ( in_array( $setting, [ self::NEVER, self::ALWAYS, self::NEW ], true ) ) {
81            return $setting;
82        }
83        return self::ALWAYS;
84    }
85
86    /**
87     * Returns an array of valid rendering modes.
88     *
89     * @return string[]
90     */
91    public function getValidRenderingModes(): array {
92        // NOTE: this method is copy-pasted into HookHandlers\SchemaHooksHandler::onLoadExtensionSchemaUpdates
93        // since we can't inject services in there.
94
95        $modes = array_map(
96            [ __CLASS__, 'normalizeRenderingMode' ],
97            $this->options->get( 'MathValidModes' )
98        );
99        return array_unique( $modes );
100    }
101
102    /**
103     * Get message keys for the names of the valid rendering modes.
104     *
105     * @return string[]
106     */
107    public function getValidRenderingModeKeys(): array {
108        $result = [];
109        foreach ( $this->getValidRenderingModes() as $mode ) {
110            $result[$mode] = 'mw-math-' . $mode;
111        }
112        return $result;
113    }
114
115    /**
116     * Get Messages for the names of the valid rendering
117     * modes.
118     *
119     * @return Message[]
120     */
121    public function getValidRenderingModeNames(): array {
122        $result = [];
123        foreach ( $this->getValidRenderingModes() as $mode ) {
124            $result[$mode] = Message::newFromKey( 'mw-math-' . $mode );
125        }
126        return $result;
127    }
128
129    /**
130     * Get the human-readable name of a rendering mode.
131     *
132     * @param string $mode one of self::MODE_* constants.
133     * @return Message
134     */
135    public function getRenderingModeName( string $mode ): Message {
136        return Message::newFromKey( 'mw-math-' . $mode );
137    }
138
139    /**
140     * Checks whether $mode is a valid rendering mode.
141     *
142     * @param string $mode
143     * @return bool
144     */
145    public function isValidRenderingMode( string $mode ): bool {
146        return in_array( $mode, $this->getValidRenderingModes(), true );
147    }
148
149    /**
150     * Get the normalized name of the rendering mode
151     * @param string|int $mode
152     * @param string $default rendering mode to use by default on unrecognized input
153     * @return string one of the self::MODE_* constants.
154     */
155    public static function normalizeRenderingMode( $mode, string $default = self::MODE_NATIVE_MML ): string {
156        if ( is_int( $mode ) ) {
157            $userOptionToMode = array_flip( self::MODES_TO_USER_OPTIONS );
158            return $userOptionToMode[$mode] ?? $default;
159        }
160        $mode = strtolower( $mode );
161        if ( in_array( $mode, self::SUPPORTED_MODES, true ) ) {
162            return $mode;
163        }
164        return $default;
165    }
166
167    /**
168     * If the WikibaseClient is enabled the API url of that client is returned, otherwise the
169     * fallback url is used.
170     * @return string url of the Wikibase url
171     */
172    public function getMathEntitySelectorUrl(): string {
173        // @see WikibaseSettings::isClientEnabled()
174        if ( $this->registry->isLoaded( 'WikibaseClient' ) ) {
175            $settings = WikibaseClient::getSettings();
176            return $settings->getSetting( 'repoUrl' ) .
177                $settings->getSetting( 'repoScriptPath' ) .
178                '/api.php';
179
180        }
181        return $this->options->get( 'MathEntitySelectorFallbackUrl' );
182    }
183}