hooks.txt
-This document describes how event hooks work in MediaWiki; how to add
-hooks for an event; and how to run hooks for an event.
+This document describes how event hooks work in MediaWiki; how to add hooks for
+an event; and how to run hooks for an event.
==Glossary==
event
- Something that happens with the wiki. For example: a user logs
- in. A wiki page is saved. A wiki page is deleted. Often there are
- two events associated with a single action: one before the code
- is run to make the event happen, and one after. Each event has a
- name, preferably in CamelCase. For example, 'UserLogin',
- 'ArticleSave', 'ArticleSaveComplete', 'ArticleDelete'.
+ Something that happens with the wiki. For example: a user logs in. A wiki
+ page is saved. A wiki page is deleted. Often there are two events
+ associated with a single action: one before the code is run to make the
+ event happen, and one after. Each event has a name, preferably in
+ CamelCase. For example, 'UserLogin', 'ArticleSave', 'ArticleSaveComplete',
+ 'ArticleDelete'.
hook
- A clump of code and data that should be run when an event
- happens. This can be either a function and a chunk of data, or an
- object and a method.
+ A clump of code and data that should be run when an event happens. This can
+ be either a function and a chunk of data, or an object and a method.
hook function
The function part of a hook.
==Rationale==
-Hooks allow us to decouple optionally-run code from code that is run
-for everyone. It allows MediaWiki hackers, third-party developers and
-local administrators to define code that will be run at certain points
-in the mainline code, and to modify the data run by that mainline
-code. Hooks can keep mainline code simple, and make it easier to
-write extensions. Hooks are a principled alternative to local patches.
+Hooks allow us to decouple optionally-run code from code that is run for
+everyone. It allows MediaWiki hackers, third-party developers and local
+administrators to define code that will be run at certain points in the mainline
+code, and to modify the data run by that mainline code. Hooks can keep mainline
+code simple, and make it easier to write extensions. Hooks are a principled
+alternative to local patches.
-Consider, for example, two options in MediaWiki. One reverses the
-order of a title before displaying the article; the other converts the
-title to all uppercase letters. Currently, in MediaWiki code, we
-would handle this as follows (note: not real code, here):
+Consider, for example, two options in MediaWiki. One reverses the order of a
+title before displaying the article; the other converts the title to all
+uppercase letters. Currently, in MediaWiki code, we would handle this as follows
+(note: not real code, here):
function showAnArticle($article) {
global $wgReverseTitle, $wgCapitalizeTitle;
# code to actually show the article goes here
}
-An extension writer, or a local admin, will often add custom code to
-the function -- with or without a global variable. For example,
-someone wanting email notification when an article is shown may add:
+An extension writer, or a local admin, will often add custom code to the
+function -- with or without a global variable. For example, someone wanting
+email notification when an article is shown may add:
function showAnArticle($article) {
- global $wgReverseTitle, $wgCapitalizeTitle;
+ global $wgReverseTitle, $wgCapitalizeTitle, $wgNotifyArticle;
- if ($wgReverseTitle) {
- wfReverseTitle($article);
- }
+ if ($wgReverseTitle) {
+ wfReverseTitle($article);
+ }
- if ($wgCapitalizeTitle) {
- wfCapitalizeTitle($article);
- }
+ if ($wgCapitalizeTitle) {
+ wfCapitalizeTitle($article);
+ }
- # code to actually show the article goes here
+ # code to actually show the article goes here
- if ($wgNotifyArticle) {
- wfNotifyArticleShow($article));
- }
+ if ($wgNotifyArticle) {
+ wfNotifyArticleShow($article));
+ }
}
-Using a hook-running strategy, we can avoid having all this
-option-specific stuff in our mainline code. Using hooks, the function
-becomes:
+Using a hook-running strategy, we can avoid having all this option-specific
+stuff in our mainline code. Using hooks, the function becomes:
function showAnArticle($article) {
}
}
-We've cleaned up the code here by removing clumps of weird,
-infrequently used code and moving them off somewhere else. It's much
-easier for someone working with this code to see what's _really_ going
-on, and make changes or fix bugs.
+We've cleaned up the code here by removing clumps of weird, infrequently used
+code and moving them off somewhere else. It's much easier for someone working
+with this code to see what's _really_ going on, and make changes or fix bugs.
-In addition, we can take all the code that deals with the little-used
-title-reversing options (say) and put it in one place. Instead of
-having little title-reversing if-blocks spread all over the codebase
-in showAnArticle, deleteAnArticle, exportArticle, etc., we can
-concentrate it all in an extension file:
+In addition, we can take all the code that deals with the little-used
+title-reversing options (say) and put it in one place. Instead of having little
+title-reversing if-blocks spread all over the codebase in showAnArticle,
+deleteAnArticle, exportArticle, etc., we can concentrate it all in an extension
+file:
function reverseArticleTitle($article) {
# ...
# ...
}
-The setup function for the extension just has to add its hook
-functions to the appropriate events:
+The setup function for the extension just has to add its hook functions to the
+appropriate events:
setupTitleReversingExtension() {
global $wgHooks;
$wgHooks['ArticleExport'][] = 'reverseForExport';
}
-Having all this code related to the title-reversion option in one
-place means that it's easier to read and understand; you don't have to
-do a grep-find to see where the $wgReverseTitle variable is used, say.
+Having all this code related to the title-reversion option in one place means
+that it's easier to read and understand; you don't have to do a grep-find to see
+where the $wgReverseTitle variable is used, say.
-If the code is well enough isolated, it can even be excluded when not
-used -- making for some slight savings in memory and load-up
-performance at runtime. Admins who want to have all the reversed
-titles can add:
+If the code is well enough isolated, it can even be excluded when not used --
+making for some slight savings in memory and load-up performance at runtime.
+Admins who want to have all the reversed titles can add:
require_once('extensions/ReverseTitle.php');
-...to their LocalSettings.php file; those of us who don't want or need
-it can just leave it out.
+...to their LocalSettings.php file; those of us who don't want or need it can
+just leave it out.
-The extensions don't even have to be shipped with MediaWiki; they
-could be provided by a third-party developer or written by the admin
-him/herself.
+The extensions don't even have to be shipped with MediaWiki; they could be
+provided by a third-party developer or written by the admin him/herself.
==Writing hooks==
* a function with some optional accompanying data, or
* an object with a method and some optional accompanying data.
-Hooks are registered by adding them to the global $wgHooks array for a
-given event. All the following are valid ways to define hooks:
+Hooks are registered by adding them to the global $wgHooks array for a given
+event. All the following are valid ways to define hooks:
$wgHooks['EventName'][] = 'someFunction'; # function, no data
$wgHooks['EventName'][] = array('someFunction', $someData);
$wgHooks['EventName'][] = array($object, 'someMethod', $someData);
$wgHooks['EventName'][] = array($object); # weird but OK
-When an event occurs, the function (or object method) will be called
-with the optional data provided as well as event-specific parameters.
-The above examples would result in the following code being executed
-when 'EventName' happened:
+When an event occurs, the function (or object method) will be called with the
+optional data provided as well as event-specific parameters. The above examples
+would result in the following code being executed when 'EventName' happened:
# function, no data
someFunction($param1, $param2)
# object with method and data
$object->someMethod($someData, $param1, $param2)
-Note that when an object is the hook, and there's no specified method,
-the default method called is 'onEventName'. For different events this
-would be different: 'onArticleSave', 'onUserLogin', etc.
+Note that when an object is the hook, and there's no specified method, the
+default method called is 'onEventName'. For different events this would be
+different: 'onArticleSave', 'onUserLogin', etc.
-The extra data is useful if we want to use the same function or object
-for different purposes. For example:
+The extra data is useful if we want to use the same function or object for
+different purposes. For example:
$wgHooks['ArticleSaveComplete'][] = array('ircNotify', 'TimStarling');
$wgHooks['ArticleSaveComplete'][] = array('ircNotify', 'brion');
-This code would result in ircNotify being run twice when an article is
-saved: once for 'TimStarling', and once for 'brion'.
+This code would result in ircNotify being run twice when an article is saved:
+once for 'TimStarling', and once for 'brion'.
Hooks can return three possible values:
* true: the hook has operated successfully
- * "some string": an error occurred; processing should
- stop and the error should be shown to the user
- * false: the hook has successfully done the work
- necessary and the calling function should skip
+ * "some string": an error occurred; processing should stop and the error
+ should be shown to the user
+ * false: the hook has successfully done the work necessary and the calling
+ function should skip
-The last result would be for cases where the hook function replaces
-the main functionality. For example, if you wanted to authenticate
-users to a custom system (LDAP, another PHP program, whatever), you
-could do:
+The last result would be for cases where the hook function replaces the main
+functionality. For example, if you wanted to authenticate users to a custom
+system (LDAP, another PHP program, whatever), you could do:
$wgHooks['UserLogin'][] = array('ldapLogin', $ldapServer);
return false;
}
-Returning false makes less sense for events where the action is
-complete, and will normally be ignored.
+Returning false makes less sense for events where the action is complete, and
+will normally be ignored.
==Using hooks==
-A calling function or method uses the wfRunHooks() function to run
-the hooks related to a particular event, like so:
+A calling function or method uses the wfRunHooks() function to run the hooks
+related to a particular event, like so:
class Article {
# ...
}
}
-wfRunHooks() returns true if the calling function should continue
-processing (the hooks ran OK, or there are no hooks to run), or false
-if it shouldn't (an error occurred, or one of the hooks handled the
-action already). Checking the return value matters more for "before"
-hooks than for "complete" hooks.
+wfRunHooks() returns true if the calling function should continue processing
+(the hooks ran OK, or there are no hooks to run), or false if it shouldn't (an
+error occurred, or one of the hooks handled the action already). Checking the
+return value matters more for "before" hooks than for "complete" hooks.
Note that hook parameters are passed in an array; this is a necessary
-inconvenience to make it possible to pass reference values (that can
-be changed) into the hook code. Also note that earlier versions of
-wfRunHooks took a variable number of arguments; the array() calling
-protocol came about after MediaWiki 1.4rc1.
+inconvenience to make it possible to pass reference values (that can be changed)
+into the hook code. Also note that earlier versions of wfRunHooks took a
+variable number of arguments; the array() calling protocol came about after
+MediaWiki 1.4rc1.
==Events and parameters==
-This is a list of known events and parameters; please add to it if
-you're going to add events to the MediaWiki code.
+This is a list of known events and parameters; please add to it if you're going
+to add events to the MediaWiki code.
+
+'AbortAutoblock': Return false to cancel an autoblock.
+$autoblockip: The IP going to be autoblocked.
+$block: The block from which the autoblock is coming.
'AbortLogin': Return false to cancel account login.
$user: the User object being authenticated against
$nt: new title
$user: user who is doing the move
$err: error message
+$reason: the reason for the move (added in 1.13)
'AbortNewAccount': Return false to cancel account creation.
$user: the User object about to be created (read-only, incomplete)
$text : the new text of the article (has yet to be saved)
$resultArr : data in this array will be added to the API result
+'APIQueryInfoTokens': use this hook to add custom tokens to prop=info.
+Every token has an action, which will be used in the intoken parameter
+and in the output (actiontoken="..."), and a callback function which
+should return the token, or false if the user isn't allowed to obtain
+it. The prototype of the callback function is func($pageid, $title)
+where $pageid is the page ID of the page the token is requested for
+and $title is the associated Title object. In the hook, just add
+your callback to the $tokenFunctions array and return true (returning
+false makes no sense)
+$tokenFunctions: array(action => callback)
+
+'APIQueryRevisionsTokens': use this hook to add custom tokens to prop=revisions.
+Every token has an action, which will be used in the rvtoken parameter
+and in the output (actiontoken="..."), and a callback function which
+should return the token, or false if the user isn't allowed to obtain
+it. The prototype of the callback function is func($pageid, $title, $rev)
+where $pageid is the page ID of the page associated to the revision the
+token is requested for, $title the associated Title object and $rev the
+associated Revision object. In the hook, just add your callback to the
+$tokenFunctions array and return true (returning false makes no sense)
+$tokenFunctions: array(action => callback)
+
'ArticleAfterFetchContent': after fetching content of an article from the database
$article: the article (object) being loaded from the database
$content: the content (string) of the article
$article: the article (object) being deleted
$user: the user (object) deleting the article
$reason: the reason (string) the article is being deleted
+$error: if the deletion was prohibited, the (raw HTML) error message to display
+ (added in 1.13)
'ArticleDeleteComplete': after an article is deleted
$article: the article that was deleted
$title: title (object) used to create the article object
$article: article (object) that will be returned
-'ArticleInsertComplete': After an article is created
+'ArticleInsertComplete': After a new article is created
$article: Article created
$user: User creating the article
$text: New content
'ArticleViewRedirect': before setting "Redirected from ..." subtitle when follwed an redirect
$article: target article (object)
+'AuthPluginAutoCreate': Called when creating a local account for an user logged
+in from an external authentication method
+$user: User object created locally
+
'AuthPluginSetup': update or replace authentication plugin object ($wgAuth)
Gives a chance for an extension to set it programattically to a variable class.
&$auth: the $wgAuth object, probably a stub
$unpatrolled: Whether or not we are showing unpatrolled changes.
$watched: Whether or not the change is watched by the user.
+'ContribsPager::getQueryInfo': Before the contributions query is about to run
+&$pager: Pager object for contributions
+&queryInfo: The query for the contribs Pager
+
+'ContributionsLineEnding': Called before a contributions HTML line is finished
+$page: SpecialPage object for contributions
+$ret: the HTML line
+$row: the DB row for this line
+
'ContributionsToolLinks': Change tool links above Special:Contributions
$id: User identifier
$title: User page title
$text: Contents of the edit box
$section: Section being edited
&$error: Error message to return
+$summary: Edit summary for page
'EditFilterMerged': Post-section-merge edit filter
$editor: EditPage instance (object)
$text: content of the edit box
$error: error message to return
+$summary: Edit summary for page
'EditFormPreloadText': Allows population of the edit form when creating new pages
&$text: Text to preload with
$user: user who performed the undeletion
$reason: reason
+'GetAutoPromoteGroups': When determining which autopromote groups a user is entitled to be in.
+&$user: user to promote.
+&$promote: groups that will be added.
+
'GetBlockedStatus': after loading blocking status of an user from the database
$user: user (object) being checked
'getUserPermissionsErrorsExpensive': Absolutely the same, but is called only
if expensive checks are enabled.
-'ImageOpenShowImageInlineBefore': Call potential extension just before showing
- the image on an image page
-$imagePage: ImagePage object ($this)
-$output: $wgOut
-
'ImageBeforeProduceHTML': Called before producing the HTML created by a wiki
image insertion. You can skip the default logic entirely by returning
false, or just modify a few things using call-by-reference.
&$time: Timestamp of file in 'YYYYMMDDHHIISS' string form, or false for current
&$res: Final HTML output, used if you return false
+
+'ImageOpenShowImageInlineBefore': Call potential extension just before showing
+ the image on an image page
+$imagePage: ImagePage object ($this)
+$output: $wgOut
+
+'ImagePageFileHistoryLine': called when a file history line is contructed
+$file: the file
+$line: the HTML of the history line
+$css: the line CSS class
+
+'ImagePageFindFile': called when fetching the file associated with an image page
+$page: ImagePage object
+&$file: File object
+&$displayFile: displayed File object
+
+'InitializeArticleMaybeRedirect': MediaWiki check to see if title is a redirect
+$title: Title object ($wgTitle)
+$request: WebRequest
+$ignoreRedirect: boolean to skip redirect check
+$target: Title/string of redirect target
+
'InitPreferencesForm': called at the end of PreferencesForm's constructor
$form: the PreferencesForm
$request: the web request to initialized from
$specialPageAliases: associative array of magic words synonyms
$lang: laguage code (string)
+'LinkerMakeExternalImage': At the end of Linker::makeExternalImage() just before the return
+&$url: the image url
+&$alt: the image's alt text
+&$img: the new image HTML (if returning false)
+
+'LinkerMakeExternalLink': At the end of Linker::makeExternalLink() just before the return
+&$url: the link url
+&$text: the link text
+&$link: the new link HTML (if returning false)
+
'LinksUpdate': At the beginning of LinksUpdate::doUpdate() just before the actual update
&$linksUpdate: the LinkUpdate object
'LoadExtensionSchemaUpdates': called by maintenance/updaters.inc when upgrading database schema
+'LocalFile::getHistory': called before file history query performed
+$file: the file
+$tables: tables
+$fields: select fields
+$conds: conditions
+$opts: query options
+$join_conds: JOIN conditions
+
'LoginAuthenticateAudit': a login attempt for a valid user account either succeeded or failed.
No return data is accepted; this hook is for auditing only.
$user: the User object being authenticated against
$title: $wgTitle
$user: $wgUser
$request: $wgRequest
+$this: The $mediawiki object
'MessagesPreLoad': When loading a message from the database
$title: title of the message (string)
instead.
$tools: array of tools
+'NewRevisionFromEditComplete': called when a revision was inserted due to an edit
+$article: the article edited
+$rev: the new revision
+$baseID: the revision ID this was based off, if any
+
+'NormalizeMessageKey': Called before the software gets the text of a message
+ (stuff in the MediaWiki: namespace), useful for changing WHAT message gets displayed
+&$key: the message being looked up. Change this to something else to change what message gets displayed (string)
+&$useDB: whether or not to look up the message in the database (bool)
+&$langCode: the language code to get the message for (string) - or -
+ whether to use the content language (true) or site language (false) (bool)
+&$transform: whether or not to expand variables and templates in the message (bool)
+
+'OpenSearchUrls': Called when constructing the OpenSearch description XML.
+Hooks can alter or append to the array of URLs for search & suggestion formats.
+&$urls: array of associative arrays with Url element attributes
+
'OutputPageBeforeHTML': a page has been processed by the parser and
the resulting HTML is about to be displayed.
$parserOutput: the parserOutput (object) that corresponds to the page
$out: OutputPage instance (object)
$parserOutput: parserOutput instance being added in $out
+'OutputPageMakeCategoryLinks': links are about to be generated for the page's categories.
+ Implementations should return false if they generate the category links, so the default link generation is skipped.
+$out: OutputPage instance (object)
+$categories: associative array, keys are category names, values are category types ("normal" or "hidden")
+$links: array, intended to hold the result. Must be an associative array with category types as keys and arrays of HTML links as values.
+
'PageHistoryBeforeList': When a history page list is about to be constructed.
$article: the article that the history is loading for
$row: the revision row for this line
$s: the string representing this parsed line
+'PageHistoryPager::getQueryInfo': when a history pager query parameter set is constructed
+$pager: the pager
+$queryInfo: the query parameters
+
'PageRenderingHash': alter the parser cache option hash key
A parser extension which depends on user options should install
this hook and append its values to the key.
$user: the User object to load preferences from
'RevisionInsertComplete': called after a revision is inserted into the DB
-$revision: the Revision
+&$revision: the Revision
+$data: the data stored in old_text. The meaning depends on $flags: if external
+ is set, it's the URL of the revision text in external storage; otherwise,
+ it's the revision text itself. In either case, if gzip is set, the revision
+ text is gzipped.
+$flags: a comma-delimited list of strings representing the options used. May
+ include: utf8 (this will always be set for new revisions); gzip; external.
'SavePreferences': called at the end of PreferencesForm::savePreferences;
returning false prevents the preferences from being saved.
'SpecialPage_initList': called when setting up SpecialPage::$mList, use this hook to remove a core special page
$list: list (array) of core special pages
+'SpecialRecentChangesPanel': called when building form options in SpecialRecentChanges
+&$extraOpts: array of added items, to which can be added
+$opts: FormOptions for this request
+
+'SpecialRecentChangesQuery': called when building sql query for SpecialRecentChanges
+&$conds: array of where conditionals for query
+&$tables: array of tables to be queried
+&$join_conds: join conditions for the tables
+$opts: FormOptions for this request
+
'SpecialSearchNogomatch': called when user clicked the "Go" button but the target doesn't exist
$title: title object generated from the text entred by the user
'SpecialSearchResults': called before search result display when there are matches
$term: string of search term
-$titleMatches: empty or SearchResultSet object
-$textMatches: empty or SearchResultSet object
+&$titleMatches: empty or SearchResultSet object
+&$textMatches: empty or SearchResultSet object
'SpecialSearchNoResults': called before search result display when there are no matches
$term: string of search term
$user: User to get rights for
&$rights: Current rights
+'UserLoadDefaults': called when loading a default user
+$user: user object
+$name: user name
+
'UserLoadFromSession': called to authenticate users on external/environmental means
$user: user object being loaded
&$result: set this to a boolean value to abort the normal authentification process
'UserLogoutComplete': after a user has logged out
$user: the user object _after_ logout (won't have name, ID, etc.)
$inject_html: Any HTML to inject after the "logged out" message.
+$oldName: name of the user before logout (string)
'UserRights': After a user's group memberships are changed
$user : User object that was changed
'UserSaveSettings': called when saving user settings
$user: User object
+'UserSetCookies': called when setting user cookies
+$user: User object
+&$session: session array, will be added to $_SESSION
+&$cookies: cookies array mapping cookie name to its value
+
'UserSetEmail': called when changing user email address
$user: User object
&$email: new email, change this to override new email address