Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
GlobalConfigBuilder
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
7 / 7
15
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 has
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 get
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 update
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setMulti
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
8
 getVarName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 build
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace MediaWiki\Settings\Config;
4
5use MediaWiki\Config\Config;
6use MediaWiki\Config\GlobalVarConfig;
7use function array_key_exists;
8
9class GlobalConfigBuilder extends ConfigBuilderBase {
10
11    public const DEFAULT_PREFIX = 'wg';
12
13    /** @var string */
14    private $prefix;
15
16    /**
17     * @param string $prefix
18     */
19    public function __construct( string $prefix = self::DEFAULT_PREFIX ) {
20        $this->prefix = $prefix;
21    }
22
23    protected function has( string $key ): bool {
24        $var = $this->getVarName( $key );
25        // (T317951) Don't call array_key_exists unless we have to, as it's slow
26        // on PHP 8.1+ for $GLOBALS. When the key is set but is explicitly set
27        // to null, we still need to fall back to array_key_exists, but that's
28        // rarer.
29        return isset( $GLOBALS[$var] ) || array_key_exists( $var, $GLOBALS );
30    }
31
32    /** @inheritDoc */
33    public function get( string $key ) {
34        $var = $this->getVarName( $key );
35        return $GLOBALS[ $var ] ?? null;
36    }
37
38    /** @inheritDoc */
39    protected function update( string $key, $value ) {
40        $var = $this->getVarName( $key );
41        $GLOBALS[ $var ] = $value;
42    }
43
44    public function setMulti( array $values, array $mergeStrategies = [] ): ConfigBuilder {
45        // NOTE: It is tempting to do $GLOBALS = array_merge( $GLOBALS, $values ).
46        //       But that no longer works in PHP 8.1!
47        //       See https://wiki.php.net/rfc/restrict_globals_usage
48
49        foreach ( $values as $key => $newValue ) {
50            $var = $this->prefix . $key; // inline getVarName() to avoid function call
51
52            // Optimization: Inlined logic from set() for performance
53            if ( isset( $GLOBALS[$var] ) && array_key_exists( $key, $mergeStrategies ) ) {
54                $mergeStrategy = $mergeStrategies[$key];
55                if ( $mergeStrategy && is_array( $newValue ) ) {
56                    $oldValue = $GLOBALS[$var];
57                    if ( $oldValue && is_array( $oldValue ) ) {
58                        $newValue = $mergeStrategy->merge( $oldValue, $newValue );
59                    }
60                }
61            }
62
63            $GLOBALS[$var] = $newValue;
64        }
65        return $this;
66    }
67
68    private function getVarName( string $key ): string {
69        return $this->prefix . $key;
70    }
71
72    public function build(): Config {
73        return new GlobalVarConfig( $this->prefix );
74    }
75}