This was added in I56b6600 in an attempt to work around a bug in
CentralAuth, but the bug has since been fixed in a better way. No hook
functions in Gerrit use the parameter (or ever have, as far as I can
tell), and anything that was passing a value other than the default
'login' has since been removed. So let's just get rid of it instead of
keeping it around doing nothing.
Change-Id: Ie604e03d268706221161ac93eb866f477e466fb4
Added for use in the CategoryTree extension to show the category count
on the special page, see If3815586c2a280b4e8958c13010c9f7436b8723d
Change-Id: If195fb55dee1350a6de095892ce89e6565287cd9
Also updated on mw.org.
This array never has language keys (at least not
unless other extensions add them) but core will
always just have numerical keys.
Change-Id: Ie9c42ac2b4ff143e36d07642f57cca769e8c00e7
The hook was removed in Ia8e17008cb9d9b62ce5645e15a41a3b402f4026a
The mentioned file in the documenation was renamed:
parserTest.inc -> ParserTest.php -> ParserTestRunner.php
Change-Id: I8fcf8302b84254d1dc5a3b629f425616bd1f5d13
The hook was readded with Iad2646acde79b8a59710bb9fd5fbbfea5a39c341
The text is from I2783c46c6d80f828f9ecf5e71fc8f35910454582
Change-Id: I5e26e0c9bef06e0a6213fd219bda58a61da80665
The main interface already has javascript enhancement to use
the API and mw.notify. This patch affects permalinks without
tokens, and opening the link without javascript.
This will match the current behaviour of action=watch.
Bug: T130946
Change-Id: I6be2c07824c17b165e068fc4ac36ab192e12bc9d
In order for an extension to add data to ApiQueryWatchlist, we need to
provide a way to allow it to manipulate the database query made by
WatchedItemQueryService. We also need some hooks in ApiQueryWatchlist to
handle the marshalling of data to and from WatchedItemQueryService.
To better handle hooking, this also moves some of the continuation logic
from ApiQueryWatchlist to WatchedItemQueryService.
Bug: T147939
Change-Id: Ie45376980f92da964a579887b28175c00fd8f57e
For extension registry, add array_replace_recursive merge strategy,
as some extensions/configuration may prefer that to array_merge_recursive.
In some cases, configuration is merged from multiple extensions,
such as JsonConfig's $wgJsonConfigs configuration: ZeroBanner defines
"JsonZeroConfig": {
"namespace": 480,
"nsName": "Zero",
"isLocal": false,
"cacheKey": "1"
}
and mobile.php overrides it with
$wgJsonConfigs['JsonZeroConfig']['isLocal'] = false;
$wgJsonConfigs['JsonZeroConfig']['remote'] = [
'url' => 'https://zero.wikimedia.org/w/api.php',
'username' => $wmgZeroPortalApiUserName,
'password' => $wmgZeroPortalApiPassword,
];
Having identical value 'isLocal' would be converted into an array
if array_merge_recursive is used, but the replace strategy fixes it.
Change-Id: Ica6ddd0ae76f23e60de9b6235c6e2a3f2754a95d
Should be useful for cases where we pull in an external library
that already manages RTL flipping in its styles, and CSSJanus
does the wrong thing without extra markup.
Example:
'ext.tmh.video-js' => $baseExtensionResource + [
'scripts' => 'resources/videojs/video.js',
'styles' => 'resources/videojs/video-js.css',
'noflip' => true,
...
],
Bug: T148572
Bug: T148565
Change-Id: Icbad20d8a6e9a0d354ad159f5816f4fb67cc2775
This allows extension to consistently use their WikiPage subclasses.
Currently the only way a subclass would be used is if Article::newPage()
was called.
Change-Id: I74cce5f9627c4bc4b92502aff74beb2daeb78d17
This will allow extensions to inject into the query to implement
"xxshow" parameters, and to add additional properties to the output
data for "xxprop" parameters.
Also, call these new hooks from ApiQueryRevisions, ApiQueryAllRevisions,
ApiQueryUserContributions, and ApiQueryRecentChanges since I701e8e19 is
going to be wanting them.
Bug: T143614
Bug: T143616
Change-Id: Id6b42c7f2eb53a6f659d0d61383287f41d96ca00
Our hardcoded enum list in the extension.json schema for license-name
values was incomplete and did not cover the full SPDX license identifier
specification, which includes things like "AND" for specifying multiple
licenses.
Composer already has solid code in a library to do this validation, so
let's use it! This updates both the validateRegistrationFile.php and
ExtensionJsonValidationTest.php to use the composer/spdx-licenses
library (a new development dependency) to ensure the license-name field
is a valid SPDX identifier.
Also fix a silly typo in the validateRegistrationFile script which
prevented it from running, and use ::class so it will be easier to
detect typos like that in the future.
Bug: T146862
Change-Id: Ibb8973ed7950ae81c90558f9630f73746b2aff2c
This creates a hook triggered when updating change tags, so that
extensions can take actions when tags are updated.
When tagging accompanies the action, the recent change is passed
while when tagging is subsequent to the action, the user who
performs the tagging is passed.
Bug: T118698
Change-Id: Ifb0cdc43252c4185e4f216d23b8a21fb31595a37
Diff is not shown on action=history, so the name was not valid.
This module contains only styles, so let's make it explicit in its name too.
mediawiki.action.history.diff module is temporarily left for
backwards compatibility. It should be removed when no longer used.
This also renames docs/uidesign/mediawiki.action.history.diff.html
to docs/uidesign/mediawiki.diff.html.
Change-Id: I7ecc08417c5f1870ed6f2ca139fd953d68f6ec8e
When it becomes impossible to load the content of a page due to some
error or misconfiguration, we still want to be able to delete that
page. This change makes WikiPage::doDeleteArticle more robust by catching
any exceptions that may be thrown while trying to load the page content
during the deletion process.
See T128466 for context.
Change-Id: I19f2d16850a3c1af5b504a70a27b9bf1330bc68d
Currently UsersPager::doBatchLookup() assumes that group data comes *only*
from one place, the (local) user_groups DB table. But this isn't correct
when an extension like [[mw:Extension:GlobalUserrights]] is installed.
With the current master version of the GlobalUserrights ext. installed
under MW 1.27, only the *local* groups are shown on Special:ListUsers.
Even if you have a global group called 'staff' and you go to the
[[Special:ListUsers/staff]] page, it *will* display the correct list of
users, but the group data in parentheses is wrong; it's either 1) missing
(if the user is only a member of a global group but not any local groups)
or 2) incorrect in that it omits global group membership(s) entirely.
With this hook, an extension such as GlobalUserrights is able to query an
additional source of user group data (such as the global_user_groups table
in $wgSharedDB in the case of the GlobalUserrights ext.) and have this
data stored in the cache to ensure that global group data shows up as it
should.
Change-Id: Ied2c0f2d5738cf96a66a9672182345d630285639
UploadBase:
* Introduce a new method, tryStashFile(), as a replacement for the
now-soft-deprecated stashFile(). The method runs the new hook and
returns a Status object, with an error (if the hook returned an
error) or a value (if it didn't).
* Introduce a new hook, UploadStashFile, allowing extensions to
prevent a file from being stashed. Note that code in extensions
which has not been updated for MediaWiki 1.28 may still call
stashFile() directly, and therefore not call this hook. For
important checks (not just for UI), extension authors should use
UploadVerifyFile or UploadVerifyUpload hooks.
* Extract common code of tryStashFile() and stashFile() to
a new protected method doStashFile().
SpecialUpload:
* Use tryStashFile() when stashing a file after a warning or
"recoverable error" was encountered.
ApiUpload:
* Refactor stashing code so that error handling only happens in one
place, not four different ones. Use Status objects rather than
exception throwing/catching for control flow.
* Simplify the error messages slightly (error codes are unchanged).
Produce better ones by always using handleStashException().
'stashfailed' is now always at root (not nested inside 'warnings'),
behaving the same as 'filekey' does on success.
* Use tryStashFile() when stashing. Handle errors so as to allow
custom API results passed via ApiMessage to be preserved.
Some API result changes for different requests are shown below.
api.php?action=upload&format=json&filename=good.png&file=...&stash=1
Before:
{
"error": {
"code": "stashfilestorage",
"info": "Could not store upload in the stash: Stashing temporary file failed: UploadStashFileException Error storing file in '/tmp/phpB32SRT': Could not create directory \"mwstore://local-backend/local-temp/3/3a\".",
"*": "See http://localhost:3080/w/api.php for API usage"
}
}
After:
{
"error": {
"code": "stashfilestorage",
"info": "Could not store upload in the stash: Error storing file in '/tmp/phpB32SRT': Could not create directory \"mwstore://local-backend/local-temp/3/3a\".",
"*": "See http://localhost:3080/w/api.php for API usage"
}
}
api.php?action=upload&format=json&filename=[bad].png&file=...
Before:
{
"upload": {
"result": "Warning",
"warnings": {
"badfilename": "-bad-.png",
"stashfailed": "Stashing temporary file failed: UploadStashFileException Error storing file in '/tmp/phpB32SRT': Could not create directory \"mwstore://local-backend/local-temp/3/3a\"."
}
}
}
After:
{
"upload": {
"result": "Warning",
"stashfailed": "Could not store upload in the stash: Error storing file in '/tmp/phpB32SRT': Could not create directory \"mwstore://local-backend/local-temp/3/3a\"."
"warnings": {
"badfilename": "-bad-.png",
}
}
}
Bug: T140521
Change-Id: I2f574b355cd33b2e9fa7ff8e1793503b257cce65
HTML formatting of the queue was distributed over several OutputPage methods.
Each method demanding a snippet of HTML by calling makeResourceLoaderLink()
with a limited amount of information. As such, makeResourceLoaderLink() was
unable to provide the client with the proper state information.
Centralising it also allows it to better reduce duplication in HTML output
and maintain a more accurate state.
Problems fixed by centralising:
1. The 'user' module is special (due to per-user 'version' and 'user' params).
It is manually requested via script-src. To avoid a separate (and wrong)
request from something that requires it, we set state=loading directly.
However, because the module is in the bottom, the old HTML formatter could
only put state=loading in the bottom also. This sometimes caused a wrong
request to be fired for modules=user if something in the top queue
triggered a requirement for it.
2. Since a464d1d4 (T87871) we track states of page-style modules, with purpose
of allowing dependencies on style modules without risking duplicate loading
on pages where the styles are loaded already. This didn't work, because the
state information about page-style modules is output near the stylesheet,
which is after the script tag with mw.loader.load(). That runs first, and
mw.loader would still make a duplicate request before it learns the state.
Changes:
* Document reasons for style/script tag order in getHeadHtml (per 09537e83).
* Pass $type from getModuleStyles() to getAllowedModules(). This wasn't needed
before since a duplicate check in makeResourceLoaderLink() verified the
origin a second time.
* Declare explicit position 'top' on 'user.options' and 'user.tokens' module.
Previously, OutputPage hardcoded them in the top. The new formatter doesn't.
* Remove getHeadScripts().
* Remove getInlineHeadScripts().
* Remove getExternalHeadScripts().
* Remove buildCssLinks().
* Remove getScriptsForBottomQueue().
* Change where Skin::setupSkinUserCss() is called. This methods lets the skin
add modules to the queue. Previously it was called from buildCssLinks(),
via headElement(), via prepareQuickTemplate(), via OutputPage::output().
It's now in OutputPage::output() directly (slightly earlier). This is needed
because prepareQuickTemplate() calls bottomScripts() before headElement().
And bottomScript() would lazy-initialise the queue and lock it before
setupSkinUserCss() is called from headElement().
This makes execution order more predictable instead of being dependent on
the arbitrary order of data extraction in prepareQuickTemplate (which varies
from one skin to another).
* Compute isUserModulePreview() and isKnownEmpty() for the 'user' module early
on so. This avoids wrongful loading and fixes problem 1.
Effective changes in output:
* mw.loader.state() is now before mw.loader.load(). This fixes problem 2.
* mw.loader.state() now sets 'user.options' and 'user.tokens' to "loading".
* mw.loader.state() now sets 'user' (as "loading" or "ready"). Fixes problem 1.
* The <script async src> tag for 'startup' changed position (slightly).
Previously it was after all inline scripts and stylesheets. It's still after
all inline scripts and after most stylesheets, but before any user styles.
Since the queue is now formatted outside OutputPage, it can't inject the
meta-ResourceLoaderDynamicStyles tag and user-stylesheet hack in the middle
of existing output. This shouldn't have any noticable impact.
Bug: T87871
Change-Id: I605b8cd1e1fc009b4662a0edbc54d09dd65ee1df
Most of the hook functions need context to see what the current user's
permissions are, to generate messages, or the LinkRenderer service to
generate the tool links.
Change-Id: I19fa27c8115ee39dded6cb98f29c35b66b934f8a
ResourceLoader modules can now carry a 'deprecated' option which can
be a boolean or an object with message key. This message or a default
deprecation message will be show whenever that module is used in production.
Note: This will not work in debug mode for ResourceLoaderFile modules
and this is deemed acceptable for the time being. We can revisit later.
Bug: T137772
Change-Id: Ib9ebd2d39a59fd41d8537e06884699f77b03580c