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        'AutoModeratorUseEditFlagMinor',
30        'AutoModeratorRevertTalkPageMessageEnabled',
31        'AutoModeratorEnableBotFlag',
32        'AutoModeratorSkipUserRights',
33        'AutoModeratorCautionLevel',
34        'AutoModeratorEnableUserRevertsPerPage',
35        'AutoModeratorUserRevertsPerPage',
36        'AutoModeratorHelpPageLink',
37        'AutoModeratorMultilingualConfigEnableRevisionCheck',
38        'AutoModeratorMultilingualConfigFalsePositivePageTitle',
39        'AutoModeratorMultilingualConfigUseEditFlagMinor',
40        'AutoModeratorMultilingualConfigRevertTalkPageMessageEnabled',
41        'AutoModeratorMultilingualConfigEnableBotFlag',
42        'AutoModeratorMultilingualConfigSkipUserRights',
43        'AutoModeratorMultilingualConfigCautionLevel',
44        'AutoModeratorMultilingualConfigEnableUserRevertsPerPage',
45        'AutoModeratorMultilingualConfigUserRevertsPerPage',
46        'AutoModeratorMultilingualConfigHelpPageLink',
47        'AutoModeratorMultilingualConfigEnableLanguageAgnostic',
48        'AutoModeratorMultilingualConfigEnableMultilingual',
49        'AutoModeratorMultilingualConfigMultilingualThreshold',
50        'AutoModeratorMultilingualConfigConfigureThreshold'
51    ];
52
53    /**
54     * Map of variable name => merge strategy. Defaults to replace.
55     * @see MergeStrategy
56     */
57    public const MERGE_STRATEGIES = [];
58
59    /**
60     * @param WikiPageConfig $wikiPageConfig
61     * @param Config $globalVarConfig
62     */
63    public function __construct(
64        WikiPageConfig $wikiPageConfig,
65        Config $globalVarConfig
66    ) {
67        $this->wikiPageConfig = $wikiPageConfig;
68        $this->globalVarConfig = $globalVarConfig;
69    }
70
71    /**
72     * @param string $name
73     * @return bool
74     */
75    private function variableIsAllowed( $name ) {
76        return in_array( $name, self::ALLOW_LIST );
77    }
78
79    /**
80     * Determine if on-wiki config is enabled or not
81     *
82     * If this returns false, all calls to get()/has() will be immediately
83     * forwarded to GlobalVarConfig, as if there was no on-wiki config.
84     *
85     * @return bool
86     */
87    public function isWikiConfigEnabled(): bool {
88        return (bool)$this->globalVarConfig->get( 'AutoModeratorEnableWikiConfig' );
89    }
90
91    /**
92     * @inheritDoc
93     */
94    public function get( $name ) {
95        return $this->getWithFlags( $name );
96    }
97
98    /**
99     * @param string $name
100     * @param int $flags bit field, see IDBAccessObject::READ_XXX
101     * @return mixed Config value
102     */
103    public function getWithFlags( string $name, int $flags = 0 ) {
104        if ( !$this->isWikiConfigEnabled() ) {
105            return $this->globalVarConfig->get( $name );
106        }
107
108        if ( !$this->variableIsAllowed( $name ) ) {
109            throw new ConfigException( 'Config key cannot be retrieved via AutoModeratorWikiConfigLoader' );
110        }
111
112        if ( $this->wikiPageConfig->hasWithFlags( $name, $flags ) ) {
113            $wikiValue = $this->wikiPageConfig->getWithFlags( $name, $flags );
114            $mergeStrategy = self::MERGE_STRATEGIES[$name] ?? null;
115            if ( !$mergeStrategy || !$this->globalVarConfig->has( $name ) ) {
116                return $wikiValue;
117            }
118            $globalValue = $this->globalVarConfig->get( $name );
119            return MergeStrategy::newFromName( $mergeStrategy )->merge( $globalValue, $wikiValue );
120        }
121
122        if ( $this->globalVarConfig->has( $name ) ) {
123            return $this->globalVarConfig->get( $name );
124        }
125
126        throw new ConfigException( 'Config key was not found in AutoModeratorWikiConfigLoader' );
127    }
128
129    /**
130     * @inheritDoc
131     */
132    public function has( $name ): bool {
133        return $this->hasWithFlags( $name );
134    }
135
136    /**
137     * @param string $name
138     * @param int $flags
139     * @return bool
140     */
141    public function hasWithFlags( string $name, int $flags = 0 ): bool {
142        if ( !$this->isWikiConfigEnabled() ) {
143            return $this->globalVarConfig->has( $name );
144        }
145
146        return $this->variableIsAllowed( $name ) && (
147            $this->wikiPageConfig->hasWithFlags( $name, $flags ) ||
148            $this->globalVarConfig->has( $name )
149        );
150    }
151}