Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
76.92% covered (warning)
76.92%
20 / 26
42.86% covered (danger)
42.86%
3 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
AutoModeratorWikiConfigLoader
76.92% covered (warning)
76.92%
20 / 26
42.86% covered (danger)
42.86%
3 / 7
19.15
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 variableIsAllowed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isWikiConfigEnabled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWithFlags
85.71% covered (warning)
85.71%
12 / 14
0.00% covered (danger)
0.00%
0 / 1
7.14
 has
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasWithFlags
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
4.07
1<?php
2
3namespace AutoModerator\Config;
4
5use MediaWiki\Config\Config;
6use MediaWiki\Config\ConfigException;
7use MediaWiki\Settings\Config\MergeStrategy;
8
9/**
10 * Config loader for wiki page config
11 *
12 * This class consults the allow list
13 * in AutoModeratorWikiConfigLoader::ALLOW_LIST, and runs
14 * WikiPageConfig if requested config variable is there. Otherwise,
15 * it throws an exception.
16 *
17 * Fallback to GlobalVarConfig is implemented, so developer setup
18 * works without any config page, and also to not let wikis break
19 * AutoModerator setup by removing an arbitrary config variable.
20 */
21class AutoModeratorWikiConfigLoader implements Config, ICustomReadConstants {
22
23    private WikiPageConfig $wikiPageConfig;
24    private Config $globalVarConfig;
25
26    public const ALLOW_LIST = [
27        'AutoModeratorEnableRevisionCheck',
28        'AutoModeratorFalsePositivePageTitle',
29        'AutoModeratorSkipUserGroups',
30        'AutoModeratorUseEditFlagMinor',
31        'AutoModeratorRevertTalkPageMessageEnabled',
32        'AutoModeratorEnableBotFlag'
33    ];
34
35    /**
36     * Map of variable name => merge strategy. Defaults to replace.
37     * @see MergeStrategy
38     */
39    public const MERGE_STRATEGIES = [];
40
41    /**
42     * @param WikiPageConfig $wikiPageConfig
43     * @param Config $globalVarConfig
44     */
45    public function __construct(
46        WikiPageConfig $wikiPageConfig,
47        Config $globalVarConfig
48    ) {
49        $this->wikiPageConfig = $wikiPageConfig;
50        $this->globalVarConfig = $globalVarConfig;
51    }
52
53    /**
54     * @param string $name
55     * @return bool
56     */
57    private function variableIsAllowed( $name ) {
58        return in_array( $name, self::ALLOW_LIST );
59    }
60
61    /**
62     * Determine if on-wiki config is enabled or not
63     *
64     * If this returns false, all calls to get()/has() will be immediately
65     * forwarded to GlobalVarConfig, as if there was no on-wiki config.
66     *
67     * @return bool
68     */
69    public function isWikiConfigEnabled(): bool {
70        return (bool)$this->globalVarConfig->get( 'AutoModeratorEnableWikiConfig' );
71    }
72
73    /**
74     * @inheritDoc
75     */
76    public function get( $name ) {
77        return $this->getWithFlags( $name );
78    }
79
80    /**
81     * @param string $name
82     * @param int $flags bit field, see IDBAccessObject::READ_XXX
83     * @return mixed Config value
84     */
85    public function getWithFlags( $name, int $flags = 0 ) {
86        if ( !$this->isWikiConfigEnabled() ) {
87            return $this->globalVarConfig->get( $name );
88        }
89
90        if ( !$this->variableIsAllowed( $name ) ) {
91            throw new ConfigException( 'Config key cannot be retrieved via AutoModeratorWikiConfigLoader' );
92        }
93
94        if ( $this->wikiPageConfig->hasWithFlags( $name, $flags ) ) {
95            $wikiValue = $this->wikiPageConfig->getWithFlags( $name, $flags );
96            $mergeStrategy = self::MERGE_STRATEGIES[$name] ?? null;
97            if ( !$mergeStrategy || !$this->globalVarConfig->has( $name ) ) {
98                return $wikiValue;
99            }
100            $globalValue = $this->globalVarConfig->get( $name );
101            return MergeStrategy::newFromName( $mergeStrategy )->merge( $globalValue, $wikiValue );
102        }
103
104        if ( $this->globalVarConfig->has( $name ) ) {
105            return $this->globalVarConfig->get( $name );
106        }
107
108        throw new ConfigException( 'Config key was not found in AutoModeratorWikiConfigLoader' );
109    }
110
111    /**
112     * @inheritDoc
113     */
114    public function has( $name ) {
115        return $this->hasWithFlags( $name );
116    }
117
118    /**
119     * @param string $name
120     * @param int $flags
121     * @return bool
122     */
123    public function hasWithFlags( $name, int $flags = 0 ) {
124        if ( !$this->isWikiConfigEnabled() ) {
125            return $this->globalVarConfig->has( $name );
126        }
127
128        return $this->variableIsAllowed( $name ) && (
129            $this->wikiPageConfig->hasWithFlags( $name, $flags ) ||
130            $this->globalVarConfig->has( $name )
131        );
132    }
133}