Page MenuHomePhabricator

The Great Namespaceization Effort
Open, LowPublic

Description

Objective

  1. MediaWiki should use namespaces in a consistent way with low maintenance overhead.
  1. Extension registration should be fast.

Problem statement

  • The use of namespaces in MediaWiki is inconsistent. Directory names are not necessarily related to namespace names.
  • The convention of listing the path of all classes in autoload.php has become unwieldy.
  • Extension registration is slow, due to the need to merge enormous class maps. Class names in the top level use generic names which risk conflicting with the PHP core.

Proposal

I propose moving all MW core classes to the MediaWiki\ namespace, with class_alias() for backwards compatibility. Autoloading would be done using PSR-4, which maps namespaces to directory names.

To work around bugs in PHP, class_alias() calls will be inserted in the file scope at the end of the file defining the new class. The autoloader will have an array mapping each legacy class name to the path of the new file. This is how class_alias() is already used in MW core. Whether this legacy autoloader is integrated with the PSR-4 autoloader or is registered separately is an implementation detail.

A notable difference between the current layout and that described by PSR-4 is that the directory names must match the namespace names, including capitalisation. We already have a MediaWiki\Linker namespace, but the files would be moved from includes/linker to MediaWiki/Linker.

Another difference is that there must only be one class per file.

MediaWiki has more directories than namespaces, and this makes sense given how directories are used in editors. Additional namespaces only really become essential when there is a risk of class name conflicts. To use PSR-4, we will have to trade off between our desire to limit the number of namespaces for usability, while still making files easy to find. The plan I detail below generally leans towards introducing additional namespaces.

There is the question of plural names. We (inconsistently) use plurals to indicate that a directory contains multiple things of a certain type, e.g. each member of includes/ is an include, each member of includes/specials is a special. This makes more sense for directories than for namespaces, given the way each is accessed: the class name MediaWiki\Specials\Activeusers would be strange to see in calling code or an error message. The namespace hierarchy is more of an ontology than a collection. I propose to use singular namespace names where the members of the namespace are are singular instance of the parent concept. So: specials -> Special, jobs -> Job, skins -> Skin. But perhaps jobqueue/utils -> JobQueue\Utils since each class also contains utils, not a single util. And perhaps services -> Services, since it has container classes, the members are not themselves services.

There is the question of whether to retain class name prefixes and suffixes. For example, we have 116 special pages, certainly enough to deserve a separate directory. But should we have MediaWiki\Special\SpecialActiveusers or MediaWiki\Special\Activeusers? I think redundant prefixes should be removed, except when the resulting name becomes very ambiguous. We should keep in mind that text editors often only display the base name.

Some directories do not make sense as modules or namespaces, and exist only out of a desire to reduce the number of PHP files in includes/. These should probably be moved into their respective parent directories. Specifically:

  • cache
  • clientpool
  • compat
  • debug
  • exception
  • json

But in the other direction, I would propose:

  • Sanitizer, MagicWord, MagicWordArray -> Parser\
  • ForkController -> Maintenance\
  • MessageCache -> Language\
  • Message, RawMessage -> Language
  • cache/localisation -> Language\LocalisationCache
  • A directory for non-class code: WebStart.php, Setup.php, DefaultSettings.php, Defines.php, GlobalFunctions.php, OutputHandler.php, NoLocalSettings.php. Namespacing of global functions and constants might be easier with PHP 7 group use, I'm not proposing that at the moment.
    • Also shell scripts, config files?
  • A namespace for the web app setup, request routing and response (Request?) MediaWiki, PathRouter, AjaxDispatcher, AjaxResponse, WebRequest, WebRequestUpload, FauxRequest, DerivativeRequest, WebResponse, OutputPage, HeaderCallback, exception/*
  • Watchlist: WatchedItem, WatchedItemQueryService, WatchedItemQueryServiceExtension
  • StubObject: StubObject, DeprecatedGlobal
  • A namespace for revision, page storage (ArticleStore?): Revision, RevisionList, MergeHistory, MovePage, HistoryBlob, LinkBatch, LinkCache,
  • A namespace for links storage: BacklinkCache, LinksUpdate, LinksDeletionUpdate
  • UserCache -> User\UserCache
  • Feed: FeedItem, ChannelFeed, RSSFeed, AtomFeed, FeedUtils

The classes in libs and utils would be better placed under the Wikimedia\ namespace, corresponding to the Composer vendor namespace, reflecting our aspirations for them to be separate from MediaWiki.

Other special cases:

  • jobqueue/jobs -> JobQueue\Job
  • includes/libs/rdbms/defines.php: migrate to namespaced constants.
  • specials -> Special
  • specials/helpers -> Special\Helper
  • specials/pagers -> Special\Pager
  • languages/classes -> MediaWiki\Language
  • languages/data/ZhConversion -> MediaWiki\Languages\Data\ZhConversion
  • maintenance: we can map MediaWiki\Maintenance to this directory for now
  • tests:
    • Some test classes are currently in the namespace they cover, I don't think that works with PSR-4. They should be in MediaWiki\Test\PHPUnit instead.
    • Test classes in MediaWiki\Test\PHPUnit, parser test runner in MediaWiki\Test\Parser
    • Classes under libs/ will be under the Wikimedia namespace, so associated tests should also be in the Wikimedia namespace
    • Map namespace MediaWiki\Test to directory tests\MediaWiki

New directory names will match namespace names, except for maintenance and tests. So for example, the language class files will not stay in languages/.

Existing namespaced extensions mostly use the top level, which I think is fine as long as the name is a distinctive product name. For generic descriptive names, I would prefer MediaWiki\Extension over MediaWiki\Extensions.

The transition should be fully scripted so that it can be used to rebase open changesets in Gerrit.

Details

Related Changes in Gerrit:
SubjectRepoBranchLines +/-
mediawiki/coremaster+14 -6
mediawiki/coremaster+33 -19
mediawiki/coremaster+109 -69
mediawiki/extensions/LinkedWikimaster+7 -0
mediawiki/coremaster+55 -240
mediawiki/coremaster+240 -55
operations/mediawiki-configmaster+2 -0
mediawiki/coremaster+55 -240
mediawiki/coremaster+12 -251
mediawiki/coremaster+125 -43
mediawiki/coremaster+136 -42
mediawiki/tools/phan/SecurityCheckPluginmaster+134 -6
mediawiki/coremaster+333 -60
mediawiki/coremaster+247 -237
mediawiki/coremaster+99 -37
mediawiki/coremaster+337 -129
mediawiki/coremaster+215 -73
mediawiki/coremaster+533 -303
mediawiki/coremaster+31 -16
mediawiki/coremaster+176 -38
mediawiki/coremaster+61 -28
mediawiki/coremaster+105 -57
mediawiki/coremaster+497 -178
mediawiki/coremaster+107 -36
mediawiki/coremaster+255 -45
mediawiki/coremaster+24 -4
mediawiki/coremaster+94 -0
mediawiki/coreREL1_40+58 -2
mediawiki/coremaster+58 -2
mediawiki/coremaster+876 -235
mediawiki/coremaster+2 -1
mediawiki/coremaster+307 -511
mediawiki/coremaster+511 -307
mediawiki/coremaster+113 -43
mediawiki/coremaster+87 -38
mediawiki/coremaster+31 -22
mediawiki/coremaster+18 -7
mediawiki/coremaster+24 -148
mediawiki/coremaster+39 -14
mediawiki/tools/namespaceizermaster+646 -0
Show related patches Customize query in gerrit

Related Objects

StatusSubtypeAssignedTask
OpenNone
ResolvedLegoktm
ResolvedLegoktm
Resolvedtstarling
ResolvedLucas_Werkmeister_WMDE
ResolvedTheresNoTime
ResolvedJdforrester-WMF
ResolvedJoe
ResolvedDzahn
Resolvedhashar
ResolvedJdforrester-WMF
ResolvedLadsgroup
ResolvedMoritzMuehlenhoff
Resolvedjijiki
ResolvedMoritzMuehlenhoff
ResolvedTrizek-WMF
ResolvedDzahn
Resolved Gilles
ResolvedDzahn
ResolvedRequestPapaul
Resolvedjijiki
DeclinedNone
ResolvedDzahn
ResolvedDzahn
ResolvedPapaul
Resolved Cmjohnson
ResolvedRequest Cmjohnson
ResolvedRequestPapaul
ResolvedAndrew
ResolvedArielGlenn
ResolvedDzahn
ResolvedLegoktm
ResolvedPapaul
ResolvedDzahn
Declined Gilles
ResolvedVolans
ResolvedDzahn
ResolvedLegoktm
ResolvedPleaseStand
ResolvedJoe
Resolvedtstarling
ResolvedArielGlenn
ResolvedJoe
Resolvedtstarling
ResolvedJdforrester-WMF
ResolvedJdforrester-WMF
ResolvedLegoktm
ResolvedJdforrester-WMF
ResolvedDaimona
ResolvedDaimona
ResolvedJdforrester-WMF
ResolvedJoe
ResolvedJMeybohm
ResolvedJoe
ResolvedJoe
ResolvedJoe
ResolvedJoe
ResolvedKrinkle
ResolvedJoe
ResolvedClement_Goubert
ResolvedClement_Goubert
ResolvedClement_Goubert
ResolvedMainframe98
ResolvedJoe
ResolvedZabe
ResolvedLadsgroup
ResolvedSecurityDaimona
OpenNone
OpenNone
OpenNone
ResolvedBUG REPORTSamwilson
ResolvedNone

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

Change 958501 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Namespace NamespaceInfo under \MediaWiki\Title

https://gerrit.wikimedia.org/r/958501

Change 958502 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Namespace TitleFormatter under \MediaWiki\Title

https://gerrit.wikimedia.org/r/958502

Change 958503 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Namespace TitleParser under \MediaWiki\Title

https://gerrit.wikimedia.org/r/958503

Change 958504 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Namespace remaining Title-related classes under \MediaWiki\Title

https://gerrit.wikimedia.org/r/958504

Change 957723 merged by jenkins-bot:

[mediawiki/core@master] Namespace core Pagers under \MediaWiki\Pager

https://gerrit.wikimedia.org/r/957723

Change 957888 merged by jenkins-bot:

[mediawiki/core@master] Namespace HistoryPager under \MediaWiki\Pager

https://gerrit.wikimedia.org/r/957888

Change 957889 merged by jenkins-bot:

[mediawiki/core@master] Namespace 'special' Pagers under \MediaWiki\Pager

https://gerrit.wikimedia.org/r/957889

Change 957890 merged by jenkins-bot:

[mediawiki/core@master] Namespace remaining 'specialpage' files under \MediaWiki\SpecialPage

https://gerrit.wikimedia.org/r/957890

Change 958500 merged by jenkins-bot:

[mediawiki/core@master] Namespace TitleValue under \MediaWiki\Title

https://gerrit.wikimedia.org/r/958500

Change 958501 merged by jenkins-bot:

[mediawiki/core@master] Namespace NamespaceInfo under \MediaWiki\Title

https://gerrit.wikimedia.org/r/958501

Change 958502 merged by jenkins-bot:

[mediawiki/core@master] Namespace TitleFormatter under \MediaWiki\Title

https://gerrit.wikimedia.org/r/958502

Change 958503 merged by jenkins-bot:

[mediawiki/core@master] Namespace TitleParser under \MediaWiki\Title

https://gerrit.wikimedia.org/r/958503

Change 958504 merged by jenkins-bot:

[mediawiki/core@master] Namespace remaining Title-related classes under \MediaWiki\Title

https://gerrit.wikimedia.org/r/958504

Change 958919 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Namespace User under \MediaWiki\User

https://gerrit.wikimedia.org/r/958919

Change 959000 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Namespace remaining User-related classes under \MediaWiki\User

https://gerrit.wikimedia.org/r/959000

Change 959001 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Namespace Sanitizer under \MediaWiki\Parser

https://gerrit.wikimedia.org/r/959001

Change 958919 merged by jenkins-bot:

[mediawiki/core@master] Namespace User under \MediaWiki\User

https://gerrit.wikimedia.org/r/958919

Change 959152 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Namespace Config-related classes under \MediaWiki\Config

https://gerrit.wikimedia.org/r/959152

Change 959153 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] RELEASE-NOTES-1.41: Consolidate PSR-4 deprecation efforts into one list

https://gerrit.wikimedia.org/r/959153

Change 959000 merged by jenkins-bot:

[mediawiki/core@master] Namespace remaining User-related classes under \MediaWiki\User

https://gerrit.wikimedia.org/r/959000

Change 959001 merged by jenkins-bot:

[mediawiki/core@master] Namespace Sanitizer under \MediaWiki\Parser

https://gerrit.wikimedia.org/r/959001

Change 959152 merged by jenkins-bot:

[mediawiki/core@master] Namespace Config-related classes under \MediaWiki\Config

https://gerrit.wikimedia.org/r/959152

Change 959153 merged by jenkins-bot:

[mediawiki/core@master] RELEASE-NOTES-1.41: Consolidate PSR-4 deprecation efforts into one list

https://gerrit.wikimedia.org/r/959153

Change 976311 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Namespace remaining files under includes/deferred

https://gerrit.wikimedia.org/r/976311

Change 976311 merged by jenkins-bot:

[mediawiki/core@master] Namespace remaining files under includes/deferred

https://gerrit.wikimedia.org/r/976311

Change 982929 had a related patch set uploaded (by Subramanya Sastry; author: Subramanya Sastry):

[mediawiki/core@master] WIP: Move Parser to Mediawiki\Parser namespace.

https://gerrit.wikimedia.org/r/982929

Change 995123 had a related patch set uploaded (by Daimona Eaytoy; author: Daimona Eaytoy):

[mediawiki/tools/phan/SecurityCheckPlugin@master] Add compatibility for Parser namespacing

https://gerrit.wikimedia.org/r/995123

Change 995123 merged by jenkins-bot:

[mediawiki/tools/phan/SecurityCheckPlugin@master] Add compatibility for Parser namespacing

https://gerrit.wikimedia.org/r/995123

Change 997927 had a related patch set uploaded (by C. Scott Ananian; author: C. Scott Ananian):

[mediawiki/core@master] Move hooks used by OutputPage into includes/Output/Hook

https://gerrit.wikimedia.org/r/997927

Change 997927 merged by jenkins-bot:

[mediawiki/core@master] Move hooks used by OutputPage into includes/Output/Hook

https://gerrit.wikimedia.org/r/997927

Change 982929 merged by jenkins-bot:

[mediawiki/core@master] Move Parser to Mediawiki\Parser namespace

https://gerrit.wikimedia.org/r/982929

After deploy of next week, I will run lsc 😈

Change #1091012 had a related patch set uploaded (by Tim Starling; author: Tim Starling):

[mediawiki/core@master] Remove 52 class aliases, deprecated since 1.40

https://gerrit.wikimedia.org/r/1091012

Change #1091012 abandoned by Tim Starling:

[mediawiki/core@master] Remove 52 class aliases, deprecated since 1.40

https://gerrit.wikimedia.org/r/1091012

Change #1120610 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] Drop all 49 remaining class_aliases from MediaWiki 1.40

https://gerrit.wikimedia.org/r/1120610

Change #1120610 merged by jenkins-bot:

[mediawiki/core@master] Drop all 49 remaining class_aliases from MediaWiki 1.40

https://gerrit.wikimedia.org/r/1120610

Change #1120610 merged by jenkins-bot:

[mediawiki/core@master] Drop all 49 remaining class_aliases from MediaWiki 1.40

https://gerrit.wikimedia.org/r/1120610

This made beta-scap-sync-world fail:

23:56:35 22:56:35 Logstash checker Counted 47 error(s) in the last 20 seconds. The threshold is 10.
23:56:35 22:56:35 Top 2 errors:
23:56:35 [34 hits] TypeError: {closure}(): Argument #1 ($title) must be of type Title, MediaWiki\Title\Title given, called in /srv/mediawiki/php-master/includes/HookContainer/HookContainer.php on line 155
23:56:35 [13 hits] Error: Class "Html" not found

Sadly this is not very helpful in finding the remaining usages.

Change #1124542 had a related patch set uploaded (by Ahmon Dancy; author: Ahmon Dancy):

[mediawiki/core@master] Revert "Drop all 49 remaining class_aliases from MediaWiki 1.40"

https://gerrit.wikimedia.org/r/1124542

Mentioned in SAL (#wikimedia-releng) [2025-03-04T23:26:33Z] <dancy> Disabling beta-scap-sync-world for noise reduction while dealing with T166010

Change #1124542 merged by jenkins-bot:

[mediawiki/core@master] Revert "Drop all 49 remaining class_aliases from MediaWiki 1.40"

https://gerrit.wikimedia.org/r/1124542

23:56:35 22:56:35 Logstash checker Counted 47 error(s) in the last 20 seconds. The threshold is 10.
23:56:35 22:56:35 Top 2 errors:
23:56:35 [34 hits] TypeError: {closure}(): Argument #1 ($title) must be of type Title, MediaWiki\Title\Title given, called in /srv/mediawiki/php-master/includes/HookContainer/HookContainer.php on line 155
23:56:35 [13 hits] Error: Class "Html" not found

Sadly this is not very helpful in finding the remaining usages.

The error message mentioning hooks and closures, and no CI check failing beforehand, would make wmf-config a prime candidate for the legacy usages. The two errors above mention Title and Html, and sure enough, CommonSettings references both with the legacy FQSEN.

I would like to see a future where our config repo only contains config, not hook handlers and the like. Even today, these could use the WikimediaMessages extension.

Change #1124548 had a related patch set uploaded (by Daimona Eaytoy; author: Daimona Eaytoy):

[operations/mediawiki-config@master] Use namespaced Title and Html classes

https://gerrit.wikimedia.org/r/1124548

Mentioned in SAL (#wikimedia-releng) [2025-03-05T00:21:28Z] <dancy> Reeanbled beta-scap-sync-world (T166010)

Change #1124548 merged by jenkins-bot:

[operations/mediawiki-config@master] Use namespaced Title and Html classes

https://gerrit.wikimedia.org/r/1124548

Mentioned in SAL (#wikimedia-operations) [2025-03-05T14:09:14Z] <dreamyjazz@deploy2002> Started scap sync-world: Backport for [[gerrit:1124480|Set Flow to read-only on remaining phase 2a wikis (T378834)]], [[gerrit:1124500|Remove unused config parameters from ReadingLists extension.]], [[gerrit:1124548|Use namespaced Title and Html classes (T166010 T387938)]], [[gerrit:1124549|officewiki: Disable the event-organizer user group (T387943)]], [[gerrit:1124768|Temporarily unset tempora

Mentioned in SAL (#wikimedia-operations) [2025-03-05T14:12:12Z] <dreamyjazz@deploy2002> daimona, zoe, dreamyjazz, dbrant: Backport for [[gerrit:1124480|Set Flow to read-only on remaining phase 2a wikis (T378834)]], [[gerrit:1124500|Remove unused config parameters from ReadingLists extension.]], [[gerrit:1124548|Use namespaced Title and Html classes (T166010 T387938)]], [[gerrit:1124549|officewiki: Disable the event-organizer user group (T387943)]], [[gerrit:1124768|Temporarily unse

Mentioned in SAL (#wikimedia-operations) [2025-03-05T14:23:41Z] <dreamyjazz@deploy2002> Finished scap sync-world: Backport for [[gerrit:1124480|Set Flow to read-only on remaining phase 2a wikis (T378834)]], [[gerrit:1124500|Remove unused config parameters from ReadingLists extension.]], [[gerrit:1124548|Use namespaced Title and Html classes (T166010 T387938)]], [[gerrit:1124549|officewiki: Disable the event-organizer user group (T387943)]], [[gerrit:1124768|Temporarily unset tempor

Change #1124809 had a related patch set uploaded (by Daimona Eaytoy; author: Daimona Eaytoy):

[mediawiki/core@master] Re-apply "Drop all 49 remaining class_aliases from MediaWiki 1.40"

https://gerrit.wikimedia.org/r/1124809

Change #1124809 merged by jenkins-bot:

[mediawiki/core@master] Re-apply "Drop all 49 remaining class_aliases from MediaWiki 1.40"

https://gerrit.wikimedia.org/r/1124809

Change #1131939 had a related patch set uploaded (by Physikerwelt; author: Physikerwelt):

[mediawiki/extensions/LinkedWiki@master] Use namespaced version of title

https://gerrit.wikimedia.org/r/1131939

Change #1131939 merged by jenkins-bot:

[mediawiki/extensions/LinkedWiki@master] Use namespaced version of title

https://gerrit.wikimedia.org/r/1131939

Change #1215685 had a related patch set uploaded (by Reedy; author: Reedy):

[mediawiki/core@master] Namespace Upload\Exception

https://gerrit.wikimedia.org/r/1215685

Change #1215691 had a related patch set uploaded (by Reedy; author: Reedy):

[mediawiki/core@master] User: Namespace remaining job classes

https://gerrit.wikimedia.org/r/1215691

Change #1215685 merged by jenkins-bot:

[mediawiki/core@master] Namespace Upload\Exception

https://gerrit.wikimedia.org/r/1215685

Change #1215720 had a related patch set uploaded (by Reedy; author: Reedy):

[mediawiki/core@master] LockManagerGroup: Namespace

https://gerrit.wikimedia.org/r/1215720

Change #1215720 merged by jenkins-bot:

[mediawiki/core@master] LockManagerGroup: Namespace

https://gerrit.wikimedia.org/r/1215720

Change #1215691 merged by jenkins-bot:

[mediawiki/core@master] User: Namespace remaining job classes

https://gerrit.wikimedia.org/r/1215691