Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
37.36% |
34 / 91 |
|
50.00% |
5 / 10 |
CRAP | |
0.00% |
0 / 1 |
PopupsHooks | |
37.36% |
34 / 91 |
|
50.00% |
5 / 10 |
165.55 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
getCustomPopupTypes | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
onGetPreferences | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
4 | |||
getPagePreviewPrefToggle | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
6 | |||
getReferencePreviewPrefToggle | |
0.00% |
0 / 23 |
|
0.00% |
0 / 1 |
30 | |||
onBeforePageDisplay | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
onResourceLoaderGetConfigVars | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
onMakeGlobalVariablesScript | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
onUserGetDefaultOptions | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
onLocalUserCreated | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | /* |
3 | * This file is part of the MediaWiki extension Popups. |
4 | * |
5 | * Popups is free software: you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation, either version 2 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * Popups is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with Popups. If not, see <http://www.gnu.org/licenses/>. |
17 | * |
18 | * @file |
19 | * @ingroup extensions |
20 | */ |
21 | namespace Popups; |
22 | |
23 | use ExtensionRegistry; |
24 | use MediaWiki\Auth\Hook\LocalUserCreatedHook; |
25 | use MediaWiki\Config\Config; |
26 | use MediaWiki\Hook\BeforePageDisplayHook; |
27 | use MediaWiki\Hook\MakeGlobalVariablesScriptHook; |
28 | use MediaWiki\Output\OutputPage; |
29 | use MediaWiki\Preferences\Hook\GetPreferencesHook; |
30 | use MediaWiki\ResourceLoader\Context; |
31 | use MediaWiki\ResourceLoader\Hook\ResourceLoaderGetConfigVarsHook; |
32 | use MediaWiki\User\Hook\UserGetDefaultOptionsHook; |
33 | use MediaWiki\User\Options\UserOptionsManager; |
34 | use MediaWiki\User\User; |
35 | use Psr\Log\LoggerInterface; |
36 | use Skin; |
37 | |
38 | /** |
39 | * Hooks definitions for Popups extension |
40 | * |
41 | * @package Popups |
42 | */ |
43 | class PopupsHooks implements |
44 | GetPreferencesHook, |
45 | BeforePageDisplayHook, |
46 | ResourceLoaderGetConfigVarsHook, |
47 | MakeGlobalVariablesScriptHook, |
48 | UserGetDefaultOptionsHook, |
49 | LocalUserCreatedHook |
50 | { |
51 | |
52 | private const PREVIEWS_PREFERENCES_SECTION = 'rendering/reading'; |
53 | |
54 | /** @var Config */ |
55 | private $config; |
56 | |
57 | /** @var PopupsContext */ |
58 | private $popupsContext; |
59 | |
60 | /** @var LoggerInterface */ |
61 | private $logger; |
62 | |
63 | /** @var UserOptionsManager */ |
64 | private $userOptionsManager; |
65 | |
66 | /** |
67 | * @param Config $config |
68 | * @param PopupsContext $popupsContext |
69 | * @param LoggerInterface $logger |
70 | * @param UserOptionsManager $userOptionsManager |
71 | */ |
72 | public function __construct( |
73 | Config $config, |
74 | PopupsContext $popupsContext, |
75 | LoggerInterface $logger, |
76 | UserOptionsManager $userOptionsManager |
77 | ) { |
78 | $this->config = $config; |
79 | $this->popupsContext = $popupsContext; |
80 | $this->logger = $logger; |
81 | $this->userOptionsManager = $userOptionsManager; |
82 | } |
83 | |
84 | /** |
85 | * Get custom Popups types registered by extensions |
86 | * @param Context $context |
87 | * @return array |
88 | */ |
89 | public static function getCustomPopupTypes( Context $context ): array { |
90 | // FIXME: If the module ext.cite.referencePreviews does not exist register reference previews. |
91 | // This code can be removed once T355194 is complete. |
92 | $others = $context->getResourceLoader()->getModule( 'ext.cite.referencePreviews' ) ? |
93 | [] : [ 'ext.popups.referencePreviews' ]; |
94 | |
95 | return array_merge( ExtensionRegistry::getInstance()->getAttribute( |
96 | 'PopupsPluginModules' |
97 | ), $others ); |
98 | } |
99 | |
100 | /** |
101 | * Add options to user Preferences page |
102 | * |
103 | * @param User $user User whose preferences are being modified |
104 | * @param array[] &$prefs Preferences description array, to be fed to a HTMLForm object |
105 | */ |
106 | public function onGetPreferences( $user, &$prefs ) { |
107 | if ( !$this->popupsContext->showPreviewsOptInOnPreferencesPage() ) { |
108 | return; |
109 | } |
110 | |
111 | $skinPosition = array_search( 'skin', array_keys( $prefs ) ); |
112 | $readingOptions = self::getPagePreviewPrefToggle( $user, $this->popupsContext ); |
113 | |
114 | if ( $this->config->get( 'PopupsReferencePreviews' ) ) { |
115 | $readingOptions = array_merge( |
116 | $readingOptions, |
117 | self::getReferencePreviewPrefToggle( $user, $this->popupsContext ) |
118 | ); |
119 | } |
120 | |
121 | if ( $skinPosition !== false ) { |
122 | $injectIntoIndex = $skinPosition + 1; |
123 | $prefs = array_slice( $prefs, 0, $injectIntoIndex, true ) |
124 | + $readingOptions |
125 | + array_slice( $prefs, $injectIntoIndex, null, true ); |
126 | } else { |
127 | $prefs += $readingOptions; |
128 | } |
129 | } |
130 | |
131 | /** |
132 | * Get Page Preview option |
133 | * |
134 | * @param User $user User whose preferences are being modified |
135 | * @param PopupsContext $context |
136 | * @return array[] |
137 | */ |
138 | private static function getPagePreviewPrefToggle( User $user, PopupsContext $context ) { |
139 | $option = [ |
140 | 'type' => 'toggle', |
141 | 'label-message' => 'popups-prefs-optin', |
142 | 'help-message' => 'popups-prefs-conflicting-gadgets-info', |
143 | 'section' => self::PREVIEWS_PREFERENCES_SECTION |
144 | ]; |
145 | |
146 | if ( $context->conflictsWithNavPopupsGadget( $user ) ) { |
147 | $option[ 'disabled' ] = true; |
148 | $option[ 'help-message' ] = [ 'popups-prefs-disable-nav-gadgets-info', |
149 | 'Special:Preferences#mw-prefsection-gadgets' ]; |
150 | } |
151 | |
152 | return [ |
153 | PopupsContext::PREVIEWS_OPTIN_PREFERENCE_NAME => $option |
154 | ]; |
155 | } |
156 | |
157 | /** |
158 | * Get Reference Preview option |
159 | * |
160 | * @param User $user User whose preferences are being modified |
161 | * @param PopupsContext $context |
162 | * @return array[] |
163 | */ |
164 | private static function getReferencePreviewPrefToggle( User $user, PopupsContext $context ) { |
165 | $option = [ |
166 | 'type' => 'toggle', |
167 | 'label-message' => 'popups-refpreview-user-preference-label', |
168 | 'help-message' => 'popups-prefs-conflicting-gadgets-info', |
169 | 'section' => self::PREVIEWS_PREFERENCES_SECTION |
170 | ]; |
171 | |
172 | $isNavPopupsGadgetEnabled = $context->conflictsWithNavPopupsGadget( $user ); |
173 | $isRefTooltipsGadgetEnabled = $context->conflictsWithRefTooltipsGadget( $user ); |
174 | |
175 | if ( $isNavPopupsGadgetEnabled && $isRefTooltipsGadgetEnabled ) { |
176 | $option[ 'disabled' ] = true; |
177 | $option[ 'help-message' ] = [ 'popups-prefs-reftooltips-and-navpopups-gadget-conflict-info', |
178 | 'Special:Preferences#mw-prefsection-gadgets' ]; |
179 | } elseif ( $isNavPopupsGadgetEnabled ) { |
180 | $option[ 'disabled' ] = true; |
181 | $option[ 'help-message' ] = [ 'popups-prefs-navpopups-gadget-conflict-info', |
182 | 'Special:Preferences#mw-prefsection-gadgets' ]; |
183 | } elseif ( $isRefTooltipsGadgetEnabled ) { |
184 | $option[ 'disabled' ] = true; |
185 | $option[ 'help-message' ] = [ 'popups-prefs-reftooltips-gadget-conflict-info', |
186 | 'Special:Preferences#mw-prefsection-gadgets' ]; |
187 | } |
188 | |
189 | return [ |
190 | PopupsContext::REFERENCE_PREVIEWS_PREFERENCE_NAME => $option |
191 | ]; |
192 | } |
193 | |
194 | /** |
195 | * Allows last minute changes to the output page, e.g. adding of CSS or JavaScript by extensions. |
196 | * |
197 | * @param OutputPage $out The Output page object |
198 | * @param Skin $skin Skin object that will be used to generate the page |
199 | */ |
200 | public function onBeforePageDisplay( $out, $skin ): void { |
201 | if ( $this->popupsContext->isTitleExcluded( $out->getTitle() ) ) { |
202 | return; |
203 | } |
204 | |
205 | if ( !$this->popupsContext->areDependenciesMet() ) { |
206 | $this->logger->error( 'Popups requires the PageImages extensions. |
207 | TextExtracts extension is required when using mwApiPlain gateway.' ); |
208 | return; |
209 | } |
210 | |
211 | $user = $out->getUser(); |
212 | if ( $this->popupsContext->shouldSendModuleToUser( $user ) ) { |
213 | $out->addModules( [ 'ext.popups' ] ); |
214 | } |
215 | } |
216 | |
217 | /** |
218 | * Hook handler for the ResourceLoaderStartUpModule that makes static configuration visible to |
219 | * the frontend. These variables end in the only "startup" ResourceLoader module that is loaded |
220 | * before all others. |
221 | * |
222 | * Dynamic configuration that depends on the context needs to be published via the |
223 | * MakeGlobalVariablesScript hook. |
224 | * |
225 | * @param array &$vars Array of variables to be added into the output of the startup module |
226 | * @param string $skin |
227 | * @param Config $config |
228 | */ |
229 | public function onResourceLoaderGetConfigVars( array &$vars, $skin, Config $config ): void { |
230 | $vars['wgPopupsVirtualPageViews'] = $this->config->get( 'PopupsVirtualPageViews' ); |
231 | $vars['wgPopupsGateway'] = $this->config->get( 'PopupsGateway' ); |
232 | $vars['wgPopupsRestGatewayEndpoint'] = $this->config->get( 'PopupsRestGatewayEndpoint' ); |
233 | $vars['wgPopupsStatsvSamplingRate'] = $this->config->get( 'PopupsStatsvSamplingRate' ); |
234 | $vars['wgPopupsTextExtractsIntroOnly'] = $this->config->get( 'PopupsTextExtractsIntroOnly' ); |
235 | } |
236 | |
237 | /** |
238 | * Hook handler publishing dynamic configuration that depends on the context, e.g. the page or |
239 | * the users settings. These variables end in an inline <script> in the documents head. |
240 | * |
241 | * Variables added: |
242 | * * `wgPopupsReferencePreviews' - The server's notion of whether or not the reference |
243 | * previews should be enabled. Depending on the general setting done on the wiki. |
244 | * * `wgPopupsConflictsWithNavPopupGadget' - The server's notion of whether or not the |
245 | * user has enabled conflicting Navigational Popups Gadget. |
246 | * * `wgPopupsConflictsWithRefTooltipsGadget' - The server's notion of whether or not the |
247 | * user has enabled conflicting Reference Tooltips Gadget. |
248 | * |
249 | * @param array &$vars variables to be added into the output of OutputPage::headElement |
250 | * @param \IContextSource $out OutputPage instance calling the hook |
251 | */ |
252 | public function onMakeGlobalVariablesScript( &$vars, $out ): void { |
253 | $vars['wgPopupsFlags'] = $this->popupsContext->getConfigBitmaskFromUser( $out->getUser() ); |
254 | } |
255 | |
256 | /** |
257 | * Called whenever a user wants to reset their preferences. |
258 | * |
259 | * @param array &$defaultOptions |
260 | */ |
261 | public function onUserGetDefaultOptions( &$defaultOptions ) { |
262 | $default = $this->config->get( 'PopupsOptInDefaultState' ); |
263 | $defaultOptions[PopupsContext::PREVIEWS_OPTIN_PREFERENCE_NAME] = $default; |
264 | |
265 | if ( $this->config->get( 'PopupsReferencePreviews' ) ) { |
266 | $defaultOptions[PopupsContext::REFERENCE_PREVIEWS_PREFERENCE_NAME] = '1'; |
267 | } |
268 | } |
269 | |
270 | /** |
271 | * Called one time when initializing a users preferences for a newly created account. |
272 | * |
273 | * @param User $user Newly created user object |
274 | * @param bool $isAutoCreated |
275 | */ |
276 | public function onLocalUserCreated( $user, $isAutoCreated ) { |
277 | $default = $this->config->get( 'PopupsOptInStateForNewAccounts' ); |
278 | $this->userOptionsManager->setOption( |
279 | $user, |
280 | PopupsContext::PREVIEWS_OPTIN_PREFERENCE_NAME, |
281 | $default |
282 | ); |
283 | |
284 | if ( $this->config->get( 'PopupsReferencePreviews' ) ) { |
285 | $this->userOptionsManager->setOption( |
286 | $user, |
287 | PopupsContext::REFERENCE_PREVIEWS_PREFERENCE_NAME, |
288 | $default |
289 | ); |
290 | } |
291 | } |
292 | } |