Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
82.22% |
37 / 45 |
|
75.00% |
6 / 8 |
CRAP | |
0.00% |
0 / 1 |
MediaWikiConfigReader | |
82.22% |
37 / 45 |
|
75.00% |
6 / 8 |
15.10 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
addMediaWikiConfigProviderKeysToMap | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
3 | |||
computeVariableToProviderMap | |
58.33% |
7 / 12 |
|
0.00% |
0 / 1 |
3.65 | |||
getVariableToProviderMap | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
getMediaWikiConfigProviderByName | |
50.00% |
3 / 6 |
|
0.00% |
0 / 1 |
2.50 | |||
getConfigByVariableName | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
get | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
has | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\CommunityConfiguration\Access; |
4 | |
5 | use BagOStuff; |
6 | use LogicException; |
7 | use MediaWiki\Config\Config; |
8 | use MediaWiki\Config\ConfigException; |
9 | use MediaWiki\Extension\CommunityConfiguration\Provider\ConfigurationProviderFactory; |
10 | use MediaWiki\Extension\CommunityConfiguration\Provider\MediaWikiConfigProvider; |
11 | use Psr\Log\LoggerAwareTrait; |
12 | use Psr\Log\NullLogger; |
13 | use Wikimedia\LightweightObjectStore\ExpirationAwareness; |
14 | |
15 | class MediaWikiConfigReader implements Config { |
16 | use LoggerAwareTrait; |
17 | |
18 | private BagOStuff $cache; |
19 | private ConfigurationProviderFactory $providerFactory; |
20 | private Config $fallbackConfig; |
21 | |
22 | public function __construct( |
23 | BagOStuff $cache, |
24 | ConfigurationProviderFactory $providerFactory, |
25 | Config $fallbackConfig |
26 | ) { |
27 | $this->cache = $cache; |
28 | $this->providerFactory = $providerFactory; |
29 | $this->fallbackConfig = $fallbackConfig; |
30 | |
31 | $this->setLogger( new NullLogger() ); |
32 | } |
33 | |
34 | private function addMediaWikiConfigProviderKeysToMap( |
35 | MediaWikiConfigProvider $provider, |
36 | array &$map |
37 | ): void { |
38 | $supportedConfigKeys = $provider->getSupportedConfigVariableNames(); |
39 | foreach ( $supportedConfigKeys as $configKey ) { |
40 | if ( isset( $map[$configKey] ) ) { |
41 | throw new ConfigException( |
42 | 'Config variable ' . $configKey |
43 | . ' is registered by multiple CommunityConfiguration providers.' |
44 | ); |
45 | } |
46 | $map[$configKey] = $provider->getId(); |
47 | } |
48 | } |
49 | |
50 | /** |
51 | * Calculate the config key => configuration provider map |
52 | * |
53 | * @return string[] |
54 | */ |
55 | private function computeVariableToProviderMap(): array { |
56 | $map = []; |
57 | $providerKeys = $this->providerFactory->getSupportedKeys(); |
58 | foreach ( $providerKeys as $providerKey ) { |
59 | $provider = $this->providerFactory->newProvider( $providerKey ); |
60 | if ( $provider instanceof MediaWikiConfigProvider ) { |
61 | $this->addMediaWikiConfigProviderKeysToMap( $provider, $map ); |
62 | } else { |
63 | // TODO: Add some support for other providers |
64 | $this->logger->debug( |
65 | __CLASS__ . ' skipped {provider}, because ' |
66 | . 'it is not a MediaWikiConfigProvider.', |
67 | [ 'provider' => $provider->getId() ] |
68 | ); |
69 | } |
70 | } |
71 | return $map; |
72 | } |
73 | |
74 | /** |
75 | * Get the cached variable to configuration provider map |
76 | * |
77 | * This is used to determine which config key can be handled by which configuration provider. |
78 | * |
79 | * @return string[] Config key => provider key |
80 | */ |
81 | private function getVariableToProviderMap(): array { |
82 | return $this->cache->getWithSetCallback( |
83 | $this->cache->makeKey( __CLASS__, |
84 | 'VariableToProviderMap' |
85 | ), |
86 | ExpirationAwareness::TTL_DAY, |
87 | function () { |
88 | return $this->computeVariableToProviderMap(); |
89 | } |
90 | ); |
91 | } |
92 | |
93 | /** |
94 | * Create a configuration provider from given key and ensure it is a MediaWikiConfigProvider |
95 | * |
96 | * @param string $providerKey |
97 | * @return MediaWikiConfigProvider |
98 | */ |
99 | private function getMediaWikiConfigProviderByName( string $providerKey ): MediaWikiConfigProvider { |
100 | $provider = $this->providerFactory->newProvider( $providerKey ); |
101 | if ( !$provider instanceof MediaWikiConfigProvider ) { |
102 | throw new LogicException( |
103 | $providerKey . ' is expected to be a MediaWikiConfigProvider' |
104 | ); |
105 | } |
106 | return $provider; |
107 | } |
108 | |
109 | /** |
110 | * Get Config instance to handle requests for $name config key |
111 | * |
112 | * @param string $name |
113 | * @return Config |
114 | */ |
115 | private function getConfigByVariableName( string $name ): Config { |
116 | $map = $this->getVariableToProviderMap(); |
117 | if ( isset( $map[$name] ) ) { |
118 | return $this->getMediaWikiConfigProviderByName( $map[$name] ); |
119 | } else { |
120 | return $this->fallbackConfig; |
121 | } |
122 | } |
123 | |
124 | /** |
125 | * @inheritDoc |
126 | */ |
127 | public function get( $name ) { |
128 | return $this->getConfigByVariableName( $name )->get( $name ); |
129 | } |
130 | |
131 | /** |
132 | * @inheritDoc |
133 | */ |
134 | public function has( $name ) { |
135 | return $this->getConfigByVariableName( $name )->has( $name ); |
136 | } |
137 | } |