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