Update to MediaWiki 1.37.1

This commit is contained in:
Pierre Schmitz 2021-12-19 15:08:59 +01:00
parent 5fa7485ceb
commit 20d5e251c2
6540 changed files with 705131 additions and 576451 deletions

27
CREDITS
View File

@ -1,5 +1,5 @@
{{int:version-credits-summary}} <!--
MediaWiki 1.36 is a collaborative project released under the
MediaWiki 1.37 is a collaborative project released under the
GNU General Public License v2. We would like to recognize the
following names for their contribution to the product.
@ -8,7 +8,6 @@ The following list can be found parsed under Special:Version/Credits -->
== Contributors ==
<!-- Updates to this list made with maintenance/updateCredits.php -->
<!-- BEGIN CONTRIBUTOR LIST -->
* [[mw:User:ST47]]
* 4shadoww
* aalekhN
* Aaron Ball
@ -54,6 +53,7 @@ The following list can be found parsed under Special:Version/Credits -->
* Alexander Mashin
* Alexander Monk
* Alexander Sigachov
* Alexander Vorwerk
* Alexandre Emsenhuber
* Alexia E. Smith
* AlQaholic007
@ -65,6 +65,7 @@ The following list can be found parsed under Special:Version/Credits -->
* Ammarpad
* Amorymeltzer
* amritsreekumar
* AnaïsGueyte
* ananay
* Anders Wegge Jakobsen
* Andre Engels
@ -147,6 +148,7 @@ The following list can be found parsed under Special:Version/Credits -->
* Bryan Davis
* Bryan Tong Minh
* burthsceh
* bwang
* C. Scott Ananian
* Cacycle
* Calak
@ -173,6 +175,7 @@ The following list can be found parsed under Special:Version/Credits -->
* ckoerner
* Clara Andrew-Wani
* clarakosi
* Clare Ming
* cobaltcigs
* Cole White
* Conrad Irwin
@ -257,6 +260,7 @@ The following list can be found parsed under Special:Version/Credits -->
* Envel Le Hir
* Eranroz
* Eric Evans
* Eric Gardner
* Eric Schneider
* Erich Lerch
* Erick Guan
@ -281,11 +285,13 @@ The following list can be found parsed under Special:Version/Credits -->
* Framawiki
* Fran Rogers
* Fred Emmott
* Func
* FunPika
* Gabriel Birke
* Gabriel Wicke
* Gary Guo
* gbt248
* gengh
* Geoffrey Mon
* Geoffrey Trang
* georggi
@ -357,6 +363,7 @@ The following list can be found parsed under Special:Version/Credits -->
* Jan Luca Naumann
* Jan Paul Posma
* Jan Zerebecki
* Jared Blumer
* Jared Flores
* Jaroslav Škarvada
* jarrettmunton
@ -473,6 +480,7 @@ The following list can be found parsed under Special:Version/Credits -->
* lwelling
* lziad
* m4tx
* MacFan4000
* Madman
* madurangasiriwardena
* Maggie Epps
@ -492,6 +500,7 @@ The following list can be found parsed under Special:Version/Credits -->
* Marcus Buck
* Margaret Epps
* Marielle Volz
* MarikoBriggs
* Marius Hoch
* Mark Bergsma
* Mark Clements
@ -542,10 +551,12 @@ The following list can be found parsed under Special:Version/Credits -->
* Michal
* Michał Łazowik
* Michał Roszka
* Michał Turek
* Michał Zieliński
* Mike Horvath
* Mikhail Popov
* Mikko Miettinen
* mikolajmeller
* Minh Nguyễn
* MinuteElectron
* misdre
@ -609,6 +620,7 @@ The following list can be found parsed under Special:Version/Credits -->
* Od1n
* Olaf Lenz
* Olivier Finlay Beaton
* ollej
* onei
* opatel99
* Oren Held
@ -656,6 +668,7 @@ The following list can be found parsed under Special:Version/Credits -->
* Platonides
* Pmlineditor
* pmolina
* Porplemontage
* Ppchelko
* pppery
* prageck
@ -701,6 +714,7 @@ The following list can be found parsed under Special:Version/Credits -->
* RockMFR
* Rohan
* Roman Nosov
* Roman Stolar
* Roman Tsukanov
* Rotem Liss
* Rowan Collins
@ -720,6 +734,7 @@ The following list can be found parsed under Special:Version/Credits -->
* S Page
* Sahajsk`
* sahil
* Sai Suman Cherukuwada
* Saint Johann
* Sakretsu
* Salvatore Ingala
@ -769,6 +784,7 @@ The following list can be found parsed under Special:Version/Credits -->
* Søren Løvborg
* Soxred93
* SQL
* Srđan
* Srikanth Lakshmanan
* ST47
* Stanislav Malyshev
@ -782,6 +798,7 @@ The following list can be found parsed under Special:Version/Credits -->
* Steve Sanbeg
* Steven Roddis
* Steven Walling
* Stevie Beth Mhaol
* stibba
* Storm1seven
* Str4nd
@ -800,6 +817,7 @@ The following list can be found parsed under Special:Version/Credits -->
* Taavi Väänänen
* tacsipacsi
* Tarquin
* TChin
* TerraCodes
* Thalia Chan
* The Discoverer
@ -849,6 +867,7 @@ The following list can be found parsed under Special:Version/Credits -->
* U-REDMOND\emadelw
* UltrasonicNXT
* Umherirrender
* Universal Omega
* utkarsh95
* Vadim Kovalenko
* Valerio Bozzolan
@ -867,12 +886,13 @@ The following list can be found parsed under Special:Version/Credits -->
* vishnu
* Vitaliy Filippov
* Vivek Ghaisas
* vladshapik
* Vlad Shapik
* vlakoff
* Volker E
* Waldir Pimenta
* wctaiwan
* Wikinaut
* wikitrent
* Wil Mahan
* William Demchick
* withoutaname
@ -891,7 +911,6 @@ The following list can be found parsed under Special:Version/Credits -->
* Yuriy Shnitkovskiy
* Yusuke Matsubara
* Yuvi Panda
* Zabe
* Zachary Hauri
* Zak Greant
* Željko Filipin

1081
HISTORY

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ Installing MediaWiki
Starting with MediaWiki 1.2.0, it's possible to install and configure the wiki
"in-place", as long as you have the necessary prerequisites available.
Required software as of MediaWiki 1.36.0:
Required software as of MediaWiki 1.37.0:
* Web server with PHP 7.3.19 or higher, plus the following extensions:
** ctype

View File

@ -1,957 +0,0 @@
= MediaWiki 1.36 =
== MediaWiki 1.36.3 ==
This is a security and maintenance release of the MediaWiki 1.36 branch.
=== Changes since MediaWiki 1.36.2 ===
* (T280363) mediawiki.page.ready: Introduce wikipage.indicators hook.
* (T290697) Add symfony/polyfill-php80.
* IcuCollation: Add some more icu to unicode version mappings.
* ApiBase: Annotate deprecated constants individually.
* PHPVersionCheck: Mark PHP 7.4.0 - 7.4.2 as buggy.
* (T293044) installer: Fix 5th param to sourceFile() in DatabaseUpdater.
* (T291127) Always encode spaces in cookie values as "%20".
* Use LocalFile::getHookRunner instead of LocalFile::hookRunner.
* (T293564) mediawiki.page.ready: Fire hook 'wikipage.indicators' with
children.
* HistoryBlobStub: add getLocation() to get $mOldId.
* Fix checkStorage.php.
* checkStorage: pass no parameters to WikiRevision::getContent().
* (T292763, CVE-2021-44854) SECURITY: Do not cache private wiki completion results.
* (T294316) Revert "Mark ApiClientLogin/ApiLogin as requiring write mode".
* (T294796) JobQueueRedis: Replace deprecated zSize with zCard.
* (T278037) NoLocalSettings: Pass an EmptyBagOStuff to TemplateParser.
* (T212428, T267468) Allow populateContentTables to continue when there are
bad blobs.
* (T295191) ApiQuerySiteinfo: Fix "rightsinfo"/"url" when $wgRightsPage is
set.
* Update pear/mail_mime to 1.10.11.
* Update deprecated Guzzle Psr7 function calls.
* (T281972) Follow-Up: I10fbd4b6a: Update @since tags as those were backported.
* Tweak error message for missing composer dependencies.
* (T296112) Allow inserting new sections named '0'.
* nukeNS: don't run purgeRedundantText() after every change.
* (T286779, T297031) installer: Fix Postgres mistakes in using changeField
method.
* (T225888) RollbackAction: fix missing pagetitle.
* (T297322, CVE-2021-44858, CVE-2021-44857) SECURITY: Fix permissions checks in
undo actions.
* (T297574, CVE-2021-45038) SECURITY: Fix permissions check in action=rollback.
* (T34716, T297416) SECURITY: Require 'read' right for most actions.
* (T271037, CVE-2021-44856) SECURITY: Fix use of EditFilterMergedContent hook when
changing content model.
== MediaWiki 1.36.2 ==
This is a security and maintenance release of the MediaWiki 1.36 branch.
=== Changes since MediaWiki 1.36.1 ===
* Don't access MWServices prematurely in Maintenence.php.
* (T283394) Mark ApiClientLogin/ApiLogin as requiring write mode.
* Installer: Fix foundation.wikimedia.org link in config-pingback-help.
* (T283273) Make postgres IRC channel point to libera.chat.
* composer.json: Promote and pin monolog/monolog to require from require-dev.
* (T287526) JavaScriptMinifer: Recognize `...` as a single token.
* (T287526) Update wikimedia/minify to 2.2.4.
* (T289108) ExtensionProcessor: Remove loaderScripts from extension.json
schemas.
* (T281549) Installer: Fix mediawiki-announce auto subscription code.
* FormatJson: Optimize encode() for supported PHP versions.
* (T290398) renameRestrictions.php: Update protected_titles as well.
* (T290489) objectcache: Fix PHP warning for ReplicatedBagOStuff::setMulti.
* $wgMimeTypeBlacklist - This configuration array now prohibits the RFC 4329
form of JavaScript, 'application/javascript', as well as previous MIME types.
* (T51097, T290273) resourceloader: Call getStyleFiles from
FileModule::getFileHashes.
* (T277788) parser: Avoid calling ParserOptions::getOption() too many times.
* (T291244) Unserialize objects in ParserCache->mExtensionData as objects.
* MysqlUpdater: Add updatelog entries for dropDefault.
* (T290776) Fix $phase check in OutputHandler.
* The wikimedia/parsoid library has been upgraded from v0.13.0 to v0.13.1.
* (T285515, CVE-2021-41798) SECURITY: XSS vulnerability in Special:Search.
* (T290379, CVE-2021-41799) SECURITY: ApiQueryBacklinks can cause a full
table scan.
* (T284419, CVE-2021-41800) SECURITY: fix PoolCounter protection of
Special:Contributions.
== MediaWiki 1.36.1 ==
This is a security and maintenance release of the MediaWiki 1.36 branch.
=== Changes since MediaWiki 1.36.0 ===
* (T283942) DatabaseInstaller.php: Only run core schema file if specified table
doesn't already exist.
* (T247223) Optimise MessageCache::isMainCacheable() for the single-message
case.
* (T283244) JavaScriptMinifer: Fix handling of "delete" as object property.
* (T284391) Fix SkinModule to correctly prepend remote path on document root
installs.
* (T235554) Disable DEFER_SET_LENGTH_AND_FLUSH headers to avoid HTTP errors.
* (T278579) Don't send headers on ob_end_clean().
* (T285287) MultiHttpClient: Replace PHP version check with defined().
* (T280226, CVE-2021-35197) SECURITY: Prevent blocked users from purging pages.
== MediaWiki 1.36.0 ==
=== Changes since MediaWiki 1.36.0-rc.0 ===
* (T248481) rdbms: Use server time in
DatabaseMysqlBase::getLagFromPtHeartbeat().
* (T281549) WebInstaller: Don't show the announce-l subscribe checkbox for now.
* (T264214) Follow-ups for UserGroupManager.
* (T282280) resourceloader: Fix path-only URLs in wiki modules when script path
is docroot.
* (T281972) UserIdentityValue: Introduce convenience static factory methods.
* (T230428) Make page_is_redirect and page_is_new unsigned.
* (T280292) Legacy feature should not load thumbnail style rules (only layout).
* (T283247) Freenode -> Libera per wikimedia moving from freenode to libera.
* (T280270) composer: Lock Parsoid version to specific 0.13.0 release.
* (T142663) Add extension.json merge strategy "provide_default".
* (T283540) HookContainer: Fix normalization of callback for static handler.
* (T283464) registration: Fix array order for array_replace_recursive merge
strategy.
* (T283539) Interwiki: Fix calling "onInterwikiLoadPrefix" hook.
* (T282594) Timeless: Re-branch to 40eb3dad1for REL1_36.
== MediaWiki 1.36.0-rc.0 ==
== Upgrading notes for 1.36 ==
Don't forget to always back up your database before upgrading!
See the file UPGRADE for more detailed per-version upgrade instructions from the
oldest supported upgrading version, MediaWiki 1.27.
Some specific notes for MediaWiki 1.36 upgrades are below:
* MediaWiki 1.36 now requires the PHP internationalization extension (commonly
referred to as Intl, ext-intl, or php-intl).
* The MediaWiki:Autoblock_whitelist block exemption control has been moved to
MediaWiki:Block-autoblock-exemptionlist. If you use this feature, please move
the MediaWiki:Autoblock_whitelist page.
* (T275334) $wgExtensionFunctions is sometimes used to change configuration
settings. This is not safe; extension functions are run relatively late, some
services are already initialized by that point and so they use the old
configuration. Changes in 1.36 make this kind of breakage even more common.
You can use the MediaWikiServices hook instead. (In the future there might be
a dedicated hook for configuration changes.)
For notes on 1.35.x and older releases, see HISTORY.
=== Configuration changes for system administrators in 1.36 ===
The MediaWiki update script, maintenance/update.php, used to accept `--nopurge`
as an option to prevent clearing caches stored in the database during upgrade.
This is no longer encouraged, and the option has been removed.
==== New configuration ====
* (T256001) $wgManualRevertSearchRadius This setting controls a new feature
that marks edits as reverts if they restore the page to an exact previous
state. This configuration variable sets the maximum number of revisions of a
page that will be checked against every new edit. Set this to 0 to disable the
feature entirely.
* (T244058) $wgOldRevisionParserCacheExpireTime — This setting was added to
control caching of ParserOutput for old (non-current) revisions.
* (T265263) $wgRememberMe - This setting configures the "remember me" checkbox
on account log-in systems via RememberMeAuthenticationRequest.
* (T157145) $wgSkinMetaTags This setting lets sysadmins configure skins that
support meta tags. These tags make sharing of MediaWiki pages on a variety of
social platforms more contentful and thus useful.
* (T280944) $wgIncludejQueryMigrate - This setting lets sysadmins disable the
jQuery Migrate plugin. It has been enabled by default since MediaWiki 1.27.
In future releases it will be disabled by default.
==== Changed configuration ====
* $wgLogos This setting selects the logo shown on the site. The default value
for the site logo, which is shown in an install if you have not set one, will
now be the new logo of MediaWiki.
* (T274695) $wgAjaxEditStash — This setting, to disable the edit stashing
feature when users start writing an edit summary, has been deprecated. In
future releases, this feature will always be enabled.
* $wgUploadStashScalerBaseUrl This setting, to enable remote on-demand media
scaling, was deprecated. Use the `thumbProxyUrl` setting in $wgLocalFileRepo
instead.
* $wgSlaveLagWarning and $wgSlaveLagCritical These settings have been renamed,
to $wgDatabaseReplicaLagWarning & $wgDatabaseReplicaLagCritical respectively.
The former configuration variable names are deprecated, but will be used as
the fall back if they are still set, and remain temporarily available for
extensions which try to read them.
* $wgWANObjectCaches - The "coalesceKeys" option was removed without deprecation
and replaced by a new "coalesceScheme" option, set to "hash_stop" by default.
If you use Dynomite, then set the new "coalesceKeys" option to "hash_tag". The
"cluster" and "mcrouterAware" options were also removed without deprecation.
Use "broadcastRoutingPrefix" instead.
==== Removed configuration ====
* $wgUseTwoButtonsSearchForm — This setting, deprecated in 1.35, has been
removed.
* $wgAllowImageMoving — This setting, deprecated in 1.35, has been removed. Use
group permission settings instead. For example, to prevent sysops from
moving files, set `$wgGroupPermissions['sysop']['movefile'] = false;`
* $wgExtNewTables, $wgExtNewFields, $wgExtNewIndexes, $wgExtPGNewFields,
$wgExtPGAlteredFields, $wgExtModifiedFields — These settings were removed.
They became obsolete after 1.17 overhauled the database updater, but were kept
for backwards compatibility. The LoadExtensionSchemaUpdates hook should be
used instead.
* $wgParserConf - This setting, deprecated in 1.35, has been removed. The last
use of this setting was for pre-processor configuration, which was deprecated
in 1.34 and removed in 1.35.
* $wgEnableRestAPI - This setting, ignored since 1.35, has been removed.
* $wgPagePropsHaveSortkey This temporary setting has been removed, along with
the schema change upgrade path it controlled. If your site is still using it,
meaning you have not yet applied the `pp_sortkey` schema change from 1.24, you
must now apply it before upgrading.
* The deprecated password policies PasswordCannotMatchBlacklist and
PasswordNotInLargeBlacklist were removed. Please use
PasswordCannotMatchDefaults and PasswordNotInCommonList respectively instead.
=== New user-facing features in 1.36 ===
* The logo of MediaWiki has changed. This means that the "Powered By MediaWiki"
button shown in the skin footer will be different.
* All HTML5 named entities are now accepted in wikitext.
* (T106263) The file description page's alternate sizes now include 2048px.
=== New developer features in 1.36 ===
* Parser test files can now declare a dependency on a specific extension being
loaded, not just on the presence of a certain extension tag hook. This is a
better fit for extensions like TimedMediaHandler, which affect the output but
don't register parser hooks. Use `extension:Foo` in the `!! hooks` section of
your parser test file to declare a dependency on the `Foo` extension being
loaded.
* To expose code previously present in SpecialBlock/SpecialUnblock to other
parts of the code, or to extensions, the new BlockUser and UnblockUser command
objects were added. Use the BlockUserFactory and UnblockUserFactory services
to create them.
* The hook UsersPagerDoBatchLookupsHook takes now a \Wikimedia\Rdbms\IDatabase,
instead of \Wikimedia\Rdbms\DBConnRef, as the first parameter.
* MediaHandlers can now customize the formatting of the metadata they emit by
over-riding MediaHandler::formatTag( $key, $value ). The default for unknown
tags is numeric formatting; non-EXIF tags which are non-numeric should always
use this method to specify the desired formatting.
* The new 'title' type can be used to validate action API and REST API inputs.
* The new ArticleParserOptions hook allows customizing the parser options used
to parse wikitext for an article, based on user preferences, title, etc.
* The new 'raw' type can be used to validate action API inputs. It bypasses the
Unicode NFC normalization done on inputs of type 'string', so it more suitable
when the input is binary or may contain deprecated Unicode sequences or
characters (such as U+2001) that should be passed unmodified.
* (T260330) A new abstraction for running shell commands has been introduced,
called BoxedCommand. A BoxedCommand object can be obtained with
MediaWikiServices::getInstance()->getCommandFactory()->createBoxed().
* ResourceLoader modules can now mark themselves as ES6-only by setting
`'es6' => true` in their module definition. ES6-only modules will not be
executed in browsers that don't support ES6, such as IE11.
=== External library changes in 1.36 ===
==== New external libraries ====
* Added wikimedia/minify 2.2.2.
* Added wikimedia/request-timeout 1.1.0.
* Added wikimedia/shellbox 1.0.4.
* Added WVUI 0.1.0.
* Added symfony/symfony/polyfill-php80 1.23.1.
==== Changed external libraries ====
* Updated composer/semver from 1.5.1 to 3.2.4.
* Updated guzzlehttp/guzzle from 6.5.4 to 7.2.0.
* Updated jQuery from v3.4.1 to v3.6.0.
* Updated jQuery Migrate from v3.1.0 to v3.3.2.
* Updated jquery.client from 2.0.2 to 3.0.0.
* Updated OOUI from 0.39.3 to 0.41.3.
* Updated pear/mail_mime from 1.10.8 to 1.10.11.
* Updated pear/net_smtp from 1.9.1 to 1.9.2.
* Updated pimple/pimple from 3.3.0 to 3.3.1.
* Updated wikimedia/at-ease from 2.0.0 to 2.1.0.
* Updated wikimedia/cldr-plural-rule-parser from 1.0.0 to 2.0.0.
* Updated wikimedia/common-passwords from 0.2.0 to 0.3.0.
* Updated wikimedia/composer-merge-plugin from 1.4.1 to 2.0.1.
* Updated wikimedia/html-formatter from 1.0.2 to 3.0.1.
* Updated wikimedia/ip-set from 2.1.0 to 3.0.0.
* Updated wikimedia/ip-utils from 1.0.0 to 3.0.2.
* Updated wikimedia/less.php from 3.0.0 to 3.1.0.
* Updated wikimedia/object-factory from 2.1.0 to 3.0.0.
* Updated wikimedia/php-session-serializer from 1.0.7 to 2.0.0.
* Updated wikimedia/remex-html from 2.2.0 to 2.2.2.
* Updated wikimedia/utfnormal from 2.0.0 to 3.0.2.
* Updated wikimedia/wait-condition-loop from 1.0.1 to 2.0.1.
* Updated wikimedia/xmp-reader from 0.7.0 to 0.8.1.
===== Changed development-only external libraries =====
* Updated composer/spdx-licenses from 1.5.3 to 1.5.4.
* Updated doctrine/dbal from 2.10.2 to 3.0.0.
* Updated doctrine/sql-formatter from 1.1.0 to 1.1.1.
* Updated mediawiki/mediawiki-phan-config from 0.10.2 to 0.10.6.
* Updated monolog/monolog from 1.25.3 to 2.2.0.
* Updated nikic/php-parser from 4.4.0 to 4.10.2.
* Updated psy/psysh from 0.10.4 to 0.10.5.
* Updated seld/jsonlint from 1.7.1 to 1.8.3.
* Updated symfony/yaml from ~3.4|~4.3|~5.0.5 to ~3.4|~5.1.
* Updated wikimedia/testing-access-wrapper from 1.0.0 to 2.0.0.
==== Removed external libraries ====
* The html5shiv library has been removed, as support for Internet Explorer 8 has
been dropped.
* The wikimedia/avro suggested development-only library has been removed, as the
support for logging in Avro format has been dropped.
=== Bug fixes in 1.36 ===
* (T190285) ApiEditPage module used to switch 'undo' and 'undoafter' parameters,
if it founds you reversed them (based on assumption that higher revision ID
indicates a later revision). The assumption is not always true, and is
hindering proper edit undoing in some cases, hence the logic has been removed.
Reversing the parameters will now lead to edit conflict or undefined behavior.
* (T263340) In history merging, pages with a content model that does not support
redirects will now be recorded as deleted if no revision is being left in the
source page (that's if all revisions of the page have been merged to another).
=== Action API changes in 1.36 ===
* (T269636) `Access-Control-Max-Age` was added to the default list of headers
allowed for cross-origin API requests ($wgAllowedCorsHeaders).
* (T258108) Accounts with the 'bot' right no longer have pages automatically
added to the watchlist when making API edits, regardless of their preferences.
This is to reduce the size of the watchlist data in the database. To add API
bot edits to the watchlist, explicitly set the 'watch' option.
=== Languages updated in 1.36 ===
MediaWiki supports over 350 languages. Many localisations are updated regularly.
Below only new and removed languages are listed, as well as changes to languages
because of Phabricator reports.
* (T258975) Added a Latin/Cyrillic script converter for the Talysh language.
* (T245359) Split Bali script locale from "ban" (Balinese) (ban-bali).
* (T264582) Added language support for Madurese (mad).
* (T259330) Added language support for Mara (mrh).
* (T263968) Added language support for Nias (nia).
* (T270365) Added language support for Tyap (kcg).
* (T276745) Added language support for Wayuu (guc).
=== Breaking changes in 1.36 ===
* Grade C (non-JavaScript) support for Internet Explorer 8 has been dropped.
* (T249459) wfIsBadImage(), deprecated in 1.34, has been removed.
* (T176526) EditPage::getContextTitle() will now throw an exception if a context
title was not set using setContextTitle(). Previously, this mis-use would only
cause a deprecation warning to be emitted.
* The DeferredStringifier class, deprecated since 1.31, was removed.
* Multiple methods that fell back to the $wgUser global variable were
individually hard deprecated previously. The following have now been removed:
- ApiTestCase::doLogin
- Article::doDeleteArticle
- Article::doDeleteArticleReal
- Article::getComment
- Article::getCreator
- Article::getUser
- Article::getUserText
- Article::insertProtectNullRevision
- File::delete
- File::recordUpload
- ForeignDBFile::delete
- ForeignDBFile::recordUpload
- LocalFile::delete
- LocalFile::deleteOld
- LocalFile::recordUpload
- PageArchive::undelete
- RecentChange::markPatrolled
- Title::getUserPermissionsErrors
- Title::quickUserCan
- Title::userCan
- WebRequest::getLimitOffset
- WikiPage::doDeleteArticle
- WikiPage::insertProtectNullRevision
* The SpecialPageFactory class, deprecated in 1.32, has been removed. Use the
SpecialPageFactory service instead.
* Multiple methods previously had optional User parameters, with fallbacks
to the $wgUser global variable. Not passing a User to those methods was
previously hard deprecated, and support for not passing a User has now
been removed:
- ArchivedFile::userCan
- File::userCan
- FileDeleteForm::__construct
- FileDeleteForm::doDelete
- LocalFileDeleteBatch::__construct
- LogEventsList::getExcludeClause (only needed for the 'user' audience)
- LogEventsList::userCan
- LogEventsList::userCanBitfield
- LogEventsList::userCanViewLogType
- LogPage::addEntry (also accepts user id instead)
- OldLocalFile::userCan
- PatrolLog::record
- Title::getNotificationTimestamp (though the entire method is deprecated)
- WikiPage::getComment (only needed for the FOR_THIS_USER audience)
- WikiPage::getCreator (only needed for the FOR_THIS_USER audience)
- WikiPage::getUser (only needed for the FOR_THIS_USER audience)
- WikiPage::getUserText (only needed for the FOR_THIS_USER audience)
* The following hooks have been removed:
- APIQueryInfoTokens
- APIQueryRecentChangesTokens
- APIQueryRevisionsTokens
- APIQueryUsersTokens
- ApiTokensGetTokenTypes
* LogEventsList::typeAction previously accepted an optional right parameter, and
checked if the context user ($wgUser) had that right. Passing a right was hard
deprecated in 1.35, and support for passing a right has now been removed.
* WikiPage::doDeleteArticleReal previously accepted an optional user as its
fifth parameter, and fell back to $wgUser if not user was provided. The
signature changed to have the user as the second parameter, and the old
signature was hard deprecated in 1.35. Support for the old signature has now
been removed.
* User::addNewUserLogEntry, deprecated since 1.27, was removed.
* As part of refactoring the EditPage class, EditPage::setPreloadedContent,
which had no known callers was removed entirely. Additionally, the following
public methods were made private:
- ::extractSectionTitle
- ::getSummaryInputWidget
- ::noSuchSectionPage
- ::initialiseForm
* EditPage::matchSpamRegex and ::matchSummarySpamRegex, deprecated in 1.35,
were removed. Use the SpamChecker service instead.
* The global function `wfWaitForSlaves`, deprecated in 1.27 and hard-deprecated
in 1.35, has been removed. Use LBFactory::waitForReplication() instead.
* Calling Action::factory() with null as the first parameter, rather than a
string, was deprecated in 1.35 and support was now removed.
* Calling Action::factory() with an object that wasn't an Article as the second
parameter was deprecated in 1.35 and support was now removed.
* The global variable $wgMemc, deprecated since 1.35, has been removed. Usage
should generally be migrated to WANObjectCache, or if you really need the
internal object, use ObjectCache::getLocalClusterInstance instead.
* The preprocessDump.php maintenance script was removed.
* CategoryFinder, which was deprecated in 1.31 and hard-deprecated in 1.35,
has been removed.
* GenderCache::singleton(), which was deprecated in 1.28 and hard-deprecated
in 1.35, has been removed.
* Sanitizer::escapeId(), deprecated in 1.30, has been removed.
* Direct invocation of Parser::__construct() (instead of via a ParserFactory)
now throws an exception; support has also been removed for several
deprecated variants on the arguments passed to Parser::__construct.
Direct invocation of Parser::__construct was deprecated in 1.34.
* Parser::setFunctionTagHook(), deprecated in 1.35, has been removed.
* The following properties of Parser, deprecated in 1.35, have been made
private:
- $mTagHooks - use Parser::getTags()
- $mFunctionHooks - use Parser::getFunctionHooks()
- $mOutput - use Parser::getOutput()
- $mPreprocessor - use Parser::getPreprocessor()
* The ParserBeforeTidy hook, deprecated in 1.35, has been removed.
* The ParserBeforeTidy, ParserBeforeStrip, and ParserAfterStrip hooks,
deprecated in 1.35, have been removed.
* All methods of MWTidy except for MW::tidy() have been removed. These were each
either marked as @internal or deprecated in 1.35.
* (T248062) Mixins `.background-image-svg()` and `.background-image-svg-quick()`
(provided by mediawiki.mixins.less), which have been deprecated since 1.35,
have now been removed. MediaWiki no longer supports any browser which would
require this SVG-fallback PNG support, so you can simply use the regular CSS
`background-image:` declaration instead.
* The ResourceLoader module `mediawiki.legacy.oldshared` and its file
'oldshared.css', deprecated since 1.35 has been removed (T248357).
* `ResourceLoader::__construct` now requires a Config parameter. The optional
nature of this parameter was deprecated in 1.34.
* The LinkBegin and LinkEnd hooks, deprecated in 1.28, have been removed. You
can instead use the HtmlPageLinkRendererBegin and HtmlPageLinkRendererEnd
hooks, respectively.
* The EmailUser hook passes its fifth param, $error, by reference, to allow
hook handlers to add error messages, indicate that they have sent the email
instead of core, etc. Setting the parameter to something other than a
Status object, true, false, an empty string, an array, or a MessageSpecifier,
object, which had been deprecated in 1.29, is no longer supported, and now
results in an MWException being thrown.
* Skin::getDynamicStylesheetQuery(), deprecated in 1.32, has been removed. You
should use action=raw&ctype=text/css directly.
* Skin::makeI18nUrl(), deprecated in 1.35, has been removed.
* The following User methods, deprecated and moved to BlockManager in 1.34, were
removed:
- ::isDnsBlacklisted
- ::inDnsBlacklist
- ::isLocallyBlockedProxy
- ::trackBlockWithCookie
* Support for v1 of the parser tests file format has been removed; it was
deprecated in 1.35. (T174199)
* SpecialUnblockUser::processUIUnblock() now returns a Status object instead of
an array of messages or a boolean value. This function was also marked as
@internal and is no longer safe to call it publicly.
* mw.Title.getDotExtension() from the 'mediawiki.Title' module was removed
without deprecation. You should use mw.Title.getExtension() and prepend the
dot if need be.
* Profiler::getTemplated and Profiler::setTemplated, deprecated in 1.34, have
been removed.
* DatabaseMysqlBase now requires MySQL version 5.6.4+ when "lagDetectionMethod"
is set to "pt-heartbeat".
* Removed HookContainer::getOriginalHooksForTest() without deprecation. This
method was introduced in 1.35 for internal use, and appears unused outside of
MediaWiki core.
* ParserCache::__construct() now requires three parameters.
* Message->getFormat(), deprecated in 1.29, has been removed.
* Support for passing Article to ParserCache::get, deprecated in 1.35, has been
removed.
* ParserCache::singleton(), deprecated in 1.30, has been removed.
* DatabaseBlock::deleteIfExpired and ::fromMaster, deprecated in 1.35, have been
removed.
* Some deprecated AbstractBlock methods have been removed:
- ::prevents, deprecated in 1.33
- ::shouldTrackWithCookie, deprecated in 1.34
- ::getBlocker, deprecated in 1.35
- ::setBlocker, deprecated in 1.35
- ::getBlockErrorParams, deprecated in 1.35
* Multiple DatabaseBlock methods dealing with cookies, deprecated in 1.34,
have been removed:
- ::setCookie
- ::clearCookie
- ::getCookieValue
- ::getIdFromCookieValue
- ::shouldTrackWithCookie
* The public static callback function SpecialUnblock::processUIUnblock has been
removed. This method was for internal use only, and appears unused outside of
MediaWiki core.
* ChangeTags::truncateTagDescription, deprecated in 1.35, has been removed.
* Deprecated null fallbacks in PasswordReset constructor have been removed.
* User::isEveryoneAllowed and User::getAllRights, deprecated in 1.34, has been
removed.
* The following methods of the UserGroupMembership class, deprecated in 1.35,
has been removed:
- ::initFromRow
- ::newFromRow - use UserGroupManager::newGroupMembershipFromRow
- ::selectFields - use UserGroupManager::getQueryInfo
- ::delete - use UserGroupManager::removeUserFromGroup
- ::insert - use UserGroupManager::addUserToGroup
- ::purgeExpired - use UserGroupManager::purgeExpired
- ::getMembershipsForUser - use UserGroupManager::getUserGroupMemberships
- ::getMembership - use UserGroupManager::getUserGroupMemberships
* The public static callback function SpecialBlock::validateTargetField has been
removed. This method was for internal use only, and appears unused outside of
MediaWiki core.
* The public static callback function SpecialUploadStash::tryClearStashedUploads
has been removed. This method was for internal use only, and appears unused
outside of MediaWiki core.
* SpecialComparePages::showDiff() ::revOrTitle(), ::checkExistingTitle(), and
::checkExistingRevision() were marked as @internal to allow for breaking
changes. They are no longer safe to call. The methods were unused outside of
MediaWiki core.
* Each special page within core now uses service injection via it constructor.
When extending these special pages, a call to the grandparent constructor
(`SpecialPage::__construct()`) in the sub-class would now break the derived
special page, as the fallback code in the parent constructor cannot set the
services as needed. Be sure to call the parent constructor when extending
core special pages. Extending core's special pages is not part of the stable
interface, and should generally be avoided.
* Language::getExtraUserToggles and ::viewPrevNext, deprecated in 1.34, have
been removed.
* StreamFile::send404Message and ::parseRange, deprecated in 1.34, have been
removed.
* SVGMetadataExtractor class, deprecated in 1.34, has been removed.
* ProcessCacheLRU class, deprecated in 1.32, has been removed.
* wfForeignMemcKey(), deprecated in 1.35, has been removed.
* LoadBalancer::safeWaitForMasterPos(), deprecated in 1.34, has been removed.
* JobQueue::factory() now requires its `idGenerator` option. The optional
nature of this option was deprecated in 1.35.
* ApiFeedRecentChanges::getFeedObject has been changed to private, and appears
unused outside of MediaWiki core.
* Skin::subPageSubtitle() has been changed to private method. Callers should
use Skin::prepareSubtitle().
* RevisionDeleter::checkRevisionExistence was removed without deprecation.
It had no known callers.
* wfForeignMemcKey() and wfMemcKey(), deprecated in 1.35, have been removed.
* MediaWiki now also requires the php-intl extension.
* BotPassword::save() now returns a Status object for the result rather than
a bool.
* The methods in CoreTagHooks have been marked @internal and type hints have
been added. The methods appeared to be unused outside of MediaWiki core.
* SquidPurgeClient and SquidPurgeClientPool, deprecated since 1.35, have been
removed.
* Several methods on WikiPage will now throw an exception when called on a
WikiPage instance that where constructed on a title that does not refer to a
proper page (but rather a special page or interwiki link). The behavior was
previously undefined and could in some cases lead to data corruption. Affected
methods are: getId(), insertOn(), newPageUpdater(), doUpdateRestrictions(),
doDeleteArticleReal(), doRollback(), and doEditContent().
* The ParserTestRunner no longer invokes the ParserTestTables hook. Instead, it
clones all database tables before running tests, like MediaWikiIntegrationTest
does. If an extension was mis-using the hook to *exclude* tables from the
clone, that will no longer occur, and tests may fail.
* The following classes, which were only loaded for tests and had no uses found
in public MediaWiki-related git, were removed:
- MockWebRequest
- UserWrapper
* Passing Title as a second parameter to RevisionStore::getPreviousRevision and
getNextRevision, hard deprecated since 1.31, was prohibited.
* (T275619) Maintenance::hasOption and Maintenance::getOption now behave as
documented and are not altered by previous calls to these methods.
* The internal class FirejailCommand was removed.
* Command::execute() now returns a Shellbox\Command\UnboxedResult instead of a
MediaWiki\Shell\Result. Any type hints should be updated.
* WikiPage::$mIsRedirect was removed.
* ObjectCache::detectLocalServerCache(), deprecated in 1.35, was removed.
* The following functions from the Title class have been removed:
- countRevisionsBetween
- getAuthorsBetween
* The PageProps class was converted to a service. PageProps::overrideInstance
was removed, and MediaWikiServices::redefineService should be used
instead.
* Support for creating a MediaWikiTitleCodec object without the InterwikiLookup
and NamespaceInfo services, deprecated in 1.34, was removed. Note that the
MediaWikiTitleCodec class is not @newable or @stable to create, and should
be retrieved from MediaWikiServices instead.
* The $wgContLang variable, deprecated in 1.32, was removed. You can instead use
MediaWikiServices::getInstance()->getContentLanguage().
* User::clearAllNotifications(), hard deprecated in 1.35, was removed. Use
WatchlistManager::clearAllUserNotifications() instead.
* DatabaseBlock::getBlocker can return any UserIdentity instance, not just User.
* MediaWiki::triggerJobs(), deprecated in 1.34, was removed.
* The following Article methods, deprecated in 1.35, were removed:
- checkFlags
- checkTouched
- clearPreparedEdit
- doDeleteUpdates
- doEditUpdates
- doPurge
- doViewUpdates
- exists
- followRedirect
- getAutoDeleteReason
- getCategories
- getContentHandler
- getContentModel
- getContributors
- getDeletionUpdates
- getHiddenCategories
- getId
- getLatest
- getLinksTimestamp
- getMinorEdit
- getOldestRevision
- getRedirectTarget
- getRedirectURL
- getRevision
- getTouched
- getUndoContent
- hasViewableContent
- insertOn
- insertRedirect
- insertRedirectEntry
- isCountable
- isRedirect
- loadFromRow
- loadPageData
- lockAndGetLatest
- makeParserOptions
- pageDataFromId
- pageDataFromTitle
- prepareContentForEdit
- protectDescription
- protectDescriptionLog
- replaceSectionAtRev
- replaceSectionContent
- setTimestamp
- shouldCheckParserCache
- supportsSections
- triggerOpportunisticLinksUpdate
- updateCategoryCounts
- updateIfNewerOn
- updateRedirectOn
- updateRevisionOn
- doUpdateRestrictions
- updateRestrictions
- doRollback
- commitRollback
- generateReason
* The monolog-based logging system has dropped the Avro format. Because of this,
the AvroFormatter class and the AvroValidator utility class have been removed
without deprecation.
* AbstractBlock::$mReason, deprecated in 1.34, was removed.
Use AbstractBlock::getReasonComment and AbstractBlock::setReason instead.
=== Deprecations in 1.36 ===
* (T278026) The DB_MASTER constant has been deprecated in favour of DB_PRIMARY.
* (T245963) User::getGrantName() is now hard deprecated and will be removed in
a subsequent release. Use MWGrants::grantName() instead.
* wfIncrStats() is now deprecated. Use MediaWikiServices::getInstance()
->getStatsdDataFactory()->updateCount() instead.
* WikiPage::doEditContent() is now deprecated. Use
WikiPage::doUserEditContent() instead. Note that doEditContent() was also
deprecated in 1.32 for unrelated reasons and doUserEditContent() is
deprecated for other reasons, however, using doUserEditContent() is
recommended over using doEditContent().
* WikiPage::doUserEditContent() is now deprecated. Use
PageUpdater::saveRevision instead. Note that the new method expects callers
to take care of checking EDIT_MINOR against the minoredit right, and to apply
the autopatrol right as appropriate.
* LocalFile::recordUpload2, soft deprecated in 1.35, now emits deprecation
warnings. Use ::recordUpload3 instead.
* Constructing a new instance of the ParserOptions class without providing
a User object, which falls back to the global $wgUser, is now deprecated.
* The User class, which was marked as @newable in 1.35, is no longer newable,
meaning that it is no longer safe to manually call the constructor via
`new User`. Instead, use the UserFactory service. Additionally, the
following static constructor methods were deprecated in favor of using the
UserFactory service:
- User::newFromName
- User::newFromId
- User::newFromActorId
- User::newFromIdentity
- User::newFromAnyId
- User::newFromConfirmationCode
* The following User methods have been hard deprecated in favor of the new
UserEditTracker service:
- User::getFirstEditTimestamp
- User::getLatestEditTimestamp
* The confusingly-named User->isLoggedIn() method has been deprecated in favour
of the method it wraps, User->isRegistered().
* Use of the `preprocessor=Preprocessor_DOM` option in parser test files has
been deprecated. Preprocessor_DOM was removed in 1.35.
* ParserOptions::setTidy() has been deprecated. It has had no effect since
1.35.
* Sanitizer::escapeIdReferenceList() has been deprecated; it will eventually
be made private to the class, as it appears to have no uses outside the
Sanitizer class.
* Sanitizer::hackDocType() is deprecated; it will eventually be made private.
* Skin::getIndicatorsHTML() is deprecated. The functionality can be retained
by reimplementing the method using the raw indicators data from
OutputPage::getIndicators.
* Skin::makeVariablesScript() has been deprecated. Use
ResourceLoader::makeInlineScript() instead.
* SpecialPageFactory::getRestrictedPages() has been deprecated.
Use SpecialPageFactory::getUsablePages() instead.
* Title::nameOf() is deprecated; use Title::newFromID()->getPrefixedDBkey()
instead.
* DatabaseBlock::insert, DatabaseBlock::update, DatabaseBlock::purgeExpired and
DatabaseBlock::delete are deprecated. Use DatabaseBlockStore::insertBlock,
DatabaseBlockStore::updateBlock, DatabaseBlockStore::purgeExpiredBlocks and
DatabaseBlockStore::deleteBlock instead.
* SpecialBlock::getTargetAndType and AbstractBlock::parseTarget are deprecated.
Call BlockUtils::parseBlockTarget instead.
* SpecialUnblock::processUnblock was deprecated - use UnblockUserFactory
service instead.
* Deprecated MediaWikiIntegrationtestCase::removeTemporaryHook() in favor of
MediaWikiIntegrationtestCase::clearHook().
* Skin::getSearchLink(), also exposed as 'searchaction' option in SkinTemplate,
has been deprecated. Use Title or SpecialPage methods directly.
* Skin::getAllowedSkins and ::getSkinNames have been deprecated. Use their
respective equivalents in SkinFactory instead.
* The RollbackComplete hook has been deprecated, use the PageSaveComplete hook
instead.
* Skin::makeUrl() has been deprecated. Title methods should be used instead.
* Skin::privacyLink(), Skin::disclaimerLink() and Skin::aboutLink() have been
deprecated. Please use Skin::footerLink() instead.
* Skin::getLogo() has been deprecated. Use ResourceLoaderSkinModule instead.
* The module `mediawiki.toc.styles` has been replaced by
ResourceLoaderSkinModule. If you are having problems styling table of contents
ensure you have an updated skin.
* Skin::mainPageLink() has been deprecated. Use LinkRenderer service instead.
* BaseTemplate::getToolbox() method has been hard deprecated. The toolbox data
is now available in a sidebar data array which you can get from any class
that's extending QuickTemplate class.
* Constructing a DefaultPreferencesFactory, LinkHolderArray or PasswordReset
without a $hookContainer parameter is deprecated.
* Autopromote class, soft deprecated since 1.35, now emits deprecation warnings.
Use UserGroupManager instead.
* SpecialBlock::canBlockEmail has been deprecated. Please use
BlockPermissionChecker::checkEmailPermissions instead.
* SpecialBlock::checkUnblockSelf has been deprecated. Please use
BlockPermissionChecker::checkBlockPermissions instead.
* SpecialBlock::parseExpiryInput was deprecated - use
BlockUser::parseExpiryInput instead.
* SpecialBlock::validateTarget has been deprecated, use BlockUtils instead.
* SpecialBlock::validateTargetField has been deprecated for external use,
use BlockUtils instead.
* SpecialPage::getLanguageConverter has been deprecated, use
LanguageConverterFactory::getLanguageConverter() directly.
* ParserCache::getKey has been deprecated. Use ParserCache::getMetadata and
ParserCache::makeParserOutputKey instead.
* The PHPUnit4And6Compat class, used to provide compatibility with PHPUnit 4,
was removed. MediaWiki support for PHPUnit 4 ended with the removal of HHVM
support.
* The PHPUnit6And8Compat class, used to provide compatibility with PHPUnit 6,
was removed without deprecation. This class was introduced during the
upgrade to PHPUnit 8, but never used.
* MediaWikiIntegrationTestCase::assertType, hard-deprecated in 1.35 due to
incompatibility with PHPUnit 8, was removed.
* ParserCache::getETag has been deprecated, instead build suitable etag
explicitly.
* The following functions from the Language class have been hard deprecated
and will be removed in a subsequent release:
- findVariantLink
- convertTitle
- updateConversionTable
- commafy
* The following functions from the Title class have been hard deprecated:
- getPreviousRevisionID
- getNextRevisionID
- getEarliestRevTime
* The following functions from the User class have been hard deprecated:
- getDefaultOptions
- getDefaultOption
* The mw.language.commafy client-side method has been deprecated, to match
the deprecation of Language::commafy. Use mw.language.convertNumber
instead.
* The "es6-promise" module has been deprecated. Use "es6-polyfills" instead.
* Title::isDeleted() and Title::isDeletedQuick() have been deprecated. Please
use Title::getDeletedEditsCount() and Title::hasDeletedEdits() instead.
* Article::getContentObject, soft-deprecated since 1.32, was hard-deprecated.
* WikiRevision::importUpload, soft-deprecated since 1.31, was hard-deprecated.
* Html::infoBox() has been deprecated. There's no replacement.
* Message::toString() without a $format parameter, soft-deprecated since 1.28,
was hard-deprecated. Use explicit formatting methods instead, such as
Message::text() and Message::escaped().
* BagOStuff::makeKeyInternal() usage outside of BagOStuff has been deprecated.
* BagOStuff::setDebug() is deprecated and calls to it are ignored. Debug logs
are now unconditionally enabled.
* The following global functions have been hard deprecated:
- wfAppendToArrayIfNotDefault
- wfAcceptToPrefs
- wfClearOutputBuffers
- wfConfiguredReadOnlyReason
- wfDebugMem
- wfGetPrecompiledData
- wfNegotiateType
* BeforeParserFetchTemplateAndtitleHook has been deprecated; replace
with the new BeforeParserFetchTemplateRevisionRecord hook. (The
similar ParserFetchTemplateHook was deprecated in 1.35; the new hook
replaces both.)
* The InterwikiLoadPrefix hook has been deprecated; it is not compatible
with future wikitext parsers (which need to enumerate all interwiki
prefixes). In test cases please use $wgInterwikiCache instead.
* WikiPage instances should no longer be constructed for titles that do not
represent editable pages (e.g. special pages). WikiPages were always
documented to represent "MediaWiki article and history".
* Skin::getSkinStylePath() has been deprecated. Please replace usages with
the direct path to the resources.
* The second argument of EnhancedChangesList::getDiffHistLinks, $query, has
been deprecated.
* The ParserTestTables hook has been deprecated; it is no longer necessary
after a ParserTestRunner refactoring.
* The following classes have been hard deprecated: CachedAction,
SpecialCachedPage, CacheHelper, ICacheHelper. They were unused in MediaWiki
ecosystem, so no replacement was provided.
* The ProtectionForm::buildForm hook has been deprecated. Please use the
ProtectionFormAddFormFields hook instead.
* RevisionStore::newMutableRevisionFromArray has been hard deprecated. Instead,
MutableRevisionRecord should be constructed directly via constructor.
* UserIdentity::getActorId() is deprecated. The actor ID should not be exposed
to application logic. Storage layer code should use the ActorNormalization
service for normalizing and denormalizing user names.
* Constructing a UserIdentityValue with an actor ID as the third parameter is
deprecated. The parameter should be omitted. Storage layer code should use
the ActorNormalization service for normalizing and denormalizing user names.
* Command::cgroup() is deprecated and no longer functional. $wgShellCgroup is
now implemented as an Executor option.
* Command::restrict() is deprecated. Instead use the new separate accessors.
* MWTidy::tidy() is deprecated. Use MediaWikiServices::getTidy()-tidy() instead.
* TidyDriverBase::supportsValidate() is deprecated; it has always returned
false since 1.33.
* WatchedItem::getUser hard-deprecated in favor of ::getUserIdentity.
* WatchedItemStoreInterface::enqueueWatchlistExpiryJob was hard deprecated in
favor of the new method maybeEnqueueWatchlistExpiryJob that takes care of
relevant configuration checks.
* LogEntry::getPerformer() and its implementations have been hard-deprecated, in
favor of ::getPerformerIdentity().
* AuthManager::singleton(), deprecated in 1.35, is hard deprecated. Use
MediaWikiServices::getAuthManager() instead.
* User::clearNotification(), deprecated in 1.35, is hard deprecated. Use
WatchlistManager::clearTitleUserNotification() instead.
* Passing string to DatabaseBlock::setBlocker was deprecated. Only UserIdentity
is now allowed.
* DatabaseBlock constructor 'byText' option was deprecated in favour of 'by'
option, which now accepts UserIdentity. Passing user ID is deprecated.
* Parser::getUser was deprecated. Use Parser::getUserIdentity instead.
* DatabaseBlock::isWhitelistedFromAutoblocks was deprecated. Use
DatabaseBlock::isExemptedFromAutoblocks instead.
* User::isIPRange(), deprecated in 1.35, is hard deprecated.
Use the UserNameUtils service or IPUtils directly.
* BaseTemplate::getFooterIcons(), deprecated in 1.35, is hard deprecated. Read
footer icons from template data requested via $this->get('footericons').
* `box-shadow()` LESS mixin from mediawiki.mixins is deprecated due to updated
basic browser support. Use unprefixed property `box-shadow:` instead.
* MergeHistory::checkPermissions was deprecated. Use ::probablyCanMerge or
::authorizeMerge instead.
* User::isValidUserName(), deprecated in 1.35, is hard deprecated.
Use the UserNameUtils service instead.
* The TitleArrayFromResult hook has been deprecated.
* The EditPageBeforeEditToolbar hook has been deprecated; it has become
defunct after the classic edit toolbar was removed. Use one of the many
other EditPage hooks instead.
* Deprecated the class name MediaWiki\User\WatchlistNotificationManager; use
MediaWiki\Watchlist\WatchlistManager instead. Deprecated the method
MediaWikiServices->getWatchlistNotificationManager(); use
MediaWikiServices->getWatchlistManager() instead.
* The "ArticleEditUpdatesDeleteFromRecentchanges" hook, deprecated in 1.35, has
been removed. Other hooks like "RecentChange_save" can be used instead.
=== Other changes in 1.36 ===
* The 'tidy' key in ParserOptions (used in the parser cache) has been removed.
It has had no effect since 1.35.
* A future release of MediaWiki will make `{{=}}` a built-in parser function,
for use when automatically escaping the `=` character in template arguments.
A tracking category and parser warning have been added to this release when
`{{=}}` is used and it expands to something other than `=`.
* The implementation of TestFileReader::read has been changed to use Parsoid's
parser test file parser. This should be compatible with existing code, but it
only supports version 2 of the test file specification and may be more strict
when parsing invalid input, including duplicate tests.
* BeforeParserFetchTemplateRevisionRecord, a new hook, unifies and replaces the
old BeforeParserFetchTemplateAndtitleHook and ParserFetchTemplateHook.
* The SkinLessImportPaths attribute was added, allowing skins to add a directory
to the import path for LESS stylesheets. Skins can use this to provide a
custom version of mediawiki.skin.variables.less, setting skin-specific values
for certain LESS variables.
* The interaction between ContentHandler::getParserOutputForIndexing() and
ContentHandler::getDataForSearchIndex() has been clarified (the latter should
only be called with the result of the former). Extensions may override
getParserOutputForIndexing() to skip generating HTML, which may improve
indexing performance. (The default implementation still generates HTML, and
getDataForSearchIndex() implementations can still rely on it if they do not
over-ride getParserOutputForIndexing().)
* Article::fetchContentObject, ::mContentObject, ::mContentLoaded,
::mRevIdFetched, all deprecated since 1.32, were removed.
* Article::mParserOptions and ::setParserOptions were removed.
* Article and ImagePage::getEmptyPageParserOutput, unused, were removed.
* ParserCache's default serialization format was changed from PHP serialization
to JSON serialization. In case some installed extension do not support JSON
yet, $wgParserCacheUseJson can be used to revert back to PHP serialization.
* PermissionManager::groupHasPermission, ::getGroupPermissions and
::getGroupsWithPermission were deprecated, use GroupPermissionsLookup
service instead.
* WatchedItemStoreInterface now accepts PageIdentity where it accepted
LinkTarget, calling with LinkTarget was deprecated.
* 'movable' attribute has been added to the 'namespaces' property of
extension.json schema. Extensions that define namespaces can set it to
`false` to disallow moving pages in the specified namespace. Extensions
should either use this or NamespaceIsMovableHook, but not both. The hook
overrides the attribute.
== Compatibility ==
MediaWiki 1.36 requires PHP 7.3.19 or later and the following PHP extensions:
* ctype
* dom
* fileinfo
* iconv
* intl
* json
* mbstring
* xml
MySQL/MariaDB is the recommended DBMS. PostgreSQL or SQLite can also be used,
but support for them is somewhat less mature.
The supported versions are:
* MySQL 5.5.8 or later
* PostgreSQL 9.4 or later
* SQLite 3.8.0 or later
== Online documentation ==
Documentation for both end-users and site administrators is available on
MediaWiki.org, and is covered under the GNU Free Documentation License (except
for pages that explicitly state that their contents are in the public domain):
https://www.mediawiki.org/wiki/Special:MyLanguage/Documentation
== Mailing list ==
A mailing list is available for MediaWiki user support and discussion:
https://lists.wikimedia.org/mailman/listinfo/mediawiki-l
A low-traffic announcements-only list is also available:
https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce
It's highly recommended that you sign up for one of these lists if you're
going to run a public MediaWiki, so you can be notified of security fixes.
== IRC help ==
There's usually someone online in #mediawiki on irc.libera.chat.

955
RELEASE-NOTES-1.37 Normal file
View File

@ -0,0 +1,955 @@
= MediaWiki 1.37 =
== MediaWiki 1.37.1 ==
This is a security and maintenance release of the MediaWiki 1.37 branch.
=== Changes since MediaWiki 1.37.0 ===
* (T296112) Allow inserting new sections named '0'.
* Fix path for ZhConversion.php.
* nukeNS: don't run purgeRedundantText() after every change.
* (T286779, T297031) installer: Fix Postgres mistakes in using changeField
method.
* (T225888) RollbackAction: fix missing pagetitle.
* (T297322, CVE-2021-44858, CVE-2021-44857) SECURITY: Fix permissions checks in
undo actions.
* (T297574, CVE-2021-45038) SECURITY: Fix permissions check in action=rollback.
* (T34716, T297416) SECURITY: Require 'read' right for most actions.
* (T271037, CVE-2021-44856) SECURITY: Fix use of EditFilterMergedContent hook when
changing content model.
== MediaWiki 1.37.0 ==
=== Changes since MediaWiki 1.37.0-rc.2 ===
* Remove justinrainbow/json-schema from vendor.
* Updated pear/mail_mime from 1.10.9 to 1.10.11.
* Update deprecated Guzzle Psr7 function calls.
* (T281972) UserIdentityValue: Correct @since tags.
* Updated wikimedia/parsoid from v0.14.0-a19 to v0.14.0.
* Localisation updates.
* Tweak error message for missing composer dependencies.
== MediaWiki 1.37.0-rc.2 ==
=== Changes since MediaWiki 1.37.0-rc.1 ===
* (T295173) Re-add wikimedia/normalized-exception to vendor.
* Remove wikimedia/testing-access-wrapper, psr/simple-cache, psr/http-factory
from vendor.
* (T295191) ApiQuerySiteinfo: Fix "rightsinfo"/"url" when $wgRightsPage is set.
* (T212428) Allow populateContentTables to continue when there are bad blobs.
== MediaWiki 1.37.0-rc.1 ==
=== Changes since MediaWiki 1.37.0-rc.0 ===
* (T294043) checkStorage: pass no parameters to WikiRevision::getContent().
* (T292763, CVE-2021-44856) SECURITY: Do not cache private wiki completion results.
* (T293783) ApiQueryImageInfo: don't show empty comments as deleted.
* (T294316) Revert "Mark ApiClientLogin/ApiLogin as requiring write mode".
* (T294796) JobQueueRedis: Replace deprecated zSize with zCard.
* Remove duplicate settings from DefaultSettings.
* (T278037) NoLocalSettings: Pass an EmptyBagOStuff to TemplateParser.
== MediaWiki 1.37.0-rc.0 ==
== Upgrading notes for 1.37 ==
Don't forget to always back up your database before upgrading!
See the file UPGRADE for more detailed per-version upgrade instructions from the
oldest supported upgrading version, MediaWiki 1.27.
Some specific notes for MediaWiki 1.37 upgrades are below:
* (T280806) Deprecated methods of fetching API tokens have been removed. This
may cause older bots and scripts to fail. Most queries are trivially
updateable to using new methods. See the Action API changes section below
for more information.
For notes on 1.36.x and older releases, see HISTORY.
=== Configuration changes for system administrators in 1.37 ===
* (T242768) The PasswordCannotMatchUsername password policy has been removed,
please use PasswordCannotBeSubstringInUsername instead. If you have not
customised your password policies, there will be nothing to do here.
==== New configuration ====
* $wgBrowserFormatDetection - This setting allows the enabling or disabling
of automatic detection of possible phone numbers in a webpage in iOS Safari.
* $wgParserEnableLegacyMediaDOM - This setting defaults to true, and enables
the legacy media HTML structure in the output from the Parser. The
alternative modern HTML structure for media is described at
https://www.mediawiki.org/wiki/Parsing/Media_structure
In a future release of MediaWiki this option will default to false,
so it's a good idea to test this setting on your wiki early and report
any issues.
==== Changed configuration ====
* $wgContentHandlerTextFallback - This migration setting, which defines how to
react if a plain text version of a non-text Content object is requested using
ContentHandler::getContentText(), is deprecated.
* $wgActions This setting lets sysadmins over-ride which actions can be used.
It has been re-worked to support injecting dependencies into Action sub-
classes as part of wider work on dependency injection. Previously, $wgActions
was an array where the keys were the names of actions, and the values had the
following impacts (for a given key 'Foo'):
- `true`: use the class 'FooAction' unless for a specific page
WikiPage::getActionOverrides() wants to override that action
- a string: use the class with that name, and do not allow over-riding on a
per-page basis
- `false`: the action is disabled
- a callable: use the Action instance returned by invoking that callback, and
do not allow overriding on a per-page basis
- an object: use that specific Action instance, and do not allow overr-iding
on a per-page basis.
As part of T253078, values can now be arrays that are not callables, which are
treated as ObjectFactory specs, allowing for services to be injected.
Additionally, the distinction between values that allow per-page overrides and
those that do not was removed - all actions can now be overridden on a per-
page basis using WikiPage::getActionOverrides().
* $wgShellboxUrl This setting, new in 1.36 to configure the novel Shellbox
encapsulation system, is now deprecated; use $wgShellboxUrls as a mapping of
service => URL instead.
* $wgIncludejQueryMigrate This setting, introduced in 1.29 to on whether to
provide a migration layer for jQuery, has now switched its default value from
true to false. This may break gadgets that depended on methods that were
removed in jQuery 3 in 2017. See T280944 for more information.
* A number of settings have been renamed. The former configuration variable
names are deprecated, but will be used as the fall back if they are still set,
and remain temporarily available for extensions which might try to read them:
- $wgFileBlacklist is now $wgProhibitedFileExtensions
- $wgMimeTypeBlacklist is now $wgMimeTypeExclusions
- $wgEnableUserEmailBlacklist is now $wgEnableUserEmailMuteList
- $wgShortPagesNamespaceBlacklist is now $wgShortPagesNamespaceExclusions
* $wgMimeTypeExclusions - As well as being renamed, this configuration array now
also prohibits the RFC 4329 form of JavaScript, 'application/javascript', as
well as previous MIME types.
* $wgFragmentMode - This setting, which determines the encoding of section IDs,
has now switched its default value from legacy-first to html5-first: both the
HTML5 anchor and the legacy percent-encoding-style anchor will still be
generated for section titles, but references to them will use the HTML5
version, resulting in human-readable fragments.
==== Removed configuration ====
* $wgLegacyJavaScriptGlobals, deprecated in 1.36.
* (T274695) $wgAjaxEditStash, deprecated in 1.36.
* $wgShowDBErrorBacktrace, deprecated and non-functional since 1.32.
* $wgShowSQLErrors, deprecated and non-functional since 1.32.
* $wgLangObjCacheSize, without deprecation; the LanguageFactory service now
always retains at most 10 objects in its LRU-cache.
* $wgDjvuToXML, without deprecation; the tool it enables is obsolete and
abandoned upstream. Use $wgDjvuDump to use that tool instead.
=== New user-facing features in 1.37 ===
* (T161934) MediaWiki now supports JPEG2000 files, to a limited extent.
=== External library changes in 1.37 ===
==== New external libraries ====
* Added symfony/polyfill-php80 1.23.1.
* Added whatwg-fetch 3.6.2.
* Added wikimedia/normalized-exception 1.0.1.
==== Changed external libraries ====
* Updated OOjs from v5.0.0 to v6.0.0
* Updated OOjs-Router from v0.2.0 to v0.3.0
* Updated OOUI from v0.41.3 to v0.42.0
* Updated WVUI from v0.1.0 to v0.3.0
* Updated cssjanus/cssjanus from v1.3.0 to v2.1.0.
* Updated pear/mail_mime from 1.10.9 to 1.10.11.
* Updated psr/container from v1.0.0 to v1.1.1.
* Updated wikimedia/minify from v2.2.2 to v2.2.4.
* Updated wikimedia/object-factory from v3.0.0 to v3.0.2.
* Updated wikimedia/parsoid from v0.13.1 to v0.14.0.
* Updated wikimedia/relpath from v2.1.1 to v3.0.0.
* Updated wikimedia/remex-html from v2.3.1 to v2.3.2.
* Updated wikimedia/shellbox from v1.0.4 to v2.0.0.
* Updated wikimedia/wait-condition-loop from v2.0.1 to v2.0.2.
* Updated zordius/lightncandy from v1.2.5 to v1.2.6.
===== Changed development-only external libraries =====
* Updated qunit from 2.10.0 to 2.16.0.
==== Removed external libraries ====
* The pimple/pimple development-only library has been removed.
=== Action API changes in 1.37 ===
* (T280806) The API methods for fetching tokens which were deprecated in
MediaWiki 1.24 have been removed. action=query&meta=tokens&type= should be
used instead. Please note some token types no longer exist, and you should
just use type=csrf for those instead.
- action=query&prop=info&intoken ->
action=query&meta=tokens&type=csrf
- action=tokens&type= ->
action=query&meta=tokens&type=
- action=query&list=recentchanges&rctoken ->
action=query&meta=tokens&type=csrf
- action=query&prop=revisions&rvtoken=rollback ->
action=query&meta=tokens&type=rollback
- action=query&meta=userinfo&uiprop=preferencestoken ->
action=query&meta=tokens&type=csrf
- action=query&list=users&ustoken=userrights ->
action=query&meta=tokens&type=userrights
=== Languages updated in 1.37 ===
MediaWiki supports over 350 languages. Many localisations are updated regularly.
Below only new and removed languages are listed, as well as changes to languages
because of Phabricator reports.
* (T280435) LRM and RLM characters were removed from names of languages with
parentheses in Names.php
* (T283422) Add namespace name translations and change the autonym of
the Kinyarwanda language to "Ikinyarwanda".
* (T283423) Change the autonym of the Lombard language from "lumbaart"
to "lombard".
* (T279619) Added language support for Dagbani (dag).
* (T282085) Added language support for Malay in Arabic (Jawi) script (ms-arab).
* (T283053) Added language support for Ojibwe (ojb).
* (T283480) Added language support for Wallisian (wls, Fakaʻuvea).
* (T284002) Added language support for Paiwan (pwn).
* (T284044) Added language support for Carpathian Romani (rmc).
* (T286460) Added language support for Gun (guw, Gungbe).
* (T287345) Added language support for Baoulé (bci).
* (T290126) Added language support for Kildin Sami (sjd).
* (T290408) Added language support for Pite Sami (sje).
* (T25216) Started the renaming of the language code for Norman from nrm to
nrf.
=== Breaking changes in 1.37 ===
* The Revision class, emitting deprecation warnings since 1.35, was removed
entirely. As part of this, the following hooks that included a Revision object
were removed:
- ArticleRevisionUndeleted - use RevisionUndeleted
- ArticleRollbackComplete - use RollbackComplete
- DiffRevisionTools - use DiffTools
- DiffViewHeader - use DifferenceEngineViewHeader
- HistoryRevisionTools - use HistoryTools
- NewRevisionFromEditComplete - use RevisionFromEditComplete
- PageContentInsertComplete - use PageSaveComplete
- PageContentSaveComplete - use PageSaveComplete
- ParserFetchTemplate - use BeforeParserFetchTemplateRevisionRecord
- RevisionInsertComplete - use RevisionRecordInserted
- TitleMoveComplete - use PageMoveComplete
- TitleMoveCompleting - use PageMoveCompleting
- UndeleteShowRevision - no replacement
- UserRetrieveNewTalks - no replacement
… the following methods and variables have been removed:
- Article::$mRevision
- Article::getRevisionFetched()
- ContribsPager::tryToCreateValidRevision()
- EditPage::$mBaseRevision
- EditPage::getBaseRevision()
- LinksUpdate::getRevision()
- LinksUpdate::setRevision()
- PageArchive::getArchivedRevision()
- PageArchive::getPreviousRevision()
- PageArchive::getRevision()
- Parser::$mRevisionObject
- Parser::fetchCurrentRevisionOfTitle()
- Parser::getRevisionObject()
- Parser::statelessFetchRevision()
- ParserOptions::getCurrentRevisionCallback()
- ParserOptions::setCurrentRevisionCallback()
- Title::countAuthorsBetween()
- Title::getFirstRevision()
- User::getNewMessageLinks()
- User::getNewMessageRevisionId()
- User::setNewtalk()
- WikiPage::getOldestRevision()
- WikiPage::getRevision()
- WikiPage::getUndoContent()
- WikiPage::updateIfNewerOn()
… and the following methods no longer accept Revision objects as parameters:
- CategoryMembershipChange::__construct()
- ContentHandler::getUndoContent()
- DerivedPageDataUpdater::prepareUpdate()
- DifferenceEngine::getRevisionHeader()
- Linker::buildRollbackLink()
- Linker::generateRollback()
- Linker::getRevDeleteLink()
- Linker::getRollbackEditCount()
- Linker::revComment()
- Linker::revUserLink()
- Linker::revUserTools()
- WikiPage::doDeleteUpdates()
- WikiPage::doEditUpdates()
- WikiPage::hasDifferencesOutsideMainSlot()
- WikiPage::onArticleEdit()
- WikiPage::prepareContentForEdit()
- WikiPage::updateRevisionOn()
The following methods return arrays that formerly included a 'revision'
key that would emit deprecation warnings when accessed and return a
Revision object. The Revision object has been removed from the arrays,
and the 'revision-record' key should be used to get the relevant
RevisionRecord instead:
- PageUpdater::doCreate()
- PageUpdater::doModify()
- Parser::statelessFetchTemplate()
- WikiPage::doEditContent()
Finally, the ParserOptions `templateCallback` option is a callback that is
called in Parser::fetchTemplateAndTitle() and should return an array - the
'revision' key to that array used to be a Revision object and was used if
no 'revision-record' was returned - is now ignored.
* Previously, the classes RevisionTestModifyableContent and
RevisionTestModifyableContentHandler were loaded for use in tests, but were
only used within the tests for the since-removed Revision class. This content
and content handler class were removed without deprecation.
* WANObjectCache::HOLDOFF_NONE, deprecated since 1.35, was removed. Use
WANObjectCache::HOLDOFF_TTL_NONE instead.
* Calling ResourceLoader::makeVersionQuery() without $modules parameter,
deprecated since MediaWiki 1.34, is no longer supported.
* LocalFile::recordUpload2(), deprecated since 1.35, was removed.
* The following methods and fields in the Language class, deprecated since 1.35,
have been removed:
- ::classFromCode()
- ::clearCaches()
- ::convertTitle()
- ::findVariantLink()
- ::$mConverter
- ::updateConversionTable()
* The following methods in the Parser class have been removed after having been
deprecated in 1.35:
- fetchTemplate()
- Title()
* (T273354) When an edit is prevented by an 'EditFilterMergedContent' hook
handler without changing the status, the edit form will now be displayed.
* User::clearNotification() which had been deprecated in 1.35 has been removed.
Use WatchlistManager::clearTitleUserNotification() instead.
* User::getNewtalk() which had been deprecated in 1.35 has been removed. Use
TalkPageNotificationManager::userHasNewMessages() instead.
* The Autopromote class, deprecated since 1.35, was removed. Use
UserGroupManager instead.
* The CachedAction, SpecialCachedPage, CacheHelper, and ICacheHelper classes,
all emitting deprecation warnings since 1.36, have been removed.
* The hooks BeforeHttpsRedirect, CanIPUseHTTPS and UserRequiresHTTPS, deprecated
in 1.35, were removed.
* The TitleArrayFromResult hook, deprecated in 1.36, was removed.
* The deprecated "es6-promise" alias ResourceLoader module has been removed. Use
the "es6-polyfills" module directly intead.
* The deprecated "mediawiki.legacy.protect" ResourceLoader module, deprecated
since 1.36, has been removed. Use "mediawiki.action.protect" instead.
* The JavaScript alias $j for references to jQuery, deprecated since 1.23, has
been removed. Use $ instead.
* The AuthenticationProvider interface and the SessionProvider class no longer
extend the PSR LoggerAwareInterface concept, so they can't be typehinted as
LoggerAwareInterface.
* User::getGrantName(), emitting deprecation warnings since 1.36, has been
removed. Use MWGrants::grantName() instead.
* The following ApiBase methods, deprecated since 1.35, have been removed:
- ApiBase::explodeMultiValue
- ApiBase::parseMultiValue
- ApiBase::validateLimit
- ApiBase::validateTimestamp
* The User::idCacheByName() public static field was removed without deprecation.
Instead of using it, get a UserIdentity by name from the UserIdentityLookup
service.
* IDatabase::upsert() and IDatabase::replace() now only accept a single unique
key. Previously, a warning was issued if there were multiple unique keys
provided.
* The MediaWiki:Autoblock_whitelist block exemption control was moved in 1.36 to
MediaWiki:Block-autoblock-exemptionlist. The backward-compatibility of reading
the old MediaWiki:Autoblock_whitelist page has now been dropped.
* The following overridable methods in File hierarchy have changed signatures:
- File::deleteFile() - now accepts UserIdentity instead of User
- File::getDescription() - now accepts Authority instead of User
- File::userCan() - now accepts Authority instead of User
- LocalFile::deleteOldFile() - now accepts UserIdentity instead of User
* The following global methods, each deprecated since 1.36, have been removed:
- wfAppendToArrayIfNotDefault()
- wfAcceptToPrefs()
- wfConfiguredReadOnlyReason()
- wfDebugMem()
- wfGetPrecompiledData()
- wfNegotiateType()
* The following deprecated methods of the Title class have been removed:
- ::nameOf(), deprecated in 1.36
- ::getPreviousRevisionID(), deprecated in 1.34
- ::getNextRevisionID(), deprecated in 1.34
- ::getEarliestRevTime(), deprecated in 1.35
* UploadBase::stashFile(), deprecated since 1.28, was removed.
* wfGetRusage(), deprecated since 1.35, has been removed.
* The following CLI options were removed from tests/phpunit.php:
- use-filebackend
- use-jobqueue
- use-bagostuff
The following options (inherited from Maintenance) were also removed:
- conf
- dbuser
- dbpass
- dbdefaultgroup
- globals
- memory-limit
- profiler
- server
The following options were changed to environment variables:
- wiki => PHPUNIT_WIKI
- use-normal-tables => PHPUNIT_USE_NORMAL_TABLES
- use-filebackend => PHPUNIT_USE_FILEBACKEND
- use-bagostuff => PHPUNIT_USE_BAGOSTUFF
- use-jobqueue => PHPUNIT_USE_JOBQUEUE
This is so that we can use the default PHPUnit entry point (T90875).
* The PHPUNIT_REUSE_DB / --reuse-db option was removed from the phpunit.php
runner. It had been broken for at least three years already. The original use
case was speeding up tests on Oracle, but Oracle support was dropped several
releases ago.
* The MediaWikiPHPUnitTest__endTestHook and MediaWikiPHPUnitTest__startTestHook
PHPUnit hooks were removed. MediaWikiHooksPHPUnitExtension was also removed.
* EntryPoint::getTextFormatters() was made private without a deprecation period;
it had no known external callers.
* DatabaseBlock::chooseBlock(), deprecated since 1.35, was removed.
* SpecialPageFactory::getRestrictedPages(), deprecated since 1.36, was removed.
* SpecialBlock::validateTarget(), deprecated since 1.36, was removed.
* The PatchFileLocation trait was removed without deprecation.
* ActorMigrationBase::getExistingActorId() and ::getNewActorId(), emitting
deprecation warnings since 1.36, were removed.
* Hook handlers implementing the MediaWikiServicesHook hook are now prohibited
from having services injected. This is because by definition, this hook runs
before the service container is fully initialized.
* The protected property LocalFile::$metadata was removed without deprecation.
* WatchedItem::getUser(), emitting deprecation warnings since 1.36, has been
removed.
* AuthManager::singleton(), emitting deprecation warnings since 1.36, has been
removed.
* The AugmentPageProps class was removed without deprecation. It had no known
uses.
* Html::infobox(), deprecated since 1.36, was removed.
* ParserOptions::__construct() now requires that the first parameter is a
UserIdentity object - passing `null` used to fallback to the global
$wgUser but was deprecated since 1.36.
* ParserOptions::newCanonical() no longer supports the first parameter being
null (or omitted entirely), which would fallback to the global $wgUser but
was deprecated since 1.35.
* The SkinTemplatePreventOtherActiveTabs hook, deprecated in 1.35, was removed
entirely.
* The SkinTemplateTabAction hook, deprecated in 1.35, was removed entirely.
* The SkinTemplateBuildNavUrlsNav_urlsAfterPermalink hook, deprecated in 1.35,
was removed entirely.
* The SkinTemplateToolboxEndHook, deprecated in 1.35, was removed entirely.
* The following methods of RevisionStore class, formerly emitting deprecation
warnings, were removed:
- ::newMutableRevisionFromArray()
- ::loadRevisionFromPageId()
- ::loadRevisionFromTitle()
- ::loadRevisionFromTimestamp()
- ::listRevisionSizes()
* LogEntry::getPerformer(), deprecated since 1.36, was removed along with
methods in sub-classes: DatabaseLogEntry, ManualLogEntry, RCDatabaseLogEntry.
* Skin::getRelevantUser() now returns an instance of UserIdentity, and not
necessarily a User object. There is no known usages in MediaWiki ecosystem
that were not satisfied with UserIdentity.
* Direct construction of MergeHistory class, deprecated since 1.35, is no longer
supported. Use MergeHistoryFactory instead. MergeHistory::checkPermissions,
deprecated since 1.36, was removed.
* Skin::generateDebugHTML(), deprecated since 1.35, was removed. Call
MWDebug::getHTMLDebugLog() directly.
* The ApiTestCase class no longer interacts with the global $wgUser.
Previously, the global variable was set at the start of each test, and in
ApiTestCase::doApiRequest() if a performer was specified $wgUser was
updated to match, and if no performer was specified $wgUser was used
instead. Now, $wgUser is not updated, and if no performer is specified
the reusable TestUser object for the sysop is relied on. Extensions
or skins that rely on the global $wgUser variable (which has been
deprecated since 1.35) should instead retrieve the acting user from the
relevant context source.
* SkinTemplate::makeArticleUrlDetails(), deprecated since 1.35, was removed.
* Skin::makeNSUrl(), deprecated since 1.35, was removed.
* Skin::getRevisionId(), deprecated since 1.34, was removed. Use
OutputPage::getRevisionId() instead.
* Skin::isRevisionCurrent(), deprecated since 1.34, was removed. Use
OutputPage::isRevisionCurrent() instead.
* AbstractBlock::parseTarget(), deprecated since 1.36, was removed.
* The ArticleEditUpdates hook, deprecated since 1.35, was removed.
* The `@stable to extend` class CentralIdLookup has following changes:
- The protected ::checkAudience() method now returns an Authority instead of a
User instance.
- A number of its `@stable to override` methods now accept an Authority
instead of a User instance as the $audience parameter.
- A number of methods now accept a UserIdentity instead of their User
parameter.
- The ::localUserFromCentralId() method now returns UserIdentity and not
necessarily a User object.
All extensions that extend this class or use this method were updated to be
ready to the new behavior.
* WatchedItemStoreInterface::enqueueWatchlistExpiryJob(), deprecated since 1.36,
was removed.
* ResultWrapper is now abstract. It cannot be directly constructed (T286694).
* The SecondaryDataUpdates hook, deprecated in 1.32, was removed entirely.
* Content::getDeletionUpdates(), was removed. Use
ContentHandler::getDeletionUpdates() instead.
* Content::getSecondaryDataUpdates(), was removed. Use
ContentHandler::getSecondaryDataUpdates() instead.
* wfDiff(), deprecated since 1.25, has been removed.
* Language::$mLangObjCache, deprecated since 1.35, was removed.
* Language::$transformData, deprecated since 1.35, was removed.
* Language::transformUsingPairFile() was marked @internal. Its deprecated
parameters are no longer supported.
* SpecialMute::getTarget(), unused outside of the SpecialMute class, was
made private.
* The Skin::setupSkinUserCss() method, deprecated in 1.32, was removed. Please
use skin registration instead.
* The ResourceLoaderSkinModule `legacy`, `content` and `content-thumbnails`
features were deprecated. Skins should instead select from the features
listed on [[mw:Manual:ResourceLoaderSkinModule]].
* ParserCache::getKey() and ::getEtag(), deprecated since 1.36, were removed.
* The BaseTemplateToolbox hook, deprecated since 1.35, was removed.
* Previously a capitalize-all-nouns class was added to the body element of
languages where nouns must be capitalized. This class is no longer added to
the body tag and must be provided by skins.
* The SkinTemplateOutputPageBeforeExec hook, deprecated since 1.35, was removed.
* Calling Message::toString() without a parameter, which triggered deprecation
warnings since 1.36, is no longer supported. You can instead use the explicit
formatting methods directly, such as Message::text() and Message::escaped().
* Article::getContentObject(), deprecated since 1.32, was removed.
* Article::delete(), Article::confirmDelete() and ImagePage::delete() were
removed. The logic responsible for building the form is being
moved to DeleteAction, while the actual deletion logic will be moved to a
separate service.
* WikiImporter::debugRevisionHandler(), unused and for debug only, was removed.
* Content::preloadTransform() now emits deprecation warnings. Instead, please
use ContentTransformer::preloadTransform(). Extensions defining a content
model should override ContentHandler::preloadTransform().
* Content::preSaveTransform() now emits deprecation warnings. Instead, please
use ContentTransformer::preSaveTransform() instead. Extensions defining
a content model should override ContentHandler::preSaveTransform().
* Constructing WikiPage objects from Title instances that cannot exist, emitting
deprecation warnings since 1.36, now throws an exception. Additionally,
WikiPage now implements ProperPageIdentity, rather than just PageIdentity.
* The Skin::bottomScripts() method is deprecated. Please instead use
OutputPage::getBottomScripts().
* LinksUpdate::getTriggeringUser() now returns ?UserIdentity instead of ?User.
* The LESS mixin `.box-shadow()` (from mediawiki.mixins.less), deprecated since
1.36, was removed. Use CSS property `box-shadow` unprefixed for all basic
supported browsers instead.
* The LESS mixin `.flex()` now no longer tries to support the 2009 version of
the Flexbox specification; support for the 2012 and modern standard versions
remains unchanged.
* The StorageAwareness::ATTR_SYNCWRITES, StorageAwareness::QOS_SYNCWRITES_*,
StorageAwareness::ATTR_LOCALITY, and StorageAwareness::QOS_LOCALITY_*
constants were removed.
=== Deprecations in 1.37 ===
* JobQueue::getWiki(), deprecated in 1.33, now emits deprecation warnings.
* AbstractBlock::getTargetAndType() and ::getTarget() now emit deprecation
warnings. Use ::getTargetName() and ::getTargetUserIdentity() together with
::getType().
* Passing a UserIdentity to WatchlistManager::clearAllUserNotifications() and
WatchlistManager::clearTitleUserNotifications() is now deprecated. Pass an
Authority instead.
* Passing LinkTarget to WatchlistManager::clearTitleUserNotifications() and
WatchlistManager::getTitleNotificationTimestamp(). Pass PageIdentity instead.
* The User class methods ::isWatched(), ::isTempWatched(), ::removeWatch(), and
::addWatch() have been deprecated. Use corresponding methods in
WatchlistManager instead.
* Multiple WatchAction methods have been deprecated in lieu of WatchlistManager:
- ::doWatchOrUnwatch() use WatchlistManager::setWatch()
- ::doWatch() -> WatchlistManager::addWatch()
- ::doUnwatch() -> WatchlistManager::removeWatch()
* WatchAction::getWatchToken() now emits deprecation warnings. Instead use
CsrfTokenSet::getToken().
* Action::getHookContainer() has been marked as internal. Actions that require
access to a hook container should have one injected instead.
* The ::getTitle() and ::setTitle() methods in Parser have been deprecated.
Use ::getPage() and ::setPage() instead.
* Title::isWatchable() has been deprecated. Use WatchlistManager::isWatchable()
instead.
* Methods and classes related to the primary database, previously referred to as
'master', have been deprecated, with the new ones replacing them as follows:
- The DBMasterPos and MySQLMasterPos classes have been respectively renamed to
DBPrimaryPos and MySQLPrimaryPos.
- LocalRepo::getMasterDB() -> ::getPrimaryDB()
- ForeignDBRepo::getMasterDB() -> ::getPrimaryDB()
- JobQueueDB::getMasterDB() -> ::getPrimaryDB()
- ForeignDBViaLBRepo::getMasterDB() -> ::getPrimaryDB()
- DBFileJournal::getMasterDB() -> ::getPrimaryDB()
- ILoadBalancer::getMasterPos() -> ::getPrimaryPos()
- IDatabase::getMasterPos() -> ::getPrimaryPos()
- ILoadBalancer::finalizeMasterChanges() -> ::finalizePrimaryChanges()
- ILoadBalancer::approveMasterChanges() -> ::approvePrimaryChanges()
- ILoadBalancer::beginMasterChanges() -> ::beginPrimaryChanges()
- ILBFactory::beginMasterChanges() -> ::beginPrimaryChanges()
- ILoadBalancer::commitMasterChanges() -> ::commitPrimaryChanges()
- ILBFactory::commitMasterChanges() -> ::commitPrimaryChanges()
- IDatabase::getTopologyRootMaster() -> ::getTopologyRootPrimary()
- IDatabase::masterPosWait() -> ::primaryPosWait()
- ILoadBalancer::runMasterTransactionIdleCallbacks() ->
::runPrimaryTransactionIdleCallbacks()
- ILoadBalancer::runMasterTransactionListenerCallbacks() ->
::runPrimaryTransactionListenerCallbacks()
- ILoadBalancer::rollbackMasterChanges() -> ::rollbackPrimaryChanges()
- ILBFactory::rollbackMasterChanges() -> ::rollbackPrimaryChanges()
- ILoadBalancer::flushMasterSnapshots() -> ::flushPrimarySnapshots()
- ILoadBalancer::hasMasterConnection() -> ::hasPrimaryConnection()
- ILoadBalancer::hasMasterChanges() -> ::hasPrimaryChanges()
- ILBFactory::hasMasterChanges() -> ::hasPrimaryChanges()
- ILoadBalancer::lastMasterChangeTimestamp() -> ::lastPrimaryChangeTimestamp()
- ILoadBalancer::hasOrMadeRecentMasterChanges() ->
::hasOrMadeRecentPrimaryChanges()
- ILBFactory::hasOrMadeRecentMasterChanges() ->
::hasOrMadeRecentPrimaryChanges()
- ILoadBalancer::pendingMasterChangeCallers() ->
::pendingPrimaryChangeCallers()
- ILoadBalancer::forEachOpenMasterConnection() ->
::forEachOpenPrimaryConnection()
- ILoadBalancer::waitForMasterPos() -> ::waitForPrimaryPos()
- Database::assertIsWritableMaster() -> ::assertIsWritablePrimary()
- RevDelList::reloadFromMaster() -> ::reloadFromPrimary()
- ExternalStoreDB::getMaster() -> ::getPrimary()
- DatabaseMysqlBase::getMasterServerInfo() -> ::getPrimaryServerInfo()
- MWExceptionHandler::rollbackMasterChangesAndLog() ->
::rollbackPrimaryChangesAndLog()
* wfGetLB(), deprecated since 1.27, now emits deprecation warnings.
* wfLocalFile(), deprecated since 1.34, now emits deprecation warnings.
* wfFindFile(), deprecated since 1.34, now emits deprecation warnings.
* wfIncrStats(), deprecated in 1.36, now emits deprecation warnings.
* wfCanIPUseHTTPS() is now deprecated, and always returns true.
* The UserLoadFromDatabase hook has been deprecated. It had no known uses.
* The following methods in ApiPageSet have been deprecated:
- ::getTitles(), use ::getTargets() instead.
- ::getGoodTitles(), use ::getGoodPages() instead.
- ::getMissingTitles(), use ::getMissingPages() instead.
- ::getGoodAndMissingTitles(), use ::getGoodAndMissingPages() instead.
- ::getRedirectTitles(), use ::getRedirectTargets() instead.
- ::getSpecialTitles(), use ::getSpecialPages() instead.
* The following methods from the User class, deprecated in 1.35, now each emit
deprecation warnings:
- ::getOptions()
- ::isIP()
- ::isUsableName()
- ::isCreatableName()
- ::getCanonicalName()
- ::addAutopromoteOnceGroups()
- ::getEffectiveGroups()
- ::getAutomaticGroups()
- ::getFormerGroups()
- ::getIntOption()
- ::getBoolOption()
* The following methods in User were deprecated:
- ::idFromName() - use UserIdentityLookup::getUserIdentityByName() instead.
- ::resetIdByNameCache() - in tests, reset service container. No replacement
needed in production code.
* Use of ActorMigration for any table except revision, deprecated in 1.34, now
emits deprecation warnings. Instead of getInsertValues(), use
ActorNormalization::acquireActorId(). Instead of getWhere() and getJoin(),
do your own join on the actor table.
* DatabasePostgres::remappedTableName() and its dependent constructor parameter
'keywordTableMap' are deprecated. Reserved identifiers that are used as table
names should be quoted where necessary.
* LinkCache::singleton(), deprecated since 1.28, now emits deprecation warnings.
* MessageCache::singleton(), deprecated since 1.34, now emits deprecation
warnings.
* LockManagerGroup::singleton() and ::destroySingletons(), deprecated since
1.34, now emit deprecation warnings.
* HtmlFileCacheUpdate::newFromTitles() is now deprecated and emitting warnings.
Use newFromPages() instead.
* SessionProvider ::setLogger(), ::setManager(), ::setConfig(), and
::setHookContainer() were deprecated. Use ::init() to inject dependencies, or
override ::postInitSetup() to do any custom post-initialization configuration.
* AbstractAuthenticationProvider ::setLogger(), ::setManager(), ::setConfig(),
and ::setHookContainer() now emit deprecation warnings. Use ::init() to inject
dependencies, or override ::postInitSetup() to do any custom post-
initialization configuration.
* User::isLoggedIn(), deprecated since 1.36, now emits deprecation warnings. Use
the method it wraps, User::isRegistered(), instead.
* FileBackendGroup::singleton() and ::destroySingletons(), deprecated since
1.35, now emit deprecation warnings.
* The first parameter of User::getBlock() should now be an integer using the
Authority::FOR_XXX constants. Providing a boolean is deprecated.
* ApiBase::addBlockInfoToStatus() is deprecated for use by extensions. It is now
marked as @internal and may be deleted in the future.
It should not be necessary to call this method, Authority should be providing
all relevant information via a PermissionStatus object.
* JobQueueGroup::singleton() was deprecated - use
MediaWikiServices::getJobQueueGroup() instead.
* JobQueueGroup::destroySingletons() was deprecated. JobQueueGroups are now
automatically destroyed after tests.
* LinkCache::addGoodLinkObj() has been deprecated, since it is prone to
corrupting the cache with invalid information. Use addGoodLinkObjFromRow()
instead. PHPUnit tests must use LinkCacheTestTrait::addGoodLinkObject().
* ContentHandler::getContentText() is now deprecated. Use Content::getText()
instead.
* LinkCache::addLinkObj() has been deprecated, use PageStore::getPageForLink()
instead.
* MediaWiki\User\UserNamePrefixSearch::search() previously accepted as its first
parameter either the string 'public' or a UserIdentity object, to filter
results for. It now expects an Authority object instead of UserIdentity, and
providing just a UserIdentity will now trigger a deprecation warning.
* User::getRights(), deprecated since 1.34, now emits deprecation warnings.
* User::changeableGroups() and ::changeableByGroup() now emit deprecation
warnings, use corresponding methods in UserGroupManager instead.
* User::incEditCount() was deprecated in favor of the new method
UserEditTracker::incrementUserEditCount().
* RepoGroup::singleton(), ::destroySingleton() and ::setSingleton(), deprecated
since 1.34, now emit deprecation warnings.
* RecentChange::getPerformer(), deprecated since 1.36, now emits deprecation
warnings. Use ::getPerformerIdentity() instead.
* ContentHandler::cleanupHandlersCache(), deprecated since 1.35, now emits
deprecation warnings.
* Category::getTitle() was deprecated in favor of Category::getPage()
* File::getUser() method now emits deprecation warnings, along with its over-
rides in LocalFile and ForeignApiFile in favor of ::getUploader().
* SpecialBlock::checkUnblockSelf(), deprecated in 1.36, now emits deprecation
warnings.
* (T284179) The mediawiki.viewport ResourceLoader module is deprecated. You can
now just use MutationObserver or InterSectionObserver directly, which are
widely available in all supported JavaScript browsers.
* The following constructor options of DatabaseBlock class will now trigger
deprecation warnings:
- the 'byText' property with blocker's name,
- the 'by' property with blocker's ID,
For both of these, use the 'by' property with UserIdentity value instead.
* The BeforeResetNotificationTimestamp hook was deprecated.
* ArchivedFile::getUser() ::getRawUser() ::getRawUserText() were deprecated in
favor of ::getUploader.() ::getRawDescription() was deprecated in favor of
::getDescription() with RAW audience parameter.
* When calling LocalFile::newFromRow() or LocalFile::loadFromRow(), passing
extra fields not requested by ::getQueryInfo() will now trigger deprecation
warnings. This is to warn callers that deprefixing and automatic assignment of
such fields will not be done in a future version.
* JobSpecification::getTitle() was deprecated without providing a replacement.
It wasn't used and job given the purpose of JobSpecification class it is not
needed.
* The protected method File::getImageSize() is now deprecated.
* BacklinkCache::get() was deprecated, use
BacklinkCacheFactory::getBacklinkCache() instead.
* Title::getBacklinkCache() now emits deprecation warnings. Instead, use the
::getBacklinkCache() method in the BacklinkCacheFactory service.
* MediaHandler::getImageSize(), ::getMetadata(), and ::isMetadataValid() were
deprecated and should no longer be overridden. Instead, sub-classes should
override getSizeAndMetadata().
* Deprecated File::getMetadata(). Instead use ::getMetadataArray(),
::getMetadataItem() and ::getMetadataItems().
* Message::title() has been deprecated; use Message::page() instead.
* BaseTemplate::getAfterPortlet(), BaseTemplate::renderAfterPortlet(), and the
BaseTemplateAfterPortlet hook, which were deprecated in 1.35,
now emit deprecation warnings.
* The LocalFile::getHistory() hook is deprecated.
* Previously the Skin templateDirectory option inside skin.json had to be
relative to MediaWiki core. This should now be relative to the skin.
* Calling WikiPage::prepareContentForEdit() without a UserIdentity is now
deprecated.
* User::getEditTokenObject(), ::getEditToken(), and ::matchEditToken() were each
deprecated. Use CsrfTokenRepository, which is available via IContextSource,
instead. ::matchEditTokenNoSuffix() was deprecated without replacement.
It was introduced to be able to provide custom error message if the token
was submitted, but ending slashes were stripped by some ASCII mangling proxy.
Use ::matchToken() instead, such proxies are much less common now and there's
not much benefit in customising the error message.
* ContentHandler::getForTitle(), deprecated since 1.35, now emits deprecation
warnings.
* User::listOptionKinds(), deprecated since 1.35, now emits deprecation
warnings.
* WikiPage::doEditContent(), deprecated since 1.32, now emits deprecation
warnings.
* CentralIdLookup::factory() and ::factoryNonLocal() now emit deprecation
warnings; obtain an instance from MediaWikiServices instead.
* The class RandomPage was renamed to SpecialRandomPage. The class RandomPage
is now deprecated.
* BotPassword::invalidateAllPasswordsForCentralId() was deprecated.
* BotPassword::removeAllPasswordsForCentralId() was deprecated.
* The Title class members: $mTextform, $mUrlform, $mDbkeyform, $mNamespace,
$mInterwiki, and $mFragment have been deprecated to not be used directly.
Instead, their corresponding accessor methods should be used.
* IDatabase::fetchObject(), ::fetchRow(), ::numRows(), ::numFields(),
::fieldName(), ::freeResult() and ::dataSeek() are deprecated. Use the
corresponding methods in IResultWrapper instead.
* ResultWrapper::unwrap(), DatabaseMysqlBase::fieldType() and
DatabasePostgres::fieldType() each now emit deprecation warnings.
* Sub-classes implementing Database::doQuery() should return either boolean or
an IResultWrapper. To do otherwise will now trigger a deprecation warning.
* User::getOptionKinds() and ::resetOptions(), both deprecated since 1.35,
now emit deprecation warnings.
* The following methods in MWNamespace, all deprecated since 1.34, now emit
deprecation warnings:
- ::isMovable()
- ::isSubject()
- ::getTalk()
- ::getSubject()
- ::getAssociated()
- ::equals()
- ::subjectEquals()
- ::hasTalkNamespace()
- ::wantSignatures()
- ::isWatchable()
- ::getSubjectNamespaces()
- ::getTalkNamespaces()
- ::isCapitalized()
- ::hasGenderDistinction()
- ::isNonincludable()
- ::getNamespaceContentModel()
- ::getRestrictionLevels()
- ::getCategoryLinkType()
* LogFormatter::styleRestricedElement() has been deprecated in favor of
LogFormatter::styleRestrictedElement()
* The following hooks related to user preferences were deprecated:
- UserLoadOptions: use LoadUserOptions instead.
- UserSaveOptions: use SaveUserOptions instead.
- UserResetAllOptions: no replacement was provided, the hook is not used.
* Title::isNamespaceProtected(), deprecated in 1.34, now emits deprecation
warnings.
* UserSelectQueryBuilder::userIds(), ::userNames(), and ::userNamePrefix() has
been deprecated in favor of ::whereUserIds(), ::whereUserNames(), and
::whereUserNamePrefix().
* Manually constructing a MovePage object, deprecated in 1.34, now emits
deprecation warnings. Use MovePageFactory instead.
* The following deletion-related methods were deprecated:
- WikiPage::doDeleteArticleReal() (soft) - use DeletePage
- WikiPage::doDeleteArticleBatched() (soft) - no replacement
- WikiPage::isBatchedDelete() (soft) - use DeletePage
- WikiPage::doDeleteUpdates() (hard) - no replacement
- WikiPage::getDeletionUpdates() (hard) - no replacement
- Title::isBigDeletion (soft) - no replacement
* Relying on PermissionManager or Authority to check for big deletions
was deprecated. This is now automatically checked if you use
DeletePage::deleteIfAllowed(). (T288759)
* The userCan hook now emits deprecation warnings. Use the
getUserPermissionsErrors or getUserPermissionsErrorsExpensive hooks instead.
* Parser::$mUser public access, and the methods ParserOptions::getUser() and
Parser::getUser() each now emit deprecation warnings.
* The following methods in the Title class have been deprecated in favor of the
corresponding methods in the new RestrictionStore service (with different
names where indicated):
- ::areCascadeProtectionSourcesLoaded()
- ::areRestrictionsCascading()
- ::areRestrictionsLoaded()
- ::getAllRestrictions()
- ::getCascadeProtectionSources()
- ::getFilteredRestrictionTypes()
-> ::listAllRestrictionTypes()
- ::getRestrictionExpiry()
- ::getRestrictionTypes()
-> ::listApplicableRestrictionTypes()
- ::getRestrictions()
- ::isCascadeProtected()
- ::isProtected()
- ::isSemiProtected()
- ::loadRestrictionsFromRows()
* The following Title methods have been deprecated with no direct public
replacement:
- ::deleteTitleProtection()
- ::getTitleProtection()
- ::flushRestrictions()
- ::loadRestrictions()
* User::isAllowUsertalk() now emits deprecation warnings. Use User::getBlock()
and AbstractBlock::isUsertalkEditAllowed() instead.
* Classes used by Preprocessor_DOM have been merged with classes used by
Preprocessor_Hash, as Preprocessor_DOM was removed in 1.35.
- PPDPart has been merged into PPDPart_Hash
- PPDStack has been merged into PPDStack_Hash
- PPDStackElement has been merged into PPDStackElement_Hash
* By default, the global variable $wgUser is now an instance of the new class
StubGlobalUser rather than User, and the first time it is used it will emit
deprecation warnings (the $wgUser variable was deprecated in 1.35). For
extensions that read from this variable, please use a relevant ContextSource
instead, falling back to RequestContext::getMain() if none is available.
* Collation::singleton() and ::factory() were deprecated; obtain an instance of
the CollationFactory from MediaWikiServices instead.
* Title::getDefaultNamespace() has been deprecated to be removed because there
are no known callers/consumers.
* With removal of the stub threshold feature, the following methods now emit
deprecation warnings:
- LinkRenderer::setStubThreshold() and ::getStubThreshold() - no replacement.
- LinkRendererFactory::createForUser() - calling ::create() is now sufficient
- ParserOptions::setStubThreshold() and ::getStubThreshold() - no replacement.
- User::getStubThreshold() - no replacement.
* The ArticleDelete and ArticleDeleteComplete hooks were deprecated. Use
PageDelete and PageDeleteComplete instead.
* The ArticleUndeleteLogEntry hook was deprecated without replacement.
* The following LESS mediawiki.mixins have been deprecated:
- .box-sizing()
- .transform()
- .transform-origin()
- .transition()
- .transition-transform()
* The `UndeleteForm::undelete` hook was deprecated. A new hook was
introduced, `PageUndelete`, that provides handlers with more information and
is also called for non-UI requests. The capability of replacing the
PageArchive object has been removed, as that violates the laws of nature.
=== Other changes in 1.37 ===
* WatchlistManager::addWatch() and WatchlistManager::addWatchIgnoringRights(),
which replace User::addWatch(), now call the WatchArticle and
WatchArticleComplete hooks.
* WatchlistManager::removeWatch() and
WatchlistManager::removeWatchIgnoringRights(), which replace
User::removeWatch(), now call the UnwatchArticle and UnwatchArticleComplete
hooks.
* The overridable postInitSetup() method was added to the
AbstractAuthenticationProvider class. A provider can override postInitSetup()
to do any custom post-initialization configuration.
* The overridable postInitSetup() method was added to the SessionProvider
class. A provider can override postInitSetup() to do any custom
post-initialization configuration.
* The protected getConfig() method was added to the SessionProvider class.
Use SessionProvider::getConfig() to get a config.
* The DBAccessBase class is deprecated. Classes that used to extend it
should get a load balancer (factory) injected in the constructor instead.
* ActorNormalization::acquireActorId() now requires IDatabase parameter.
Not providing one emitted deprecation warnings since 1.36.
* Anti-lock constants ALF_PRELOAD_LINK, ALF_NO_BLOCK_LOCK, ALF_NO_LINK_LOCK
and ALF_PRELOAD_EXISTENCE have been removed. They're unused since 1.25.
* (T278036) CSS class 'mw-htmlform-field-autoinfuse' used by some forms has been
renamed to 'mw-htmlform-autoinfuse'.
* User::newFromRow() does not accept pre-loaded user preferences under
$data['user_properties'] anymore. This optimization was not used.
* The following files change the letter case of the file names:
- SpecialRandompage.php -> SpecialRandomPage.php
- SpecialRandomredirect.php -> SpecialRandomRedirect.php
- SpecialRandomrootpage.php -> SpecialRandomRootPage.php
* Media files which are uploaded server side using the importImages.php
maintenance script will now have the "mw-server-side-upload" change tag.
* (T284917) The stub threshold feature has been removed.
* Skin::getPoweredBy() and Skin::getCopyrightIcon() have been deprecated as they
are only designed for use by skins extended BaseTemplate. You can move calls
to instead use BaseTemplate::getPoweredByHTML() and ::getCopyrightIconHTML()
respectively.
* The SkinGetPoweredBy hook is deprecated. No replacement is provided.
* HTMLTitleTextField didn't support interwiki titles well previously.
Starting with 1.37, HTMLTitleTextField has a new parameter, 'interwiki',
which can be used to control acceptance of interwiki titles. To provide
a transitional period, the default value ('interwiki' => null) ensures
MW will have the same behavior as before (logging a deprecation warning).
In 1.38, the default behavior will change to "interwiki links aren't allowed".
== Compatibility ==
MediaWiki 1.37 requires PHP 7.3.19 or later, or PHP 7.4.3 or later, and the
following PHP extensions:
* ctype
* dom
* fileinfo
* iconv
* intl
* json
* mbstring
* xml
Support for PHP 8.0 is not yet complete.
MySQL/MariaDB is the recommended DBMS. PostgreSQL or SQLite can also be used,
but support for them is somewhat less mature.
The supported versions are:
* MySQL 5.5.8 or later
* PostgreSQL 9.4 or later
* SQLite 3.8.0 or later
== Online documentation ==
Documentation for both end-users and site administrators is available on
MediaWiki.org, and is covered under the GNU Free Documentation License (except
for pages that explicitly state that their contents are in the public domain):
https://www.mediawiki.org/wiki/Special:MyLanguage/Documentation
== Mailing list ==
A mailing list is available for MediaWiki user support and discussion:
https://lists.wikimedia.org/mailman/listinfo/mediawiki-l
A low-traffic announcements-only list is also available:
https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce
It's highly recommended that you sign up for one of these lists if you're
going to run a public MediaWiki, so you can be notified of security fixes.
== IRC help ==
There's usually someone online in #mediawiki on irc.libera.chat.

View File

@ -6,7 +6,7 @@ specific problems, you should check:
https://lists.wikimedia.org/pipermail/mediawiki-l/ ; and
* the bug tracker at https://phabricator.wikimedia.org/
 for information and workarounds to common issues.
for information and workarounds to common issues.
== Overview ==

View File

@ -105,12 +105,12 @@ function wfApiMain() {
if ( $processor ) {
try {
$manager = $processor->getModuleManager();
$module = $manager->getModule( $wgRequest->getVal( 'action' ), 'action' );
$module = $manager->getModule( $wgRequest->getRawVal( 'action' ), 'action' );
} catch ( Throwable $ex ) {
$module = null;
}
if ( !$module || $module->mustBePosted() ) {
$items[] = "action=" . $wgRequest->getVal( 'action' );
$items[] = "action=" . $wgRequest->getRawVal( 'action' );
} else {
$items[] = wfArrayToCgi( $wgRequest->getValues() );
}

View File

@ -11,6 +11,7 @@ $wgAutoloadLocalClasses = [
'ActiveUsersPager' => __DIR__ . '/includes/specials/pagers/ActiveUsersPager.php',
'ActivityUpdateJob' => __DIR__ . '/includes/jobqueue/jobs/ActivityUpdateJob.php',
'ActorMigration' => __DIR__ . '/includes/ActorMigration.php',
'ActorMigrationBase' => __DIR__ . '/includes/ActorMigrationBase.php',
'AddChangeTag' => __DIR__ . '/maintenance/addChangeTag.php',
'AddRFCandPMIDInterwiki' => __DIR__ . '/maintenance/addRFCandPMIDInterwiki.php',
'AddSite' => __DIR__ . '/maintenance/addSite.php',
@ -148,7 +149,6 @@ $wgAutoloadLocalClasses = [
'ApiSetPageLanguage' => __DIR__ . '/includes/api/ApiSetPageLanguage.php',
'ApiStashEdit' => __DIR__ . '/includes/api/ApiStashEdit.php',
'ApiTag' => __DIR__ . '/includes/api/ApiTag.php',
'ApiTokens' => __DIR__ . '/includes/api/ApiTokens.php',
'ApiUnblock' => __DIR__ . '/includes/api/ApiUnblock.php',
'ApiUndelete' => __DIR__ . '/includes/api/ApiUndelete.php',
'ApiUpload' => __DIR__ . '/includes/api/ApiUpload.php',
@ -166,11 +166,9 @@ $wgAutoloadLocalClasses = [
'AtomFeed' => __DIR__ . '/includes/changes/AtomFeed.php',
'AtomicSectionUpdate' => __DIR__ . '/includes/deferred/AtomicSectionUpdate.php',
'AttachLatest' => __DIR__ . '/maintenance/attachLatest.php',
'AugmentPageProps' => __DIR__ . '/includes/search/AugmentPageProps.php',
'AuthManagerSpecialPage' => __DIR__ . '/includes/specialpage/AuthManagerSpecialPage.php',
'AutoCommitUpdate' => __DIR__ . '/includes/deferred/AutoCommitUpdate.php',
'AutoloadGenerator' => __DIR__ . '/includes/utils/AutoloadGenerator.php',
'Autopromote' => __DIR__ . '/includes/Autopromote.php',
'BacklinkCache' => __DIR__ . '/includes/cache/BacklinkCache.php',
'BacklinkJobUtils' => __DIR__ . '/includes/jobqueue/utils/BacklinkJobUtils.php',
'BackupDumper' => __DIR__ . '/maintenance/includes/BackupDumper.php',
@ -187,18 +185,14 @@ $wgAutoloadLocalClasses = [
'BatchRowUpdate' => __DIR__ . '/includes/utils/BatchRowUpdate.php',
'BatchRowWriter' => __DIR__ . '/includes/utils/BatchRowWriter.php',
'BcryptPassword' => __DIR__ . '/includes/password/BcryptPassword.php',
'BenchHttpHttps' => __DIR__ . '/maintenance/benchmarks/bench_HTTP_HTTPS.php',
'BenchIfSwitch' => __DIR__ . '/maintenance/benchmarks/bench_if_switch.php',
'BenchUtf8TitleCheck' => __DIR__ . '/maintenance/benchmarks/bench_utf8_title_check.php',
'BenchWikimediaBaseConvert' => __DIR__ . '/maintenance/benchmarks/bench_Wikimedia_base_convert.php',
'BenchmarkDeleteTruncate' => __DIR__ . '/maintenance/benchmarks/bench_delete_truncate.php',
'BenchmarkCommentFormatter' => __DIR__ . '/maintenance/benchmarks/benchmarkCommentFormatter.php',
'BenchmarkEval' => __DIR__ . '/maintenance/benchmarks/benchmarkEval.php',
'BenchmarkHooks' => __DIR__ . '/maintenance/benchmarks/benchmarkHooks.php',
'BenchmarkJSMinPlus' => __DIR__ . '/maintenance/benchmarks/benchmarkJSMinPlus.php',
'BenchmarkLruHash' => __DIR__ . '/maintenance/benchmarks/benchmarkLruHash.php',
'BenchmarkParse' => __DIR__ . '/maintenance/benchmarks/benchmarkParse.php',
'BenchmarkPurge' => __DIR__ . '/maintenance/benchmarks/benchmarkPurge.php',
'BenchmarkSanitizer' => __DIR__ . '/maintenance/benchmarks/benchmarkSanitizer.php',
'BenchmarkStringReplacement' => __DIR__ . '/maintenance/benchmarks/benchmarkStringReplacement.php',
'BenchmarkTidy' => __DIR__ . '/maintenance/benchmarks/benchmarkTidy.php',
'BenchmarkTitleValue' => __DIR__ . '/maintenance/benchmarks/benchmarkTitleValue.php',
'Benchmarker' => __DIR__ . '/maintenance/includes/Benchmarker.php',
@ -216,9 +210,7 @@ $wgAutoloadLocalClasses = [
'BufferingStatsdDataFactory' => __DIR__ . '/includes/libs/stats/BufferingStatsdDataFactory.php',
'CLIParser' => __DIR__ . '/maintenance/parse.php',
'CacheDependency' => __DIR__ . '/includes/cache/dependency/CacheDependency.php',
'CacheHelper' => __DIR__ . '/includes/cache/CacheHelper.php',
'CacheTime' => __DIR__ . '/includes/parser/CacheTime.php',
'CachedAction' => __DIR__ . '/includes/actions/CachedAction.php',
'CachedBagOStuff' => __DIR__ . '/includes/libs/objectcache/CachedBagOStuff.php',
'CachingSiteStore' => __DIR__ . '/includes/site/CachingSiteStore.php',
'CannotCreateActorException' => __DIR__ . '/includes/exception/CannotCreateActorException.php',
@ -232,7 +224,7 @@ $wgAutoloadLocalClasses = [
'CategoryViewer' => __DIR__ . '/includes/CategoryViewer.php',
'CdnCacheUpdate' => __DIR__ . '/includes/deferred/CdnCacheUpdate.php',
'CdnPurgeJob' => __DIR__ . '/includes/jobqueue/jobs/CdnPurgeJob.php',
'CentralIdLookup' => __DIR__ . '/includes/user/CentralIdLookup.php',
'CentralIdLookup' => __DIR__ . '/includes/user/CentralId/CentralIdLookup.php',
'ChangePassword' => __DIR__ . '/maintenance/changePassword.php',
'ChangeTags' => __DIR__ . '/includes/changetags/ChangeTags.php',
'ChangeTagsList' => __DIR__ . '/includes/changetags/ChangeTagsList.php',
@ -254,7 +246,6 @@ $wgAutoloadLocalClasses = [
'CheckComposerLockUpToDate' => __DIR__ . '/maintenance/checkComposerLockUpToDate.php',
'CheckDependencies' => __DIR__ . '/maintenance/checkDependencies.php',
'CheckImages' => __DIR__ . '/maintenance/checkImages.php',
'CheckLess' => __DIR__ . '/maintenance/checkLess.php',
'CheckUsernames' => __DIR__ . '/maintenance/checkUsernames.php',
'ClassCollector' => __DIR__ . '/includes/utils/ClassCollector.php',
'CleanupBlocks' => __DIR__ . '/maintenance/cleanupBlocks.php',
@ -490,6 +481,7 @@ $wgAutoloadLocalClasses = [
'FallbackContentHandler' => __DIR__ . '/includes/content/FallbackContentHandler.php',
'FatalError' => __DIR__ . '/includes/exception/FatalError.php',
'FauxRequest' => __DIR__ . '/includes/FauxRequest.php',
'FauxRequestUpload' => __DIR__ . '/includes/FauxRequestUpload.php',
'FauxResponse' => __DIR__ . '/includes/FauxResponse.php',
'FauxSearchResult' => __DIR__ . '/includes/search/FauxSearchResult.php',
'FauxSearchResultSet' => __DIR__ . '/includes/search/FauxSearchResultSet.php',
@ -520,6 +512,7 @@ $wgAutoloadLocalClasses = [
'FileOpPerfTest' => __DIR__ . '/maintenance/fileOpPerfTest.php',
'FileRepo' => __DIR__ . '/includes/filerepo/FileRepo.php',
'FindBadBlobs' => __DIR__ . '/maintenance/findBadBlobs.php',
'FindClasses' => __DIR__ . '/maintenance/findClasses.php',
'FindDeprecated' => __DIR__ . '/maintenance/findDeprecated.php',
'FindMissingActors' => __DIR__ . '/maintenance/findMissingActors.php',
'FindMissingFiles' => __DIR__ . '/maintenance/findMissingFiles.php',
@ -527,6 +520,7 @@ $wgAutoloadLocalClasses = [
'FixDefaultJsonContentPages' => __DIR__ . '/maintenance/fixDefaultJsonContentPages.php',
'FixDoubleRedirects' => __DIR__ . '/maintenance/fixDoubleRedirects.php',
'FixExtLinksProtocolRelative' => __DIR__ . '/maintenance/fixExtLinksProtocolRelative.php',
'FixMergeHistoryCorruption' => __DIR__ . '/maintenance/fixMergeHistoryCorruption.php',
'FixTimestamps' => __DIR__ . '/maintenance/fixTimestamps.php',
'FixUserRegistration' => __DIR__ . '/maintenance/fixUserRegistration.php',
'ForeignAPIFile' => __DIR__ . '/includes/filerepo/file/ForeignAPIFile.php',
@ -638,7 +632,6 @@ $wgAutoloadLocalClasses = [
'HttpStatus' => __DIR__ . '/includes/libs/HttpStatus.php',
'IApiMessage' => __DIR__ . '/includes/api/IApiMessage.php',
'IBufferingStatsdDataFactory' => __DIR__ . '/includes/libs/stats/IBufferingStatsdDataFactory.php',
'ICacheHelper' => __DIR__ . '/includes/cache/ICacheHelper.php',
'IContextSource' => __DIR__ . '/includes/context/IContextSource.php',
'IDBAccessObject' => __DIR__ . '/includes/dao/IDBAccessObject.php',
'IDatabase' => __DIR__ . '/includes/libs/rdbms/database/IDatabase.php',
@ -689,7 +682,8 @@ $wgAutoloadLocalClasses = [
'InstallerSessionProvider' => __DIR__ . '/includes/installer/InstallerSessionProvider.php',
'Interwiki' => __DIR__ . '/includes/interwiki/Interwiki.php',
'InvalidPassword' => __DIR__ . '/includes/password/InvalidPassword.php',
'InvalidateUserSesssions' => __DIR__ . '/maintenance/invalidateUserSessions.php',
'InvalidateBotPasswords' => __DIR__ . '/maintenance/invalidateBotPasswords.php',
'InvalidateUserSessions' => __DIR__ . '/maintenance/invalidateUserSessions.php',
'IteratorDecorator' => __DIR__ . '/includes/libs/iterators/IteratorDecorator.php',
'IuConverter' => __DIR__ . '/includes/language/converters/IuConverter.php',
'JSCompilerContext' => __DIR__ . '/includes/libs/jsminplus.php',
@ -715,6 +709,7 @@ $wgAutoloadLocalClasses = [
'JobQueueRedis' => __DIR__ . '/includes/jobqueue/JobQueueRedis.php',
'JobRunner' => __DIR__ . '/includes/jobqueue/JobRunner.php',
'JobSpecification' => __DIR__ . '/includes/jobqueue/JobSpecification.php',
'Jpeg2000Handler' => __DIR__ . '/includes/media/Jpeg2000Handler.php',
'JpegHandler' => __DIR__ . '/includes/media/JpegHandler.php',
'JpegMetadataExtractor' => __DIR__ . '/includes/media/JpegMetadataExtractor.php',
'JsonContent' => __DIR__ . '/includes/content/JsonContent.php',
@ -727,42 +722,42 @@ $wgAutoloadLocalClasses = [
'LCStoreNull' => __DIR__ . '/includes/cache/localisation/LCStoreNull.php',
'LCStoreStaticArray' => __DIR__ . '/includes/cache/localisation/LCStoreStaticArray.php',
'LangMemUsage' => __DIR__ . '/maintenance/language/langmemusage.php',
'Language' => __DIR__ . '/languages/Language.php',
'LanguageAr' => __DIR__ . '/languages/classes/LanguageAr.php',
'LanguageAz' => __DIR__ . '/languages/classes/LanguageAz.php',
'LanguageBe_tarask' => __DIR__ . '/languages/classes/LanguageBe_tarask.php',
'LanguageBs' => __DIR__ . '/languages/classes/LanguageBs.php',
'Language' => __DIR__ . '/includes/language/Language.php',
'LanguageAr' => __DIR__ . '/includes/languages/LanguageAr.php',
'LanguageAz' => __DIR__ . '/includes/languages/LanguageAz.php',
'LanguageBe_tarask' => __DIR__ . '/includes/languages/LanguageBe_tarask.php',
'LanguageBs' => __DIR__ . '/includes/languages/LanguageBs.php',
'LanguageCode' => __DIR__ . '/includes/language/LanguageCode.php',
'LanguageConverter' => __DIR__ . '/includes/language/LanguageConverter.php',
'LanguageConverterIcu' => __DIR__ . '/includes/language/LanguageConverterIcu.php',
'LanguageConverterSpecific' => __DIR__ . '/includes/language/LanguageConverterSpecific.php',
'LanguageCu' => __DIR__ . '/languages/classes/LanguageCu.php',
'LanguageDsb' => __DIR__ . '/languages/classes/LanguageDsb.php',
'LanguageEn' => __DIR__ . '/languages/classes/LanguageEn.php',
'LanguageFi' => __DIR__ . '/languages/classes/LanguageFi.php',
'LanguageGa' => __DIR__ . '/languages/classes/LanguageGa.php',
'LanguageGan' => __DIR__ . '/languages/classes/LanguageGan.php',
'LanguageHsb' => __DIR__ . '/languages/classes/LanguageHsb.php',
'LanguageHu' => __DIR__ . '/languages/classes/LanguageHu.php',
'LanguageHy' => __DIR__ . '/languages/classes/LanguageHy.php',
'LanguageJa' => __DIR__ . '/languages/classes/LanguageJa.php',
'LanguageKaa' => __DIR__ . '/languages/classes/LanguageKaa.php',
'LanguageKk' => __DIR__ . '/languages/classes/LanguageKk.php',
'LanguageKk_cyrl' => __DIR__ . '/languages/classes/LanguageKk_cyrl.php',
'LanguageKm' => __DIR__ . '/languages/classes/LanguageKm.php',
'LanguageKsh' => __DIR__ . '/languages/classes/LanguageKsh.php',
'LanguageLa' => __DIR__ . '/languages/classes/LanguageLa.php',
'LanguageMl' => __DIR__ . '/languages/classes/LanguageMl.php',
'LanguageMy' => __DIR__ . '/languages/classes/LanguageMy.php',
'LanguageOs' => __DIR__ . '/languages/classes/LanguageOs.php',
'LanguageQqx' => __DIR__ . '/languages/classes/LanguageQqx.php',
'LanguageSl' => __DIR__ . '/languages/classes/LanguageSl.php',
'LanguageTr' => __DIR__ . '/languages/classes/LanguageTr.php',
'LanguageTyv' => __DIR__ . '/languages/classes/LanguageTyv.php',
'LanguageWa' => __DIR__ . '/languages/classes/LanguageWa.php',
'LanguageYue' => __DIR__ . '/languages/classes/LanguageYue.php',
'LanguageZh' => __DIR__ . '/languages/classes/LanguageZh.php',
'LanguageZh_hans' => __DIR__ . '/languages/classes/LanguageZh_hans.php',
'LanguageCu' => __DIR__ . '/includes/languages/LanguageCu.php',
'LanguageDsb' => __DIR__ . '/includes/languages/LanguageDsb.php',
'LanguageEn' => __DIR__ . '/includes/languages/LanguageEn.php',
'LanguageFi' => __DIR__ . '/includes/languages/LanguageFi.php',
'LanguageGa' => __DIR__ . '/includes/languages/LanguageGa.php',
'LanguageGan' => __DIR__ . '/includes/languages/LanguageGan.php',
'LanguageHsb' => __DIR__ . '/includes/languages/LanguageHsb.php',
'LanguageHu' => __DIR__ . '/includes/languages/LanguageHu.php',
'LanguageHy' => __DIR__ . '/includes/languages/LanguageHy.php',
'LanguageJa' => __DIR__ . '/includes/languages/LanguageJa.php',
'LanguageKaa' => __DIR__ . '/includes/languages/LanguageKaa.php',
'LanguageKk' => __DIR__ . '/includes/languages/LanguageKk.php',
'LanguageKk_cyrl' => __DIR__ . '/includes/languages/LanguageKk_cyrl.php',
'LanguageKm' => __DIR__ . '/includes/languages/LanguageKm.php',
'LanguageKsh' => __DIR__ . '/includes/languages/LanguageKsh.php',
'LanguageLa' => __DIR__ . '/includes/languages/LanguageLa.php',
'LanguageMl' => __DIR__ . '/includes/languages/LanguageMl.php',
'LanguageMy' => __DIR__ . '/includes/languages/LanguageMy.php',
'LanguageOs' => __DIR__ . '/includes/languages/LanguageOs.php',
'LanguageQqx' => __DIR__ . '/includes/languages/LanguageQqx.php',
'LanguageSl' => __DIR__ . '/includes/languages/LanguageSl.php',
'LanguageTr' => __DIR__ . '/includes/languages/LanguageTr.php',
'LanguageTyv' => __DIR__ . '/includes/languages/LanguageTyv.php',
'LanguageWa' => __DIR__ . '/includes/languages/LanguageWa.php',
'LanguageYue' => __DIR__ . '/includes/languages/LanguageYue.php',
'LanguageZh' => __DIR__ . '/includes/languages/LanguageZh.php',
'LanguageZh_hans' => __DIR__ . '/includes/languages/LanguageZh_hans.php',
'LayeredParameterizedPassword' => __DIR__ . '/includes/password/LayeredParameterizedPassword.php',
'LegacyLogFormatter' => __DIR__ . '/includes/logging/LegacyLogFormatter.php',
'License' => __DIR__ . '/includes/specials/helpers/License.php',
@ -783,7 +778,7 @@ $wgAutoloadLocalClasses = [
'LocalFileLockError' => __DIR__ . '/includes/filerepo/file/LocalFileLockError.php',
'LocalFileMoveBatch' => __DIR__ . '/includes/filerepo/file/LocalFileMoveBatch.php',
'LocalFileRestoreBatch' => __DIR__ . '/includes/filerepo/file/LocalFileRestoreBatch.php',
'LocalIdLookup' => __DIR__ . '/includes/user/LocalIdLookup.php',
'LocalIdLookup' => __DIR__ . '/includes/user/CentralId/LocalIdLookup.php',
'LocalRepo' => __DIR__ . '/includes/filerepo/LocalRepo.php',
'LocalSettingsGenerator' => __DIR__ . '/includes/installer/LocalSettingsGenerator.php',
'LocalisationCache' => __DIR__ . '/includes/cache/localisation/LocalisationCache.php',
@ -847,6 +842,7 @@ $wgAutoloadLocalClasses = [
'MediaFileTrait' => __DIR__ . '/includes/filerepo/file/MediaFileTrait.php',
'MediaHandler' => __DIR__ . '/includes/media/MediaHandler.php',
'MediaHandlerFactory' => __DIR__ . '/includes/media/MediaHandlerFactory.php',
'MediaHandlerState' => __DIR__ . '/includes/media/MediaHandlerState.php',
'MediaTransformError' => __DIR__ . '/includes/media/MediaTransformError.php',
'MediaTransformInvalidParametersException' => __DIR__ . '/includes/media/MediaTransformInvalidParametersException.php',
'MediaTransformOutput' => __DIR__ . '/includes/media/MediaTransformOutput.php',
@ -855,6 +851,7 @@ $wgAutoloadLocalClasses = [
'MediaWikiSite' => __DIR__ . '/includes/site/MediaWikiSite.php',
'MediaWikiTitleCodec' => __DIR__ . '/includes/title/MediaWikiTitleCodec.php',
'MediaWikiVersionFetcher' => __DIR__ . '/includes/MediaWikiVersionFetcher.php',
'MediaWiki\\Collation\\CollationFactory' => __DIR__ . '/includes/collation/CollationFactory.php',
'MediaWiki\\DAO\\WikiAwareEntity' => __DIR__ . '/includes/dao/WikiAwareEntity.php',
'MediaWiki\\DAO\\WikiAwareEntityTrait' => __DIR__ . '/includes/dao/WikiAwareEntityTrait.php',
'MediaWiki\\Debug\\DeprecatablePropertyArray' => __DIR__ . '/includes/debug/DeprecatablePropertyArray.php',
@ -870,7 +867,6 @@ $wgAutoloadLocalClasses = [
'MediaWiki\\Hook\\AncientPagesQueryHook' => __DIR__ . '/includes/specials/Hook/AncientPagesQueryHook.php',
'MediaWiki\\Hook\\ArticleRevisionVisibilitySetHook' => __DIR__ . '/includes/revisiondelete/Hook/ArticleRevisionVisibilitySetHook.php',
'MediaWiki\\Hook\\BaseTemplateAfterPortletHook' => __DIR__ . '/includes/skins/Hook/BaseTemplateAfterPortletHook.php',
'MediaWiki\\Hook\\BaseTemplateToolboxHook' => __DIR__ . '/includes/skins/Hook/BaseTemplateToolboxHook.php',
'MediaWiki\\Hook\\BeforeParserFetchFileAndTitleHook' => __DIR__ . '/includes/parser/Hook/BeforeParserFetchFileAndTitleHook.php',
'MediaWiki\\Hook\\BeforeParserFetchTemplateAndtitleHook' => __DIR__ . '/includes/parser/Hook/BeforeParserFetchTemplateAndtitleHook.php',
'MediaWiki\\Hook\\BeforeParserFetchTemplateRevisionRecordHook' => __DIR__ . '/includes/parser/Hook/BeforeParserFetchTemplateRevisionRecordHook.php',
@ -916,7 +912,6 @@ $wgAutoloadLocalClasses = [
'MediaWiki\\Hook\\GetMetadataVersionHook' => __DIR__ . '/includes/media/Hook/GetMetadataVersionHook.php',
'MediaWiki\\Hook\\GetNewMessagesAlertHook' => __DIR__ . '/includes/skins/Hook/GetNewMessagesAlertHook.php',
'MediaWiki\\Hook\\HistoryPageToolLinksHook' => __DIR__ . '/includes/actions/Hook/HistoryPageToolLinksHook.php',
'MediaWiki\\Hook\\HistoryRevisionToolsHook' => __DIR__ . '/includes/actions/Hook/HistoryRevisionToolsHook.php',
'MediaWiki\\Hook\\HistoryToolsHook' => __DIR__ . '/includes/actions/Hook/HistoryToolsHook.php',
'MediaWiki\\Hook\\IRCLineURLHook' => __DIR__ . '/includes/rcfeed/Hook/IRCLineURLHook.php',
'MediaWiki\\Hook\\ImportHandleContentXMLTagHook' => __DIR__ . '/includes/import/Hook/ImportHandleContentXMLTagHook.php',
@ -970,7 +965,6 @@ $wgAutoloadLocalClasses = [
'MediaWiki\\Hook\\ParserCacheSaveCompleteHook' => __DIR__ . '/includes/parser/Hook/ParserCacheSaveCompleteHook.php',
'MediaWiki\\Hook\\ParserClearStateHook' => __DIR__ . '/includes/parser/Hook/ParserClearStateHook.php',
'MediaWiki\\Hook\\ParserClonedHook' => __DIR__ . '/includes/parser/Hook/ParserClonedHook.php',
'MediaWiki\\Hook\\ParserFetchTemplateHook' => __DIR__ . '/includes/parser/Hook/ParserFetchTemplateHook.php',
'MediaWiki\\Hook\\ParserFirstCallInitHook' => __DIR__ . '/includes/parser/Hook/ParserFirstCallInitHook.php',
'MediaWiki\\Hook\\ParserGetVariableValueSwitchHook' => __DIR__ . '/includes/parser/Hook/ParserGetVariableValueSwitchHook.php',
'MediaWiki\\Hook\\ParserGetVariableValueTsHook' => __DIR__ . '/includes/parser/Hook/ParserGetVariableValueTsHook.php',
@ -1007,15 +1001,10 @@ $wgAutoloadLocalClasses = [
'MediaWiki\\Hook\\SkinGetPoweredByHook' => __DIR__ . '/includes/skins/Hook/SkinGetPoweredByHook.php',
'MediaWiki\\Hook\\SkinPreloadExistenceHook' => __DIR__ . '/includes/skins/Hook/SkinPreloadExistenceHook.php',
'MediaWiki\\Hook\\SkinSubPageSubtitleHook' => __DIR__ . '/includes/skins/Hook/SkinSubPageSubtitleHook.php',
'MediaWiki\\Hook\\SkinTemplateBuildNavUrlsNav_urlsAfterPermalinkHook' => __DIR__ . '/includes/skins/Hook/SkinTemplateBuildNavUrlsNav_urlsAfterPermalinkHook.php',
'MediaWiki\\Hook\\SkinTemplateGetLanguageLinkHook' => __DIR__ . '/includes/skins/Hook/SkinTemplateGetLanguageLinkHook.php',
'MediaWiki\\Hook\\SkinTemplateNavigationHook' => __DIR__ . '/includes/skins/Hook/SkinTemplateNavigationHook.php',
'MediaWiki\\Hook\\SkinTemplateNavigation__SpecialPageHook' => __DIR__ . '/includes/skins/Hook/SkinTemplateNavigation__SpecialPageHook.php',
'MediaWiki\\Hook\\SkinTemplateNavigation__UniversalHook' => __DIR__ . '/includes/skins/Hook/SkinTemplateNavigation__UniversalHook.php',
'MediaWiki\\Hook\\SkinTemplateOutputPageBeforeExecHook' => __DIR__ . '/includes/skins/Hook/SkinTemplateOutputPageBeforeExecHook.php',
'MediaWiki\\Hook\\SkinTemplatePreventOtherActiveTabsHook' => __DIR__ . '/includes/skins/Hook/SkinTemplatePreventOtherActiveTabsHook.php',
'MediaWiki\\Hook\\SkinTemplateTabActionHook' => __DIR__ . '/includes/skins/Hook/SkinTemplateTabActionHook.php',
'MediaWiki\\Hook\\SkinTemplateToolboxEndHook' => __DIR__ . '/includes/skins/Hook/SkinTemplateToolboxEndHook.php',
'MediaWiki\\Hook\\SoftwareInfoHook' => __DIR__ . '/includes/specials/Hook/SoftwareInfoHook.php',
'MediaWiki\\Hook\\SpecialBlockModifyFormFieldsHook' => __DIR__ . '/includes/specials/Hook/SpecialBlockModifyFormFieldsHook.php',
'MediaWiki\\Hook\\SpecialContributionsBeforeMainOutputHook' => __DIR__ . '/includes/specials/Hook/SpecialContributionsBeforeMainOutputHook.php',
@ -1056,7 +1045,6 @@ $wgAutoloadLocalClasses = [
'MediaWiki\\Hook\\UndeleteForm__showRevisionHook' => __DIR__ . '/includes/specials/Hook/UndeleteForm__showRevisionHook.php',
'MediaWiki\\Hook\\UndeleteForm__undeleteHook' => __DIR__ . '/includes/specials/Hook/UndeleteForm__undeleteHook.php',
'MediaWiki\\Hook\\UndeletePageToolLinksHook' => __DIR__ . '/includes/skins/Hook/UndeletePageToolLinksHook.php',
'MediaWiki\\Hook\\UndeleteShowRevisionHook' => __DIR__ . '/includes/specials/Hook/UndeleteShowRevisionHook.php',
'MediaWiki\\Hook\\UnwatchArticleCompleteHook' => __DIR__ . '/includes/actions/Hook/UnwatchArticleCompleteHook.php',
'MediaWiki\\Hook\\UnwatchArticleHook' => __DIR__ . '/includes/actions/Hook/UnwatchArticleHook.php',
'MediaWiki\\Hook\\UpdateUserMailerFormattedPageStatusHook' => __DIR__ . '/includes/mail/Hook/UpdateUserMailerFormattedPageStatusHook.php',
@ -1089,9 +1077,6 @@ $wgAutoloadLocalClasses = [
'MediaWiki\\Hook\\WikiExporter__dumpStableQueryHook' => __DIR__ . '/includes/export/Hook/WikiExporter__dumpStableQueryHook.php',
'MediaWiki\\Hook\\XmlDumpWriterOpenPageHook' => __DIR__ . '/includes/export/Hook/XmlDumpWriterOpenPageHook.php',
'MediaWiki\\Hook\\XmlDumpWriterWriteRevisionHook' => __DIR__ . '/includes/export/Hook/XmlDumpWriterWriteRevisionHook.php',
'MediaWiki\\Languages\\Data\\CrhExceptions' => __DIR__ . '/languages/data/CrhExceptions.php',
'MediaWiki\\Languages\\Data\\Names' => __DIR__ . '/languages/data/Names.php',
'MediaWiki\\Languages\\Data\\ZhConversion' => __DIR__ . '/languages/data/ZhConversion.php',
'MediaWiki\\Languages\\Hook\\LanguageGetTranslatedLanguageNamesHook' => __DIR__ . '/includes/language/Hook/LanguageGetTranslatedLanguageNamesHook.php',
'MediaWiki\\Languages\\Hook\\Language__getMessagesFileNameHook' => __DIR__ . '/includes/language/Hook/Language__getMessagesFileNameHook.php',
'MediaWiki\\Languages\\LanguageConverterFactory' => __DIR__ . '/includes/language/LanguageConverterFactory.php',
@ -1145,6 +1130,7 @@ $wgAutoloadLocalClasses = [
'MigrateComments' => __DIR__ . '/maintenance/migrateComments.php',
'MigrateFileRepoLayout' => __DIR__ . '/maintenance/migrateFileRepoLayout.php',
'MigrateImageCommentTemp' => __DIR__ . '/maintenance/migrateImageCommentTemp.php',
'MigrateRevisionActorTemp' => __DIR__ . '/maintenance/migrateRevisionActorTemp.php',
'MigrateUserGroup' => __DIR__ . '/maintenance/migrateUserGroup.php',
'MimeAnalyzer' => __DIR__ . '/includes/libs/mime/MimeAnalyzer.php',
'MostimagesPage' => __DIR__ . '/includes/specials/SpecialMostimages.php',
@ -1198,10 +1184,7 @@ $wgAutoloadLocalClasses = [
'PNGHandler' => __DIR__ . '/includes/media/PNGHandler.php',
'PNGMetadataExtractor' => __DIR__ . '/includes/media/PNGMetadataExtractor.php',
'PPCustomFrame_Hash' => __DIR__ . '/includes/parser/PPCustomFrame_Hash.php',
'PPDPart' => __DIR__ . '/includes/parser/PPDPart.php',
'PPDPart_Hash' => __DIR__ . '/includes/parser/PPDPart_Hash.php',
'PPDStack' => __DIR__ . '/includes/parser/PPDStack.php',
'PPDStackElement' => __DIR__ . '/includes/parser/PPDStackElement.php',
'PPDStackElement_Hash' => __DIR__ . '/includes/parser/PPDStackElement_Hash.php',
'PPDStack_Hash' => __DIR__ . '/includes/parser/PPDStack_Hash.php',
'PPFrame' => __DIR__ . '/includes/parser/PPFrame.php',
@ -1317,7 +1300,7 @@ $wgAutoloadLocalClasses = [
'RCFeedFormatter' => __DIR__ . '/includes/rcfeed/RCFeedFormatter.php',
'RESTBagOStuff' => __DIR__ . '/includes/libs/objectcache/RESTBagOStuff.php',
'RSSFeed' => __DIR__ . '/includes/changes/RSSFeed.php',
'RandomPage' => __DIR__ . '/includes/specials/SpecialRandompage.php',
'RandomPage' => __DIR__ . '/includes/specials/SpecialRandomPage.php',
'RangeChronologicalPager' => __DIR__ . '/includes/pager/RangeChronologicalPager.php',
'RangeDifference' => __DIR__ . '/includes/diff/RangeDifference.php',
'RawAction' => __DIR__ . '/includes/actions/RawAction.php',
@ -1409,7 +1392,6 @@ $wgAutoloadLocalClasses = [
'ReverseChronologicalPager' => __DIR__ . '/includes/pager/ReverseChronologicalPager.php',
'RevertAction' => __DIR__ . '/includes/actions/RevertAction.php',
'RevertedTagUpdateJob' => __DIR__ . '/includes/jobqueue/jobs/RevertedTagUpdateJob.php',
'Revision' => __DIR__ . '/includes/Revision.php',
'RevisionDeleteUser' => __DIR__ . '/includes/revisiondelete/RevisionDeleteUser.php',
'RevisionDeleter' => __DIR__ . '/includes/revisiondelete/RevisionDeleter.php',
'RevisionItem' => __DIR__ . '/includes/revisionlist/RevisionItem.php',
@ -1494,7 +1476,6 @@ $wgAutoloadLocalClasses = [
'SpecialBookSources' => __DIR__ . '/includes/specials/SpecialBookSources.php',
'SpecialBotPasswords' => __DIR__ . '/includes/specials/SpecialBotPasswords.php',
'SpecialBrokenRedirects' => __DIR__ . '/includes/specials/SpecialBrokenRedirects.php',
'SpecialCachedPage' => __DIR__ . '/includes/specials/SpecialCachedPage.php',
'SpecialCategories' => __DIR__ . '/includes/specials/SpecialCategories.php',
'SpecialChangeContentModel' => __DIR__ . '/includes/specials/SpecialChangeContentModel.php',
'SpecialChangeCredentials' => __DIR__ . '/includes/specials/SpecialChangeCredentials.php',
@ -1569,8 +1550,9 @@ $wgAutoloadLocalClasses = [
'SpecialProtectedtitles' => __DIR__ . '/includes/specials/SpecialProtectedtitles.php',
'SpecialPurge' => __DIR__ . '/includes/specials/SpecialPurge.php',
'SpecialRandomInCategory' => __DIR__ . '/includes/specials/SpecialRandomInCategory.php',
'SpecialRandomredirect' => __DIR__ . '/includes/specials/SpecialRandomredirect.php',
'SpecialRandomrootpage' => __DIR__ . '/includes/specials/SpecialRandomrootpage.php',
'SpecialRandomPage' => __DIR__ . '/includes/specials/SpecialRandomPage.php',
'SpecialRandomRedirect' => __DIR__ . '/includes/specials/SpecialRandomRedirect.php',
'SpecialRandomRootPage' => __DIR__ . '/includes/specials/SpecialRandomRootPage.php',
'SpecialRecentChanges' => __DIR__ . '/includes/specials/SpecialRecentChanges.php',
'SpecialRecentChangesLinked' => __DIR__ . '/includes/specials/SpecialRecentChangesLinked.php',
'SpecialRedirect' => __DIR__ . '/includes/specials/SpecialRedirect.php',
@ -1627,6 +1609,7 @@ $wgAutoloadLocalClasses = [
'StringPrefixSearch' => __DIR__ . '/includes/search/StringPrefixSearch.php',
'StringUtils' => __DIR__ . '/includes/libs/StringUtils.php',
'StripState' => __DIR__ . '/includes/parser/StripState.php',
'StubGlobalUser' => __DIR__ . '/includes/StubGlobalUser.php',
'StubObject' => __DIR__ . '/includes/StubObject.php',
'StubUserLang' => __DIR__ . '/includes/StubUserLang.php',
'SubmitAction' => __DIR__ . '/includes/actions/SubmitAction.php',
@ -1677,6 +1660,7 @@ $wgAutoloadLocalClasses = [
'TransformTooBigImageAreaError' => __DIR__ . '/includes/media/TransformTooBigImageAreaError.php',
'TransformationalImageHandler' => __DIR__ . '/includes/media/TransformationalImageHandler.php',
'TrivialLanguageConverter' => __DIR__ . '/includes/language/TrivialLanguageConverter.php',
'TrivialMediaHandlerState' => __DIR__ . '/includes/media/TrivialMediaHandlerState.php',
'UDPRCFeedEngine' => __DIR__ . '/includes/rcfeed/UDPRCFeedEngine.php',
'UDPTransport' => __DIR__ . '/includes/libs/UDPTransport.php',
'UIDGenerator' => __DIR__ . '/includes/utils/UIDGenerator.php',
@ -1788,6 +1772,7 @@ $wgAutoloadLocalClasses = [
'WikiExporter' => __DIR__ . '/includes/export/WikiExporter.php',
'WikiFilePage' => __DIR__ . '/includes/page/WikiFilePage.php',
'WikiImporter' => __DIR__ . '/includes/import/WikiImporter.php',
'WikiImporterFactory' => __DIR__ . '/includes/import/WikiImporterFactory.php',
'WikiMap' => __DIR__ . '/includes/WikiMap.php',
'WikiPage' => __DIR__ . '/includes/page/WikiPage.php',
'WikiReference' => __DIR__ . '/includes/WikiReference.php',
@ -1812,7 +1797,8 @@ $wgAutoloadLocalClasses = [
'Wikimedia\\Rdbms\\DBConnectionError' => __DIR__ . '/includes/libs/rdbms/exception/DBConnectionError.php',
'Wikimedia\\Rdbms\\DBError' => __DIR__ . '/includes/libs/rdbms/exception/DBError.php',
'Wikimedia\\Rdbms\\DBExpectedError' => __DIR__ . '/includes/libs/rdbms/exception/DBExpectedError.php',
'Wikimedia\\Rdbms\\DBMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/DBMasterPos.php',
'Wikimedia\\Rdbms\\DBMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/DBPrimaryPos.php',
'Wikimedia\\Rdbms\\DBPrimaryPos' => __DIR__ . '/includes/libs/rdbms/database/position/DBPrimaryPos.php',
'Wikimedia\\Rdbms\\DBQueryDisconnectedError' => __DIR__ . '/includes/libs/rdbms/exception/DBQueryDisconnectedError.php',
'Wikimedia\\Rdbms\\DBQueryError' => __DIR__ . '/includes/libs/rdbms/exception/DBQueryError.php',
'Wikimedia\\Rdbms\\DBQueryTimeoutError' => __DIR__ . '/includes/libs/rdbms/exception/DBQueryTimeoutError.php',
@ -1829,11 +1815,11 @@ $wgAutoloadLocalClasses = [
'Wikimedia\\Rdbms\\DatabaseMysqli' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqli.php',
'Wikimedia\\Rdbms\\DatabasePostgres' => __DIR__ . '/includes/libs/rdbms/database/DatabasePostgres.php',
'Wikimedia\\Rdbms\\DatabaseSqlite' => __DIR__ . '/includes/libs/rdbms/database/DatabaseSqlite.php',
'Wikimedia\\Rdbms\\DoctrineAbstractSchemaTrait' => __DIR__ . '/includes/libs/rdbms/database/DoctrineAbstractSchemaTrait.php',
'Wikimedia\\Rdbms\\DoctrineSchemaBuilder' => __DIR__ . '/includes/libs/rdbms/database/DoctrineSchemaBuilder.php',
'Wikimedia\\Rdbms\\DoctrineSchemaBuilderFactory' => __DIR__ . '/includes/libs/rdbms/database/DoctrineSchemaBuilderFactory.php',
'Wikimedia\\Rdbms\\DoctrineSchemaChangeBuilder' => __DIR__ . '/includes/libs/rdbms/database/DoctrineSchemaChangeBuilder.php',
'Wikimedia\\Rdbms\\EnumType' => __DIR__ . '/includes/libs/rdbms/database/EnumType.php',
'Wikimedia\\Rdbms\\DoctrineAbstractSchemaTrait' => __DIR__ . '/includes/libs/rdbms/dbal/DoctrineAbstractSchemaTrait.php',
'Wikimedia\\Rdbms\\DoctrineSchemaBuilder' => __DIR__ . '/includes/libs/rdbms/dbal/DoctrineSchemaBuilder.php',
'Wikimedia\\Rdbms\\DoctrineSchemaBuilderFactory' => __DIR__ . '/includes/libs/rdbms/dbal/DoctrineSchemaBuilderFactory.php',
'Wikimedia\\Rdbms\\DoctrineSchemaChangeBuilder' => __DIR__ . '/includes/libs/rdbms/dbal/DoctrineSchemaChangeBuilder.php',
'Wikimedia\\Rdbms\\EnumType' => __DIR__ . '/includes/libs/rdbms/dbal/EnumType.php',
'Wikimedia\\Rdbms\\FakeResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/FakeResultWrapper.php',
'Wikimedia\\Rdbms\\Field' => __DIR__ . '/includes/libs/rdbms/field/Field.php',
'Wikimedia\\Rdbms\\GeneralizedSql' => __DIR__ . '/includes/libs/rdbms/database/utils/GeneralizedSql.php',
@ -1856,23 +1842,27 @@ $wgAutoloadLocalClasses = [
'Wikimedia\\Rdbms\\LoadMonitor' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitor.php',
'Wikimedia\\Rdbms\\LoadMonitorMySQL' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php',
'Wikimedia\\Rdbms\\LoadMonitorNull' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php',
'Wikimedia\\Rdbms\\MWMySQLPlatform' => __DIR__ . '/includes/libs/rdbms/database/MWMySQLPlatform.php',
'Wikimedia\\Rdbms\\MWPostgreSqlPlatform' => __DIR__ . '/includes/libs/rdbms/database/MWPostgreSqlPlatform.php',
'Wikimedia\\Rdbms\\MWMySQLPlatform' => __DIR__ . '/includes/libs/rdbms/dbal/MWMySQLPlatform.php',
'Wikimedia\\Rdbms\\MWPostgreSqlPlatform' => __DIR__ . '/includes/libs/rdbms/dbal/MWPostgreSqlPlatform.php',
'Wikimedia\\Rdbms\\MaintainableDBConnRef' => __DIR__ . '/includes/libs/rdbms/database/MaintainableDBConnRef.php',
'Wikimedia\\Rdbms\\MySQLField' => __DIR__ . '/includes/libs/rdbms/field/MySQLField.php',
'Wikimedia\\Rdbms\\MySQLMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/MySQLMasterPos.php',
'Wikimedia\\Rdbms\\MySQLMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/MySQLPrimaryPos.php',
'Wikimedia\\Rdbms\\MySQLPrimaryPos' => __DIR__ . '/includes/libs/rdbms/database/position/MySQLPrimaryPos.php',
'Wikimedia\\Rdbms\\MysqliResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/MysqliResultWrapper.php',
'Wikimedia\\Rdbms\\NextSequenceValue' => __DIR__ . '/includes/libs/rdbms/database/utils/NextSequenceValue.php',
'Wikimedia\\Rdbms\\PostgresBlob' => __DIR__ . '/includes/libs/rdbms/encasing/PostgresBlob.php',
'Wikimedia\\Rdbms\\PostgresField' => __DIR__ . '/includes/libs/rdbms/field/PostgresField.php',
'Wikimedia\\Rdbms\\PostgresResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/PostgresResultWrapper.php',
'Wikimedia\\Rdbms\\ResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/ResultWrapper.php',
'Wikimedia\\Rdbms\\SQLiteField' => __DIR__ . '/includes/libs/rdbms/field/SQLiteField.php',
'Wikimedia\\Rdbms\\SchemaBuilder' => __DIR__ . '/includes/libs/rdbms/database/SchemaBuilder.php',
'Wikimedia\\Rdbms\\SchemaChangeBuilder' => __DIR__ . '/includes/libs/rdbms/database/SchemaChangeBuilder.php',
'Wikimedia\\Rdbms\\SchemaBuilder' => __DIR__ . '/includes/libs/rdbms/dbal/SchemaBuilder.php',
'Wikimedia\\Rdbms\\SchemaChangeBuilder' => __DIR__ . '/includes/libs/rdbms/dbal/SchemaChangeBuilder.php',
'Wikimedia\\Rdbms\\SelectQueryBuilder' => __DIR__ . '/includes/libs/rdbms/querybuilder/SelectQueryBuilder.php',
'Wikimedia\\Rdbms\\SessionConsistentConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManager.php',
'Wikimedia\\Rdbms\\SqliteResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/SqliteResultWrapper.php',
'Wikimedia\\Rdbms\\Subquery' => __DIR__ . '/includes/libs/rdbms/encasing/Subquery.php',
'Wikimedia\\Rdbms\\TimestampType' => __DIR__ . '/includes/libs/rdbms/database/TimestampType.php',
'Wikimedia\\Rdbms\\TinyIntType' => __DIR__ . '/includes/libs/rdbms/database/TinyIntType.php',
'Wikimedia\\Rdbms\\TimestampType' => __DIR__ . '/includes/libs/rdbms/dbal/TimestampType.php',
'Wikimedia\\Rdbms\\TinyIntType' => __DIR__ . '/includes/libs/rdbms/dbal/TinyIntType.php',
'Wikimedia\\Rdbms\\TransactionProfiler' => __DIR__ . '/includes/libs/rdbms/TransactionProfiler.php',
'Wikimedia\\Reflection\\GhostFieldAccessTrait' => __DIR__ . '/includes/libs/GhostFieldAccessTrait.php',
'WikitextContent' => __DIR__ . '/includes/content/WikitextContent.php',

View File

@ -22,7 +22,7 @@
"prefer-stable": true,
"require": {
"composer/semver": "3.2.4",
"cssjanus/cssjanus": "1.3.0",
"cssjanus/cssjanus": "2.1.0",
"ext-ctype": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
@ -36,12 +36,12 @@
"guzzlehttp/guzzle": "7.2.0",
"liuggio/statsd-php-client": "1.0.18",
"monolog/monolog": "2.2.0",
"oojs/oojs-ui": "0.41.3",
"oojs/oojs-ui": "0.42.0",
"pear/mail": "1.4.1",
"pear/mail_mime": "1.10.11",
"pear/net_smtp": "1.9.2",
"php": ">=7.3.19",
"psr/container": "1.0.0",
"psr/container": "1.1.1",
"psr/log": "1.1.3",
"ralouphie/getallheaders": "3.0.3",
"symfony/polyfill-php80": "1.23.1",
@ -57,23 +57,24 @@
"wikimedia/ip-utils": "3.0.2",
"wikimedia/less.php": "3.1.0",
"wikimedia/minify": "2.2.4",
"wikimedia/object-factory": "3.0.0",
"wikimedia/parsoid": "0.13.1",
"wikimedia/normalized-exception": "1.0.1",
"wikimedia/object-factory": "3.0.2",
"wikimedia/parsoid": "0.14.0",
"wikimedia/php-session-serializer": "2.0.0",
"wikimedia/purtle": "1.0.7",
"wikimedia/relpath": "2.1.1",
"wikimedia/remex-html": "2.2.2",
"wikimedia/relpath": "3.0.0",
"wikimedia/remex-html": "2.3.2",
"wikimedia/request-timeout": "1.1.0",
"wikimedia/running-stat": "1.2.1",
"wikimedia/scoped-callback": "3.0.0",
"wikimedia/services": "2.0.1",
"wikimedia/shellbox": "1.0.4",
"wikimedia/shellbox": "2.0.0",
"wikimedia/utfnormal": "3.0.2",
"wikimedia/timestamp": "3.0.0",
"wikimedia/wait-condition-loop": "2.0.1",
"wikimedia/wait-condition-loop": "2.0.2",
"wikimedia/wrappedstring": "3.2.0",
"wikimedia/xmp-reader": "0.8.1",
"zordius/lightncandy": "1.2.5"
"zordius/lightncandy": "1.2.6"
},
"require-dev": {
"composer/spdx-licenses": "1.5.4",
@ -83,19 +84,18 @@
"hamcrest/hamcrest-php": "^2.0",
"johnkary/phpunit-speedtrap": "^3.1",
"justinrainbow/json-schema": "~5.2",
"mediawiki/mediawiki-codesniffer": "35.0.0",
"mediawiki/mediawiki-phan-config": "0.10.6",
"mediawiki/mediawiki-codesniffer": "37.0.0",
"mediawiki/mediawiki-phan-config": "0.11.0",
"nikic/php-parser": "4.10.2",
"nmred/kafka-php": "0.1.5",
"php-parallel-lint/php-console-highlighter": "0.5",
"php-parallel-lint/php-parallel-lint": "1.2.0",
"php-parallel-lint/php-parallel-lint": "1.3.0",
"phpunit/phpunit": "^8.5",
"pimple/pimple": "3.3.1",
"psy/psysh": "0.10.5",
"seld/jsonlint": "1.8.3",
"symfony/yaml": "~3.4|~5.1",
"wikimedia/testing-access-wrapper": "~2.0",
"wmde/hamcrest-html-matchers": "^0.1.0"
"wmde/hamcrest-html-matchers": "^1.0.0"
},
"replace": {
"symfony/polyfill-ctype": "1.99",
@ -127,7 +127,7 @@
"serve": "php -S localhost:4000",
"lint": "parallel-lint --exclude vendor",
"phan": "phan -d . --long-progress-bar",
"phpcs": "phpcs -p -s",
"phpcs": "phpcs -p -s --cache",
"fix": [
"phpcbf"
],
@ -136,8 +136,8 @@
"post-install-cmd": "ComposerVendorHtaccessCreator::onEvent",
"post-update-cmd": "ComposerVendorHtaccessCreator::onEvent",
"test": [
"composer lint",
"composer phpcs"
"composer lint .",
"composer phpcs ."
],
"test-some": [
"composer lint",
@ -147,7 +147,8 @@
"phpunit:unit": "phpunit --colors=always --testsuite=core:unit,extensions:unit,skins:unit",
"phpunit:integration": "phpunit --colors=always --testsuite=core:integration,extensions:integration,skins:integration",
"phpunit:coverage": "phpunit --testsuite=core:unit --exclude-group Dump,Broken",
"phpunit:coverage-edit": "ComposerPhpunitXmlCoverageEdit::onEvent"
"phpunit:coverage-edit": "ComposerPhpunitXmlCoverageEdit::onEvent",
"phpunit:entrypoint": "php tests/phpunit/phpunit.php"
},
"config": {
"optimize-autoloader": true,

View File

@ -21,8 +21,8 @@ A page's content model is available using the `Title::getContentModel()` method.
* Pages in `NS_MEDIAWIKI` and `NS_USER` default to the CSS or JavaScript model if they end in .css or .js, respectively. Pages in `NS_MEDIAWIKI` default to the wikitext model otherwise.
* Otherwise, the wikitext model is used.
Note that is currently no mechanism to convert a page from one content model to another, and there is no guarantee that revisions of a page will all have the same content model. Use `Revision::getContentModel()`to find it.
Note that there is no guarantee that revisions of a page will all have the same content model. To find the content model of the slot of a revision, use `SlotRecord::getModel()` -
the content model of the main slot can for now be assumed to be the content model for the overall revision.
## Architecture
@ -33,9 +33,10 @@ Two class hierarchies are used to provide the functionality associated with the
The most important function of ContentHandler is to act as a factory for the appropriate implementation of Content. These `Content` objects are to be used by MediaWiki everywhere, instead of passing page content around as text. All manipulation and analysis of page content must be done via the appropriate methods of the Content object.
For each content model, a subclass of ContentHandler has to be registered with `$wgContentHandlers`. The ContentHandler object for a given content model can be obtained using `ContentHandler::getForModelID( $id )`. Also `Title`, `WikiPage` and `Revision` now have `getContentHandler()` methods for convenience.
For each content model, a subclass of ContentHandler has to be registered with `$wgContentHandlers`. The ContentHandler object for a given content model can be obtained using `ContentHandler::getForModelID( $id )`. Also `Title` and `WikiPage` now have `getContentHandler()` methods for convenience.
`ContentHandler` objects are singletons that provide functionality specific to the content type, but not directly acting on the content of some page. `ContentHandler::makeEmptyContent()` and `ContentHandler::unserializeContent()` can be used to create a Content object of the appropriate type. However, it is recommended to instead use `WikiPage::getContent()` resp. `Revision::getContent()` to get a page's content as a Content object. These two methods should be the ONLY way in which page content is accessed.
`ContentHandler` objects are singletons that provide functionality specific to the content type, but not directly acting on the content of some page. `ContentHandler::makeEmptyContent()` and `ContentHandler::unserializeContent()` can be used to create a Content object of the appropriate type. However, it is recommended to instead use `WikiPage::getContent()` resp. `RevisionRecord::getContent()` to get a page's content as a Content object. These two methods should be the ONLY way in which page content is accessed.
For `WikiPage::getContent()` the content of the main slot is returned, other slots can be retrieved by using `RevisionRecord::getContent()` and specifying the slot.
Another important function of ContentHandler objects is to define custom action handlers for a content model, see `ContentHandler::getActionOverrides()`. This is similar to what `WikiPage::getActionOverrides()` was already doing.
@ -66,7 +67,7 @@ The ContentHandler facility is introduced in a way that should allow all existin
Most importantly, the following functions have been deprecated:
* `Revisions::getText()` is deprecated in favor of `Revisions::getContent()`
* `Revision::getText()` was deprecated in favor of `Revision::getContent()` (though the Revision class was later fully removed as part of the migration to Multi-Content Revisions (MCR), see [documentation of mediawiki.org][mediawiki.org/wiki/Multi-Content_Revisions].
* `WikiPage::getText()` is deprecated in favor of `WikiPage::getContent()`
Also, the old `Article::getContent()` (which returns text) is superceded by `Article::getContentObject()`. However, both methods should be avoided since they do not provide clean access to the page's actual content. For instance, they may return a system message for non-existing pages. Use `WikiPage::getContent()` instead.
@ -78,9 +79,9 @@ For rendering page content, `Content::getParserOutput()` should be used instead
Besides some functions, some hooks have also been replaced by new versions (see hooks.txt for details). These hooks will now trigger a warning when used:
* `ArticleAfterFetchContent` was replaced by `ArticleAfterFetchContentObject`, later replaced by `ArticleRevisionViewCustom`
* `ArticleInsertComplete` was replaced by `PageContentInsertComplete`
* `ArticleInsertComplete` was replaced by `PageContentInsertComplete`, later replaced by `PageSaveComplete`
* `ArticleSave` was replaced by `PageContentSave`
* `ArticleSaveComplete` was replaced by `PageContentSaveComplete`
* `ArticleSaveComplete` was replaced by `PageContentSaveComplete`, later replaced by `PageSaveComplete`
* `ArticleViewCustom` was replaced by `ArticleContentViewCustom`, which was later removed entirely
* `EditFilterMerged` was replaced by `EditFilterMergedContent`
* `EditPageGetDiffText` was replaced by `EditPageGetDiffContent`
@ -89,7 +90,7 @@ Besides some functions, some hooks have also been replaced by new versions (see
## Database Storage
Page content is stored in the database using the same mechanism as before. Non-text content is serialized first. The appropriate serialization and deserialization is handled by the Revision class.
Page content is stored in the database using the same mechanism as before. Non-text content is serialized first.
Each revision's content model and serialization format is stored in the revision table (resp. in the archive table, if the revision was deleted). The page's (current) content model (that is, the content model of the latest revision) is also stored in the page table.

View File

@ -24,10 +24,10 @@ foreach ( $res as $row ) {
For a write query, use something like:
```php
$dbw = wfGetDB( DB_MASTER );
$dbw = wfGetDB( DB_PRIMARY );
$dbw->insert( /* ...see docs... */ );
```
We use the convention `$dbr` for read and `$dbw` for write to help you keep track of whether the database object is a replica (read-only) or a master (read/write). If you write to a replica, the world will explode. Or to be precise, a subsequent write query which succeeded on the master may fail when propagated to the replica due to a unique key collision. Replication will then stop and it may take hours to repair the database and get it back online. Setting `read_only` in `my.cnf` on the replica will avoid this scenario, but given the dire consequences, we prefer to have as many checks as possible.
We use the convention `$dbr` for read and `$dbw` for write to help you keep track of whether the database object is a replica (read-only) or a primary (read/write). If you write to a replica, the world will explode. Or to be precise, a subsequent write query which succeeded on the primary may fail when propagated to the replica due to a unique key collision. Replication will then stop and it may take hours to repair the database and get it back online. Setting `read_only` in `my.cnf` on the replica will avoid this scenario, but given the dire consequences, we prefer to have as many checks as possible.
We provide a `query()` function for raw SQL, but the wrapper functions like `select()` and `insert()` are usually more convenient. They take care of things like table prefixes and escaping for you. If you really need to make your own SQL, please read the documentation for `tableName()` and `addQuotes()`. You will need both of them.
@ -38,19 +38,19 @@ MediaWiki developers who need to write DB queries should have some understanding
## Replication
The largest installation of MediaWiki, Wikimedia, uses a large set of replica MySQL servers replicating writes made to a master MySQL server. It is important to understand the issues associated with this setup if you want to write code destined for Wikipedia.
The largest installation of MediaWiki, Wikimedia, uses a large set of replica MySQL servers replicating writes made to a primary MySQL server. It is important to understand the issues associated with this setup if you want to write code destined for Wikipedia.
It's often the case that the best algorithm to use for a given task depends on whether or not replication is in use. Due to our unabashed Wikipedia-centrism, we often just use the replication-friendly version, but if you like, you can use `LoadBalancer::getServerCount() > 1` to check to see if replication is in use.
## Lag
Lag primarily occurs when large write queries are sent to the master. Writes on the master are executed in parallel, but they are executed in serial when they are replicated to the replicas. The master writes the query to the binlog when the transaction is committed. The replicas poll the binlog and start executing the query as soon as it appears. They can service reads while they are performing a write query, but will not read anything more from the binlog and thus will perform no more writes. This means that if the write query runs for a long time, the replicas will lag behind the master for the time it takes for the write query to complete.
Lag primarily occurs when large write queries are sent to the primary. Writes on the primary are executed in parallel, but they are executed in serial when they are replicated to the replicas. The primary writes the query to the binlog when the transaction is committed. The replicas poll the binlog and start executing the query as soon as it appears. They can service reads while they are performing a write query, but will not read anything more from the binlog and thus will perform no more writes. This means that if the write query runs for a long time, the replicas will lag behind the primary for the time it takes for the write query to complete.
Lag can be exacerbated by high read load. MediaWiki's load balancer will stop sending reads to a replica when it is lagged by more than 30 seconds. If the load ratios are set incorrectly, or if there is too much load generally, this may lead to a replica permanently hovering around 30 seconds lag.
If all replicas are lagged by more than 30 seconds, MediaWiki will stop writing to the database. All edits and other write operations will be refused, with an error returned to the user. This gives the replicas a chance to catch up. Before we had this mechanism, the replicas would regularly lag by several minutes, making review of recent edits difficult.
In addition to this, MediaWiki attempts to ensure that the user sees events occurring on the wiki in chronological order. A few seconds of lag can be tolerated, as long as the user sees a consistent picture from subsequent requests. This is done by saving the master binlog position in the session, and then at the start of each request, waiting for the replica to catch up to that position before doing any reads from it. If this wait times out, reads are allowed anyway, but the request is considered to be in "lagged replica mode". Lagged replica mode can be checked by calling `LoadBalancer::getLaggedReplicaMode()`. The only practical consequence at present is a warning displayed in the page footer.
In addition to this, MediaWiki attempts to ensure that the user sees events occurring on the wiki in chronological order. A few seconds of lag can be tolerated, as long as the user sees a consistent picture from subsequent requests. This is done by saving the primary binlog position in the session, and then at the start of each request, waiting for the replica to catch up to that position before doing any reads from it. If this wait times out, reads are allowed anyway, but the request is considered to be in "lagged replica mode". Lagged replica mode can be checked by calling `LoadBalancer::getLaggedReplicaMode()`. The only practical consequence at present is a warning displayed in the page footer.
## Lag avoidance
@ -58,14 +58,14 @@ To avoid excessive lag, queries which write large numbers of rows should be spli
## Working with lag
Despite our best efforts, it's not practical to guarantee a low-lag environment. Lag will usually be less than one second, but may occasionally be up to 30 seconds. For scalability, it's very important to keep load on the master low, so simply sending all your queries to the master is not the answer. So when you have a genuine need for up-to-date data, the following approach is advised:
Despite our best efforts, it's not practical to guarantee a low-lag environment. Lag will usually be less than one second, but may occasionally be up to 30 seconds. For scalability, it's very important to keep load on the primary low, so simply sending all your queries to the masprimaryter is not the answer. So when you have a genuine need for up-to-date data, the following approach is advised:
1) Do a quick query to the master for a sequence number or timestamp
1) Do a quick query to the primary for a sequence number or timestamp
2) Run the full query on the replica and check if it matches the data you got
from the master
3) If it doesn't, run the full query on the master
from the primary
3) If it doesn't, run the full query on the primary
To avoid swamping the master every time the replicas lag, use of this approach should be kept to a minimum. In most cases you should just read from the replica and let the user deal with the delay.
To avoid swamping the primary every time the replicas lag, use of this approach should be kept to a minimum. In most cases you should just read from the replica and let the user deal with the delay.
## Lock contention
@ -74,7 +74,7 @@ Due to the high write rate on Wikipedia (and some other wikis), MediaWiki develo
Often this approach is not good enough, and it becomes necessary to enclose small groups of queries in their own transaction. Use the following syntax:
```php
$dbw = wfGetDB( DB_MASTER );
$dbw = wfGetDB( DB_PRIMARY );
$dbw->begin( __METHOD__ );
/* Do queries */
$dbw->commit( __METHOD__ );
@ -86,7 +86,7 @@ Instead of locking reads, combine your existence checks into your write queries,
## Query groups
MediaWiki supports database query groups, a way to indicate a preferred group of database hosts to use for a given query. Query groups are only supported for connections to child (non-master) databases, making them only viable for read operations. It should be noted that using query groups does not _guarantee_ a given group of hosts will be used, but rather that the query prefers such group. Making use of query groups can be benficial in many cases.
MediaWiki supports database query groups, a way to indicate a preferred group of database hosts to use for a given query. Query groups are only supported for connections to child (non-primary) databases, making them only viable for read operations. It should be noted that using query groups does not _guarantee_ a given group of hosts will be used, but rather that the query prefers such group. Making use of query groups can be benficial in many cases.
One benefit is a reduction of cache misses. Directing reads for a category of queries (e.g. all logging queries) to a given host can result in more deterministic and faster performing queries.

View File

@ -5,7 +5,10 @@
"additionalProperties": false,
"patternProperties": {
"^@": {
"type": "string",
"type": [
"string",
"array"
],
"description": "Arbitrary notes, ignored by the parser."
}
},
@ -987,6 +990,18 @@
"type": "object",
"additionalProperties": false,
"properties": {
"localBasePath": {
"type": "string",
"description": "Base path to prepend to all local paths, relative to current directory"
},
"remoteExtPath": {
"type": "string",
"description": "Base path to prepend to all remote paths, relative to $wgExtensionAssetsPath"
},
"remoteSkinPath": {
"type": "string",
"description": "Base path to prepend to all remote paths, relative to $wgStylePath"
},
"scripts": {
"type": "string",
"description": "Path to script file."

View File

@ -63,7 +63,7 @@ To start the daemon manually, use something like:
memcached -d -l 127.0.0.1 -p 11211 -m 64
(to run in daemon mode, accessible only via loopback interface,
on port 11211, using up to 64MB of memory)
on port 11211, using up to 64 MiB of memory)
In your LocalSettings.php file, set:

View File

@ -61,7 +61,7 @@ $specialPageAliases['bcl'] = [
'CategoryTree' => [ 'KahoyNinKategorya' ],
];
/** Belarusian (Taraškievica orthography) (беларуская (тарашкевіца)) */
/** Belarusian (Taraškievica orthography) (беларуская (тарашкевіца)) */
$specialPageAliases['be-tarask'] = [
'CategoryTree' => [ рэваатэгорыяў' ],
];
@ -501,17 +501,17 @@ $specialPageAliases['yi'] = [
'CategoryTree' => [ 'קאטעגאריע_בוים' ],
];
/** Simplified Chinese (中文(简体)) */
/** Simplified Chinese (中文(简体)) */
$specialPageAliases['zh-hans'] = [
'CategoryTree' => [ '分类树' ],
];
/** Traditional Chinese (中文(繁體)) */
/** Traditional Chinese (中文(繁體)) */
$specialPageAliases['zh-hant'] = [
'CategoryTree' => [ '分類樹' ],
];
/** Chinese (Taiwan) (中文(台灣)) */
/** Chinese (Taiwan) (中文(台灣)) */
$specialPageAliases['zh-tw'] = [
'CategoryTree' => [ '分類樹' ],
];

View File

@ -126,7 +126,7 @@ $magicWords['ko'] = [
'categorytree' => [ 0, '분류트리' ],
];
/** Kurdish (Latin script) (Kurdî (latînî)) */
/** Kurdish (Latin script) (Kurdî (latînî)) */
$magicWords['ku-latn'] = [
'categorytree' => [ 0, 'dara_kategoriyan' ],
];
@ -197,12 +197,12 @@ $magicWords['ru'] = [
'categorytree' => [ 0, 'деревокатегорий' ],
];
/** Serbian (Cyrillic script) (српски (ћирилица)) */
/** Serbian (Cyrillic script) (српски (ћирилица)) */
$magicWords['sr-ec'] = [
'categorytree' => [ 0, 'стаблокатегорије', 'стаблоатегорије' ],
];
/** Serbian (Latin script) (srpski (latinica)) */
/** Serbian (Latin script) (srpski (latinica)) */
$magicWords['sr-el'] = [
'categorytree' => [ 0, 'stablokategorije', 'stablo_kategorije' ],
];
@ -252,12 +252,12 @@ $magicWords['yi'] = [
'categorytree' => [ 0, 'קאטעגאריע_בוים' ],
];
/** Simplified Chinese (中文(简体)) */
/** Simplified Chinese (中文(简体)) */
$magicWords['zh-hans'] = [
'categorytree' => [ 0, '分类树' ],
];
/** Traditional Chinese (中文(繁體)) */
/** Traditional Chinese (中文(繁體)) */
$magicWords['zh-hant'] = [
'categorytree' => [ 0, '分類樹' ],
];

View File

@ -1,10 +1,10 @@
{
"require-dev": {
"mediawiki/mediawiki-codesniffer": "35.0.0",
"mediawiki/mediawiki-phan-config": "0.10.6",
"mediawiki/mediawiki-codesniffer": "37.0.0",
"mediawiki/mediawiki-phan-config": "0.11.0",
"mediawiki/minus-x": "1.1.1",
"php-parallel-lint/php-console-highlighter": "0.5.0",
"php-parallel-lint/php-parallel-lint": "1.2.0"
"php-parallel-lint/php-parallel-lint": "1.3.1"
},
"scripts": {
"fix": [

View File

@ -6,24 +6,21 @@
"license-name": "GPL-2.0-or-later",
"type": "parserhook",
"requires": {
"MediaWiki": ">= 1.35.0"
"MediaWiki": ">= 1.37.0"
},
"ConfigRegistry": {
"categorytree": "GlobalVarConfig::newInstance"
},
"ExtensionFunctions": [
"CategoryTreeHooks::initialize"
],
"SpecialPages": {
"CategoryTree": {
"class": "CategoryTreePage",
"class": "MediaWiki\\Extension\\CategoryTree\\CategoryTreePage",
"services": [
"SearchEngineFactory"
]
}
},
"APIModules": {
"categorytree": "ApiCategoryTree"
"categorytree": "MediaWiki\\Extension\\CategoryTree\\ApiCategoryTree"
},
"MessagesDirs": {
"CategoryTree": [
@ -35,15 +32,8 @@
"CategoryTreeAlias": "CategoryTree.alias.php",
"CategoryTreeMagic": "CategoryTree.i18n.magic.php"
},
"AutoloadClasses": {
"CategoryTreePage": "includes/CategoryTreePage.php",
"CategoryTree": "includes/CategoryTree.php",
"CategoryTreeCategoryPage": "includes/CategoryTreeCategoryPage.php",
"CategoryTreeCategoryViewer": "includes/CategoryTreeCategoryViewer.php",
"CategoryTreeHooks": "includes/CategoryTreeHooks.php",
"CategoryTreeMode": "includes/CategoryTreeMode.php",
"CategoryTreeHidePrefix": "includes/CategoryTreeHidePrefix.php",
"ApiCategoryTree": "includes/ApiCategoryTree.php"
"AutoloadNamespaces": {
"MediaWiki\\Extension\\CategoryTree\\": "includes/"
},
"ResourceModules": {
"ext.categoryTree": {
@ -54,7 +44,7 @@
"ext.categoryTree.js",
{
"name": "data.json",
"callback": "CategoryTreeHooks::getDataForJs"
"callback": "MediaWiki\\Extension\\CategoryTree\\Hooks::getDataForJs"
}
],
"targets": [
@ -64,8 +54,6 @@
"messages": [
"categorytree-collapse",
"categorytree-expand",
"categorytree-collapse-bullet",
"categorytree-expand-bullet",
"categorytree-load",
"categorytree-loading",
"categorytree-nothing-found",
@ -91,16 +79,25 @@
"localBasePath": "modules",
"remoteExtPath": "CategoryTree/modules"
},
"HookHandlers": {
"default": {
"class": "MediaWiki\\Extension\\CategoryTree\\Hooks",
"services": [ "DBLoadBalancer", "MainConfig" ]
},
"config": {
"class": "MediaWiki\\Extension\\CategoryTree\\ConfigHookHandler"
}
},
"Hooks": {
"ArticleFromTitle": "CategoryTreeHooks::articleFromTitle",
"SpecialTrackingCategories::preprocess": "CategoryTreeHooks::onSpecialTrackingCategoriesPreprocess",
"SpecialTrackingCategories::generateCatLink": "CategoryTreeHooks::onSpecialTrackingCategoriesGenerateCatLink",
"SkinBuildSidebar": "CategoryTreeHooks::onSkinBuildSidebar",
"ParserFirstCallInit": "CategoryTreeHooks::setHooks",
"OutputPageMakeCategoryLinks": "CategoryTreeHooks::outputPageMakeCategoryLinks",
"BeforePageDisplay": "CategoryTreeHooks::addHeaders",
"BeforePageDisplayMobile": "CategoryTreeHooks::addHeaders",
"OutputPageParserOutput": "CategoryTreeHooks::parserOutput"
"MediaWikiServices": "config",
"ArticleFromTitle": "default",
"SpecialTrackingCategories::preprocess": "default",
"SpecialTrackingCategories::generateCatLink": "default",
"SkinAfterPortlet": "default",
"SkinBuildSidebar": "default",
"ParserFirstCallInit": "default",
"OutputPageMakeCategoryLinks": "default",
"OutputPageParserOutput": "default"
},
"config": {
"CategoryTreeMaxChildren": {
@ -120,9 +117,6 @@
},
"merge_strategy": "array_plus"
},
"CategoryTreeForceHeaders": {
"value": false
},
"CategoryTreeSidebarRoot": {
"value": null
},

View File

@ -1,8 +0,0 @@
{
"@metadata": {
"authors": [
"Csisc"
]
},
"categorytree-expand": "Wassiģ"
}

View File

@ -25,8 +25,6 @@
"categorytree-mode-all": "كل الصفحات",
"categorytree-collapse": "اطو",
"categorytree-expand": "فرد",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "يحتوي على {{PLURAL:$1|1 تصنيف فرعي واحد|تصنيفين فرعيين|$1 تصنيفات فرعية|$1 تصنيف فرعي}} و{{PLURAL:$2| صفحة واحدة|صفحتين|$2 صفحات|$2 صفحة}}، و {{PLURAL:$3| ملف واحد|ملفين|$3 ملفات|$3 ملفاً|$3 ملف}}",
"categorytree-num-categories": "$1 ت",
"categorytree-num-pages": " $1 ص",

View File

@ -14,8 +14,6 @@
"categorytree-mode-all": "ܟܠ ܦܐܬܬ̈ܐ",
"categorytree-collapse": "ܐܟܪܟ",
"categorytree-expand": "ܐܪܘܚ",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "ܚܒܫ ܥܠ {{PLURAL:$1|1 ܣܕܪܐ ܦܪܥܝܐ|$1 ܣܕܪ̈ ܦܪ̈ܥܝܐ}}، {{PLURAL:$2|1 ܦܐܬܐ|$2 ܦܐܬܬ̈ܐ}}، ܘ{{PLURAL:$3|1 ܠܦܦܐ|$3 ܠܦܦ̈ܐ}}",
"categorytree-num-categories": "$1 ܣ",
"categorytree-num-pages": " $1 ܦ",

View File

@ -19,8 +19,6 @@
"categorytree-mode-all": "كل الصفحات",
"categorytree-collapse": "اضغط",
"categorytree-expand": "اتوسع",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "فيه {{PLURAL:$1|1 تصنيف فرعي|$1 تصنيف فرعي}}، {{PLURAL:$2|1 صفحة|$2 صفحة}}، و {{PLURAL:$3|1 ملف|$3 ملف}}",
"categorytree-num-categories": "$1 ت",
"categorytree-num-pages": " $1 ص",

View File

@ -3,11 +3,11 @@
"authors": [
"Cekli829",
"Dağlı95",
"PPerviz",
"Vugar 1981",
"Wertuose",
"NMW03",
"Toghrul Rahimli"
"PPerviz",
"Toghrul Rahimli",
"Vugar 1981",
"Wertuose"
]
},
"categorytree": "Kateqoriya ağacı",

View File

@ -23,8 +23,6 @@
"categorytree-mode-all": "بوتون صفحه‌لر",
"categorytree-collapse": "گیزلت",
"categorytree-expand": "گئنیشلندیر",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "{{PLURAL:$1|1 آلت بولمه|$1 آلت بولمه}}، {{PLURAL:$2|1 صفحه|$2 صفحه}}، و {{PLURAL:$3|1 فایل|$3 فایل}} واریدیر",
"categorytree-num-categories": "$1 ب",
"categorytree-num-pages": "$1 ص",

View File

@ -20,8 +20,6 @@
"categorytree-mode-all": "موچین دیمان",
"categorytree-collapse": "سقوط",
"categorytree-expand": "پچ",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "شامل چه {{PLURAL:$1|یک چیررده|$1 چیررده}}، {{PLURAL:$2|یک تاک|$2 تاک}} ءُ {{PLURAL:$3|یک فایل|$3 فایل انت}}",
"categorytree-num-categories": "$1 س",
"categorytree-num-pages": "$1 پ",

View File

@ -1,8 +0,0 @@
{
"@metadata": {
"authors": [
"Fanjiayi"
]
},
"categorytree-member-counts": "Contains {{PLURAL:$1|1 subcategory|$1 subcategories}}, {{PLURAL:$2|1 pej|$2 pejs}}, and {{PLURAL:$3|1 file|$3 files}}"
}

View File

@ -1,9 +0,0 @@
{
"@metadata": {
"authors": [
"Fanjiayi"
]
},
"categorytree-num-pages": "$1 P",
"categorytree-num-files": "$1 L"
}

View File

@ -1,12 +0,0 @@
{
"@metadata": {
"authors": [
"Aandeginini"
]
},
"categorytree-expand": "Ozhitoon mangadeyaa",
"categorytree-member-counts": "Biindig {{PLURAL:$1|1 subcategory|$1 anaamayi'ii-niibiwa-mazina'igan}}, {{PLURAL:$2|1 page|$2 mazina'igan}}, gaye {{PLURAL:$3|1 file|$3 niibiwa-mazina'igan}}",
"categorytree-num-categories": "$1 G",
"categorytree-num-pages": "$1 M",
"categorytree-num-files": "$1 NM"
}

View File

@ -20,8 +20,6 @@
"categorytree-mode-all": "ھەموو پەڕەکان",
"categorytree-collapse": "کۆیبکەوە",
"categorytree-expand": "بڵاویبکەوە",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "{{PLURAL:$1|یەک ژێرپۆل|$1 ژێرپۆل}}، {{PLURAL:$2|یەک پەڕە|$2 پەڕە}}، and {{PLURAL:$3|یەک پەڕگە|$3 پەڕگە}} لەبەردەگرێتەوە",
"categorytree-num-categories": "$1 پۆل",
"categorytree-num-pages": "$1 پەڕە",

View File

@ -1,11 +1,11 @@
{
"@metadata": {
"authors": [
"Alhassan Mohammed Awal",
"Amire80",
"Chirifo",
"Dnshitobu",
"Shahadusadik",
"Alhassan Mohammed Awal",
"Chirifo",
"Sir Amugi"
]
},

View File

@ -18,10 +18,6 @@
"categorytree-mode-all": "all pages",
"categorytree-collapse": "collapse",
"categorytree-expand": "expand",
"categorytree-collapse-bullet": "▼",
"categorytree-expand-bullet": "►",
"categorytree-empty-bullet": "►",
"categorytree-page-bullet": "&nbsp;",
"categorytree-member-counts": "Contains {{PLURAL:$1|1 subcategory|$1 subcategories}}, {{PLURAL:$2|1 page|$2 pages}}, and {{PLURAL:$3|1 file|$3 files}}",
"categorytree-member-num": "($5)",
"categorytree-num-categories": "$1 C",

View File

@ -1,12 +0,0 @@
{
"@metadata": {
"authors": [
"KATRINE1993"
]
},
"categorytree-expand": "expandir",
"categorytree-member-counts": "Contiene {{PLURAL:$1|1 subcategoria|$1 subcategorias}}, {{PLURAL:$2|1 pagina|$2 paginas}}, y {{PLURAL:$3|1 fichero|$3 ficheros}}",
"categorytree-num-categories": "$1 C",
"categorytree-num-pages": "$1 P",
"categorytree-num-files": "$1 F"
}

View File

@ -28,8 +28,6 @@
"categorytree-mode-all": "todas las páginas",
"categorytree-collapse": "contraer",
"categorytree-expand": "expandir",
"categorytree-expand-bullet": "►",
"categorytree-empty-bullet": "►",
"categorytree-member-counts": "Contiene {{PLURAL:$1|una subcategoría|$1 subcategorías}}, {{PLURAL:$2|una página|$2 páginas}} y {{PLURAL:$3|un archivo|$3 archivos}}",
"categorytree-num-categories": "$1 C",
"categorytree-num-pages": "$1 P",

View File

@ -5,11 +5,11 @@
"Ebraminio",
"Fatemi127",
"Huji",
"Jeeputer",
"Leyth",
"Mjbmr",
"Rtemis",
"ZxxZxxZ",
"Jeeputer"
"ZxxZxxZ"
]
},
"categorytree": "درخت رده",
@ -26,8 +26,6 @@
"categorytree-mode-all": "تمام صفحه‌ها",
"categorytree-collapse": "نهفتن",
"categorytree-expand": "گسترش",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "شامل {{PLURAL:$1|یک زیررده|$1 زیررده}}، {{PLURAL:$2|یک صفحه|$2 صفحه}} و {{PLURAL:$3|یک پرونده|$3 پرونده}} است",
"categorytree-num-categories": "$1 ر",
"categorytree-num-pages": "$1 ص",

View File

@ -1,7 +1,8 @@
{
"@metadata": {
"authors": [
"Ibrahima"
"Ibrahima",
"Ibrahima Malal Sarr"
]
},
"categorytree-expand": "yaajtinde",

View File

@ -30,8 +30,6 @@
"categorytree-mode-all": "toutes les pages",
"categorytree-collapse": "replier",
"categorytree-expand": "Développer",
"categorytree-expand-bullet": "►",
"categorytree-empty-bullet": "►",
"categorytree-member-counts": "contient $1 sous-catégorie{{PLURAL:$1||s}}, $2 page{{PLURAL:$2||s}} et $3 fichier{{PLURAL:$3||s}}",
"categorytree-num-categories": "$1C",
"categorytree-num-pages": "$1P",

View File

@ -19,8 +19,6 @@
"categorytree-mode-all": "a h-uile duilleag",
"categorytree-collapse": "co-theannaich",
"categorytree-expand": "leudaich",
"categorytree-expand-bullet": "►",
"categorytree-empty-bullet": "►",
"categorytree-member-counts": "Tha $1 {{PLURAL:$1|fho-roinn-seòrsa|fho-roinn-seòrsa|fo-roinnean-seòrsa|fo-roinn-seòrsa}}, $2 {{PLURAL:$2|duilleag|dhuilleag|duilleagan|duilleag}} 's $3 {{PLURAL:$3|fhaidhle|fhaidhle|faidhlichean|faidhle}} 'na broinn",
"categorytree-num-categories": "$1 R-S",
"categorytree-num-pages": "$1 D",

View File

@ -1,9 +0,0 @@
{
"@metadata": {
"authors": [
"Fanjiayi"
]
},
"categorytree-num-categories": "$1 N",
"categorytree-num-pages": "$1 P"
}

View File

@ -20,8 +20,6 @@
"categorytree-mode-all": "כל הדפים",
"categorytree-collapse": "כיווץ",
"categorytree-expand": "הרחבה",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "מכילה {{PLURAL:$1|קטגוריית־משנה אחת|$1 קטגוריות־משנה}}, {{PLURAL:$2|דף אחד|$2 דפים}}, ו{{PLURAL:$3|קובץ אחד|־$3 קבצים}}",
"categorytree-num-categories": "{{PLURAL:$1|קט' אחת|$1 קט'}}",
"categorytree-num-pages": "{{PLURAL:$1|דף אחד|$1 דפים}}",

View File

@ -24,8 +24,6 @@
"categorytree-mode-all": "sve stranice",
"categorytree-collapse": "sklopi",
"categorytree-expand": "raširi",
"categorytree-expand-bullet": "►",
"categorytree-empty-bullet": "►",
"categorytree-member-counts": "sadrži {{PLURAL:$1|1 potkategoriju|$1 potkategorije|$1 potkategorija}}, {{PLURAL:$2|1 stranicu|$2 stranice|$2 stranica}} i {{PLURAL:$3|1 datoteku|$3 datoteke|$3 datoteka}}",
"categorytree-num-categories": "$1 kat.",
"categorytree-num-pages": "$1 str.",

View File

@ -20,8 +20,6 @@
"categorytree-mode-all": "allar síður",
"categorytree-collapse": "fela",
"categorytree-expand": "sýna",
"categorytree-expand-bullet": "►",
"categorytree-empty-bullet": "►",
"categorytree-member-counts": "Inniheldur $1 {{PLURAL:$1|undirflokk|undirflokka}}, $2 {{PLURAL:$2|síðu|síður}}, og $3 {{PLURAL:$3|mynd|myndir}}",
"categorytree-num-categories": "$1 F",
"categorytree-num-pages": "$1 S",

View File

@ -27,7 +27,6 @@
"categorytree-mode-all": "すべてのページ",
"categorytree-collapse": "折り畳む",
"categorytree-expand": "展開する",
"categorytree-empty-bullet": "►",
"categorytree-member-counts": "{{PLURAL:$1|下位カテゴリ $1 件}}、{{PLURAL:$2|ページ $2 件}}、{{PLURAL:$3|ファイル $3 件}}を含んでいます",
"categorytree-num-categories": "$1カテゴリ",
"categorytree-num-pages": "$1頁",

View File

@ -6,8 +6,6 @@
},
"categorytree-category": "زٲژ:",
"categorytree-expand": "پُھہلاوُن",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-num-categories": "$1 ز",
"categorytree-num-pages": "$1 ص",
"categorytree-num-files": "$1 ف"

View File

@ -19,7 +19,6 @@
"categorytree-mode-all": "alles: nomahl Sigge, Saachjroppe, un Mehdije",
"categorytree-collapse": "zosammefallde",
"categorytree-expand": "opfallde",
"categorytree-empty-bullet": "►",
"categorytree-member-counts": "do dren {{PLURAL:$1|{{PLURAL:$4|sin|es|es}} ein Ungerjrupp|sin $1 Ungerjruppe|es kein Ungerjrupp}}, {{PLURAL:$2|ein Sigg|$2 Sigge|kein Sigg}}, un {{PLURAL:$3|ein Datei|$3 Dateie|kein Dateie}}, zosamme {{PLURAL:$4|ein Saach|$4 Saache|och nix}}",
"categorytree-num-categories": "$1&nbsp;J",
"categorytree-num-pages": "$1&nbsp;S",

View File

@ -23,8 +23,6 @@
"categorytree-mode-all": "visi puslapiai",
"categorytree-collapse": "suskleisti",
"categorytree-expand": "išskleisti",
"categorytree-expand-bullet": "►",
"categorytree-empty-bullet": "►",
"categorytree-member-counts": "turi $1 {{PLURAL:$1|subkategoriją|subkategorijas|subkategorijų}}, $2 {{PLURAL:$2|puslapį|puslapius|puslapių}}, ir $3 {{PLURAL:$3|rinkmeną|rinkmenas|rinkmenų}}",
"categorytree-num-categories": "$1 C",
"categorytree-num-pages": "$1 P",

View File

@ -20,7 +20,6 @@
"categorytree-mode-all": "сите страници",
"categorytree-collapse": "собери",
"categorytree-expand": "отвори",
"categorytree-empty-bullet": "[<b>×</b>]",
"categorytree-member-counts": "содржи {{PLURAL:$1|една поткатегорија|$1 поткатегории}}, {{PLURAL:$2|една страница|$2 страници}} и {{PLURAL:$3|една податотека|$3 податотеки}}",
"categorytree-num-categories": "$1 К",
"categorytree-num-pages": "$1 С",

View File

@ -1,8 +0,0 @@
{
"@metadata": {
"authors": [
"Fanjiayi"
]
},
"categorytree-num-pages": "$1 P"
}

View File

@ -1,8 +0,0 @@
{
"@metadata": {
"authors": [
"Fanjiayi"
]
},
"categorytree-num-pages": "$1 P"
}

View File

@ -1,7 +1,6 @@
{
"@metadata": {
"authors": [
"Siebrand",
"McDutchie"
]
},

View File

@ -4,9 +4,9 @@
"Huhbakker",
"Kippenvlees1",
"Mainframe98",
"Nickthijssen1994",
"SPQRobin",
"Siebrand",
"Nickthijssen1994"
"Siebrand"
]
},
"categorytree": "Categorieboom",

View File

@ -1,11 +1,12 @@
{
"@metadata": {
"authors": [
"Fanjiayi",
"MinecraftAustralia"
]
},
"categorytree-expand": "meik biga",
"categorytree-member-counts": "Konteins {{PLURAL:$1|1 subcategory|$1 subcategories}}, {{PLURAL:$2|1 paij|$2 paijs}}, an {{PLURAL:$3|1 file|$3 files}}",
"categorytree-num-categories": "$1 K",
"categorytree-num-pages": "$1 P",
"categorytree-num-files": "$1 F"
}

View File

@ -18,8 +18,6 @@
"categorytree-mode-all": "سارے صفحے",
"categorytree-collapse": "مک گیا",
"categorytree-expand": "ودھاؤ",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "ایہدے وچ {{PLURAL:$1|1 نکی گٹھ|$1 گٹھاں}}, {{PLURAL:$2|1 صفحہ|$2 صفحے}}, تے {{PLURAL:$3|1 فائل|$3 فائلاں}} ہیگیاں نیں۔",
"categorytree-num-categories": "$1 سی",
"categorytree-num-pages": "$1 پی",

View File

@ -15,8 +15,6 @@
"categorytree-mode-all": "ټول مخونه",
"categorytree-collapse": "پرځول",
"categorytree-expand": "غځول",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "{{PLURAL:$1|1 څېرمه وېشنيزه|$1 څېرمه وېشنيزې}}، {{PLURAL:$2|1 مخ|$2 مخونه}} او {{PLURAL:$3|1 دوتنه|$3 دوتنې}} لري",
"categorytree-num-categories": "$1 و",
"categorytree-num-pages": "$1 م",

View File

@ -25,8 +25,6 @@
"categorytree-mode-all": "todas as páginas",
"categorytree-collapse": "recolher",
"categorytree-expand": "expandir",
"categorytree-expand-bullet": "►",
"categorytree-empty-bullet": "►",
"categorytree-member-counts": "Possui {{PLURAL:$1|1 subcategoria|$1 subcategorias}}, {{PLURAL:$2|1 página|$2 páginas}} e {{PLURAL:$3|1 arquivo|$3 arquivos}}",
"categorytree-num-categories": "$1 C",
"categorytree-num-pages": "$1 P",

View File

@ -37,10 +37,6 @@
"categorytree-mode-all": "Item for the mode choice on [[Special:CategoryTree]], indicating that all pages are listed.\n\n{{Identical|All pages}}",
"categorytree-collapse": "Tooltip for the \"collapse\" button.\n{{Identical|Collapse}}",
"categorytree-expand": "Tooltip for the \"expand\" button.\n{{Identical|Expand}}",
"categorytree-collapse-bullet": "{{notranslate}}",
"categorytree-expand-bullet": "For right-to-left scripts, set this message to the single character ◄ . Otherwise, do not translate this message. Does not support wiki-syntax, html or entity references. \n{{optional}}",
"categorytree-empty-bullet": "{{optional}}\nPrefix used before category names in category pages when the number of subcategories (or something) is 0, to indicate that there is no sub-tree of items to expand. Does not support wiki-syntax, html or entity references.",
"categorytree-page-bullet": "{{notranslate}}",
"categorytree-member-counts": "Tooltip showing a detailed summary of subcategory member counts. Parameters:\n* $1 - number of subcategories\n* $2 - number of pages (without subcategories and files)\n* $3 - number of files\n* $4 - (Unused) total number of members\n* $5 - (Unused) members to be shown in the tree, depending on mode\nUse with <nowiki>{{PLURAL}}</nowiki>",
"categorytree-member-num": "{{notranslate}}\nHowever, if needed, you can localise the parentheses.\n\n(From https://www.mediawiki.org/wiki/Extension:CategoryTree#categorytree-member-num):\nBy default, when listing subcategories on a category page, each subcategory is followed by an integer indicating how many subcategories lie beneath it:\n<pre>\nMy category name (5)\n</pre>\nYou can change this behavior by overriding this system message. Parameters:\n* $1 - (Unused) number of subcategories\n* $2 - (Unused) number of articles (not including category pages or file pages)\n* $3 - (Unused) number of uploaded files\n* $4 - (Unused) total number of member pages, including category pages and file pages\n* $5 - (Varies depending on CategoryTree mode....Can someone describe it?)\n\nTip: Use the ParserFunctions extension (https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions) to provide if/then/else logic to display different parts conditionally. For example:\n<pre>\n{{#ifeq:$1|0||$1 categories}}\n</pre>",
"categorytree-num-categories": "'''\"C\" is short for \"Category\".''' It must be as short as possible.\n\nNumber of sub-categories in a category. Appears in brackets after a name of an empty category.\n\nParameters:\n* $1 - number of sub-categories. Can be used for PLURAL.\n{{Related|Categorytree-num}}",

View File

@ -21,8 +21,6 @@
"categorytree-collapse": "ᱢᱩᱨᱪᱷᱟᱹᱣ ᱪᱟᱵᱟ",
"categorytree-expand": "ᱯᱷᱟᱭᱞᱟᱣ",
"categorytree-member-counts": "Contains {{PLURAL:$1|1 ᱥᱟᱵ ᱠᱮᱴᱟᱜᱳᱨᱤ|$1 ᱥᱟᱵ ᱠᱮᱴᱟᱜᱳᱨᱤᱥ}}, {{PLURAL:$2|1 ᱥᱟᱦᱴᱟ|$2 ᱥᱟᱦᱴᱟᱠᱩ}}, and {{PLURAL:$3|1 ᱯᱷᱟᱭᱤᱞ|$3 ᱯᱷᱟᱭᱤᱞᱥ}}",
"categorytree-num-categories": "$1 C",
"categorytree-num-pages": "$1 P",
"categorytree-num-files": "$1 ᱮᱯᱷ",
"categorytree-num-empty": "ᱠᱷᱟᱹᱞᱤᱜᱮᱭᱟ",
"categorytree-load": "ᱞᱟᱫᱮ",

View File

@ -1,11 +1,11 @@
{
"@metadata": {
"authors": [
"1233qwer1234qwer4",
"Aushulz",
"C.R.",
"Pippinu",
"Santu",
"1233qwer1234qwer4",
"Ajeje Brazorf"
]
},
@ -23,8 +23,6 @@
"categorytree-mode-all": "tutti li pàggini",
"categorytree-collapse": "cumprimi",
"categorytree-expand": "spanni",
"categorytree-expand-bullet": "[<b>+</b>]",
"categorytree-empty-bullet": "[<b>×</b>]",
"categorytree-member-counts": "cunteni {{PLURAL:$1|1 suttacatigurìa|$1 suttacatigurìi}}, {{PLURAL:$2|1 pàggina|$2 pàggini}} e {{PLURAL:$3|1 file|$3 file}}",
"categorytree-num-categories": "$1 C",
"categorytree-num-pages": "$1 P",

View File

@ -2,10 +2,10 @@
"@metadata": {
"authors": [
"Acamicamacaraca",
"BadDog",
"Kolega2357",
"OC Ripper",
"Vlad5250",
"BadDog"
"Vlad5250"
]
},
"categorytree": "Stablasti prikaz hijerarhije kategorija",

View File

@ -1,8 +0,0 @@
{
"@metadata": {
"authors": [
"Fanjiayi"
]
},
"categorytree-num-pages": "$1 P"
}

View File

@ -21,8 +21,6 @@
"categorytree-mode-all": "lahat ng mga pahina",
"categorytree-collapse": "tiklupin",
"categorytree-expand": "palawakin",
"categorytree-expand-bullet": "►",
"categorytree-empty-bullet": "►",
"categorytree-member-counts": "Naglalaman ng {{PLURAL:$1|1 subkategorya|$1 (na) subkategorya}}, {{PLURAL:$2|1 pahina|$2 (na) pahina}}, at {{PLURAL:$3|1 file|$3 (na) file}}",
"categorytree-num-categories": "$1 ka.",
"categorytree-num-pages": "$1 pa.",

View File

@ -20,9 +20,9 @@
"categorytree-collapse": "burmə kardey",
"categorytree-expand": "һовуж карде",
"categorytree-member-counts": "Дыләдә һестыше{{PLURAL:$1|1 жинә тиспир|$1 жинә тиспир}}, {{PLURAL:$2|1 сәһифә|$2 сәһифә}}, ијән{{PLURAL:$3|1 фајл|$3 фајл}}",
"categorytree-num-categories": "$1 К",
"categorytree-num-pages": "$1 С",
"categorytree-num-files": "$1 Ф",
"categorytree-num-categories": "$1 K",
"categorytree-num-pages": "$1 S",
"categorytree-num-files": "$1 F",
"categorytree-num-empty": "təy",
"categorytree-load": "әловә карде",
"categorytree-loading": "әловә кардејдә...",

View File

@ -1,7 +1,8 @@
{
"@metadata": {
"authors": [
"Fanjiayi"
"Fanjiayi",
"Weather Top Wizard"
]
},
"categorytree": "Fuʻuʻakau faʻahinga",
@ -9,5 +10,7 @@
"categorytree-go": "ʻAsi mai",
"categorytree-collapse": "holo",
"categorytree-expand": "fano",
"categorytree-num-pages": "$1 P"
"categorytree-num-categories": "$1 F",
"categorytree-num-pages": "$1 P",
"categorytree-num-files": "$1 Fa"
}

View File

@ -18,8 +18,6 @@
"categorytree-mode-all": "ھەممە بەتلەر",
"categorytree-collapse": "قاتلا",
"categorytree-expand": "ياي",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "{{PLURAL:$1|1 تارماق تۈر|$1 تارماق تۈر}}, {{PLURAL:$2|1 بەت|$2 بەت}} ۋە {{PLURAL:$3|1 ھۆججەت|$3 ھۆججەت}} نى ئۆز ئىچىگە ئالىدۇ",
"categorytree-num-categories": "$1 تۈر",
"categorytree-num-pages": "$1 بەت",

View File

@ -4,6 +4,7 @@
"AS",
"Ahonc",
"Base",
"DDPAT",
"Piramidion",
"Sodmy",
"Ата"

View File

@ -22,8 +22,6 @@
"categorytree-mode-all": "تمام صفحات",
"categorytree-collapse": "چھپائیں",
"categorytree-expand": "وسیع کریں",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "اس میں {{PLURAL:$1|1 ذیلی زمرہ|$1 ذیلی زمرہ جات}}، {{PLURAL:$2|1 صفحہ|$2 صفحات}} اور {{PLURAL:$3|1 فائل|$3 فائلیں}} موجود ہیں/ہے۔",
"categorytree-num-categories": "$1 ز",
"categorytree-num-pages": "$1 ص",

View File

@ -2,8 +2,8 @@
"@metadata": {
"authors": [
"Abdulla",
"Sociologist",
"Malikxan"
"Malikxan",
"Sociologist"
]
},
"categorytree": "Turkum daraxti",

View File

@ -1,8 +1,8 @@
{
"@metadata": {
"authors": [
"Amire80",
"Gildo Máquina"
"Gildo Máquina",
"Amire80"
]
},
"categorytree-expand": "omwarexela okina",

View File

@ -18,8 +18,6 @@
"categorytree-mode-all": "אַלע בלעטער",
"categorytree-collapse": "אײַנציען",
"categorytree-expand": "פֿאַרברייטערן",
"categorytree-expand-bullet": "◄",
"categorytree-empty-bullet": "◄",
"categorytree-member-counts": "אנטהאלט {{PLURAL:$1|1 אונטערקאטעגאריע|$1 אונטערקאטעגאריעס}}, {{PLURAL:$2|1 בלאט|$2 בלעטער}}, און {{PLURAL:$3|1 טעקע|$3 טעקעס}}",
"categorytree-num-categories": "$1 קאַט",
"categorytree-num-pages": "$1 ב",

View File

@ -2,9 +2,9 @@
"@metadata": {
"authors": [
"Amara-Amaziɣ",
"Brahim-essaidi",
"Mdb897",
"YesIn",
"Brahim-essaidi"
"YesIn"
]
},
"categorytree-expand": "ⴼⵙⵉ",

View File

@ -1,6 +1,12 @@
<?php
namespace MediaWiki\Extension\CategoryTree;
use ApiBase;
use Config;
use FormatJson;
use MediaWiki\MediaWikiServices;
use Title;
/**
* This program is free software; you can redistribute it and/or modify
@ -44,7 +50,6 @@ class ApiCategoryTree extends ApiBase {
$ct = new CategoryTree( $options );
$depth = CategoryTree::capDepth( $ct->getOption( 'mode' ), $depth );
$ctConfig = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'categorytree' );
// @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141
$html = $this->getHTML( $ct, $title, $depth, $ctConfig );
$this->getMain()->setCacheMode( 'public' );
@ -95,7 +100,7 @@ class ApiCategoryTree extends ApiBase {
$ctConfig->get( 'RenderHashAppend' )
),
$cache::TTL_DAY,
function () use ( $ct, $title, $depth ) {
static function () use ( $ct, $title, $depth ) {
return trim( $ct->renderChildren( $title, $depth ) );
},
[

View File

@ -21,8 +21,23 @@
* @ingroup Extensions
* @author Daniel Kinzler, brightbyte.de
*/
namespace MediaWiki\Extension\CategoryTree;
use Category;
use Exception;
use ExtensionRegistry;
use FormatJson;
use Html;
use IContextSource;
use LinkBatch;
use MediaWiki\Linker\LinkRenderer;
use MediaWiki\MediaWikiServices;
use OutputPage;
use Parser;
use RequestContext;
use SpecialPage;
use Title;
/**
* Core functions for the CategoryTree extension, an AJAX based gadget
@ -317,7 +332,7 @@ class CategoryTree {
}
/**
* Custom tag implementation. This is called by CategoryTreeHooks::parserHook, which is used to
* Custom tag implementation. This is called by Hooks::parserHook, which is used to
* load CategoryTreeFunctions.php on demand.
* @param ?Parser $parser
* @param string $category
@ -360,29 +375,21 @@ class CategoryTree {
$attr['data-ct-mode'] = $this->mOptions['mode'];
$attr['data-ct-options'] = $this->getOptionsAsJsStructure();
$html = '';
$html .= Html::openElement( 'div', $attr );
if ( !$allowMissing && !$title->getArticleID() ) {
$html .= Html::openElement( 'span', [ 'class' => 'CategoryTreeNotice' ] );
if ( $parser ) {
$html .= $parser->recursiveTagParse(
wfMessage( 'categorytree-not-found', $category )->plain() );
} else {
$html .= wfMessage( 'categorytree-not-found', $category )->parse();
}
$html .= Html::closeElement( 'span' );
$html = Html::rawElement( 'span', [ 'class' => 'CategoryTreeNotice' ],
wfMessage( 'categorytree-not-found' )
->plaintextParams( $category )
->parse()
);
} else {
if ( !$hideroot ) {
$html .= $this->renderNode( $title, $depth );
$html = $this->renderNode( $title, $depth );
} else {
$html .= $this->renderChildren( $title, $depth );
$html = $this->renderChildren( $title, $depth );
}
}
$html .= Xml::closeElement( 'div' );
return $html;
return Html::rawElement( 'div', $attr, $html );
}
/**
@ -538,26 +545,22 @@ class CategoryTree {
$special = SpecialPage::getTitleFor( 'CategoryTree' );
$s = '';
$s = [];
foreach ( $res as $row ) {
$t = Title::makeTitle( NS_CATEGORY, $row->cl_to );
if ( $s !== '' ) {
$s .= wfMessage( 'pipe-separator' )->escaped();
}
$s .= Xml::openElement( 'span', [ 'class' => 'CategoryTreeItem' ] );
$s .= $this->linkRenderer->makeLink(
$special,
$t->getText(),
[ 'class' => 'CategoryTreeLabel' ],
[ 'target' => $t->getDBkey() ] + $this->mOptions
$s[] = Html::rawElement( 'span', [ 'class' => 'CategoryTreeItem' ],
$this->linkRenderer->makeLink(
$special,
$t->getText(),
[ 'class' => 'CategoryTreeLabel' ],
[ 'target' => $t->getDBkey() ] + $this->mOptions
)
);
$s .= Xml::closeElement( 'span' );
}
return $s;
return implode( wfMessage( 'pipe-separator' )->escaped(), $s );
}
/**
@ -624,8 +627,8 @@ class CategoryTree {
# Specifically, the CategoryTreeChildren div must be the first
# sibling with nodeName = DIV of the grandparent of the expland link.
$s .= Xml::openElement( 'div', [ 'class' => 'CategoryTreeSection' ] );
$s .= Xml::openElement( 'div', [ 'class' => 'CategoryTreeItem' ] );
$s .= Html::openElement( 'div', [ 'class' => 'CategoryTreeSection' ] );
$s .= Html::openElement( 'div', [ 'class' => 'CategoryTreeItem' ] );
$attr = [ 'class' => 'CategoryTreeBullet' ];
@ -640,7 +643,7 @@ class CategoryTree {
}
}
if ( $count === 0 ) {
$bullet = wfMessage( 'categorytree-empty-bullet' )->escaped() . ' ';
$bullet = '';
$attr['class'] = 'CategoryTreeEmptyBullet';
} else {
$linkattr = [];
@ -649,23 +652,19 @@ class CategoryTree {
$linkattr['data-ct-title'] = $key;
if ( $children == 0 ) {
// Use ->plain() to ensure identical result as JS,
// which does:
// $link.text( mw.msg( 'categorytree-expand-bullet' ) );
$txt = wfMessage( 'categorytree-expand-bullet' )->plain();
$linkattr[ 'data-ct-state' ] = 'collapsed';
} else {
$txt = wfMessage( 'categorytree-collapse-bullet' )->plain();
$linkattr[ 'data-ct-loaded' ] = true;
$linkattr[ 'data-ct-state' ] = 'expanded';
}
$bullet = Html::element( 'span', $linkattr, $txt ) . ' ';
$bullet = Html::element( 'span', $linkattr ) . ' ';
}
} else {
$bullet = wfMessage( 'categorytree-page-bullet' )->escaped();
$bullet = '';
$attr['class'] = 'CategoryTreePageBullet';
}
$s .= Xml::tags( 'span', $attr, $bullet ) . ' ';
$s .= Html::rawElement( 'span', $attr, $bullet ) . ' ';
$s .= $link;
@ -673,8 +672,8 @@ class CategoryTree {
$s .= self::createCountString( RequestContext::getMain(), $cat, $count );
}
$s .= Xml::closeElement( 'div' );
$s .= Xml::openElement(
$s .= Html::closeElement( 'div' );
$s .= Html::openElement(
'div',
[
'class' => 'CategoryTreeChildren',
@ -685,23 +684,28 @@ class CategoryTree {
if ( $ns == NS_CATEGORY && $children > 0 ) {
$children = $this->renderChildren( $title, $children );
if ( $children == '' ) {
$s .= Xml::openElement( 'i', [ 'class' => 'CategoryTreeNotice' ] );
if ( $mode == CategoryTreeMode::CATEGORIES ) {
$s .= wfMessage( 'categorytree-no-subcategories' )->escaped();
} elseif ( $mode == CategoryTreeMode::PAGES ) {
$s .= wfMessage( 'categorytree-no-pages' )->escaped();
} elseif ( $mode == CategoryTreeMode::PARENTS ) {
$s .= wfMessage( 'categorytree-no-parent-categories' )->escaped();
} else {
$s .= wfMessage( 'categorytree-nothing-found' )->escaped();
switch ( $mode ) {
case CategoryTreeMode::CATEGORIES:
$msg = 'categorytree-no-subcategories';
break;
case CategoryTreeMode::PAGES:
$msg = 'categorytree-no-pages';
break;
case CategoryTreeMode::PARENTS:
$msg = 'categorytree-no-parent-categories';
break;
default:
$msg = 'categorytree-nothing-found';
break;
}
$s .= Xml::closeElement( 'i' );
} else {
$s .= $children;
$children = Html::element( 'i', [ 'class' => 'CategoryTreeNotice' ],
wfMessage( $msg )->text()
);
}
$s .= $children;
}
$s .= Xml::closeElement( 'div' ) . Xml::closeElement( 'div' );
$s .= Html::closeElement( 'div' ) . Html::closeElement( 'div' );
return $s;
}
@ -752,7 +756,7 @@ class CategoryTree {
# Only $5 is actually used in the default message.
# Other arguments can be used in a customized message.
$s .= Xml::tags(
$s .= Html::rawElement(
'span',
$attr,
$context->msg( 'categorytree-member-num' )
@ -770,9 +774,9 @@ class CategoryTree {
* @return null|Title
*/
public static function makeTitle( $title ) {
$title = trim( $title );
$title = trim( strval( $title ) );
if ( strval( $title ) === '' ) {
if ( $title === '' ) {
return null;
}
@ -790,7 +794,6 @@ class CategoryTree {
/**
* Internal function to cap depth
* @suppress PhanPluginDuplicateConditionalNullCoalescing until PHP7 is required
* @param string $mode
* @param int $depth
* @return int|mixed
@ -798,14 +801,14 @@ class CategoryTree {
public static function capDepth( $mode, $depth ) {
global $wgCategoryTreeMaxDepth;
if ( is_numeric( $depth ) ) {
$depth = intval( $depth );
} else {
if ( !is_numeric( $depth ) ) {
return 1;
}
$depth = intval( $depth );
if ( is_array( $wgCategoryTreeMaxDepth ) ) {
$max = isset( $wgCategoryTreeMaxDepth[$mode] ) ? $wgCategoryTreeMaxDepth[$mode] : 1;
$max = $wgCategoryTreeMaxDepth[$mode] ?? 1;
} elseif ( is_numeric( $wgCategoryTreeMaxDepth ) ) {
$max = $wgCategoryTreeMaxDepth;
} else {

View File

@ -18,6 +18,10 @@
* @file
*/
namespace MediaWiki\Extension\CategoryTree;
use CategoryPage;
class CategoryTreeCategoryPage extends CategoryPage {
public $mCategoryViewerClass = CategoryTreeCategoryViewer::class;
}

View File

@ -18,6 +18,11 @@
* @file
*/
namespace MediaWiki\Extension\CategoryTree;
use Category;
use CategoryViewer;
class CategoryTreeCategoryViewer extends CategoryViewer {
public $child_cats;
@ -31,11 +36,16 @@ class CategoryTreeCategoryViewer extends CategoryViewer {
*/
private function getCategoryTree() {
if ( !isset( $this->categorytree ) ) {
if ( !CategoryTreeHooks::shouldForceHeaders() ) {
CategoryTree::setHeaders( $this->getOutput() );
CategoryTree::setHeaders( $this->getOutput() );
$options = $this->getConfig()->get( 'CategoryTreeCategoryPageOptions' );
$mode = $this->getRequest()->getVal( 'mode' );
if ( $mode !== null ) {
$options['mode'] = CategoryTree::decodeMode( $mode );
}
$this->categorytree = new CategoryTree( $this->getConfig()->get( 'CategoryTreeCategoryPageOptions' ) );
$this->categorytree = new CategoryTree( $options );
}
return $this->categorytree;

View File

@ -22,6 +22,8 @@
* @author Daniel Kinzler, brightbyte.de
*/
namespace MediaWiki\Extension\CategoryTree;
/**
* Constants for use with the hideprefix option,
* defining when the namespace prefix should be hidden.

View File

@ -1,324 +0,0 @@
<?php
/**
* © 2006-2008 Daniel Kinzler and others
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Extensions
* @author Daniel Kinzler, brightbyte.de
*/
/**
* Hooks for the CategoryTree extension, an AJAX based gadget
* to display the category structure of a wiki
*/
class CategoryTreeHooks {
private const EXTENSION_DATA_FLAG = 'CategoryTree';
/**
* @internal For use by CategoryTreeCategoryViewer and CategoryTreePage only!
* @return bool
*/
public static function shouldForceHeaders() {
global $wgCategoryTreeForceHeaders;
return $wgCategoryTreeForceHeaders;
}
/**
* Adjusts config once MediaWiki is fully initialised
* TODO: Don't do this, lazy initialize the config
*/
public static function initialize() {
global $wgRequest;
global $wgCategoryTreeDefaultOptions, $wgCategoryTreeDefaultMode;
global $wgCategoryTreeCategoryPageOptions, $wgCategoryTreeCategoryPageMode;
global $wgCategoryTreeOmitNamespace;
if ( !isset( $wgCategoryTreeDefaultOptions['mode'] )
|| $wgCategoryTreeDefaultOptions['mode'] === null
) {
$wgCategoryTreeDefaultOptions['mode'] = $wgCategoryTreeDefaultMode;
}
if ( !isset( $wgCategoryTreeDefaultOptions['hideprefix'] )
|| $wgCategoryTreeDefaultOptions['hideprefix'] === null
) {
$wgCategoryTreeDefaultOptions['hideprefix'] = $wgCategoryTreeOmitNamespace;
}
if ( !isset( $wgCategoryTreeCategoryPageOptions['mode'] )
|| $wgCategoryTreeCategoryPageOptions['mode'] === null
) {
$mode = $wgRequest->getVal( 'mode' );
$wgCategoryTreeCategoryPageOptions['mode'] = ( $mode )
? CategoryTree::decodeMode( $mode ) : $wgCategoryTreeCategoryPageMode;
}
}
/**
* @param Parser $parser
*/
public static function setHooks( Parser $parser ) {
global $wgCategoryTreeAllowTag;
if ( !$wgCategoryTreeAllowTag ) {
return;
}
$parser->setHook( 'categorytree', 'CategoryTreeHooks::parserHook' );
$parser->setFunctionHook( 'categorytree', 'CategoryTreeHooks::parserFunction' );
}
/**
* Entry point for the {{#categorytree}} tag parser function.
* This is a wrapper around CategoryTreeHooks::parserHook
* @param Parser $parser
* @param string ...$params
* @return array|string
*/
public static function parserFunction( Parser $parser, ...$params ) {
// first user-supplied parameter must be category name
if ( !$params ) {
// no category specified, return nothing
return '';
}
$cat = array_shift( $params );
// build associative arguments from flat parameter list
$argv = [];
foreach ( $params as $p ) {
if ( preg_match( '/^\s*(\S.*?)\s*=\s*(.*?)\s*$/', $p, $m ) ) {
$k = $m[1];
// strip any quotes enclusing the value
$v = preg_replace( '/^"\s*(.*?)\s*"$/', '$1', $m[2] );
} else {
$k = trim( $p );
$v = true;
}
$argv[$k] = $v;
}
if ( $parser->getOutputType() === Parser::OT_PREPROCESS ) {
return Html::openElement( 'categorytree', $argv ) .
$cat . Html::closeElement( 'categorytree' );
} else {
// now handle just like a <categorytree> tag
$html = self::parserHook( $cat, $argv, $parser );
return [ $html, 'noparse' => true, 'isHTML' => true ];
}
}
/**
* Hook implementation for injecting a category tree into the sidebar.
* Only does anything if $wgCategoryTreeSidebarRoot is set to a category name.
* @param Skin $skin
* @param array &$sidebar
*/
public static function onSkinBuildSidebar( Skin $skin, array &$sidebar ) {
global $wgCategoryTreeSidebarRoot, $wgCategoryTreeSidebarOptions;
if ( !$wgCategoryTreeSidebarRoot ) {
return;
}
$html = self::parserHook( $wgCategoryTreeSidebarRoot, $wgCategoryTreeSidebarOptions );
if ( $html ) {
$sidebar['categorytree-portlet'] = $html;
CategoryTree::setHeaders( $skin->getOutput() );
}
}
/**
* Entry point for the <categorytree> tag parser hook.
* This loads CategoryTreeFunctions.php and calls CategoryTree::getTag()
* @param string $cat
* @param array $argv
* @param Parser|null $parser
* @param PPFrame|null $frame
* @param bool $allowMissing
* @return bool|string
*/
public static function parserHook(
$cat,
array $argv,
Parser $parser = null,
PPFrame $frame = null,
$allowMissing = false
) {
if ( $parser ) {
# flag for use by CategoryTreeHooks::parserOutput
$parser->getOutput()->setExtensionData( self::EXTENSION_DATA_FLAG, true );
}
$ct = new CategoryTree( $argv );
$attr = Sanitizer::validateTagAttributes( $argv, 'div' );
$hideroot = isset( $argv['hideroot'] )
? CategoryTree::decodeBoolean( $argv['hideroot'] ) : null;
$onlyroot = isset( $argv['onlyroot'] )
? CategoryTree::decodeBoolean( $argv['onlyroot'] ) : null;
$depthArg = isset( $argv['depth'] ) ? (int)$argv['depth'] : null;
$depth = CategoryTree::capDepth( $ct->getOption( 'mode' ), $depthArg );
if ( $onlyroot ) {
$depth = 0;
}
return $ct->getTag( $parser, $cat, $hideroot, $attr, $depth, $allowMissing );
}
/**
* Hook callback that injects messages and things into the <head> tag,
* if needed in the current page.
* Does nothing if self::EXTENSION_DATA_FLAG is not set on $parserOutput extension data.
* @param OutputPage $outputPage
* @param ParserOutput $parserOutput
*/
public static function parserOutput( OutputPage $outputPage, ParserOutput $parserOutput ) {
if ( self::shouldForceHeaders() ) {
// Skip, we've already set the headers unconditionally
return;
}
if ( $parserOutput->getExtensionData( self::EXTENSION_DATA_FLAG ) ) {
CategoryTree::setHeaders( $outputPage );
}
}
/**
* BeforePageDisplay and BeforePageDisplayMobile hooks.
* These hooks are used when $wgCategoryTreeForceHeaders is set.
* Otherwise similar to CategoryTreeHooks::parserOutput.
* @param OutputPage $out
*/
public static function addHeaders( OutputPage $out ) {
if ( !self::shouldForceHeaders() ) {
return;
}
CategoryTree::setHeaders( $out );
}
/**
* ArticleFromTitle hook, override category page handling
*
* @param Title $title
* @param Article|null &$article Article (object) that will be returned
*/
public static function articleFromTitle( Title $title, Article &$article = null ) {
if ( $title->getNamespace() == NS_CATEGORY ) {
$article = new CategoryTreeCategoryPage( $title );
}
}
/**
* OutputPageMakeCategoryLinks hook, override category links
* @param OutputPage &$out
* @param array $categories
* @param array &$links
* @return bool
*/
public static function outputPageMakeCategoryLinks(
OutputPage &$out,
array $categories,
array &$links
) {
global $wgCategoryTreePageCategoryOptions, $wgCategoryTreeHijackPageCategories;
if ( !$wgCategoryTreeHijackPageCategories ) {
// Not enabled, don't do anything
return true;
}
foreach ( $categories as $category => $type ) {
$links[$type][] = self::parserHook( $category, $wgCategoryTreePageCategoryOptions, null, null, true );
}
CategoryTree::setHeaders( $out );
return false;
}
/**
* Get exported data for the "ext.categoryTree" ResourceLoader module.
*
* @internal For use in extension.json only.
* @return array Data to be serialised as data.json
*/
public static function getDataForJs() {
global $wgCategoryTreeCategoryPageOptions;
// Look, this is pretty bad but CategoryTree is just whacky, it needs to be rewritten
$ct = new CategoryTree( $wgCategoryTreeCategoryPageOptions );
return [
'defaultCtOptions' => $ct->getOptionsAsJsStructure(),
];
}
/**
* Hook handler for the SpecialTrackingCategories::preprocess hook
* @suppress PhanUndeclaredProperty SpecialPage->categoryTreeCategories
* @param SpecialPage $specialPage SpecialTrackingCategories object
* @param array $trackingCategories [ 'msg' => Title, 'cats' => Title[] ]
* @phan-param array<string,array{msg:Title,cats:Title[]}> $trackingCategories
*/
public static function onSpecialTrackingCategoriesPreprocess(
SpecialPage $specialPage, array $trackingCategories
) {
$categoryDbKeys = [];
foreach ( $trackingCategories as $catMsg => $data ) {
foreach ( $data['cats'] as $catTitle ) {
$categoryDbKeys[] = $catTitle->getDbKey();
}
}
$categories = [];
if ( $categoryDbKeys ) {
$dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'category',
[ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
[ 'cat_title' => array_unique( $categoryDbKeys ) ],
__METHOD__
);
foreach ( $res as $row ) {
$categories[$row->cat_title] = Category::newFromRow( $row );
}
}
$specialPage->categoryTreeCategories = $categories;
}
/**
* Hook handler for the SpecialTrackingCategories::generateCatLink hook
* @suppress PhanUndeclaredProperty SpecialPage->categoryTreeCategories
* @param SpecialPage $specialPage SpecialTrackingCategories object
* @param Title $catTitle Title object of the linked category
* @param string &$html Result html
*/
public static function onSpecialTrackingCategoriesGenerateCatLink(
SpecialPage $specialPage, Title $catTitle, &$html
) {
if ( !isset( $specialPage->categoryTreeCategories ) ) {
return;
}
$cat = null;
if ( isset( $specialPage->categoryTreeCategories[$catTitle->getDbKey()] ) ) {
$cat = $specialPage->categoryTreeCategories[$catTitle->getDbKey()];
}
$html .= CategoryTree::createCountString( $specialPage->getContext(), $cat, 0 );
}
}

View File

@ -22,6 +22,8 @@
* @author Daniel Kinzler, brightbyte.de
*/
namespace MediaWiki\Extension\CategoryTree;
/**
* Constants for use with the mode, defining what should be shown in the tree.
*/

View File

@ -22,6 +22,14 @@
* @author Daniel Kinzler, brightbyte.de
*/
namespace MediaWiki\Extension\CategoryTree;
use Html;
use HTMLForm;
use SearchEngineFactory;
use SpecialPage;
use Title;
/**
* Special page for the CategoryTree extension, an AJAX based gadget
* to display the category structure of a wiki
@ -68,10 +76,10 @@ class CategoryTreePage extends SpecialPage {
$this->addHelpLink( 'Extension:CategoryTree' );
$request = $this->getRequest();
if ( $par ) {
$this->target = $par;
$this->target = trim( $par );
} else {
$this->target = $request->getVal( 'target' );
if ( $this->target === null ) {
$this->target = trim( $request->getVal( 'target', '' ) );
if ( $this->target === '' ) {
$rootcategory = $this->msg( 'rootcategory' );
if ( $rootcategory->exists() ) {
$this->target = $rootcategory->text();
@ -79,8 +87,6 @@ class CategoryTreePage extends SpecialPage {
}
}
$this->target = trim( $this->target );
$options = [];
$config = $this->getConfig();
@ -97,45 +103,12 @@ class CategoryTreePage extends SpecialPage {
$this->tree = new CategoryTree( $options );
$output = $this->getOutput();
$output->addWikiMsg( 'categorytree-header' );
$this->getOutput()->addWikiMsg( 'categorytree-header' );
$this->executeInputForm();
if ( $this->target !== '' && $this->target !== null ) {
if ( !CategoryTreeHooks::shouldForceHeaders() ) {
CategoryTree::setHeaders( $output );
}
$title = CategoryTree::makeTitle( $this->target );
if ( $title && $title->getArticleID() ) {
$output->addHTML( Xml::openElement( 'div', [ 'class' => 'CategoryTreeParents' ] ) );
$output->addHTML( $this->msg( 'categorytree-parents' )->parse() );
$output->addHTML( $this->msg( 'colon-separator' )->escaped() );
$parents = $this->tree->renderParents( $title );
if ( $parents == '' ) {
$output->addHTML( $this->msg( 'categorytree-no-parent-categories' )->parse() );
} else {
$output->addHTML( $parents );
}
$output->addHTML( Xml::closeElement( 'div' ) );
$output->addHTML( Xml::openElement( 'div', [
'class' => 'CategoryTreeResult CategoryTreeTag',
'data-ct-mode' => $this->tree->getOption( 'mode' ),
'data-ct-options' => $this->tree->getOptionsAsJsStructure(),
] ) );
$output->addHTML( $this->tree->renderNode( $title, 1 ) );
$output->addHTML( Xml::closeElement( 'div' ) );
} else {
$output->addHTML( Xml::openElement( 'div', [ 'class' => 'CategoryTreeNotice' ] ) );
$output->addHTML( $this->msg( 'categorytree-not-found', $this->target )->parse() );
$output->addHTML( Xml::closeElement( 'div' ) );
}
if ( $this->target !== '' ) {
$this->executeCategoryTree();
}
}
@ -192,6 +165,44 @@ class CategoryTreePage extends SpecialPage {
->displayForm( false );
}
/**
* Show the category tree
*/
private function executeCategoryTree() {
$output = $this->getOutput();
CategoryTree::setHeaders( $output );
$title = CategoryTree::makeTitle( $this->target );
if ( !$title || !$title->getArticleID() ) {
$output->addHTML( Html::rawElement( 'div', [ 'class' => 'CategoryTreeNotice' ],
$this->msg( 'categorytree-not-found' )
->plaintextParams( $this->target )
->parse()
) );
return;
}
$parents = $this->tree->renderParents( $title );
if ( $parents == '' ) {
$parents = $this->msg( 'categorytree-no-parent-categories' )->parse();
}
$output->addHTML( Html::rawElement( 'div', [ 'class' => 'CategoryTreeParents' ],
$this->msg( 'categorytree-parents' )->parse() .
$this->msg( 'colon-separator' )->escaped() .
$parents
) );
$output->addHTML( Html::rawElement( 'div',
[
'class' => 'CategoryTreeResult CategoryTreeTag',
'data-ct-mode' => $this->tree->getOption( 'mode' ),
'data-ct-options' => $this->tree->getOptionsAsJsStructure(),
],
$this->tree->renderNode( $title, 1 )
) );
}
/**
* Return an array of subpages beginning with $search that this special page will accept.
*
@ -216,7 +227,7 @@ class CategoryTreePage extends SpecialPage {
$searchEngine->setNamespaces( [ NS_CATEGORY ] );
$result = $searchEngine->defaultPrefixSearch( $search );
return array_map( function ( Title $t ) {
return array_map( static function ( Title $t ) {
// Remove namespace in search suggestion
return $t->getText();
}, $result );

View File

@ -0,0 +1,62 @@
<?php
/**
* © 2006-2008 Daniel Kinzler and others
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Extensions
* @author Daniel Kinzler, brightbyte.de
*/
namespace MediaWiki\Extension\CategoryTree;
use MediaWiki\Hook\MediaWikiServicesHook;
use MediaWiki\MediaWikiServices;
/**
* Hook handler for manipulating configuration.
*
* @note This hook runs before the service container is fully initialized, so it cannot have
* services injected. For this reason, it needs to be separate from the handlers for other
* hooks.
*/
class ConfigHookHandler implements MediaWikiServicesHook {
/**
* Adjusts config once MediaWiki is fully initialised
* TODO: Don't do this, lazy initialize the config
* @param MediaWikiServices $services
*/
public function onMediaWikiServices( $services ) {
global $wgCategoryTreeDefaultOptions, $wgCategoryTreeDefaultMode;
global $wgCategoryTreeCategoryPageOptions, $wgCategoryTreeCategoryPageMode;
global $wgCategoryTreeOmitNamespace;
if ( !isset( $wgCategoryTreeDefaultOptions['mode'] ) ) {
$wgCategoryTreeDefaultOptions['mode'] = $wgCategoryTreeDefaultMode;
}
if ( !isset( $wgCategoryTreeDefaultOptions['hideprefix'] ) ) {
$wgCategoryTreeDefaultOptions['hideprefix'] = $wgCategoryTreeOmitNamespace;
}
if ( !isset( $wgCategoryTreeCategoryPageOptions['mode'] ) ) {
$wgCategoryTreeCategoryPageOptions['mode'] = $wgCategoryTreeCategoryPageMode;
}
}
}

View File

@ -0,0 +1,337 @@
<?php
/**
* © 2006-2008 Daniel Kinzler and others
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Extensions
* @author Daniel Kinzler, brightbyte.de
*/
namespace MediaWiki\Extension\CategoryTree;
use Article;
use Category;
use Config;
use Html;
use IContextSource;
use MediaWiki\Hook\OutputPageMakeCategoryLinksHook;
use MediaWiki\Hook\OutputPageParserOutputHook;
use MediaWiki\Hook\ParserFirstCallInitHook;
use MediaWiki\Hook\SkinBuildSidebarHook;
use MediaWiki\Hook\SpecialTrackingCategories__generateCatLinkHook;
use MediaWiki\Hook\SpecialTrackingCategories__preprocessHook;
use MediaWiki\Page\Hook\ArticleFromTitleHook;
use OutputPage;
use Parser;
use ParserOutput;
use PPFrame;
use Sanitizer;
use Skin;
use SpecialPage;
use Title;
use Wikimedia\Rdbms\ILoadBalancer;
/**
* Hooks for the CategoryTree extension, an AJAX based gadget
* to display the category structure of a wiki
*
* @phpcs:disable MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName
*/
class Hooks implements
ArticleFromTitleHook,
SpecialTrackingCategories__preprocessHook,
SpecialTrackingCategories__generateCatLinkHook,
OutputPageParserOutputHook,
SkinBuildSidebarHook,
ParserFirstCallInitHook,
OutputPageMakeCategoryLinksHook
{
private const EXTENSION_DATA_FLAG = 'CategoryTree';
/** @var ILoadBalancer */
private $loadBalancer;
/**
* @var Config
*/
private $config;
/**
* @param ILoadBalancer $loadBalancer
* @param Config $config
*/
public function __construct( ILoadBalancer $loadBalancer, Config $config ) {
$this->loadBalancer = $loadBalancer;
$this->config = $config;
}
/**
* @param Parser $parser
*/
public function onParserFirstCallInit( $parser ) {
if ( !$this->config->get( 'CategoryTreeAllowTag' ) ) {
return;
}
$parser->setHook( 'categorytree', [ $this, 'parserHook' ] );
$parser->setFunctionHook( 'categorytree', [ $this, 'parserFunction' ] );
}
/**
* Entry point for the {{#categorytree}} tag parser function.
* This is a wrapper around Hooks::parserHook
* @param Parser $parser
* @param string ...$params
* @return array|string
*/
public function parserFunction( Parser $parser, ...$params ) {
// first user-supplied parameter must be category name
if ( !$params ) {
// no category specified, return nothing
return '';
}
$cat = array_shift( $params );
// build associative arguments from flat parameter list
$argv = [];
foreach ( $params as $p ) {
if ( preg_match( '/^\s*(\S.*?)\s*=\s*(.*?)\s*$/', $p, $m ) ) {
$k = $m[1];
// strip any quotes enclosing the value
$v = preg_replace( '/^"\s*(.*?)\s*"$/', '$1', $m[2] );
} else {
$k = trim( $p );
$v = true;
}
$argv[$k] = $v;
}
if ( $parser->getOutputType() === Parser::OT_PREPROCESS ) {
return Html::rawElement( 'categorytree', $argv, $cat );
} else {
// now handle just like a <categorytree> tag
$html = $this->parserHook( $cat, $argv, $parser );
return [ $html, 'noparse' => true, 'isHTML' => true ];
}
}
/**
* Obtain a category sidebar link based on config
* @return bool|string of link
*/
private function getCategorySidebarBox() {
global $wgCategoryTreeSidebarRoot, $wgCategoryTreeSidebarOptions;
if ( !$wgCategoryTreeSidebarRoot ) {
return false;
}
return self::parserHook( $wgCategoryTreeSidebarRoot, $wgCategoryTreeSidebarOptions );
}
/**
* Hook implementation for injecting a category tree into the sidebar.
* Only does anything if $wgCategoryTreeSidebarRoot is set to a category name.
* @param Skin $skin
* @param array &$sidebar
*/
public function onSkinBuildSidebar( $skin, &$sidebar ) {
$html = $this->getCategorySidebarBox();
if ( $html ) {
$sidebar['categorytree-portlet'] = [];
CategoryTree::setHeaders( $skin->getOutput() );
}
}
/**
* Hook implementation for injecting a category tree link into the sidebar.
* Only does anything if $wgCategoryTreeSidebarRoot is set to a category name.
* @param Skin $skin
* @param string $portlet
* @param string &$html
*/
public function onSkinAfterPortlet( $skin, $portlet, &$html ) {
if ( $portlet === 'categorytree-portlet' ) {
$box = $this->getCategorySidebarBox();
if ( $box ) {
$html .= $box;
}
}
}
/**
* Entry point for the <categorytree> tag parser hook.
* This loads CategoryTreeFunctions.php and calls CategoryTree::getTag()
* @param string $cat
* @param array $argv
* @param Parser|null $parser
* @param PPFrame|null $frame
* @param bool $allowMissing
* @return bool|string
*/
public function parserHook(
$cat,
array $argv,
Parser $parser = null,
PPFrame $frame = null,
$allowMissing = false
) {
if ( $parser ) {
# flag for use by Hooks::parserOutput
$parser->getOutput()->setExtensionData( self::EXTENSION_DATA_FLAG, true );
}
$ct = new CategoryTree( $argv );
$attr = Sanitizer::validateTagAttributes( $argv, 'div' );
$hideroot = isset( $argv['hideroot'] )
? CategoryTree::decodeBoolean( $argv['hideroot'] ) : null;
$onlyroot = isset( $argv['onlyroot'] )
? CategoryTree::decodeBoolean( $argv['onlyroot'] ) : null;
$depthArg = isset( $argv['depth'] ) ? (int)$argv['depth'] : null;
$depth = CategoryTree::capDepth( $ct->getOption( 'mode' ), $depthArg );
if ( $onlyroot ) {
$depth = 0;
}
return $ct->getTag( $parser, $cat, $hideroot, $attr, $depth, $allowMissing );
}
/**
* Hook callback that injects messages and things into the <head> tag,
* if needed in the current page.
* Does nothing if self::EXTENSION_DATA_FLAG is not set on $parserOutput extension data.
* @param OutputPage $outputPage
* @param ParserOutput $parserOutput
*/
public function onOutputPageParserOutput( $outputPage, $parserOutput ): void {
if ( $parserOutput->getExtensionData( self::EXTENSION_DATA_FLAG ) ) {
CategoryTree::setHeaders( $outputPage );
}
}
/**
* ArticleFromTitle hook, override category page handling
*
* @param Title $title
* @param Article|null &$article Article (object) that will be returned
* @param IContextSource $context
* @return bool|void True or no return value to continue or false to abort
*/
public function onArticleFromTitle( $title, &$article, $context ) {
if ( $title->getNamespace() == NS_CATEGORY ) {
$article = new CategoryTreeCategoryPage( $title );
}
}
/**
* OutputPageMakeCategoryLinks hook, override category links
* @param OutputPage $out
* @param array $categories
* @param array &$links
* @return bool
*/
public function onOutputPageMakeCategoryLinks( $out, $categories, &$links ) {
global $wgCategoryTreePageCategoryOptions, $wgCategoryTreeHijackPageCategories;
if ( !$wgCategoryTreeHijackPageCategories ) {
// Not enabled, don't do anything
return true;
}
foreach ( $categories as $category => $type ) {
$links[$type][] = $this->parserHook( $category, $wgCategoryTreePageCategoryOptions, null, null, true );
}
CategoryTree::setHeaders( $out );
return false;
}
/**
* Get exported data for the "ext.categoryTree" ResourceLoader module.
*
* @internal For use in extension.json only.
* @return array Data to be serialised as data.json
*/
public static function getDataForJs() {
global $wgCategoryTreeCategoryPageOptions;
// Look, this is pretty bad but CategoryTree is just whacky, it needs to be rewritten
$ct = new CategoryTree( $wgCategoryTreeCategoryPageOptions );
return [
'defaultCtOptions' => $ct->getOptionsAsJsStructure(),
];
}
/**
* Hook handler for the SpecialTrackingCategories::preprocess hook
* @suppress PhanUndeclaredProperty SpecialPage->categoryTreeCategories
* @param SpecialPage $specialPage SpecialTrackingCategories object
* @param array $trackingCategories [ 'msg' => Title, 'cats' => Title[] ]
* @phan-param array<string,array{msg:Title,cats:Title[]}> $trackingCategories
*/
public function onSpecialTrackingCategories__preprocess(
$specialPage,
$trackingCategories
) {
$categoryDbKeys = [];
foreach ( $trackingCategories as $catMsg => $data ) {
foreach ( $data['cats'] as $catTitle ) {
$categoryDbKeys[] = $catTitle->getDbKey();
}
}
$categories = [];
if ( $categoryDbKeys ) {
$dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
$res = $dbr->select(
'category',
[ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
[ 'cat_title' => array_unique( $categoryDbKeys ) ],
__METHOD__
);
foreach ( $res as $row ) {
$categories[$row->cat_title] = Category::newFromRow( $row );
}
}
$specialPage->categoryTreeCategories = $categories;
}
/**
* Hook handler for the SpecialTrackingCategories::generateCatLink hook
* @suppress PhanUndeclaredProperty SpecialPage->categoryTreeCategories
* @param SpecialPage $specialPage SpecialTrackingCategories object
* @param Title $catTitle Title object of the linked category
* @param string &$html Result html
*/
public function onSpecialTrackingCategories__generateCatLink( $specialPage,
$catTitle, &$html
) {
if ( !isset( $specialPage->categoryTreeCategories ) ) {
return;
}
$cat = null;
if ( isset( $specialPage->categoryTreeCategories[$catTitle->getDBkey()] ) ) {
$cat = $specialPage->categoryTreeCategories[$catTitle->getDBkey()];
}
$html .= CategoryTree::createCountString( $specialPage->getContext(), $cat, 0 );
}
}

View File

@ -23,11 +23,22 @@
* @author Daniel Kinzler, brightbyte.de
*/
/* On the list of subcategories hide the normal list bullet */
.client-js #mw-subcategories ul {
list-style: none none;
list-style: none;
}
/* and reduce the margin on the margin start side. */
/* @noflip */
.client-js #mw-subcategories .mw-content-ltr ul {
margin-left: 0.25em;
}
/* @noflip */
.client-js #mw-subcategories .mw-content-rtl ul {
margin-right: 0.25em;
}
#mw-panel .portal .body .CategoryTreeTag {
margin: 0;
font-size: 0.75em;
@ -38,10 +49,33 @@
padding: 0.25em 0;
}
/*
* Indent the children on each level on margin start side.
* A category tree in the sidebar is in user interface language therefor
* a flipped margin-left is the margin start side.
*/
.CategoryTreeChildren {
margin-left: 1.25em;
}
/*
* Category trees in the content are in content language and therefor
* an unflipped margin-left or margin-right is the margin start side.
* Use margin: 0 0 0 1.25em instead of margin-left: 1.25em here to
* overwrite the flipped margin-left from above.
*/
/* @noflip */
.mw-content-ltr .CategoryTreeChildren,
.mw-content-rtl .mw-content-ltr .CategoryTreeChildren {
margin: 0 0 0 1.25em;
}
/* @noflip */
.mw-content-rtl .CategoryTreeChildren,
.mw-content-ltr .mw-content-rtl .CategoryTreeChildren {
margin: 0 1.25em 0 0;
}
.CategoryTreeBullet,
.CategoryTreeEmptyBullet {
cursor: default;
@ -74,6 +108,50 @@
color: #0645ad;
}
.CategoryTreeEmptyBullet,
.CategoryTreeToggle,
.CategoryTreePageBullet {
display: inline-block;
width: 0;
height: 0;
}
.CategoryTreeEmptyBullet,
.CategoryTreeToggle[ data-ct-state='collapsed' ] {
border-top: 5px solid transparent;
border-left: 10px solid;
border-bottom: 5px solid transparent;
border-right: 0 none;
}
/* @noflip */
.mw-content-ltr .CategoryTreeEmptyBullet,
.mw-content-ltr .CategoryTreeToggle[ data-ct-state='collapsed' ],
.mw-content-rtl .mw-content-ltr .CategoryTreeEmptyBullet,
.mw-content-rtl .mw-content-ltr .CategoryTreeToggle[ data-ct-state='collapsed' ] {
border-left: 10px solid;
border-right: 0 none;
}
/* @noflip */
.mw-content-rtl .CategoryTreeEmptyBullet,
.mw-content-rtl .CategoryTreeToggle[ data-ct-state='collapsed' ],
.mw-content-ltr .mw-content-rtl .CategoryTreeEmptyBullet,
.mw-content-ltr .mw-content-rtl .CategoryTreeToggle[ data-ct-state='collapsed' ] {
border-right: 10px solid;
border-left: 0 none;
}
.CategoryTreeToggle[ data-ct-state='expanded' ] {
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 10px solid;
}
.CategoryTreePageBullet {
border-left: 10px solid transparent;
}
.CategoryTreeLabelPage {
font-style: italic;
}
@ -95,7 +173,3 @@
.CategoryTreeNotice {
font-style: italic;
}
.CategoryTreeSection {
direction: ltr;
}

View File

@ -19,13 +19,12 @@
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Extensions
* @author Daniel Kinzler, brightbyte.de
*/
( function () {
var loadChildren,
data = require( './data.json' );
config = require( './data.json' );
/**
* Expands a given node (loading it's children if not loaded)
@ -39,9 +38,8 @@
$children.show();
$link
.text( mw.msg( 'categorytree-collapse-bullet' ) )
.attr( 'title', mw.msg( 'categorytree-collapse' ) )
.data( 'ct-state', 'expanded' );
.attr( 'data-ct-state', 'expanded' );
if ( !$link.data( 'ct-loaded' ) ) {
loadChildren( $link, $children );
@ -59,19 +57,18 @@
.siblings( '.CategoryTreeChildren' ).hide();
$link
.text( mw.msg( 'categorytree-expand-bullet' ) )
.attr( 'title', mw.msg( 'categorytree-expand' ) )
.data( 'ct-state', 'collapsed' );
.attr( 'data-ct-state', 'collapsed' );
}
/**
* Handles clicks on the expand buttons, and calls the appropriate function
*
* @context {Element} CategoryTreeToggle
* @this {Element} CategoryTreeToggle
*/
function handleNode() {
var $link = $( this );
if ( $link.data( 'ct-state' ) === 'collapsed' ) {
if ( $link.attr( 'data-ct-state' ) === 'collapsed' ) {
expandNode( $link );
} else {
collapseNode( $link );
@ -88,7 +85,7 @@
.on( 'click', handleNode )
.attr( 'title', function () {
return mw.msg(
$( this ).data( 'ct-state' ) === 'collapsed' ?
$( this ).attr( 'data-ct-state' ) === 'collapsed' ?
'categorytree-expand' :
'categorytree-collapse'
);
@ -146,7 +143,7 @@
ctTitle = $link.attr( 'data-ct-title' );
ctMode = $linkParentCTTag.data( 'ct-mode' );
ctMode = typeof ctMode === 'number' ? ctMode : undefined;
ctOptions = $linkParentCTTag.attr( 'data-ct-options' ) || data.defaultCtOptions;
ctOptions = $linkParentCTTag.attr( 'data-ct-options' ) || config.defaultCtOptions;
// Mode and options have defaults or fallbacks, title does not.
// Don't make a request if there is no title.

View File

@ -1,10 +1,10 @@
{
"require-dev": {
"mediawiki/mediawiki-codesniffer": "35.0.0",
"mediawiki/mediawiki-phan-config": "0.10.6",
"mediawiki/mediawiki-codesniffer": "37.0.0",
"mediawiki/mediawiki-phan-config": "0.11.0",
"mediawiki/minus-x": "1.1.1",
"php-parallel-lint/php-console-highlighter": "0.5.0",
"php-parallel-lint/php-parallel-lint": "1.2.0"
"php-parallel-lint/php-parallel-lint": "1.3.1"
},
"scripts": {
"test": [

View File

@ -1,8 +1,9 @@
{
"@metadata": {
"authors": [
"Gazimagomedov"
"Gazimagomedov",
"Omarov M."
]
},
"cite_error": "Цитированиялъул гъалатӀ: $1"
"cite_error": "Цитатинабиялъул гъалатӀ: $1"
}

View File

@ -1,8 +1,8 @@
{
"@metadata": {
"authors": [
"NoiX180",
"Chinamoonroll"
"Chinamoonroll",
"NoiX180"
]
},
"cite_error": "Pikobet nganggit: $1",

View File

@ -1,8 +0,0 @@
{
"@metadata": {
"authors": [
"Aandeginini"
]
},
"cite_error": "Ondaadad wani: $1"
}

View File

@ -1,11 +0,0 @@
{
"@metadata": {
"authors": [
"Imre",
"Kghbln",
"Raimond Spekking"
]
},
"cite_error_ref_numeric_key": "Ungültige Verwendung von <code>&lt;ref&gt;</code>: Der Parameter „name“ darf kein reiner Zahlenwert sein. Benutzen Sie einen beschreibenden Namen.",
"cite_error_references_invalid_parameters": "Ungültige Verwendung von <code>&lt;references&gt;</code>: Es sind keine Parameter möglich. Verwenden Sie ausschließlich <code><nowiki><references /></nowiki></code>."
}

View File

@ -1,7 +1,8 @@
{
"@metadata": {
"authors": [
"Ibrahima"
"Ibrahima",
"Ibrahima Malal Sarr"
]
},
"cite_error": "Juumre jubbugol $1"

View File

@ -1,8 +0,0 @@
{
"@metadata": {
"authors": [
"Abdul Kadir"
]
},
"cite_error": "Cite error: $1"
}

View File

@ -6,9 +6,9 @@
"Dnik",
"MaGa",
"Neptune, the Mystic",
"Ponor",
"Roberta F.",
"SpeedyGonsales",
"Ponor"
"SpeedyGonsales"
]
},
"cite-desc": "Dodaje <code>&lt;ref[ name=id]&gt;</code> i <code>&lt;references/&gt;</code> oznake, za citiranje",

View File

@ -1,7 +1,6 @@
{
"@metadata": {
"authors": [
"Ukabia",
"Tochiprecious"
]
},

View File

@ -1,8 +0,0 @@
{
"@metadata": {
"authors": [
"Olwe519"
]
},
"apihelp-query+references-example-1": "lo se sitna pe <kbd>la .albert. .ainstain.</kbd>"
}

View File

@ -1,9 +0,0 @@
{
"@metadata": {
"authors": [
"គីមស៊្រុន",
"វ័ណថារិទ្ធ"
]
},
"cite-desc": "បន្ថែមស្លាក <code>&lt;ref[ name=id]&gt;</code> និង <code>&lt;references/&gt;</code> សម្រាប់ការយោង​ឯកសារ​"
}

View File

@ -15,11 +15,12 @@
},
"cite-desc": "인용에 쓰이는 <code>&lt;ref&gt;</code>와 <code>&lt;references&gt;</code> 태그를 추가합니다",
"cite_error": "인용 오류: $1",
"cite_error_ref_invalid_dir": "유효하지 않은 <code>&lt;ref&gt;</code> 태그입니다. dir \"$1\" 속성을 알 수 없습니다. ltr 또는 rtl이어야 합니다",
"cite_error_ref_numeric_key": "<code>&lt;ref&gt;</code> 태그가 잘못되었습니다;\n이름은 숫자가 될 수 없습니다. 설명적인 이름을 사용하세요",
"cite_error_ref_invalid_dir": "<code>dir=\"$1\"</code> 속성이 잘못되었습니다. <code>ltr</code> 또는 <code>rtl</code>이어야 합니다",
"cite_error_ref_numeric_key": "<code>&lt;ref&gt;</code> 태그가 잘못되었습니다; 이름은 숫자가 될 수 없습니다. 설명적인 이름을 사용하세요",
"cite_error_ref_no_key": "열린 <code>&lt;ref&gt;</code> 태그가 잘못 만들어졌거나 이름이 잘못되었습니다",
"cite_error_ref_too_many_keys": "<code>&lt;ref&gt;</code> 태그가 잘못되었습니다;\n잘못된 이름입니다, 너무 많은 등",
"cite_error_ref_no_input": "<code>&lt;ref&gt;</code> 태그가 잘못되었습니다;\n이름이 없는 ref 태그는 반드시 내용이 있어야 합니다",
"cite_error_ref_nested_extends": "<code>&lt;ref&gt;</code> 태그를 1단계 이상의 깊이로 확장할 수 없습니다.",
"cite_error_ref_no_input": "<code>&lt;ref&gt;</code> 태그가 잘못되었습니다; 이름이 없는 ref 태그는 반드시 내용이 있어야 합니다",
"cite_error_references_duplicate_key": "잘못된 <code>&lt;ref&gt;</code> 태그; \"$1\"이 다른 콘텐츠로 여러 번 정의되었습니다",
"cite_error_references_invalid_parameters": "<code>&lt;references&gt;</code> 태그 안의 변수가 잘못되었습니다",
"cite_error_references_no_backlink_label": "사용자 지정 백링크 라벨이 바닥이 났습니다. [[MediaWiki:Cite references link many format backlink labels]]메시지에 더 정의하세요.",

View File

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Noktonissian"
]
},
"cite_error": "ᩋ᩶ᩣ᩠ᨦᩋᩥ᩠ᨦᩉᩖᩩ: $1"
}

View File

@ -1,6 +0,0 @@
{
"@metadata": {
"authors": []
},
"cite_error": "Bitlaen so error $1; $2"
}

View File

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"MinecraftAustralia"
]
},
"cite_error": "Sait probl'm: $1"
}

View File

@ -9,10 +9,11 @@
"Sadrettin",
"Superyetkin",
"SwornToTranslate29",
"Vito Genovese"
"Vito Genovese",
"SaldırganSincap"
]
},
"cite-desc": "Alıntılar için, <code>&lt;ref&gt;</code> ve <code>&lt;references&gt;</code> etiketlerini ekler",
"cite-desc": "Kaynaklar için, <code>&lt;ref&gt;</code> ve <code>&lt;references&gt;</code> etiketlerini ekler",
"cite_error": "Kaynak hatası: $1",
"cite_error_ref_invalid_dir": "Geçersiz <code>dir=\"$1\"</code>, <code>ltr</code> veya <code>rtl</code> olmalıdır",
"cite_error_ref_numeric_key": "Geçersiz <code>&lt;ref&gt;</code> etiketi; isim basit bir tamsayı olamaz. Açıklayıcı bir başlık kullanın",
@ -22,17 +23,17 @@
"cite_error_ref_no_input": "Geçersiz <code>&lt;ref&gt;</code> etiketi; isimsiz ref içeriği olmalı",
"cite_error_references_duplicate_key": "Geçersiz <code>&lt;ref&gt;</code> etiketi: \"$1\" adı farklı içerikte birden fazla tanımlanmış",
"cite_error_references_invalid_parameters": "<code>&lt;references&gt;</code> etiketinde geçersiz parametre",
"cite_error_references_no_backlink_label": "Özel geri bağlantı etiketleri kalmadı. [[MediaWiki:Cite references link many format backlink labels]] mesajında daha fazla tanımlayın",
"cite_error_references_no_backlink_label": "Özel geri bağlantı etiketleri kalmadı. [[MediaWiki:Cite references link many format backlink labels]] mesajında daha fazla tanımlayın.",
"cite_error_no_link_label_group": "\"$1\" grubu için özel bağlantı etiketleri bitti. [[MediaWiki:$2]] mesajında daha fazla tanımlayın.",
"cite_error_references_no_text": "Geçersiz <code>&lt;ref&gt;</code> etiketi; <code>$1</code> isimli refler için metin temin edilmemiş",
"cite_error_references_no_text": "Geçersiz <code>&lt;ref&gt;</code> etiketi; <code>$1</code> isimli refler için metin sağlanmadı",
"cite_error_included_ref": "<code>&lt;ref&gt;</code> etiketi için <code>&lt;/ref&gt;</code> kapanışı eksik",
"cite_error_included_references": "<code>&lt;references&gt;</code> olmadığı için etiket kapatılıyor",
"cite_error_group_refs_without_references": "<code>&lt;ref&gt;</code> \"$1\" adında grup ana etiketi bulunuyor, ancak <code>&lt;references group=\"$1\"/&gt;</code> etiketinin karşılığı bulunamadı.",
"cite_error_included_references": "<code>&lt;references&gt;</code> için kapanış etiketi eksik",
"cite_error_group_refs_without_references": "<code>&lt;ref&gt;</code> \"$1\" adında grup ana etiketi bulunuyor, ancak <code>&lt;references group=\"$1\"/&gt;</code> etiketinin karşılığı bulunamadı",
"cite_error_references_group_mismatch": "<code>&lt;references&gt;</code> içinde <code>&lt;ref&gt;</code> etiketinin çelişen \"$1\" grup özniteliği var.",
"cite_error_references_missing_group": "<code>&lt;references&gt;</code> üzerinde tanımlanan <code>&lt;ref&gt;</code> etiketinin önceki metinde olmayan \"$1\" grup özniteliği var.",
"cite_error_references_missing_key": "<code>&lt;references&gt;</code> üzerinde tanımlanan \"$1\" adındaki <code>&lt;ref&gt;</code> etiketi önceki metinde kullanılmıyor.",
"cite_error_references_no_key": "<code>&lt;references&gt;</code>'da tanımlanan <code>&lt;ref&gt;</code> etiketinin hiçbir ad özniteliği yok.",
"cite_error_empty_references_define": "<code>&lt;references&gt;</code> üzerinde tanımlanan \"$1\" adlı <code>&lt;ref&gt;</code> etiketinin içeriği yok.",
"cite_error_references_no_key": "<code>&lt;references&gt;</code> içinde tanımlanan <code>&lt;ref&gt;</code> etiketinin hiçbir ad özniteliği yok.",
"cite_error_empty_references_define": "<code>&lt;references&gt;</code> inde tanımlanan \"$1\" adlı <code>&lt;ref&gt;</code> etiketinin içeriği yok.",
"cite-tracking-category-cite-error": "Kaynak gösterme hatası bulunan maddeler",
"cite-tracking-category-cite-error-desc": "Bu kategorideki maddelerde kaynak etiketinin kullanımında hata bulunmaktadır.",
"cite_references_link_accessibility_label": "Yukarı git",

View File

@ -4,14 +4,14 @@
"AS",
"Ahonc",
"Andriykopanytsia",
"DDPAT",
"Dim Grits",
"DixonD",
"NickK",
"Piramidion",
"Prima klasy4na",
"Ytsukeng Fyvaprol",
"Ата",
"DDPAT"
"Ата"
]
},
"cite-desc": "Додає теги <code>&lt;ref&gt;</code> і <code>&lt;references/&gt;</code> для виносок",

View File

@ -9,12 +9,12 @@
"Mywood",
"PhiLiP",
"Philip",
"Shizhao",
"TianyinLee",
"Zhuyifei1999",
"乌拉跨氪",
"列维劳德",
"沈澄心",
"Shizhao"
"沈澄心"
]
},
"cite-desc": "增加用于引用的<code>&lt;ref&gt;</code>和<code>&lt;references/&gt;</code>标签",

View File

@ -10,10 +10,11 @@
"Philip",
"Waihorace",
"Wbxshiori",
"乌拉跨氪"
"乌拉跨氪",
"Winston Sung"
]
},
"cite-desc": "添加用於引用的 <code>&lt;ref&gt;</code> 與 <code>&lt;references/&gt;</code> 標籤",
"cite-desc": "加入用於參考資料的 <code>&lt;ref&gt;</code> 與 <code>&lt;references/&gt;</code> 標籤",
"cite_error": "引用錯誤:$1",
"cite_error_ref_invalid_dir": "無效的 <code>dir=\"$1\"</code>,必須是 <code>ltr</code> 或 <code>rtl</code>",
"cite_error_ref_numeric_key": "無效的 <code>&lt;ref&gt;</code> 標籤name 屬性不能使用數字,請使用可描述內容的標題",

View File

@ -3,7 +3,8 @@
"authors": [
"Dibya Dutta",
"Gitartha.bordoloi",
"IKHazarika"
"IKHazarika",
"Simbu123"
]
},
"visualeditor-cite-tool-name-book": "কিতাপ",
@ -26,7 +27,7 @@
"cite-ve-dialog-referenceslist-title": "তথ্যসূত্ৰৰ তালিকা",
"cite-ve-dialogbutton-citation-educationpopup-text": "তথ্যৰ উৎস যোগ দি আপোনাৰ সমল উন্নত কৰে। আপুনি কিতাপ, বাতৰি কাকত আৰু ৱেবছাইটৰ উদ্ধৃতি দিব পাৰে।",
"cite-ve-dialogbutton-citation-educationpopup-title": "উদ্ধৃতিসমূহ",
"cite-ve-dialogbutton-reference-full-label": "প্ৰাথমিক ৰূপ",
"cite-ve-dialogbutton-reference-full-label": "সাধাৰণ",
"cite-ve-dialogbutton-reference-title": "তথ্যসংগ্ৰহ",
"cite-ve-dialogbutton-reference-tooltip": "সাধাৰণ",
"cite-ve-dialogbutton-referenceslist-tooltip": "তথ্যসূত্ৰৰ তালিকা",

Some files were not shown because too many files have changed in this diff Show More