Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.45% covered (success)
92.45%
49 / 53
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
GlobalParsedConfig
92.45% covered (success)
92.45%
49 / 53
80.00% covered (warning)
80.00%
4 / 5
9.03
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 initialize
82.61% covered (warning)
82.61%
19 / 23
0.00% covered (danger)
0.00%
0 / 1
5.13
 parseConfig
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 saveConfigToCache
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 applyUrlOverrides
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace MediaWiki\Extension\MediaUploader\Config;
4
5use JobQueueGroup;
6use MediaWiki\Config\ServiceOptions;
7use MediaWiki\User\UserOptionsLookup;
8use ParserOptions;
9use WANObjectCache;
10
11/**
12 * Represents the parsed global MediaUploader config.
13 * Automatically handles caching.
14 *
15 * Consider using RawConfig instead if you don't need the parsed values.
16 */
17class GlobalParsedConfig extends ParsedConfig {
18
19    /** @var ConfigParserFactory */
20    private $configParserFactory;
21
22    /** @var RequestConfig */
23    private $requestConfig;
24
25    /** @var JobQueueGroup */
26    private $jobQueueGroup;
27
28    /** @var array */
29    private $urlOverrides;
30
31    /**
32     * @param WANObjectCache $cache
33     * @param UserOptionsLookup $userOptionsLookup
34     * @param ConfigCacheInvalidator $cacheInvalidator
35     * @param ParserOptions $parserOptions
36     * @param ConfigParserFactory $configParserFactory
37     * @param RequestConfig $requestConfig
38     * @param JobQueueGroup $jobQueueGroup
39     * @param array $urlOverrides
40     * @param ServiceOptions $options
41     *
42     * @internal Only for use by ConfigFactory
43     */
44    public function __construct(
45        WANObjectCache $cache,
46        UserOptionsLookup $userOptionsLookup,
47        ConfigCacheInvalidator $cacheInvalidator,
48        ParserOptions $parserOptions,
49        ConfigParserFactory $configParserFactory,
50        RequestConfig $requestConfig,
51        JobQueueGroup $jobQueueGroup,
52        array $urlOverrides,
53        ServiceOptions $options
54    ) {
55        parent::__construct(
56            $cache,
57            $userOptionsLookup,
58            $cacheInvalidator,
59            $parserOptions,
60            $options
61        );
62
63        $this->configParserFactory = $configParserFactory;
64        $this->requestConfig = $requestConfig;
65        $this->jobQueueGroup = $jobQueueGroup;
66        $this->urlOverrides = $urlOverrides;
67    }
68
69    /**
70     * @inheritDoc
71     */
72    final protected function initialize( bool $noCache ): void {
73        if ( $noCache ) {
74            // Just reparse the config
75            $this->parseConfig();
76            $this->applyUrlOverrides();
77            return;
78        }
79
80        $configHash = $this->requestConfig->getConfigHash();
81        $cacheKey = $this->makeCacheKey();
82        $cachedValue = $this->cache->get(
83            $cacheKey,
84            $ttl,
85            [ $this->invalidator->makeInvalidateTimestampKey() ]
86        );
87
88        if ( $ttl < 0 ) {
89            // The cache has expired or was invalidated, reparse and save it
90            $this->parseConfig();
91            $this->saveConfigToCache( $cacheKey, $configHash );
92        } elseif ( !$cachedValue || $cachedValue['hash'] !== $configHash ) {
93            // There's no cache or the raw config has changed
94            $this->parseConfig();
95            $this->saveConfigToCache( $cacheKey, $configHash );
96
97            // The set of templates used in the config may have changed, the
98            // update will take care of that.
99            $this->jobQueueGroup->lazyPush(
100                GlobalConfigAnchorUpdateJob::newSpec()
101            );
102        } else {
103            $this->parsedConfig = $cachedValue['config'];
104            $this->usedTemplates = $cachedValue['templates'];
105        }
106
107        // Apply config overrides from URL
108        $this->applyUrlOverrides();
109    }
110
111    /**
112     * Parses the config and sets appropriate fields.
113     */
114    private function parseConfig(): void {
115        $configParser = $this->configParserFactory->newConfigParser(
116            $this->requestConfig->getConfigArray(),
117            $this->parserOptions
118        );
119
120        $this->parsedConfig = $configParser->getParsedConfig();
121        $this->usedTemplates = $configParser->getTemplates();
122    }
123
124    /**
125     * Saves the parsed config to cache.
126     *
127     * @param string $cacheKey
128     * @param string $configHash
129     */
130    private function saveConfigToCache(
131        string $cacheKey, string $configHash
132    ): void {
133        $this->cache->set(
134            $cacheKey,
135            [
136                'hash' => $configHash,
137                'config' => $this->parsedConfig,
138                'templates' => $this->usedTemplates,
139            ],
140            // Set this to a week and not indefinite to allow for cache
141            // invalidation using 'checkKeys'.
142            $this->cache::TTL_WEEK
143        );
144    }
145
146    /**
147     * Applies URL overrides to the parsed config.
148     */
149    private function applyUrlOverrides(): void {
150        $this->parsedConfig = array_replace_recursive(
151            $this->parsedConfig,
152            $this->urlOverrides
153        );
154    }
155}