Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
ParsedConfig
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
4 / 4
7
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 makeCacheKey
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
2
 initialize
n/a
0 / 0
n/a
0 / 0
0
 getConfigArray
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getTemplates
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace MediaWiki\Extension\MediaUploader\Config;
4
5use MediaWiki\Config\ServiceOptions;
6use MediaWiki\User\UserOptionsLookup;
7use ParserOptions;
8use WANObjectCache;
9
10/**
11 * Abstract parsed config.
12 */
13abstract class ParsedConfig extends ConfigBase {
14
15    /**
16     * @internal
17     */
18    public const NO_CACHE = 'NoConfigCache';
19
20    /**
21     * @internal Only for use by ConfigFactory
22     */
23    public const CONSTRUCTOR_OPTIONS = [ self::NO_CACHE ];
24
25    /** @var array */
26    protected $parsedConfig;
27
28    /** @var array */
29    protected $usedTemplates;
30
31    /** @var WANObjectCache */
32    protected $cache;
33
34    /** @var UserOptionsLookup */
35    private $userOptionsLookup;
36
37    /** @var ConfigCacheInvalidator */
38    protected $invalidator;
39
40    /** @var ParserOptions */
41    protected $parserOptions;
42
43    /** @var ServiceOptions */
44    private $options;
45
46    /**
47     * @param WANObjectCache $cache
48     * @param UserOptionsLookup $userOptionsLookup
49     * @param ConfigCacheInvalidator $cacheInvalidator
50     * @param ParserOptions $parserOptions
51     * @param ServiceOptions $options
52     */
53    protected function __construct(
54        WANObjectCache $cache,
55        UserOptionsLookup $userOptionsLookup,
56        ConfigCacheInvalidator $cacheInvalidator,
57        ParserOptions $parserOptions,
58        ServiceOptions $options
59    ) {
60        $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
61
62        $this->cache = $cache;
63        $this->userOptionsLookup = $userOptionsLookup;
64        $this->invalidator = $cacheInvalidator;
65        $this->parserOptions = $parserOptions;
66        $this->options = $options;
67    }
68
69    /**
70     * Returns the key used to store the parsed config.
71     *
72     * @param string ...$additionalComponents Additional cache key components
73     *
74     * @return string
75     */
76    final protected function makeCacheKey( string ...$additionalComponents ): string {
77        // We build a cache key manually instead of relying on popts
78        // because its algorithm for cache key generation is a mountain
79        // of duct tape to make Parser.php (tm) work properly. Including
80        // just the gender and language is probably not exhaustive, but
81        // will be enough for 99% of use cases.
82        $gender = $this->userOptionsLookup->getOption(
83            $this->parserOptions->getUserIdentity(),
84            'gender'
85        );
86        $lang = $this->parserOptions->getTargetLanguage();
87
88        return $this->cache->makeKey(
89            'mediauploader',
90            'parsed-config',
91            $lang ? $lang->getCode() : '-',
92            $gender,
93            ...$additionalComponents
94        );
95    }
96
97    /**
98     * Retrieves the parsed config from cache, if available.
99     * Otherwise, re-parses the config, stores it in cache and sets the
100     * $parsedConfig and $usedTemplates fields.
101     *
102     * @param bool $noCache Whether to bypass cache entirely.
103     *  No reads or writes to cache should be made.
104     */
105    abstract protected function initialize( bool $noCache ): void;
106
107    /**
108     * @inheritDoc
109     */
110    public function getConfigArray(): array {
111        if ( $this->parsedConfig === null ) {
112            $this->initialize(
113                $this->options->get( self::NO_CACHE )
114            );
115        }
116
117        return $this->parsedConfig;
118    }
119
120    /**
121     * Returns the templates used in this config
122     *
123     * @return array [ ns => [ dbKey => [ page_id, rev_id ] ] ]
124     */
125    public function getTemplates(): array {
126        if ( $this->usedTemplates === null ) {
127            $this->initialize(
128                $this->options->get( self::NO_CACHE )
129            );
130        }
131
132        return $this->usedTemplates;
133    }
134}