Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
90.91% |
70 / 77 |
|
55.56% |
5 / 9 |
CRAP | |
0.00% |
0 / 1 |
MediaWikiHooksHelper | |
90.91% |
70 / 77 |
|
55.56% |
5 / 9 |
35.92 | |
0.00% |
0 / 1 |
getInstance | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
clearCache | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
registerHook | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
3.04 | |||
loadExtensionJson | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
5.03 | |||
readJsonFile | |
83.33% |
20 / 24 |
|
0.00% |
0 / 1 |
13.78 | |||
getHookSubscribers | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
isSpecialHookSubscriber | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
4 | |||
getMwParserClassFQSEN | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
3 | |||
getPPFrameClassFQSEN | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
3.01 |
1 | <?php |
2 | |
3 | namespace SecurityCheckPlugin; |
4 | |
5 | use Phan\CodeBase; |
6 | use Phan\Config; |
7 | use Phan\Language\FQSEN\FullyQualifiedClassName; |
8 | use Phan\Language\FQSEN\FullyQualifiedFunctionLikeName; |
9 | use Phan\Language\FQSEN\FullyQualifiedFunctionName; |
10 | use Phan\Language\FQSEN\FullyQualifiedMethodName; |
11 | |
12 | /** |
13 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License as published by |
15 | * the Free Software Foundation; either version 2 of the License, or |
16 | * (at your option) any later version. |
17 | * |
18 | * This program is distributed in the hope that it will be useful, |
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 | * GNU General Public License for more details. |
22 | * |
23 | * You should have received a copy of the GNU General Public License along |
24 | * with this program; if not, write to the Free Software Foundation, Inc., |
25 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
26 | */ |
27 | |
28 | class MediaWikiHooksHelper { |
29 | /** |
30 | * @var bool Whether extension.json/skin.json was already loaded |
31 | */ |
32 | private $extensionJsonLoaded = false; |
33 | |
34 | /** |
35 | * @var FullyQualifiedFunctionLikeName[][] A mapping from hook names to FQSEN that implement it |
36 | * @phan-var array<string,FullyQualifiedFunctionLikeName[]> |
37 | */ |
38 | private $hookSubscribers = []; |
39 | |
40 | private ?FullyQualifiedClassName $parserFQSEN = null; |
41 | private ?FullyQualifiedClassName $ppFrameFQSEN = null; |
42 | |
43 | /** @var self|null */ |
44 | private static $instance; |
45 | |
46 | /** |
47 | * @return self |
48 | */ |
49 | public static function getInstance(): self { |
50 | if ( !self::$instance ) { |
51 | self::$instance = new self; |
52 | } |
53 | return self::$instance; |
54 | } |
55 | |
56 | /** |
57 | * Clear the extension.json cache, for testing purpose |
58 | * |
59 | * @suppress PhanUnreferencedPublicMethod |
60 | */ |
61 | public function clearCache(): void { |
62 | $this->extensionJsonLoaded = false; |
63 | } |
64 | |
65 | /** |
66 | * Add a hook implementation to our list. |
67 | * |
68 | * This also handles parser hooks which aren't normal hooks. |
69 | * Non-normal hooks start their name with a "!" |
70 | * |
71 | * @param string $hookName Name of hook |
72 | * @param FullyQualifiedFunctionLikeName $fqsen The implementing method |
73 | * @return bool true if already registered, false otherwise |
74 | */ |
75 | public function registerHook( string $hookName, FullyQualifiedFunctionLikeName $fqsen ): bool { |
76 | if ( !isset( $this->hookSubscribers[$hookName] ) ) { |
77 | $this->hookSubscribers[$hookName] = []; |
78 | } |
79 | if ( in_array( $fqsen, $this->hookSubscribers[$hookName], true ) ) { |
80 | return true; |
81 | } |
82 | $this->hookSubscribers[$hookName][] = $fqsen; |
83 | return false; |
84 | } |
85 | |
86 | /** |
87 | * Register hooks from extension.json/skin.json |
88 | * |
89 | * Assumes extension.json/skin.json is in project root directory |
90 | * unless SECURITY_CHECK_EXT_PATH is set |
91 | */ |
92 | protected function loadExtensionJson(): void { |
93 | if ( $this->extensionJsonLoaded ) { |
94 | return; |
95 | } |
96 | foreach ( [ 'extension.json', 'skin.json' ] as $filename ) { |
97 | $envPath = getenv( 'SECURITY_CHECK_EXT_PATH' ); |
98 | if ( $envPath ) { |
99 | $jsonPath = $envPath . '/' . $filename; |
100 | } else { |
101 | $jsonPath = Config::projectPath( $filename ); |
102 | } |
103 | if ( file_exists( $jsonPath ) ) { |
104 | $this->readJsonFile( $jsonPath ); |
105 | } |
106 | } |