2015-10-12 08:05:45 +00:00
|
|
|
<?php
|
|
|
|
|
/**
|
2023-03-18 18:16:00 +00:00
|
|
|
* Service implementations for %MediaWiki core.
|
2022-04-12 01:25:37 +00:00
|
|
|
*
|
|
|
|
|
* This file returns the array loaded by the MediaWikiServices class
|
|
|
|
|
* for use through `MediaWiki\MediaWikiServices::getInstance()`
|
|
|
|
|
*
|
|
|
|
|
* @see [Dependency Injection](@ref dependencyinjection) in docs/Injection.md
|
|
|
|
|
* for the principles of DI and how to use it MediaWiki core.
|
|
|
|
|
*
|
|
|
|
|
* Reminder:
|
|
|
|
|
*
|
|
|
|
|
* - ServiceWiring is NOT a cache for arbitrary singletons.
|
|
|
|
|
*
|
|
|
|
|
* - Services MUST NOT vary their behaviour on global state, especially not
|
2022-10-27 13:14:16 +00:00
|
|
|
* WebRequest, RequestContext (T218555), or other details of the current
|
2022-04-12 01:25:37 +00:00
|
|
|
* request or CLI process (e.g. "current" user or title). Doing so may
|
|
|
|
|
* cause a chain reaction and cause serious data corruption.
|
|
|
|
|
*
|
|
|
|
|
* Refer to [DI Principles](@ref di-principles) in docs/Injection.md for
|
|
|
|
|
* how and why we avoid this, as well as for limited exemptions to these
|
|
|
|
|
* principles.
|
|
|
|
|
*
|
|
|
|
|
* -------
|
2015-10-12 08:05:45 +00:00
|
|
|
*
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
|
|
|
|
|
2018-08-18 10:22:38 +00:00
|
|
|
use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
|
2021-03-21 22:34:04 +00:00
|
|
|
use MediaWiki\Actions\ActionFactory;
|
2017-11-07 03:10:14 +00:00
|
|
|
use MediaWiki\Auth\AuthManager;
|
2022-02-28 03:05:58 +00:00
|
|
|
use MediaWiki\Auth\Throttler;
|
Move DatabaseBlock read query methods to DatabaseBlockStore
* Move to DatabaseBlockStore the DatabaseBlock methods newFromID,
getQueryInfo, getRangeCond, newFromRow, isExemptedFromAutoblocks,
doAutoblock, updateTimestamp, getAutoblockExpiry, newFromTarget,
newListFromTarget.
* Split DatabaseBlock::getBlocksForIPList. Now
BlockManager::getBlocksForIPList() is responsible for XFF header
validation and trusted proxy handling. DatabaseBlockStore::
newListFromIPs() just does the queries and constructs the Block
objects.
* In DatabaseBlockStore::newFromRow() and doAutoblock(), use the
DatabaseBlock constructor instead of calling many setter methods. Add
constructor options decodedExpiry, decodedTimestamp, id,
parentBlockId and restrictions to support this.
* Move isExemptedFromAutoblocks() to its own service. Remove the cache
since in my testing with production eval.php, the WAN cache fetch is
10 times slower than just using the message cache, contradicting the
comment written in 2008.
* Fix AuthManagerTest which was previously passing an unrecognised
"restrictions" option to DatabaseBlock. Now that the option actually
works, we have to use the right type.
Bug: T255433
Change-Id: I5049e60be1681f67fcca133e569e315792dc42dd
2023-10-31 05:58:23 +00:00
|
|
|
use MediaWiki\Block\AutoblockExemptionList;
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
use MediaWiki\Block\BlockActionInfo;
|
2019-09-20 15:03:48 +00:00
|
|
|
use MediaWiki\Block\BlockErrorFormatter;
|
2019-04-05 19:13:17 +00:00
|
|
|
use MediaWiki\Block\BlockManager;
|
2020-05-07 18:50:24 +00:00
|
|
|
use MediaWiki\Block\BlockPermissionCheckerFactory;
|
2019-04-11 19:54:10 +00:00
|
|
|
use MediaWiki\Block\BlockRestrictionStore;
|
2021-09-28 17:21:37 +00:00
|
|
|
use MediaWiki\Block\BlockRestrictionStoreFactory;
|
2020-04-23 19:33:56 +00:00
|
|
|
use MediaWiki\Block\BlockUserFactory;
|
2020-09-18 19:01:34 +00:00
|
|
|
use MediaWiki\Block\BlockUtils;
|
2024-01-03 18:40:04 +00:00
|
|
|
use MediaWiki\Block\BlockUtilsFactory;
|
2022-09-07 15:23:14 +00:00
|
|
|
use MediaWiki\Block\DatabaseBlock;
|
2020-05-08 06:29:23 +00:00
|
|
|
use MediaWiki\Block\DatabaseBlockStore;
|
2022-09-07 15:23:14 +00:00
|
|
|
use MediaWiki\Block\DatabaseBlockStoreFactory;
|
Support new block schema
Support migration stages when reading and writing blocks.
I tried to set it up for an easy next stage, in which support for the
old schema is removed. I tried to avoid factoring out of shared code
between the two schemas, so that the old schema cases can simply be
deleted without the need to revert unnecessary abstractions.
However, I added HideUserUtils to factor out ipb_deleted queries. Code
review showed that this was already quite complex, with multiple
approaches to the problem, so it benefits from refactoring even without
the schema abstraction.
HideUserUtils is a service rather than a standalone class to support
unit tests, since unit tests do not allow global config access. When
the migration stage config is removed, it will be a service with no
constructor parameters -- an unnecessary abstraction which should
ideally be resolved at that time.
When interpreting result rows, it is possible to share code by using
field aliases. But when constructing WHERE conditions, the actual field
names need to be used, so the migration is more intrusive in
ApiQueryBlocks and SpecialBlockList, where complex conditions are used.
Bug: T346293
Bug: T51504
Bug: T349883
Change-Id: I408acf7a57b0100fe18c455fc13141277a598925
2023-10-27 03:34:10 +00:00
|
|
|
use MediaWiki\Block\HideUserUtils;
|
2020-04-23 19:33:03 +00:00
|
|
|
use MediaWiki\Block\UnblockUserFactory;
|
|
|
|
|
use MediaWiki\Block\UserBlockCommandFactory;
|
2024-02-08 19:09:50 +00:00
|
|
|
use MediaWiki\Cache\BacklinkCache;
|
2021-09-08 17:19:11 +00:00
|
|
|
use MediaWiki\Cache\BacklinkCacheFactory;
|
2024-02-08 19:09:50 +00:00
|
|
|
use MediaWiki\Cache\GenderCache;
|
|
|
|
|
use MediaWiki\Cache\HTMLCacheUpdater;
|
2019-10-19 11:08:40 +00:00
|
|
|
use MediaWiki\Cache\LinkBatchFactory;
|
2024-02-08 19:09:50 +00:00
|
|
|
use MediaWiki\Cache\LinkCache;
|
|
|
|
|
use MediaWiki\Cache\UserCache;
|
2023-02-09 18:59:23 +00:00
|
|
|
use MediaWiki\Category\TrackingCategories;
|
2023-05-07 00:26:40 +00:00
|
|
|
use MediaWiki\ChangeTags\ChangeTagsStore;
|
2021-08-24 19:12:39 +00:00
|
|
|
use MediaWiki\Collation\CollationFactory;
|
Introduce CommentFormatter
CommentParser:
* Move comment formatting backend from Linker to a CommentParser service.
Allow link existence and file existence to be batched.
* Rename $local to $samePage since I think that is clearer.
* Rename $title to $selfLinkTarget since it was unclear what the title
was used for.
* Rename the "autocomment" concept to "section link" in public
interfaces, although the old term remains in CSS classes.
* Keep unsafe HTML pass-through in separate "unsafe" methods, for easier
static analysis and code review.
CommentFormatter:
* Add CommentFormatter and RowCommentFormatter services as a usable
frontend for comment batches, and to replace the Linker static methods.
* Provide fluent and parametric interfaces.
Linker:
* Remove Linker::makeCommentLink() without deprecation -- nothing calls
it and it is obviously an internal helper.
* Soft-deprecate Linker methods formatComment(), formatLinksInComment(),
commentBlock() and revComment().
Caller migration:
* CommentFormatter single: Linker, RollbackAction, ApiComparePages,
ApiParse
* CommentFormatter parametric batch: ImageHistoryPseudoPager
* CommentFormatter fluent batch: ApiQueryFilearchive
* RowCommentFormatter sequential: History feed, BlocklistPager,
ProtectedPagesPager, ApiQueryProtectedTitles
* RowCommentFormatter with index: ChangesFeed, ChangesList,
ApiQueryDeletedrevs, ApiQueryLogEvents, ApiQueryRecentChanges
* RevisionCommentBatch: HistoryPager, ContribsPager
Bug: T285917
Change-Id: Ia3fd50a4a13138ba5003d884962da24746d562d0
2021-07-01 06:55:03 +00:00
|
|
|
use MediaWiki\CommentFormatter\CommentFormatter;
|
|
|
|
|
use MediaWiki\CommentFormatter\CommentParserFactory;
|
|
|
|
|
use MediaWiki\CommentFormatter\RowCommentFormatter;
|
2022-12-28 21:50:03 +00:00
|
|
|
use MediaWiki\CommentStore\CommentStore;
|
2023-09-20 07:54:42 +00:00
|
|
|
use MediaWiki\Config\Config;
|
|
|
|
|
use MediaWiki\Config\ConfigException;
|
|
|
|
|
use MediaWiki\Config\ConfigFactory;
|
2016-12-14 20:55:56 +00:00
|
|
|
use MediaWiki\Config\ConfigRepository;
|
2019-04-10 15:03:54 +00:00
|
|
|
use MediaWiki\Config\ServiceOptions;
|
2020-01-18 20:25:04 +00:00
|
|
|
use MediaWiki\Content\ContentHandlerFactory;
|
|
|
|
|
use MediaWiki\Content\IContentHandlerFactory;
|
2021-08-24 12:17:12 +00:00
|
|
|
use MediaWiki\Content\Renderer\ContentRenderer;
|
2021-07-21 01:03:59 +00:00
|
|
|
use MediaWiki\Content\Transform\ContentTransformer;
|
2024-02-08 14:56:54 +00:00
|
|
|
use MediaWiki\Context\RequestContext;
|
2021-09-28 17:21:37 +00:00
|
|
|
use MediaWiki\DAO\WikiAwareEntity;
|
2023-11-21 21:08:14 +00:00
|
|
|
use MediaWiki\Deferred\DeferredUpdates;
|
2022-05-16 16:56:20 +00:00
|
|
|
use MediaWiki\Edit\ParsoidOutputStash;
|
|
|
|
|
use MediaWiki\Edit\SimpleParsoidOutputStash;
|
2020-10-21 01:05:00 +00:00
|
|
|
use MediaWiki\EditPage\Constraint\EditConstraintFactory;
|
2023-04-19 22:27:50 +00:00
|
|
|
use MediaWiki\EditPage\IntroMessageBuilder;
|
|
|
|
|
use MediaWiki\EditPage\PreloadedContentBuilder;
|
2020-04-25 04:21:55 +00:00
|
|
|
use MediaWiki\EditPage\SpamChecker;
|
2021-07-21 23:49:49 +00:00
|
|
|
use MediaWiki\Export\WikiExporterFactory;
|
2019-08-16 10:00:15 +00:00
|
|
|
use MediaWiki\FileBackend\FSFile\TempFSFileFactory;
|
2019-08-15 18:07:36 +00:00
|
|
|
use MediaWiki\FileBackend\LockManager\LockManagerGroupFactory;
|
2022-10-25 14:03:05 +00:00
|
|
|
use MediaWiki\HookContainer\FauxGlobalHookArray;
|
2020-04-17 06:03:29 +00:00
|
|
|
use MediaWiki\HookContainer\HookContainer;
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
use MediaWiki\HookContainer\HookRunner;
|
2022-10-25 14:03:05 +00:00
|
|
|
use MediaWiki\HookContainer\StaticHookRegistry;
|
2019-04-22 08:21:50 +00:00
|
|
|
use MediaWiki\Http\HttpRequestFactory;
|
2023-07-20 13:31:25 +00:00
|
|
|
use MediaWiki\Http\Telemetry;
|
2023-05-31 13:00:55 +00:00
|
|
|
use MediaWiki\Installer\Pingback;
|
2015-10-30 22:04:52 +00:00
|
|
|
use MediaWiki\Interwiki\ClassicInterwikiLookup;
|
2018-08-07 16:33:20 +00:00
|
|
|
use MediaWiki\Interwiki\InterwikiLookup;
|
2023-01-12 13:17:43 +00:00
|
|
|
use MediaWiki\JobQueue\JobFactory;
|
2021-03-17 12:37:06 +00:00
|
|
|
use MediaWiki\JobQueue\JobQueueGroupFactory;
|
2020-11-18 00:26:53 +00:00
|
|
|
use MediaWiki\Json\JsonCodec;
|
2023-09-25 13:32:24 +00:00
|
|
|
use MediaWiki\Language\FormatterFactory;
|
2023-10-01 12:03:37 +00:00
|
|
|
use MediaWiki\Language\LazyLocalizationContext;
|
2020-01-23 18:39:23 +00:00
|
|
|
use MediaWiki\Languages\LanguageConverterFactory;
|
2018-08-07 13:17:16 +00:00
|
|
|
use MediaWiki\Languages\LanguageFactory;
|
2019-08-22 15:39:26 +00:00
|
|
|
use MediaWiki\Languages\LanguageFallback;
|
2019-05-02 14:23:42 +00:00
|
|
|
use MediaWiki\Languages\LanguageNameUtils;
|
2018-08-07 16:33:20 +00:00
|
|
|
use MediaWiki\Linker\LinkRenderer;
|
Add LinkRenderer (rewrite of Linker::link())
This is a rewrite of Linker::link() to a non-static, LinkTarget-based
interface. Users of plain Linker::link() with no options can use the
LinkRenderer instance provided by MediaWikiServices. Others that
have specific options should create and configure their own instance,
which can be used to create as many links as necessary.
The main entrypoints for making links are:
* ->makeLink( $target, $text, $attribs, $query );
* ->makeKnownLink( $target, $text, $attribs, $query );
* ->makeBrokenLink( $target, $text, $attribs, $query );
The order of the parameters are the same as Linker::link(), except
$options are now part of the LinkRenderer instance, and
known/broken status requires calling the function explicitly.
Additionally, instead of passing in raw $html for the link text, the
$text parameter will automatically be escaped unless it is specially
marked as safe HTML using the MediaWiki\Linker\HtmlArmor class.
The LinkBegin and LinkEnd hooks are now deprecated, but still function
for backwards-compatability. Clients should migrate to the nearly-
equivalent LinkRendererBegin and LinkRendererEnd hooks.
The main differences between the hooks are:
* Passing HtmlPageLinkRenderer object instead of deprecated DummyLinker
* Using LinkTarget instead of Title
* Begin hook can no longer change known/broken status of link. Use the
TitleIsAlwaysKnown hook for that.
* $options are no longer passed, they can be read (but shouldn't be
modified!) from the LinkRenderer object.
Bug: T469
Change-Id: I057cc86ae6404a080aa3c8e0e956ecbb10a897d5
2016-04-21 20:13:21 +00:00
|
|
|
use MediaWiki\Linker\LinkRendererFactory;
|
2022-04-05 20:13:27 +00:00
|
|
|
use MediaWiki\Linker\LinksMigration;
|
2022-02-07 19:13:22 +00:00
|
|
|
use MediaWiki\Linker\LinkTargetLookup;
|
|
|
|
|
use MediaWiki\Linker\LinkTargetStore;
|
2016-10-02 07:04:17 +00:00
|
|
|
use MediaWiki\Logger\LoggerFactory;
|
2020-03-09 11:00:28 +00:00
|
|
|
use MediaWiki\Mail\Emailer;
|
2023-03-10 19:01:48 +00:00
|
|
|
use MediaWiki\Mail\EmailUser;
|
2023-05-22 14:08:03 +00:00
|
|
|
use MediaWiki\Mail\EmailUserFactory;
|
2020-03-09 11:00:28 +00:00
|
|
|
use MediaWiki\Mail\IEmailer;
|
2022-04-01 15:58:32 +00:00
|
|
|
use MediaWiki\MainConfigNames;
|
2015-10-12 08:05:45 +00:00
|
|
|
use MediaWiki\MediaWikiServices;
|
2019-07-15 10:24:38 +00:00
|
|
|
use MediaWiki\Message\MessageFormatterFactory;
|
2024-01-02 02:26:54 +00:00
|
|
|
use MediaWiki\OutputTransform\DefaultOutputPipelineFactory;
|
|
|
|
|
use MediaWiki\OutputTransform\OutputTransformPipeline;
|
2020-05-30 19:10:58 +00:00
|
|
|
use MediaWiki\Page\ContentModelChangeFactory;
|
2021-08-20 19:56:10 +00:00
|
|
|
use MediaWiki\Page\DeletePageFactory;
|
2023-02-22 17:51:26 +00:00
|
|
|
use MediaWiki\Page\File\BadFileLookup;
|
2020-04-28 22:54:18 +00:00
|
|
|
use MediaWiki\Page\MergeHistoryFactory;
|
2019-05-01 11:39:45 +00:00
|
|
|
use MediaWiki\Page\MovePageFactory;
|
2020-04-28 22:54:18 +00:00
|
|
|
use MediaWiki\Page\PageCommandFactory;
|
2022-12-09 12:17:40 +00:00
|
|
|
use MediaWiki\Page\PageProps;
|
2021-02-09 11:08:36 +00:00
|
|
|
use MediaWiki\Page\PageStore;
|
2021-03-17 22:13:35 +00:00
|
|
|
use MediaWiki\Page\PageStoreFactory;
|
2020-09-30 19:25:29 +00:00
|
|
|
use MediaWiki\Page\ParserOutputAccess;
|
2021-10-20 15:51:22 +00:00
|
|
|
use MediaWiki\Page\RedirectLookup;
|
|
|
|
|
use MediaWiki\Page\RedirectStore;
|
2021-03-26 22:56:39 +00:00
|
|
|
use MediaWiki\Page\RollbackPageFactory;
|
2021-08-30 20:55:05 +00:00
|
|
|
use MediaWiki\Page\UndeletePageFactory;
|
2020-07-27 13:24:05 +00:00
|
|
|
use MediaWiki\Page\WikiPageFactory;
|
2022-12-09 12:28:41 +00:00
|
|
|
use MediaWiki\Parser\MagicWordFactory;
|
2023-12-13 22:50:44 +00:00
|
|
|
use MediaWiki\Parser\Parser;
|
2020-09-25 20:02:03 +00:00
|
|
|
use MediaWiki\Parser\ParserCacheFactory;
|
2021-09-21 15:58:05 +00:00
|
|
|
use MediaWiki\Parser\ParserObserver;
|
2022-03-25 20:34:04 +00:00
|
|
|
use MediaWiki\Parser\Parsoid\Config\DataAccess as MWDataAccess;
|
|
|
|
|
use MediaWiki\Parser\Parsoid\Config\PageConfigFactory as MWPageConfigFactory;
|
|
|
|
|
use MediaWiki\Parser\Parsoid\Config\SiteConfig as MWSiteConfig;
|
2022-10-16 21:44:53 +00:00
|
|
|
use MediaWiki\Parser\Parsoid\HtmlTransformFactory;
|
2022-06-17 14:00:27 +00:00
|
|
|
use MediaWiki\Parser\Parsoid\ParsoidOutputAccess;
|
2022-05-27 16:38:32 +00:00
|
|
|
use MediaWiki\Parser\Parsoid\ParsoidParserFactory;
|
2021-08-06 19:51:07 +00:00
|
|
|
use MediaWiki\Permissions\GrantsInfo;
|
|
|
|
|
use MediaWiki\Permissions\GrantsLocalization;
|
2021-01-05 23:08:09 +00:00
|
|
|
use MediaWiki\Permissions\GroupPermissionsLookup;
|
2019-03-07 20:02:07 +00:00
|
|
|
use MediaWiki\Permissions\PermissionManager;
|
2022-05-24 20:54:25 +00:00
|
|
|
use MediaWiki\Permissions\RateLimiter;
|
2021-07-26 13:24:22 +00:00
|
|
|
use MediaWiki\Permissions\RestrictionStore;
|
2022-12-14 21:56:52 +00:00
|
|
|
use MediaWiki\PoolCounter\PoolCounterFactory;
|
2017-11-07 03:10:14 +00:00
|
|
|
use MediaWiki\Preferences\DefaultPreferencesFactory;
|
2020-01-10 00:00:51 +00:00
|
|
|
use MediaWiki\Preferences\PreferencesFactory;
|
2021-12-12 15:18:36 +00:00
|
|
|
use MediaWiki\Preferences\SignatureValidator;
|
|
|
|
|
use MediaWiki\Preferences\SignatureValidatorFactory;
|
2023-08-06 10:22:58 +00:00
|
|
|
use MediaWiki\Request\ProxyLookup;
|
2023-09-07 11:46:15 +00:00
|
|
|
use MediaWiki\Request\WebRequest;
|
2022-05-06 09:09:56 +00:00
|
|
|
use MediaWiki\ResourceLoader\MessageBlobStore;
|
|
|
|
|
use MediaWiki\ResourceLoader\ResourceLoader;
|
2023-01-13 21:30:21 +00:00
|
|
|
use MediaWiki\Rest\Handler\Helper\PageRestHelperFactory;
|
2021-10-02 10:18:22 +00:00
|
|
|
use MediaWiki\Revision\ArchivedRevisionLookup;
|
2020-06-02 21:24:59 +00:00
|
|
|
use MediaWiki\Revision\ContributionsLookup;
|
2018-11-19 11:39:56 +00:00
|
|
|
use MediaWiki\Revision\MainSlotRoleHandler;
|
2018-09-20 17:29:04 +00:00
|
|
|
use MediaWiki\Revision\RevisionFactory;
|
|
|
|
|
use MediaWiki\Revision\RevisionLookup;
|
|
|
|
|
use MediaWiki\Revision\RevisionRenderer;
|
|
|
|
|
use MediaWiki\Revision\RevisionStore;
|
|
|
|
|
use MediaWiki\Revision\RevisionStoreFactory;
|
2023-01-03 15:24:42 +00:00
|
|
|
use MediaWiki\Revision\SlotRecord;
|
2020-01-10 00:00:51 +00:00
|
|
|
use MediaWiki\Revision\SlotRoleRegistry;
|
2022-08-31 14:51:57 +00:00
|
|
|
use MediaWiki\Search\SearchResultThumbnailProvider;
|
2023-02-19 08:06:34 +00:00
|
|
|
use MediaWiki\Search\TitleMatcher;
|
2022-02-21 16:28:35 +00:00
|
|
|
use MediaWiki\Settings\Config\ConfigSchema;
|
2022-11-06 20:35:07 +00:00
|
|
|
use MediaWiki\Settings\SettingsBuilder;
|
2017-10-07 02:26:52 +00:00
|
|
|
use MediaWiki\Shell\CommandFactory;
|
2020-09-11 03:21:24 +00:00
|
|
|
use MediaWiki\Shell\ShellboxClientFactory;
|
2023-12-14 18:36:16 +00:00
|
|
|
use MediaWiki\Site\CachingSiteStore;
|
|
|
|
|
use MediaWiki\Site\DBSiteStore;
|
|
|
|
|
use MediaWiki\Site\SiteLookup;
|
|
|
|
|
use MediaWiki\Site\SiteStore;
|
2020-02-21 00:01:43 +00:00
|
|
|
use MediaWiki\SpecialPage\SpecialPageFactory;
|
2018-08-07 16:33:20 +00:00
|
|
|
use MediaWiki\Storage\BlobStore;
|
2017-12-23 17:14:28 +00:00
|
|
|
use MediaWiki\Storage\BlobStoreFactory;
|
2020-07-06 11:47:22 +00:00
|
|
|
use MediaWiki\Storage\EditResultCache;
|
2020-05-27 14:45:29 +00:00
|
|
|
use MediaWiki\Storage\NameTableStore;
|
2018-09-04 01:59:03 +00:00
|
|
|
use MediaWiki\Storage\NameTableStoreFactory;
|
2019-04-13 04:38:55 +00:00
|
|
|
use MediaWiki\Storage\PageEditStash;
|
2021-07-16 17:32:30 +00:00
|
|
|
use MediaWiki\Storage\PageUpdaterFactory;
|
2020-07-06 11:47:22 +00:00
|
|
|
use MediaWiki\Storage\RevertedTagUpdateManager;
|
2020-01-10 00:00:51 +00:00
|
|
|
use MediaWiki\Storage\SqlBlobStore;
|
2021-02-18 16:51:12 +00:00
|
|
|
use MediaWiki\Tidy\RemexDriver;
|
|
|
|
|
use MediaWiki\Tidy\TidyDriverBase;
|
2023-09-18 15:00:50 +00:00
|
|
|
use MediaWiki\Title\MediaWikiTitleCodec;
|
2023-09-18 14:17:28 +00:00
|
|
|
use MediaWiki\Title\NamespaceInfo;
|
2022-11-26 01:15:16 +00:00
|
|
|
use MediaWiki\Title\TitleFactory;
|
2023-09-18 14:26:53 +00:00
|
|
|
use MediaWiki\Title\TitleFormatter;
|
2023-09-18 14:35:57 +00:00
|
|
|
use MediaWiki\Title\TitleParser;
|
2022-12-16 11:41:52 +00:00
|
|
|
use MediaWiki\User\ActorMigration;
|
2021-02-22 10:58:46 +00:00
|
|
|
use MediaWiki\User\ActorNormalization;
|
2021-02-16 23:47:45 +00:00
|
|
|
use MediaWiki\User\ActorStore;
|
2021-01-22 19:51:43 +00:00
|
|
|
use MediaWiki\User\ActorStoreFactory;
|
2020-10-30 17:33:33 +00:00
|
|
|
use MediaWiki\User\BotPasswordStore;
|
2023-09-19 16:42:44 +00:00
|
|
|
use MediaWiki\User\CentralId\CentralIdLookup;
|
2021-06-22 19:28:29 +00:00
|
|
|
use MediaWiki\User\CentralId\CentralIdLookupFactory;
|
2023-11-29 11:17:49 +00:00
|
|
|
use MediaWiki\User\Options\ConditionalDefaultsLookup;
|
2023-11-29 10:21:43 +00:00
|
|
|
use MediaWiki\User\Options\DefaultOptionsLookup;
|
|
|
|
|
use MediaWiki\User\Options\UserOptionsLookup;
|
|
|
|
|
use MediaWiki\User\Options\UserOptionsManager;
|
2023-09-19 16:42:44 +00:00
|
|
|
use MediaWiki\User\PasswordReset;
|
2023-09-14 10:18:56 +00:00
|
|
|
use MediaWiki\User\Registration\LocalUserRegistrationProvider;
|
|
|
|
|
use MediaWiki\User\Registration\UserRegistrationLookup;
|
2020-04-04 03:39:01 +00:00
|
|
|
use MediaWiki\User\TalkPageNotificationManager;
|
2022-02-28 03:05:58 +00:00
|
|
|
use MediaWiki\User\TempUser\RealTempUserConfig;
|
|
|
|
|
use MediaWiki\User\TempUser\TempUserCreator;
|
2020-05-26 03:33:28 +00:00
|
|
|
use MediaWiki\User\UserEditTracker;
|
2020-05-23 03:48:21 +00:00
|
|
|
use MediaWiki\User\UserFactory;
|
2019-10-24 03:14:31 +00:00
|
|
|
use MediaWiki\User\UserGroupManager;
|
|
|
|
|
use MediaWiki\User\UserGroupManagerFactory;
|
|
|
|
|
use MediaWiki\User\UserIdentity;
|
2021-02-16 23:47:45 +00:00
|
|
|
use MediaWiki\User\UserIdentityLookup;
|
2023-07-18 04:00:49 +00:00
|
|
|
use MediaWiki\User\UserIdentityUtils;
|
2020-10-02 02:21:23 +00:00
|
|
|
use MediaWiki\User\UserNamePrefixSearch;
|
Add a new UserNameUtils service
This replaces User::isValidUserName, ::isUsableName, ::isCreatableName,
::getCanonicalName, and ::isIP.
Unlike User::isIP, UserNameUtils::isIP will //not// return true
for IPv6 ranges.
UserNameUtils::isIPRange, like User::isIPRange, accepts a name and
simply calls IPUtils::isValidRange.
User::isValidUserName, ::isUsableName, ::isCreatableName,
::getCanonical, ::isIP, and ::isValidRange are all soft deprecated
A follow up patch will add this to the release notes, to avoid merge
conflicts.
Bug: T245231
Bug: T239527
Change-Id: I46684bc492bb74b728ff102971f6cdd4d746a50a
2020-02-23 23:52:44 +00:00
|
|
|
use MediaWiki\User\UserNameUtils;
|
2022-04-04 19:41:23 +00:00
|
|
|
use MediaWiki\Utils\UrlUtils;
|
2021-03-26 22:24:43 +00:00
|
|
|
use MediaWiki\Watchlist\WatchlistManager;
|
2023-02-23 20:44:38 +00:00
|
|
|
use MediaWiki\WikiMap\WikiMap;
|
2019-06-29 04:50:31 +00:00
|
|
|
use Wikimedia\DependencyStore\KeyValueDependencyStore;
|
|
|
|
|
use Wikimedia\DependencyStore\SqlModuleDependencyStore;
|
2023-06-09 20:58:57 +00:00
|
|
|
use Wikimedia\EventRelayer\EventRelayerGroup;
|
2020-01-10 00:00:51 +00:00
|
|
|
use Wikimedia\Message\IMessageFormatterFactory;
|
2022-03-09 22:16:22 +00:00
|
|
|
use Wikimedia\ObjectFactory\ObjectFactory;
|
2022-03-25 20:34:04 +00:00
|
|
|
use Wikimedia\Parsoid\Config\DataAccess;
|
|
|
|
|
use Wikimedia\Parsoid\Config\SiteConfig;
|
2022-06-17 14:00:27 +00:00
|
|
|
use Wikimedia\Parsoid\Parsoid;
|
2023-08-25 11:03:30 +00:00
|
|
|
use Wikimedia\Rdbms\ChronologyProtector;
|
2023-05-04 21:41:21 +00:00
|
|
|
use Wikimedia\Rdbms\ConfiguredReadOnlyMode;
|
2020-07-23 09:31:57 +00:00
|
|
|
use Wikimedia\Rdbms\DatabaseFactory;
|
2024-01-13 07:50:18 +00:00
|
|
|
use Wikimedia\Rdbms\IConnectionProvider;
|
2023-05-04 21:41:21 +00:00
|
|
|
use Wikimedia\Rdbms\ReadOnlyMode;
|
2021-01-06 05:23:15 +00:00
|
|
|
use Wikimedia\RequestTimeout\CriticalSectionProvider;
|
|
|
|
|
use Wikimedia\RequestTimeout\RequestTimeout;
|
2023-02-24 21:18:13 +00:00
|
|
|
use Wikimedia\Stats\StatsCache;
|
|
|
|
|
use Wikimedia\Stats\StatsFactory;
|
2019-05-31 23:24:56 +00:00
|
|
|
use Wikimedia\UUID\GlobalIdGenerator;
|
2022-06-22 11:18:50 +00:00
|
|
|
use Wikimedia\WRStats\BagOStuffStatsStore;
|
|
|
|
|
use Wikimedia\WRStats\WRStatsFactory;
|
2015-10-12 08:05:45 +00:00
|
|
|
|
2021-02-25 12:01:58 +00:00
|
|
|
/** @phpcs-require-sorted-array */
|
2015-10-12 08:05:45 +00:00
|
|
|
return [
|
2021-03-21 22:34:04 +00:00
|
|
|
'ActionFactory' => static function ( MediaWikiServices $services ): ActionFactory {
|
|
|
|
|
return new ActionFactory(
|
2022-04-01 15:58:32 +00:00
|
|
|
$services->getMainConfig()->get( MainConfigNames::Actions ),
|
2021-03-21 22:34:04 +00:00
|
|
|
LoggerFactory::getInstance( 'ActionFactory' ),
|
2021-07-28 10:31:27 +00:00
|
|
|
$services->getObjectFactory(),
|
|
|
|
|
$services->getHookContainer()
|
2021-03-21 22:34:04 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ActorMigration' => static function ( MediaWikiServices $services ): ActorMigration {
|
2020-10-11 21:55:12 +00:00
|
|
|
return new ActorMigration(
|
2021-01-22 19:51:43 +00:00
|
|
|
$services->getActorStoreFactory()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ActorNormalization' => static function ( MediaWikiServices $services ): ActorNormalization {
|
2021-02-22 10:58:46 +00:00
|
|
|
return $services->getActorStoreFactory()->getActorNormalization();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ActorStore' => static function ( MediaWikiServices $services ): ActorStore {
|
2021-02-16 23:47:45 +00:00
|
|
|
return $services->getActorStoreFactory()->getActorStore();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ActorStoreFactory' => static function ( MediaWikiServices $services ): ActorStoreFactory {
|
2021-01-22 19:51:43 +00:00
|
|
|
return new ActorStoreFactory(
|
|
|
|
|
new ServiceOptions( ActorStoreFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
|
|
|
|
$services->getDBLoadBalancerFactory(),
|
|
|
|
|
$services->getUserNameUtils(),
|
2023-08-02 13:27:41 +00:00
|
|
|
$services->getTempUserConfig(),
|
Support new block schema
Support migration stages when reading and writing blocks.
I tried to set it up for an easy next stage, in which support for the
old schema is removed. I tried to avoid factoring out of shared code
between the two schemas, so that the old schema cases can simply be
deleted without the need to revert unnecessary abstractions.
However, I added HideUserUtils to factor out ipb_deleted queries. Code
review showed that this was already quite complex, with multiple
approaches to the problem, so it benefits from refactoring even without
the schema abstraction.
HideUserUtils is a service rather than a standalone class to support
unit tests, since unit tests do not allow global config access. When
the migration stage config is removed, it will be a service with no
constructor parameters -- an unnecessary abstraction which should
ideally be resolved at that time.
When interpreting result rows, it is possible to share code by using
field aliases. But when constructing WHERE conditions, the actual field
names need to be used, so the migration is more intrusive in
ApiQueryBlocks and SpecialBlockList, where complex conditions are used.
Bug: T346293
Bug: T51504
Bug: T349883
Change-Id: I408acf7a57b0100fe18c455fc13141277a598925
2023-10-27 03:34:10 +00:00
|
|
|
LoggerFactory::getInstance( 'ActorStore' ),
|
|
|
|
|
$services->getHideUserUtils()
|
2020-10-11 21:55:12 +00:00
|
|
|
);
|
2016-05-01 19:29:11 +00:00
|
|
|
},
|
|
|
|
|
|
2021-10-02 10:18:22 +00:00
|
|
|
'ArchivedRevisionLookup' => static function ( MediaWikiServices $services ): ArchivedRevisionLookup {
|
|
|
|
|
return new ArchivedRevisionLookup(
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2021-10-02 10:18:22 +00:00
|
|
|
$services->getRevisionStore()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'AuthManager' => static function ( MediaWikiServices $services ): AuthManager {
|
2019-11-08 21:24:00 +00:00
|
|
|
$authManager = new AuthManager(
|
|
|
|
|
RequestContext::getMain()->getRequest(),
|
|
|
|
|
$services->getMainConfig(),
|
2020-02-20 09:45:13 +00:00
|
|
|
$services->getObjectFactory(),
|
2020-10-10 21:03:11 +00:00
|
|
|
$services->getHookContainer(),
|
2020-04-08 18:19:49 +00:00
|
|
|
$services->getReadOnlyMode(),
|
2020-10-30 10:55:50 +00:00
|
|
|
$services->getUserNameUtils(),
|
|
|
|
|
$services->getBlockManager(),
|
2021-07-22 11:38:45 +00:00
|
|
|
$services->getWatchlistManager(),
|
|
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
$services->getContentLanguage(),
|
2021-08-05 21:09:06 +00:00
|
|
|
$services->getLanguageConverterFactory(),
|
|
|
|
|
$services->getBotPasswordStore(),
|
|
|
|
|
$services->getUserFactory(),
|
|
|
|
|
$services->getUserIdentityLookup(),
|
|
|
|
|
$services->getUserOptionsManager()
|
2019-11-08 21:24:00 +00:00
|
|
|
);
|
|
|
|
|
$authManager->setLogger( LoggerFactory::getInstance( 'authentication' ) );
|
|
|
|
|
return $authManager;
|
|
|
|
|
},
|
|
|
|
|
|
Move DatabaseBlock read query methods to DatabaseBlockStore
* Move to DatabaseBlockStore the DatabaseBlock methods newFromID,
getQueryInfo, getRangeCond, newFromRow, isExemptedFromAutoblocks,
doAutoblock, updateTimestamp, getAutoblockExpiry, newFromTarget,
newListFromTarget.
* Split DatabaseBlock::getBlocksForIPList. Now
BlockManager::getBlocksForIPList() is responsible for XFF header
validation and trusted proxy handling. DatabaseBlockStore::
newListFromIPs() just does the queries and constructs the Block
objects.
* In DatabaseBlockStore::newFromRow() and doAutoblock(), use the
DatabaseBlock constructor instead of calling many setter methods. Add
constructor options decodedExpiry, decodedTimestamp, id,
parentBlockId and restrictions to support this.
* Move isExemptedFromAutoblocks() to its own service. Remove the cache
since in my testing with production eval.php, the WAN cache fetch is
10 times slower than just using the message cache, contradicting the
comment written in 2008.
* Fix AuthManagerTest which was previously passing an unrecognised
"restrictions" option to DatabaseBlock. Now that the option actually
works, we have to use the right type.
Bug: T255433
Change-Id: I5049e60be1681f67fcca133e569e315792dc42dd
2023-10-31 05:58:23 +00:00
|
|
|
'AutoblockExemptionList' => static function ( MediaWikiServices $services ): AutoblockExemptionList {
|
2023-11-03 18:16:40 +00:00
|
|
|
$messageFormatterFactory = new MessageFormatterFactory( Message::FORMAT_PLAIN );
|
|
|
|
|
return new AutoblockExemptionList(
|
|
|
|
|
LoggerFactory::getInstance( 'AutoblockExemptionList' ),
|
|
|
|
|
$messageFormatterFactory->getTextFormatter(
|
|
|
|
|
$services->getContentLanguage()->getCode()
|
|
|
|
|
)
|
|
|
|
|
);
|
Move DatabaseBlock read query methods to DatabaseBlockStore
* Move to DatabaseBlockStore the DatabaseBlock methods newFromID,
getQueryInfo, getRangeCond, newFromRow, isExemptedFromAutoblocks,
doAutoblock, updateTimestamp, getAutoblockExpiry, newFromTarget,
newListFromTarget.
* Split DatabaseBlock::getBlocksForIPList. Now
BlockManager::getBlocksForIPList() is responsible for XFF header
validation and trusted proxy handling. DatabaseBlockStore::
newListFromIPs() just does the queries and constructs the Block
objects.
* In DatabaseBlockStore::newFromRow() and doAutoblock(), use the
DatabaseBlock constructor instead of calling many setter methods. Add
constructor options decodedExpiry, decodedTimestamp, id,
parentBlockId and restrictions to support this.
* Move isExemptedFromAutoblocks() to its own service. Remove the cache
since in my testing with production eval.php, the WAN cache fetch is
10 times slower than just using the message cache, contradicting the
comment written in 2008.
* Fix AuthManagerTest which was previously passing an unrecognised
"restrictions" option to DatabaseBlock. Now that the option actually
works, we have to use the right type.
Bug: T255433
Change-Id: I5049e60be1681f67fcca133e569e315792dc42dd
2023-10-31 05:58:23 +00:00
|
|
|
},
|
|
|
|
|
|
2021-09-08 17:19:11 +00:00
|
|
|
'BacklinkCacheFactory' => static function ( MediaWikiServices $services ): BacklinkCacheFactory {
|
2022-11-19 21:37:44 +00:00
|
|
|
return new BacklinkCacheFactory(
|
2023-10-02 18:10:11 +00:00
|
|
|
new ServiceOptions(
|
|
|
|
|
BacklinkCache::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$services->getLinksMigration(),
|
2022-11-19 21:37:44 +00:00
|
|
|
$services->getMainWANObjectCache(),
|
2023-07-05 08:57:11 +00:00
|
|
|
$services->getHookContainer(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider()
|
2022-11-19 21:37:44 +00:00
|
|
|
);
|
2021-09-08 17:19:11 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'BadFileLookup' => static function ( MediaWikiServices $services ): BadFileLookup {
|
2019-08-18 18:19:05 +00:00
|
|
|
return new BadFileLookup(
|
2021-02-10 22:31:02 +00:00
|
|
|
static function () {
|
2019-08-18 18:19:05 +00:00
|
|
|
return wfMessage( 'bad_image_list' )->inContentLanguage()->plain();
|
|
|
|
|
},
|
|
|
|
|
$services->getLocalServerObjectCache(),
|
|
|
|
|
$services->getRepoGroup(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getTitleParser(),
|
|
|
|
|
$services->getHookContainer()
|
2019-08-18 18:19:05 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'BlobStore' => static function ( MediaWikiServices $services ): BlobStore {
|
2018-08-03 08:05:44 +00:00
|
|
|
return $services->getService( '_SqlBlobStore' );
|
2016-05-01 19:29:11 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'BlobStoreFactory' => static function ( MediaWikiServices $services ): BlobStoreFactory {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new BlobStoreFactory(
|
2018-08-22 06:47:04 +00:00
|
|
|
$services->getDBLoadBalancerFactory(),
|
2018-02-27 06:24:46 +00:00
|
|
|
$services->getExternalStoreAccess(),
|
2018-08-03 08:05:44 +00:00
|
|
|
$services->getMainWANObjectCache(),
|
2019-10-08 18:27:22 +00:00
|
|
|
new ServiceOptions( BlobStoreFactory::CONSTRUCTOR_OPTIONS,
|
2019-10-01 16:20:45 +00:00
|
|
|
$services->getMainConfig() )
|
2018-08-03 08:05:44 +00:00
|
|
|
);
|
2015-10-12 08:05:45 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'BlockActionInfo' => static function ( MediaWikiServices $services ): BlockActionInfo {
|
2021-04-19 10:18:20 +00:00
|
|
|
return new BlockActionInfo( $services->getHookContainer() );
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'BlockErrorFormatter' => static function ( MediaWikiServices $services ): BlockErrorFormatter {
|
2023-10-01 12:03:37 +00:00
|
|
|
return $services->getFormatterFactory()->getBlockErrorFormatter(
|
|
|
|
|
new LazyLocalizationContext( static function () {
|
|
|
|
|
return RequestContext::getMain();
|
|
|
|
|
} )
|
2020-10-12 20:41:01 +00:00
|
|
|
);
|
2019-09-20 15:03:48 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'BlockManager' => static function ( MediaWikiServices $services ): BlockManager {
|
2019-04-05 19:13:17 +00:00
|
|
|
return new BlockManager(
|
2019-06-26 14:06:01 +00:00
|
|
|
new ServiceOptions(
|
2020-12-16 20:07:38 +00:00
|
|
|
BlockManager::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
2019-06-26 14:06:01 +00:00
|
|
|
),
|
2021-05-26 20:14:10 +00:00
|
|
|
$services->getUserFactory(),
|
2023-08-07 09:56:43 +00:00
|
|
|
$services->getUserIdentityUtils(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
LoggerFactory::getInstance( 'BlockManager' ),
|
2023-10-31 07:57:33 +00:00
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getDatabaseBlockStore(),
|
|
|
|
|
$services->getProxyLookup()
|
2019-04-05 19:13:17 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-02-10 22:31:02 +00:00
|
|
|
'BlockPermissionCheckerFactory' => static function (
|
2020-05-07 18:50:24 +00:00
|
|
|
MediaWikiServices $services
|
2021-07-22 03:11:47 +00:00
|
|
|
): BlockPermissionCheckerFactory {
|
2020-05-07 18:50:24 +00:00
|
|
|
return new BlockPermissionCheckerFactory(
|
2020-09-18 19:40:19 +00:00
|
|
|
new ServiceOptions(
|
|
|
|
|
BlockPermissionCheckerFactory::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
2021-03-10 19:40:33 +00:00
|
|
|
$services->getBlockUtils()
|
2020-05-07 18:50:24 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'BlockRestrictionStore' => static function ( MediaWikiServices $services ): BlockRestrictionStore {
|
2021-09-28 17:21:37 +00:00
|
|
|
return $services->getBlockRestrictionStoreFactory()->getBlockRestrictionStore( WikiAwareEntity::LOCAL );
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'BlockRestrictionStoreFactory' => static function ( MediaWikiServices $services ): BlockRestrictionStoreFactory {
|
|
|
|
|
return new BlockRestrictionStoreFactory(
|
Support new block schema
Support migration stages when reading and writing blocks.
I tried to set it up for an easy next stage, in which support for the
old schema is removed. I tried to avoid factoring out of shared code
between the two schemas, so that the old schema cases can simply be
deleted without the need to revert unnecessary abstractions.
However, I added HideUserUtils to factor out ipb_deleted queries. Code
review showed that this was already quite complex, with multiple
approaches to the problem, so it benefits from refactoring even without
the schema abstraction.
HideUserUtils is a service rather than a standalone class to support
unit tests, since unit tests do not allow global config access. When
the migration stage config is removed, it will be a service with no
constructor parameters -- an unnecessary abstraction which should
ideally be resolved at that time.
When interpreting result rows, it is possible to share code by using
field aliases. But when constructing WHERE conditions, the actual field
names need to be used, so the migration is more intrusive in
ApiQueryBlocks and SpecialBlockList, where complex conditions are used.
Bug: T346293
Bug: T51504
Bug: T349883
Change-Id: I408acf7a57b0100fe18c455fc13141277a598925
2023-10-27 03:34:10 +00:00
|
|
|
$services->getDBLoadBalancerFactory(),
|
|
|
|
|
$services->getMainConfig()->get( MainConfigNames::BlockTargetMigrationStage )
|
2019-04-11 19:54:10 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'BlockUserFactory' => static function ( MediaWikiServices $services ): BlockUserFactory {
|
2020-04-23 19:33:56 +00:00
|
|
|
return $services->getService( '_UserBlockCommandFactory' );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'BlockUtils' => static function ( MediaWikiServices $services ): BlockUtils {
|
2024-01-03 18:40:04 +00:00
|
|
|
return $services->getBlockUtilsFactory()->getBlockUtils();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'BlockUtilsFactory' => static function ( MediaWikiServices $services ): BlockUtilsFactory {
|
|
|
|
|
return new BlockUtilsFactory(
|
2020-09-18 19:01:34 +00:00
|
|
|
new ServiceOptions(
|
2024-01-03 18:40:04 +00:00
|
|
|
BlockUtilsFactory::CONSTRUCTOR_OPTIONS,
|
2020-09-18 19:01:34 +00:00
|
|
|
$services->getMainConfig()
|
2020-10-06 21:27:06 +00:00
|
|
|
),
|
2024-01-03 18:40:04 +00:00
|
|
|
$services->getActorStoreFactory(),
|
2024-01-12 12:41:47 +00:00
|
|
|
$services->getUserNameUtils(),
|
|
|
|
|
$services->getDBLoadBalancerFactory()
|
2020-09-18 19:01:34 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'BotPasswordStore' => static function ( MediaWikiServices $services ): BotPasswordStore {
|
2020-10-30 17:33:33 +00:00
|
|
|
return new BotPasswordStore(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
BotPasswordStore::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$services->getCentralIdLookup(),
|
|
|
|
|
$services->getDBLoadBalancerFactory()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'CentralIdLookup' => static function ( MediaWikiServices $services ): CentralIdLookup {
|
2021-06-22 19:28:29 +00:00
|
|
|
return $services->getCentralIdLookupFactory()->getLookup();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'CentralIdLookupFactory' => static function ( MediaWikiServices $services ): CentralIdLookupFactory {
|
2021-06-22 19:28:29 +00:00
|
|
|
return new CentralIdLookupFactory(
|
|
|
|
|
new ServiceOptions( CentralIdLookupFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
2021-06-22 21:26:40 +00:00
|
|
|
$services->getObjectFactory(),
|
2024-01-22 20:28:07 +00:00
|
|
|
$services->getUserIdentityLookup(),
|
|
|
|
|
$services->getUserFactory()
|
2021-06-22 19:28:29 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ChangeTagDefStore' => static function ( MediaWikiServices $services ): NameTableStore {
|
2020-05-27 14:45:29 +00:00
|
|
|
return $services->getNameTableStoreFactory()->getChangeTagDef();
|
|
|
|
|
},
|
|
|
|
|
|
2023-05-07 00:26:40 +00:00
|
|
|
'ChangeTagsStore' => static function ( MediaWikiServices $services ): ChangeTagsStore {
|
|
|
|
|
return new ChangeTagsStore(
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2023-05-07 00:26:40 +00:00
|
|
|
$services->getChangeTagDefStore(),
|
|
|
|
|
$services->getMainWANObjectCache(),
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
LoggerFactory::getInstance( 'ChangeTags' ),
|
2023-06-02 11:26:53 +00:00
|
|
|
$services->getUserFactory(),
|
2023-05-07 00:26:40 +00:00
|
|
|
new ServiceOptions(
|
|
|
|
|
ChangeTagsStore::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2023-08-25 11:03:30 +00:00
|
|
|
'ChronologyProtector' => static function ( MediaWikiServices $services ): ChronologyProtector {
|
|
|
|
|
$mainConfig = $services->getMainConfig();
|
|
|
|
|
$cpStashType = $mainConfig->get( MainConfigNames::ChronologyProtectorStash );
|
|
|
|
|
$isMainCacheBad = ObjectCache::isDatabaseId( $mainConfig->get( MainConfigNames::MainCacheType ) );
|
|
|
|
|
|
|
|
|
|
if ( is_string( $cpStashType ) ) {
|
|
|
|
|
$cpStash = ObjectCache::getInstance( $cpStashType );
|
|
|
|
|
} elseif ( $isMainCacheBad ) {
|
|
|
|
|
$cpStash = new EmptyBagOStuff();
|
|
|
|
|
} else {
|
|
|
|
|
$cpStash = ObjectCache::getLocalClusterInstance();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$chronologyProtector = new ChronologyProtector(
|
|
|
|
|
$cpStash,
|
|
|
|
|
$mainConfig->get( MainConfigNames::ChronologyProtectorSecret ),
|
2023-12-18 18:54:59 +00:00
|
|
|
MW_ENTRY_POINT === 'cli',
|
2023-08-25 11:03:30 +00:00
|
|
|
LoggerFactory::getInstance( 'rdbms' )
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Use the global WebRequest singleton. The main reason for using this
|
|
|
|
|
// is to call WebRequest::getIP() which is non-trivial to reproduce statically
|
|
|
|
|
// because it needs $wgUsePrivateIPs, as well as ProxyLookup and HookRunner services.
|
|
|
|
|
// TODO: Create a static version of WebRequest::getIP that accepts these three
|
|
|
|
|
// as dependencies, and then call that here. The other uses of $req below can
|
|
|
|
|
// trivially use $_COOKIES, $_GET and $_SERVER instead.
|
|
|
|
|
$req = RequestContext::getMain()->getRequest();
|
|
|
|
|
|
|
|
|
|
// Set user IP/agent information for agent session consistency purposes
|
|
|
|
|
$reqStart = (int)( $_SERVER['REQUEST_TIME_FLOAT'] ?? time() );
|
|
|
|
|
$cpPosInfo = ChronologyProtector::getCPInfoFromCookieValue(
|
|
|
|
|
// The cookie has no prefix and is set by MediaWiki::preOutputCommit()
|
|
|
|
|
$req->getCookie( 'cpPosIndex', '' ),
|
|
|
|
|
// Mitigate broken client-side cookie expiration handling (T190082)
|
|
|
|
|
$reqStart - ChronologyProtector::POSITION_COOKIE_TTL
|
|
|
|
|
);
|
|
|
|
|
$chronologyProtector->setRequestInfo( [
|
|
|
|
|
'IPAddress' => $req->getIP(),
|
|
|
|
|
'UserAgent' => $req->getHeader( 'User-Agent' ),
|
|
|
|
|
'ChronologyPositionIndex' => $req->getInt( 'cpPosIndex', $cpPosInfo['index'] ),
|
|
|
|
|
'ChronologyClientId' => $cpPosInfo['clientId'] ?? null,
|
|
|
|
|
] );
|
|
|
|
|
return $chronologyProtector;
|
|
|
|
|
},
|
|
|
|
|
|
2021-08-24 19:12:39 +00:00
|
|
|
'CollationFactory' => static function ( MediaWikiServices $services ): CollationFactory {
|
|
|
|
|
return new CollationFactory(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
CollationFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
|
|
|
|
$services->getObjectFactory(),
|
|
|
|
|
$services->getHookContainer()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
Introduce CommentFormatter
CommentParser:
* Move comment formatting backend from Linker to a CommentParser service.
Allow link existence and file existence to be batched.
* Rename $local to $samePage since I think that is clearer.
* Rename $title to $selfLinkTarget since it was unclear what the title
was used for.
* Rename the "autocomment" concept to "section link" in public
interfaces, although the old term remains in CSS classes.
* Keep unsafe HTML pass-through in separate "unsafe" methods, for easier
static analysis and code review.
CommentFormatter:
* Add CommentFormatter and RowCommentFormatter services as a usable
frontend for comment batches, and to replace the Linker static methods.
* Provide fluent and parametric interfaces.
Linker:
* Remove Linker::makeCommentLink() without deprecation -- nothing calls
it and it is obviously an internal helper.
* Soft-deprecate Linker methods formatComment(), formatLinksInComment(),
commentBlock() and revComment().
Caller migration:
* CommentFormatter single: Linker, RollbackAction, ApiComparePages,
ApiParse
* CommentFormatter parametric batch: ImageHistoryPseudoPager
* CommentFormatter fluent batch: ApiQueryFilearchive
* RowCommentFormatter sequential: History feed, BlocklistPager,
ProtectedPagesPager, ApiQueryProtectedTitles
* RowCommentFormatter with index: ChangesFeed, ChangesList,
ApiQueryDeletedrevs, ApiQueryLogEvents, ApiQueryRecentChanges
* RevisionCommentBatch: HistoryPager, ContribsPager
Bug: T285917
Change-Id: Ia3fd50a4a13138ba5003d884962da24746d562d0
2021-07-01 06:55:03 +00:00
|
|
|
'CommentFormatter' => static function ( MediaWikiServices $services ): CommentFormatter {
|
2023-05-05 09:45:35 +00:00
|
|
|
return new CommentFormatter(
|
|
|
|
|
$services->getCommentParserFactory()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'CommentParserFactory' => static function ( MediaWikiServices $services ): CommentParserFactory {
|
|
|
|
|
return new CommentParserFactory(
|
|
|
|
|
$services->getLinkRendererFactory()->create( [ 'renderForComment' => true ] ),
|
Introduce CommentFormatter
CommentParser:
* Move comment formatting backend from Linker to a CommentParser service.
Allow link existence and file existence to be batched.
* Rename $local to $samePage since I think that is clearer.
* Rename $title to $selfLinkTarget since it was unclear what the title
was used for.
* Rename the "autocomment" concept to "section link" in public
interfaces, although the old term remains in CSS classes.
* Keep unsafe HTML pass-through in separate "unsafe" methods, for easier
static analysis and code review.
CommentFormatter:
* Add CommentFormatter and RowCommentFormatter services as a usable
frontend for comment batches, and to replace the Linker static methods.
* Provide fluent and parametric interfaces.
Linker:
* Remove Linker::makeCommentLink() without deprecation -- nothing calls
it and it is obviously an internal helper.
* Soft-deprecate Linker methods formatComment(), formatLinksInComment(),
commentBlock() and revComment().
Caller migration:
* CommentFormatter single: Linker, RollbackAction, ApiComparePages,
ApiParse
* CommentFormatter parametric batch: ImageHistoryPseudoPager
* CommentFormatter fluent batch: ApiQueryFilearchive
* RowCommentFormatter sequential: History feed, BlocklistPager,
ProtectedPagesPager, ApiQueryProtectedTitles
* RowCommentFormatter with index: ChangesFeed, ChangesList,
ApiQueryDeletedrevs, ApiQueryLogEvents, ApiQueryRecentChanges
* RevisionCommentBatch: HistoryPager, ContribsPager
Bug: T285917
Change-Id: Ia3fd50a4a13138ba5003d884962da24746d562d0
2021-07-01 06:55:03 +00:00
|
|
|
$services->getLinkBatchFactory(),
|
|
|
|
|
$services->getLinkCache(),
|
|
|
|
|
$services->getRepoGroup(),
|
|
|
|
|
RequestContext::getMain()->getLanguage(),
|
|
|
|
|
$services->getContentLanguage(),
|
|
|
|
|
$services->getTitleParser(),
|
|
|
|
|
$services->getNamespaceInfo(),
|
|
|
|
|
$services->getHookContainer()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'CommentStore' => static function ( MediaWikiServices $services ): CommentStore {
|
2023-08-29 10:34:53 +00:00
|
|
|
return new CommentStore( $services->getContentLanguage() );
|
2015-10-12 08:05:45 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ConfigFactory' => static function ( MediaWikiServices $services ): ConfigFactory {
|
2015-10-12 08:05:45 +00:00
|
|
|
// Use the bootstrap config to initialize the ConfigFactory.
|
2022-04-01 15:58:32 +00:00
|
|
|
$registry = $services->getBootstrapConfig()->get( MainConfigNames::ConfigRegistry );
|
2015-10-12 08:05:45 +00:00
|
|
|
$factory = new ConfigFactory();
|
|
|
|
|
|
|
|
|
|
foreach ( $registry as $name => $callback ) {
|
|
|
|
|
$factory->register( $name, $callback );
|
|
|
|
|
}
|
|
|
|
|
return $factory;
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ConfigRepository' => static function ( MediaWikiServices $services ): ConfigRepository {
|
2016-12-14 20:55:56 +00:00
|
|
|
return new ConfigRepository( $services->getConfigFactory() );
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-21 16:28:35 +00:00
|
|
|
'ConfigSchema' => static function ( MediaWikiServices $services ): ConfigSchema {
|
2022-11-06 20:35:07 +00:00
|
|
|
/** @var SettingsBuilder $settings */
|
|
|
|
|
$settings = $services->get( '_SettingsBuilder' );
|
|
|
|
|
return $settings->getConfigSchema();
|
2022-02-21 16:28:35 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ConfiguredReadOnlyMode' => static function ( MediaWikiServices $services ): ConfiguredReadOnlyMode {
|
2019-04-10 15:03:54 +00:00
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
return new ConfiguredReadOnlyMode(
|
2022-04-01 15:58:32 +00:00
|
|
|
$config->get( MainConfigNames::ReadOnly ),
|
|
|
|
|
$config->get( MainConfigNames::ReadOnlyFile )
|
2019-04-10 15:03:54 +00:00
|
|
|
);
|
2015-10-12 08:05:45 +00:00
|
|
|
},
|
|
|
|
|
|
2024-01-13 07:50:18 +00:00
|
|
|
'ConnectionProvider' => static function ( MediaWikiServices $services ): IConnectionProvider {
|
|
|
|
|
return $services->getDBLoadBalancerFactory();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ContentHandlerFactory' => static function ( MediaWikiServices $services ): IContentHandlerFactory {
|
2022-04-01 15:58:32 +00:00
|
|
|
$contentHandlerConfig = $services->getMainConfig()->get( MainConfigNames::ContentHandlers );
|
2020-01-18 20:25:04 +00:00
|
|
|
|
2020-01-18 20:25:04 +00:00
|
|
|
return new ContentHandlerFactory(
|
|
|
|
|
$contentHandlerConfig,
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getObjectFactory(),
|
2020-06-01 01:53:14 +00:00
|
|
|
$services->getHookContainer(),
|
|
|
|
|
LoggerFactory::getInstance( 'ContentHandler' )
|
2020-01-18 20:25:04 +00:00
|
|
|
);
|
2020-01-18 20:25:04 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ContentLanguage' => static function ( MediaWikiServices $services ): Language {
|
2018-08-07 13:17:16 +00:00
|
|
|
return $services->getLanguageFactory()->getLanguage(
|
2022-04-01 15:58:32 +00:00
|
|
|
$services->getMainConfig()->get( MainConfigNames::LanguageCode ) );
|
2015-10-30 22:04:52 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ContentModelChangeFactory' => static function ( MediaWikiServices $services ): ContentModelChangeFactory {
|
2020-05-30 19:10:58 +00:00
|
|
|
return $services->getService( '_PageCommandFactory' );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ContentModelStore' => static function ( MediaWikiServices $services ): NameTableStore {
|
2020-05-27 14:45:29 +00:00
|
|
|
return $services->getNameTableStoreFactory()->getContentModels();
|
|
|
|
|
},
|
|
|
|
|
|
2021-08-24 12:17:12 +00:00
|
|
|
'ContentRenderer' => static function ( MediaWikiServices $services ): ContentRenderer {
|
Add ParserOutput::{get,set}RenderId() and set render id in ContentRenderer
Set the render ID for each parse stored into cache so that we are able
to identify a specific parse when there are dependencies (for example
in an edit based on that parse). This is recorded as a property added
to the ParserOutput, not the parent CacheTime interface. Even though
the render ID is /related/ to the CacheTime interface, CacheTime is
also used directly as a parser cache key, and the UUID should not be
part of the lookup key.
In general we are trying to move the location where these cache
properties are set as early as possible, so we check at each location
to ensure we don't overwrite a previously-set value. Eventually we
can convert most of these checks into assertions that the cache
properties have already been set (T350538). The primary location for
setting cache properties is the ContentRenderer.
Moved setting the revision timestamp into ContentRenderer as well, as
it was set along the same code paths. An extra parameter was added to
ContentRenderer::getParserOutput() to support this.
Added merge code to ParserOutput::mergeInternalMetaDataFrom() which
should ensure that cache time, revision, timestamp, and render id are
all set properly when multiple slots are combined together in MCR.
In order to ensure the render ID is set on all codepaths we needed to
plumb the GlobalIdGenerator service into ContentRenderer, ParserCache,
ParserCacheFactory, and RevisionOutputCache. Eventually (T350538) it
should only be necessary in the ContentRenderer.
Bug: T350538
Bug: T349868
Followup-To: Ic9b7cc0fcf365e772b7d080d76a065e3fd585f80
Change-Id: I72c5e6f86b7f081ab5ce7a56f5365d2f75067a78
2023-09-14 16:11:20 +00:00
|
|
|
return new ContentRenderer(
|
|
|
|
|
$services->getContentHandlerFactory(),
|
|
|
|
|
$services->getGlobalIdGenerator()
|
|
|
|
|
);
|
2021-08-24 12:17:12 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-21 01:03:59 +00:00
|
|
|
'ContentTransformer' => static function ( MediaWikiServices $services ): ContentTransformer {
|
|
|
|
|
return new ContentTransformer( $services->getContentHandlerFactory() );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ContributionsLookup' => static function ( MediaWikiServices $services ): ContributionsLookup {
|
2020-09-19 22:43:46 +00:00
|
|
|
return new ContributionsLookup(
|
|
|
|
|
$services->getRevisionStore(),
|
2021-08-26 19:01:49 +00:00
|
|
|
$services->getLinkRendererFactory(),
|
2020-09-19 22:43:46 +00:00
|
|
|
$services->getLinkBatchFactory(),
|
|
|
|
|
$services->getHookContainer(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
Introduce CommentFormatter
CommentParser:
* Move comment formatting backend from Linker to a CommentParser service.
Allow link existence and file existence to be batched.
* Rename $local to $samePage since I think that is clearer.
* Rename $title to $selfLinkTarget since it was unclear what the title
was used for.
* Rename the "autocomment" concept to "section link" in public
interfaces, although the old term remains in CSS classes.
* Keep unsafe HTML pass-through in separate "unsafe" methods, for easier
static analysis and code review.
CommentFormatter:
* Add CommentFormatter and RowCommentFormatter services as a usable
frontend for comment batches, and to replace the Linker static methods.
* Provide fluent and parametric interfaces.
Linker:
* Remove Linker::makeCommentLink() without deprecation -- nothing calls
it and it is obviously an internal helper.
* Soft-deprecate Linker methods formatComment(), formatLinksInComment(),
commentBlock() and revComment().
Caller migration:
* CommentFormatter single: Linker, RollbackAction, ApiComparePages,
ApiParse
* CommentFormatter parametric batch: ImageHistoryPseudoPager
* CommentFormatter fluent batch: ApiQueryFilearchive
* RowCommentFormatter sequential: History feed, BlocklistPager,
ProtectedPagesPager, ApiQueryProtectedTitles
* RowCommentFormatter with index: ChangesFeed, ChangesList,
ApiQueryDeletedrevs, ApiQueryLogEvents, ApiQueryRecentChanges
* RevisionCommentBatch: HistoryPager, ContribsPager
Bug: T285917
Change-Id: Ia3fd50a4a13138ba5003d884962da24746d562d0
2021-07-01 06:55:03 +00:00
|
|
|
$services->getNamespaceInfo(),
|
|
|
|
|
$services->getCommentFormatter()
|
2020-09-19 22:43:46 +00:00
|
|
|
);
|
2020-06-02 21:24:59 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'CriticalSectionProvider' => static function ( MediaWikiServices $services ): CriticalSectionProvider {
|
2021-01-06 05:23:15 +00:00
|
|
|
$config = $services->getMainConfig();
|
2023-12-18 18:54:59 +00:00
|
|
|
$limit = MW_ENTRY_POINT === 'cli' ? INF : $config->get( MainConfigNames::CriticalSectionTimeLimit );
|
2021-01-06 05:23:15 +00:00
|
|
|
return RequestTimeout::singleton()->createCriticalSectionProvider( $limit );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'CryptHKDF' => static function ( MediaWikiServices $services ): CryptHKDF {
|
2018-07-02 17:01:45 +00:00
|
|
|
$config = $services->getMainConfig();
|
2018-08-03 08:05:44 +00:00
|
|
|
|
2022-04-01 15:58:32 +00:00
|
|
|
$secret = $config->get( MainConfigNames::HKDFSecret ) ?: $config->get( MainConfigNames::SecretKey );
|
2018-08-03 08:05:44 +00:00
|
|
|
if ( !$secret ) {
|
|
|
|
|
throw new RuntimeException( "Cannot use MWCryptHKDF without a secret." );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// In HKDF, the context can be known to the attacker, but this will
|
|
|
|
|
// keep simultaneous runs from producing the same output.
|
|
|
|
|
$context = [ microtime(), getmypid(), gethostname() ];
|
|
|
|
|
|
|
|
|
|
// Setup salt cache. Use APC, or fallback to the main cache if it isn't setup
|
|
|
|
|
$cache = $services->getLocalServerObjectCache();
|
|
|
|
|
if ( $cache instanceof EmptyBagOStuff ) {
|
|
|
|
|
$cache = ObjectCache::getLocalClusterInstance();
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-01 15:58:32 +00:00
|
|
|
return new CryptHKDF( $secret, $config->get( MainConfigNames::HKDFAlgorithm ), $cache, $context );
|
2018-08-03 08:05:44 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'DatabaseBlockStore' => static function ( MediaWikiServices $services ): DatabaseBlockStore {
|
2022-09-07 15:23:14 +00:00
|
|
|
return $services->getDatabaseBlockStoreFactory()->getDatabaseBlockStore( DatabaseBlock::LOCAL );
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'DatabaseBlockStoreFactory' => static function ( MediaWikiServices $services ): DatabaseBlockStoreFactory {
|
|
|
|
|
return new DatabaseBlockStoreFactory(
|
2020-05-08 06:29:23 +00:00
|
|
|
new ServiceOptions(
|
2022-09-07 15:23:14 +00:00
|
|
|
DatabaseBlockStoreFactory::CONSTRUCTOR_OPTIONS,
|
2020-05-08 06:29:23 +00:00
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
LoggerFactory::getInstance( 'DatabaseBlockStore' ),
|
2021-05-05 21:34:14 +00:00
|
|
|
$services->getActorStoreFactory(),
|
2022-09-07 15:23:14 +00:00
|
|
|
$services->getBlockRestrictionStoreFactory(),
|
2020-05-08 06:29:23 +00:00
|
|
|
$services->getCommentStore(),
|
|
|
|
|
$services->getHookContainer(),
|
2022-09-07 15:23:14 +00:00
|
|
|
$services->getDBLoadBalancerFactory(),
|
2023-09-08 11:58:27 +00:00
|
|
|
$services->getReadOnlyMode(),
|
Move DatabaseBlock read query methods to DatabaseBlockStore
* Move to DatabaseBlockStore the DatabaseBlock methods newFromID,
getQueryInfo, getRangeCond, newFromRow, isExemptedFromAutoblocks,
doAutoblock, updateTimestamp, getAutoblockExpiry, newFromTarget,
newListFromTarget.
* Split DatabaseBlock::getBlocksForIPList. Now
BlockManager::getBlocksForIPList() is responsible for XFF header
validation and trusted proxy handling. DatabaseBlockStore::
newListFromIPs() just does the queries and constructs the Block
objects.
* In DatabaseBlockStore::newFromRow() and doAutoblock(), use the
DatabaseBlock constructor instead of calling many setter methods. Add
constructor options decodedExpiry, decodedTimestamp, id,
parentBlockId and restrictions to support this.
* Move isExemptedFromAutoblocks() to its own service. Remove the cache
since in my testing with production eval.php, the WAN cache fetch is
10 times slower than just using the message cache, contradicting the
comment written in 2008.
* Fix AuthManagerTest which was previously passing an unrecognised
"restrictions" option to DatabaseBlock. Now that the option actually
works, we have to use the right type.
Bug: T255433
Change-Id: I5049e60be1681f67fcca133e569e315792dc42dd
2023-10-31 05:58:23 +00:00
|
|
|
$services->getUserFactory(),
|
|
|
|
|
$services->getTempUserConfig(),
|
2024-01-03 18:40:04 +00:00
|
|
|
$services->getBlockUtilsFactory(),
|
Move DatabaseBlock read query methods to DatabaseBlockStore
* Move to DatabaseBlockStore the DatabaseBlock methods newFromID,
getQueryInfo, getRangeCond, newFromRow, isExemptedFromAutoblocks,
doAutoblock, updateTimestamp, getAutoblockExpiry, newFromTarget,
newListFromTarget.
* Split DatabaseBlock::getBlocksForIPList. Now
BlockManager::getBlocksForIPList() is responsible for XFF header
validation and trusted proxy handling. DatabaseBlockStore::
newListFromIPs() just does the queries and constructs the Block
objects.
* In DatabaseBlockStore::newFromRow() and doAutoblock(), use the
DatabaseBlock constructor instead of calling many setter methods. Add
constructor options decodedExpiry, decodedTimestamp, id,
parentBlockId and restrictions to support this.
* Move isExemptedFromAutoblocks() to its own service. Remove the cache
since in my testing with production eval.php, the WAN cache fetch is
10 times slower than just using the message cache, contradicting the
comment written in 2008.
* Fix AuthManagerTest which was previously passing an unrecognised
"restrictions" option to DatabaseBlock. Now that the option actually
works, we have to use the right type.
Bug: T255433
Change-Id: I5049e60be1681f67fcca133e569e315792dc42dd
2023-10-31 05:58:23 +00:00
|
|
|
$services->getAutoblockExemptionList()
|
2020-05-08 06:29:23 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2020-07-23 09:31:57 +00:00
|
|
|
'DatabaseFactory' => static function ( MediaWikiServices $services ): DatabaseFactory {
|
2023-09-05 16:12:02 +00:00
|
|
|
return new DatabaseFactory(
|
|
|
|
|
[ 'debugSql' => $services->getMainConfig()->get( MainConfigNames::DebugDumpSql ) ]
|
|
|
|
|
);
|
2020-07-23 09:31:57 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'DateFormatterFactory' => static function ( MediaWikiServices $services ): DateFormatterFactory {
|
2020-07-16 16:04:59 +00:00
|
|
|
return new DateFormatterFactory();
|
Rehabilitate DateFormatter
This code is surprisingly little changed since I added the class in
November 2003, and needs some modernisation.
* Remove the "linked" option, unused since 1.21. Similarly, make the
"match-whole" option implied. This allows the regexes to be
simplified. Nothing will be broken, according to CodeSearch.
* Instead of ucfirst(), use the canonical month name from the language.
This will work with e.g. French which does not capitalise month names.
* Stop caching DateFormatter instances in APC. Caching was added
in 2005 when initialisation was being done on every request, but now
it is only needed when parsing a page with {{#formatdate}}, which is
rarely, and the constructor overhead is only 200µs after Language
object data initialisation. Instead, use an in-process cache via a
factory service.
* Add docs and extra tests.
* Remove todo note obsolete since 38 minutes after the original commit.
* Rename many variables.
* Use double-slash comments
* Don't store the Language object, just get arrays.
* Use mb_strtolower() instead of Language::lc() -- any customisation of
Language::lc() would break PCRE case-insensitive matching.
* Use named subpatterns instead of "keys"
* Remove the ISO1/ISO2 distinction, the only difference was linking.
* Use closure variables instead of temporary object members
Change-Id: I25fb1203dba2930724d7bc28ad0d51f59f88e1ea
2019-04-10 05:33:57 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'DBLoadBalancer' => static function ( MediaWikiServices $services ): Wikimedia\Rdbms\ILoadBalancer {
|
2018-08-03 08:05:44 +00:00
|
|
|
// just return the default LB from the DBLoadBalancerFactory service
|
|
|
|
|
return $services->getDBLoadBalancerFactory()->getMainLB();
|
|
|
|
|
},
|
|
|
|
|
|
2023-10-12 21:52:47 +00:00
|
|
|
'DBLoadBalancerFactory' => static function ( MediaWikiServices $services ): Wikimedia\Rdbms\LBFactory {
|
2018-08-03 08:05:44 +00:00
|
|
|
$mainConfig = $services->getMainConfig();
|
2022-05-24 13:50:02 +00:00
|
|
|
$lbFactoryConfigBuilder = $services->getDBLoadBalancerFactoryConfigBuilder();
|
2018-08-03 08:05:44 +00:00
|
|
|
|
2022-05-24 13:50:02 +00:00
|
|
|
$lbConf = $lbFactoryConfigBuilder->applyDefaultConfig(
|
|
|
|
|
$mainConfig->get( MainConfigNames::LBFactoryConf )
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$class = $lbFactoryConfigBuilder->getLBFactoryClass( $lbConf );
|
|
|
|
|
$instance = new $class( $lbConf );
|
|
|
|
|
|
|
|
|
|
$lbFactoryConfigBuilder->setDomainAliases( $instance );
|
|
|
|
|
|
|
|
|
|
// NOTE: This accesses ProxyLookup from the MediaWikiServices singleton
|
2022-10-27 13:14:16 +00:00
|
|
|
// for non-essential non-nonimal purposes (via WebRequest::getIP).
|
2022-05-24 13:50:02 +00:00
|
|
|
// This state is fine (and meant) to be consistent for a given PHP process,
|
|
|
|
|
// even if applied to the service container for a different wiki.
|
|
|
|
|
$lbFactoryConfigBuilder->applyGlobalState(
|
|
|
|
|
$instance,
|
|
|
|
|
$mainConfig,
|
|
|
|
|
$services->getStatsdDataFactory()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return $instance;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'DBLoadBalancerFactoryConfigBuilder' => static function ( MediaWikiServices $services ): MWLBFactory {
|
2023-05-03 02:14:13 +00:00
|
|
|
$mainConfig = $services->getMainConfig();
|
2023-08-25 11:03:30 +00:00
|
|
|
if ( ObjectCache::isDatabaseId( $mainConfig->get( MainConfigNames::MainCacheType ) ) ) {
|
2023-05-03 02:14:13 +00:00
|
|
|
$wanCache = WANObjectCache::newEmpty();
|
|
|
|
|
} else {
|
2019-11-04 22:02:33 +00:00
|
|
|
$wanCache = $services->getMainWANObjectCache();
|
|
|
|
|
}
|
2020-09-15 16:10:57 +00:00
|
|
|
$srvCache = $services->getLocalServerObjectCache();
|
|
|
|
|
if ( $srvCache instanceof EmptyBagOStuff ) {
|
2020-12-16 01:02:04 +00:00
|
|
|
// Use process cache if no APCU or other local-server cache (e.g. on CLI)
|
2020-09-15 16:10:57 +00:00
|
|
|
$srvCache = new HashBagOStuff( [ 'maxKeys' => 100 ] );
|
|
|
|
|
}
|
2023-08-25 11:03:30 +00:00
|
|
|
|
2022-05-24 13:50:02 +00:00
|
|
|
return new MWLBFactory(
|
|
|
|
|
new ServiceOptions( MWLBFactory::APPLY_DEFAULT_CONFIG_OPTIONS, $services->getMainConfig() ),
|
2023-09-11 18:39:11 +00:00
|
|
|
new ConfiguredReadOnlyMode(
|
|
|
|
|
$mainConfig->get( MainConfigNames::ReadOnly ),
|
|
|
|
|
$mainConfig->get( MainConfigNames::ReadOnlyFile )
|
|
|
|
|
),
|
2023-08-25 11:03:30 +00:00
|
|
|
$services->getChronologyProtector(),
|
2020-09-15 16:10:57 +00:00
|
|
|
$srvCache,
|
2020-12-01 05:08:32 +00:00
|
|
|
$wanCache,
|
2022-07-18 23:54:21 +00:00
|
|
|
$services->getCriticalSectionProvider(),
|
2023-10-04 11:41:19 +00:00
|
|
|
$services->getStatsdDataFactory(),
|
|
|
|
|
ExtensionRegistry::getInstance()->getAttribute( 'DatabaseVirtualDomains' )
|
2018-07-02 17:01:45 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2023-10-20 13:21:53 +00:00
|
|
|
'DefaultOutputPipeline' => static function ( MediaWikiServices $services ): OutputTransformPipeline {
|
|
|
|
|
return ( new DefaultOutputPipelineFactory(
|
2023-10-10 15:05:08 +00:00
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getTidy(),
|
parser: Move lang/dir and mw-content-ltr to ParserOutput::getText
== Skin::wrapHTML ==
Skin::wrapHTML no longer has to perform any guessing of the
ParserOutput language. Nor does it have to special wiki pages vs
special pages in this regard. Yay, code removal.
== ImagePage ==
On URLs like /wiki/File:Example.jpg, the main output handler is
ImagePage::view. This calls the parent Article::view to handle most of
its output. Article::view obtains the ParserOptions, and then fetches
ParserOutput, and then adds `<div class=mw-parser-output>` and its
metadata to OutputPage.
Before this change, ImagePage::view was creating a wrapper based
on "predicting" what language the ParserOutput will contain. It
couldn't call the new OutputPage::getContentLanguage or some
equivalent as Article::view wouldn't have populated that yet.
This leaky abstraction is fixed by this change as now the `<div>`
from ParserOutput no longer comes with a "please wrap it properly"
contract that Article subclasses couldn't possibly implement correctly
(it coudln't wrap it after the fact because Article::view writes to
OutputPage directly).
RECENT (T310445):
A special case was recently added for file pages about translated SVGs.
For those, we decide which language to use for the "fullMedia" thumb
atop the page. This was recently changed as part of T310445 from a
hardcoded $wgLanguageCode (site content lang) to new problematic
Title::getPageViewLanguage, which tries to guestimate the page
language of the rendered ParserOutput and then gets the preferred
variant for the current user. The motivation for this was to support
language variants but used Title::getPageViewLanguage as a kitchen
sink to achieve that minor side-effect. The only part of this
now-deprecated method that we actually need is
LanguageConverter::getPreferredVariant().
Test plan: Covered by ImagePageTest.
== Skin mainpage-title ==
RECENT (T331095, T298715):
A special case was added to Skin::getTemplateData that powers the
mainpage-title interface message feature. This is empty by default,
but when created via MediaWiki:mainpage-title allows interface admins
to replace the H1 with a custom and localised page heading.
A few months ago, in Ifc9f0a7174, Title::getPageViewLanguage was
applied here to support language variants. Replace with the same
fix as for ImagePage. Revert back to Message::inContentLanguage()
but refactor to inLanguage() via MediaWikiServices::getContentLanguage
so that LanguageConverter::getPreferredVariant can be applied.
== EditPage ==
This was doing similar "predicting" of the ParserOutput language to
create an empty preview placeholder for use by preview.js. Now that
ApiParse (via ParserOutput::getText) returns a usable element without
any secret "you magically know the right class, lang, and dir" contract,
this placeholder is no longer needed.
Test Plan:
* EditPage: Default preview
1. index.php?title=Main_Page&action=edit
2. Show preview
3. Assert <div class="mw-content-ltr mw-parser-output" lang=en dir=ltr>
* EditPage: JS preview
1. Preferences > Editing > Show preview without reload
2. index.php?title=Main_Page&action=edit
3. Show preview
4. Assert <div class="mw-content-ltr mw-parser-output" lang=en dir=ltr>
5. Type something and 'Show preview' again
6. Assert old element gone, new text is shown, and new element
attributes are the same as the above.
== McrUndoAction ==
Same as EditPage basically, but without the JS preview use case.
== DifferenceEngine ==
Test:
1. Open /w/index.php?title=Main_Page&diff=0
(this shows the latest diff, can do manually by viewing
/wiki/Main_Page, click "View history", click "Compare selected revisions")
2. Assert <div class="mw-content-ltr mw-parser-output" lang=en dir=ltr>
3. Open /w/index.php?title=Main_Page&diff=0&action=render
4. Assert <div class="mw-content-ltr mw-parser-output" lang=en dir=ltr>
== Special:ExpandTemplates ==
Test:
1. /wiki/Special:ExpandTemplates
2. Write "Hello".
3. "OK"
4. Assert <div class="mw-content-ltr mw-parser-output" lang=en dir=ltr>
Bug: T341244
Depends-On: Icd9c079f5896ee83d86b9c2699636dc81d25a14c
Depends-On: I4e7484b3b94f1cb6062e7cef9f20626b650bb4b1
Depends-On: I90b88f3b3a3bbeba4f48d118f92f54864997e105
Change-Id: Ib130a055e46764544af0f1a46d2bc2b3a7ee85b7
2023-10-04 04:45:07 +00:00
|
|
|
$services->getLanguageFactory(),
|
|
|
|
|
$services->getContentLanguage(),
|
2023-10-20 13:21:53 +00:00
|
|
|
LoggerFactory::getInstance( 'Parser' ),
|
|
|
|
|
$services->getTitleFactory()
|
|
|
|
|
) )->buildPipeline();
|
2023-10-10 15:05:08 +00:00
|
|
|
},
|
|
|
|
|
|
2021-08-20 19:56:10 +00:00
|
|
|
'DeletePageFactory' => static function ( MediaWikiServices $services ): DeletePageFactory {
|
|
|
|
|
return $services->getService( '_PageCommandFactory' );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'Emailer' => static function ( MediaWikiServices $services ): IEmailer {
|
2020-03-09 11:00:28 +00:00
|
|
|
return new Emailer();
|
|
|
|
|
},
|
|
|
|
|
|
2023-05-22 14:08:03 +00:00
|
|
|
'EmailUserFactory' => static function ( MediaWikiServices $services ): EmailUserFactory {
|
|
|
|
|
return new EmailUserFactory(
|
2023-03-10 19:01:48 +00:00
|
|
|
new ServiceOptions( EmailUser::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getUserOptionsLookup(),
|
|
|
|
|
$services->getCentralIdLookup(),
|
|
|
|
|
$services->getUserFactory(),
|
2023-05-23 14:23:59 +00:00
|
|
|
$services->getEmailer(),
|
|
|
|
|
$services->getMessageFormatterFactory(),
|
|
|
|
|
$services->getMessageFormatterFactory()->getTextFormatter( $services->getContentLanguage()->getCode() )
|
2023-03-10 19:01:48 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'EventRelayerGroup' => static function ( MediaWikiServices $services ): EventRelayerGroup {
|
2022-04-01 15:58:32 +00:00
|
|
|
return new EventRelayerGroup( $services->getMainConfig()->get( MainConfigNames::EventRelayerConfig ) );
|
2016-04-23 00:09:14 +00:00
|
|
|
},
|
|
|
|
|
|
2023-12-29 06:25:52 +00:00
|
|
|
'ExtensionRegistry' => static function ( MediaWikiServices $services ): ExtensionRegistry {
|
|
|
|
|
return ExtensionRegistry::getInstance();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ExternalStoreAccess' => static function ( MediaWikiServices $services ): ExternalStoreAccess {
|
2018-02-27 06:24:46 +00:00
|
|
|
return new ExternalStoreAccess(
|
|
|
|
|
$services->getExternalStoreFactory(),
|
|
|
|
|
LoggerFactory::getInstance( 'ExternalStore' )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ExternalStoreFactory' => static function ( MediaWikiServices $services ): ExternalStoreFactory {
|
2018-08-03 08:05:44 +00:00
|
|
|
$config = $services->getMainConfig();
|
2022-04-01 15:58:32 +00:00
|
|
|
$writeStores = $config->get( MainConfigNames::DefaultExternalStore );
|
2016-04-03 08:37:11 +00:00
|
|
|
|
2018-08-03 08:05:44 +00:00
|
|
|
return new ExternalStoreFactory(
|
2022-04-01 15:58:32 +00:00
|
|
|
$config->get( MainConfigNames::ExternalStores ),
|
2018-02-27 06:24:46 +00:00
|
|
|
( $writeStores !== false ) ? (array)$writeStores : [],
|
|
|
|
|
$services->getDBLoadBalancer()->getLocalDomainID(),
|
|
|
|
|
LoggerFactory::getInstance( 'ExternalStore' )
|
2018-08-03 08:05:44 +00:00
|
|
|
);
|
2016-04-19 11:55:23 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'FileBackendGroup' => static function ( MediaWikiServices $services ): FileBackendGroup {
|
2019-08-13 08:52:13 +00:00
|
|
|
$mainConfig = $services->getMainConfig();
|
|
|
|
|
|
|
|
|
|
$ld = WikiMap::getCurrentWikiDbDomain();
|
|
|
|
|
$fallbackWikiId = WikiMap::getWikiIdFromDbDomain( $ld );
|
|
|
|
|
// If the local wiki ID and local domain ID do not match, probably due to a non-default
|
|
|
|
|
// schema, issue a warning. A non-default schema indicates that it might be used to
|
|
|
|
|
// disambiguate different wikis.
|
|
|
|
|
$legacyDomainId = strlen( $ld->getTablePrefix() )
|
|
|
|
|
? "{$ld->getDatabase()}-{$ld->getTablePrefix()}"
|
|
|
|
|
: $ld->getDatabase();
|
|
|
|
|
if ( $ld->getSchema() !== null && $legacyDomainId !== $fallbackWikiId ) {
|
|
|
|
|
wfWarn(
|
|
|
|
|
"Legacy default 'domainId' is '$legacyDomainId' but wiki ID is '$fallbackWikiId'."
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$cache = $services->getLocalServerObjectCache();
|
|
|
|
|
if ( $cache instanceof EmptyBagOStuff ) {
|
2020-07-16 16:04:59 +00:00
|
|
|
$cache = new HashBagOStuff();
|
2019-08-13 08:52:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new FileBackendGroup(
|
|
|
|
|
new ServiceOptions( FileBackendGroup::CONSTRUCTOR_OPTIONS, $mainConfig,
|
|
|
|
|
[ 'fallbackWikiId' => $fallbackWikiId ] ),
|
2023-09-11 18:39:11 +00:00
|
|
|
$services->getReadOnlyMode(),
|
2019-08-13 08:52:13 +00:00
|
|
|
$cache,
|
|
|
|
|
$services->getMainWANObjectCache(),
|
|
|
|
|
$services->getMimeAnalyzer(),
|
|
|
|
|
$services->getLockManagerGroupFactory(),
|
2019-10-23 13:34:53 +00:00
|
|
|
$services->getTempFSFileFactory(),
|
|
|
|
|
$services->getObjectFactory()
|
2019-08-13 08:52:13 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2023-09-25 13:32:24 +00:00
|
|
|
'FormatterFactory' => static function ( MediaWikiServices $services ): FormatterFactory {
|
2023-10-01 12:03:37 +00:00
|
|
|
return new FormatterFactory(
|
|
|
|
|
$services->getMessageCache(),
|
|
|
|
|
$services->getTitleFormatter(),
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getUserIdentityUtils(),
|
|
|
|
|
$services->getLanguageFactory()
|
|
|
|
|
);
|
2023-09-25 13:32:24 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'GenderCache' => static function ( MediaWikiServices $services ): GenderCache {
|
2019-06-05 21:16:45 +00:00
|
|
|
$nsInfo = $services->getNamespaceInfo();
|
|
|
|
|
// Database layer may be disabled, so processing without database connection
|
|
|
|
|
$dbLoadBalancer = $services->isServiceDisabled( 'DBLoadBalancer' )
|
|
|
|
|
? null
|
2023-09-15 17:07:11 +00:00
|
|
|
: $services->getDBLoadBalancerFactory();
|
2020-06-02 17:27:10 +00:00
|
|
|
return new GenderCache( $nsInfo, $dbLoadBalancer, $services->get( '_DefaultOptionsLookup' ) );
|
2018-08-03 08:05:44 +00:00
|
|
|
},
|
2016-05-01 19:29:11 +00:00
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'GlobalIdGenerator' => static function ( MediaWikiServices $services ): GlobalIdGenerator {
|
2019-05-31 23:24:56 +00:00
|
|
|
$mainConfig = $services->getMainConfig();
|
|
|
|
|
|
|
|
|
|
return new GlobalIdGenerator(
|
2022-04-01 15:58:32 +00:00
|
|
|
$mainConfig->get( MainConfigNames::TmpDirectory ),
|
2021-02-10 22:31:02 +00:00
|
|
|
static function ( $command ) {
|
2019-05-31 23:24:56 +00:00
|
|
|
return wfShellExec( $command );
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-08-06 19:51:07 +00:00
|
|
|
'GrantsInfo' => static function ( MediaWikiServices $services ): GrantsInfo {
|
|
|
|
|
return new GrantsInfo(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
GrantsInfo::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'GrantsLocalization' => static function ( MediaWikiServices $services ): GrantsLocalization {
|
|
|
|
|
return new GrantsLocalization(
|
|
|
|
|
$services->getGrantsInfo(),
|
|
|
|
|
$services->getLinkRenderer(),
|
|
|
|
|
$services->getLanguageFactory(),
|
|
|
|
|
$services->getContentLanguage()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'GroupPermissionsLookup' => static function ( MediaWikiServices $services ): GroupPermissionsLookup {
|
2021-01-05 23:08:09 +00:00
|
|
|
return new GroupPermissionsLookup(
|
|
|
|
|
new ServiceOptions( GroupPermissionsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
Support new block schema
Support migration stages when reading and writing blocks.
I tried to set it up for an easy next stage, in which support for the
old schema is removed. I tried to avoid factoring out of shared code
between the two schemas, so that the old schema cases can simply be
deleted without the need to revert unnecessary abstractions.
However, I added HideUserUtils to factor out ipb_deleted queries. Code
review showed that this was already quite complex, with multiple
approaches to the problem, so it benefits from refactoring even without
the schema abstraction.
HideUserUtils is a service rather than a standalone class to support
unit tests, since unit tests do not allow global config access. When
the migration stage config is removed, it will be a service with no
constructor parameters -- an unnecessary abstraction which should
ideally be resolved at that time.
When interpreting result rows, it is possible to share code by using
field aliases. But when constructing WHERE conditions, the actual field
names need to be used, so the migration is more intrusive in
ApiQueryBlocks and SpecialBlockList, where complex conditions are used.
Bug: T346293
Bug: T51504
Bug: T349883
Change-Id: I408acf7a57b0100fe18c455fc13141277a598925
2023-10-27 03:34:10 +00:00
|
|
|
'HideUserUtils' => static function ( MediaWikiServices $services ): HideUserUtils {
|
|
|
|
|
return new HideUserUtils(
|
|
|
|
|
$services->getMainConfig()->get( MainConfigNames::BlockTargetMigrationStage )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'HookContainer' => static function ( MediaWikiServices $services ): HookContainer {
|
2022-10-25 14:03:05 +00:00
|
|
|
// NOTE: This is called while $services is being initialized, in order to call the
|
|
|
|
|
// MediaWikiServices hook.
|
|
|
|
|
|
|
|
|
|
$configHooks = $services->getBootstrapConfig()->get( MainConfigNames::Hooks );
|
|
|
|
|
|
|
|
|
|
// If we are instantiating this service after $wgHooks was replaced by a fake,
|
|
|
|
|
// get the original array out of the object. This should only happen in the installer,
|
|
|
|
|
// when it calls resetMediaWikiServices().
|
|
|
|
|
if ( $configHooks instanceof FauxGlobalHookArray ) {
|
|
|
|
|
$configHooks = $configHooks->getOriginalArray();
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-10 14:47:46 +00:00
|
|
|
$extRegistry = ExtensionRegistry::getInstance();
|
2022-10-25 14:03:05 +00:00
|
|
|
$extHooks = $extRegistry->getAttribute( 'Hooks' );
|
2020-02-10 14:47:46 +00:00
|
|
|
$extDeprecatedHooks = $extRegistry->getAttribute( 'DeprecatedHooks' );
|
2022-10-25 14:03:05 +00:00
|
|
|
|
|
|
|
|
$hookRegistry = new StaticHookRegistry( $configHooks, $extHooks, $extDeprecatedHooks );
|
|
|
|
|
$hookContainer = new HookContainer(
|
2020-05-11 08:58:38 +00:00
|
|
|
$hookRegistry,
|
|
|
|
|
$services->getObjectFactory()
|
2020-02-10 14:47:46 +00:00
|
|
|
);
|
2022-10-25 14:03:05 +00:00
|
|
|
|
|
|
|
|
return $hookContainer;
|
2020-02-10 14:47:46 +00:00
|
|
|
},
|
|
|
|
|
|
2024-02-08 19:09:50 +00:00
|
|
|
'HtmlCacheUpdater' => static function ( MediaWikiServices $services ): HTMLCacheUpdater {
|
2019-03-15 00:23:26 +00:00
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
|
2024-02-08 19:09:50 +00:00
|
|
|
return new HTMLCacheUpdater(
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getHookContainer(),
|
2021-04-11 20:24:16 +00:00
|
|
|
$services->getTitleFactory(),
|
2022-04-01 15:58:32 +00:00
|
|
|
$config->get( MainConfigNames::CdnReboundPurgeDelay ),
|
|
|
|
|
$config->get( MainConfigNames::UseFileCache ),
|
|
|
|
|
$config->get( MainConfigNames::CdnMaxAge )
|
2019-03-15 00:23:26 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2022-10-16 21:44:53 +00:00
|
|
|
'HtmlTransformFactory' => static function ( MediaWikiServices $services ): HtmlTransformFactory {
|
|
|
|
|
return new HtmlTransformFactory(
|
2022-08-26 10:27:53 +00:00
|
|
|
$services->getService( '_Parsoid' ),
|
|
|
|
|
$services->getMainConfig()->get( MainConfigNames::ParsoidSettings ),
|
2022-09-21 10:20:11 +00:00
|
|
|
$services->getParsoidPageConfigFactory(),
|
2022-10-04 11:54:37 +00:00
|
|
|
$services->getContentHandlerFactory(),
|
|
|
|
|
$services->getParsoidSiteConfig(),
|
2022-10-04 13:34:05 +00:00
|
|
|
$services->getTitleFactory(),
|
2022-11-03 10:52:25 +00:00
|
|
|
$services->getLanguageConverterFactory(),
|
2022-10-04 13:34:05 +00:00
|
|
|
$services->getLanguageFactory()
|
2022-08-26 10:27:53 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2023-10-12 21:52:47 +00:00
|
|
|
'HttpRequestFactory' => static function ( MediaWikiServices $services ): HttpRequestFactory {
|
2020-05-15 05:19:56 +00:00
|
|
|
return new HttpRequestFactory(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
HttpRequestFactory::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
2023-07-20 13:31:25 +00:00
|
|
|
LoggerFactory::getInstance( 'http' ),
|
|
|
|
|
Telemetry::getInstance()
|
2020-05-15 05:19:56 +00:00
|
|
|
);
|
2018-08-03 08:05:44 +00:00
|
|
|
},
|
2016-05-01 19:29:11 +00:00
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'InterwikiLookup' => static function ( MediaWikiServices $services ): InterwikiLookup {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new ClassicInterwikiLookup(
|
2023-01-27 09:31:49 +00:00
|
|
|
new ServiceOptions(
|
|
|
|
|
ClassicInterwikiLookup::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig(),
|
|
|
|
|
[ 'wikiId' => WikiMap::getCurrentWikiId() ]
|
|
|
|
|
),
|
2018-08-03 08:05:44 +00:00
|
|
|
$services->getContentLanguage(),
|
|
|
|
|
$services->getMainWANObjectCache(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getHookContainer(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider()
|
2018-08-03 08:05:44 +00:00
|
|
|
);
|
2016-04-19 11:55:23 +00:00
|
|
|
},
|
2016-04-03 08:37:11 +00:00
|
|
|
|
2023-04-19 22:27:50 +00:00
|
|
|
'IntroMessageBuilder' => static function ( MediaWikiServices $services ): IntroMessageBuilder {
|
|
|
|
|
return new IntroMessageBuilder(
|
|
|
|
|
$services->getMainConfig(),
|
|
|
|
|
$services->getLinkRenderer(),
|
|
|
|
|
$services->getPermissionManager(),
|
|
|
|
|
$services->getUserNameUtils(),
|
|
|
|
|
$services->getTempUserCreator(),
|
|
|
|
|
$services->getUserFactory(),
|
|
|
|
|
$services->getRestrictionStore(),
|
2023-10-31 07:57:33 +00:00
|
|
|
$services->getDatabaseBlockStore(),
|
2023-04-19 22:27:50 +00:00
|
|
|
$services->getReadOnlyMode(),
|
|
|
|
|
$services->getSpecialPageFactory(),
|
|
|
|
|
$services->getRepoGroup(),
|
|
|
|
|
$services->getNamespaceInfo(),
|
2024-02-14 17:10:00 +00:00
|
|
|
$services->getSkinFactory(),
|
|
|
|
|
$services->getConnectionProvider()
|
2023-04-19 22:27:50 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2023-01-12 13:17:43 +00:00
|
|
|
'JobFactory' => static function ( MediaWikiServices $services ): JobFactory {
|
|
|
|
|
return new JobFactory(
|
|
|
|
|
$services->getObjectFactory(),
|
|
|
|
|
$services->getMainConfig()->get( MainConfigNames::JobClasses )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'JobQueueGroup' => static function ( MediaWikiServices $services ): JobQueueGroup {
|
2021-03-17 12:37:06 +00:00
|
|
|
return $services->getJobQueueGroupFactory()->makeJobQueueGroup();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'JobQueueGroupFactory' => static function ( MediaWikiServices $services ): JobQueueGroupFactory {
|
2021-03-17 12:37:06 +00:00
|
|
|
return new JobQueueGroupFactory(
|
|
|
|
|
new ServiceOptions( JobQueueGroupFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
2023-09-11 18:39:11 +00:00
|
|
|
$services->getReadOnlyMode(),
|
2021-03-17 12:37:06 +00:00
|
|
|
$services->getStatsdDataFactory(),
|
|
|
|
|
$services->getMainWANObjectCache(),
|
|
|
|
|
$services->getGlobalIdGenerator()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'JobRunner' => static function ( MediaWikiServices $services ): JobRunner {
|
2020-02-07 02:24:00 +00:00
|
|
|
return new JobRunner(
|
|
|
|
|
new ServiceOptions( JobRunner::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
|
|
|
|
$services->getDBLoadBalancerFactory(),
|
2021-03-17 12:37:06 +00:00
|
|
|
$services->getJobQueueGroup(),
|
2020-02-07 02:24:00 +00:00
|
|
|
$services->getReadOnlyMode(),
|
|
|
|
|
$services->getLinkCache(),
|
|
|
|
|
$services->getStatsdDataFactory(),
|
|
|
|
|
LoggerFactory::getInstance( 'runJobs' )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'JsonCodec' => static function ( MediaWikiServices $services ): JsonCodec {
|
2020-11-18 00:26:53 +00:00
|
|
|
return new JsonCodec();
|
2020-10-23 00:17:31 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LanguageConverterFactory' => static function ( MediaWikiServices $services ): LanguageConverterFactory {
|
2020-11-25 04:35:49 +00:00
|
|
|
return new LanguageConverterFactory(
|
2023-12-08 17:41:34 +00:00
|
|
|
new ServiceOptions( LanguageConverterFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
2021-10-23 21:33:01 +00:00
|
|
|
$services->getObjectFactory(),
|
2021-02-10 22:31:02 +00:00
|
|
|
static function () use ( $services ) {
|
2020-11-25 04:35:49 +00:00
|
|
|
return $services->getContentLanguage();
|
|
|
|
|
}
|
|
|
|
|
);
|
2020-01-23 18:39:23 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LanguageFactory' => static function ( MediaWikiServices $services ): LanguageFactory {
|
2018-08-07 13:17:16 +00:00
|
|
|
return new LanguageFactory(
|
|
|
|
|
new ServiceOptions( LanguageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
2022-03-11 22:54:37 +00:00
|
|
|
$services->getNamespaceInfo(),
|
2018-08-07 13:17:16 +00:00
|
|
|
$services->getLocalisationCache(),
|
|
|
|
|
$services->getLanguageNameUtils(),
|
2020-01-23 18:39:23 +00:00
|
|
|
$services->getLanguageFallback(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getLanguageConverterFactory(),
|
2021-05-12 07:38:49 +00:00
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getMainConfig()
|
2018-08-07 13:17:16 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LanguageFallback' => static function ( MediaWikiServices $services ): LanguageFallback {
|
2019-08-22 15:39:26 +00:00
|
|
|
return new LanguageFallback(
|
2022-04-01 15:58:32 +00:00
|
|
|
$services->getMainConfig()->get( MainConfigNames::LanguageCode ),
|
2019-08-22 15:39:26 +00:00
|
|
|
$services->getLocalisationCache(),
|
|
|
|
|
$services->getLanguageNameUtils()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LanguageNameUtils' => static function ( MediaWikiServices $services ): LanguageNameUtils {
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
return new LanguageNameUtils(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
LanguageNameUtils::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$services->getHookContainer()
|
|
|
|
|
);
|
2019-05-02 14:23:42 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LinkBatchFactory' => static function ( MediaWikiServices $services ): LinkBatchFactory {
|
2019-10-19 11:08:40 +00:00
|
|
|
return new LinkBatchFactory(
|
|
|
|
|
$services->getLinkCache(),
|
|
|
|
|
$services->getTitleFormatter(),
|
|
|
|
|
$services->getContentLanguage(),
|
|
|
|
|
$services->getGenderCache(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2022-04-21 19:35:30 +00:00
|
|
|
$services->getLinksMigration(),
|
2022-01-27 23:32:56 +00:00
|
|
|
LoggerFactory::getInstance( 'LinkBatch' )
|
2019-10-19 11:08:40 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LinkCache' => static function ( MediaWikiServices $services ): LinkCache {
|
2020-08-13 20:10:35 +00:00
|
|
|
// Database layer may be disabled, so processing without database connection
|
|
|
|
|
$dbLoadBalancer = $services->isServiceDisabled( 'DBLoadBalancer' )
|
|
|
|
|
? null
|
|
|
|
|
: $services->getDBLoadBalancer();
|
2021-06-02 15:49:19 +00:00
|
|
|
$linkCache = new LinkCache(
|
2018-08-03 08:05:44 +00:00
|
|
|
$services->getTitleFormatter(),
|
2019-04-09 09:30:58 +00:00
|
|
|
$services->getMainWANObjectCache(),
|
2020-08-13 20:10:35 +00:00
|
|
|
$services->getNamespaceInfo(),
|
|
|
|
|
$dbLoadBalancer
|
2016-04-06 10:46:50 +00:00
|
|
|
);
|
2021-06-02 15:49:19 +00:00
|
|
|
$linkCache->setLogger( LoggerFactory::getInstance( 'LinkCache' ) );
|
|
|
|
|
return $linkCache;
|
2018-08-03 08:05:44 +00:00
|
|
|
},
|
2017-03-20 13:18:22 +00:00
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LinkRenderer' => static function ( MediaWikiServices $services ): LinkRenderer {
|
2021-08-01 15:11:23 +00:00
|
|
|
return $services->getLinkRendererFactory()->create();
|
2016-04-06 10:46:50 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LinkRendererFactory' => static function ( MediaWikiServices $services ): LinkRendererFactory {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new LinkRendererFactory(
|
|
|
|
|
$services->getTitleFormatter(),
|
2018-08-05 12:44:11 +00:00
|
|
|
$services->getLinkCache(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getSpecialPageFactory(),
|
|
|
|
|
$services->getHookContainer()
|
2018-01-26 19:17:27 +00:00
|
|
|
);
|
2016-04-19 09:34:31 +00:00
|
|
|
},
|
|
|
|
|
|
2022-04-05 20:13:27 +00:00
|
|
|
'LinksMigration' => static function ( MediaWikiServices $services ): LinksMigration {
|
|
|
|
|
return new LinksMigration(
|
|
|
|
|
$services->getMainConfig(),
|
|
|
|
|
$services->getLinkTargetLookup()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2022-02-07 19:13:22 +00:00
|
|
|
'LinkTargetLookup' => static function ( MediaWikiServices $services ): LinkTargetLookup {
|
|
|
|
|
return new LinkTargetStore(
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2022-02-07 19:13:22 +00:00
|
|
|
$services->getLocalServerObjectCache(),
|
|
|
|
|
$services->getMainWANObjectCache()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LocalisationCache' => static function ( MediaWikiServices $services ): LocalisationCache {
|
2022-04-01 15:58:32 +00:00
|
|
|
$conf = $services->getMainConfig()->get( MainConfigNames::LocalisationCacheConf );
|
2019-05-01 13:56:41 +00:00
|
|
|
|
|
|
|
|
$logger = LoggerFactory::getInstance( 'localisation' );
|
|
|
|
|
|
|
|
|
|
$store = LocalisationCache::getStoreFromConf(
|
2022-04-01 15:58:32 +00:00
|
|
|
$conf, $services->getMainConfig()->get( MainConfigNames::CacheDirectory ) );
|
2020-02-21 00:50:54 +00:00
|
|
|
$logger->debug( 'LocalisationCache using store ' . get_class( $store ) );
|
2019-05-01 13:56:41 +00:00
|
|
|
|
|
|
|
|
return new $conf['class'](
|
|
|
|
|
new ServiceOptions(
|
2019-10-08 18:25:30 +00:00
|
|
|
LocalisationCache::CONSTRUCTOR_OPTIONS,
|
2019-05-01 13:56:41 +00:00
|
|
|
// Two of the options are stored in $wgLocalisationCacheConf
|
|
|
|
|
$conf,
|
|
|
|
|
// In case someone set that config variable and didn't reset all keys, set defaults.
|
|
|
|
|
[
|
|
|
|
|
'forceRecache' => false,
|
|
|
|
|
'manualRecache' => false,
|
|
|
|
|
],
|
|
|
|
|
// Some other options come from config itself
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$store,
|
|
|
|
|
$logger,
|
2021-02-10 22:31:02 +00:00
|
|
|
[ static function () use ( $services ) {
|
2019-11-26 19:33:10 +00:00
|
|
|
// NOTE: Make sure we use the same cache object that is assigned in the
|
|
|
|
|
// constructor of the MessageBlobStore class used by ResourceLoader.
|
|
|
|
|
// T231866: Avoid circular dependency via ResourceLoader.
|
|
|
|
|
MessageBlobStore::clearGlobalCacheEntry( $services->getMainWANObjectCache() );
|
2019-05-02 14:23:42 +00:00
|
|
|
} ],
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getLanguageNameUtils(),
|
|
|
|
|
$services->getHookContainer()
|
2019-05-01 13:56:41 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LocalServerObjectCache' => static function ( MediaWikiServices $services ): BagOStuff {
|
2023-09-07 15:12:17 +00:00
|
|
|
return $services->getObjectCacheFactory()->getInstance( CACHE_ACCEL );
|
2016-10-02 07:04:17 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LockManagerGroupFactory' => static function ( MediaWikiServices $services ): LockManagerGroupFactory {
|
2019-08-15 18:07:36 +00:00
|
|
|
return new LockManagerGroupFactory(
|
|
|
|
|
WikiMap::getCurrentWikiDbDomain()->getId(),
|
2022-08-03 05:22:48 +00:00
|
|
|
$services->getMainConfig()->get( MainConfigNames::LockManagers )
|
2019-08-15 18:07:36 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'MagicWordFactory' => static function ( MediaWikiServices $services ): MagicWordFactory {
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
return new MagicWordFactory(
|
|
|
|
|
$services->getContentLanguage(),
|
|
|
|
|
$services->getHookContainer()
|
|
|
|
|
);
|
2018-08-03 08:05:44 +00:00
|
|
|
},
|
2016-10-04 17:48:02 +00:00
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'MainConfig' => static function ( MediaWikiServices $services ): Config {
|
2018-08-03 08:05:44 +00:00
|
|
|
// Use the 'main' config from the ConfigFactory service.
|
|
|
|
|
return $services->getConfigFactory()->makeConfig( 'main' );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'MainObjectStash' => static function ( MediaWikiServices $services ): BagOStuff {
|
2018-08-03 08:05:44 +00:00
|
|
|
$mainConfig = $services->getMainConfig();
|
|
|
|
|
|
2022-04-01 15:58:32 +00:00
|
|
|
$id = $mainConfig->get( MainConfigNames::MainStash );
|
2023-09-07 15:12:17 +00:00
|
|
|
$store = $services->getObjectCacheFactory()->getInstance( $id );
|
2020-03-02 14:56:08 +00:00
|
|
|
$store->getLogger()->debug( 'MainObjectStash using store {class}', [
|
2019-10-10 20:30:47 +00:00
|
|
|
'class' => get_class( $store )
|
|
|
|
|
] );
|
|
|
|
|
|
|
|
|
|
return $store;
|
2018-08-03 08:05:44 +00:00
|
|
|
},
|
2016-10-04 17:48:02 +00:00
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'MainWANObjectCache' => static function ( MediaWikiServices $services ): WANObjectCache {
|
2018-08-03 08:05:44 +00:00
|
|
|
$mainConfig = $services->getMainConfig();
|
|
|
|
|
|
objectcache: Remove $wgMainWANCache and $wgWANObjectCaches
We always wrap the local cluster cache, and there are no subclasses
of WANObjectCache. It was never documented or recommended how these
would be used. It is a left-over from the original 2015 Multi-DC plan
in which WANObjectCache would work differently. See task for details.
Note that this requires no configuration changes, even in the
theoretical case of these variables being used, as the only
option is to use the main cache, and that's also the default.
* Update WAN overrides to override the underlying main cache
instead.
* Fix EditPageTest which was previously implicitly using a 'hash'
as main cache but also relying on wan cache to be 'none'.
The part that it actually needs is the 'none'. When WAN cache is
enabled, testUpdateNoMinor fails due to an edit conflict because
one of the edits it makes is made with a current timestamp whereas
it expects to simulate wpEdittime in the year 2012 which, when
caching is enabled, is ignored and becomes the current time instead.
I don't understand exactly why, but I'm going to conserve that
behaviour for now.
* Fix TemplateCategoriesTest, which was failing due to an unexpected
cache hit:
> [objectcache] fetchOrRegenerate(…:page:10:…): volatile hit
This could be solved in a more realistic way by splitting the test,
or by explicitly resetting services half-way the test to clear
WikiPageFactory, PageStore and WANCache process state.
For now, keep the prior behaviour of no cache in this test.
Bug: T305093
Bug: T329680
Depends-On: If890622eed0d0f8b4bd73d36ba1815a3d760ea05
Depends-On: Ie1def75208822bdf19bb2cfd7e6edf32c2000e6b
Depends-On: I35cce61dc3ee90dcee3dd6f0b36f84133be029ed
Change-Id: I53781a8c06ebb2583f6ca83dd91bbfe8a5c88b13
2023-02-14 21:43:12 +00:00
|
|
|
$store = $services->get( '_LocalClusterCache' );
|
2020-03-02 14:56:08 +00:00
|
|
|
$logger = $store->getLogger();
|
2019-10-08 21:34:17 +00:00
|
|
|
$logger->debug( 'MainWANObjectCache using store {class}', [
|
|
|
|
|
'class' => get_class( $store )
|
|
|
|
|
] );
|
|
|
|
|
|
objectcache: Remove $wgMainWANCache and $wgWANObjectCaches
We always wrap the local cluster cache, and there are no subclasses
of WANObjectCache. It was never documented or recommended how these
would be used. It is a left-over from the original 2015 Multi-DC plan
in which WANObjectCache would work differently. See task for details.
Note that this requires no configuration changes, even in the
theoretical case of these variables being used, as the only
option is to use the main cache, and that's also the default.
* Update WAN overrides to override the underlying main cache
instead.
* Fix EditPageTest which was previously implicitly using a 'hash'
as main cache but also relying on wan cache to be 'none'.
The part that it actually needs is the 'none'. When WAN cache is
enabled, testUpdateNoMinor fails due to an edit conflict because
one of the edits it makes is made with a current timestamp whereas
it expects to simulate wpEdittime in the year 2012 which, when
caching is enabled, is ignored and becomes the current time instead.
I don't understand exactly why, but I'm going to conserve that
behaviour for now.
* Fix TemplateCategoriesTest, which was failing due to an unexpected
cache hit:
> [objectcache] fetchOrRegenerate(…:page:10:…): volatile hit
This could be solved in a more realistic way by splitting the test,
or by explicitly resetting services half-way the test to clear
WikiPageFactory, PageStore and WANCache process state.
For now, keep the prior behaviour of no cache in this test.
Bug: T305093
Bug: T329680
Depends-On: If890622eed0d0f8b4bd73d36ba1815a3d760ea05
Depends-On: Ie1def75208822bdf19bb2cfd7e6edf32c2000e6b
Depends-On: I35cce61dc3ee90dcee3dd6f0b36f84133be029ed
Change-Id: I53781a8c06ebb2583f6ca83dd91bbfe8a5c88b13
2023-02-14 21:43:12 +00:00
|
|
|
$wanParams = $mainConfig->get( MainConfigNames::WANObjectCache ) + [
|
|
|
|
|
'cache' => $store,
|
|
|
|
|
'logger' => $logger,
|
|
|
|
|
'secret' => $mainConfig->get( MainConfigNames::SecretKey ),
|
|
|
|
|
];
|
2023-12-18 18:54:59 +00:00
|
|
|
if ( MW_ENTRY_POINT !== 'cli' ) {
|
2019-10-08 21:34:17 +00:00
|
|
|
// Send the statsd data post-send on HTTP requests; avoid in CLI mode (T181385)
|
2020-03-30 21:28:53 +00:00
|
|
|
$wanParams['stats'] = $services->getStatsdDataFactory();
|
2019-10-08 21:34:17 +00:00
|
|
|
// Let pre-emptive refreshes happen post-send on HTTP requests
|
2020-03-30 21:28:53 +00:00
|
|
|
$wanParams['asyncHandler'] = [ DeferredUpdates::class, 'addCallableUpdate' ];
|
2019-10-08 21:34:17 +00:00
|
|
|
}
|
objectcache: Remove $wgMainWANCache and $wgWANObjectCaches
We always wrap the local cluster cache, and there are no subclasses
of WANObjectCache. It was never documented or recommended how these
would be used. It is a left-over from the original 2015 Multi-DC plan
in which WANObjectCache would work differently. See task for details.
Note that this requires no configuration changes, even in the
theoretical case of these variables being used, as the only
option is to use the main cache, and that's also the default.
* Update WAN overrides to override the underlying main cache
instead.
* Fix EditPageTest which was previously implicitly using a 'hash'
as main cache but also relying on wan cache to be 'none'.
The part that it actually needs is the 'none'. When WAN cache is
enabled, testUpdateNoMinor fails due to an edit conflict because
one of the edits it makes is made with a current timestamp whereas
it expects to simulate wpEdittime in the year 2012 which, when
caching is enabled, is ignored and becomes the current time instead.
I don't understand exactly why, but I'm going to conserve that
behaviour for now.
* Fix TemplateCategoriesTest, which was failing due to an unexpected
cache hit:
> [objectcache] fetchOrRegenerate(…:page:10:…): volatile hit
This could be solved in a more realistic way by splitting the test,
or by explicitly resetting services half-way the test to clear
WikiPageFactory, PageStore and WANCache process state.
For now, keep the prior behaviour of no cache in this test.
Bug: T305093
Bug: T329680
Depends-On: If890622eed0d0f8b4bd73d36ba1815a3d760ea05
Depends-On: Ie1def75208822bdf19bb2cfd7e6edf32c2000e6b
Depends-On: I35cce61dc3ee90dcee3dd6f0b36f84133be029ed
Change-Id: I53781a8c06ebb2583f6ca83dd91bbfe8a5c88b13
2023-02-14 21:43:12 +00:00
|
|
|
return new WANObjectCache( $wanParams );
|
2016-10-04 17:48:02 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'MediaHandlerFactory' => static function ( MediaWikiServices $services ): MediaHandlerFactory {
|
2016-07-29 00:01:08 +00:00
|
|
|
return new MediaHandlerFactory(
|
2021-03-31 16:50:45 +00:00
|
|
|
LoggerFactory::getInstance( 'MediaHandlerFactory' ),
|
2022-04-01 15:58:32 +00:00
|
|
|
$services->getMainConfig()->get( MainConfigNames::MediaHandlers )
|
2016-07-29 00:01:08 +00:00
|
|
|
);
|
2016-07-26 02:19:25 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'MergeHistoryFactory' => static function ( MediaWikiServices $services ): MergeHistoryFactory {
|
2020-04-28 22:54:18 +00:00
|
|
|
return $services->getService( '_PageCommandFactory' );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'MessageCache' => static function ( MediaWikiServices $services ): MessageCache {
|
2019-04-08 15:21:49 +00:00
|
|
|
$mainConfig = $services->getMainConfig();
|
2022-04-01 15:58:32 +00:00
|
|
|
$clusterCache = ObjectCache::getInstance( $mainConfig->get( MainConfigNames::MessageCacheType ) );
|
|
|
|
|
$srvCache = $mainConfig->get( MainConfigNames::UseLocalMessageCache )
|
2019-10-11 23:26:18 +00:00
|
|
|
? $services->getLocalServerObjectCache()
|
|
|
|
|
: new EmptyBagOStuff();
|
|
|
|
|
|
|
|
|
|
$logger = LoggerFactory::getInstance( 'MessageCache' );
|
|
|
|
|
$logger->debug( 'MessageCache using store {class}', [
|
|
|
|
|
'class' => get_class( $clusterCache )
|
|
|
|
|
] );
|
|
|
|
|
|
2022-07-14 06:24:44 +00:00
|
|
|
$options = new ServiceOptions( MessageCache::CONSTRUCTOR_OPTIONS, $mainConfig );
|
|
|
|
|
|
2019-04-08 15:21:49 +00:00
|
|
|
return new MessageCache(
|
|
|
|
|
$services->getMainWANObjectCache(),
|
2019-10-11 23:26:18 +00:00
|
|
|
$clusterCache,
|
|
|
|
|
$srvCache,
|
2019-10-11 23:37:37 +00:00
|
|
|
$services->getContentLanguage(),
|
2021-10-15 23:20:32 +00:00
|
|
|
$services->getLanguageConverterFactory(),
|
2019-10-11 23:37:37 +00:00
|
|
|
$logger,
|
2022-07-14 06:24:44 +00:00
|
|
|
$options,
|
2019-10-28 18:05:35 +00:00
|
|
|
$services->getLanguageFactory(),
|
2020-01-03 23:03:14 +00:00
|
|
|
$services->getLocalisationCache(),
|
|
|
|
|
$services->getLanguageNameUtils(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getLanguageFallback(),
|
2023-07-29 19:21:04 +00:00
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getParserFactory()
|
2019-04-08 15:21:49 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'MessageFormatterFactory' => static function ( MediaWikiServices $services ): IMessageFormatterFactory {
|
2019-07-15 10:24:38 +00:00
|
|
|
return new MessageFormatterFactory();
|
|
|
|
|
},
|
|
|
|
|
|
2023-11-07 13:53:52 +00:00
|
|
|
'MicroStash' => static function ( MediaWikiServices $services ): BagOStuff {
|
|
|
|
|
$mainConfig = $services->getMainConfig();
|
|
|
|
|
|
|
|
|
|
$id = $mainConfig->get( MainConfigNames::MicroStashType );
|
2023-09-07 15:12:17 +00:00
|
|
|
$store = $services->getObjectCacheFactory()->getInstance( $id );
|
2023-11-07 13:53:52 +00:00
|
|
|
|
|
|
|
|
$store->getLogger()->debug( 'MicroStash using store {class}', [
|
|
|
|
|
'class' => get_class( $store )
|
|
|
|
|
] );
|
|
|
|
|
|
|
|
|
|
return $store;
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'MimeAnalyzer' => static function ( MediaWikiServices $services ): MimeAnalyzer {
|
2016-11-22 23:57:34 +00:00
|
|
|
$logger = LoggerFactory::getInstance( 'Mime' );
|
|
|
|
|
$mainConfig = $services->getMainConfig();
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$hookRunner = new HookRunner( $services->getHookContainer() );
|
2016-11-22 23:57:34 +00:00
|
|
|
$params = [
|
2022-04-01 15:58:32 +00:00
|
|
|
'typeFile' => $mainConfig->get( MainConfigNames::MimeTypeFile ),
|
|
|
|
|
'infoFile' => $mainConfig->get( MainConfigNames::MimeInfoFile ),
|
|
|
|
|
'xmlTypes' => $mainConfig->get( MainConfigNames::XMLMimeTypes ),
|
2023-10-12 21:52:47 +00:00
|
|
|
'guessCallback' => static function (
|
|
|
|
|
$mimeAnalyzer, &$head, &$tail, $file, &$mime
|
|
|
|
|
) use ( $logger, $hookRunner ) {
|
|
|
|
|
// Also test DjVu
|
|
|
|
|
$deja = new DjVuImage( $file );
|
|
|
|
|
if ( $deja->isValid() ) {
|
|
|
|
|
$logger->info( "Detected $file as image/vnd.djvu\n" );
|
|
|
|
|
$mime = 'image/vnd.djvu';
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// Some strings by reference for performance - assuming well-behaved hooks
|
|
|
|
|
$hookRunner->onMimeMagicGuessFromContent(
|
|
|
|
|
$mimeAnalyzer, $head, $tail, $file, $mime );
|
|
|
|
|
},
|
2021-02-10 22:31:02 +00:00
|
|
|
'extCallback' => static function ( $mimeAnalyzer, $ext, &$mime ) use ( $hookRunner ) {
|
2016-11-22 23:57:34 +00:00
|
|
|
// Media handling extensions can improve the MIME detected
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$hookRunner->onMimeMagicImproveFromExtension( $mimeAnalyzer, $ext, $mime );
|
2016-11-22 23:57:34 +00:00
|
|
|
},
|
2021-02-10 22:31:02 +00:00
|
|
|
'initCallback' => static function ( $mimeAnalyzer ) use ( $hookRunner ) {
|
2016-11-22 23:57:34 +00:00
|
|
|
// Allow media handling extensions adding MIME-types and MIME-info
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$hookRunner->onMimeMagicInit( $mimeAnalyzer );
|
2016-11-22 23:57:34 +00:00
|
|
|
},
|
|
|
|
|
'logger' => $logger
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
if ( $params['infoFile'] === 'includes/mime.info' ) {
|
mime: Convert built-in MIME mappings to PHP arrays
Currently, MimeAnalyzer builds the internal mappings of MIME types <=> file
extensions by concatenating several string buffers in mime.type format into a
giant string, and then parsing it. The mapping of MIME types to internal
media types is built up in a similar way, except we use a dubious homegrown
format with undocumented conventions. It's a mess, and an expensive one --
~1.5% of api.php CPU time on the WMF cluster is spent building these buffers
and parsing them. Converting the mappings to PHP associative arrays makes
them much cheaper to load and easier to maintain.
Doing this without breaking compatibility with existing behaviors requires
some delicate footwork. The current mime.types buffer is made up of the
following fragments, in order:
1) MimeAnalyzer::$wellKnownTypes
2) If $wgMimeTypeFile == 'includes/mime.types' (sic!):
the contents of includes/libs/mime/mime.types.
If $wgMimeTypeFile is another file path (e.g., '/etc/mime.types'):
the contents of that file.
If !wg$MimeTypeFile, this fragment is blank.
3) MimeAnalyzer::$extraTypes (populated by extensions via hook).
The mime.info buffer is built up in the exact same way, except it's
MimeAnalyzer::$wellKnownInfo, $wgMimeInfoFile, and MimeAnalyzer::$extraInfo.
What this means in effect is that some built-in MediaWiki MIME mappings are
"baked in" (anything in MimeAnalyzer::$wellKnown*), and others can be
overridden (anything in includes/libs/mime/mime.*).
To avoid breaking backward compatibility, we have to preserve the
distinction. Thus this change has two MIME mappings, encapsulated in two
classes: 'MimeMapMinimal', which contains just the baked-in mappings, and
'MimeMap' which contains both the baked-in and overridable mappings. We also
have to keep the code for parsing mime.types and the ad-hoc mime.info format,
at least for now.
In a FUTURE change (i.e., not here), I think we can:
* Deprecate $wgMimeTypeFile in favor of a new config var,
$wgExtraMimeTypeFile. $wgMimeTypeFile is evil because if you are using to
add support for additional MIME types, you can end up unwittingly dropping
support for other types that exist in MediaWiki's mime.types but not your
file. The new $wgExtraMimeTypeFile would only be used to add new MIME
mappings on top of the standard MimeMappings, which was probably the
original intent for $wgMimeTypeFile.
* Deprecate $wgMimeInfoFile. I don't think we need to provide a replacement,
because extensions can use the hook, and I doubt anyone is using the config
var. But if we wanted to provide an alternative, we could have a
$wgExtraMimeInfoMap that has an array of extra mappings.
* Deprecate MimeAnalyzer::addExtraTypes and MimeAnalyzer::addExtraInfo, and
provide alternative interfaces that take structured input instead of string
blobs.
I tested this by dumping the internal state of MimeAnalyzer before and after
this CL using the script in Ib856a69fe, using both default and custom values
for $wgMimeInfo(File|Type).
Bug: T252228
Change-Id: I9b2979d3c9c0dee96bb19e0290f680724e718891
2020-05-12 19:42:35 +00:00
|
|
|
$params['infoFile'] = MimeAnalyzer::USE_INTERNAL;
|
2016-11-22 23:57:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( $params['typeFile'] === 'includes/mime.types' ) {
|
mime: Convert built-in MIME mappings to PHP arrays
Currently, MimeAnalyzer builds the internal mappings of MIME types <=> file
extensions by concatenating several string buffers in mime.type format into a
giant string, and then parsing it. The mapping of MIME types to internal
media types is built up in a similar way, except we use a dubious homegrown
format with undocumented conventions. It's a mess, and an expensive one --
~1.5% of api.php CPU time on the WMF cluster is spent building these buffers
and parsing them. Converting the mappings to PHP associative arrays makes
them much cheaper to load and easier to maintain.
Doing this without breaking compatibility with existing behaviors requires
some delicate footwork. The current mime.types buffer is made up of the
following fragments, in order:
1) MimeAnalyzer::$wellKnownTypes
2) If $wgMimeTypeFile == 'includes/mime.types' (sic!):
the contents of includes/libs/mime/mime.types.
If $wgMimeTypeFile is another file path (e.g., '/etc/mime.types'):
the contents of that file.
If !wg$MimeTypeFile, this fragment is blank.
3) MimeAnalyzer::$extraTypes (populated by extensions via hook).
The mime.info buffer is built up in the exact same way, except it's
MimeAnalyzer::$wellKnownInfo, $wgMimeInfoFile, and MimeAnalyzer::$extraInfo.
What this means in effect is that some built-in MediaWiki MIME mappings are
"baked in" (anything in MimeAnalyzer::$wellKnown*), and others can be
overridden (anything in includes/libs/mime/mime.*).
To avoid breaking backward compatibility, we have to preserve the
distinction. Thus this change has two MIME mappings, encapsulated in two
classes: 'MimeMapMinimal', which contains just the baked-in mappings, and
'MimeMap' which contains both the baked-in and overridable mappings. We also
have to keep the code for parsing mime.types and the ad-hoc mime.info format,
at least for now.
In a FUTURE change (i.e., not here), I think we can:
* Deprecate $wgMimeTypeFile in favor of a new config var,
$wgExtraMimeTypeFile. $wgMimeTypeFile is evil because if you are using to
add support for additional MIME types, you can end up unwittingly dropping
support for other types that exist in MediaWiki's mime.types but not your
file. The new $wgExtraMimeTypeFile would only be used to add new MIME
mappings on top of the standard MimeMappings, which was probably the
original intent for $wgMimeTypeFile.
* Deprecate $wgMimeInfoFile. I don't think we need to provide a replacement,
because extensions can use the hook, and I doubt anyone is using the config
var. But if we wanted to provide an alternative, we could have a
$wgExtraMimeInfoMap that has an array of extra mappings.
* Deprecate MimeAnalyzer::addExtraTypes and MimeAnalyzer::addExtraInfo, and
provide alternative interfaces that take structured input instead of string
blobs.
I tested this by dumping the internal state of MimeAnalyzer before and after
this CL using the script in Ib856a69fe, using both default and custom values
for $wgMimeInfo(File|Type).
Bug: T252228
Change-Id: I9b2979d3c9c0dee96bb19e0290f680724e718891
2020-05-12 19:42:35 +00:00
|
|
|
$params['typeFile'] = MimeAnalyzer::USE_INTERNAL;
|
2016-11-22 23:57:34 +00:00
|
|
|
}
|
|
|
|
|
|
2022-04-01 15:58:32 +00:00
|
|
|
$detectorCmd = $mainConfig->get( MainConfigNames::MimeDetectorCommand );
|
2016-11-22 23:57:34 +00:00
|
|
|
if ( $detectorCmd ) {
|
2017-10-25 01:51:45 +00:00
|
|
|
$factory = $services->getShellCommandFactory();
|
2021-02-10 22:31:02 +00:00
|
|
|
$params['detectCallback'] = static function ( $file ) use ( $detectorCmd, $factory ) {
|
2017-10-25 01:51:45 +00:00
|
|
|
$result = $factory->create()
|
|
|
|
|
// $wgMimeDetectorCommand can contain commands with parameters
|
|
|
|
|
->unsafeParams( $detectorCmd )
|
|
|
|
|
->params( $file )
|
|
|
|
|
->execute();
|
|
|
|
|
return $result->getStdout();
|
2016-11-22 23:57:34 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-21 01:40:59 +00:00
|
|
|
return new MimeAnalyzer( $params );
|
2016-09-22 04:57:13 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'MovePageFactory' => static function ( MediaWikiServices $services ): MovePageFactory {
|
2020-04-28 22:54:18 +00:00
|
|
|
return $services->getService( '_PageCommandFactory' );
|
2019-05-01 11:39:45 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'NamespaceInfo' => static function ( MediaWikiServices $services ): NamespaceInfo {
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
return new NamespaceInfo(
|
|
|
|
|
new ServiceOptions( NamespaceInfo::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
2023-07-15 14:45:21 +00:00
|
|
|
$services->getHookContainer(),
|
|
|
|
|
ExtensionRegistry::getInstance()->getAttribute( 'ExtensionNamespaces' ),
|
|
|
|
|
ExtensionRegistry::getInstance()->getAttribute( 'ImmovableNamespaces' )
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
);
|
2019-04-10 10:36:02 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'NameTableStoreFactory' => static function ( MediaWikiServices $services ): NameTableStoreFactory {
|
2018-09-04 01:59:03 +00:00
|
|
|
return new NameTableStoreFactory(
|
|
|
|
|
$services->getDBLoadBalancerFactory(),
|
|
|
|
|
$services->getMainWANObjectCache(),
|
|
|
|
|
LoggerFactory::getInstance( 'NameTableSqlStore' )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2023-09-07 15:12:17 +00:00
|
|
|
'ObjectCacheFactory' => static function ( MediaWikiServices $services ): ObjectCacheFactory {
|
|
|
|
|
return new ObjectCacheFactory(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
ObjectCacheFactory::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$services->getStatsFactory(),
|
2024-03-21 19:06:32 +00:00
|
|
|
LoggerFactory::getProvider(),
|
|
|
|
|
WikiMap::getCurrentWikiDbDomain()->getId()
|
2023-09-07 15:12:17 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ObjectFactory' => static function ( MediaWikiServices $services ): ObjectFactory {
|
2019-08-21 16:10:30 +00:00
|
|
|
return new ObjectFactory( $services );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'OldRevisionImporter' => static function ( MediaWikiServices $services ): OldRevisionImporter {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new ImportableOldRevisionImporter(
|
|
|
|
|
true,
|
|
|
|
|
LoggerFactory::getInstance( 'OldRevisionImporter' ),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2023-11-29 20:43:12 +00:00
|
|
|
$services->getRevisionStoreFactory()->getRevisionStoreForImport(),
|
2020-11-11 22:08:46 +00:00
|
|
|
$services->getSlotRoleRegistry(),
|
2021-10-06 22:07:55 +00:00
|
|
|
$services->getWikiPageFactory(),
|
2021-12-19 13:31:03 +00:00
|
|
|
$services->getPageUpdaterFactory(),
|
|
|
|
|
$services->getUserFactory()
|
2016-09-22 02:52:06 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'PageEditStash' => static function ( MediaWikiServices $services ): PageEditStash {
|
2019-04-13 04:38:55 +00:00
|
|
|
return new PageEditStash(
|
|
|
|
|
ObjectCache::getLocalClusterInstance(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2019-04-13 04:38:55 +00:00
|
|
|
LoggerFactory::getInstance( 'StashEdit' ),
|
|
|
|
|
$services->getStatsdDataFactory(),
|
2021-03-15 23:46:30 +00:00
|
|
|
$services->getUserEditTracker(),
|
|
|
|
|
$services->getUserFactory(),
|
2021-06-23 10:43:46 +00:00
|
|
|
$services->getWikiPageFactory(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getHookContainer(),
|
2023-12-18 18:54:59 +00:00
|
|
|
defined( 'MEDIAWIKI_JOB_RUNNER' ) || MW_ENTRY_POINT === 'cli'
|
2019-04-13 04:38:55 +00:00
|
|
|
? PageEditStash::INITIATOR_JOB_OR_CLI
|
|
|
|
|
: PageEditStash::INITIATOR_USER
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'PageProps' => static function ( MediaWikiServices $services ): PageProps {
|
2020-05-21 03:47:11 +00:00
|
|
|
return new PageProps(
|
|
|
|
|
$services->getLinkBatchFactory(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider()
|
2020-05-21 03:47:11 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2022-11-18 16:55:18 +00:00
|
|
|
'PageRestHelperFactory' => static function ( MediaWikiServices $services ): PageRestHelperFactory {
|
|
|
|
|
return new PageRestHelperFactory(
|
|
|
|
|
new ServiceOptions( PageRestHelperFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
|
|
|
|
$services->getRevisionLookup(),
|
|
|
|
|
$services->getTitleFormatter(),
|
|
|
|
|
$services->getPageStore(),
|
|
|
|
|
$services->getParsoidOutputStash(),
|
|
|
|
|
$services->getStatsdDataFactory(),
|
|
|
|
|
$services->getParsoidOutputAccess(),
|
2022-11-24 21:54:11 +00:00
|
|
|
$services->getHtmlTransformFactory(),
|
|
|
|
|
$services->getContentHandlerFactory(),
|
2023-06-11 16:56:29 +00:00
|
|
|
$services->getLanguageFactory(),
|
2023-06-16 18:56:48 +00:00
|
|
|
$services->getRedirectStore(),
|
|
|
|
|
$services->getLanguageConverterFactory()
|
2022-11-18 16:55:18 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'PageStore' => static function ( MediaWikiServices $services ): PageStore {
|
2021-03-17 22:13:35 +00:00
|
|
|
return $services->getPageStoreFactory()->getPageStore();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'PageStoreFactory' => static function ( MediaWikiServices $services ): PageStoreFactory {
|
2021-03-17 22:13:35 +00:00
|
|
|
$options = new ServiceOptions(
|
|
|
|
|
PageStoreFactory::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return new PageStoreFactory(
|
2021-02-09 11:08:36 +00:00
|
|
|
$options,
|
2021-03-17 22:13:35 +00:00
|
|
|
$services->getDBLoadBalancerFactory(),
|
2021-05-04 20:45:30 +00:00
|
|
|
$services->getNamespaceInfo(),
|
2021-06-01 20:14:36 +00:00
|
|
|
$services->getTitleParser(),
|
|
|
|
|
$services->getLinkCache(),
|
|
|
|
|
$services->getStatsdDataFactory()
|
2020-05-21 03:47:11 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-16 17:32:30 +00:00
|
|
|
'PageUpdaterFactory' => static function (
|
|
|
|
|
MediaWikiServices $services
|
|
|
|
|
): PageUpdaterFactory {
|
|
|
|
|
$editResultCache = new EditResultCache(
|
|
|
|
|
$services->getMainObjectStash(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2021-07-16 17:32:30 +00:00
|
|
|
new ServiceOptions(
|
|
|
|
|
EditResultCache::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return new PageUpdaterFactory(
|
|
|
|
|
$services->getRevisionStore(),
|
|
|
|
|
$services->getRevisionRenderer(),
|
|
|
|
|
$services->getSlotRoleRegistry(),
|
|
|
|
|
$services->getParserCache(),
|
|
|
|
|
$services->getJobQueueGroup(),
|
|
|
|
|
$services->getMessageCache(),
|
|
|
|
|
$services->getContentLanguage(),
|
|
|
|
|
$services->getDBLoadBalancerFactory(),
|
|
|
|
|
$services->getContentHandlerFactory(),
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$editResultCache,
|
|
|
|
|
$services->getUserNameUtils(),
|
|
|
|
|
LoggerFactory::getInstance( 'SavePage' ),
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
PageUpdaterFactory::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$services->getUserEditTracker(),
|
|
|
|
|
$services->getUserGroupManager(),
|
2021-07-27 02:45:11 +00:00
|
|
|
$services->getTitleFormatter(),
|
2021-07-21 01:03:59 +00:00
|
|
|
$services->getContentTransformer(),
|
2021-06-05 21:10:29 +00:00
|
|
|
$services->getPageEditStash(),
|
|
|
|
|
$services->getTalkPageNotificationManager(),
|
|
|
|
|
$services->getMainWANObjectCache(),
|
|
|
|
|
$services->getPermissionManager(),
|
2021-06-23 10:43:46 +00:00
|
|
|
$services->getWikiPageFactory(),
|
2023-06-08 23:32:11 +00:00
|
|
|
$services->getChangeTagsStore()->getSoftwareTags()
|
2021-07-16 17:32:30 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'Parser' => static function ( MediaWikiServices $services ): Parser {
|
2023-10-07 20:57:53 +00:00
|
|
|
// This service exists as convenience function to get the global parser in global code.
|
|
|
|
|
// Do not use this service for dependency injection or in service wiring (T343070).
|
|
|
|
|
// Use the 'ParserFactory' service instead.
|
2022-06-20 03:48:44 +00:00
|
|
|
return $services->getParserFactory()->getMainInstance();
|
2016-08-16 20:47:43 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ParserCache' => static function ( MediaWikiServices $services ): ParserCache {
|
2020-09-25 20:02:03 +00:00
|
|
|
return $services->getParserCacheFactory()
|
2020-12-15 01:05:17 +00:00
|
|
|
->getParserCache( ParserCacheFactory::DEFAULT_NAME );
|
2020-09-25 20:02:03 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ParserCacheFactory' => static function ( MediaWikiServices $services ): ParserCacheFactory {
|
2017-05-30 00:10:16 +00:00
|
|
|
$config = $services->getMainConfig();
|
2022-04-01 15:58:32 +00:00
|
|
|
$cache = ObjectCache::getInstance( $config->get( MainConfigNames::ParserCacheType ) );
|
2020-12-04 15:28:25 +00:00
|
|
|
$wanCache = $services->getMainWANObjectCache();
|
|
|
|
|
|
|
|
|
|
$options = new ServiceOptions( ParserCacheFactory::CONSTRUCTOR_OPTIONS, $config );
|
|
|
|
|
|
2020-09-25 20:02:03 +00:00
|
|
|
return new ParserCacheFactory(
|
2017-05-30 00:10:16 +00:00
|
|
|
$cache,
|
2020-12-04 15:28:25 +00:00
|
|
|
$wanCache,
|
2020-04-15 19:57:07 +00:00
|
|
|
$services->getHookContainer(),
|
2020-11-18 00:26:53 +00:00
|
|
|
$services->getJsonCodec(),
|
2024-03-04 21:58:44 +00:00
|
|
|
$services->getStatsFactory(),
|
2020-10-12 10:03:18 +00:00
|
|
|
LoggerFactory::getInstance( 'ParserCache' ),
|
2021-03-24 14:05:44 +00:00
|
|
|
$options,
|
|
|
|
|
$services->getTitleFactory(),
|
Add ParserOutput::{get,set}RenderId() and set render id in ContentRenderer
Set the render ID for each parse stored into cache so that we are able
to identify a specific parse when there are dependencies (for example
in an edit based on that parse). This is recorded as a property added
to the ParserOutput, not the parent CacheTime interface. Even though
the render ID is /related/ to the CacheTime interface, CacheTime is
also used directly as a parser cache key, and the UUID should not be
part of the lookup key.
In general we are trying to move the location where these cache
properties are set as early as possible, so we check at each location
to ensure we don't overwrite a previously-set value. Eventually we
can convert most of these checks into assertions that the cache
properties have already been set (T350538). The primary location for
setting cache properties is the ContentRenderer.
Moved setting the revision timestamp into ContentRenderer as well, as
it was set along the same code paths. An extra parameter was added to
ContentRenderer::getParserOutput() to support this.
Added merge code to ParserOutput::mergeInternalMetaDataFrom() which
should ensure that cache time, revision, timestamp, and render id are
all set properly when multiple slots are combined together in MCR.
In order to ensure the render ID is set on all codepaths we needed to
plumb the GlobalIdGenerator service into ContentRenderer, ParserCache,
ParserCacheFactory, and RevisionOutputCache. Eventually (T350538) it
should only be necessary in the ContentRenderer.
Bug: T350538
Bug: T349868
Followup-To: Ic9b7cc0fcf365e772b7d080d76a065e3fd585f80
Change-Id: I72c5e6f86b7f081ab5ce7a56f5365d2f75067a78
2023-09-14 16:11:20 +00:00
|
|
|
$services->getWikiPageFactory(),
|
|
|
|
|
$services->getGlobalIdGenerator()
|
2017-05-30 00:10:16 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ParserFactory' => static function ( MediaWikiServices $services ): ParserFactory {
|
2019-10-08 18:30:42 +00:00
|
|
|
$options = new ServiceOptions( Parser::CONSTRUCTOR_OPTIONS,
|
2019-04-12 09:50:30 +00:00
|
|
|
$services->getMainConfig()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return new ParserFactory(
|
|
|
|
|
$options,
|
2018-08-03 08:25:15 +00:00
|
|
|
$services->getMagicWordFactory(),
|
|
|
|
|
$services->getContentLanguage(),
|
2022-04-28 13:33:39 +00:00
|
|
|
$services->getUrlUtils(),
|
2018-08-08 14:49:46 +00:00
|
|
|
$services->getSpecialPageFactory(),
|
2018-08-05 12:50:01 +00:00
|
|
|
$services->getLinkRendererFactory(),
|
2019-06-27 03:35:50 +00:00
|
|
|
$services->getNamespaceInfo(),
|
2020-02-04 12:42:03 +00:00
|
|
|
LoggerFactory::getInstance( 'Parser' ),
|
|
|
|
|
$services->getBadFileLookup(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getLanguageConverterFactory(),
|
2021-02-18 16:51:12 +00:00
|
|
|
$services->getHookContainer(),
|
2021-02-19 17:26:39 +00:00
|
|
|
$services->getTidy(),
|
2021-03-16 18:31:27 +00:00
|
|
|
$services->getMainWANObjectCache(),
|
|
|
|
|
$services->getUserOptionsLookup(),
|
2021-04-25 17:29:33 +00:00
|
|
|
$services->getUserFactory(),
|
2021-08-04 12:56:30 +00:00
|
|
|
$services->getTitleFormatter(),
|
2021-10-08 16:37:26 +00:00
|
|
|
$services->getHttpRequestFactory(),
|
2022-04-07 23:52:05 +00:00
|
|
|
$services->getTrackingCategories(),
|
2022-04-11 01:26:51 +00:00
|
|
|
$services->getSignatureValidatorFactory(),
|
|
|
|
|
$services->getUserNameUtils()
|
2018-08-03 08:25:15 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ParserOutputAccess' => static function ( MediaWikiServices $services ): ParserOutputAccess {
|
2020-09-30 19:25:29 +00:00
|
|
|
return new ParserOutputAccess(
|
2023-03-23 14:48:49 +00:00
|
|
|
$services->getParserCacheFactory(),
|
2021-04-03 02:12:43 +00:00
|
|
|
$services->getRevisionLookup(),
|
2020-11-13 11:46:05 +00:00
|
|
|
$services->getRevisionRenderer(),
|
2020-11-16 20:05:03 +00:00
|
|
|
$services->getStatsdDataFactory(),
|
2020-11-13 12:04:35 +00:00
|
|
|
$services->getDBLoadBalancerFactory(),
|
2023-09-01 10:42:14 +00:00
|
|
|
$services->getChronologyProtector(),
|
2021-04-03 02:12:43 +00:00
|
|
|
LoggerFactory::getProvider(),
|
|
|
|
|
$services->getWikiPageFactory(),
|
|
|
|
|
$services->getTitleFormatter()
|
2020-09-30 19:25:29 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2022-03-25 20:34:04 +00:00
|
|
|
'ParsoidDataAccess' => static function ( MediaWikiServices $services ): DataAccess {
|
2022-03-25 21:11:51 +00:00
|
|
|
$mainConfig = $services->getMainConfig();
|
2022-03-25 20:34:04 +00:00
|
|
|
return new MWDataAccess(
|
2022-03-25 21:11:51 +00:00
|
|
|
new ServiceOptions( MWDataAccess::CONSTRUCTOR_OPTIONS, $mainConfig ),
|
2022-03-25 20:34:04 +00:00
|
|
|
$services->getRepoGroup(),
|
|
|
|
|
$services->getBadFileLookup(),
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getContentTransformer(),
|
2022-03-25 21:20:00 +00:00
|
|
|
$services->getReadOnlyMode(),
|
2022-12-19 20:15:01 +00:00
|
|
|
$services->getParserFactory(), // *legacy* parser factory
|
|
|
|
|
$services->getLinkBatchFactory()
|
2022-03-25 20:34:04 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2022-06-17 14:00:27 +00:00
|
|
|
'ParsoidOutputAccess' => static function ( MediaWikiServices $services ): ParsoidOutputAccess {
|
|
|
|
|
return new ParsoidOutputAccess(
|
2023-08-29 20:13:43 +00:00
|
|
|
$services->getParsoidParserFactory(),
|
|
|
|
|
$services->getParserOutputAccess(),
|
2022-09-13 15:52:44 +00:00
|
|
|
$services->getPageStore(),
|
2022-06-17 14:00:27 +00:00
|
|
|
$services->getRevisionLookup(),
|
2022-06-29 17:01:21 +00:00
|
|
|
$services->getParsoidSiteConfig(),
|
2022-12-08 22:01:49 +00:00
|
|
|
$services->getContentHandlerFactory()
|
2022-06-17 14:00:27 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2022-05-16 16:56:20 +00:00
|
|
|
'ParsoidOutputStash' => static function ( MediaWikiServices $services ): ParsoidOutputStash {
|
|
|
|
|
// TODO: Determine storage requirements and config options for stashing parsoid
|
|
|
|
|
// output for VE edits (T309016).
|
2022-06-02 18:15:36 +00:00
|
|
|
$config = $services->getMainConfig()->get( MainConfigNames::ParsoidCacheConfig );
|
2022-06-17 15:17:42 +00:00
|
|
|
$backend = $config['StashType']
|
|
|
|
|
? ObjectCache::getInstance( $config['StashType'] )
|
2022-06-02 18:15:36 +00:00
|
|
|
: $services->getMainObjectStash();
|
|
|
|
|
|
2022-10-29 18:52:23 +00:00
|
|
|
return new SimpleParsoidOutputStash(
|
|
|
|
|
$services->getContentHandlerFactory(),
|
|
|
|
|
$backend,
|
|
|
|
|
$config['StashDuration']
|
|
|
|
|
);
|
2022-05-16 16:56:20 +00:00
|
|
|
},
|
|
|
|
|
|
2022-03-25 20:34:04 +00:00
|
|
|
'ParsoidPageConfigFactory' => static function ( MediaWikiServices $services ): MWPageConfigFactory {
|
Use Bcp47Code when interfacing with Parsoid
It is very easy for developers and maintainers to mix up "internal
MediaWiki language codes" and "BCP-47 language codes"; the latter are
standards-compliant and used in web protocols like HTTP, HTML, and
SVG; but much of WMF production is very dependent on historical codes
used by MediaWiki which in some cases predate the IANA standardized
name for the language in question.
Phan and other static checking tools aren't much help distinguishing
BCP-47 from internal codes when both are represented with the PHP
string type, so the wikimedia/bcp-47-code package introduced a very
lightweight wrapper type in order to uniquely identify BCP-47 codes.
Language implements Bcp47Code, and LanguageFactory::getLanguage() is
an easy way to convert (or downcast) between Bcp47Code and Language
objects.
This patch updates the Parsoid integration code and the associated
REST handlers to use Bcp47Code in APIs so that the standalone Parsoid
library does not need to know anything about MediaWiki-internal codes.
The principle has been, first, to try to convert a string to a
Bcp47Code as soon as possible and as close to the original input as
possible, so it is easy to see *why* a given string is a BCP-47 code
(usually, because it is coming from HTTP/HTML/etc) and we're not stuck
deep inside some method trying to figure out where a string we're
given is coming from and therefore what sort of string code it might
be. Second, we've added explicit compatibility code to accept
MediaWiki internal codes and convert them to Bcp47Code for backward
compatibility with existing clients, using the @internal
LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention
is to gradually remove these backward compatibility thunks and replace
them with HTTP 400 errors or wfDeprecated messages in order to
identify and repair callers who are incorrectly using
non-standard-compliant language codes in web standards
(HTTP/HTML/SVG/etc).
Finally, maintaining a code as a Bcp47Code and not immediately
converting to Language helps us delay or even avoid full loading of a
Language object in some cases, which is another reason to occasionally
push Bcp47Code (instead of Language) down the call stack.
Bug: T327379
Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c
Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
|
|
|
return new MWPageConfigFactory(
|
|
|
|
|
$services->getRevisionStore(),
|
|
|
|
|
$services->getSlotRoleRegistry(),
|
|
|
|
|
$services->getLanguageFactory()
|
|
|
|
|
);
|
2022-03-25 20:34:04 +00:00
|
|
|
},
|
|
|
|
|
|
2022-05-27 16:38:32 +00:00
|
|
|
'ParsoidParserFactory' => static function ( MediaWikiServices $services ): ParsoidParserFactory {
|
|
|
|
|
return new ParsoidParserFactory(
|
|
|
|
|
$services->getParsoidSiteConfig(),
|
|
|
|
|
$services->getParsoidDataAccess(),
|
|
|
|
|
$services->getParsoidPageConfigFactory(),
|
|
|
|
|
$services->getLanguageConverterFactory(),
|
2023-08-29 20:13:43 +00:00
|
|
|
$services->getParserFactory(),
|
|
|
|
|
$services->getGlobalIdGenerator()
|
2022-05-27 16:38:32 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2022-03-25 20:34:04 +00:00
|
|
|
'ParsoidSiteConfig' => static function ( MediaWikiServices $services ): SiteConfig {
|
|
|
|
|
$mainConfig = $services->getMainConfig();
|
2022-04-01 15:58:32 +00:00
|
|
|
$parsoidSettings = $mainConfig->get( MainConfigNames::ParsoidSettings );
|
2022-03-25 20:34:04 +00:00
|
|
|
return new MWSiteConfig(
|
|
|
|
|
new ServiceOptions( MWSiteConfig::CONSTRUCTOR_OPTIONS, $mainConfig ),
|
|
|
|
|
$parsoidSettings,
|
|
|
|
|
$services->getObjectFactory(),
|
|
|
|
|
$services->getContentLanguage(),
|
|
|
|
|
$services->getStatsdDataFactory(),
|
|
|
|
|
$services->getMagicWordFactory(),
|
|
|
|
|
$services->getNamespaceInfo(),
|
|
|
|
|
$services->getSpecialPageFactory(),
|
|
|
|
|
$services->getInterwikiLookup(),
|
|
|
|
|
$services->getUserOptionsLookup(),
|
|
|
|
|
$services->getLanguageFactory(),
|
|
|
|
|
$services->getLanguageConverterFactory(),
|
|
|
|
|
$services->getLanguageNameUtils(),
|
2022-08-26 19:57:04 +00:00
|
|
|
$services->getUrlUtils(),
|
2023-07-15 14:51:26 +00:00
|
|
|
ExtensionRegistry::getInstance()->getAttribute( 'ParsoidModules' ),
|
2022-03-25 20:34:04 +00:00
|
|
|
// These arguments are temporary and will be removed once
|
|
|
|
|
// better solutions are found.
|
2023-07-29 10:48:43 +00:00
|
|
|
$services->getParserFactory(), // T268776
|
2023-07-15 14:51:26 +00:00
|
|
|
$mainConfig, // T268777
|
|
|
|
|
ExtensionRegistry::getInstance()->isLoaded( 'TimedMediaHandler' )
|
2022-03-25 20:34:04 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'PasswordFactory' => static function ( MediaWikiServices $services ): PasswordFactory {
|
2018-08-03 08:05:44 +00:00
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
return new PasswordFactory(
|
2022-04-01 15:58:32 +00:00
|
|
|
$config->get( MainConfigNames::PasswordConfig ),
|
|
|
|
|
$config->get( MainConfigNames::PasswordDefault )
|
2017-07-04 21:46:46 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'PasswordReset' => static function ( MediaWikiServices $services ): PasswordReset {
|
2019-10-08 18:26:17 +00:00
|
|
|
$options = new ServiceOptions( PasswordReset::CONSTRUCTOR_OPTIONS, $services->getMainConfig() );
|
2019-09-10 02:49:12 +00:00
|
|
|
return new PasswordReset(
|
|
|
|
|
$options,
|
2020-10-02 23:02:31 +00:00
|
|
|
LoggerFactory::getInstance( 'authentication' ),
|
2020-03-31 18:51:49 +00:00
|
|
|
$services->getAuthManager(),
|
2020-10-02 23:02:31 +00:00
|
|
|
$services->getHookContainer(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2020-10-02 23:02:31 +00:00
|
|
|
$services->getUserFactory(),
|
|
|
|
|
$services->getUserNameUtils(),
|
|
|
|
|
$services->getUserOptionsLookup()
|
2019-09-10 02:49:12 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2023-10-12 21:52:47 +00:00
|
|
|
'PerDbNameStatsdDataFactory' => static function ( MediaWikiServices $services ): StatsdDataFactoryInterface {
|
2018-08-03 08:05:44 +00:00
|
|
|
$config = $services->getMainConfig();
|
2022-04-01 15:58:32 +00:00
|
|
|
$wiki = $config->get( MainConfigNames::DBname );
|
2018-08-18 10:22:38 +00:00
|
|
|
return new PrefixingStatsdDataFactoryProxy(
|
|
|
|
|
$services->getStatsdDataFactory(),
|
|
|
|
|
$wiki
|
2017-07-04 21:46:46 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'PermissionManager' => static function ( MediaWikiServices $services ): PermissionManager {
|
2019-03-07 20:02:07 +00:00
|
|
|
return new PermissionManager(
|
2019-08-21 05:28:47 +00:00
|
|
|
new ServiceOptions(
|
2019-10-08 18:23:08 +00:00
|
|
|
PermissionManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
|
2019-08-21 05:28:47 +00:00
|
|
|
),
|
2019-03-07 20:02:07 +00:00
|
|
|
$services->getSpecialPageFactory(),
|
2019-09-20 15:03:48 +00:00
|
|
|
$services->getNamespaceInfo(),
|
2021-01-05 23:08:09 +00:00
|
|
|
$services->getGroupPermissionsLookup(),
|
|
|
|
|
$services->getUserGroupManager(),
|
2023-10-09 05:10:06 +00:00
|
|
|
$services->getBlockManager(),
|
2023-10-01 12:03:37 +00:00
|
|
|
$services->getFormatterFactory()->getBlockErrorFormatter(
|
|
|
|
|
new LazyLocalizationContext( static function () {
|
|
|
|
|
return RequestContext::getMain();
|
|
|
|
|
} )
|
|
|
|
|
),
|
2020-10-20 17:34:25 +00:00
|
|
|
$services->getHookContainer(),
|
2021-10-20 15:51:22 +00:00
|
|
|
$services->getUserCache(),
|
2022-04-14 16:39:56 +00:00
|
|
|
$services->getRedirectLookup(),
|
|
|
|
|
$services->getRestrictionStore(),
|
2022-04-11 01:39:33 +00:00
|
|
|
$services->getTitleFormatter(),
|
|
|
|
|
$services->getTempUserConfig(),
|
2022-04-15 21:36:33 +00:00
|
|
|
$services->getUserFactory(),
|
|
|
|
|
$services->getActionFactory()
|
2019-04-09 09:28:38 +00:00
|
|
|
);
|
2019-03-07 20:02:07 +00:00
|
|
|
},
|
|
|
|
|
|
2023-12-11 15:05:02 +00:00
|
|
|
'Pingback' => static function ( MediaWikiServices $services ): Pingback {
|
2023-05-31 13:00:55 +00:00
|
|
|
return new Pingback(
|
|
|
|
|
$services->getMainConfig(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2023-05-31 13:00:55 +00:00
|
|
|
ObjectCache::getLocalClusterInstance(),
|
|
|
|
|
$services->getHttpRequestFactory(),
|
|
|
|
|
LoggerFactory::getInstance( 'Pingback' )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2022-12-14 21:56:52 +00:00
|
|
|
'PoolCounterFactory' => static function ( MediaWikiServices $services ): PoolCounterFactory {
|
|
|
|
|
$mainConfig = $services->getMainConfig();
|
|
|
|
|
return new PoolCounterFactory(
|
|
|
|
|
$mainConfig->get( MainConfigNames::PoolCounterConf ),
|
2024-03-01 19:00:23 +00:00
|
|
|
$mainConfig->get( MainConfigNames::PoolCountClientConf ),
|
|
|
|
|
LoggerFactory::getInstance( 'poolcounter' )
|
2022-12-14 21:56:52 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'PreferencesFactory' => static function ( MediaWikiServices $services ): PreferencesFactory {
|
2018-07-26 20:23:07 +00:00
|
|
|
$factory = new DefaultPreferencesFactory(
|
2019-04-10 15:03:54 +00:00
|
|
|
new ServiceOptions(
|
2019-10-08 18:28:15 +00:00
|
|
|
DefaultPreferencesFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
2018-07-26 20:23:07 +00:00
|
|
|
$services->getContentLanguage(),
|
2020-03-31 18:51:49 +00:00
|
|
|
$services->getAuthManager(),
|
2018-08-05 12:56:23 +00:00
|
|
|
$services->getLinkRendererFactory()->create(),
|
2019-08-22 22:53:05 +00:00
|
|
|
$services->getNamespaceInfo(),
|
2020-02-04 12:42:03 +00:00
|
|
|
$services->getPermissionManager(),
|
2020-01-03 23:03:14 +00:00
|
|
|
$services->getLanguageConverterFactory()->getLanguageConverter(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getLanguageNameUtils(),
|
2021-03-16 15:16:18 +00:00
|
|
|
$services->getHookContainer(),
|
2021-06-05 03:45:14 +00:00
|
|
|
$services->getUserOptionsManager(),
|
2021-06-04 23:24:44 +00:00
|
|
|
$services->getLanguageConverterFactory(),
|
2023-07-29 12:11:56 +00:00
|
|
|
$services->getParserFactory(),
|
2021-06-04 23:24:44 +00:00
|
|
|
$services->getSkinFactory(),
|
2022-04-07 23:52:05 +00:00
|
|
|
$services->getUserGroupManager(),
|
2024-02-19 10:46:50 +00:00
|
|
|
$services->getSignatureValidatorFactory()
|
2018-07-26 20:23:07 +00:00
|
|
|
);
|
2018-08-03 08:05:44 +00:00
|
|
|
$factory->setLogger( LoggerFactory::getInstance( 'preferences' ) );
|
2017-10-07 02:26:52 +00:00
|
|
|
|
|
|
|
|
return $factory;
|
|
|
|
|
},
|
|
|
|
|
|
2023-04-19 22:27:50 +00:00
|
|
|
'PreloadedContentBuilder' => static function ( MediaWikiServices $services ): PreloadedContentBuilder {
|
|
|
|
|
return new PreloadedContentBuilder(
|
|
|
|
|
$services->getContentHandlerFactory(),
|
|
|
|
|
$services->getWikiPageFactory(),
|
|
|
|
|
$services->getRedirectLookup(),
|
|
|
|
|
$services->getSpecialPageFactory(),
|
|
|
|
|
$services->getContentTransformer(),
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ProxyLookup' => static function ( MediaWikiServices $services ): ProxyLookup {
|
2018-08-03 08:05:44 +00:00
|
|
|
$mainConfig = $services->getMainConfig();
|
|
|
|
|
return new ProxyLookup(
|
2022-04-01 15:58:32 +00:00
|
|
|
$mainConfig->get( MainConfigNames::CdnServers ),
|
|
|
|
|
$mainConfig->get( MainConfigNames::CdnServersNoPurge ),
|
2021-03-30 18:43:18 +00:00
|
|
|
$services->getHookContainer()
|
2018-08-03 08:05:44 +00:00
|
|
|
);
|
|
|
|
|
},
|
2017-11-14 11:17:34 +00:00
|
|
|
|
2022-05-24 20:54:25 +00:00
|
|
|
'RateLimiter' => static function ( MediaWikiServices $services ): RateLimiter {
|
2023-06-18 12:31:18 +00:00
|
|
|
$rateLimiter = new RateLimiter(
|
2022-05-24 20:54:25 +00:00
|
|
|
new ServiceOptions( RateLimiter::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
2022-07-01 06:07:07 +00:00
|
|
|
$services->getWRStatsFactory(),
|
2022-05-24 20:54:25 +00:00
|
|
|
$services->getCentralIdLookupFactory()->getNonLocalLookup(),
|
|
|
|
|
$services->getUserFactory(),
|
|
|
|
|
$services->getUserGroupManager(),
|
|
|
|
|
$services->getHookContainer()
|
|
|
|
|
);
|
2023-06-18 12:31:18 +00:00
|
|
|
|
|
|
|
|
$rateLimiter->setStats( $services->getStatsdDataFactory() );
|
|
|
|
|
|
|
|
|
|
return $rateLimiter;
|
2022-05-24 20:54:25 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ReadOnlyMode' => static function ( MediaWikiServices $services ): ReadOnlyMode {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new ReadOnlyMode(
|
2023-09-11 18:39:11 +00:00
|
|
|
new ConfiguredReadOnlyMode(
|
|
|
|
|
$services->getMainConfig()->get( MainConfigNames::ReadOnly ),
|
|
|
|
|
$services->getMainConfig()->get( MainConfigNames::ReadOnlyFile )
|
|
|
|
|
),
|
2023-09-08 11:58:27 +00:00
|
|
|
$services->getDBLoadBalancerFactory()
|
2017-11-14 11:17:34 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-10-20 15:51:22 +00:00
|
|
|
'RedirectLookup' => static function ( MediaWikiServices $services ): RedirectLookup {
|
|
|
|
|
return $services->getRedirectStore();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'RedirectStore' => static function ( MediaWikiServices $services ): RedirectStore {
|
|
|
|
|
return new RedirectStore( $services->getWikiPageFactory() );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'RepoGroup' => static function ( MediaWikiServices $services ): RepoGroup {
|
2019-05-01 12:54:54 +00:00
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
return new RepoGroup(
|
2022-04-01 15:58:32 +00:00
|
|
|
$config->get( MainConfigNames::LocalFileRepo ),
|
|
|
|
|
$config->get( MainConfigNames::ForeignFileRepos ),
|
2021-08-13 11:46:31 +00:00
|
|
|
$services->getMainWANObjectCache(),
|
|
|
|
|
$services->getMimeAnalyzer()
|
2019-05-01 12:54:54 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ResourceLoader' => static function ( MediaWikiServices $services ): ResourceLoader {
|
2019-03-29 01:21:18 +00:00
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
|
2022-05-15 17:08:20 +00:00
|
|
|
$maxage = $config->get( MainConfigNames::ResourceLoaderMaxage );
|
2019-03-29 01:21:18 +00:00
|
|
|
$rl = new ResourceLoader(
|
|
|
|
|
$config,
|
2019-06-29 04:50:31 +00:00
|
|
|
LoggerFactory::getInstance( 'resourceloader' ),
|
2022-04-01 15:58:32 +00:00
|
|
|
$config->get( MainConfigNames::ResourceLoaderUseObjectCacheForDeps )
|
2019-06-29 04:50:31 +00:00
|
|
|
? new KeyValueDependencyStore( $services->getMainObjectStash() )
|
2022-05-15 17:08:20 +00:00
|
|
|
: new SqlModuleDependencyStore( $services->getDBLoadBalancer() ),
|
|
|
|
|
[
|
|
|
|
|
'loadScript' => $config->get( MainConfigNames::LoadScript ),
|
|
|
|
|
'maxageVersioned' => $maxage['versioned'] ?? null,
|
|
|
|
|
'maxageUnversioned' => $maxage['unversioned'] ?? null,
|
|
|
|
|
]
|
2019-02-16 23:16:09 +00:00
|
|
|
);
|
2019-04-17 14:17:15 +00:00
|
|
|
|
2020-03-09 20:12:45 +00:00
|
|
|
$extRegistry = ExtensionRegistry::getInstance();
|
|
|
|
|
// Attribute has precedence over config
|
2020-03-09 20:12:45 +00:00
|
|
|
$modules = $extRegistry->getAttribute( 'ResourceModules' )
|
2022-04-01 15:58:32 +00:00
|
|
|
+ $config->get( MainConfigNames::ResourceModules );
|
2020-03-09 20:12:45 +00:00
|
|
|
$moduleSkinStyles = $extRegistry->getAttribute( 'ResourceModuleSkinStyles' )
|
2022-04-01 15:58:32 +00:00
|
|
|
+ $config->get( MainConfigNames::ResourceModuleSkinStyles );
|
2020-03-09 20:12:45 +00:00
|
|
|
|
|
|
|
|
$rl->setModuleSkinStyles( $moduleSkinStyles );
|
2022-04-01 15:58:32 +00:00
|
|
|
$rl->addSource( $config->get( MainConfigNames::ResourceLoaderSources ) );
|
2019-04-17 14:17:15 +00:00
|
|
|
|
|
|
|
|
// Core modules, then extension/skin modules
|
2023-07-24 16:56:00 +00:00
|
|
|
$rl->register( include MW_INSTALL_PATH . '/resources/Resources.php' );
|
2020-03-09 20:12:45 +00:00
|
|
|
$rl->register( $modules );
|
2020-07-29 15:41:38 +00:00
|
|
|
$hookRunner = new \MediaWiki\ResourceLoader\HookRunner( $services->getHookContainer() );
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$hookRunner->onResourceLoaderRegisterModules( $rl );
|
2019-04-17 14:17:15 +00:00
|
|
|
|
2019-10-12 03:17:51 +00:00
|
|
|
$msgPosterAttrib = $extRegistry->getAttribute( 'MessagePosterModule' );
|
|
|
|
|
$rl->register( 'mediawiki.messagePoster', [
|
2023-07-24 16:56:00 +00:00
|
|
|
'localBasePath' => MW_INSTALL_PATH,
|
2019-10-12 03:17:51 +00:00
|
|
|
'debugRaw' => false,
|
|
|
|
|
'scripts' => array_merge(
|
|
|
|
|
[
|
2020-10-28 02:18:32 +00:00
|
|
|
"resources/src/mediawiki.messagePoster/factory.js",
|
|
|
|
|
"resources/src/mediawiki.messagePoster/MessagePoster.js",
|
|
|
|
|
"resources/src/mediawiki.messagePoster/WikitextMessagePoster.js",
|
2019-10-12 03:17:51 +00:00
|
|
|
],
|
|
|
|
|
$msgPosterAttrib['scripts'] ?? []
|
|
|
|
|
),
|
|
|
|
|
'dependencies' => array_merge(
|
|
|
|
|
[
|
|
|
|
|
'oojs',
|
|
|
|
|
'mediawiki.api',
|
|
|
|
|
'mediawiki.ForeignApi',
|
|
|
|
|
],
|
|
|
|
|
$msgPosterAttrib['dependencies'] ?? []
|
|
|
|
|
),
|
|
|
|
|
] );
|
|
|
|
|
|
2022-04-01 15:58:32 +00:00
|
|
|
if ( $config->get( MainConfigNames::EnableJavaScriptTest ) === true ) {
|
2019-04-17 14:17:15 +00:00
|
|
|
$rl->registerTestModules();
|
|
|
|
|
}
|
2019-03-29 01:21:18 +00:00
|
|
|
|
|
|
|
|
return $rl;
|
2019-02-16 23:16:09 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-26 13:24:22 +00:00
|
|
|
'RestrictionStore' => static function ( MediaWikiServices $services ): RestrictionStore {
|
|
|
|
|
return new RestrictionStore(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
RestrictionStore::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$services->getMainWANObjectCache(),
|
|
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
$services->getLinkCache(),
|
2022-05-12 09:12:38 +00:00
|
|
|
$services->getLinksMigration(),
|
2021-07-26 13:24:22 +00:00
|
|
|
$services->getCommentStore(),
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getPageStore()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'RevertedTagUpdateManager' => static function ( MediaWikiServices $services ): RevertedTagUpdateManager {
|
2020-07-06 11:47:22 +00:00
|
|
|
$editResultCache = new EditResultCache(
|
|
|
|
|
$services->getMainObjectStash(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2020-07-06 11:47:22 +00:00
|
|
|
new ServiceOptions(
|
|
|
|
|
EditResultCache::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return new RevertedTagUpdateManager(
|
|
|
|
|
$editResultCache,
|
2021-03-17 12:37:06 +00:00
|
|
|
$services->getJobQueueGroup()
|
2020-07-06 11:47:22 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'RevisionFactory' => static function ( MediaWikiServices $services ): RevisionFactory {
|
2018-08-03 08:05:44 +00:00
|
|
|
return $services->getRevisionStore();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'RevisionLookup' => static function ( MediaWikiServices $services ): RevisionLookup {
|
2018-08-03 08:05:44 +00:00
|
|
|
return $services->getRevisionStore();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'RevisionRenderer' => static function ( MediaWikiServices $services ): RevisionRenderer {
|
2018-11-19 11:39:56 +00:00
|
|
|
$renderer = new RevisionRenderer(
|
|
|
|
|
$services->getDBLoadBalancer(),
|
2021-09-29 14:02:36 +00:00
|
|
|
$services->getSlotRoleRegistry(),
|
|
|
|
|
$services->getContentRenderer()
|
2018-11-19 11:39:56 +00:00
|
|
|
);
|
2018-10-29 22:48:22 +00:00
|
|
|
|
2018-11-19 11:39:56 +00:00
|
|
|
$renderer->setLogger( LoggerFactory::getInstance( 'SaveParse' ) );
|
2018-10-29 22:48:22 +00:00
|
|
|
return $renderer;
|
2018-08-07 16:52:40 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'RevisionStore' => static function ( MediaWikiServices $services ): RevisionStore {
|
2018-06-27 12:16:35 +00:00
|
|
|
return $services->getRevisionStoreFactory()->getRevisionStore();
|
|
|
|
|
},
|
2017-11-15 12:02:40 +00:00
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'RevisionStoreFactory' => static function ( MediaWikiServices $services ): RevisionStoreFactory {
|
2022-04-12 19:19:32 +00:00
|
|
|
return new RevisionStoreFactory(
|
2018-06-27 12:16:35 +00:00
|
|
|
$services->getDBLoadBalancerFactory(),
|
|
|
|
|
$services->getBlobStoreFactory(),
|
2018-09-04 01:59:03 +00:00
|
|
|
$services->getNameTableStoreFactory(),
|
2018-11-19 11:39:56 +00:00
|
|
|
$services->getSlotRoleRegistry(),
|
2018-01-29 14:25:49 +00:00
|
|
|
$services->getMainWANObjectCache(),
|
2021-12-17 17:56:27 +00:00
|
|
|
$services->getLocalServerObjectCache(),
|
2017-09-12 17:12:29 +00:00
|
|
|
$services->getCommentStore(),
|
2021-02-04 02:43:09 +00:00
|
|
|
$services->getActorStoreFactory(),
|
2019-09-10 02:24:18 +00:00
|
|
|
LoggerFactory::getInstance( 'RevisionStore' ),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getContentHandlerFactory(),
|
2021-03-17 22:13:35 +00:00
|
|
|
$services->getPageStoreFactory(),
|
2021-03-15 18:09:19 +00:00
|
|
|
$services->getTitleFactory(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getHookContainer()
|
2017-11-15 12:02:40 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'RollbackPageFactory' => static function ( MediaWikiServices $services ): RollbackPageFactory {
|
2021-03-26 22:56:39 +00:00
|
|
|
return $services->get( '_PageCommandFactory' );
|
|
|
|
|
},
|
|
|
|
|
|
Introduce CommentFormatter
CommentParser:
* Move comment formatting backend from Linker to a CommentParser service.
Allow link existence and file existence to be batched.
* Rename $local to $samePage since I think that is clearer.
* Rename $title to $selfLinkTarget since it was unclear what the title
was used for.
* Rename the "autocomment" concept to "section link" in public
interfaces, although the old term remains in CSS classes.
* Keep unsafe HTML pass-through in separate "unsafe" methods, for easier
static analysis and code review.
CommentFormatter:
* Add CommentFormatter and RowCommentFormatter services as a usable
frontend for comment batches, and to replace the Linker static methods.
* Provide fluent and parametric interfaces.
Linker:
* Remove Linker::makeCommentLink() without deprecation -- nothing calls
it and it is obviously an internal helper.
* Soft-deprecate Linker methods formatComment(), formatLinksInComment(),
commentBlock() and revComment().
Caller migration:
* CommentFormatter single: Linker, RollbackAction, ApiComparePages,
ApiParse
* CommentFormatter parametric batch: ImageHistoryPseudoPager
* CommentFormatter fluent batch: ApiQueryFilearchive
* RowCommentFormatter sequential: History feed, BlocklistPager,
ProtectedPagesPager, ApiQueryProtectedTitles
* RowCommentFormatter with index: ChangesFeed, ChangesList,
ApiQueryDeletedrevs, ApiQueryLogEvents, ApiQueryRecentChanges
* RevisionCommentBatch: HistoryPager, ContribsPager
Bug: T285917
Change-Id: Ia3fd50a4a13138ba5003d884962da24746d562d0
2021-07-01 06:55:03 +00:00
|
|
|
'RowCommentFormatter' => static function ( MediaWikiServices $services ): RowCommentFormatter {
|
|
|
|
|
return new RowCommentFormatter(
|
2023-05-05 09:45:35 +00:00
|
|
|
$services->getCommentParserFactory(),
|
Introduce CommentFormatter
CommentParser:
* Move comment formatting backend from Linker to a CommentParser service.
Allow link existence and file existence to be batched.
* Rename $local to $samePage since I think that is clearer.
* Rename $title to $selfLinkTarget since it was unclear what the title
was used for.
* Rename the "autocomment" concept to "section link" in public
interfaces, although the old term remains in CSS classes.
* Keep unsafe HTML pass-through in separate "unsafe" methods, for easier
static analysis and code review.
CommentFormatter:
* Add CommentFormatter and RowCommentFormatter services as a usable
frontend for comment batches, and to replace the Linker static methods.
* Provide fluent and parametric interfaces.
Linker:
* Remove Linker::makeCommentLink() without deprecation -- nothing calls
it and it is obviously an internal helper.
* Soft-deprecate Linker methods formatComment(), formatLinksInComment(),
commentBlock() and revComment().
Caller migration:
* CommentFormatter single: Linker, RollbackAction, ApiComparePages,
ApiParse
* CommentFormatter parametric batch: ImageHistoryPseudoPager
* CommentFormatter fluent batch: ApiQueryFilearchive
* RowCommentFormatter sequential: History feed, BlocklistPager,
ProtectedPagesPager, ApiQueryProtectedTitles
* RowCommentFormatter with index: ChangesFeed, ChangesList,
ApiQueryDeletedrevs, ApiQueryLogEvents, ApiQueryRecentChanges
* RevisionCommentBatch: HistoryPager, ContribsPager
Bug: T285917
Change-Id: Ia3fd50a4a13138ba5003d884962da24746d562d0
2021-07-01 06:55:03 +00:00
|
|
|
$services->getCommentStore()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'SearchEngineConfig' => static function ( MediaWikiServices $services ): SearchEngineConfig {
|
2019-04-10 15:03:54 +00:00
|
|
|
// @todo This should not take a Config object, but it's not so easy to remove because it
|
|
|
|
|
// exposes it in a getter, which is actually used.
|
2020-04-27 12:44:55 +00:00
|
|
|
return new SearchEngineConfig(
|
|
|
|
|
$services->getMainConfig(),
|
|
|
|
|
$services->getContentLanguage(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getHookContainer(),
|
2022-04-22 12:39:40 +00:00
|
|
|
ExtensionRegistry::getInstance()->getAttribute( 'SearchMappings' ),
|
|
|
|
|
$services->getUserOptionsLookup()
|
2020-04-27 12:44:55 +00:00
|
|
|
);
|
2018-01-09 08:53:38 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'SearchEngineFactory' => static function ( MediaWikiServices $services ): SearchEngineFactory {
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
return new SearchEngineFactory(
|
|
|
|
|
$services->getSearchEngineConfig(),
|
2021-04-22 20:46:26 +00:00
|
|
|
$services->getHookContainer(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider()
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
);
|
2018-01-09 08:53:38 +00:00
|
|
|
},
|
|
|
|
|
|
2022-08-31 14:51:57 +00:00
|
|
|
'SearchResultThumbnailProvider' => static function ( MediaWikiServices $services ): SearchResultThumbnailProvider {
|
|
|
|
|
return new SearchResultThumbnailProvider(
|
|
|
|
|
$services->getRepoGroup(),
|
|
|
|
|
$services->getHookContainer()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ShellboxClientFactory' => static function ( MediaWikiServices $services ): ShellboxClientFactory {
|
2022-04-01 15:58:32 +00:00
|
|
|
$urls = $services->getMainConfig()->get( MainConfigNames::ShellboxUrls );
|
2022-09-21 15:16:26 +00:00
|
|
|
|
2020-09-11 03:21:24 +00:00
|
|
|
return new ShellboxClientFactory(
|
|
|
|
|
$services->getHttpRequestFactory(),
|
2021-06-18 08:41:28 +00:00
|
|
|
$urls,
|
2022-04-01 15:58:32 +00:00
|
|
|
$services->getMainConfig()->get( MainConfigNames::ShellboxSecretKey )
|
2020-09-11 03:21:24 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ShellCommandFactory' => static function ( MediaWikiServices $services ): CommandFactory {
|
2018-08-03 08:05:44 +00:00
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
|
|
|
|
|
$limits = [
|
2022-04-01 15:58:32 +00:00
|
|
|
'time' => $config->get( MainConfigNames::MaxShellTime ),
|
|
|
|
|
'walltime' => $config->get( MainConfigNames::MaxShellWallClockTime ),
|
|
|
|
|
'memory' => $config->get( MainConfigNames::MaxShellMemory ),
|
|
|
|
|
'filesize' => $config->get( MainConfigNames::MaxShellFileSize ),
|
2018-08-03 08:05:44 +00:00
|
|
|
];
|
2022-04-01 15:58:32 +00:00
|
|
|
$cgroup = $config->get( MainConfigNames::ShellCgroup );
|
|
|
|
|
$restrictionMethod = $config->get( MainConfigNames::ShellRestrictionMethod );
|
2018-08-03 08:05:44 +00:00
|
|
|
|
2020-09-11 03:21:24 +00:00
|
|
|
$factory = new CommandFactory( $services->getShellboxClientFactory(),
|
|
|
|
|
$limits, $cgroup, $restrictionMethod );
|
2018-08-03 08:05:44 +00:00
|
|
|
$factory->setLogger( LoggerFactory::getInstance( 'exec' ) );
|
|
|
|
|
$factory->logStderr();
|
|
|
|
|
|
|
|
|
|
return $factory;
|
2017-12-23 17:14:28 +00:00
|
|
|
},
|
|
|
|
|
|
2021-12-12 15:18:36 +00:00
|
|
|
'SignatureValidatorFactory' => static function ( MediaWikiServices $services ): SignatureValidatorFactory {
|
|
|
|
|
return new SignatureValidatorFactory(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
SignatureValidator::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
2023-08-08 12:51:43 +00:00
|
|
|
// Use closures for these to avoid a circular dependency on Parser
|
2022-04-07 23:52:05 +00:00
|
|
|
static function () use ( $services ) {
|
2022-06-20 03:48:44 +00:00
|
|
|
return $services->getParserFactory();
|
2022-04-07 23:52:05 +00:00
|
|
|
},
|
2023-08-08 12:51:43 +00:00
|
|
|
static function () use ( $services ) {
|
|
|
|
|
return $services->get( '_Parsoid' );
|
|
|
|
|
},
|
|
|
|
|
$services->getParsoidPageConfigFactory(),
|
2021-12-12 15:18:36 +00:00
|
|
|
$services->getSpecialPageFactory(),
|
2024-03-22 18:16:20 +00:00
|
|
|
$services->getTitleFactory(),
|
|
|
|
|
$services->getExtensionRegistry()
|
2021-12-12 15:18:36 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'SiteLookup' => static function ( MediaWikiServices $services ): SiteLookup {
|
2019-03-14 19:46:19 +00:00
|
|
|
// Use SiteStore as the SiteLookup as well. This was originally separated
|
2020-01-02 23:50:53 +00:00
|
|
|
// to allow for a cacheable read-only interface, but this was never used.
|
|
|
|
|
// SiteStore has caching (see below).
|
2019-03-14 19:46:19 +00:00
|
|
|
return $services->getSiteStore();
|
2017-11-15 12:02:40 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'SiteStore' => static function ( MediaWikiServices $services ): SiteStore {
|
2024-01-13 07:50:18 +00:00
|
|
|
$rawSiteStore = new DBSiteStore( $services->getConnectionProvider() );
|
2018-08-03 08:05:44 +00:00
|
|
|
|
2019-07-20 21:09:31 +00:00
|
|
|
$cache = $services->getLocalServerObjectCache();
|
|
|
|
|
if ( $cache instanceof EmptyBagOStuff ) {
|
|
|
|
|
$cache = ObjectCache::getLocalClusterInstance();
|
|
|
|
|
}
|
2018-08-03 08:05:44 +00:00
|
|
|
|
|
|
|
|
return new CachingSiteStore( $rawSiteStore, $cache );
|
2017-11-15 12:02:40 +00:00
|
|
|
},
|
|
|
|
|
|
2020-05-29 23:00:19 +00:00
|
|
|
/** @suppress PhanTypeInvalidCallableArrayKey */
|
2021-07-22 03:11:47 +00:00
|
|
|
'SkinFactory' => static function ( MediaWikiServices $services ): SkinFactory {
|
2020-07-15 05:28:37 +00:00
|
|
|
$factory = new SkinFactory(
|
|
|
|
|
$services->getObjectFactory(),
|
2022-04-01 15:58:32 +00:00
|
|
|
(array)$services->getMainConfig()->get( MainConfigNames::SkipSkins )
|
2020-07-15 05:28:37 +00:00
|
|
|
);
|
2018-08-03 08:05:44 +00:00
|
|
|
|
2022-04-01 15:58:32 +00:00
|
|
|
$names = $services->getMainConfig()->get( MainConfigNames::ValidSkinNames );
|
2018-08-03 08:05:44 +00:00
|
|
|
|
|
|
|
|
foreach ( $names as $name => $skin ) {
|
2020-05-14 11:20:24 +00:00
|
|
|
if ( is_array( $skin ) ) {
|
|
|
|
|
$spec = $skin;
|
|
|
|
|
$displayName = $skin['displayname'] ?? $name;
|
2022-02-05 05:35:29 +00:00
|
|
|
$skippable = $skin['skippable'] ?? null;
|
2020-05-14 11:20:24 +00:00
|
|
|
} else {
|
|
|
|
|
$displayName = $skin;
|
2022-02-05 05:35:29 +00:00
|
|
|
$skippable = null;
|
2020-05-14 11:20:24 +00:00
|
|
|
$spec = [
|
2020-09-16 10:02:31 +00:00
|
|
|
'name' => $name,
|
2020-05-14 11:20:24 +00:00
|
|
|
'class' => "Skin$skin"
|
|
|
|
|
];
|
|
|
|
|
}
|
2021-09-15 00:26:48 +00:00
|
|
|
$factory->register( $name, $displayName, $spec, $skippable );
|
2018-08-03 08:05:44 +00:00
|
|
|
}
|
2020-05-14 11:20:24 +00:00
|
|
|
|
2018-08-03 08:05:44 +00:00
|
|
|
// Register a hidden "fallback" skin
|
2020-02-06 09:44:05 +00:00
|
|
|
$factory->register( 'fallback', 'Fallback', [
|
2020-05-29 23:00:19 +00:00
|
|
|
'class' => SkinFallback::class,
|
|
|
|
|
'args' => [
|
|
|
|
|
[
|
2020-09-16 10:02:31 +00:00
|
|
|
'name' => 'fallback',
|
2020-05-29 23:00:19 +00:00
|
|
|
'styles' => [ 'mediawiki.skinning.interface' ],
|
|
|
|
|
'templateDirectory' => __DIR__ . '/skins/templates/fallback',
|
|
|
|
|
]
|
|
|
|
|
]
|
2021-09-15 00:26:48 +00:00
|
|
|
], true );
|
2018-08-03 08:05:44 +00:00
|
|
|
// Register a hidden skin for api output
|
2020-02-06 09:44:05 +00:00
|
|
|
$factory->register( 'apioutput', 'ApiOutput', [
|
2020-05-29 23:00:19 +00:00
|
|
|
'class' => SkinApi::class,
|
|
|
|
|
'args' => [
|
|
|
|
|
[
|
2020-09-16 10:02:31 +00:00
|
|
|
'name' => 'apioutput',
|
2020-05-29 23:00:19 +00:00
|
|
|
'styles' => [ 'mediawiki.skinning.interface' ],
|
|
|
|
|
'templateDirectory' => __DIR__ . '/skins/templates/apioutput',
|
|
|
|
|
]
|
|
|
|
|
]
|
2021-09-15 00:26:48 +00:00
|
|
|
], true );
|
2018-08-03 08:05:44 +00:00
|
|
|
|
|
|
|
|
return $factory;
|
2018-01-16 13:53:22 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'SlotRoleRegistry' => static function ( MediaWikiServices $services ): SlotRoleRegistry {
|
2018-11-19 11:39:56 +00:00
|
|
|
$registry = new SlotRoleRegistry(
|
2020-05-27 20:41:19 +00:00
|
|
|
$services->getSlotRoleStore()
|
2018-11-19 11:39:56 +00:00
|
|
|
);
|
|
|
|
|
|
2021-03-11 20:24:22 +00:00
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
$contentHandlerFactory = $services->getContentHandlerFactory();
|
|
|
|
|
$hookContainer = $services->getHookContainer();
|
|
|
|
|
$titleFactory = $services->getTitleFactory();
|
|
|
|
|
$registry->defineRole(
|
2023-01-03 15:24:42 +00:00
|
|
|
SlotRecord::MAIN,
|
2021-03-11 20:24:22 +00:00
|
|
|
static function () use ( $config, $contentHandlerFactory, $hookContainer, $titleFactory ) {
|
|
|
|
|
return new MainSlotRoleHandler(
|
2022-04-01 15:58:32 +00:00
|
|
|
$config->get( MainConfigNames::NamespaceContentModels ),
|
2021-03-11 20:24:22 +00:00
|
|
|
$contentHandlerFactory,
|
|
|
|
|
$hookContainer,
|
|
|
|
|
$titleFactory
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|
2018-11-19 11:39:56 +00:00
|
|
|
|
|
|
|
|
return $registry;
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'SlotRoleStore' => static function ( MediaWikiServices $services ): NameTableStore {
|
2020-05-27 14:45:29 +00:00
|
|
|
return $services->getNameTableStoreFactory()->getSlotRoles();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'SpamChecker' => static function ( MediaWikiServices $services ): SpamChecker {
|
2020-04-25 04:21:55 +00:00
|
|
|
return new SpamChecker(
|
2022-04-01 15:58:32 +00:00
|
|
|
(array)$services->getMainConfig()->get( MainConfigNames::SpamRegex ),
|
|
|
|
|
(array)$services->getMainConfig()->get( MainConfigNames::SummarySpamRegex )
|
2020-04-25 04:21:55 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'SpecialPageFactory' => static function ( MediaWikiServices $services ): SpecialPageFactory {
|
2018-08-07 10:58:31 +00:00
|
|
|
return new SpecialPageFactory(
|
2019-04-10 15:03:54 +00:00
|
|
|
new ServiceOptions(
|
2019-10-08 18:30:32 +00:00
|
|
|
SpecialPageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
2019-09-06 09:21:29 +00:00
|
|
|
$services->getContentLanguage(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getObjectFactory(),
|
2021-04-11 20:48:13 +00:00
|
|
|
$services->getTitleFactory(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getHookContainer()
|
2018-08-07 10:58:31 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'StatsdDataFactory' => static function ( MediaWikiServices $services ): IBufferingStatsdDataFactory {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new BufferingStatsdDataFactory(
|
2022-04-01 15:58:32 +00:00
|
|
|
rtrim( $services->getMainConfig()->get( MainConfigNames::StatsdMetricPrefix ), '.' )
|
2018-06-21 06:59:02 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2023-02-24 21:18:13 +00:00
|
|
|
'StatsFactory' => static function ( MediaWikiServices $services ): StatsFactory {
|
|
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
$format = \Wikimedia\Stats\OutputFormats::getFormatFromString(
|
|
|
|
|
$config->get( MainConfigNames::StatsFormat ) ?? 'null'
|
|
|
|
|
);
|
2023-03-06 19:00:43 +00:00
|
|
|
$cache = new StatsCache;
|
2023-02-24 21:18:13 +00:00
|
|
|
$emitter = \Wikimedia\Stats\OutputFormats::getNewEmitter(
|
|
|
|
|
$config->get( MainConfigNames::StatsPrefix ) ?? 'MediaWiki',
|
|
|
|
|
$cache,
|
|
|
|
|
\Wikimedia\Stats\OutputFormats::getNewFormatter( $format ),
|
|
|
|
|
$config->get( MainConfigNames::StatsTarget )
|
|
|
|
|
);
|
2023-03-06 19:00:43 +00:00
|
|
|
$factory = new StatsFactory( $cache, $emitter, LoggerFactory::getInstance( 'Stats' ) );
|
2023-03-03 16:10:54 +00:00
|
|
|
return $factory->withStatsdDataFactory( $services->getStatsdDataFactory() );
|
2023-02-24 21:18:13 +00:00
|
|
|
},
|
|
|
|
|
|
2021-02-10 22:31:02 +00:00
|
|
|
'TalkPageNotificationManager' => static function (
|
2020-04-04 03:39:01 +00:00
|
|
|
MediaWikiServices $services
|
2021-07-22 03:11:47 +00:00
|
|
|
): TalkPageNotificationManager {
|
2020-04-04 03:39:01 +00:00
|
|
|
return new TalkPageNotificationManager(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
TalkPageNotificationManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
|
|
|
|
|
),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2020-04-04 03:39:01 +00:00
|
|
|
$services->getReadOnlyMode(),
|
2022-03-18 00:51:34 +00:00
|
|
|
$services->getRevisionLookup(),
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getUserFactory()
|
2020-04-04 03:39:01 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'TempFSFileFactory' => static function ( MediaWikiServices $services ): TempFSFileFactory {
|
2022-04-01 15:58:32 +00:00
|
|
|
return new TempFSFileFactory( $services->getMainConfig()->get( MainConfigNames::TmpDirectory ) );
|
2019-08-16 10:00:15 +00:00
|
|
|
},
|
|
|
|
|
|
2022-02-28 03:05:58 +00:00
|
|
|
'TempUserConfig' => static function ( MediaWikiServices $services ): RealTempUserConfig {
|
|
|
|
|
return new RealTempUserConfig(
|
2022-04-25 15:19:41 +00:00
|
|
|
$services->getMainConfig()->get( MainConfigNames::AutoCreateTempUser )
|
2022-02-28 03:05:58 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'TempUserCreator' => static function ( MediaWikiServices $services ): TempUserCreator {
|
|
|
|
|
return new TempUserCreator(
|
|
|
|
|
$services->getTempUserConfig(),
|
|
|
|
|
$services->getObjectFactory(),
|
|
|
|
|
$services->getUserFactory(),
|
|
|
|
|
$services->getAuthManager(),
|
Handle collisions from SerialProvider::acquireIndex
Why:
* When using the TempUserCreator::create or ::acquireAndStashName to
get temporary account when the chosen username already existed, that
temporary account is treated as if it doesn't exist. This causes
confusing "userexists" errors and also causes the user to be logged
into an already existing temporary account.
* Furthermore, because the user existence check in AuthManager::auto
CreateUser only checks the local wiki, if an existing temporary
account exists globally but not on the local wiki then the code
sign a new user into an existing temporary account.
* This is very bad behaviour, though shouldn't happen unless the
serialMapping configuration uses a SerialMapping class that could
provide duplicates and/or the configuration has been changed to
use a different SerialMapping class.
* There is a need to change the SerialMapping class in use to a
different class, which means that the code will attempt to use
temporary account usernames which already exist.
* As such, the code that is generating the temporary account usernames
based on the SerialMapping and SerialProvider should be aware that
it may produce an already existing temporary account username, even
if the SerialMapping class being used is asserted to never provide
duplicates.
* Therefore, the code that generates temporary account usernames
should always attempt to verify that a automatically generated
temporary account name does not already exist on the wiki.
What:
* Update TempUserCreator::acquireName to check to see if the username
it generates already exists centrally using the CentralIdLookup.
If it does, then the method returns null. Otherwise, the username
that hasn't been used yet is returned.
* Create the private method TempUserCreator::attemptAutoCreate that
attempts an autocreate for a temporary account name, and optionally
logs the account in.
* Update TempUserCreator::create to use ::attemptAutoCreate to
first to check if the account can be created and then again once
the account is created to actually login to that temporary account.
This is done to prevent logins to existing temporary accounts on
the local wiki. The second call to actually perform the login is
necessary as there is no other way to login to a temporary account.
* Update TempUserCreator::acquireAndStashName to respond to the changes
to ::acquireName, such that it returns null if ::acquireName returns
null and also does not modify the session.
* Update EditPage::maybeActivateTempUserCreate to return a Status and
return a good status in all cases except when a temporary account
name could not be acquired.
* Add IEditObject::AS_UNABLE_TO_ACQUIRE_TEMP_ACCOUNT, and use it as
the value of the fatal status returned by EditPage
::internalAttemptSave if a temporary account name could not be
acquired. This will cause the display of a useful error to the
user on edit.
* Update ApiEditPage and ApiAcquireTempUserName to die with an error
if a temporary account username was unable to be acquired.
* Provide tests for the untested ApiAcquireTempUserName.php file
including testing the new behaviour.
* Add and update tests for TempUserCreator.php
Bug: T353390
Change-Id: Id3a316ea0eba544d51d4ffcdfb03e35f4b3c54cc
2023-12-13 22:56:29 +00:00
|
|
|
$services->getCentralIdLookup(),
|
2022-02-28 03:05:58 +00:00
|
|
|
// This is supposed to match ThrottlePreAuthenticationProvider
|
|
|
|
|
new Throttler(
|
2024-03-03 19:16:41 +00:00
|
|
|
$services->getMainConfig()->get( MainConfigNames::TempAccountCreationThrottle ),
|
2022-02-28 03:05:58 +00:00
|
|
|
[
|
2024-03-03 19:16:41 +00:00
|
|
|
'type' => 'tempacctcreate',
|
2024-01-18 07:09:09 +00:00
|
|
|
'cache' => ObjectCache::getLocalClusterInstance(),
|
2022-02-28 03:05:58 +00:00
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'Tidy' => static function ( MediaWikiServices $services ): TidyDriverBase {
|
2021-02-18 16:51:12 +00:00
|
|
|
return new RemexDriver(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
RemexDriver::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'TitleFactory' => static function ( MediaWikiServices $services ): TitleFactory {
|
2019-10-17 16:48:39 +00:00
|
|
|
return new TitleFactory();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'TitleFormatter' => static function ( MediaWikiServices $services ): TitleFormatter {
|
2018-08-03 08:05:44 +00:00
|
|
|
return $services->getService( '_MediaWikiTitleCodec' );
|
2017-11-07 03:10:14 +00:00
|
|
|
},
|
|
|
|
|
|
2023-01-26 19:38:20 +00:00
|
|
|
'TitleMatcher' => static function ( MediaWikiServices $services ): TitleMatcher {
|
|
|
|
|
return new TitleMatcher(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
TitleMatcher::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$services->getContentLanguage(),
|
|
|
|
|
$services->getLanguageConverterFactory(),
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getWikiPageFactory(),
|
|
|
|
|
$services->getUserNameUtils(),
|
2023-07-21 00:29:59 +00:00
|
|
|
$services->getRepoGroup(),
|
|
|
|
|
$services->getTitleFactory()
|
2023-01-26 19:38:20 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'TitleParser' => static function ( MediaWikiServices $services ): TitleParser {
|
2018-08-03 08:05:44 +00:00
|
|
|
return $services->getService( '_MediaWikiTitleCodec' );
|
2018-01-16 23:11:08 +00:00
|
|
|
},
|
|
|
|
|
|
2020-10-14 23:04:27 +00:00
|
|
|
'TrackingCategories' => static function ( MediaWikiServices $services ): TrackingCategories {
|
|
|
|
|
return new TrackingCategories(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
TrackingCategories::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$services->getNamespaceInfo(),
|
2021-10-08 16:37:26 +00:00
|
|
|
$services->getTitleParser(),
|
|
|
|
|
LoggerFactory::getInstance( 'TrackingCategories' )
|
2020-10-14 23:04:27 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UnblockUserFactory' => static function ( MediaWikiServices $services ): UnblockUserFactory {
|
2020-04-23 19:33:03 +00:00
|
|
|
return $services->getService( '_UserBlockCommandFactory' );
|
|
|
|
|
},
|
|
|
|
|
|
2021-08-30 20:55:05 +00:00
|
|
|
'UndeletePageFactory' => static function ( MediaWikiServices $services ): UndeletePageFactory {
|
|
|
|
|
return $services->getService( '_PageCommandFactory' );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UploadRevisionImporter' => static function ( MediaWikiServices $services ): UploadRevisionImporter {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new ImportableUploadRevisionImporter(
|
2022-04-01 15:58:32 +00:00
|
|
|
$services->getMainConfig()->get( MainConfigNames::EnableUploads ),
|
2018-08-03 08:05:44 +00:00
|
|
|
LoggerFactory::getInstance( 'UploadRevisionImporter' )
|
2018-01-24 23:41:01 +00:00
|
|
|
);
|
2017-09-12 17:12:29 +00:00
|
|
|
},
|
|
|
|
|
|
2022-04-04 19:41:23 +00:00
|
|
|
'UrlUtils' => static function ( MediaWikiServices $services ): UrlUtils {
|
|
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
return new UrlUtils( [
|
2022-04-25 15:19:41 +00:00
|
|
|
UrlUtils::SERVER => $config->get( MainConfigNames::Server ),
|
|
|
|
|
UrlUtils::CANONICAL_SERVER => $config->get( MainConfigNames::CanonicalServer ),
|
|
|
|
|
UrlUtils::INTERNAL_SERVER => $config->get( MainConfigNames::InternalServer ),
|
2022-04-04 19:41:23 +00:00
|
|
|
UrlUtils::FALLBACK_PROTOCOL => RequestContext::getMain()->getRequest()->getProtocol(),
|
2022-04-25 15:19:41 +00:00
|
|
|
UrlUtils::HTTPS_PORT => $config->get( MainConfigNames::HttpsPort ),
|
|
|
|
|
UrlUtils::VALID_PROTOCOLS => $config->get( MainConfigNames::UrlProtocols ),
|
2022-04-04 19:41:23 +00:00
|
|
|
] );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UserCache' => static function ( MediaWikiServices $services ): UserCache {
|
2020-05-18 20:12:34 +00:00
|
|
|
return new UserCache(
|
|
|
|
|
LoggerFactory::getInstance( 'UserCache' ),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2020-05-18 20:12:34 +00:00
|
|
|
$services->getLinkBatchFactory()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UserEditTracker' => static function ( MediaWikiServices $services ): UserEditTracker {
|
2020-05-26 03:33:28 +00:00
|
|
|
return new UserEditTracker(
|
|
|
|
|
$services->getActorMigration(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2021-03-17 12:37:06 +00:00
|
|
|
$services->getJobQueueGroup()
|
2020-05-26 03:33:28 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UserFactory' => static function ( MediaWikiServices $services ): UserFactory {
|
2020-10-02 02:46:22 +00:00
|
|
|
return new UserFactory(
|
2023-02-20 21:51:41 +00:00
|
|
|
new ServiceOptions(
|
|
|
|
|
UserFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$services->getDBLoadBalancerFactory(),
|
2020-10-02 02:46:22 +00:00
|
|
|
$services->getUserNameUtils()
|
|
|
|
|
);
|
2020-05-23 03:48:21 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UserGroupManager' => static function ( MediaWikiServices $services ): UserGroupManager {
|
2019-10-24 03:14:31 +00:00
|
|
|
return $services->getUserGroupManagerFactory()->getUserGroupManager();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UserGroupManagerFactory' => static function ( MediaWikiServices $services ): UserGroupManagerFactory {
|
2019-10-24 03:14:31 +00:00
|
|
|
return new UserGroupManagerFactory(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
UserGroupManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
|
|
|
|
|
),
|
2023-09-08 11:58:27 +00:00
|
|
|
$services->getReadOnlyMode(),
|
2019-10-24 03:14:31 +00:00
|
|
|
$services->getDBLoadBalancerFactory(),
|
|
|
|
|
$services->getHookContainer(),
|
2020-06-04 16:41:12 +00:00
|
|
|
$services->getUserEditTracker(),
|
2021-01-05 23:08:09 +00:00
|
|
|
$services->getGroupPermissionsLookup(),
|
2021-07-31 06:31:11 +00:00
|
|
|
$services->getJobQueueGroupFactory(),
|
2020-06-04 16:41:12 +00:00
|
|
|
LoggerFactory::getInstance( 'UserGroupManager' ),
|
2022-04-11 01:26:51 +00:00
|
|
|
$services->getTempUserConfig(),
|
2021-02-10 22:31:02 +00:00
|
|
|
[ static function ( UserIdentity $user ) use ( $services ) {
|
2023-08-01 10:26:22 +00:00
|
|
|
if ( $user->getWikiId() === UserIdentity::LOCAL ) {
|
|
|
|
|
$services->getPermissionManager()->invalidateUsersRightsCache( $user );
|
|
|
|
|
}
|
|
|
|
|
$services->getUserFactory()->invalidateCache( $user );
|
2019-10-24 03:14:31 +00:00
|
|
|
} ]
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UserIdentityLookup' => static function ( MediaWikiServices $services ): UserIdentityLookup {
|
2021-02-16 23:47:45 +00:00
|
|
|
return $services->getActorStoreFactory()->getUserIdentityLookup();
|
|
|
|
|
},
|
|
|
|
|
|
2023-07-18 04:00:49 +00:00
|
|
|
'UserIdentityUtils' => static function ( MediaWikiServices $services ): UserIdentityUtils {
|
|
|
|
|
return new UserIdentityUtils(
|
|
|
|
|
$services->getTempUserConfig()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UserNamePrefixSearch' => static function ( MediaWikiServices $services ): UserNamePrefixSearch {
|
2020-10-02 02:21:23 +00:00
|
|
|
return new UserNamePrefixSearch(
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
Support new block schema
Support migration stages when reading and writing blocks.
I tried to set it up for an easy next stage, in which support for the
old schema is removed. I tried to avoid factoring out of shared code
between the two schemas, so that the old schema cases can simply be
deleted without the need to revert unnecessary abstractions.
However, I added HideUserUtils to factor out ipb_deleted queries. Code
review showed that this was already quite complex, with multiple
approaches to the problem, so it benefits from refactoring even without
the schema abstraction.
HideUserUtils is a service rather than a standalone class to support
unit tests, since unit tests do not allow global config access. When
the migration stage config is removed, it will be a service with no
constructor parameters -- an unnecessary abstraction which should
ideally be resolved at that time.
When interpreting result rows, it is possible to share code by using
field aliases. But when constructing WHERE conditions, the actual field
names need to be used, so the migration is more intrusive in
ApiQueryBlocks and SpecialBlockList, where complex conditions are used.
Bug: T346293
Bug: T51504
Bug: T349883
Change-Id: I408acf7a57b0100fe18c455fc13141277a598925
2023-10-27 03:34:10 +00:00
|
|
|
$services->getUserNameUtils(),
|
|
|
|
|
$services->getHideUserUtils()
|
2020-10-02 02:21:23 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UserNameUtils' => static function ( MediaWikiServices $services ): UserNameUtils {
|
2020-03-31 23:29:51 +00:00
|
|
|
$messageFormatterFactory = new MessageFormatterFactory( Message::FORMAT_PLAIN );
|
Add a new UserNameUtils service
This replaces User::isValidUserName, ::isUsableName, ::isCreatableName,
::getCanonicalName, and ::isIP.
Unlike User::isIP, UserNameUtils::isIP will //not// return true
for IPv6 ranges.
UserNameUtils::isIPRange, like User::isIPRange, accepts a name and
simply calls IPUtils::isValidRange.
User::isValidUserName, ::isUsableName, ::isCreatableName,
::getCanonical, ::isIP, and ::isValidRange are all soft deprecated
A follow up patch will add this to the release notes, to avoid merge
conflicts.
Bug: T245231
Bug: T239527
Change-Id: I46684bc492bb74b728ff102971f6cdd4d746a50a
2020-02-23 23:52:44 +00:00
|
|
|
return new UserNameUtils(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
UserNameUtils::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$services->getContentLanguage(),
|
|
|
|
|
LoggerFactory::getInstance( 'UserNameUtils' ),
|
2020-04-05 20:03:29 +00:00
|
|
|
$services->getTitleParser(),
|
2020-03-31 23:29:51 +00:00
|
|
|
$messageFormatterFactory->getTextFormatter(
|
|
|
|
|
$services->getContentLanguage()->getCode()
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
),
|
2022-02-28 03:05:58 +00:00
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getTempUserConfig()
|
Add a new UserNameUtils service
This replaces User::isValidUserName, ::isUsableName, ::isCreatableName,
::getCanonicalName, and ::isIP.
Unlike User::isIP, UserNameUtils::isIP will //not// return true
for IPv6 ranges.
UserNameUtils::isIPRange, like User::isIPRange, accepts a name and
simply calls IPUtils::isValidRange.
User::isValidUserName, ::isUsableName, ::isCreatableName,
::getCanonical, ::isIP, and ::isValidRange are all soft deprecated
A follow up patch will add this to the release notes, to avoid merge
conflicts.
Bug: T245231
Bug: T239527
Change-Id: I46684bc492bb74b728ff102971f6cdd4d746a50a
2020-02-23 23:52:44 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UserOptionsLookup' => static function ( MediaWikiServices $services ): UserOptionsLookup {
|
2020-01-17 06:21:28 +00:00
|
|
|
return $services->getUserOptionsManager();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'UserOptionsManager' => static function ( MediaWikiServices $services ): UserOptionsManager {
|
2020-01-17 06:21:28 +00:00
|
|
|
return new UserOptionsManager(
|
|
|
|
|
new ServiceOptions( UserOptionsManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
2020-05-11 19:19:13 +00:00
|
|
|
$services->get( '_DefaultOptionsLookup' ),
|
2020-01-17 06:21:28 +00:00
|
|
|
$services->getLanguageConverterFactory(),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
LoggerFactory::getInstance( 'UserOptionsManager' ),
|
2021-10-25 19:56:47 +00:00
|
|
|
$services->getHookContainer(),
|
2023-03-21 19:54:07 +00:00
|
|
|
$services->getUserFactory(),
|
|
|
|
|
$services->getUserNameUtils()
|
2020-01-17 06:21:28 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2023-09-14 10:18:56 +00:00
|
|
|
'UserRegistrationLookup' => static function ( MediaWikiServices $services ): UserRegistrationLookup {
|
|
|
|
|
$lookup = new UserRegistrationLookup(
|
|
|
|
|
new ServiceOptions( UserRegistrationLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
|
|
|
|
$services->getObjectFactory()
|
|
|
|
|
);
|
|
|
|
|
if ( !$lookup->isRegistered( LocalUserRegistrationProvider::TYPE ) ) {
|
|
|
|
|
throw new ConfigException( 'UserRegistrationLookup: Local provider is required' );
|
|
|
|
|
}
|
|
|
|
|
return $lookup;
|
|
|
|
|
},
|
|
|
|
|
|
2023-10-12 21:52:47 +00:00
|
|
|
'WatchedItemQueryService' => static function ( MediaWikiServices $services ): WatchedItemQueryService {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new WatchedItemQueryService(
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2018-08-03 08:05:44 +00:00
|
|
|
$services->getCommentStore(),
|
2019-09-13 20:39:50 +00:00
|
|
|
$services->getWatchedItemStore(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getHookContainer(),
|
2022-04-22 12:46:10 +00:00
|
|
|
$services->getUserOptionsLookup(),
|
2024-03-01 19:47:04 +00:00
|
|
|
$services->getTempUserConfig(),
|
2022-04-01 15:58:32 +00:00
|
|
|
$services->getMainConfig()->get( MainConfigNames::WatchlistExpiry ),
|
|
|
|
|
$services->getMainConfig()->get( MainConfigNames::MaxExecutionTimeForExpensiveQueries )
|
2017-09-12 17:12:29 +00:00
|
|
|
);
|
|
|
|
|
},
|
2018-01-24 23:41:01 +00:00
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'WatchedItemStore' => static function ( MediaWikiServices $services ): WatchedItemStore {
|
2018-08-03 08:05:44 +00:00
|
|
|
$store = new WatchedItemStore(
|
2020-04-20 22:22:27 +00:00
|
|
|
new ServiceOptions( WatchedItemStore::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig() ),
|
2018-10-11 19:11:43 +00:00
|
|
|
$services->getDBLoadBalancerFactory(),
|
2021-03-17 12:37:06 +00:00
|
|
|
$services->getJobQueueGroup(),
|
2018-03-03 00:21:36 +00:00
|
|
|
$services->getMainObjectStash(),
|
2018-08-03 08:05:44 +00:00
|
|
|
new HashBagOStuff( [ 'maxKeys' => 100 ] ),
|
|
|
|
|
$services->getReadOnlyMode(),
|
2019-04-29 17:25:13 +00:00
|
|
|
$services->getNamespaceInfo(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getRevisionLookup(),
|
2021-09-21 23:22:19 +00:00
|
|
|
$services->getLinkBatchFactory()
|
2018-08-03 08:05:44 +00:00
|
|
|
);
|
|
|
|
|
$store->setStatsdDataFactory( $services->getStatsdDataFactory() );
|
|
|
|
|
|
2022-04-01 15:58:32 +00:00
|
|
|
if ( $services->getMainConfig()->get( MainConfigNames::ReadOnlyWatchedItemStore ) ) {
|
2018-08-03 08:05:44 +00:00
|
|
|
$store = new NoWriteWatchedItemStore( $store );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $store;
|
2018-07-24 16:44:09 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'WatchlistManager' => static function ( MediaWikiServices $services ): WatchlistManager {
|
2021-03-26 22:24:43 +00:00
|
|
|
return new WatchlistManager(
|
2022-08-21 15:07:07 +00:00
|
|
|
[
|
|
|
|
|
WatchlistManager::OPTION_ENOTIF =>
|
|
|
|
|
RecentChange::isEnotifEnabled( $services->getMainConfig() ),
|
|
|
|
|
],
|
2020-05-23 08:43:34 +00:00
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getReadOnlyMode(),
|
|
|
|
|
$services->getRevisionLookup(),
|
|
|
|
|
$services->getTalkPageNotificationManager(),
|
2021-03-26 22:24:43 +00:00
|
|
|
$services->getWatchedItemStore(),
|
2021-04-08 19:34:40 +00:00
|
|
|
$services->getUserFactory(),
|
2021-04-13 03:28:23 +00:00
|
|
|
$services->getNamespaceInfo(),
|
|
|
|
|
$services->getWikiPageFactory()
|
2020-05-23 08:43:34 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-21 23:49:49 +00:00
|
|
|
'WikiExporterFactory' => static function ( MediaWikiServices $services ): WikiExporterFactory {
|
|
|
|
|
return new WikiExporterFactory(
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getRevisionStore(),
|
2022-07-06 19:21:04 +00:00
|
|
|
$services->getTitleParser(),
|
|
|
|
|
$services->getCommentStore()
|
2021-07-21 23:49:49 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'WikiImporterFactory' => static function ( MediaWikiServices $services ): WikiImporterFactory {
|
2021-05-14 23:16:34 +00:00
|
|
|
return new WikiImporterFactory(
|
|
|
|
|
$services->getMainConfig(),
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getContentLanguage(),
|
|
|
|
|
$services->getNamespaceInfo(),
|
|
|
|
|
$services->getTitleFactory(),
|
|
|
|
|
$services->getWikiPageFactory(),
|
|
|
|
|
$services->getWikiRevisionUploadImporter(),
|
|
|
|
|
$services->getContentHandlerFactory(),
|
|
|
|
|
$services->getSlotRoleRegistry()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'WikiPageFactory' => static function ( MediaWikiServices $services ): WikiPageFactory {
|
2020-07-27 13:24:05 +00:00
|
|
|
return new WikiPageFactory(
|
|
|
|
|
$services->getTitleFactory(),
|
|
|
|
|
new HookRunner( $services->getHookContainer() ),
|
2024-01-15 21:26:35 +00:00
|
|
|
$services->getDBLoadBalancerFactory()
|
2020-07-27 13:24:05 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2023-10-12 21:52:47 +00:00
|
|
|
'WikiRevisionOldRevisionImporterNoUpdates' => static function (
|
|
|
|
|
MediaWikiServices $services
|
|
|
|
|
): ImportableOldRevisionImporter {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new ImportableOldRevisionImporter(
|
|
|
|
|
false,
|
|
|
|
|
LoggerFactory::getInstance( 'OldRevisionImporter' ),
|
2024-01-13 07:50:18 +00:00
|
|
|
$services->getConnectionProvider(),
|
2023-11-29 20:43:12 +00:00
|
|
|
$services->getRevisionStoreFactory()->getRevisionStoreForImport(),
|
2020-11-11 22:08:46 +00:00
|
|
|
$services->getSlotRoleRegistry(),
|
2021-10-06 22:07:55 +00:00
|
|
|
$services->getWikiPageFactory(),
|
2021-12-19 13:31:03 +00:00
|
|
|
$services->getPageUpdaterFactory(),
|
|
|
|
|
$services->getUserFactory()
|
2018-08-03 08:05:44 +00:00
|
|
|
);
|
2022-06-22 11:18:50 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'WRStatsFactory' => static function ( MediaWikiServices $services ): WRStatsFactory {
|
|
|
|
|
return new WRStatsFactory(
|
2023-11-07 13:53:52 +00:00
|
|
|
new BagOStuffStatsStore( $services->getMicroStash() )
|
2022-06-22 11:18:50 +00:00
|
|
|
);
|
2018-07-25 14:37:16 +00:00
|
|
|
},
|
|
|
|
|
|
2023-11-29 11:17:49 +00:00
|
|
|
'_ConditionalDefaultsLookup' => static function (
|
|
|
|
|
MediaWikiServices $services
|
|
|
|
|
): ConditionalDefaultsLookup {
|
|
|
|
|
return new ConditionalDefaultsLookup(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
ConditionalDefaultsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$services->getUserRegistrationLookup()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'_DefaultOptionsLookup' => static function ( MediaWikiServices $services ): DefaultOptionsLookup {
|
2020-05-11 19:19:13 +00:00
|
|
|
return new DefaultOptionsLookup(
|
|
|
|
|
new ServiceOptions( DefaultOptionsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getContentLanguage(),
|
2021-09-29 09:03:32 +00:00
|
|
|
$services->getHookContainer(),
|
2023-08-06 00:36:52 +00:00
|
|
|
$services->getNamespaceInfo(),
|
2023-08-12 00:15:02 +00:00
|
|
|
$services->get( '_ConditionalDefaultsLookup' )
|
2020-01-17 06:21:28 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'_EditConstraintFactory' => static function ( MediaWikiServices $services ): EditConstraintFactory {
|
2020-10-21 01:05:00 +00:00
|
|
|
// This service is internal and currently only exists because a significant number
|
|
|
|
|
// of dependencies will be needed by different constraints. It is not part of
|
|
|
|
|
// the public interface and has no corresponding method in MediaWikiServices
|
|
|
|
|
return new EditConstraintFactory(
|
2020-10-23 03:17:31 +00:00
|
|
|
// Multiple
|
2020-10-27 18:36:46 +00:00
|
|
|
new ServiceOptions(
|
|
|
|
|
EditConstraintFactory::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
LoggerFactory::getProvider(),
|
2021-03-22 23:04:32 +00:00
|
|
|
|
|
|
|
|
// UserBlockConstraint
|
2020-10-23 03:17:31 +00:00
|
|
|
$services->getPermissionManager(),
|
|
|
|
|
|
2020-11-07 02:10:43 +00:00
|
|
|
// EditFilterMergedContentHookConstraint
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
|
2020-10-23 03:17:31 +00:00
|
|
|
// ReadOnlyConstraint
|
|
|
|
|
$services->getReadOnlyMode(),
|
|
|
|
|
|
2020-10-21 16:26:32 +00:00
|
|
|
// SpamRegexConstraint
|
2023-10-27 17:34:38 +00:00
|
|
|
$services->getSpamChecker(),
|
|
|
|
|
|
|
|
|
|
// UserRateLimitConstraint
|
|
|
|
|
$services->getRateLimiter()
|
2020-10-21 01:05:00 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2023-02-14 21:18:33 +00:00
|
|
|
'_LocalClusterCache' => static function ( MediaWikiServices $services ): BagOStuff {
|
|
|
|
|
$mainConfig = $services->getMainConfig();
|
|
|
|
|
$id = $mainConfig->get( MainConfigNames::MainCacheType );
|
2023-09-07 15:12:17 +00:00
|
|
|
return $services->getObjectCacheFactory()->getInstance( $id );
|
2023-02-14 21:18:33 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'_MediaWikiTitleCodec' => static function ( MediaWikiServices $services ): MediaWikiTitleCodec {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new MediaWikiTitleCodec(
|
|
|
|
|
$services->getContentLanguage(),
|
|
|
|
|
$services->getGenderCache(),
|
2022-04-01 15:58:32 +00:00
|
|
|
$services->getMainConfig()->get( MainConfigNames::LocalInterwikis ),
|
2018-08-05 13:00:56 +00:00
|
|
|
$services->getInterwikiLookup(),
|
|
|
|
|
$services->getNamespaceInfo()
|
2016-10-02 07:41:55 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'_PageCommandFactory' => static function ( MediaWikiServices $services ): PageCommandFactory {
|
2020-04-28 22:54:18 +00:00
|
|
|
return new PageCommandFactory(
|
2021-03-26 22:56:39 +00:00
|
|
|
$services->getMainConfig(),
|
2021-08-20 19:56:10 +00:00
|
|
|
$services->getDBLoadBalancerFactory(),
|
2020-04-17 01:30:38 +00:00
|
|
|
$services->getNamespaceInfo(),
|
|
|
|
|
$services->getWatchedItemStore(),
|
|
|
|
|
$services->getRepoGroup(),
|
2021-03-26 22:56:39 +00:00
|
|
|
$services->getReadOnlyMode(),
|
2020-04-17 01:30:38 +00:00
|
|
|
$services->getContentHandlerFactory(),
|
2020-05-13 21:30:46 +00:00
|
|
|
$services->getRevisionStore(),
|
Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-03-19 02:42:09 +00:00
|
|
|
$services->getSpamChecker(),
|
2021-03-26 22:56:39 +00:00
|
|
|
$services->getTitleFormatter(),
|
2020-11-11 21:10:47 +00:00
|
|
|
$services->getHookContainer(),
|
2021-03-02 01:28:23 +00:00
|
|
|
$services->getWikiPageFactory(),
|
2021-03-26 22:56:39 +00:00
|
|
|
$services->getUserFactory(),
|
2021-04-19 00:57:23 +00:00
|
|
|
$services->getActorMigration(),
|
2021-05-14 00:52:32 +00:00
|
|
|
$services->getActorNormalization(),
|
2021-04-24 04:54:48 +00:00
|
|
|
$services->getTitleFactory(),
|
2021-08-24 19:12:39 +00:00
|
|
|
$services->getUserEditTracker(),
|
2021-08-20 19:56:10 +00:00
|
|
|
$services->getCollationFactory(),
|
|
|
|
|
$services->getJobQueueGroup(),
|
|
|
|
|
$services->getCommentStore(),
|
2022-01-11 09:58:31 +00:00
|
|
|
$services->getMainObjectStash(),
|
2021-08-20 19:56:10 +00:00
|
|
|
WikiMap::getCurrentWikiDbDomain()->getId(),
|
2021-09-08 22:07:01 +00:00
|
|
|
WebRequest::getRequestId(),
|
2021-08-30 20:55:05 +00:00
|
|
|
$services->getBacklinkCacheFactory(),
|
2021-10-06 22:07:55 +00:00
|
|
|
LoggerFactory::getInstance( 'UndeletePage' ),
|
DeletePage: add option to delete the associated talk page
Currently this is implemented internally as a second method call. In the
future, it might be possible to optimize the implementation, e.g. to
reduce the amount of DB queries/jobs etc. without changing anything for
callers.
Since the implementation of e.g. the result getters is generic, a future
commit may add an option to delete subpages with relatively low effort.
The revision limit for big deletions is now using the total number of
revisions (base page + talk page). This is because both deletions would
happen in the same main transaction, and we presumably want to optimize
the deletion as a whole, not as two separated steps. This would become
even more important if the aforementioned improvements are ever
implemented. Note, the whole concept of "big deletion" might have been
superseded by batched deletions in the author's opinion, but as long as
such a limit exists, it should serve its purpose.
The current interpretation of the associated talk option is that the
request is validated, and an exception is raised if we cannot delete the
associated talk, as opposed to silently ignoring the parameter if the
talk cannot be deleted. The only exception to this is that it will not
fail hard if the talk page turns out not to exist by the time the
deletion is attempted, as that's hard to foresee due to race conditions.
Note that the summary for the talk deletion is prefixed with the
delete-talk-summary-prefix message. The main reason behind this is that
the delete UI can sometimes offer an auto-generated summary like "the
only contributor was XXX" or "the content was YYY", and since this may
not apply to the talk page as well, the log entry might look confusing.
Bug: T263209
Bug: T27471
Change-Id: Ife1f4e8258a69528dd1ce8fef8ae809761aa6f1d
2021-09-01 12:56:43 +00:00
|
|
|
$services->getPageUpdaterFactory(),
|
|
|
|
|
$services->getMessageFormatterFactory()->getTextFormatter(
|
|
|
|
|
$services->getContentLanguage()->getCode()
|
2021-11-08 14:40:46 +00:00
|
|
|
),
|
2022-04-14 17:12:27 +00:00
|
|
|
$services->getArchivedRevisionLookup(),
|
2023-10-17 21:12:37 +00:00
|
|
|
$services->getRestrictionStore(),
|
|
|
|
|
$services->getLinkTargetLookup()
|
2020-04-17 01:30:38 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-09-21 15:58:05 +00:00
|
|
|
'_ParserObserver' => static function ( MediaWikiServices $services ): ParserObserver {
|
|
|
|
|
return new ParserObserver( LoggerFactory::getInstance( 'DuplicateParse' ) );
|
|
|
|
|
},
|
|
|
|
|
|
2022-08-26 10:27:53 +00:00
|
|
|
'_Parsoid' => static function ( MediaWikiServices $services ): Parsoid {
|
|
|
|
|
return new Parsoid(
|
|
|
|
|
$services->getParsoidSiteConfig(),
|
|
|
|
|
$services->getParsoidDataAccess()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2022-11-06 20:35:07 +00:00
|
|
|
'_SettingsBuilder' => static function ( MediaWikiServices $services ): SettingsBuilder {
|
|
|
|
|
return SettingsBuilder::getInstance();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'_SqlBlobStore' => static function ( MediaWikiServices $services ): SqlBlobStore {
|
2018-08-03 08:05:44 +00:00
|
|
|
return $services->getBlobStoreFactory()->newSqlBlobStore();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'_UserBlockCommandFactory' => static function ( MediaWikiServices $services ): UserBlockCommandFactory {
|
2020-04-23 19:33:03 +00:00
|
|
|
return new UserBlockCommandFactory(
|
2020-04-23 19:33:56 +00:00
|
|
|
new ServiceOptions( UserBlockCommandFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
|
|
|
|
$services->getHookContainer(),
|
2020-04-23 19:33:03 +00:00
|
|
|
$services->getBlockPermissionCheckerFactory(),
|
2020-10-04 21:20:06 +00:00
|
|
|
$services->getBlockUtils(),
|
2020-08-27 09:27:10 +00:00
|
|
|
$services->getDatabaseBlockStore(),
|
2020-04-23 19:33:56 +00:00
|
|
|
$services->getBlockRestrictionStore(),
|
2021-03-16 01:37:57 +00:00
|
|
|
$services->getUserFactory(),
|
2021-03-23 00:48:56 +00:00
|
|
|
$services->getUserEditTracker(),
|
2021-04-01 08:53:15 +00:00
|
|
|
LoggerFactory::getInstance( 'BlockManager' ),
|
2021-05-03 04:10:20 +00:00
|
|
|
$services->getTitleFactory(),
|
|
|
|
|
$services->getBlockActionInfo()
|
2020-04-23 19:33:03 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2015-10-12 08:05:45 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// NOTE: When adding a service here, don't forget to add a getter function
|
|
|
|
|
// in the MediaWikiServices class. The convenience getter should just call
|
|
|
|
|
// $this->getService( 'FooBarService' ).
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
];
|