Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
45.65% |
21 / 46 |
|
25.00% |
2 / 8 |
CRAP | |
0.00% |
0 / 1 |
Hooks | |
45.65% |
21 / 46 |
|
25.00% |
2 / 8 |
57.09 | |
0.00% |
0 / 1 |
onSetup | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
onBeforePageDisplay | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
getSchemas | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
getEventLoggingConfig | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
getModuleData | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
onGetPreferences | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
onCanonicalNamespaces | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
loadEventStreamConfigs | |
84.62% |
11 / 13 |
|
0.00% |
0 / 1 |
3.03 |
1 | <?php |
2 | /** |
3 | * Hooks for EventLogging extension. |
4 | * |
5 | * @file |
6 | * |
7 | * @ingroup Extensions |
8 | * @ingroup EventLogging |
9 | * |
10 | * @author Ori Livneh <ori@wikimedia.org> |
11 | */ |
12 | |
13 | namespace MediaWiki\Extension\EventLogging; |
14 | |
15 | use ExtensionRegistry; |
16 | use MediaWiki\Config\Config; |
17 | use MediaWiki\Hook\BeforePageDisplayHook; |
18 | use MediaWiki\Hook\CanonicalNamespacesHook; |
19 | use MediaWiki\MediaWikiServices; |
20 | use MediaWiki\Output\OutputPage; |
21 | use MediaWiki\Preferences\Hook\GetPreferencesHook; |
22 | use MediaWiki\ResourceLoader as RL; |
23 | use MediaWiki\User\User; |
24 | use Skin; |
25 | |
26 | class Hooks implements |
27 | CanonicalNamespacesHook, |
28 | BeforePageDisplayHook, |
29 | GetPreferencesHook |
30 | { |
31 | |
32 | /** |
33 | * The list of stream config settings that should be sent to the client as part of the |
34 | * ext.eventLogging RL module. |
35 | * |
36 | * @var string[] |
37 | */ |
38 | private const STREAM_CONFIG_SETTINGS_ALLOWLIST = [ |
39 | 'sample', |
40 | 'producers', |
41 | ]; |
42 | |
43 | /** |
44 | * Emit a debug log message for each invalid or unset |
45 | * configuration variable (if any). |
46 | */ |
47 | public static function onSetup(): void { |
48 | global $wgEventLoggingBaseUri, $wgEventLoggingStreamNames; |
49 | |
50 | if ( $wgEventLoggingBaseUri === false ) { |
51 | EventLogging::getLogger()->debug( 'wgEventLoggingBaseUri has not been configured.' ); |
52 | } |
53 | |
54 | if ( $wgEventLoggingStreamNames !== false && !is_array( $wgEventLoggingStreamNames ) ) { |
55 | EventLogging::getLogger()->debug( |
56 | 'wgEventLoggingStreamNames is configured but is not a list of stream names' |
57 | ); |
58 | |
59 | $wgEventLoggingStreamNames = []; |
60 | } |
61 | } |
62 | |
63 | /** |
64 | * @param OutputPage $out |
65 | * @param Skin $skin |
66 | */ |
67 | public function onBeforePageDisplay( $out, $skin ): void { |
68 | $out->addModules( [ 'ext.eventLogging' ] ); |
69 | |
70 | $services = MediaWikiServices::getInstance(); |
71 | $lookup = $services->getUserOptionsLookup(); |
72 | if ( $lookup->getIntOption( $out->getUser(), 'eventlogging-display-web' ) |
73 | || $lookup->getIntOption( $out->getUser(), 'eventlogging-display-console' ) |
74 | ) { |
75 | $out->addModules( 'ext.eventLogging.debug' ); |
76 | } |
77 | } |
78 | |
79 | /** |
80 | * Return all schemas registered in extension.json EventLoggingSchemas and |
81 | * PHP $wgEventLoggingSchemas. The returned array will map from schema name |
82 | * to either MediaWiki (metawiki) revision id, or to a relative schema URI |
83 | * for forward compatibility with Event Platform. |
84 | * TODO: what happens when two extensions register the same schema with a different revision? |
85 | * |
86 | * @return array |
87 | */ |
88 | private static function getSchemas() { |
89 | global $wgEventLoggingSchemas; |
90 | |
91 | $extRegistry = ExtensionRegistry::getInstance(); |
92 | $schemas = $wgEventLoggingSchemas + $extRegistry->getAttribute( 'EventLoggingSchemas' ); |
93 | |
94 | return $schemas; |
95 | } |
96 | |
97 | /** |
98 | * Returns an object with EventLogging specific configuration extracted from |
99 | * MW Config and from extension attributes. |
100 | * |
101 | * @param Config $config |
102 | * @return array |
103 | */ |
104 | public static function getEventLoggingConfig( Config $config ) { |
105 | return [ |
106 | 'baseUrl' => $config->get( 'EventLoggingBaseUri' ), |
107 | 'schemasInfo' => self::getSchemas(), |
108 | 'serviceUri' => $config->get( 'EventLoggingServiceUri' ), |
109 | 'queueLingerSeconds' => $config->get( 'EventLoggingQueueLingerSeconds' ), |
110 | // If this is false, EventLogging will not use stream config. |
111 | 'streamConfigs' => self::loadEventStreamConfigs() |
112 | ]; |
113 | } |
114 | |
115 | /** |
116 | * Wraps getEventLoggingConfig for use with ResourceLoader. |
117 | * |
118 | * @param RL\Context $context |
119 | * @param Config $config |
120 | * @return array |
121 | */ |
122 | public static function getModuleData( RL\Context $context, Config $config ) { |
123 | return self::getEventLoggingConfig( $config ); |
124 | } |
125 | |
126 | /** |
127 | * @param User $user |
128 | * @param array &$preferences |
129 | */ |
130 | public function onGetPreferences( $user, &$preferences ): void { |
131 | // See 'ext.eventLogging.debug' module. |
132 | $preferences['eventlogging-display-web'] = [ |
133 | 'type' => 'api', |
134 | ]; |
135 | $preferences['eventlogging-display-console'] = [ |
136 | 'type' => 'api', |
137 | ]; |
138 | } |
139 | |
140 | public function onCanonicalNamespaces( &$namespaces ): void { |
141 | if ( JsonSchemaHooks::isSchemaNamespaceEnabled() ) { |
142 | $namespaces[ NS_SCHEMA ] = 'Schema'; |
143 | $namespaces[ NS_SCHEMA_TALK ] = 'Schema_talk'; |
144 | } |
145 | } |
146 | |
147 | /** |
148 | * Uses the EventStreamConfig extension to return a stream configs map |
149 | * (stream name -> config). The target stream configs to export are |
150 | * selected using the $wgEventLoggingStreamNames MW config variable. |
151 | * This is expected to be a list of stream names that are defined |
152 | * in $wgEventStreams. |
153 | * |
154 | * EventLogging uses this within the ./data.json data file |
155 | * from which it loads and configures all of the streams and stream |
156 | * configs to which it is allowed to submit events. |
157 | * |
158 | * This function returns an array mapping explicit stream names |
159 | * to their configurations. |
160 | * |
161 | * NOTE: We need a list of target streams to get configs for. |
162 | * $wgEventStreams may not explicitly define all stream names; |
163 | * it supports matching stream names by regexes. We need to |
164 | * give the EventStreamConfig StreamConfigs->get function |
165 | * a list of streams to search for in $wgEventStreams. |
166 | * $wgEventLoggingStreamNames is that list. |
167 | * |
168 | * @return array|bool Selected stream name -> stream configs |
169 | */ |
170 | private static function loadEventStreamConfigs() { |
171 | // FIXME: Does the following need to be logged? |
172 | if ( !ExtensionRegistry::getInstance()->isLoaded( 'EventStreamConfig' ) ) { |
173 | EventLogging::getLogger()->debug( 'EventStreamConfig is not installed' ); |
174 | return false; |
175 | } |
176 | |
177 | $streamConfigs = MediaWikiServices::getInstance()->getService( 'EventLogging.StreamConfigs' ); |
178 | |
179 | if ( $streamConfigs === false ) { |
180 | return false; |
181 | } |
182 | |
183 | // Only send stream config settings that should be sent to the client as part of the |
184 | // ext.eventLogging RL module. |
185 | $settingsAllowList = array_flip( self::STREAM_CONFIG_SETTINGS_ALLOWLIST ); |
186 | |
187 | return array_map( |
188 | static function ( $streamConfig ) use ( $settingsAllowList ) { |
189 | return array_intersect_key( $streamConfig, $settingsAllowList ); |
190 | }, |
191 | $streamConfigs |
192 | ); |
193 | } |
194 | } |