MediaWiki REL1_34
GadgetHooks.php
Go to the documentation of this file.
1<?php
2
24use Wikimedia\WrappedString;
25
34 public static function onPageContentSaveComplete( WikiPage $wikiPage, $user, $content ) {
35 // update cache if MediaWiki:Gadgets-definition was edited
36 GadgetRepo::singleton()->handlePageUpdate( $wikiPage->getTitle() );
37 }
38
43 public static function userGetDefaultOptions( array &$defaultOptions ) {
44 $gadgets = GadgetRepo::singleton()->getStructuredList();
45 if ( !$gadgets ) {
46 return;
47 }
48
52 foreach ( $gadgets as $thisSection ) {
53 foreach ( $thisSection as $gadgetId => $gadget ) {
54 if ( $gadget->isOnByDefault() ) {
55 $defaultOptions['gadget-' . $gadgetId] = 1;
56 }
57 }
58 }
59 }
60
66 public static function getPreferences( User $user, array &$preferences ) {
67 $gadgets = GadgetRepo::singleton()->getStructuredList();
68 if ( !$gadgets ) {
69 return;
70 }
71
72 $options = [];
73 $default = [];
74 $skin = RequestContext::getMain()->getSkin();
75 foreach ( $gadgets as $section => $thisSection ) {
76 $available = [];
77
81 foreach ( $thisSection as $gadget ) {
82 if (
83 !$gadget->isHidden()
84 && $gadget->isAllowed( $user )
85 && $gadget->isSkinSupported( $skin )
86 ) {
87 $gname = $gadget->getName();
88 # bug 30182: dir="auto" because it's often not translated
89 $desc = '<span dir="auto">' . $gadget->getDescription() . '</span>';
90 $available[$desc] = $gname;
91 if ( $gadget->isEnabled( $user ) ) {
92 $default[] = $gname;
93 }
94 }
95 }
96
97 if ( $section !== '' ) {
98 $section = wfMessage( "gadget-section-$section" )->parse();
99
100 if ( count( $available ) ) {
101 $options[$section] = $available;
102 }
103 } else {
104 $options = array_merge( $options, $available );
105 }
106 }
107
108 $preferences['gadgets-intro'] =
109 [
110 'type' => 'info',
111 'default' => wfMessage( 'gadgets-prefstext' )->parseAsBlock(),
112 'section' => 'gadgets',
113 'raw' => true,
114 ];
115
116 $preferences['gadgets'] =
117 [
118 'type' => 'multiselect',
119 'options' => $options,
120 'section' => 'gadgets',
121 'label' => '&#160;',
122 'prefix' => 'gadget-',
123 'default' => $default,
124 'noglobal' => true,
125 ];
126 }
127
132 public static function registerModules( ResourceLoader &$resourceLoader ) {
133 $repo = GadgetRepo::singleton();
134 $ids = $repo->getGadgetIds();
135
136 foreach ( $ids as $id ) {
137 $resourceLoader->register( Gadget::getModuleName( $id ), [
138 'class' => 'GadgetResourceLoaderModule',
139 'id' => $id,
140 ] );
141 }
142 }
143
148 public static function beforePageDisplay( OutputPage $out ) {
149 $repo = GadgetRepo::singleton();
150 $ids = $repo->getGadgetIds();
151 if ( !$ids ) {
152 return;
153 }
154
155 $lb = new LinkBatch();
156 $lb->setCaller( __METHOD__ );
157 $enabledLegacyGadgets = [];
158
162 $user = $out->getUser();
163 $skin = $out->getSkin();
164 foreach ( $ids as $id ) {
165 try {
166 $gadget = $repo->getGadget( $id );
167 } catch ( InvalidArgumentException $e ) {
168 continue;
169 }
170 $peers = [];
171 foreach ( $gadget->getPeers() as $peerName ) {
172 try {
173 $peers[] = $repo->getGadget( $peerName );
174 } catch ( InvalidArgumentException $e ) {
175 // Ignore
176 // @todo: Emit warning for invalid peer?
177 }
178 }
179 if ( $gadget->isEnabled( $user )
180 && $gadget->isAllowed( $user )
181 && $gadget->isSkinSupported( $skin )
182 ) {
183 if ( $gadget->hasModule() ) {
184 if ( $gadget->getType() === 'styles' ) {
185 $out->addModuleStyles( Gadget::getModuleName( $gadget->getName() ) );
186 } else {
187 $out->addModules( Gadget::getModuleName( $gadget->getName() ) );
188 // Load peer modules
189 foreach ( $peers as $peer ) {
190 if ( $peer->getType() === 'styles' ) {
191 $out->addModuleStyles( Gadget::getModuleName( $peer->getName() ) );
192 }
193 // Else, if not type=styles: Use dependencies instead.
194 // Note: No need for recursion as styles modules don't support
195 // either of 'dependencies' and 'peers'.
196 }
197 }
198 }
199
200 if ( $gadget->getLegacyScripts() ) {
201 $enabledLegacyGadgets[] = $id;
202 }
203 }
204 }
205
206 $strings = [];
207 foreach ( $enabledLegacyGadgets as $id ) {
208 $strings[] = self::makeLegacyWarning( $id );
209 }
210 $out->addHTML( WrappedString::join( "\n", $strings ) );
211 }
212
213 private static function makeLegacyWarning( $id ) {
214 $special = SpecialPage::getTitleFor( 'Gadgets' );
215
216 return ResourceLoader::makeInlineScript(
217 Xml::encodeJsCall( 'mw.log.warn', [
218 "Gadget \"$id\" was not loaded. Please migrate it to use ResourceLoader. " .
219 'See <' . $special->getCanonicalURL() . '>.'
220 ] )
221 );
222 }
223
236 Status $status,
237 $summary
238 ) {
239 $title = $context->getTitle();
240
241 if ( !$title->inNamespace( NS_GADGET_DEFINITION ) ) {
242 return true;
243 }
244
245 if ( !$content instanceof GadgetDefinitionContent ) {
246 // This should not be possible?
247 throw new Exception(
248 "Tried to save non-GadgetDefinitionContent to {$title->getPrefixedText()}"
249 );
250 }
251
252 $validateStatus = $content->validate();
253 if ( !$validateStatus->isGood() ) {
254 $status->merge( $validateStatus );
255 return false;
256 }
257
258 return true;
259 }
260
267 public static function onPageContentInsertComplete( WikiPage $page ) {
268 if ( $page->getTitle()->inNamespace( NS_GADGET_DEFINITION ) ) {
269 GadgetRepo::singleton()->handlePageCreation( $page->getTitle() );
270 }
271 }
272
281 public static function onContentHandlerDefaultModelFor( Title $title, &$model ) {
282 if ( $title->inNamespace( NS_GADGET ) ) {
283 preg_match( '!\.(css|js)$!u', $title->getText(), $ext );
284 $ext = $ext[1] ?? '';
285 switch ( $ext ) {
286 case 'js':
287 $model = 'javascript';
288 return false;
289 case 'css':
290 $model = 'css';
291 return false;
292 }
293 }
294
295 return true;
296 }
297
306 public static function onCodeEditorGetPageLanguage( Title $title, &$lang ) {
307 if ( $title->hasContentModel( 'GadgetDefinition' ) ) {
308 $lang = 'json';
309 return false;
310 }
311
312 return true;
313 }
314
319 public static function onwgQueryPages( array &$queryPages ) {
320 $queryPages[] = [ 'SpecialGadgetUsage', 'GadgetUsage' ];
321 }
322
330 public static function onDeleteUnknownPreferences( array &$where, IDatabase $db ) {
331 $where[] = 'up_property NOT' . $db->buildLike( 'gadget-', $db->anyString() );
332 }
333}
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
static getPreferences(User $user, array &$preferences)
GetPreferences hook handler.
static onDeleteUnknownPreferences(array &$where, IDatabase $db)
Prevent gadget preferences from being deleted.
static onwgQueryPages(array &$queryPages)
Add the GadgetUsage special page to the list of QueryPages.
static registerModules(ResourceLoader &$resourceLoader)
ResourceLoaderRegisterModules hook handler.
static onCodeEditorGetPageLanguage(Title $title, &$lang)
Set the CodeEditor language for Gadget definition pages.
static beforePageDisplay(OutputPage $out)
BeforePageDisplay hook handler.
static onPageContentInsertComplete(WikiPage $page)
After a new page is created in the Gadget definition namespace, invalidate the list of gadget ids.
static makeLegacyWarning( $id)
static onPageContentSaveComplete(WikiPage $wikiPage, $user, $content)
PageContentSaveComplete hook handler.
static onEditFilterMergedContent(IContextSource $context, Content $content, Status $status, $summary)
Valid gadget definition page after content is modified.
static userGetDefaultOptions(array &$defaultOptions)
UserGetDefaultOptions hook handler.
static onContentHandlerDefaultModelFor(Title $title, &$model)
Mark the Title as having a content model of javascript or css for pages in the Gadget namespace based...
static singleton()
Get the configured default GadgetRepo.
static getModuleName( $id)
Definition Gadget.php:150
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition LinkBatch.php:34
This is one of the Core classes and should be read at least once by any new developers.
addModuleStyles( $modules)
Load the styles of one or more ResourceLoader modules on this page.
addHTML( $text)
Append $text to the body HTML.
addModules( $modules)
Load one or more ResourceLoader modules on this page.
ResourceLoader is a loading system for JavaScript and CSS resources.
merge( $other, $overwriteValue=false)
Merge another status object into this one.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:40
Represents a title within MediaWiki.
Definition Title.php:42
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:51
Class representing a MediaWiki article and history.
Definition WikiPage.php:47
getTitle()
Get the title object of the article.
Definition WikiPage.php:298
Base interface for content objects.
Definition Content.php:34
Interface for objects which can provide a MediaWiki context on request.
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:38
buildLike( $param)
LIKE statement wrapper.
anyString()
Returns a token for buildLike() that denotes a '' to be used in a LIKE query.
$resourceLoader
Definition load.php:44
$context
Definition load.php:45
$content
Definition router.php:78
if(!is_readable( $file)) $ext
Definition router.php:48
if(!isset( $args[0])) $lang