2015-10-12 08:05:45 +00:00
|
|
|
<?php
|
|
|
|
|
/**
|
|
|
|
|
* Default wiring for MediaWiki services.
|
|
|
|
|
*
|
|
|
|
|
* 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
|
|
|
|
|
*
|
|
|
|
|
* This file is loaded by MediaWiki\MediaWikiServices::getInstance() during the
|
|
|
|
|
* bootstrapping of the dependency injection framework.
|
|
|
|
|
*
|
|
|
|
|
* This file returns an array that associates service name with instantiator functions
|
|
|
|
|
* that create the default instances for the services used by MediaWiki core.
|
|
|
|
|
* For every service that MediaWiki core requires, an instantiator must be defined in
|
|
|
|
|
* this file.
|
|
|
|
|
*
|
2019-08-27 16:49:36 +00:00
|
|
|
* Note that, ideally, all information used to instantiate service objects should come
|
|
|
|
|
* from configuration. Information derived from the current request is acceptable, but
|
|
|
|
|
* only where there is no feasible alternative. It is preferred that such information
|
|
|
|
|
* (like the client IP, the acting user's identity, requested title, etc) be passed to
|
|
|
|
|
* the service object's methods as parameters. This makes the flow of information more
|
|
|
|
|
* obvious, and makes it easier to understand the behavior of services.
|
|
|
|
|
*
|
2015-10-12 08:05:45 +00:00
|
|
|
* @note As of version 1.27, MediaWiki is only beginning to use dependency injection.
|
|
|
|
|
* The services defined here do not yet fully represent all services used by core,
|
|
|
|
|
* much of the code still relies on global state for this accessing services.
|
|
|
|
|
*
|
|
|
|
|
* @since 1.27
|
|
|
|
|
*
|
2019-12-14 04:13:17 +00:00
|
|
|
* @see docs/Injection.md for an overview of using dependency injection in the
|
2015-10-12 08:05:45 +00:00
|
|
|
* MediaWiki code base.
|
|
|
|
|
*/
|
|
|
|
|
|
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;
|
2019-08-18 18:19:05 +00:00
|
|
|
use MediaWiki\BadFileLookup;
|
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;
|
2020-05-08 06:29:23 +00:00
|
|
|
use MediaWiki\Block\DatabaseBlockStore;
|
2020-04-23 19:33:03 +00:00
|
|
|
use MediaWiki\Block\UnblockUserFactory;
|
|
|
|
|
use MediaWiki\Block\UserBlockCommandFactory;
|
2021-09-08 17:19:11 +00:00
|
|
|
use MediaWiki\Cache\BacklinkCacheFactory;
|
2019-10-19 11:08:40 +00:00
|
|
|
use MediaWiki\Cache\LinkBatchFactory;
|
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;
|
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;
|
2021-09-28 17:21:37 +00:00
|
|
|
use MediaWiki\DAO\WikiAwareEntity;
|
2020-10-21 01:05:00 +00:00
|
|
|
use MediaWiki\EditPage\Constraint\EditConstraintFactory;
|
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;
|
2020-04-17 06:03:29 +00:00
|
|
|
use MediaWiki\HookContainer\DeprecatedHooks;
|
2020-05-11 08:58:38 +00:00
|
|
|
use MediaWiki\HookContainer\GlobalHookRegistry;
|
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;
|
2019-04-22 08:21:50 +00:00
|
|
|
use MediaWiki\Http\HttpRequestFactory;
|
2015-10-30 22:04:52 +00:00
|
|
|
use MediaWiki\Interwiki\ClassicInterwikiLookup;
|
2018-08-07 16:33:20 +00:00
|
|
|
use MediaWiki\Interwiki\InterwikiLookup;
|
2021-03-17 12:37:06 +00:00
|
|
|
use MediaWiki\JobQueue\JobQueueGroupFactory;
|
2020-11-18 00:26:53 +00:00
|
|
|
use MediaWiki\Json\JsonCodec;
|
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;
|
2016-10-02 07:04:17 +00:00
|
|
|
use MediaWiki\Logger\LoggerFactory;
|
2020-03-09 11:00:28 +00:00
|
|
|
use MediaWiki\Mail\Emailer;
|
|
|
|
|
use MediaWiki\Mail\IEmailer;
|
2015-10-12 08:05:45 +00:00
|
|
|
use MediaWiki\MediaWikiServices;
|
2019-07-15 10:24:38 +00:00
|
|
|
use MediaWiki\Message\MessageFormatterFactory;
|
2020-05-30 19:10:58 +00:00
|
|
|
use MediaWiki\Page\ContentModelChangeFactory;
|
2021-08-20 19:56:10 +00:00
|
|
|
use MediaWiki\Page\DeletePageFactory;
|
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;
|
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;
|
2020-09-25 20:02:03 +00:00
|
|
|
use MediaWiki\Parser\ParserCacheFactory;
|
2021-09-21 15:58:05 +00:00
|
|
|
use MediaWiki\Parser\ParserObserver;
|
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;
|
2021-07-26 13:24:22 +00:00
|
|
|
use MediaWiki\Permissions\RestrictionStore;
|
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;
|
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;
|
2020-01-10 00:00:51 +00:00
|
|
|
use MediaWiki\Revision\SlotRoleRegistry;
|
2017-10-07 02:26:52 +00:00
|
|
|
use MediaWiki\Shell\CommandFactory;
|
2020-09-11 03:21:24 +00:00
|
|
|
use MediaWiki\Shell\ShellboxClientFactory;
|
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;
|
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;
|
2021-06-22 19:28:29 +00:00
|
|
|
use MediaWiki\User\CentralId\CentralIdLookupFactory;
|
2020-05-11 19:19:13 +00:00
|
|
|
use MediaWiki\User\DefaultOptionsLookup;
|
2020-04-04 03:39:01 +00:00
|
|
|
use MediaWiki\User\TalkPageNotificationManager;
|
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;
|
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;
|
2020-01-17 06:21:28 +00:00
|
|
|
use MediaWiki\User\UserOptionsLookup;
|
|
|
|
|
use MediaWiki\User\UserOptionsManager;
|
2021-03-26 22:24:43 +00:00
|
|
|
use MediaWiki\Watchlist\WatchlistManager;
|
2019-06-29 04:50:31 +00:00
|
|
|
use Wikimedia\DependencyStore\KeyValueDependencyStore;
|
|
|
|
|
use Wikimedia\DependencyStore\SqlModuleDependencyStore;
|
2020-01-10 00:00:51 +00:00
|
|
|
use Wikimedia\Message\IMessageFormatterFactory;
|
2021-09-16 18:09:17 +00:00
|
|
|
use Wikimedia\Metrics\MetricsFactory;
|
2019-08-21 16:10:30 +00:00
|
|
|
use Wikimedia\ObjectFactory;
|
2021-01-06 05:23:15 +00:00
|
|
|
use Wikimedia\RequestTimeout\CriticalSectionProvider;
|
|
|
|
|
use Wikimedia\RequestTimeout\RequestTimeout;
|
2019-11-04 22:02:33 +00:00
|
|
|
use Wikimedia\Services\RecursiveServiceDependencyException;
|
2019-05-31 23:24:56 +00:00
|
|
|
use Wikimedia\UUID\GlobalIdGenerator;
|
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(
|
|
|
|
|
$services->getMainConfig()->get( 'Actions' ),
|
|
|
|
|
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-05-03 05:13:41 +00:00
|
|
|
$services->getMainConfig()->get( 'ActorTableSchemaMigrationStage' ),
|
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(),
|
|
|
|
|
LoggerFactory::getInstance( 'ActorStore' )
|
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(
|
|
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
$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;
|
|
|
|
|
},
|
|
|
|
|
|
2021-09-08 17:19:11 +00:00
|
|
|
'BacklinkCacheFactory' => static function ( MediaWikiServices $services ): BacklinkCacheFactory {
|
|
|
|
|
return new BacklinkCacheFactory( $services->getMainWANObjectCache() );
|
|
|
|
|
},
|
|
|
|
|
|
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 {
|
2020-10-12 20:41:01 +00:00
|
|
|
return new BlockErrorFormatter(
|
2021-07-23 07:39:35 +00:00
|
|
|
$services->getTitleFormatter()
|
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-01-12 04:48:49 +00:00
|
|
|
$services->getPermissionManager(),
|
2021-05-26 20:14:10 +00:00
|
|
|
$services->getUserFactory(),
|
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' ),
|
2021-01-08 21:21:38 +00:00
|
|
|
$services->getHookContainer()
|
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(
|
|
|
|
|
$services->getDBLoadBalancerFactory()
|
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 {
|
2020-09-18 19:01:34 +00:00
|
|
|
return new BlockUtils(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
BlockUtils::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
2020-10-06 21:27:06 +00:00
|
|
|
),
|
2021-07-15 21:57:52 +00:00
|
|
|
$services->getUserIdentityLookup(),
|
|
|
|
|
$services->getUserNameUtils()
|
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(),
|
|
|
|
|
$services->getUserIdentityLookup()
|
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();
|
|
|
|
|
},
|
|
|
|
|
|
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 {
|
2021-10-05 14:36:00 +00:00
|
|
|
$linkRenderer = $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
|
|
|
$parserFactory = new CommentParserFactory(
|
2021-10-05 14:36:00 +00:00
|
|
|
$linkRenderer,
|
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()
|
|
|
|
|
);
|
|
|
|
|
return new CommentFormatter( $parserFactory );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'CommentStore' => static function ( MediaWikiServices $services ): CommentStore {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new CommentStore(
|
|
|
|
|
$services->getContentLanguage(),
|
2019-01-04 18:55:11 +00:00
|
|
|
MIGRATION_NEW
|
2018-08-03 08:05:44 +00:00
|
|
|
);
|
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.
|
|
|
|
|
$registry = $services->getBootstrapConfig()->get( 'ConfigRegistry' );
|
|
|
|
|
$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() );
|
|
|
|
|
},
|
|
|
|
|
|
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(
|
|
|
|
|
$config->get( 'ReadOnly' ),
|
|
|
|
|
$config->get( 'ReadOnlyFile' )
|
|
|
|
|
);
|
2015-10-12 08:05:45 +00:00
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ContentHandlerFactory' => static function ( MediaWikiServices $services ): IContentHandlerFactory {
|
2020-01-18 20:25:04 +00:00
|
|
|
$contentHandlerConfig = $services->getMainConfig()->get( 'ContentHandlers' );
|
|
|
|
|
|
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(
|
|
|
|
|
$services->getMainConfig()->get( '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 {
|
|
|
|
|
return new ContentRenderer( $services->getContentHandlerFactory() );
|
|
|
|
|
},
|
|
|
|
|
|
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(),
|
|
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
$services->getActorMigration(),
|
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();
|
|
|
|
|
$limit = $config->get( 'CommandLineMode' ) ? INF : $config->get( 'CriticalSectionTimeLimit' );
|
|
|
|
|
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
|
|
|
|
|
|
|
|
$secret = $config->get( 'HKDFSecret' ) ?: $config->get( 'SecretKey' );
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new CryptHKDF( $secret, $config->get( 'HKDFAlgorithm' ), $cache, $context );
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'DatabaseBlockStore' => static function ( MediaWikiServices $services ): DatabaseBlockStore {
|
2020-05-08 06:29:23 +00:00
|
|
|
return new DatabaseBlockStore(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
DatabaseBlockStore::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
LoggerFactory::getInstance( 'DatabaseBlockStore' ),
|
2021-05-05 21:34:14 +00:00
|
|
|
$services->getActorStoreFactory(),
|
2020-05-08 06:29:23 +00:00
|
|
|
$services->getBlockRestrictionStore(),
|
|
|
|
|
$services->getCommentStore(),
|
|
|
|
|
$services->getHookContainer(),
|
|
|
|
|
$services->getDBLoadBalancer(),
|
2021-06-03 10:25:17 +00:00
|
|
|
$services->getReadOnlyMode(),
|
|
|
|
|
$services->getUserFactory()
|
2020-05-08 06:29:23 +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();
|
|
|
|
|
},
|
|
|
|
|
|
2018-08-07 16:33:20 +00:00
|
|
|
'DBLoadBalancerFactory' =>
|
2021-07-22 03:11:47 +00:00
|
|
|
static function ( MediaWikiServices $services ): Wikimedia\Rdbms\LBFactory {
|
2018-08-03 08:05:44 +00:00
|
|
|
$mainConfig = $services->getMainConfig();
|
|
|
|
|
|
2021-02-05 04:18:47 +00:00
|
|
|
$cpStashType = $mainConfig->get( 'ChronologyProtectorStash' );
|
|
|
|
|
if ( is_string( $cpStashType ) ) {
|
|
|
|
|
$cpStash = ObjectCache::getInstance( $cpStashType );
|
|
|
|
|
} else {
|
|
|
|
|
try {
|
|
|
|
|
$cpStash = ObjectCache::getLocalClusterInstance();
|
|
|
|
|
} catch ( RecursiveServiceDependencyException $e ) {
|
|
|
|
|
$cpStash = new EmptyBagOStuff(); // T141804: handle cases like CACHE_DB
|
|
|
|
|
}
|
2019-11-04 22:02:33 +00:00
|
|
|
}
|
2021-03-02 20:53:27 +00:00
|
|
|
LoggerFactory::getInstance( 'DBReplication' )->debug(
|
|
|
|
|
'ChronologyProtector using store {class}',
|
|
|
|
|
[ 'class' => get_class( $cpStash ) ]
|
|
|
|
|
);
|
2019-11-04 22:02:33 +00:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$wanCache = $services->getMainWANObjectCache();
|
|
|
|
|
} catch ( RecursiveServiceDependencyException $e ) {
|
|
|
|
|
$wanCache = WANObjectCache::newEmpty(); // T141804: handle cases like CACHE_DB
|
|
|
|
|
}
|
|
|
|
|
|
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 ] );
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-03 08:05:44 +00:00
|
|
|
$lbConf = MWLBFactory::applyDefaultConfig(
|
|
|
|
|
$mainConfig->get( 'LBFactoryConf' ),
|
2019-10-08 18:33:31 +00:00
|
|
|
new ServiceOptions( MWLBFactory::APPLY_DEFAULT_CONFIG_OPTIONS, $mainConfig ),
|
2019-03-22 07:17:36 +00:00
|
|
|
$services->getConfiguredReadOnlyMode(),
|
2021-02-05 04:18:47 +00:00
|
|
|
$cpStash,
|
2020-09-15 16:10:57 +00:00
|
|
|
$srvCache,
|
2020-12-01 05:08:32 +00:00
|
|
|
$wanCache,
|
|
|
|
|
$services->getCriticalSectionProvider()
|
2018-07-02 17:01:45 +00:00
|
|
|
);
|
2019-07-03 22:02:41 +00:00
|
|
|
|
2018-08-03 08:05:44 +00:00
|
|
|
$class = MWLBFactory::getLBFactoryClass( $lbConf );
|
2019-07-03 22:02:41 +00:00
|
|
|
$instance = new $class( $lbConf );
|
|
|
|
|
|
|
|
|
|
MWLBFactory::setDomainAliases( $instance );
|
2018-08-03 08:05:44 +00:00
|
|
|
|
2021-04-15 22:48:58 +00:00
|
|
|
// NOTE: This accesses ProxyLookup from the MediaWikiServices singleton
|
|
|
|
|
// for non-essential non-nonimal purposes (via WebRequest::getIP).
|
|
|
|
|
// 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.
|
rdbms: Move setLBFactoryTriggers from doMaintenance to service wiring
This logic is not needed to run on every PHP process and was making
it difficult to run offline maintenance scripts without additional
complexity based on Maintenance::getDbType and DB_NONE.
Instead of skipping this only for DB_NONE, and establishing a pattern
that may spread to other ad-hoc places throughout the codebase, instead
remove this entirely from the eager set up code for all PHP processes
and move it to the service wiring and dependency injection.
That way, it naturally doesn't happen until and unless the DB service
is actually called upon. Scripts and entry point that need to disable
the DB service, can continue to use
MediaWikiServices::disableStorageBackend.
== Impact on SiteStatsUpdate ==
With wgCommandLineMode no longer being read at run-time from a global,
but in service wiring, this means SiteStatsUpdateTest can't change
the behaviour between CLI-like and Web-like, unless it e.g. resets
the 'DBLoadBalancerFactory' service first. Unfortunately, while most
any reset is supported, a reset of the 'DBLoadBalancerFactory' would
be unsupported as that would lose the temporary db clone context and
such, bringing us to either the developer's live db, or a broken set
up altogether. If there is a strong need for toggling oppertunistic
updates off and on at run-time, this could be supported in the
DeferredUpdates class perhaps, but we already have numerous methods
there (incl db begin/commit being a good proxy already), which this
test already used, so for now I've just removed the extra assertion
for this as it wasn't essential to that test.
Bug: T228895
Bug: T238436
Change-Id: Icf29bc484c155f52b6d8f61e5902233a15ba0c6d
2021-04-15 23:08:44 +00:00
|
|
|
MWLBFactory::applyGlobalState(
|
|
|
|
|
$instance,
|
|
|
|
|
$mainConfig,
|
|
|
|
|
$services->getStatsdDataFactory()
|
|
|
|
|
);
|
2021-04-15 22:48:58 +00:00
|
|
|
|
2019-07-03 22:02:41 +00:00
|
|
|
return $instance;
|
2018-07-02 17:01:45 +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();
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'EventRelayerGroup' => static function ( MediaWikiServices $services ): EventRelayerGroup {
|
2016-04-23 00:09:14 +00:00
|
|
|
return new EventRelayerGroup( $services->getMainConfig()->get( 'EventRelayerConfig' ) );
|
|
|
|
|
},
|
|
|
|
|
|
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();
|
2018-02-27 06:24:46 +00:00
|
|
|
$writeStores = $config->get( 'DefaultExternalStore' );
|
2016-04-03 08:37:11 +00:00
|
|
|
|
2018-08-03 08:05:44 +00:00
|
|
|
return new ExternalStoreFactory(
|
2018-02-27 06:24:46 +00:00
|
|
|
$config->get( 'ExternalStores' ),
|
|
|
|
|
( $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 ] ),
|
|
|
|
|
$services->getConfiguredReadOnlyMode(),
|
|
|
|
|
$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
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
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
|
|
|
|
|
: $services->getDBLoadBalancer();
|
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(
|
|
|
|
|
$mainConfig->get( '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() )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'HookContainer' => static function ( MediaWikiServices $services ): HookContainer {
|
2020-02-10 14:47:46 +00:00
|
|
|
$extRegistry = ExtensionRegistry::getInstance();
|
|
|
|
|
$extDeprecatedHooks = $extRegistry->getAttribute( 'DeprecatedHooks' );
|
|
|
|
|
$deprecatedHooks = new DeprecatedHooks( $extDeprecatedHooks );
|
2020-05-11 08:58:38 +00:00
|
|
|
$hookRegistry = new GlobalHookRegistry( $extRegistry, $deprecatedHooks );
|
2020-02-10 14:47:46 +00:00
|
|
|
return new HookContainer(
|
2020-05-11 08:58:38 +00:00
|
|
|
$hookRegistry,
|
|
|
|
|
$services->getObjectFactory()
|
2020-02-10 14:47:46 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'HtmlCacheUpdater' => static function ( MediaWikiServices $services ): HtmlCacheUpdater {
|
2019-03-15 00:23:26 +00:00
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
|
|
|
|
|
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(),
|
2019-03-15 00:23:26 +00:00
|
|
|
$config->get( 'CdnReboundPurgeDelay' ),
|
2020-05-21 09:40:16 +00:00
|
|
|
$config->get( 'UseFileCache' ),
|
|
|
|
|
$config->get( 'CdnMaxAge' )
|
2019-03-15 00:23:26 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2018-08-07 16:33:20 +00:00
|
|
|
'HttpRequestFactory' =>
|
2021-07-22 03:11:47 +00:00
|
|
|
static function ( MediaWikiServices $services ): HttpRequestFactory {
|
2020-05-15 05:19:56 +00:00
|
|
|
return new HttpRequestFactory(
|
|
|
|
|
new ServiceOptions(
|
|
|
|
|
HttpRequestFactory::CONSTRUCTOR_OPTIONS,
|
|
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
LoggerFactory::getInstance( 'http' )
|
|
|
|
|
);
|
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
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
return new ClassicInterwikiLookup(
|
|
|
|
|
$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(),
|
2021-04-01 20:48:53 +00:00
|
|
|
$services->getDBLoadBalancer(),
|
2018-08-03 08:05:44 +00:00
|
|
|
$config->get( 'InterwikiExpiry' ),
|
|
|
|
|
$config->get( 'InterwikiCache' ),
|
|
|
|
|
$config->get( 'InterwikiScopes' ),
|
|
|
|
|
$config->get( 'InterwikiFallbackSite' )
|
|
|
|
|
);
|
2016-04-19 11:55:23 +00:00
|
|
|
},
|
2016-04-03 08:37:11 +00:00
|
|
|
|
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() ),
|
|
|
|
|
$services->getConfiguredReadOnlyMode(),
|
|
|
|
|
$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-01-23 18:39:23 +00:00
|
|
|
$usePigLatinVariant = $services->getMainConfig()->get( 'UsePigLatinVariant' );
|
2020-11-25 04:35:49 +00:00
|
|
|
$isConversionDisabled = $services->getMainConfig()->get( 'DisableLangConversion' );
|
|
|
|
|
$isTitleConversionDisabled = $services->getMainConfig()->get( 'DisableTitleConversion' );
|
|
|
|
|
return new LanguageConverterFactory(
|
2021-10-23 21:33:01 +00:00
|
|
|
$services->getObjectFactory(),
|
2020-11-25 04:35:49 +00:00
|
|
|
$usePigLatinVariant,
|
|
|
|
|
$isConversionDisabled,
|
|
|
|
|
$isTitleConversionDisabled,
|
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() ),
|
|
|
|
|
$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(),
|
|
|
|
|
$services->getHookContainer()
|
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(
|
|
|
|
|
$services->getMainConfig()->get( 'LanguageCode' ),
|
|
|
|
|
$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(),
|
2022-01-27 23:32:56 +00:00
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
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
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'LocalisationCache' => static function ( MediaWikiServices $services ): LocalisationCache {
|
2019-05-01 13:56:41 +00:00
|
|
|
$conf = $services->getMainConfig()->get( 'LocalisationCacheConf' );
|
|
|
|
|
|
|
|
|
|
$logger = LoggerFactory::getInstance( 'localisation' );
|
|
|
|
|
|
|
|
|
|
$store = LocalisationCache::getStoreFromConf(
|
|
|
|
|
$conf, $services->getMainConfig()->get( '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 {
|
2020-03-04 15:21:19 +00:00
|
|
|
return ObjectCache::makeLocalServerCache();
|
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(),
|
|
|
|
|
$services->getMainConfig()->get( 'LockManagers' ),
|
|
|
|
|
$services->getDBLoadBalancerFactory()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
$id = $mainConfig->get( 'MainStash' );
|
|
|
|
|
if ( !isset( $mainConfig->get( 'ObjectCaches' )[$id] ) ) {
|
|
|
|
|
throw new UnexpectedValueException(
|
|
|
|
|
"Cache type \"$id\" is not present in \$wgObjectCaches." );
|
2016-10-04 17:48:02 +00:00
|
|
|
}
|
|
|
|
|
|
2019-10-10 20:30:47 +00:00
|
|
|
$params = $mainConfig->get( 'ObjectCaches' )[$id];
|
2020-12-28 22:34:29 +00:00
|
|
|
$params['stats'] = $services->getStatsdDataFactory();
|
2019-10-10 20:30:47 +00:00
|
|
|
|
2020-03-02 14:56:08 +00:00
|
|
|
$store = ObjectCache::newFromParams( $params, $mainConfig );
|
|
|
|
|
$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();
|
|
|
|
|
|
2020-03-30 21:28:53 +00:00
|
|
|
$wanId = $mainConfig->get( 'MainWANCache' );
|
|
|
|
|
$wanParams = $mainConfig->get( 'WANObjectCaches' )[$wanId] ?? null;
|
|
|
|
|
if ( !$wanParams ) {
|
2018-08-03 08:05:44 +00:00
|
|
|
throw new UnexpectedValueException(
|
2020-03-30 21:28:53 +00:00
|
|
|
"wgWANObjectCaches must have \"$wanId\" set (via wgMainWANCache)"
|
|
|
|
|
);
|
2016-10-04 17:48:02 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-30 21:28:53 +00:00
|
|
|
$cacheId = $wanParams['cacheId'];
|
|
|
|
|
$wanClass = $wanParams['class'];
|
|
|
|
|
unset( $wanParams['cacheId'] );
|
|
|
|
|
unset( $wanParams['class'] );
|
2019-10-08 21:34:17 +00:00
|
|
|
|
2020-03-30 21:28:53 +00:00
|
|
|
$storeParams = $mainConfig->get( 'ObjectCaches' )[$cacheId] ?? null;
|
|
|
|
|
if ( !$storeParams ) {
|
2018-08-03 08:05:44 +00:00
|
|
|
throw new UnexpectedValueException(
|
2020-03-30 21:28:53 +00:00
|
|
|
"wgObjectCaches must have \"$cacheId\" set (via wgWANObjectCaches)"
|
|
|
|
|
);
|
2018-08-03 08:05:44 +00:00
|
|
|
}
|
2020-12-28 22:34:29 +00:00
|
|
|
$storeParams['stats'] = $services->getStatsdDataFactory();
|
2020-03-02 14:56:08 +00:00
|
|
|
$store = ObjectCache::newFromParams( $storeParams, $mainConfig );
|
|
|
|
|
$logger = $store->getLogger();
|
2019-10-08 21:34:17 +00:00
|
|
|
$logger->debug( 'MainWANObjectCache using store {class}', [
|
|
|
|
|
'class' => get_class( $store )
|
|
|
|
|
] );
|
|
|
|
|
|
2020-03-30 21:28:53 +00:00
|
|
|
$wanParams['cache'] = $store;
|
|
|
|
|
$wanParams['logger'] = $logger;
|
|
|
|
|
$wanParams['secret'] = $wanParams['secret'] ?? $mainConfig->get( 'SecretKey' );
|
2019-10-08 21:34:17 +00:00
|
|
|
if ( !$mainConfig->get( 'CommandLineMode' ) ) {
|
|
|
|
|
// 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
|
|
|
}
|
|
|
|
|
|
2020-03-30 21:28:53 +00:00
|
|
|
$instance = new $wanClass( $wanParams );
|
2018-08-03 08:05:44 +00:00
|
|
|
|
2019-10-08 21:34:17 +00:00
|
|
|
'@phan-var WANObjectCache $instance';
|
|
|
|
|
return $instance;
|
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' ),
|
2016-07-29 00:01:08 +00:00
|
|
|
$services->getMainConfig()->get( 'MediaHandlers' )
|
|
|
|
|
);
|
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();
|
2019-10-11 23:26:18 +00:00
|
|
|
$clusterCache = ObjectCache::getInstance( $mainConfig->get( 'MessageCacheType' ) );
|
|
|
|
|
$srvCache = $mainConfig->get( 'UseLocalMessageCache' )
|
|
|
|
|
? $services->getLocalServerObjectCache()
|
|
|
|
|
: new EmptyBagOStuff();
|
|
|
|
|
|
|
|
|
|
$logger = LoggerFactory::getInstance( 'MessageCache' );
|
|
|
|
|
$logger->debug( 'MessageCache using store {class}', [
|
|
|
|
|
'class' => get_class( $clusterCache )
|
|
|
|
|
] );
|
|
|
|
|
|
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(),
|
2020-01-23 18:39:23 +00:00
|
|
|
$services->getLanguageConverterFactory()->getLanguageConverter(),
|
2019-10-11 23:37:37 +00:00
|
|
|
$logger,
|
2019-08-26 12:24:37 +00:00
|
|
|
[ 'useDB' => $mainConfig->get( 'UseDatabaseMessages' ) ],
|
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(),
|
|
|
|
|
$services->getHookContainer()
|
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();
|
|
|
|
|
},
|
|
|
|
|
|
2021-09-16 18:09:17 +00:00
|
|
|
'MetricsFactory' => static function ( MediaWikiServices $services ): MetricsFactory {
|
|
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
return new MetricsFactory(
|
|
|
|
|
[
|
|
|
|
|
'target' => $config->get( 'MetricsTarget' ),
|
2022-01-20 02:33:36 +00:00
|
|
|
'format' => $config->get( 'MetricsFormat' ),
|
|
|
|
|
'prefix' => $config->get( 'MetricsPrefix' ),
|
2021-09-16 18:09:17 +00:00
|
|
|
],
|
|
|
|
|
LoggerFactory::getInstance( 'Metrics' )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
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 = [
|
|
|
|
|
'typeFile' => $mainConfig->get( 'MimeTypeFile' ),
|
|
|
|
|
'infoFile' => $mainConfig->get( 'MimeInfoFile' ),
|
|
|
|
|
'xmlTypes' => $mainConfig->get( 'XMLMimeTypes' ),
|
|
|
|
|
'guessCallback' =>
|
2021-02-10 22:31:02 +00:00
|
|
|
static function ( $mimeAnalyzer, &$head, &$tail, $file, &$mime )
|
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 ( $logger, $hookRunner ) {
|
2016-11-22 23:57:34 +00:00
|
|
|
// Also test DjVu
|
|
|
|
|
$deja = new DjVuImage( $file );
|
|
|
|
|
if ( $deja->isValid() ) {
|
2018-09-30 15:25:59 +00:00
|
|
|
$logger->info( "Detected $file as image/vnd.djvu\n" );
|
2016-11-22 23:57:34 +00:00
|
|
|
$mime = 'image/vnd.djvu';
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// Some strings by reference for performance - assuming well-behaved hooks
|
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->onMimeMagicGuessFromContent(
|
|
|
|
|
$mimeAnalyzer, $head, $tail, $file, $mime );
|
2016-11-22 23:57:34 +00:00
|
|
|
},
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$detectorCmd = $mainConfig->get( 'MimeDetectorCommand' );
|
|
|
|
|
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() ),
|
|
|
|
|
$services->getHookContainer()
|
|
|
|
|
);
|
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' )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
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' ),
|
2020-04-06 09:16:17 +00:00
|
|
|
$services->getDBLoadBalancer(),
|
2020-07-18 22:17:25 +00:00
|
|
|
$services->getRevisionStore(),
|
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
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
|
|
|
|
|
return new PageEditStash(
|
|
|
|
|
ObjectCache::getLocalClusterInstance(),
|
|
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
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(),
|
2019-04-13 04:38:55 +00:00
|
|
|
defined( 'MEDIAWIKI_JOB_RUNNER' ) || $config->get( 'CommandLineMode' )
|
|
|
|
|
? 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(),
|
|
|
|
|
$services->getDBLoadBalancer()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
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(),
|
|
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
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(),
|
2021-07-16 17:32:30 +00:00
|
|
|
ChangeTags::getSoftwareTags()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'Parser' => static function ( MediaWikiServices $services ): Parser {
|
2018-08-03 08:43:00 +00:00
|
|
|
return $services->getParserFactory()->create();
|
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();
|
|
|
|
|
$cache = ObjectCache::getInstance( $config->get( '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(),
|
2020-09-25 20:02:03 +00:00
|
|
|
$services->getStatsdDataFactory(),
|
2020-10-12 10:03:18 +00:00
|
|
|
LoggerFactory::getInstance( 'ParserCache' ),
|
2021-03-24 14:05:44 +00:00
|
|
|
$options,
|
|
|
|
|
$services->getTitleFactory(),
|
|
|
|
|
$services->getWikiPageFactory()
|
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(),
|
2018-08-15 01:11:59 +00:00
|
|
|
wfUrlProtocols(),
|
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(),
|
|
|
|
|
$services->getTrackingCategories()
|
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(
|
|
|
|
|
$services->getParserCache(),
|
2020-12-04 15:28:25 +00:00
|
|
|
$services->getParserCacheFactory()->getRevisionOutputCache( 'rcache' ),
|
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(),
|
2021-04-03 02:12:43 +00:00
|
|
|
LoggerFactory::getProvider(),
|
|
|
|
|
$services->getWikiPageFactory(),
|
|
|
|
|
$services->getTitleFormatter()
|
2020-09-30 19:25:29 +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(
|
|
|
|
|
$config->get( 'PasswordConfig' ),
|
|
|
|
|
$config->get( '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(),
|
2019-09-10 02:49:12 +00:00
|
|
|
$services->getDBLoadBalancer(),
|
2020-10-02 23:02:31 +00:00
|
|
|
$services->getUserFactory(),
|
|
|
|
|
$services->getUserNameUtils(),
|
|
|
|
|
$services->getUserOptionsLookup()
|
2019-09-10 02:49:12 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2018-08-07 16:33:20 +00:00
|
|
|
'PerDbNameStatsdDataFactory' =>
|
2021-07-22 03:11:47 +00:00
|
|
|
static function ( MediaWikiServices $services ): StatsdDataFactoryInterface {
|
2018-08-03 08:05:44 +00:00
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
$wiki = $config->get( '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(),
|
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->getBlockErrorFormatter(),
|
2020-10-20 17:34:25 +00:00
|
|
|
$services->getHookContainer(),
|
2021-10-20 15:51:22 +00:00
|
|
|
$services->getUserCache(),
|
|
|
|
|
$services->getRedirectLookup()
|
2019-04-09 09:28:38 +00:00
|
|
|
);
|
2019-03-07 20:02:07 +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(),
|
|
|
|
|
$services->getParser(),
|
|
|
|
|
$services->getSkinFactory(),
|
2021-05-29 01:32:24 +00:00
|
|
|
$services->getUserGroupManager()
|
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;
|
|
|
|
|
},
|
|
|
|
|
|
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(
|
2017-11-01 20:55:24 +00:00
|
|
|
$mainConfig->get( 'CdnServers' ),
|
2021-03-30 18:43:18 +00:00
|
|
|
$mainConfig->get( 'CdnServersNoPurge' ),
|
|
|
|
|
$services->getHookContainer()
|
2018-08-03 08:05:44 +00:00
|
|
|
);
|
|
|
|
|
},
|
2017-11-14 11:17:34 +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(
|
|
|
|
|
$services->getConfiguredReadOnlyMode(),
|
|
|
|
|
$services->getDBLoadBalancer()
|
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(
|
|
|
|
|
$config->get( 'LocalFileRepo' ),
|
|
|
|
|
$config->get( '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-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.
|
2019-04-06 20:41:36 +00:00
|
|
|
global $IP;
|
2019-03-29 01:21:18 +00:00
|
|
|
$config = $services->getMainConfig();
|
|
|
|
|
|
|
|
|
|
$rl = new ResourceLoader(
|
|
|
|
|
$config,
|
2019-06-29 04:50:31 +00:00
|
|
|
LoggerFactory::getInstance( 'resourceloader' ),
|
|
|
|
|
$config->get( 'ResourceLoaderUseObjectCacheForDeps' )
|
|
|
|
|
? new KeyValueDependencyStore( $services->getMainObjectStash() )
|
|
|
|
|
: new SqlModuleDependencyStore( $services->getDBLoadBalancer() )
|
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' )
|
|
|
|
|
+ $config->get( 'ResourceModules' );
|
2020-03-09 20:12:45 +00:00
|
|
|
$moduleSkinStyles = $extRegistry->getAttribute( 'ResourceModuleSkinStyles' )
|
|
|
|
|
+ $config->get( 'ResourceModuleSkinStyles' );
|
|
|
|
|
|
|
|
|
|
$rl->setModuleSkinStyles( $moduleSkinStyles );
|
2019-03-29 01:21:18 +00:00
|
|
|
$rl->addSource( $config->get( 'ResourceLoaderSources' ) );
|
2019-04-17 14:17:15 +00:00
|
|
|
|
|
|
|
|
// Core modules, then extension/skin modules
|
2019-04-06 20:41:36 +00:00
|
|
|
$rl->register( include "$IP/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', [
|
2020-10-28 02:18:32 +00:00
|
|
|
'localBasePath' => $IP,
|
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'] ?? []
|
|
|
|
|
),
|
|
|
|
|
'targets' => [ 'desktop', 'mobile' ],
|
|
|
|
|
] );
|
|
|
|
|
|
2019-04-17 14:17:15 +00:00
|
|
|
if ( $config->get( 'EnableJavaScriptTest' ) === true ) {
|
|
|
|
|
$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(),
|
|
|
|
|
$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(),
|
|
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
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 {
|
2018-06-27 12:16:35 +00:00
|
|
|
$config = $services->getMainConfig();
|
2019-12-17 16:20:32 +00:00
|
|
|
|
|
|
|
|
if ( $config->has( 'MultiContentRevisionSchemaMigrationStage' ) ) {
|
|
|
|
|
if ( $config->get( 'MultiContentRevisionSchemaMigrationStage' ) !== SCHEMA_COMPAT_NEW ) {
|
|
|
|
|
throw new UnexpectedValueException(
|
|
|
|
|
'The MultiContentRevisionSchemaMigrationStage setting is no longer supported!'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-27 12:16:35 +00:00
|
|
|
$store = new RevisionStoreFactory(
|
|
|
|
|
$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(),
|
2018-06-27 12:16:35 +00:00
|
|
|
$services->getActorMigration(),
|
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
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return $store;
|
|
|
|
|
},
|
|
|
|
|
|
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 {
|
|
|
|
|
$parserFactory = new CommentParserFactory(
|
|
|
|
|
$services->getLinkRenderer(),
|
|
|
|
|
$services->getLinkBatchFactory(),
|
|
|
|
|
$services->getLinkCache(),
|
|
|
|
|
$services->getRepoGroup(),
|
|
|
|
|
RequestContext::getMain()->getLanguage(),
|
|
|
|
|
$services->getContentLanguage(),
|
|
|
|
|
$services->getTitleParser(),
|
|
|
|
|
$services->getNamespaceInfo(),
|
|
|
|
|
$services->getHookContainer()
|
|
|
|
|
);
|
|
|
|
|
return new RowCommentFormatter(
|
|
|
|
|
$parserFactory,
|
|
|
|
|
$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(),
|
2020-04-27 12:44:55 +00:00
|
|
|
ExtensionRegistry::getInstance()->getAttribute( 'SearchMappings' )
|
|
|
|
|
);
|
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(),
|
|
|
|
|
$services->getDBLoadBalancer()
|
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
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'ShellboxClientFactory' => static function ( MediaWikiServices $services ): ShellboxClientFactory {
|
2021-06-18 08:41:28 +00:00
|
|
|
$urls = $services->getMainConfig()->get( 'ShellboxUrls' );
|
|
|
|
|
// TODO: Remove this logic and $wgShellboxUrl configuration in 1.38
|
|
|
|
|
$url = $services->getMainConfig()->get( 'ShellboxUrl' );
|
|
|
|
|
if ( $url !== null ) {
|
|
|
|
|
$urls['default'] = $url;
|
|
|
|
|
}
|
2020-09-11 03:21:24 +00:00
|
|
|
return new ShellboxClientFactory(
|
|
|
|
|
$services->getHttpRequestFactory(),
|
2021-06-18 08:41:28 +00:00
|
|
|
$urls,
|
2020-09-11 03:21:24 +00:00
|
|
|
$services->getMainConfig()->get( 'ShellboxSecretKey' )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
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 = [
|
|
|
|
|
'time' => $config->get( 'MaxShellTime' ),
|
|
|
|
|
'walltime' => $config->get( 'MaxShellWallClockTime' ),
|
|
|
|
|
'memory' => $config->get( 'MaxShellMemory' ),
|
|
|
|
|
'filesize' => $config->get( 'MaxShellFileSize' ),
|
|
|
|
|
];
|
|
|
|
|
$cgroup = $config->get( 'ShellCgroup' );
|
|
|
|
|
$restrictionMethod = $config->get( 'ShellRestrictionMethod' );
|
|
|
|
|
|
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()
|
|
|
|
|
),
|
|
|
|
|
$services->getParser(),
|
|
|
|
|
$services->getSpecialPageFactory(),
|
|
|
|
|
$services->getTitleFactory()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
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 {
|
2018-08-03 08:05:44 +00:00
|
|
|
$rawSiteStore = new DBSiteStore( $services->getDBLoadBalancer() );
|
|
|
|
|
|
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(),
|
|
|
|
|
(array)$services->getMainConfig()->get( 'SkipSkins' )
|
|
|
|
|
);
|
2018-08-03 08:05:44 +00:00
|
|
|
|
|
|
|
|
$names = $services->getMainConfig()->get( 'ValidSkinNames' );
|
|
|
|
|
|
|
|
|
|
foreach ( $names as $name => $skin ) {
|
2020-05-14 11:20:24 +00:00
|
|
|
if ( is_array( $skin ) ) {
|
|
|
|
|
$spec = $skin;
|
|
|
|
|
$displayName = $skin['displayname'] ?? $name;
|
2021-09-15 00:26:48 +00:00
|
|
|
$skippable = $skin['skippable'] ?? false;
|
2020-05-14 11:20:24 +00:00
|
|
|
} else {
|
|
|
|
|
$displayName = $skin;
|
2021-09-15 00:26:48 +00:00
|
|
|
$skippable = false;
|
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(
|
|
|
|
|
'main',
|
|
|
|
|
static function () use ( $config, $contentHandlerFactory, $hookContainer, $titleFactory ) {
|
|
|
|
|
return new MainSlotRoleHandler(
|
|
|
|
|
$config->get( 'NamespaceContentModels' ),
|
|
|
|
|
$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(
|
|
|
|
|
(array)$services->getMainConfig()->get( 'SpamRegex' ),
|
|
|
|
|
(array)$services->getMainConfig()->get( 'SummarySpamRegex' )
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
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(
|
|
|
|
|
rtrim( $services->getMainConfig()->get( 'StatsdMetricPrefix' ), '.' )
|
2018-06-21 06:59:02 +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()
|
|
|
|
|
),
|
|
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
$services->getReadOnlyMode(),
|
|
|
|
|
$services->getRevisionLookup()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
'TempFSFileFactory' => static function ( MediaWikiServices $services ): TempFSFileFactory {
|
2019-08-16 10:00:15 +00:00
|
|
|
return new TempFSFileFactory( $services->getMainConfig()->get( 'TmpDirectory' ) );
|
|
|
|
|
},
|
|
|
|
|
|
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
|
|
|
},
|
|
|
|
|
|
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(
|
|
|
|
|
$services->getMainConfig()->get( 'EnableUploads' ),
|
|
|
|
|
LoggerFactory::getInstance( 'UploadRevisionImporter' )
|
2018-01-24 23:41:01 +00:00
|
|
|
);
|
2017-09-12 17:12:29 +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' ),
|
|
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
$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(),
|
2020-08-05 16:02:05 +00:00
|
|
|
$services->getDBLoadBalancer(),
|
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(
|
|
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
$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()
|
|
|
|
|
),
|
|
|
|
|
$services->getConfiguredReadOnlyMode(),
|
|
|
|
|
$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' ),
|
2021-02-10 22:31:02 +00:00
|
|
|
[ static function ( UserIdentity $user ) use ( $services ) {
|
2019-10-24 03:14:31 +00:00
|
|
|
$services->getPermissionManager()->invalidateUsersRightsCache( $user );
|
2021-01-05 23:08:09 +00:00
|
|
|
$services->getUserFactory()->newFromUserIdentity( $user )->invalidateCache();
|
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();
|
|
|
|
|
},
|
|
|
|
|
|
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(
|
|
|
|
|
$services->getDBLoadBalancer(),
|
2021-06-28 07:41:34 +00:00
|
|
|
$services->getUserFactory(),
|
|
|
|
|
$services->getUserNameUtils()
|
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
|
|
|
),
|
|
|
|
|
$services->getHookContainer()
|
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(),
|
|
|
|
|
$services->getDBLoadBalancer(),
|
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(),
|
|
|
|
|
$services->getUserFactory()
|
2020-01-17 06:21:28 +00:00
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2018-08-07 16:33:20 +00:00
|
|
|
'VirtualRESTServiceClient' =>
|
2021-07-22 03:11:47 +00:00
|
|
|
static function ( MediaWikiServices $services ): VirtualRESTServiceClient {
|
2018-08-03 08:05:44 +00:00
|
|
|
$config = $services->getMainConfig()->get( 'VirtualRestConfig' );
|
|
|
|
|
|
2020-05-21 03:57:15 +00:00
|
|
|
$vrsClient = new VirtualRESTServiceClient(
|
|
|
|
|
$services->getHttpRequestFactory()->createMultiClient() );
|
2018-08-03 08:05:44 +00:00
|
|
|
foreach ( $config['paths'] as $prefix => $serviceConfig ) {
|
|
|
|
|
$class = $serviceConfig['class'];
|
|
|
|
|
// Merge in the global defaults
|
|
|
|
|
$constructArg = $serviceConfig['options'] ?? [];
|
|
|
|
|
$constructArg += $config['global'];
|
|
|
|
|
// Make the VRS service available at the mount point
|
|
|
|
|
$vrsClient->mount( $prefix, [ 'class' => $class, 'config' => $constructArg ] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $vrsClient;
|
|
|
|
|
},
|
|
|
|
|
|
2018-08-07 16:33:20 +00:00
|
|
|
'WatchedItemQueryService' =>
|
2021-07-22 03:11:47 +00:00
|
|
|
static function ( MediaWikiServices $services ): WatchedItemQueryService {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new WatchedItemQueryService(
|
|
|
|
|
$services->getDBLoadBalancer(),
|
|
|
|
|
$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(),
|
2021-12-14 09:08:51 +00:00
|
|
|
$services->getMainConfig()->get( 'WatchlistExpiry' ),
|
|
|
|
|
$services->getMainConfig()->get( '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() );
|
|
|
|
|
|
|
|
|
|
if ( $services->getMainConfig()->get( 'ReadOnlyWatchedItemStore' ) ) {
|
|
|
|
|
$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(
|
2020-05-23 08:43:34 +00:00
|
|
|
new ServiceOptions(
|
2021-03-26 22:24:43 +00:00
|
|
|
WatchlistManager::CONSTRUCTOR_OPTIONS,
|
2020-05-23 08:43:34 +00:00
|
|
|
$services->getMainConfig()
|
|
|
|
|
),
|
|
|
|
|
$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(),
|
|
|
|
|
$services->getTitleParser()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
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->getPermissionManager(),
|
|
|
|
|
$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() ),
|
|
|
|
|
$services->getDBLoadBalancer()
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
2018-08-07 16:33:20 +00:00
|
|
|
'WikiRevisionOldRevisionImporterNoUpdates' =>
|
2021-07-22 03:11:47 +00:00
|
|
|
static function ( MediaWikiServices $services ): ImportableOldRevisionImporter {
|
2018-08-03 08:05:44 +00:00
|
|
|
return new ImportableOldRevisionImporter(
|
|
|
|
|
false,
|
|
|
|
|
LoggerFactory::getInstance( 'OldRevisionImporter' ),
|
2020-04-06 09:16:17 +00:00
|
|
|
$services->getDBLoadBalancer(),
|
2020-07-18 22:17:25 +00:00
|
|
|
$services->getRevisionStore(),
|
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
|
|
|
);
|
2018-07-25 14:37:16 +00:00
|
|
|
},
|
|
|
|
|
|
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(),
|
|
|
|
|
$services->getNamespaceInfo()
|
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
|
|
|
|
|
$services->getSpamChecker()
|
2020-10-21 01:05:00 +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(),
|
2018-08-15 07:15:04 +00:00
|
|
|
$services->getMainConfig()->get( '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()
|
|
|
|
|
)
|
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' ) );
|
|
|
|
|
},
|
|
|
|
|
|
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' ).
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
];
|