aboutsummaryrefslogtreecommitdiffstats
path: root/includes
diff options
context:
space:
mode:
Diffstat (limited to 'includes')
-rw-r--r--includes/Hook/AfterBuildFeedLinksHook.php21
-rw-r--r--includes/Hook/AfterFinalPageOutputHook.php22
-rw-r--r--includes/Hook/AlternateEditHook.php20
-rw-r--r--includes/Hook/AlternateEditPreviewHook.php27
-rw-r--r--includes/Hook/ApiBeforeMainHook.php19
-rw-r--r--includes/Hook/ArticleMergeCompleteHook.php20
-rw-r--r--includes/Hook/ArticleUpdateBeforeRedirectHook.php24
-rw-r--r--includes/Hook/AutopromoteConditionHook.php22
-rw-r--r--includes/Hook/BadImageHook.php22
-rw-r--r--includes/Hook/BeforeHttpsRedirectHook.php24
-rw-r--r--includes/Hook/BeforeInitializeHook.php27
-rw-r--r--includes/Hook/BeforePageDisplayHook.php20
-rw-r--r--includes/Hook/BeforePageRedirectHook.php23
-rw-r--r--includes/Hook/CanIPUseHTTPSHook.php22
-rw-r--r--includes/Hook/CategoryViewer__doCategoryQueryHook.php23
-rw-r--r--includes/Hook/CategoryViewer__generateLinkHook.php25
-rw-r--r--includes/Hook/ContentSecurityPolicyDefaultSourceHook.php26
-rw-r--r--includes/Hook/ContentSecurityPolicyDirectivesHook.php26
-rw-r--r--includes/Hook/ContentSecurityPolicyScriptSourceHook.php27
-rw-r--r--includes/Hook/DeleteUnknownPreferencesHook.php27
-rw-r--r--includes/Hook/EditFilterHook.php23
-rw-r--r--includes/Hook/EditFilterMergedContentHook.php33
-rw-r--r--includes/Hook/EditFormInitialTextHook.php20
-rw-r--r--includes/Hook/EditFormPreloadTextHook.php21
-rw-r--r--includes/Hook/EditPageBeforeConflictDiffHook.php24
-rw-r--r--includes/Hook/EditPageBeforeEditButtonsHook.php22
-rw-r--r--includes/Hook/EditPageBeforeEditToolbarHook.php21
-rw-r--r--includes/Hook/EditPageCopyrightWarningHook.php22
-rw-r--r--includes/Hook/EditPageGetCheckboxesDefinitionHook.php22
-rw-r--r--includes/Hook/EditPageGetDiffContentHook.php22
-rw-r--r--includes/Hook/EditPageGetPreviewContentHook.php22
-rw-r--r--includes/Hook/EditPageNoSuchSectionHook.php21
-rw-r--r--includes/Hook/EditPageTosSummaryHook.php22
-rw-r--r--includes/Hook/EditPage__attemptSaveHook.php21
-rw-r--r--includes/Hook/EditPage__attemptSave_afterHook.php24
-rw-r--r--includes/Hook/EditPage__importFormDataHook.php23
-rw-r--r--includes/Hook/EditPage__showEditForm_fieldsHook.php22
-rw-r--r--includes/Hook/EditPage__showEditForm_initialHook.php25
-rw-r--r--includes/Hook/EditPage__showReadOnlyForm_initialHook.php23
-rw-r--r--includes/Hook/EditPage__showStandardInputs_optionsHook.php26
-rw-r--r--includes/Hook/FileDeleteCompleteHook.php26
-rw-r--r--includes/Hook/FormatAutocommentsHook.php30
-rw-r--r--includes/Hook/GetAutoPromoteGroupsHook.php21
-rw-r--r--includes/Hook/GetCacheVaryCookiesHook.php21
-rw-r--r--includes/Hook/GetCanonicalURLHook.php22
-rw-r--r--includes/Hook/GetDefaultSortkeyHook.php20
-rw-r--r--includes/Hook/GetDoubleUnderscoreIDsHook.php20
-rw-r--r--includes/Hook/GetFullURLHook.php21
-rw-r--r--includes/Hook/GetIPHook.php19
-rw-r--r--includes/Hook/GetInternalURLHook.php21
-rw-r--r--includes/Hook/GetLocalURLHook.php25
-rw-r--r--includes/Hook/GetLocalURL__ArticleHook.php22
-rw-r--r--includes/Hook/GetLocalURL__InternalHook.php22
-rw-r--r--includes/Hook/GetRelativeTimestampHook.php28
-rw-r--r--includes/Hook/GitViewersHook.php20
-rw-r--r--includes/Hook/ImageBeforeProduceHTMLHook.php34
-rw-r--r--includes/Hook/ImgAuthBeforeStreamHook.php29
-rw-r--r--includes/Hook/ImgAuthModifyHeadersHook.php24
-rw-r--r--includes/Hook/ImportHandleUnknownUserHook.php21
-rw-r--r--includes/Hook/InitializeArticleMaybeRedirectHook.php25
-rw-r--r--includes/Hook/IsTrustedProxyHook.php20
-rw-r--r--includes/Hook/LanguageLinksHook.php26
-rw-r--r--includes/Hook/LinkerMakeExternalImageHook.php22
-rw-r--r--includes/Hook/LinkerMakeExternalLinkHook.php26
-rw-r--r--includes/Hook/LinkerMakeMediaLinkFileHook.php26
-rw-r--r--includes/Hook/LocalisationChecksBlacklistHook.php21
-rw-r--r--includes/Hook/LocalisationIgnoredOptionalMessagesHook.php21
-rw-r--r--includes/Hook/MagicWordwgVariableIDsHook.php19
-rw-r--r--includes/Hook/MaintenanceRefreshLinksInitHook.php20
-rw-r--r--includes/Hook/MaintenanceUpdateAddParamsHook.php27
-rw-r--r--includes/Hook/MakeGlobalVariablesScriptHook.php24
-rw-r--r--includes/Hook/MediaWikiPHPUnitTest__endTestHook.php21
-rw-r--r--includes/Hook/MediaWikiPHPUnitTest__startTestHook.php20
-rw-r--r--includes/Hook/MediaWikiPerformActionHook.php28
-rw-r--r--includes/Hook/MediaWikiServicesHook.php22
-rw-r--r--includes/Hook/MimeMagicGuessFromContentHook.php26
-rw-r--r--includes/Hook/MimeMagicImproveFromExtensionHook.php22
-rw-r--r--includes/Hook/MimeMagicInitHook.php26
-rw-r--r--includes/Hook/MovePageCheckPermissionsHook.php26
-rw-r--r--includes/Hook/MovePageIsValidMoveHook.php22
-rw-r--r--includes/Hook/OpenSearchUrlsHook.php20
-rw-r--r--includes/Hook/OutputPageAfterGetHeadLinksArrayHook.php22
-rw-r--r--includes/Hook/OutputPageBeforeHTMLHook.php21
-rw-r--r--includes/Hook/OutputPageBodyAttributesHook.php24
-rw-r--r--includes/Hook/OutputPageCheckLastModifiedHook.php22
-rw-r--r--includes/Hook/OutputPageMakeCategoryLinksHook.php25
-rw-r--r--includes/Hook/OutputPageParserOutputHook.php20
-rw-r--r--includes/Hook/ParserTestGlobalsHook.php20
-rw-r--r--includes/Hook/ParserTestTablesHook.php21
-rw-r--r--includes/Hook/ProtectionForm__buildFormHook.php22
-rw-r--r--includes/Hook/ProtectionForm__saveHook.php23
-rw-r--r--includes/Hook/ProtectionForm__showLogExtractHook.php22
-rw-r--r--includes/Hook/ResourceLoaderRegisterModulesHook.php21
-rw-r--r--includes/Hook/SelfLinkBeginHook.php24
-rw-r--r--includes/Hook/SetupAfterCacheHook.php17
-rw-r--r--includes/Hook/TestCanonicalRedirectHook.php24
-rw-r--r--includes/Hook/TitleArrayFromResultHook.php21
-rw-r--r--includes/Hook/TitleExistsHook.php20
-rw-r--r--includes/Hook/TitleGetEditNoticesHook.php22
-rw-r--r--includes/Hook/TitleGetRestrictionTypesHook.php21
-rw-r--r--includes/Hook/TitleIsAlwaysKnownHook.php23
-rw-r--r--includes/Hook/TitleIsMovableHook.php24
-rw-r--r--includes/Hook/TitleMoveCompleteHook.php27
-rw-r--r--includes/Hook/TitleMoveCompletingHook.php27
-rw-r--r--includes/Hook/TitleMoveHook.php24
-rw-r--r--includes/Hook/TitleMoveStartingHook.php22
-rw-r--r--includes/Hook/TitleSquidURLsHook.php20
-rw-r--r--includes/Hook/UnitTestsAfterDatabaseSetupHook.php21
-rw-r--r--includes/Hook/UnitTestsBeforeDatabaseTeardownHook.php18
-rw-r--r--includes/Hook/UnitTestsListHook.php21
-rw-r--r--includes/Hook/UserToolLinksEditHook.php22
-rw-r--r--includes/Hook/WebRequestPathInfoRouterHook.php20
-rw-r--r--includes/Hook/WebResponseSetCookieHook.php23
-rw-r--r--includes/Permissions/Hook/GetUserPermissionsErrorsExpensiveHook.php32
-rw-r--r--includes/Permissions/Hook/GetUserPermissionsErrorsHook.php30
-rw-r--r--includes/Permissions/Hook/TitleQuickPermissionsHook.php27
-rw-r--r--includes/Permissions/Hook/TitleReadWhitelistHook.php23
-rw-r--r--includes/Permissions/Hook/UserCanHook.php24
-rw-r--r--includes/Permissions/Hook/UserGetAllRightsHook.php19
-rw-r--r--includes/Permissions/Hook/UserGetRightsHook.php20
-rw-r--r--includes/Permissions/Hook/UserGetRightsRemoveHook.php23
-rw-r--r--includes/Permissions/Hook/UserIsBlockedFromHook.php24
-rw-r--r--includes/Permissions/Hook/UserIsEveryoneAllowedHook.php20
-rw-r--r--includes/Revision/Hook/ContentHandlerDefaultModelForHook.php22
-rw-r--r--includes/Revision/Hook/RevisionInsertCompleteHook.php22
-rw-r--r--includes/Revision/Hook/RevisionRecordInsertedHook.php19
-rw-r--r--includes/Storage/Hook/ArticleEditUpdateNewTalkHook.php21
-rw-r--r--includes/Storage/Hook/ArticleEditUpdatesDeleteFromRecentchangesHook.php21
-rw-r--r--includes/Storage/Hook/ArticleEditUpdatesHook.php23
-rw-r--r--includes/Storage/Hook/ArticlePrepareTextForEditHook.php20
-rw-r--r--includes/Storage/Hook/MultiContentSaveHook.php33
-rw-r--r--includes/Storage/Hook/PageContentInsertCompleteHook.php29
-rw-r--r--includes/Storage/Hook/PageContentSaveCompleteHook.php37
-rw-r--r--includes/Storage/Hook/PageContentSaveHook.php33
-rw-r--r--includes/Storage/Hook/ParserOutputStashForEditHook.php26
-rw-r--r--includes/Storage/Hook/RevisionDataUpdatesHook.php24
-rw-r--r--includes/actions/Hook/ActionBeforeFormDisplayHook.php21
-rw-r--r--includes/actions/Hook/ActionModifyFormFieldsHook.php22
-rw-r--r--includes/actions/Hook/CustomEditorHook.php22
-rw-r--r--includes/actions/Hook/HistoryPageToolLinksHook.php21
-rw-r--r--includes/actions/Hook/HistoryRevisionToolsHook.php23
-rw-r--r--includes/actions/Hook/InfoActionHook.php20
-rw-r--r--includes/actions/Hook/PageHistoryBeforeListHook.php20
-rw-r--r--includes/actions/Hook/PageHistoryLineEndingHook.php27
-rw-r--r--includes/actions/Hook/PageHistoryPager__doBatchLookupsHook.php24
-rw-r--r--includes/actions/Hook/PageHistoryPager__getQueryInfoHook.php22
-rw-r--r--includes/actions/Hook/RawPageViewBeforeOutputHook.php20
-rw-r--r--includes/actions/Hook/UnwatchArticleCompleteHook.php20
-rw-r--r--includes/actions/Hook/UnwatchArticleHook.php21
-rw-r--r--includes/actions/Hook/WatchArticleCompleteHook.php20
-rw-r--r--includes/actions/Hook/WatchArticleHook.php22
-rw-r--r--includes/api/Hook/APIAfterExecuteHook.php20
-rw-r--r--includes/api/Hook/APIGetAllowedParamsHook.php21
-rw-r--r--includes/api/Hook/APIGetDescriptionMessagesHook.php20
-rw-r--r--includes/api/Hook/APIGetParamDescriptionMessagesHook.php21
-rw-r--r--includes/api/Hook/APIHelpModifyOutputHook.php23
-rw-r--r--includes/api/Hook/APIQueryAfterExecuteHook.php20
-rw-r--r--includes/api/Hook/APIQueryGeneratorAfterExecuteHook.php21
-rw-r--r--includes/api/Hook/APIQueryInfoTokensHook.php27
-rw-r--r--includes/api/Hook/APIQueryRecentChangesTokensHook.php29
-rw-r--r--includes/api/Hook/APIQueryRevisionsTokensHook.php29
-rw-r--r--includes/api/Hook/APIQuerySiteInfoGeneralInfoHook.php21
-rw-r--r--includes/api/Hook/APIQuerySiteInfoStatisticsInfoHook.php20
-rw-r--r--includes/api/Hook/APIQueryUsersTokensHook.php27
-rw-r--r--includes/api/Hook/ApiCheckCanExecuteHook.php28
-rw-r--r--includes/api/Hook/ApiDeprecationHelpHook.php21
-rw-r--r--includes/api/Hook/ApiFeedContributions__feedItemHook.php29
-rw-r--r--includes/api/Hook/ApiFormatHighlightHook.php23
-rw-r--r--includes/api/Hook/ApiMain__moduleManagerHook.php21
-rw-r--r--includes/api/Hook/ApiMain__onExceptionHook.php22
-rw-r--r--includes/api/Hook/ApiMakeParserOptionsHook.php27
-rw-r--r--includes/api/Hook/ApiMaxLagInfoHook.php28
-rw-r--r--includes/api/Hook/ApiOpenSearchSuggestHook.php29
-rw-r--r--includes/api/Hook/ApiOptionsHook.php25
-rw-r--r--includes/api/Hook/ApiParseMakeOutputPageHook.php22
-rw-r--r--includes/api/Hook/ApiQueryBaseAfterQueryHook.php26
-rw-r--r--includes/api/Hook/ApiQueryBaseBeforeQueryHook.php33
-rw-r--r--includes/api/Hook/ApiQueryBaseProcessRowHook.php26
-rw-r--r--includes/api/Hook/ApiQueryTokensRegisterTypesHook.php22
-rw-r--r--includes/api/Hook/ApiQueryWatchlistExtractOutputDataHook.php24
-rw-r--r--includes/api/Hook/ApiQueryWatchlistPrepareWatchedItemQueryServiceOptionsHook.php25
-rw-r--r--includes/api/Hook/ApiQuery__moduleManagerHook.php21
-rw-r--r--includes/api/Hook/ApiRsdServiceApisHook.php22
-rw-r--r--includes/api/Hook/ApiTokensGetTokenTypesHook.php21
-rw-r--r--includes/api/Hook/ApiValidatePasswordHook.php20
-rw-r--r--includes/api/Hook/RequestHasSameOriginSecurityHook.php22
-rw-r--r--includes/auth/Hook/AuthManagerLoginAuthenticateAuditHook.php32
-rw-r--r--includes/auth/Hook/ExemptFromAccountCreationThrottleHook.php20
-rw-r--r--includes/auth/Hook/LocalUserCreatedHook.php20
-rw-r--r--includes/auth/Hook/ResetPasswordExpirationHook.php20
-rw-r--r--includes/auth/Hook/SecuritySensitiveOperationStatusHook.php29
-rw-r--r--includes/auth/Hook/UserLoggedInHook.php19
-rw-r--r--includes/block/Hook/AbortAutoblockHook.php20
-rw-r--r--includes/block/Hook/GetUserBlockHook.php24
-rw-r--r--includes/block/Hook/PerformRetroactiveAutoblockHook.php21
-rw-r--r--includes/cache/Hook/BacklinkCacheGetConditionsHook.php22
-rw-r--r--includes/cache/Hook/BacklinkCacheGetPrefixHook.php20
-rw-r--r--includes/cache/Hook/HTMLFileCache__useFileCacheHook.php22
-rw-r--r--includes/cache/Hook/MessageCacheReplaceHook.php21
-rw-r--r--includes/cache/Hook/MessageCache__getHook.php23
-rw-r--r--includes/cache/Hook/MessagesPreLoadHook.php21
-rw-r--r--includes/cache/localisation/Hook/LocalisationCacheRecacheFallbackHook.php23
-rw-r--r--includes/cache/localisation/Hook/LocalisationCacheRecacheHook.php23
-rw-r--r--includes/changes/Hook/AbortEmailNotificationHook.php21
-rw-r--r--includes/changes/Hook/ChangesListInitRowsHook.php21
-rw-r--r--includes/changes/Hook/ChangesListInsertArticleLinkHook.php26
-rw-r--r--includes/changes/Hook/EnhancedChangesListModifyBlockLineDataHook.php25
-rw-r--r--includes/changes/Hook/EnhancedChangesListModifyLineDataHook.php31
-rw-r--r--includes/changes/Hook/EnhancedChangesList__getLogTextHook.php26
-rw-r--r--includes/changes/Hook/FetchChangesListHook.php24
-rw-r--r--includes/changes/Hook/MarkPatrolledCompleteHook.php25
-rw-r--r--includes/changes/Hook/MarkPatrolledHook.php26
-rw-r--r--includes/changes/Hook/OldChangesListRecentChangesLineHook.php28
-rw-r--r--includes/changes/Hook/RecentChange_saveHook.php20
-rw-r--r--includes/changetags/Hook/ChangeTagAfterDeleteHook.php24
-rw-r--r--includes/changetags/Hook/ChangeTagCanCreateHook.php25
-rw-r--r--includes/changetags/Hook/ChangeTagCanDeleteHook.php27
-rw-r--r--includes/changetags/Hook/ChangeTagsAfterUpdateTagsHook.php31
-rw-r--r--includes/changetags/Hook/ChangeTagsAllowedAddHook.php23
-rw-r--r--includes/changetags/Hook/ChangeTagsListActiveHook.php20
-rw-r--r--includes/changetags/Hook/ListDefinedTagsHook.php19
-rw-r--r--includes/collation/Hook/Collation__factoryHook.php22
-rw-r--r--includes/content/Hook/ContentAlterParserOutputHook.php25
-rw-r--r--includes/content/Hook/ContentGetParserOutputHook.php32
-rw-r--r--includes/content/Hook/ContentHandlerForModelIDHook.php24
-rw-r--r--includes/content/Hook/ContentModelCanBeUsedOnHook.php25
-rw-r--r--includes/content/Hook/ConvertContentHook.php27
-rw-r--r--includes/content/Hook/GetContentModelsHook.php20
-rw-r--r--includes/content/Hook/GetDifferenceEngineHook.php27
-rw-r--r--includes/content/Hook/GetSlotDiffRendererHook.php24
-rw-r--r--includes/content/Hook/PageContentLanguageHook.php24
-rw-r--r--includes/content/Hook/PlaceNewSectionHook.php23
-rw-r--r--includes/content/Hook/SearchDataForIndexHook.php26
-rw-r--r--includes/content/Hook/SecondaryDataUpdatesHook.php30
-rw-r--r--includes/context/Hook/RequestContextCreateSkinHook.php23
-rw-r--r--includes/context/Hook/UserGetLanguageObjectHook.php21
-rw-r--r--includes/deferred/Hook/LinksUpdateAfterInsertHook.php22
-rw-r--r--includes/deferred/Hook/LinksUpdateCompleteHook.php21
-rw-r--r--includes/deferred/Hook/LinksUpdateConstructedHook.php19
-rw-r--r--includes/deferred/Hook/LinksUpdateHook.php20
-rw-r--r--includes/diff/Hook/AbortDiffCacheHook.php19
-rw-r--r--includes/diff/Hook/ArticleContentOnDiffHook.php21
-rw-r--r--includes/diff/Hook/DiffRevisionToolsHook.php23
-rw-r--r--includes/diff/Hook/DiffViewHeaderHook.php21
-rw-r--r--includes/diff/Hook/DifferenceEngineAfterLoadNewTextHook.php21
-rw-r--r--includes/diff/Hook/DifferenceEngineLoadTextAfterNewContentIsLoadedHook.php25
-rw-r--r--includes/diff/Hook/DifferenceEngineMarkPatrolledLinkHook.php25
-rw-r--r--includes/diff/Hook/DifferenceEngineMarkPatrolledRCIDHook.php27
-rw-r--r--includes/diff/Hook/DifferenceEngineNewHeaderHook.php40
-rw-r--r--includes/diff/Hook/DifferenceEngineOldHeaderHook.php35
-rw-r--r--includes/diff/Hook/DifferenceEngineOldHeaderNoOldRevHook.php20
-rw-r--r--includes/diff/Hook/DifferenceEngineRenderRevisionAddParserOutputHook.php26
-rw-r--r--includes/diff/Hook/DifferenceEngineRenderRevisionShowFinalPatrolLinkHook.php20
-rw-r--r--includes/diff/Hook/DifferenceEngineShowDiffHook.php20
-rw-r--r--includes/diff/Hook/DifferenceEngineShowDiffPageHook.php20
-rw-r--r--includes/diff/Hook/DifferenceEngineShowDiffPageMaybeShowMissingRevisionHook.php24
-rw-r--r--includes/diff/Hook/DifferenceEngineShowEmptyOldContentHook.php21
-rw-r--r--includes/diff/Hook/NewDifferenceEngineHook.php23
-rw-r--r--includes/exception/Hook/LogExceptionHook.php23
-rw-r--r--includes/export/Hook/ModifyExportQueryHook.php25
-rw-r--r--includes/export/Hook/WikiExporter__dumpStableQueryHook.php23
-rw-r--r--includes/export/Hook/XmlDumpWriterOpenPageHook.php23
-rw-r--r--includes/export/Hook/XmlDumpWriterWriteRevisionHook.php24
-rw-r--r--includes/filerepo/Hook/FileTransformedHook.php22
-rw-r--r--includes/filerepo/Hook/FileUploadHook.php23
-rw-r--r--includes/filerepo/Hook/LocalFilePurgeThumbnailsHook.php20
-rw-r--r--includes/filerepo/Hook/LocalFile__getHistoryHook.php27
-rw-r--r--includes/gallery/Hook/GalleryGetModesHook.php22
-rw-r--r--includes/import/Hook/AfterImportPageHook.php25
-rw-r--r--includes/import/Hook/ImportHandleLogItemXMLTagHook.php21
-rw-r--r--includes/import/Hook/ImportHandlePageXMLTagHook.php21
-rw-r--r--includes/import/Hook/ImportHandleRevisionXMLTagHook.php24
-rw-r--r--includes/import/Hook/ImportHandleToplevelXMLTagHook.php20
-rw-r--r--includes/import/Hook/ImportHandleUploadXMLTagHook.php21
-rw-r--r--includes/installer/Hook/LoadExtensionSchemaUpdatesHook.php19
-rw-r--r--includes/interwiki/Hook/InterwikiLoadPrefixHook.php22
-rw-r--r--includes/jobqueue/jobs/Hook/RecentChangesPurgeRowsHook.php21
-rw-r--r--includes/language/Hook/LanguageGetTranslatedLanguageNamesHook.php20
-rw-r--r--includes/language/Hook/Language__getMessagesFileNameHook.php19
-rw-r--r--includes/linker/Hook/HtmlPageLinkRendererBeginHook.php33
-rw-r--r--includes/linker/Hook/HtmlPageLinkRendererEndHook.php31
-rw-r--r--includes/linker/Hook/LinkBeginHook.php36
-rw-r--r--includes/linker/Hook/LinkEndHook.php30
-rw-r--r--includes/logging/Hook/LogEventsListGetExtraInputsHook.php25
-rw-r--r--includes/logging/Hook/LogEventsListLineEndingHook.php27
-rw-r--r--includes/logging/Hook/LogEventsListShowLogExtractHook.php40
-rw-r--r--includes/logging/Hook/LogLineHook.php32
-rw-r--r--includes/logging/Hook/ManualLogEntryBeforePublishHook.php20
-rw-r--r--includes/mail/Hook/AbortTalkPageEmailNotificationHook.php21
-rw-r--r--includes/mail/Hook/AlternateUserMailerHook.php27
-rw-r--r--includes/mail/Hook/SendWatchlistEmailNotificationHook.php22
-rw-r--r--includes/mail/Hook/UpdateUserMailerFormattedPageStatusHook.php19
-rw-r--r--includes/mail/Hook/UserMailerChangeReturnPathHook.php21
-rw-r--r--includes/mail/Hook/UserMailerSplitToHook.php21
-rw-r--r--includes/mail/Hook/UserMailerTransformContentHook.php25
-rw-r--r--includes/mail/Hook/UserMailerTransformMessageHook.php29
-rw-r--r--includes/media/Hook/BitmapHandlerCheckImageAreaHook.php25
-rw-r--r--includes/media/Hook/BitmapHandlerTransformHook.php25
-rw-r--r--includes/media/Hook/GetExtendedMetadataHook.php31
-rw-r--r--includes/media/Hook/GetMetadataVersionHook.php24
-rw-r--r--includes/media/Hook/ThumbnailBeforeProduceHTMLHook.php24
-rw-r--r--includes/media/Hook/ValidateExtendedMetadataCacheHook.php22
-rw-r--r--includes/page/Hook/ArticleConfirmDeleteHook.php22
-rw-r--r--includes/page/Hook/ArticleDeleteAfterSuccessHook.php20
-rw-r--r--includes/page/Hook/ArticleDeleteCompleteHook.php27
-rw-r--r--includes/page/Hook/ArticleDeleteHook.php28
-rw-r--r--includes/page/Hook/ArticleFromTitleHook.php22
-rw-r--r--includes/page/Hook/ArticlePageDataAfterHook.php20
-rw-r--r--includes/page/Hook/ArticlePageDataBeforeHook.php24
-rw-r--r--includes/page/Hook/ArticleProtectCompleteHook.php22
-rw-r--r--includes/page/Hook/ArticleProtectHook.php22
-rw-r--r--includes/page/Hook/ArticlePurgeHook.php19
-rw-r--r--includes/page/Hook/ArticleRevisionUndeletedHook.php21
-rw-r--r--includes/page/Hook/ArticleRevisionViewCustomHook.php27
-rw-r--r--includes/page/Hook/ArticleRollbackCompleteHook.php24
-rw-r--r--includes/page/Hook/ArticleShowPatrolFooterHook.php21
-rw-r--r--includes/page/Hook/ArticleUndeleteHook.php29
-rw-r--r--includes/page/Hook/ArticleUndeleteLogEntryHook.php21
-rw-r--r--includes/page/Hook/ArticleViewFooterHook.php20
-rw-r--r--includes/page/Hook/ArticleViewHeaderHook.php24
-rw-r--r--includes/page/Hook/ArticleViewRedirectHook.php20
-rw-r--r--includes/page/Hook/Article__MissingArticleConditionsHook.php24
-rw-r--r--includes/page/Hook/BeforeDisplayNoArticleTextHook.php20
-rw-r--r--includes/page/Hook/CategoryAfterPageAddedHook.php20
-rw-r--r--includes/page/Hook/CategoryAfterPageRemovedHook.php21
-rw-r--r--includes/page/Hook/CategoryPageViewHook.php19
-rw-r--r--includes/page/Hook/DisplayOldSubtitleHook.php21
-rw-r--r--includes/page/Hook/ImageOpenShowImageInlineBeforeHook.php21
-rw-r--r--includes/page/Hook/ImagePageAfterImageLinksHook.php21
-rw-r--r--includes/page/Hook/ImagePageFileHistoryLineHook.php22
-rw-r--r--includes/page/Hook/ImagePageFindFileHook.php22
-rw-r--r--includes/page/Hook/ImagePageShowTOCHook.php20
-rw-r--r--includes/page/Hook/IsFileCacheableHook.php19
-rw-r--r--includes/page/Hook/NewRevisionFromEditCompleteHook.php29
-rw-r--r--includes/page/Hook/OpportunisticLinksUpdateHook.php27
-rw-r--r--includes/page/Hook/PageDeletionDataUpdatesHook.php23
-rw-r--r--includes/page/Hook/PageViewUpdatesHook.php22
-rw-r--r--includes/page/Hook/ShowMissingArticleHook.php19
-rw-r--r--includes/page/Hook/WikiPageDeletionUpdatesHook.php25
-rw-r--r--includes/page/Hook/WikiPageFactoryHook.php20
-rw-r--r--includes/parser/Hook/AfterParserFetchFileAndTitleHook.php23
-rw-r--r--includes/parser/Hook/BeforeParserFetchFileAndTitleHook.php25
-rw-r--r--includes/parser/Hook/BeforeParserFetchTemplateAndtitleHook.php24
-rw-r--r--includes/parser/Hook/BeforeParserrenderImageGalleryHook.php20
-rw-r--r--includes/parser/Hook/GetLinkColoursHook.php22
-rw-r--r--includes/parser/Hook/InternalParseBeforeLinksHook.php22
-rw-r--r--includes/parser/Hook/InternalParseBeforeSanitizeHook.php24
-rw-r--r--includes/parser/Hook/IsValidEmailAddrHook.php21
-rw-r--r--includes/parser/Hook/PageRenderingHashHook.php24
-rw-r--r--includes/parser/Hook/ParserAfterParseHook.php22
-rw-r--r--includes/parser/Hook/ParserAfterStripHook.php22
-rw-r--r--includes/parser/Hook/ParserAfterTidyHook.php20
-rw-r--r--includes/parser/Hook/ParserBeforeInternalParseHook.php21
-rw-r--r--includes/parser/Hook/ParserBeforeStripHook.php22
-rw-r--r--includes/parser/Hook/ParserBeforeTidyHook.php20
-rw-r--r--includes/parser/Hook/ParserCacheSaveCompleteHook.php26
-rw-r--r--includes/parser/Hook/ParserClearStateHook.php19
-rw-r--r--includes/parser/Hook/ParserClonedHook.php19
-rw-r--r--includes/parser/Hook/ParserFetchTemplateHook.php23
-rw-r--r--includes/parser/Hook/ParserFirstCallInitHook.php19
-rw-r--r--includes/parser/Hook/ParserGetVariableValueSwitchHook.php27
-rw-r--r--includes/parser/Hook/ParserGetVariableValueTsHook.php21
-rw-r--r--includes/parser/Hook/ParserGetVariableValueVarCacheHook.php21
-rw-r--r--includes/parser/Hook/ParserLimitReportFormatHook.php29
-rw-r--r--includes/parser/Hook/ParserLimitReportPrepareHook.php23
-rw-r--r--includes/parser/Hook/ParserMakeImageParamsHook.php23
-rw-r--r--includes/parser/Hook/ParserOptionsRegisterHook.php27
-rw-r--r--includes/parser/Hook/ParserOutputPostCacheTransformHook.php24
-rw-r--r--includes/parser/Hook/ParserPreSaveTransformCompleteHook.php22
-rw-r--r--includes/parser/Hook/ParserSectionCreateHook.php28
-rw-r--r--includes/parser/Hook/RejectParserCacheValueHook.php26
-rw-r--r--includes/password/Hook/PasswordPoliciesForUserHook.php20
-rw-r--r--includes/preferences/Hook/GetPreferencesHook.php20
-rw-r--r--includes/preferences/Hook/PreferencesFormPreSaveHook.php25
-rw-r--r--includes/rcfeed/Hook/IRCLineURLHook.php22
-rw-r--r--includes/resourceloader/Hook/ResourceLoaderForeignApiModulesHook.php23
-rw-r--r--includes/resourceloader/Hook/ResourceLoaderGetConfigVarsHook.php25
-rw-r--r--includes/resourceloader/Hook/ResourceLoaderJqueryMsgModuleMagicWordsHook.php25
-rw-r--r--includes/resourceloader/Hook/ResourceLoaderSiteModulePagesHook.php20
-rw-r--r--includes/resourceloader/Hook/ResourceLoaderSiteStylesModulePagesHook.php20
-rw-r--r--includes/resourceloader/Hook/ResourceLoaderTestModulesHook.php29
-rw-r--r--includes/revisiondelete/Hook/ArticleRevisionVisibilitySetHook.php27
-rw-r--r--includes/search/Hook/PrefixSearchBackendHook.php28
-rw-r--r--includes/search/Hook/PrefixSearchExtractNamespaceHook.php23
-rw-r--r--includes/search/Hook/SearchAfterNoDirectMatchHook.php22
-rw-r--r--includes/search/Hook/SearchGetNearMatchBeforeHook.php21
-rw-r--r--includes/search/Hook/SearchGetNearMatchCompleteHook.php21
-rw-r--r--includes/search/Hook/SearchGetNearMatchHook.php21
-rw-r--r--includes/search/Hook/SearchIndexFieldsHook.php20
-rw-r--r--includes/search/Hook/SearchResultInitFromTitleHook.php21
-rw-r--r--includes/search/Hook/SearchResultsAugmentHook.php25
-rw-r--r--includes/search/Hook/SearchableNamespacesHook.php19
-rw-r--r--includes/search/Hook/ShowSearchHitHook.php34
-rw-r--r--includes/search/Hook/ShowSearchHitTitleHook.php30
-rw-r--r--includes/search/Hook/SpecialSearchPowerBoxHook.php22
-rw-r--r--includes/search/Hook/SpecialSearchProfileFormHook.php25
-rw-r--r--includes/session/Hook/SessionCheckInfoHook.php26
-rw-r--r--includes/session/Hook/SessionMetadataHook.php22
-rw-r--r--includes/session/Hook/UserSetCookiesHook.php25
-rw-r--r--includes/shell/Hook/WfShellWikiCmdHook.php23
-rw-r--r--includes/skins/Hook/BaseTemplateAfterPortletHook.php22
-rw-r--r--includes/skins/Hook/BaseTemplateToolboxHook.php25
-rw-r--r--includes/skins/Hook/GetNewMessagesAlertHook.php27
-rw-r--r--includes/skins/Hook/PersonalUrlsHook.php23
-rw-r--r--includes/skins/Hook/SidebarBeforeOutputHook.php23
-rw-r--r--includes/skins/Hook/SiteNoticeAfterHook.php21
-rw-r--r--includes/skins/Hook/SiteNoticeBeforeHook.php22
-rw-r--r--includes/skins/Hook/SkinAfterBottomScriptsHook.php21
-rw-r--r--includes/skins/Hook/SkinAfterContentHook.php22
-rw-r--r--includes/skins/Hook/SkinBuildSidebarHook.php21
-rw-r--r--includes/skins/Hook/SkinCopyrightFooterHook.php24
-rw-r--r--includes/skins/Hook/SkinEditSectionLinksHook.php34
-rw-r--r--includes/skins/Hook/SkinGetPoweredByHook.php21
-rw-r--r--includes/skins/Hook/SkinPreloadExistenceHook.php21
-rw-r--r--includes/skins/Hook/SkinSubPageSubtitleHook.php25
-rw-r--r--includes/skins/Hook/SkinTemplateBuildNavUrlsNav_urlsAfterPermalinkHook.php26
-rw-r--r--includes/skins/Hook/SkinTemplateGetLanguageLinkHook.php26
-rw-r--r--includes/skins/Hook/SkinTemplateNavigationHook.php22
-rw-r--r--includes/skins/Hook/SkinTemplateNavigation__SpecialPageHook.php23
-rw-r--r--includes/skins/Hook/SkinTemplateNavigation__UniversalHook.php23
-rw-r--r--includes/skins/Hook/SkinTemplateOutputPageBeforeExecHook.php21
-rw-r--r--includes/skins/Hook/SkinTemplatePreventOtherActiveTabsHook.php20
-rw-r--r--includes/skins/Hook/SkinTemplateTabActionHook.php31
-rw-r--r--includes/skins/Hook/SkinTemplateToolboxEndHook.php24
-rw-r--r--includes/skins/Hook/UndeletePageToolLinksHook.php22
-rw-r--r--includes/specialpage/Hook/AuthChangeFormFieldsHook.php28
-rw-r--r--includes/specialpage/Hook/ChangeAuthenticationDataAuditHook.php21
-rw-r--r--includes/specialpage/Hook/ChangesListSpecialPageQueryHook.php35
-rw-r--r--includes/specialpage/Hook/ChangesListSpecialPageStructuredFiltersHook.php32
-rw-r--r--includes/specialpage/Hook/RedirectSpecialArticleRedirectParamsHook.php21
-rw-r--r--includes/specialpage/Hook/SpecialPageAfterExecuteHook.php20
-rw-r--r--includes/specialpage/Hook/SpecialPageBeforeExecuteHook.php21
-rw-r--r--includes/specialpage/Hook/SpecialPageBeforeFormDisplayHook.php20
-rw-r--r--includes/specialpage/Hook/SpecialPage_initListHook.php21
-rw-r--r--includes/specialpage/Hook/WgQueryPagesHook.php20
-rw-r--r--includes/specials/Hook/AddNewAccountHook.php21
-rw-r--r--includes/specials/Hook/AncientPagesQueryHook.php22
-rw-r--r--includes/specials/Hook/BeforeWelcomeCreationHook.php25
-rw-r--r--includes/specials/Hook/BlockIpCompleteHook.php21
-rw-r--r--includes/specials/Hook/BlockIpHook.php21
-rw-r--r--includes/specials/Hook/BookInformationHook.php20
-rw-r--r--includes/specials/Hook/ChangeUserGroupsHook.php22
-rw-r--r--includes/specials/Hook/ContribsPager__getQueryInfoHook.php21
-rw-r--r--includes/specials/Hook/ContribsPager__reallyDoQueryHook.php27
-rw-r--r--includes/specials/Hook/ContributionsLineEndingHook.php27
-rw-r--r--includes/specials/Hook/ContributionsToolLinksHook.php24
-rw-r--r--includes/specials/Hook/DeletedContribsPager__reallyDoQueryHook.php28
-rw-r--r--includes/specials/Hook/DeletedContributionsLineEndingHook.php29
-rw-r--r--includes/specials/Hook/EmailUserCCHook.php22
-rw-r--r--includes/specials/Hook/EmailUserCompleteHook.php22
-rw-r--r--includes/specials/Hook/EmailUserFormHook.php19
-rw-r--r--includes/specials/Hook/EmailUserHook.php24
-rw-r--r--includes/specials/Hook/EmailUserPermissionsErrorsHook.php23
-rw-r--r--includes/specials/Hook/ExtensionTypesHook.php20
-rw-r--r--includes/specials/Hook/FileUndeleteCompleteHook.php22
-rw-r--r--includes/specials/Hook/GetLogTypesOnUserHook.php19
-rw-r--r--includes/specials/Hook/ImportLogInterwikiLinkHook.php21
-rw-r--r--includes/specials/Hook/ImportSourcesHook.php21
-rw-r--r--includes/specials/Hook/LanguageSelectorHook.php20
-rw-r--r--includes/specials/Hook/LoginFormValidErrorMessagesHook.php22
-rw-r--r--includes/specials/Hook/LonelyPagesQueryHook.php22
-rw-r--r--includes/specials/Hook/NewPagesLineEndingHook.php26
-rw-r--r--includes/specials/Hook/OtherAutoblockLogLinkHook.php20
-rw-r--r--includes/specials/Hook/OtherBlockLogLinkHook.php21
-rw-r--r--includes/specials/Hook/PostLoginRedirectHook.php26
-rw-r--r--includes/specials/Hook/PreferencesGetLegendHook.php23
-rw-r--r--includes/specials/Hook/PrefsEmailAuditHook.php21
-rw-r--r--includes/specials/Hook/RandomPageQueryHook.php22
-rw-r--r--includes/specials/Hook/ShortPagesQueryHook.php23
-rw-r--r--includes/specials/Hook/SoftwareInfoHook.php21
-rw-r--r--includes/specials/Hook/SpecialBlockModifyFormFieldsHook.php20
-rw-r--r--includes/specials/Hook/SpecialContributionsBeforeMainOutputHook.php21
-rw-r--r--includes/specials/Hook/SpecialContributions__formatRow__flagsHook.php25
-rw-r--r--includes/specials/Hook/SpecialContributions__getForm__filtersHook.php22
-rw-r--r--includes/specials/Hook/SpecialListusersDefaultQueryHook.php21
-rw-r--r--includes/specials/Hook/SpecialListusersFormatRowHook.php21
-rw-r--r--includes/specials/Hook/SpecialListusersHeaderFormHook.php21
-rw-r--r--includes/specials/Hook/SpecialListusersHeaderHook.php21
-rw-r--r--includes/specials/Hook/SpecialListusersQueryInfoHook.php21
-rw-r--r--includes/specials/Hook/SpecialLogAddLogSearchRelationsHook.php21
-rw-r--r--includes/specials/Hook/SpecialMovepageAfterMoveHook.php21
-rw-r--r--includes/specials/Hook/SpecialMuteModifyFormFieldsHook.php20
-rw-r--r--includes/specials/Hook/SpecialMuteSubmitHook.php19
-rw-r--r--includes/specials/Hook/SpecialNewPagesFiltersHook.php22
-rw-r--r--includes/specials/Hook/SpecialNewpagesConditionsHook.php27
-rw-r--r--includes/specials/Hook/SpecialRandomGetRandomTitleHook.php27
-rw-r--r--includes/specials/Hook/SpecialRecentChangesPanelHook.php21
-rw-r--r--includes/specials/Hook/SpecialResetTokensTokensHook.php24
-rw-r--r--includes/specials/Hook/SpecialSearchCreateLinkHook.php21
-rw-r--r--includes/specials/Hook/SpecialSearchGoResultHook.php25
-rw-r--r--includes/specials/Hook/SpecialSearchNogomatchHook.php22
-rw-r--r--includes/specials/Hook/SpecialSearchProfilesHook.php19
-rw-r--r--includes/specials/Hook/SpecialSearchResultsAppendHook.php22
-rw-r--r--includes/specials/Hook/SpecialSearchResultsHook.php21
-rw-r--r--includes/specials/Hook/SpecialSearchResultsPrependHook.php24
-rw-r--r--includes/specials/Hook/SpecialSearchSetupEngineHook.php21
-rw-r--r--includes/specials/Hook/SpecialStatsAddExtraHook.php26
-rw-r--r--includes/specials/Hook/SpecialTrackingCategories__generateCatLinkHook.php25
-rw-r--r--includes/specials/Hook/SpecialTrackingCategories__preprocessHook.php25
-rw-r--r--includes/specials/Hook/SpecialUploadCompleteHook.php20
-rw-r--r--includes/specials/Hook/SpecialVersionVersionUrlHook.php20
-rw-r--r--includes/specials/Hook/SpecialWatchlistGetNonRevisionTypesHook.php21
-rw-r--r--includes/specials/Hook/UnblockUserCompleteHook.php20
-rw-r--r--includes/specials/Hook/UnblockUserHook.php21
-rw-r--r--includes/specials/Hook/UndeleteForm__showHistoryHook.php22
-rw-r--r--includes/specials/Hook/UndeleteForm__showRevisionHook.php22
-rw-r--r--includes/specials/Hook/UndeleteForm__undeleteHook.php24
-rw-r--r--includes/specials/Hook/UndeleteShowRevisionHook.php20
-rw-r--r--includes/specials/Hook/UploadFormInitDescriptorHook.php20
-rw-r--r--includes/specials/Hook/UploadFormSourceDescriptorsHook.php24
-rw-r--r--includes/specials/Hook/UploadForm_BeforeProcessingHook.php24
-rw-r--r--includes/specials/Hook/UploadForm_getInitialPageTextHook.php23
-rw-r--r--includes/specials/Hook/UploadForm_initialHook.php22
-rw-r--r--includes/specials/Hook/UserLoginCompleteHook.php25
-rw-r--r--includes/specials/Hook/UserLogoutCompleteHook.php21
-rw-r--r--includes/specials/Hook/UsersPagerDoBatchLookupsHook.php27
-rw-r--r--includes/specials/Hook/WantedPages__getQueryInfoHook.php22
-rw-r--r--includes/specials/Hook/WatchlistEditorBeforeFormRenderHook.php21
-rw-r--r--includes/specials/Hook/WatchlistEditorBuildRemoveLineHook.php26
-rw-r--r--includes/specials/Hook/WhatLinksHerePropsHook.php22
-rw-r--r--includes/title/Hook/CanonicalNamespacesHook.php28
-rw-r--r--includes/title/Hook/NamespaceIsMovableHook.php23
-rw-r--r--includes/upload/Hook/IsUploadAllowedFromUrlHook.php20
-rw-r--r--includes/upload/Hook/UploadCompleteHook.php20
-rw-r--r--includes/upload/Hook/UploadCreateFromRequestHook.php20
-rw-r--r--includes/upload/Hook/UploadStashFileHook.php31
-rw-r--r--includes/upload/Hook/UploadVerifyFileHook.php25
-rw-r--r--includes/upload/Hook/UploadVerifyUploadHook.php34
-rw-r--r--includes/user/Hook/ConfirmEmailCompleteHook.php20
-rw-r--r--includes/user/Hook/EmailConfirmedHook.php22
-rw-r--r--includes/user/Hook/InvalidateEmailCompleteHook.php20
-rw-r--r--includes/user/Hook/IsValidPasswordHook.php21
-rw-r--r--includes/user/Hook/PingLimiterHook.php24
-rw-r--r--includes/user/Hook/SpecialPasswordResetOnSubmitHook.php24
-rw-r--r--includes/user/Hook/UserAddGroupHook.php23
-rw-r--r--includes/user/Hook/UserArrayFromResultHook.php21
-rw-r--r--includes/user/Hook/UserCanSendEmailHook.php20
-rw-r--r--includes/user/Hook/UserClearNewTalkNotificationHook.php21
-rw-r--r--includes/user/Hook/UserEffectiveGroupsHook.php20
-rw-r--r--includes/user/Hook/UserGetDefaultOptionsHook.php23
-rw-r--r--includes/user/Hook/UserGetEmailAuthenticationTimestampHook.php22
-rw-r--r--includes/user/Hook/UserGetEmailHook.php20
-rw-r--r--includes/user/Hook/UserGetReservedNamesHook.php19
-rw-r--r--includes/user/Hook/UserGroupsChangedHook.php30
-rw-r--r--includes/user/Hook/UserIsBlockedGloballyHook.php22
-rw-r--r--includes/user/Hook/UserIsBotHook.php20
-rw-r--r--includes/user/Hook/UserIsLockedHook.php20
-rw-r--r--includes/user/Hook/UserLoadAfterLoadFromSessionHook.php20
-rw-r--r--includes/user/Hook/UserLoadDefaultsHook.php20
-rw-r--r--includes/user/Hook/UserLoadFromDatabaseHook.php20
-rw-r--r--includes/user/Hook/UserLoadOptionsHook.php21
-rw-r--r--includes/user/Hook/UserLogoutHook.php19
-rw-r--r--includes/user/Hook/UserRemoveGroupHook.php21
-rw-r--r--includes/user/Hook/UserRequiresHTTPSHook.php21
-rw-r--r--includes/user/Hook/UserResetAllOptionsHook.php28
-rw-r--r--includes/user/Hook/UserRetrieveNewTalksHook.php21
-rw-r--r--includes/user/Hook/UserSaveOptionsHook.php24
-rw-r--r--includes/user/Hook/UserSaveSettingsHook.php21
-rw-r--r--includes/user/Hook/UserSendConfirmationMailHook.php33
-rw-r--r--includes/user/Hook/UserSetEmailAuthenticationTimestampHook.php22
-rw-r--r--includes/user/Hook/UserSetEmailHook.php20
-rw-r--r--includes/user/Hook/User__mailPasswordInternalHook.php23
-rw-r--r--includes/watcheditem/Hook/BeforeResetNotificationTimestampHook.php26
-rw-r--r--includes/watcheditem/Hook/WatchedItemQueryServiceExtensionsHook.php22
564 files changed, 13068 insertions, 0 deletions
diff --git a/includes/Hook/AfterBuildFeedLinksHook.php b/includes/Hook/AfterBuildFeedLinksHook.php
new file mode 100644
index 000000000000..7528a783230f
--- /dev/null
+++ b/includes/Hook/AfterBuildFeedLinksHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AfterBuildFeedLinksHook {
+ /**
+ * Executed in OutputPage.php after all feed links (atom,
+ * rss,...) are created. Can be used to omit specific feeds from being outputted.
+ * You must not use this hook to add feeds, use OutputPage::addFeedLink() instead.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$feedLinks Array of created feed links
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAfterBuildFeedLinks( &$feedLinks );
+}
diff --git a/includes/Hook/AfterFinalPageOutputHook.php b/includes/Hook/AfterFinalPageOutputHook.php
new file mode 100644
index 000000000000..a912dc1ee0fd
--- /dev/null
+++ b/includes/Hook/AfterFinalPageOutputHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AfterFinalPageOutputHook {
+ /**
+ * Nearly at the end of OutputPage::output() but
+ * before OutputPage::sendCacheControl() and final ob_end_flush() which
+ * will send the buffered output to the client. This allows for last-minute
+ * modification of the output within the buffer by using ob_get_clean().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $output The OutputPage object where output() was called
+ * @return bool|void This hook must not abort, it must return true or null.
+ */
+ public function onAfterFinalPageOutput( $output );
+}
diff --git a/includes/Hook/AlternateEditHook.php b/includes/Hook/AlternateEditHook.php
new file mode 100644
index 000000000000..86aab771b73a
--- /dev/null
+++ b/includes/Hook/AlternateEditHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AlternateEditHook {
+ /**
+ * Before checking if a user can edit a page and before showing
+ * the edit form ( EditPage::edit() ). This is triggered on &action=edit.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editPage the EditPage object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAlternateEdit( $editPage );
+}
diff --git a/includes/Hook/AlternateEditPreviewHook.php b/includes/Hook/AlternateEditPreviewHook.php
new file mode 100644
index 000000000000..306ad55b6c14
--- /dev/null
+++ b/includes/Hook/AlternateEditPreviewHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AlternateEditPreviewHook {
+ /**
+ * Before generating the preview of the page when editing
+ * ( EditPage::getPreviewText() ).
+ * Return false and set $previewHTML and $parserOutput to output custom page
+ * preview HTML.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editPage the EditPage object
+ * @param ?mixed &$content the Content object for the text field from the edit page
+ * @param ?mixed &$previewHTML Text to be placed into the page for the preview
+ * @param ?mixed &$parserOutput the ParserOutput object for the preview
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAlternateEditPreview( $editPage, &$content, &$previewHTML,
+ &$parserOutput
+ );
+}
diff --git a/includes/Hook/ApiBeforeMainHook.php b/includes/Hook/ApiBeforeMainHook.php
new file mode 100644
index 000000000000..493f89f31b1e
--- /dev/null
+++ b/includes/Hook/ApiBeforeMainHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiBeforeMainHook {
+ /**
+ * Before calling ApiMain's execute() method in api.php.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$main ApiMain object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiBeforeMain( &$main );
+}
diff --git a/includes/Hook/ArticleMergeCompleteHook.php b/includes/Hook/ArticleMergeCompleteHook.php
new file mode 100644
index 000000000000..c22ddf58d123
--- /dev/null
+++ b/includes/Hook/ArticleMergeCompleteHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleMergeCompleteHook {
+ /**
+ * After merging to article using Special:Mergehistory.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $targetTitle target title (object)
+ * @param ?mixed $destTitle destination title (object)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleMergeComplete( $targetTitle, $destTitle );
+}
diff --git a/includes/Hook/ArticleUpdateBeforeRedirectHook.php b/includes/Hook/ArticleUpdateBeforeRedirectHook.php
new file mode 100644
index 000000000000..2a4a5c582906
--- /dev/null
+++ b/includes/Hook/ArticleUpdateBeforeRedirectHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleUpdateBeforeRedirectHook {
+ /**
+ * After a page is updated (usually on save), before
+ * the user is redirected back to the page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article the article
+ * @param ?mixed &$sectionanchor The section anchor link (e.g. "#overview" )
+ * @param ?mixed &$extraq Extra query parameters which can be added via hooked functions
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleUpdateBeforeRedirect( $article, &$sectionanchor,
+ &$extraq
+ );
+}
diff --git a/includes/Hook/AutopromoteConditionHook.php b/includes/Hook/AutopromoteConditionHook.php
new file mode 100644
index 000000000000..7983ddaf561c
--- /dev/null
+++ b/includes/Hook/AutopromoteConditionHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AutopromoteConditionHook {
+ /**
+ * Check autopromote condition for user.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $type condition type
+ * @param ?mixed $args arguments
+ * @param ?mixed $user user
+ * @param ?mixed &$result result of checking autopromote condition
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAutopromoteCondition( $type, $args, $user, &$result );
+}
diff --git a/includes/Hook/BadImageHook.php b/includes/Hook/BadImageHook.php
new file mode 100644
index 000000000000..35fc6310f7d5
--- /dev/null
+++ b/includes/Hook/BadImageHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BadImageHook {
+ /**
+ * When checking against the bad image list. Change $bad and return
+ * false to override. If an image is "bad", it is not rendered inline in wiki
+ * pages or galleries in category pages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $name Image name being checked
+ * @param ?mixed &$bad Whether or not the image is "bad"
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBadImage( $name, &$bad );
+}
diff --git a/includes/Hook/BeforeHttpsRedirectHook.php b/includes/Hook/BeforeHttpsRedirectHook.php
new file mode 100644
index 000000000000..71dfc26d6651
--- /dev/null
+++ b/includes/Hook/BeforeHttpsRedirectHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BeforeHttpsRedirectHook {
+ /**
+ * Prior to forcing HTTP->HTTPS redirect. Gives a chance to
+ * override how the redirect is output by modifying, or by returning false, and
+ * letting standard HTTP rendering take place.
+ * ATTENTION: This hook is likely to be removed soon due to overall design of the
+ * system.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $context IContextSource object
+ * @param ?mixed &$redirect string URL, modifiable
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBeforeHttpsRedirect( $context, &$redirect );
+}
diff --git a/includes/Hook/BeforeInitializeHook.php b/includes/Hook/BeforeInitializeHook.php
new file mode 100644
index 000000000000..664c14545d9a
--- /dev/null
+++ b/includes/Hook/BeforeInitializeHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BeforeInitializeHook {
+ /**
+ * Before anything is initialized in
+ * MediaWiki::performRequest().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title being used for request
+ * @param ?mixed $unused null
+ * @param ?mixed $output OutputPage object
+ * @param ?mixed $user User
+ * @param ?mixed $request WebRequest object
+ * @param ?mixed $mediaWiki Mediawiki object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBeforeInitialize( $title, $unused, $output, $user, $request,
+ $mediaWiki
+ );
+}
diff --git a/includes/Hook/BeforePageDisplayHook.php b/includes/Hook/BeforePageDisplayHook.php
new file mode 100644
index 000000000000..00bb91edd7bd
--- /dev/null
+++ b/includes/Hook/BeforePageDisplayHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BeforePageDisplayHook {
+ /**
+ * Prior to outputting a page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $out OutputPage object
+ * @param ?mixed $skin Skin object
+ * @return bool|void This hook must not abort, it must return true or null.
+ */
+ public function onBeforePageDisplay( $out, $skin );
+}
diff --git a/includes/Hook/BeforePageRedirectHook.php b/includes/Hook/BeforePageRedirectHook.php
new file mode 100644
index 000000000000..a819052a4b9d
--- /dev/null
+++ b/includes/Hook/BeforePageRedirectHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BeforePageRedirectHook {
+ /**
+ * Prior to sending an HTTP redirect. Gives a chance to
+ * override how the redirect is output by modifying, or by returning false and
+ * taking over the output.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $out OutputPage object
+ * @param ?mixed &$redirect URL, modifiable
+ * @param ?mixed &$code HTTP code (eg '301' or '302'), modifiable
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBeforePageRedirect( $out, &$redirect, &$code );
+}
diff --git a/includes/Hook/CanIPUseHTTPSHook.php b/includes/Hook/CanIPUseHTTPSHook.php
new file mode 100644
index 000000000000..a4bbe9fd168a
--- /dev/null
+++ b/includes/Hook/CanIPUseHTTPSHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface CanIPUseHTTPSHook {
+ /**
+ * Determine whether the client at a given source IP is likely
+ * to be able to access the wiki via HTTPS.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $ip The IP address in human-readable form
+ * @param ?mixed &$canDo This reference should be set to false if the client may not be able
+ * to use HTTPS
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onCanIPUseHTTPS( $ip, &$canDo );
+}
diff --git a/includes/Hook/CategoryViewer__doCategoryQueryHook.php b/includes/Hook/CategoryViewer__doCategoryQueryHook.php
new file mode 100644
index 000000000000..fe126f4b0c5c
--- /dev/null
+++ b/includes/Hook/CategoryViewer__doCategoryQueryHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface CategoryViewer__doCategoryQueryHook {
+ /**
+ * After querying for pages to be displayed
+ * in a Category page. Gives extensions the opportunity to batch load any
+ * related data about the pages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $type The category type. Either 'page', 'file' or 'subcat'
+ * @param ?mixed $res Query result from Wikimedia\Rdbms\IDatabase::select()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onCategoryViewer__doCategoryQuery( $type, $res );
+}
diff --git a/includes/Hook/CategoryViewer__generateLinkHook.php b/includes/Hook/CategoryViewer__generateLinkHook.php
new file mode 100644
index 000000000000..1e24969d6d7f
--- /dev/null
+++ b/includes/Hook/CategoryViewer__generateLinkHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface CategoryViewer__generateLinkHook {
+ /**
+ * Before generating an output link allow
+ * extensions opportunity to generate a more specific or relevant link.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $type The category type. Either 'page', 'img' or 'subcat'
+ * @param ?mixed $title Title object for the categorized page
+ * @param ?mixed $html Requested html content of anchor
+ * @param ?mixed &$link Returned value. When set to a non-null value by a hook subscriber
+ * this value will be used as the anchor instead of Linker::link
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onCategoryViewer__generateLink( $type, $title, $html, &$link );
+}
diff --git a/includes/Hook/ContentSecurityPolicyDefaultSourceHook.php b/includes/Hook/ContentSecurityPolicyDefaultSourceHook.php
new file mode 100644
index 000000000000..a302fbdca4fb
--- /dev/null
+++ b/includes/Hook/ContentSecurityPolicyDefaultSourceHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContentSecurityPolicyDefaultSourceHook {
+ /**
+ * Modify the allowed CSP load sources. This
+ * affects all directives except for the script directive. If you want to add a
+ * script source, see ContentSecurityPolicyScriptSource hook.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$defaultSrc Array of Content-Security-Policy allowed sources
+ * @param ?mixed $policyConfig Current configuration for the Content-Security-Policy header
+ * @param ?mixed $mode ContentSecurityPolicy::REPORT_ONLY_MODE or
+ * ContentSecurityPolicy::FULL_MODE depending on type of header
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContentSecurityPolicyDefaultSource( &$defaultSrc,
+ $policyConfig, $mode
+ );
+}
diff --git a/includes/Hook/ContentSecurityPolicyDirectivesHook.php b/includes/Hook/ContentSecurityPolicyDirectivesHook.php
new file mode 100644
index 000000000000..f013c2c524a7
--- /dev/null
+++ b/includes/Hook/ContentSecurityPolicyDirectivesHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContentSecurityPolicyDirectivesHook {
+ /**
+ * Modify the content security policy
+ * directives. Use this only if ContentSecurityPolicyDefaultSource and
+ * ContentSecurityPolicyScriptSource do not meet your needs.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$directives Array of CSP directives
+ * @param ?mixed $policyConfig Current configuration for the CSP header
+ * @param ?mixed $mode ContentSecurityPolicy::REPORT_ONLY_MODE or
+ * ContentSecurityPolicy::FULL_MODE depending on type of header
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContentSecurityPolicyDirectives( &$directives, $policyConfig,
+ $mode
+ );
+}
diff --git a/includes/Hook/ContentSecurityPolicyScriptSourceHook.php b/includes/Hook/ContentSecurityPolicyScriptSourceHook.php
new file mode 100644
index 000000000000..3a1d803497aa
--- /dev/null
+++ b/includes/Hook/ContentSecurityPolicyScriptSourceHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContentSecurityPolicyScriptSourceHook {
+ /**
+ * Modify the allowed CSP script sources.
+ * Note that you also have to use ContentSecurityPolicyDefaultSource if you
+ * want non-script sources to be loaded from
+ * whatever you add.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$scriptSrc Array of CSP directives
+ * @param ?mixed $policyConfig Current configuration for the CSP header
+ * @param ?mixed $mode ContentSecurityPolicy::REPORT_ONLY_MODE or
+ * ContentSecurityPolicy::FULL_MODE depending on type of header
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContentSecurityPolicyScriptSource( &$scriptSrc,
+ $policyConfig, $mode
+ );
+}
diff --git a/includes/Hook/DeleteUnknownPreferencesHook.php b/includes/Hook/DeleteUnknownPreferencesHook.php
new file mode 100644
index 000000000000..2447d9c83c25
--- /dev/null
+++ b/includes/Hook/DeleteUnknownPreferencesHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DeleteUnknownPreferencesHook {
+ /**
+ * Called by the cleanupPreferences.php maintenance
+ * script to build a WHERE clause with which to delete preferences that are not
+ * known about. This hook is used by extensions that have dynamically-named
+ * preferences that should not be deleted in the usual cleanup process. For
+ * example, the Gadgets extension creates preferences prefixed with 'gadget-', and
+ * so anything with that prefix is excluded from the deletion.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$where An array that will be passed as the $cond parameter to
+ * IDatabase::select() to determine what will be deleted from the user_properties
+ * table.
+ * @param ?mixed $db The IDatabase object, useful for accessing $db->buildLike() etc.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDeleteUnknownPreferences( &$where, $db );
+}
diff --git a/includes/Hook/EditFilterHook.php b/includes/Hook/EditFilterHook.php
new file mode 100644
index 000000000000..cac1b7887688
--- /dev/null
+++ b/includes/Hook/EditFilterHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditFilterHook {
+ /**
+ * Perform checks on an edit
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editor EditPage instance (object). The edit form (see includes/EditPage.php)
+ * @param ?mixed $text Contents of the edit box
+ * @param ?mixed $section Section being edited
+ * @param ?mixed &$error Error message to return
+ * @param ?mixed $summary Edit summary for page
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditFilter( $editor, $text, $section, &$error, $summary );
+}
diff --git a/includes/Hook/EditFilterMergedContentHook.php b/includes/Hook/EditFilterMergedContentHook.php
new file mode 100644
index 000000000000..df2ef95a287d
--- /dev/null
+++ b/includes/Hook/EditFilterMergedContentHook.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditFilterMergedContentHook {
+ /**
+ * Post-section-merge edit filter.
+ * This may be triggered by the EditPage or any other facility that modifies page
+ * content. Use the $status object to indicate whether the edit should be allowed,
+ * and to provide a reason for disallowing it. Return false to abort the edit, and
+ * true to continue. Returning true if $status->isOK() returns false means "don't
+ * save but continue user interaction", e.g. show the edit form.
+ * $status->apiHookResult can be set to an array to be returned by api.php
+ * action=edit. This is used to deliver captchas.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $context object implementing the IContextSource interface.
+ * @param ?mixed $content content of the edit box, as a Content object.
+ * @param ?mixed $status Status object to represent errors, etc.
+ * @param ?mixed $summary Edit summary for page
+ * @param ?mixed $user the User object representing the user whois performing the edit.
+ * @param ?mixed $minoredit whether the edit was marked as minor by the user.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditFilterMergedContent( $context, $content, $status,
+ $summary, $user, $minoredit
+ );
+}
diff --git a/includes/Hook/EditFormInitialTextHook.php b/includes/Hook/EditFormInitialTextHook.php
new file mode 100644
index 000000000000..d27251f0acf4
--- /dev/null
+++ b/includes/Hook/EditFormInitialTextHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditFormInitialTextHook {
+ /**
+ * Allows modifying the edit form when editing existing
+ * pages
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editPage EditPage object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditFormInitialText( $editPage );
+}
diff --git a/includes/Hook/EditFormPreloadTextHook.php b/includes/Hook/EditFormPreloadTextHook.php
new file mode 100644
index 000000000000..24772e5537e0
--- /dev/null
+++ b/includes/Hook/EditFormPreloadTextHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditFormPreloadTextHook {
+ /**
+ * Allows population of the edit form when creating
+ * new pages
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$text Text to preload with
+ * @param ?mixed $title Title object representing the page being created
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditFormPreloadText( &$text, $title );
+}
diff --git a/includes/Hook/EditPageBeforeConflictDiffHook.php b/includes/Hook/EditPageBeforeConflictDiffHook.php
new file mode 100644
index 000000000000..92d18ae8bb19
--- /dev/null
+++ b/includes/Hook/EditPageBeforeConflictDiffHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPageBeforeConflictDiffHook {
+ /**
+ * allows modifying the EditPage object and output
+ * when there's an edit conflict. Return false to halt normal diff output; in
+ * this case you're responsible for computing and outputting the entire "conflict"
+ * part, i.e., the "difference between revisions" and "your text" headers and
+ * sections.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editor EditPage instance
+ * @param ?mixed $out OutputPage instance
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPageBeforeConflictDiff( $editor, $out );
+}
diff --git a/includes/Hook/EditPageBeforeEditButtonsHook.php b/includes/Hook/EditPageBeforeEditButtonsHook.php
new file mode 100644
index 000000000000..6086275428be
--- /dev/null
+++ b/includes/Hook/EditPageBeforeEditButtonsHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPageBeforeEditButtonsHook {
+ /**
+ * Allows modifying the edit buttons below the
+ * textarea in the edit form.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editpage The current EditPage object
+ * @param ?mixed &$buttons Array of edit buttons "Save", "Preview", "Live", and "Diff"
+ * @param ?mixed &$tabindex HTML tabindex of the last edit check/button
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPageBeforeEditButtons( $editpage, &$buttons, &$tabindex );
+}
diff --git a/includes/Hook/EditPageBeforeEditToolbarHook.php b/includes/Hook/EditPageBeforeEditToolbarHook.php
new file mode 100644
index 000000000000..fc9724706ce9
--- /dev/null
+++ b/includes/Hook/EditPageBeforeEditToolbarHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPageBeforeEditToolbarHook {
+ /**
+ * Allow adding an edit toolbar above the textarea in
+ * the edit form.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$toolbar The toolbar HTML, initially an empty `<div id="toolbar"></div>`
+ * Hook subscribers can return false to have no toolbar HTML be loaded.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPageBeforeEditToolbar( &$toolbar );
+}
diff --git a/includes/Hook/EditPageCopyrightWarningHook.php b/includes/Hook/EditPageCopyrightWarningHook.php
new file mode 100644
index 000000000000..c4a7a2e0bed8
--- /dev/null
+++ b/includes/Hook/EditPageCopyrightWarningHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPageCopyrightWarningHook {
+ /**
+ * Allow for site and per-namespace customization of
+ * contribution/copyright notice.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title title of page being edited
+ * @param ?mixed &$msg localization message name, overridable. Default is either
+ * 'copyrightwarning' or 'copyrightwarning2'.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPageCopyrightWarning( $title, &$msg );
+}
diff --git a/includes/Hook/EditPageGetCheckboxesDefinitionHook.php b/includes/Hook/EditPageGetCheckboxesDefinitionHook.php
new file mode 100644
index 000000000000..217638bb6cd0
--- /dev/null
+++ b/includes/Hook/EditPageGetCheckboxesDefinitionHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPageGetCheckboxesDefinitionHook {
+ /**
+ * Allows modifying the edit checkboxes
+ * below the textarea in the edit form.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editpage The current EditPage object
+ * @param ?mixed &$checkboxes Array of checkbox definitions. See
+ * EditPage::getCheckboxesDefinition() for the format.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPageGetCheckboxesDefinition( $editpage, &$checkboxes );
+}
diff --git a/includes/Hook/EditPageGetDiffContentHook.php b/includes/Hook/EditPageGetDiffContentHook.php
new file mode 100644
index 000000000000..d785aefb510b
--- /dev/null
+++ b/includes/Hook/EditPageGetDiffContentHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPageGetDiffContentHook {
+ /**
+ * Allow modifying the wikitext that will be used in
+ * "Show changes". Note that it is preferable to implement diff handling for
+ * different data types using the ContentHandler facility.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editPage EditPage object
+ * @param ?mixed &$newtext wikitext that will be used as "your version"
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPageGetDiffContent( $editPage, &$newtext );
+}
diff --git a/includes/Hook/EditPageGetPreviewContentHook.php b/includes/Hook/EditPageGetPreviewContentHook.php
new file mode 100644
index 000000000000..af75aa66df00
--- /dev/null
+++ b/includes/Hook/EditPageGetPreviewContentHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPageGetPreviewContentHook {
+ /**
+ * Allow modifying the wikitext that will be
+ * previewed. Note that it is preferable to implement previews for different data
+ * types using the ContentHandler facility.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editPage EditPage object
+ * @param ?mixed &$content Content object to be previewed (may be replaced by hook function)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPageGetPreviewContent( $editPage, &$content );
+}
diff --git a/includes/Hook/EditPageNoSuchSectionHook.php b/includes/Hook/EditPageNoSuchSectionHook.php
new file mode 100644
index 000000000000..f7abcfb3ebd6
--- /dev/null
+++ b/includes/Hook/EditPageNoSuchSectionHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPageNoSuchSectionHook {
+ /**
+ * When a section edit request is given for an
+ * non-existent section
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editpage The current EditPage object
+ * @param ?mixed &$res the HTML of the error text
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPageNoSuchSection( $editpage, &$res );
+}
diff --git a/includes/Hook/EditPageTosSummaryHook.php b/includes/Hook/EditPageTosSummaryHook.php
new file mode 100644
index 000000000000..4fe5b38e7fdb
--- /dev/null
+++ b/includes/Hook/EditPageTosSummaryHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPageTosSummaryHook {
+ /**
+ * Give a chance for site and per-namespace customizations
+ * of terms of service summary link that might exist separately from the copyright
+ * notice.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title title of page being edited
+ * @param ?mixed &$msg localization message name, overridable. Default is 'editpage-tos-summary'
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPageTosSummary( $title, &$msg );
+}
diff --git a/includes/Hook/EditPage__attemptSaveHook.php b/includes/Hook/EditPage__attemptSaveHook.php
new file mode 100644
index 000000000000..52d280106717
--- /dev/null
+++ b/includes/Hook/EditPage__attemptSaveHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPage__attemptSaveHook {
+ /**
+ * Called before an article is
+ * saved, that is before WikiPage::doEditContent() is called
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editpage_Obj the current EditPage object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPage__attemptSave( $editpage_Obj );
+}
diff --git a/includes/Hook/EditPage__attemptSave_afterHook.php b/includes/Hook/EditPage__attemptSave_afterHook.php
new file mode 100644
index 000000000000..64248bf8a7b0
--- /dev/null
+++ b/includes/Hook/EditPage__attemptSave_afterHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPage__attemptSave_afterHook {
+ /**
+ * Called after an article save attempt
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editpage_Obj the current EditPage object
+ * @param ?mixed $status the resulting Status object
+ * @param ?mixed $resultDetails Result details array
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPage__attemptSave_after( $editpage_Obj, $status,
+ $resultDetails
+ );
+}
diff --git a/includes/Hook/EditPage__importFormDataHook.php b/includes/Hook/EditPage__importFormDataHook.php
new file mode 100644
index 000000000000..5c2df02eade1
--- /dev/null
+++ b/includes/Hook/EditPage__importFormDataHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPage__importFormDataHook {
+ /**
+ * allow extensions to read additional data
+ * posted in the form
+ * Return value is ignored (should always return true)
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editpage EditPage instance
+ * @param ?mixed $request Webrequest
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPage__importFormData( $editpage, $request );
+}
diff --git a/includes/Hook/EditPage__showEditForm_fieldsHook.php b/includes/Hook/EditPage__showEditForm_fieldsHook.php
new file mode 100644
index 000000000000..078a455d554e
--- /dev/null
+++ b/includes/Hook/EditPage__showEditForm_fieldsHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPage__showEditForm_fieldsHook {
+ /**
+ * allows injection of form field into edit form
+ * Return value is ignored (should always return true)
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editor the EditPage instance for reference
+ * @param ?mixed $out an OutputPage instance to write to
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPage__showEditForm_fields( $editor, $out );
+}
diff --git a/includes/Hook/EditPage__showEditForm_initialHook.php b/includes/Hook/EditPage__showEditForm_initialHook.php
new file mode 100644
index 000000000000..66aa910a3216
--- /dev/null
+++ b/includes/Hook/EditPage__showEditForm_initialHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPage__showEditForm_initialHook {
+ /**
+ * before showing the edit form
+ * Return false to halt editing; you'll need to handle error messages, etc.
+ * yourself. Alternatively, modifying $error and returning true will cause the
+ * contents of $error to be echoed at the top of the edit form as wikitext.
+ * Return true without altering $error to allow the edit to proceed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editor EditPage instance (object)
+ * @param ?mixed $out an OutputPage instance to write to
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPage__showEditForm_initial( $editor, $out );
+}
diff --git a/includes/Hook/EditPage__showReadOnlyForm_initialHook.php b/includes/Hook/EditPage__showReadOnlyForm_initialHook.php
new file mode 100644
index 000000000000..d9160f67c571
--- /dev/null
+++ b/includes/Hook/EditPage__showReadOnlyForm_initialHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPage__showReadOnlyForm_initialHook {
+ /**
+ * similar to EditPage::showEditForm:initial
+ * but for the read-only 'view source' variant of the edit form.
+ * Return value is ignored (should always return true)
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editor EditPage instance (object)
+ * @param ?mixed $out an OutputPage instance to write to
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPage__showReadOnlyForm_initial( $editor, $out );
+}
diff --git a/includes/Hook/EditPage__showStandardInputs_optionsHook.php b/includes/Hook/EditPage__showStandardInputs_optionsHook.php
new file mode 100644
index 000000000000..e4002860db38
--- /dev/null
+++ b/includes/Hook/EditPage__showStandardInputs_optionsHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EditPage__showStandardInputs_optionsHook {
+ /**
+ * allows injection of form fields into
+ * the editOptions area
+ * Return value is ignored (should always be true)
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editor EditPage instance (object)
+ * @param ?mixed $out an OutputPage instance to write to
+ * @param ?mixed &$tabindex HTML tabindex of the last edit check/button
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEditPage__showStandardInputs_options( $editor, $out,
+ &$tabindex
+ );
+}
diff --git a/includes/Hook/FileDeleteCompleteHook.php b/includes/Hook/FileDeleteCompleteHook.php
new file mode 100644
index 000000000000..31412d1d0eb1
--- /dev/null
+++ b/includes/Hook/FileDeleteCompleteHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface FileDeleteCompleteHook {
+ /**
+ * When a file is deleted.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $file reference to the deleted file
+ * @param ?mixed $oldimage in case of the deletion of an old image, the name of the old file
+ * @param ?mixed $article in case all revisions of the file are deleted a reference to the
+ * WikiFilePage associated with the file.
+ * @param ?mixed $user user who performed the deletion
+ * @param ?mixed $reason reason
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onFileDeleteComplete( $file, $oldimage, $article, $user,
+ $reason
+ );
+}
diff --git a/includes/Hook/FormatAutocommentsHook.php b/includes/Hook/FormatAutocommentsHook.php
new file mode 100644
index 000000000000..7050fc7663ac
--- /dev/null
+++ b/includes/Hook/FormatAutocommentsHook.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface FormatAutocommentsHook {
+ /**
+ * When an autocomment is formatted by the Linker.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$comment Reference to the accumulated comment. Initially null, when set the
+ * default code will be skipped.
+ * @param ?mixed $pre Boolean, true if there is text before this autocomment
+ * @param ?mixed $auto The extracted part of the parsed comment before the call to the hook.
+ * @param ?mixed $post Boolean, true if there is text after this autocomment
+ * @param ?mixed $title An optional title object used to links to sections. Can be null.
+ * @param ?mixed $local Boolean indicating whether section links should refer to local page.
+ * @param ?mixed $wikiId String containing the ID (as used by WikiMap) of the wiki from which the
+ * autocomment originated; null for the local wiki. Added in 1.26, should default
+ * to null in handler functions, for backwards compatibility.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onFormatAutocomments( &$comment, $pre, $auto, $post, $title,
+ $local, $wikiId
+ );
+}
diff --git a/includes/Hook/GetAutoPromoteGroupsHook.php b/includes/Hook/GetAutoPromoteGroupsHook.php
new file mode 100644
index 000000000000..550db2d73347
--- /dev/null
+++ b/includes/Hook/GetAutoPromoteGroupsHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetAutoPromoteGroupsHook {
+ /**
+ * When determining which autopromote groups a user is
+ * entitled to be in.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user user to promote.
+ * @param ?mixed &$promote groups that will be added.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetAutoPromoteGroups( $user, &$promote );
+}
diff --git a/includes/Hook/GetCacheVaryCookiesHook.php b/includes/Hook/GetCacheVaryCookiesHook.php
new file mode 100644
index 000000000000..b10238a0c2af
--- /dev/null
+++ b/includes/Hook/GetCacheVaryCookiesHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetCacheVaryCookiesHook {
+ /**
+ * Get cookies that should vary cache options.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $out OutputPage object
+ * @param ?mixed &$cookies array of cookies name, add a value to it if you want to add a cookie
+ * that have to vary cache options
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetCacheVaryCookies( $out, &$cookies );
+}
diff --git a/includes/Hook/GetCanonicalURLHook.php b/includes/Hook/GetCanonicalURLHook.php
new file mode 100644
index 000000000000..ff0324e58ff7
--- /dev/null
+++ b/includes/Hook/GetCanonicalURLHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetCanonicalURLHook {
+ /**
+ * Modify fully-qualified URLs used for IRC and e-mail
+ * notifications.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object of page
+ * @param ?mixed &$url string value as output (out parameter, can modify)
+ * @param ?mixed $query query options as string passed to Title::getCanonicalURL()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetCanonicalURL( $title, &$url, $query );
+}
diff --git a/includes/Hook/GetDefaultSortkeyHook.php b/includes/Hook/GetDefaultSortkeyHook.php
new file mode 100644
index 000000000000..450b4f2f40e8
--- /dev/null
+++ b/includes/Hook/GetDefaultSortkeyHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetDefaultSortkeyHook {
+ /**
+ * Override the default sortkey for a page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object that we need to get a sortkey for
+ * @param ?mixed &$sortkey Sortkey to use.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetDefaultSortkey( $title, &$sortkey );
+}
diff --git a/includes/Hook/GetDoubleUnderscoreIDsHook.php b/includes/Hook/GetDoubleUnderscoreIDsHook.php
new file mode 100644
index 000000000000..e09e04c91889
--- /dev/null
+++ b/includes/Hook/GetDoubleUnderscoreIDsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetDoubleUnderscoreIDsHook {
+ /**
+ * Modify the list of behavior switch (double
+ * underscore) magic words. Called by MagicWord.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$doubleUnderscoreIDs array of strings
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetDoubleUnderscoreIDs( &$doubleUnderscoreIDs );
+}
diff --git a/includes/Hook/GetFullURLHook.php b/includes/Hook/GetFullURLHook.php
new file mode 100644
index 000000000000..525d36627b6b
--- /dev/null
+++ b/includes/Hook/GetFullURLHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetFullURLHook {
+ /**
+ * Modify fully-qualified URLs used in redirects/export/offsite data.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object of page
+ * @param ?mixed &$url string value as output (out parameter, can modify)
+ * @param ?mixed $query query options as string passed to Title::getFullURL()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetFullURL( $title, &$url, $query );
+}
diff --git a/includes/Hook/GetIPHook.php b/includes/Hook/GetIPHook.php
new file mode 100644
index 000000000000..2b06051cf5a1
--- /dev/null
+++ b/includes/Hook/GetIPHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetIPHook {
+ /**
+ * modify the ip of the current user (called only once).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$ip string holding the ip as determined so far
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetIP( &$ip );
+}
diff --git a/includes/Hook/GetInternalURLHook.php b/includes/Hook/GetInternalURLHook.php
new file mode 100644
index 000000000000..908a682cbbe4
--- /dev/null
+++ b/includes/Hook/GetInternalURLHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetInternalURLHook {
+ /**
+ * Modify fully-qualified URLs used for squid cache purging.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object of page
+ * @param ?mixed &$url string value as output (out parameter, can modify)
+ * @param ?mixed $query query options as string passed to Title::getInternalURL()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetInternalURL( $title, &$url, $query );
+}
diff --git a/includes/Hook/GetLocalURLHook.php b/includes/Hook/GetLocalURLHook.php
new file mode 100644
index 000000000000..b112e0d32c0f
--- /dev/null
+++ b/includes/Hook/GetLocalURLHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetLocalURLHook {
+ /**
+ * Modify local URLs as output into page links. Note that if you are
+ * working with internal urls (non-interwiki) then it may be preferable to work
+ * with the GetLocalURL::Internal or GetLocalURL::Article hooks as GetLocalURL can
+ * be buggy for internal urls on render if you do not re-implement the horrible
+ * hack that Title::getLocalURL uses in your own extension.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object of page
+ * @param ?mixed &$url string value as output (out parameter, can modify)
+ * @param ?mixed $query query options as string passed to Title::getLocalURL()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetLocalURL( $title, &$url, $query );
+}
diff --git a/includes/Hook/GetLocalURL__ArticleHook.php b/includes/Hook/GetLocalURL__ArticleHook.php
new file mode 100644
index 000000000000..62e8092b4848
--- /dev/null
+++ b/includes/Hook/GetLocalURL__ArticleHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetLocalURL__ArticleHook {
+ /**
+ * Modify local URLs specifically pointing to article paths
+ * without any fancy queries or variants.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object of page
+ * @param ?mixed &$url string value as output (out parameter, can modify)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetLocalURL__Article( $title, &$url );
+}
diff --git a/includes/Hook/GetLocalURL__InternalHook.php b/includes/Hook/GetLocalURL__InternalHook.php
new file mode 100644
index 000000000000..b5043692dd3d
--- /dev/null
+++ b/includes/Hook/GetLocalURL__InternalHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetLocalURL__InternalHook {
+ /**
+ * Modify local URLs to internal pages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object of page
+ * @param ?mixed &$url string value as output (out parameter, can modify)
+ * @param ?mixed $query query options as string passed to Title::getLocalURL()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetLocalURL__Internal( $title, &$url, $query );
+}
diff --git a/includes/Hook/GetRelativeTimestampHook.php b/includes/Hook/GetRelativeTimestampHook.php
new file mode 100644
index 000000000000..9ed81817a4b0
--- /dev/null
+++ b/includes/Hook/GetRelativeTimestampHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetRelativeTimestampHook {
+ /**
+ * Pre-emptively override the relative timestamp generated
+ * by MWTimestamp::getRelativeTimestamp(). Return false in this hook to use the
+ * custom output.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$output string for the output timestamp
+ * @param ?mixed &$diff DateInterval representing the difference between the timestamps
+ * @param ?mixed $timestamp MWTimestamp object of the current (user-adjusted) timestamp
+ * @param ?mixed $relativeTo MWTimestamp object of the relative (user-adjusted) timestamp
+ * @param ?mixed $user User whose preferences are being used to make timestamp
+ * @param ?mixed $lang Language that will be used to render the timestamp
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetRelativeTimestamp( &$output, &$diff, $timestamp,
+ $relativeTo, $user, $lang
+ );
+}
diff --git a/includes/Hook/GitViewersHook.php b/includes/Hook/GitViewersHook.php
new file mode 100644
index 000000000000..643404ff808e
--- /dev/null
+++ b/includes/Hook/GitViewersHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GitViewersHook {
+ /**
+ * Called when generating the list of git viewers for
+ * Special:Version, use this to change the list.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$extTypes associative array of repo URLS to viewer URLs.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGitViewers( &$extTypes );
+}
diff --git a/includes/Hook/ImageBeforeProduceHTMLHook.php b/includes/Hook/ImageBeforeProduceHTMLHook.php
new file mode 100644
index 000000000000..0751cbb6c4bf
--- /dev/null
+++ b/includes/Hook/ImageBeforeProduceHTMLHook.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImageBeforeProduceHTMLHook {
+ /**
+ * Called before producing the HTML created by a wiki
+ * image insertion. You can skip the default logic entirely by returning false, or
+ * just modify a few things using call-by-reference.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $skin Skin object
+ * @param ?mixed &$title Title object of the image
+ * @param ?mixed &$file File object, or false if it doesn't exist
+ * @param ?mixed &$frameParams Various parameters with special meanings; see documentation in
+ * includes/Linker.php for Linker::makeImageLink
+ * @param ?mixed &$handlerParams Various parameters with special meanings; see documentation in
+ * includes/Linker.php for Linker::makeImageLink
+ * @param ?mixed &$time Timestamp of file in 'YYYYMMDDHHIISS' string form, or false for current
+ * @param ?mixed &$res Final HTML output, used if you return false
+ * @param ?mixed $parser Parser instance
+ * @param ?mixed &$query Query params for desc URL
+ * @param ?mixed &$widthOption Used by the parser to remember the user preference thumbnailsize
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImageBeforeProduceHTML( $skin, &$title, &$file,
+ &$frameParams, &$handlerParams, &$time, &$res, $parser, &$query, &$widthOption
+ );
+}
diff --git a/includes/Hook/ImgAuthBeforeStreamHook.php b/includes/Hook/ImgAuthBeforeStreamHook.php
new file mode 100644
index 000000000000..755f517d8ca7
--- /dev/null
+++ b/includes/Hook/ImgAuthBeforeStreamHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImgAuthBeforeStreamHook {
+ /**
+ * Executed before file is streamed to user, but only when
+ * using img_auth.php.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$title the Title object of the file as it would appear for the upload page
+ * @param ?mixed &$path the original file and path name when img_auth was invoked by the web
+ * server
+ * @param ?mixed &$name the name only component of the file
+ * @param ?mixed &$result The location to pass back results of the hook routine (only used if
+ * failed)
+ * $result[0]=The index of the header message
+ * $result[1]=The index of the body text message
+ * $result[2 through n]=Parameters passed to body text message. Please note the
+ * header message cannot receive/use parameters.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImgAuthBeforeStream( &$title, &$path, &$name, &$result );
+}
diff --git a/includes/Hook/ImgAuthModifyHeadersHook.php b/includes/Hook/ImgAuthModifyHeadersHook.php
new file mode 100644
index 000000000000..05e59d3dfa85
--- /dev/null
+++ b/includes/Hook/ImgAuthModifyHeadersHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImgAuthModifyHeadersHook {
+ /**
+ * Executed just before a file is streamed to a user via
+ * img_auth.php, allowing headers to be modified beforehand.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title LinkTarget object
+ * @param ?mixed &$headers HTTP headers ( name => value, names are case insensitive ).
+ * Two headers get special handling: If-Modified-Since (value must be
+ * a valid HTTP date) and Range (must be of the form "bytes=(\d*-\d*)")
+ * will be honored when streaming the file.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImgAuthModifyHeaders( $title, &$headers );
+}
diff --git a/includes/Hook/ImportHandleUnknownUserHook.php b/includes/Hook/ImportHandleUnknownUserHook.php
new file mode 100644
index 000000000000..b5406424f7ef
--- /dev/null
+++ b/includes/Hook/ImportHandleUnknownUserHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImportHandleUnknownUserHook {
+ /**
+ * When a user doesn't exist locally, this hook is
+ * called to give extensions an opportunity to auto-create it. If the auto-creation
+ * is successful, return false.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $name User name
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImportHandleUnknownUser( $name );
+}
diff --git a/includes/Hook/InitializeArticleMaybeRedirectHook.php b/includes/Hook/InitializeArticleMaybeRedirectHook.php
new file mode 100644
index 000000000000..53d515c55240
--- /dev/null
+++ b/includes/Hook/InitializeArticleMaybeRedirectHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface InitializeArticleMaybeRedirectHook {
+ /**
+ * MediaWiki check to see if title is a redirect.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object for the current page
+ * @param ?mixed $request WebRequest
+ * @param ?mixed &$ignoreRedirect boolean to skip redirect check
+ * @param ?mixed &$target Title/string of redirect target
+ * @param ?mixed &$article Article object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onInitializeArticleMaybeRedirect( $title, $request,
+ &$ignoreRedirect, &$target, &$article
+ );
+}
diff --git a/includes/Hook/IsTrustedProxyHook.php b/includes/Hook/IsTrustedProxyHook.php
new file mode 100644
index 000000000000..7484788d0fd1
--- /dev/null
+++ b/includes/Hook/IsTrustedProxyHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface IsTrustedProxyHook {
+ /**
+ * Override the result of ProxyLookup::isTrustedProxy()
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $ip IP being check
+ * @param ?mixed &$result Change this value to override the result of ProxyLookup::isTrustedProxy()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onIsTrustedProxy( $ip, &$result );
+}
diff --git a/includes/Hook/LanguageLinksHook.php b/includes/Hook/LanguageLinksHook.php
new file mode 100644
index 000000000000..1bea68551f74
--- /dev/null
+++ b/includes/Hook/LanguageLinksHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LanguageLinksHook {
+ /**
+ * Manipulate a page's language links. This is called
+ * in various places to allow extensions to define the effective language
+ * links for a page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title The page's Title.
+ * @param ?mixed &$links Array with elements of the form "language:title" in the order
+ * that they will be output.
+ * @param ?mixed &$linkFlags Associative array mapping prefixed links to arrays of flags.
+ * Currently unused, but planned to provide support for marking individual
+ * language links in the UI, e.g. for featured articles.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLanguageLinks( $title, &$links, &$linkFlags );
+}
diff --git a/includes/Hook/LinkerMakeExternalImageHook.php b/includes/Hook/LinkerMakeExternalImageHook.php
new file mode 100644
index 000000000000..feeaaa2f4dfb
--- /dev/null
+++ b/includes/Hook/LinkerMakeExternalImageHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LinkerMakeExternalImageHook {
+ /**
+ * At the end of Linker::makeExternalImage() just
+ * before the return.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$url the image url
+ * @param ?mixed &$alt the image's alt text
+ * @param ?mixed &$img the new image HTML (if returning false)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLinkerMakeExternalImage( &$url, &$alt, &$img );
+}
diff --git a/includes/Hook/LinkerMakeExternalLinkHook.php b/includes/Hook/LinkerMakeExternalLinkHook.php
new file mode 100644
index 000000000000..33670bbd7888
--- /dev/null
+++ b/includes/Hook/LinkerMakeExternalLinkHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LinkerMakeExternalLinkHook {
+ /**
+ * At the end of Linker::makeExternalLink() just
+ * before the return.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$url the link url
+ * @param ?mixed &$text the link text
+ * @param ?mixed &$link the new link HTML (if returning false)
+ * @param ?mixed &$attribs the attributes to be applied.
+ * @param ?mixed $linkType The external link type
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLinkerMakeExternalLink( &$url, &$text, &$link, &$attribs,
+ $linkType
+ );
+}
diff --git a/includes/Hook/LinkerMakeMediaLinkFileHook.php b/includes/Hook/LinkerMakeMediaLinkFileHook.php
new file mode 100644
index 000000000000..0a4be71fdeeb
--- /dev/null
+++ b/includes/Hook/LinkerMakeMediaLinkFileHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LinkerMakeMediaLinkFileHook {
+ /**
+ * At the end of Linker::makeMediaLinkFile() just
+ * before the return.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title the Title object that the link is pointing to
+ * @param ?mixed $file the File object or false if broken link
+ * @param ?mixed &$html the link text
+ * @param ?mixed &$attribs the attributes to be applied
+ * @param ?mixed &$ret the value to return if your hook returns false
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLinkerMakeMediaLinkFile( $title, $file, &$html, &$attribs,
+ &$ret
+ );
+}
diff --git a/includes/Hook/LocalisationChecksBlacklistHook.php b/includes/Hook/LocalisationChecksBlacklistHook.php
new file mode 100644
index 000000000000..dbe5a29f6fdd
--- /dev/null
+++ b/includes/Hook/LocalisationChecksBlacklistHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LocalisationChecksBlacklistHook {
+ /**
+ * When fetching the blacklist of
+ * localisation checks.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$blacklist array of checks to blacklist. See the bottom of
+ * maintenance/language/checkLanguage.inc for the format of this variable.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLocalisationChecksBlacklist( &$blacklist );
+}
diff --git a/includes/Hook/LocalisationIgnoredOptionalMessagesHook.php b/includes/Hook/LocalisationIgnoredOptionalMessagesHook.php
new file mode 100644
index 000000000000..0867eebff08e
--- /dev/null
+++ b/includes/Hook/LocalisationIgnoredOptionalMessagesHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LocalisationIgnoredOptionalMessagesHook {
+ /**
+ * When fetching the list of ignored and
+ * optional localisation messages
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$ignored Array of ignored message keys
+ * @param ?mixed &$optional Array of optional message keys
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLocalisationIgnoredOptionalMessages( &$ignored, &$optional );
+}
diff --git a/includes/Hook/MagicWordwgVariableIDsHook.php b/includes/Hook/MagicWordwgVariableIDsHook.php
new file mode 100644
index 000000000000..9b58d1302923
--- /dev/null
+++ b/includes/Hook/MagicWordwgVariableIDsHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MagicWordwgVariableIDsHook {
+ /**
+ * When defining new magic words IDs.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$variableIDs array of strings
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMagicWordwgVariableIDs( &$variableIDs );
+}
diff --git a/includes/Hook/MaintenanceRefreshLinksInitHook.php b/includes/Hook/MaintenanceRefreshLinksInitHook.php
new file mode 100644
index 000000000000..ea06258640e7
--- /dev/null
+++ b/includes/Hook/MaintenanceRefreshLinksInitHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MaintenanceRefreshLinksInitHook {
+ /**
+ * before executing the refreshLinks.php maintenance
+ * script.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $refreshLinks RefreshLinks object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMaintenanceRefreshLinksInit( $refreshLinks );
+}
diff --git a/includes/Hook/MaintenanceUpdateAddParamsHook.php b/includes/Hook/MaintenanceUpdateAddParamsHook.php
new file mode 100644
index 000000000000..194786023b9b
--- /dev/null
+++ b/includes/Hook/MaintenanceUpdateAddParamsHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Generic.Files.LineLength -- Remove this after doc review
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MaintenanceUpdateAddParamsHook {
+ /**
+ * allow extensions to add params to the update.php
+ * maintenance script.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$params array to populate with the params to be added. Array elements are keyed by
+ * the param name. Each param is an associative array that must include the following keys:
+ * - desc The description of the param to show on --help
+ * - require Is the param required? Defaults to false if not set.
+ * - withArg Is an argument required with this option? Defaults to false if not set.
+ * - shortName Character to use as short name, or false if none. Defaults to false if not set.
+ * - multiOccurrence Can this option be passed multiple times? Defaults to false if not set.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMaintenanceUpdateAddParams( &$params );
+}
diff --git a/includes/Hook/MakeGlobalVariablesScriptHook.php b/includes/Hook/MakeGlobalVariablesScriptHook.php
new file mode 100644
index 000000000000..8454cc030baf
--- /dev/null
+++ b/includes/Hook/MakeGlobalVariablesScriptHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MakeGlobalVariablesScriptHook {
+ /**
+ * Called at end of OutputPage::getJSVars.
+ * Ideally, this hook should only be used to add variables that depend on
+ * the current page/request; static configuration should be added through
+ * ResourceLoaderGetConfigVars instead.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$vars variable (or multiple variables) to be added into the output of
+ * Skin::makeVariablesScript
+ * @param ?mixed $out The OutputPage which called the hook, can be used to get the real title.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMakeGlobalVariablesScript( &$vars, $out );
+}
diff --git a/includes/Hook/MediaWikiPHPUnitTest__endTestHook.php b/includes/Hook/MediaWikiPHPUnitTest__endTestHook.php
new file mode 100644
index 000000000000..0f48af9da0de
--- /dev/null
+++ b/includes/Hook/MediaWikiPHPUnitTest__endTestHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MediaWikiPHPUnitTest__endTestHook {
+ /**
+ * After each PHPUnit test completes
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $test PHPUnit\Framework\Test object
+ * @param ?mixed $time The execution time in seconds
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMediaWikiPHPUnitTest__endTest( $test, $time );
+}
diff --git a/includes/Hook/MediaWikiPHPUnitTest__startTestHook.php b/includes/Hook/MediaWikiPHPUnitTest__startTestHook.php
new file mode 100644
index 000000000000..a08ba6b40844
--- /dev/null
+++ b/includes/Hook/MediaWikiPHPUnitTest__startTestHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MediaWikiPHPUnitTest__startTestHook {
+ /**
+ * Before each PHPUnit test starts
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $test PHPUnit\Framework\Test object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMediaWikiPHPUnitTest__startTest( $test );
+}
diff --git a/includes/Hook/MediaWikiPerformActionHook.php b/includes/Hook/MediaWikiPerformActionHook.php
new file mode 100644
index 000000000000..f0e2416b6954
--- /dev/null
+++ b/includes/Hook/MediaWikiPerformActionHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MediaWikiPerformActionHook {
+ /**
+ * Override MediaWiki::performAction(). Use this to do
+ * something completely different, after the basic globals have been set up, but
+ * before ordinary actions take place.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $output Context output
+ * @param ?mixed $article Article on which the action will be performed
+ * @param ?mixed $title Title on which the action will be performed
+ * @param ?mixed $user Context user
+ * @param ?mixed $request Context request
+ * @param ?mixed $mediaWiki The $mediawiki object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMediaWikiPerformAction( $output, $article, $title, $user,
+ $request, $mediaWiki
+ );
+}
diff --git a/includes/Hook/MediaWikiServicesHook.php b/includes/Hook/MediaWikiServicesHook.php
new file mode 100644
index 000000000000..0cbfcdf76790
--- /dev/null
+++ b/includes/Hook/MediaWikiServicesHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MediaWikiServicesHook {
+ /**
+ * Called when a global MediaWikiServices instance is
+ * initialized. Extensions may use this to define, replace, or wrap services.
+ * However, the preferred way to define a new service is
+ * the $wgServiceWiringFiles array.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $services MediaWikiServices
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMediaWikiServices( $services );
+}
diff --git a/includes/Hook/MimeMagicGuessFromContentHook.php b/includes/Hook/MimeMagicGuessFromContentHook.php
new file mode 100644
index 000000000000..bc2cda7d8cff
--- /dev/null
+++ b/includes/Hook/MimeMagicGuessFromContentHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MimeMagicGuessFromContentHook {
+ /**
+ * Allows MW extensions guess the MIME by content.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $mimeMagic Instance of MimeAnalyzer.
+ * @param ?mixed &$head First 1024 bytes of the file in a string (in - Do not alter!).
+ * @param ?mixed &$tail More or equal than last 65558 bytes of the file in a string
+ * (in - Do not alter!).
+ * @param ?mixed $file File path.
+ * @param ?mixed &$mime MIME type (out).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMimeMagicGuessFromContent( $mimeMagic, &$head, &$tail, $file,
+ &$mime
+ );
+}
diff --git a/includes/Hook/MimeMagicImproveFromExtensionHook.php b/includes/Hook/MimeMagicImproveFromExtensionHook.php
new file mode 100644
index 000000000000..6649a6144c80
--- /dev/null
+++ b/includes/Hook/MimeMagicImproveFromExtensionHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MimeMagicImproveFromExtensionHook {
+ /**
+ * Allows MW extensions to further improve the
+ * MIME type detected by considering the file extension.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $mimeMagic Instance of MimeAnalyzer.
+ * @param ?mixed $ext File extension.
+ * @param ?mixed &$mime MIME type (in/out).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMimeMagicImproveFromExtension( $mimeMagic, $ext, &$mime );
+}
diff --git a/includes/Hook/MimeMagicInitHook.php b/includes/Hook/MimeMagicInitHook.php
new file mode 100644
index 000000000000..a1e76b4b53ba
--- /dev/null
+++ b/includes/Hook/MimeMagicInitHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MimeMagicInitHook {
+ /**
+ * Before processing the list mapping MIME types to media types
+ * and the list mapping MIME types to file extensions.
+ * As an extension author, you are encouraged to submit patches to MediaWiki's
+ * core to add new MIME types to mime.types.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $mimeMagic Instance of MimeAnalyzer.
+ * Use $mimeMagic->addExtraInfo( $stringOfInfo );
+ * for adding new MIME info to the list.
+ * Use $mimeMagic->addExtraTypes( $stringOfTypes );
+ * for adding new MIME types to the list.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMimeMagicInit( $mimeMagic );
+}
diff --git a/includes/Hook/MovePageCheckPermissionsHook.php b/includes/Hook/MovePageCheckPermissionsHook.php
new file mode 100644
index 000000000000..18213e797cac
--- /dev/null
+++ b/includes/Hook/MovePageCheckPermissionsHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MovePageCheckPermissionsHook {
+ /**
+ * Specify whether the user is allowed to move the
+ * page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $oldTitle Title object of the current (old) location
+ * @param ?mixed $newTitle Title object of the new location
+ * @param ?mixed $user User making the move
+ * @param ?mixed $reason string of the reason provided by the user
+ * @param ?mixed $status Status object to pass error messages to
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMovePageCheckPermissions( $oldTitle, $newTitle, $user,
+ $reason, $status
+ );
+}
diff --git a/includes/Hook/MovePageIsValidMoveHook.php b/includes/Hook/MovePageIsValidMoveHook.php
new file mode 100644
index 000000000000..2d86e0ca5431
--- /dev/null
+++ b/includes/Hook/MovePageIsValidMoveHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MovePageIsValidMoveHook {
+ /**
+ * Specify whether a page can be moved for technical
+ * reasons.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $oldTitle Title object of the current (old) location
+ * @param ?mixed $newTitle Title object of the new location
+ * @param ?mixed $status Status object to pass error messages to
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMovePageIsValidMove( $oldTitle, $newTitle, $status );
+}
diff --git a/includes/Hook/OpenSearchUrlsHook.php b/includes/Hook/OpenSearchUrlsHook.php
new file mode 100644
index 000000000000..35b28c3dffa4
--- /dev/null
+++ b/includes/Hook/OpenSearchUrlsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface OpenSearchUrlsHook {
+ /**
+ * Called when constructing the OpenSearch description XML. Hooks
+ * can alter or append to the array of URLs for search & suggestion formats.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$urls array of associative arrays with Url element attributes
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onOpenSearchUrls( &$urls );
+}
diff --git a/includes/Hook/OutputPageAfterGetHeadLinksArrayHook.php b/includes/Hook/OutputPageAfterGetHeadLinksArrayHook.php
new file mode 100644
index 000000000000..a2ebf4a03642
--- /dev/null
+++ b/includes/Hook/OutputPageAfterGetHeadLinksArrayHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface OutputPageAfterGetHeadLinksArrayHook {
+ /**
+ * Called in OutputPage#getHeadLinksArray right
+ * before returning the result.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tags array containing all <head> links generated so far. The array format is
+ * "link name or number => 'link HTML'".
+ * @param ?mixed $out the OutputPage object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onOutputPageAfterGetHeadLinksArray( &$tags, $out );
+}
diff --git a/includes/Hook/OutputPageBeforeHTMLHook.php b/includes/Hook/OutputPageBeforeHTMLHook.php
new file mode 100644
index 000000000000..68baa8268a0d
--- /dev/null
+++ b/includes/Hook/OutputPageBeforeHTMLHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface OutputPageBeforeHTMLHook {
+ /**
+ * A page has been processed by the parser and the
+ * resulting HTML is about to be displayed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $out the OutputPage (object) that corresponds to the page
+ * @param ?mixed &$text the text that will be displayed, in HTML (string)
+ * @return bool|void This hook must not abort, it must return true or null.
+ */
+ public function onOutputPageBeforeHTML( $out, &$text );
+}
diff --git a/includes/Hook/OutputPageBodyAttributesHook.php b/includes/Hook/OutputPageBodyAttributesHook.php
new file mode 100644
index 000000000000..4b3ab4982815
--- /dev/null
+++ b/includes/Hook/OutputPageBodyAttributesHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface OutputPageBodyAttributesHook {
+ /**
+ * Called when OutputPage::headElement is creating the
+ * body tag to allow for extensions to add attributes to the body of the page they
+ * might need. Or to allow building extensions to add body classes that aren't of
+ * high enough demand to be included in core.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $out The OutputPage which called the hook, can be used to get the real title
+ * @param ?mixed $sk The Skin that called OutputPage::headElement
+ * @param ?mixed &$bodyAttrs An array of attributes for the body tag passed to Html::openElement
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onOutputPageBodyAttributes( $out, $sk, &$bodyAttrs );
+}
diff --git a/includes/Hook/OutputPageCheckLastModifiedHook.php b/includes/Hook/OutputPageCheckLastModifiedHook.php
new file mode 100644
index 000000000000..9cc4f364d268
--- /dev/null
+++ b/includes/Hook/OutputPageCheckLastModifiedHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface OutputPageCheckLastModifiedHook {
+ /**
+ * when checking if the page has been modified
+ * since the last visit.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$modifiedTimes array of timestamps.
+ * The following keys are set: page, user, epoch
+ * @param ?mixed $out OutputPage object (since 1.28)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onOutputPageCheckLastModified( &$modifiedTimes, $out );
+}
diff --git a/includes/Hook/OutputPageMakeCategoryLinksHook.php b/includes/Hook/OutputPageMakeCategoryLinksHook.php
new file mode 100644
index 000000000000..987ec888a60d
--- /dev/null
+++ b/includes/Hook/OutputPageMakeCategoryLinksHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface OutputPageMakeCategoryLinksHook {
+ /**
+ * Links are about to be generated for the page's
+ * categories. Implementations should return false if they generate the category
+ * links, so the default link generation is skipped.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $out OutputPage instance (object)
+ * @param ?mixed $categories associative array, keys are category names, values are category
+ * types ("normal" or "hidden")
+ * @param ?mixed &$links array, intended to hold the result. Must be an associative array with
+ * category types as keys and arrays of HTML links as values.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onOutputPageMakeCategoryLinks( $out, $categories, &$links );
+}
diff --git a/includes/Hook/OutputPageParserOutputHook.php b/includes/Hook/OutputPageParserOutputHook.php
new file mode 100644
index 000000000000..234e20d9de41
--- /dev/null
+++ b/includes/Hook/OutputPageParserOutputHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface OutputPageParserOutputHook {
+ /**
+ * after adding a parserOutput to $wgOut
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $out OutputPage instance (object)
+ * @param ?mixed $parserOutput parserOutput instance being added in $out
+ * @return bool|void This hook must not abort, it must return true or null.
+ */
+ public function onOutputPageParserOutput( $out, $parserOutput );
+}
diff --git a/includes/Hook/ParserTestGlobalsHook.php b/includes/Hook/ParserTestGlobalsHook.php
new file mode 100644
index 000000000000..d8cf22f9f357
--- /dev/null
+++ b/includes/Hook/ParserTestGlobalsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserTestGlobalsHook {
+ /**
+ * Allows to define globals for parser tests.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$globals Array with all the globals which should be set for parser tests.
+ * The arrays keys serve as the globals names, its values are the globals values.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserTestGlobals( &$globals );
+}
diff --git a/includes/Hook/ParserTestTablesHook.php b/includes/Hook/ParserTestTablesHook.php
new file mode 100644
index 000000000000..4206f8fe5365
--- /dev/null
+++ b/includes/Hook/ParserTestTablesHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserTestTablesHook {
+ /**
+ * Alter the list of tables to duplicate when parser tests are
+ * run. Use when page save hooks require the presence of custom tables to ensure
+ * that tests continue to run properly.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tables array of table names
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserTestTables( &$tables );
+}
diff --git a/includes/Hook/ProtectionForm__buildFormHook.php b/includes/Hook/ProtectionForm__buildFormHook.php
new file mode 100644
index 000000000000..ea069c5d61e0
--- /dev/null
+++ b/includes/Hook/ProtectionForm__buildFormHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ProtectionForm__buildFormHook {
+ /**
+ * Called after all protection type fieldsets are made
+ * in the form.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article the title being (un)protected
+ * @param ?mixed &$output a string of the form HTML so far
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onProtectionForm__buildForm( $article, &$output );
+}
diff --git a/includes/Hook/ProtectionForm__saveHook.php b/includes/Hook/ProtectionForm__saveHook.php
new file mode 100644
index 000000000000..28f9f9a3a0f1
--- /dev/null
+++ b/includes/Hook/ProtectionForm__saveHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ProtectionForm__saveHook {
+ /**
+ * Called when a protection form is submitted.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article the Page being (un)protected
+ * @param ?mixed &$errorMsg an html message string of an error or an array of message name and
+ * its parameters
+ * @param ?mixed $reasonstr a string describing the reason page protection level is altered
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onProtectionForm__save( $article, &$errorMsg, $reasonstr );
+}
diff --git a/includes/Hook/ProtectionForm__showLogExtractHook.php b/includes/Hook/ProtectionForm__showLogExtractHook.php
new file mode 100644
index 000000000000..7ebea610d2a8
--- /dev/null
+++ b/includes/Hook/ProtectionForm__showLogExtractHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ProtectionForm__showLogExtractHook {
+ /**
+ * Called after the protection log extract is
+ * shown.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article the page the form is shown for
+ * @param ?mixed $out OutputPage object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onProtectionForm__showLogExtract( $article, $out );
+}
diff --git a/includes/Hook/ResourceLoaderRegisterModulesHook.php b/includes/Hook/ResourceLoaderRegisterModulesHook.php
new file mode 100644
index 000000000000..dcd58b52d5ac
--- /dev/null
+++ b/includes/Hook/ResourceLoaderRegisterModulesHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ResourceLoaderRegisterModulesHook {
+ /**
+ * Right before modules information is required,
+ * such as when responding to a resource
+ * loader request or generating HTML output.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $resourceLoader ResourceLoader object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onResourceLoaderRegisterModules( $resourceLoader );
+}
diff --git a/includes/Hook/SelfLinkBeginHook.php b/includes/Hook/SelfLinkBeginHook.php
new file mode 100644
index 000000000000..664ef3828750
--- /dev/null
+++ b/includes/Hook/SelfLinkBeginHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SelfLinkBeginHook {
+ /**
+ * Called before a link to the current article is displayed to
+ * allow the display of the link to be customized.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $nt the Title object
+ * @param ?mixed &$html html to display for the link
+ * @param ?mixed &$trail optional text to display before $html
+ * @param ?mixed &$prefix optional text to display after $html
+ * @param ?mixed &$ret the value to return if your hook returns false
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSelfLinkBegin( $nt, &$html, &$trail, &$prefix, &$ret );
+}
diff --git a/includes/Hook/SetupAfterCacheHook.php b/includes/Hook/SetupAfterCacheHook.php
new file mode 100644
index 000000000000..a398bd727e55
--- /dev/null
+++ b/includes/Hook/SetupAfterCacheHook.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SetupAfterCacheHook {
+ /**
+ * Called in Setup.php, after cache objects are set
+ *
+ * @since 1.35
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSetupAfterCache();
+}
diff --git a/includes/Hook/TestCanonicalRedirectHook.php b/includes/Hook/TestCanonicalRedirectHook.php
new file mode 100644
index 000000000000..50848a4dc434
--- /dev/null
+++ b/includes/Hook/TestCanonicalRedirectHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TestCanonicalRedirectHook {
+ /**
+ * Called when about to force a redirect to a canonical
+ * URL for a title when we have no other parameters on the URL. Gives a chance for
+ * extensions that alter page view behavior radically to abort that redirect or
+ * handle it manually.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $request WebRequest
+ * @param ?mixed $title Title of the currently found title obj
+ * @param ?mixed $output OutputPage object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTestCanonicalRedirect( $request, $title, $output );
+}
diff --git a/includes/Hook/TitleArrayFromResultHook.php b/includes/Hook/TitleArrayFromResultHook.php
new file mode 100644
index 000000000000..ab8327a869e8
--- /dev/null
+++ b/includes/Hook/TitleArrayFromResultHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleArrayFromResultHook {
+ /**
+ * Called when creating an TitleArray object from a
+ * database result.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$titleArray set this to an object to override the default object returned
+ * @param ?mixed $res database result used to create the object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleArrayFromResult( &$titleArray, $res );
+}
diff --git a/includes/Hook/TitleExistsHook.php b/includes/Hook/TitleExistsHook.php
new file mode 100644
index 000000000000..47493a2891b1
--- /dev/null
+++ b/includes/Hook/TitleExistsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleExistsHook {
+ /**
+ * Called when determining whether a page exists at a given title.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title The title being tested.
+ * @param ?mixed &$exists Whether the title exists.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleExists( $title, &$exists );
+}
diff --git a/includes/Hook/TitleGetEditNoticesHook.php b/includes/Hook/TitleGetEditNoticesHook.php
new file mode 100644
index 000000000000..8739d6c1a047
--- /dev/null
+++ b/includes/Hook/TitleGetEditNoticesHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleGetEditNoticesHook {
+ /**
+ * Allows extensions to add edit notices
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title The Title object for the page the edit notices are for
+ * @param ?mixed $oldid Revision ID that the edit notices are for (or 0 for latest)
+ * @param ?mixed &$notices Array of notices. Keys are i18n message keys, values are
+ * parseAsBlock()ed messages.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleGetEditNotices( $title, $oldid, &$notices );
+}
diff --git a/includes/Hook/TitleGetRestrictionTypesHook.php b/includes/Hook/TitleGetRestrictionTypesHook.php
new file mode 100644
index 000000000000..d5e144129a20
--- /dev/null
+++ b/includes/Hook/TitleGetRestrictionTypesHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleGetRestrictionTypesHook {
+ /**
+ * Allows extensions to modify the types of protection
+ * that can be applied.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title The title in question.
+ * @param ?mixed &$types The types of protection available.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleGetRestrictionTypes( $title, &$types );
+}
diff --git a/includes/Hook/TitleIsAlwaysKnownHook.php b/includes/Hook/TitleIsAlwaysKnownHook.php
new file mode 100644
index 000000000000..f65346cafeeb
--- /dev/null
+++ b/includes/Hook/TitleIsAlwaysKnownHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleIsAlwaysKnownHook {
+ /**
+ * Called when determining if a page exists. Allows
+ * overriding default behavior for determining if a page exists. If $isKnown is
+ * kept as null, regular checks happen. If it's a boolean, this value is returned
+ * by the isKnown method.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object that is being checked
+ * @param ?mixed &$isKnown Boolean|null; whether MediaWiki currently thinks this page is known
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleIsAlwaysKnown( $title, &$isKnown );
+}
diff --git a/includes/Hook/TitleIsMovableHook.php b/includes/Hook/TitleIsMovableHook.php
new file mode 100644
index 000000000000..75d4b04d7874
--- /dev/null
+++ b/includes/Hook/TitleIsMovableHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleIsMovableHook {
+ /**
+ * Called when determining if it is possible to move a page. Note
+ * that this hook is not called for interwiki pages or pages in immovable
+ * namespaces: for these, isMovable() always returns false.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object that is being checked
+ * @param ?mixed &$result Boolean; whether MediaWiki currently thinks this page is movable.
+ * Hooks may change this value to override the return value of
+ * Title::isMovable().
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleIsMovable( $title, &$result );
+}
diff --git a/includes/Hook/TitleMoveCompleteHook.php b/includes/Hook/TitleMoveCompleteHook.php
new file mode 100644
index 000000000000..ff535f203514
--- /dev/null
+++ b/includes/Hook/TitleMoveCompleteHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleMoveCompleteHook {
+ /**
+ * After moving an article (title), post-commit.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $old old title
+ * @param ?mixed $nt new title
+ * @param ?mixed $user user who did the move
+ * @param ?mixed $pageid database ID of the page that's been moved
+ * @param ?mixed $redirid database ID of the created redirect
+ * @param ?mixed $reason reason for the move
+ * @param ?mixed $revision the Revision created by the move
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleMoveComplete( $old, $nt, $user, $pageid, $redirid,
+ $reason, $revision
+ );
+}
diff --git a/includes/Hook/TitleMoveCompletingHook.php b/includes/Hook/TitleMoveCompletingHook.php
new file mode 100644
index 000000000000..3c623db4a36e
--- /dev/null
+++ b/includes/Hook/TitleMoveCompletingHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleMoveCompletingHook {
+ /**
+ * After moving an article (title), pre-commit.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $old old title
+ * @param ?mixed $nt new title
+ * @param ?mixed $user user who did the move
+ * @param ?mixed $pageid database ID of the page that's been moved
+ * @param ?mixed $redirid database ID of the created redirect
+ * @param ?mixed $reason reason for the move
+ * @param ?mixed $revision the Revision created by the move
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleMoveCompleting( $old, $nt, $user, $pageid, $redirid,
+ $reason, $revision
+ );
+}
diff --git a/includes/Hook/TitleMoveHook.php b/includes/Hook/TitleMoveHook.php
new file mode 100644
index 000000000000..fa54bc886f0c
--- /dev/null
+++ b/includes/Hook/TitleMoveHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleMoveHook {
+ /**
+ * Before moving an article (title).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $old old title
+ * @param ?mixed $nt new title
+ * @param ?mixed $user user who does the move
+ * @param ?mixed $reason string of the reason provided by the user
+ * @param ?mixed &$status Status object. To abort the move, add a fatal error to this object
+ * (i.e. call $status->fatal()).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleMove( $old, $nt, $user, $reason, &$status );
+}
diff --git a/includes/Hook/TitleMoveStartingHook.php b/includes/Hook/TitleMoveStartingHook.php
new file mode 100644
index 000000000000..d8c4169ce38c
--- /dev/null
+++ b/includes/Hook/TitleMoveStartingHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleMoveStartingHook {
+ /**
+ * Before moving an article (title), but just after the atomic
+ * DB section starts.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $old old title
+ * @param ?mixed $nt new title
+ * @param ?mixed $user user who does the move
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleMoveStarting( $old, $nt, $user );
+}
diff --git a/includes/Hook/TitleSquidURLsHook.php b/includes/Hook/TitleSquidURLsHook.php
new file mode 100644
index 000000000000..25c6f2258e17
--- /dev/null
+++ b/includes/Hook/TitleSquidURLsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleSquidURLsHook {
+ /**
+ * Called to determine which URLs to purge from HTTP caches.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object to purge
+ * @param ?mixed &$urls An array of URLs to purge from the caches, to be manipulated.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleSquidURLs( $title, &$urls );
+}
diff --git a/includes/Hook/UnitTestsAfterDatabaseSetupHook.php b/includes/Hook/UnitTestsAfterDatabaseSetupHook.php
new file mode 100644
index 000000000000..003e3364c6ce
--- /dev/null
+++ b/includes/Hook/UnitTestsAfterDatabaseSetupHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UnitTestsAfterDatabaseSetupHook {
+ /**
+ * Called right after MediaWiki's test
+ * infrastructure has finished creating/duplicating core tables for unit tests.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $database Database in question
+ * @param ?mixed $prefix Table prefix to be used in unit tests
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUnitTestsAfterDatabaseSetup( $database, $prefix );
+}
diff --git a/includes/Hook/UnitTestsBeforeDatabaseTeardownHook.php b/includes/Hook/UnitTestsBeforeDatabaseTeardownHook.php
new file mode 100644
index 000000000000..3b504a541775
--- /dev/null
+++ b/includes/Hook/UnitTestsBeforeDatabaseTeardownHook.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UnitTestsBeforeDatabaseTeardownHook {
+ /**
+ * Called right before MediaWiki tears down its
+ * database infrastructure used for unit tests.
+ *
+ * @since 1.35
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUnitTestsBeforeDatabaseTeardown();
+}
diff --git a/includes/Hook/UnitTestsListHook.php b/includes/Hook/UnitTestsListHook.php
new file mode 100644
index 000000000000..4f690c34f4e5
--- /dev/null
+++ b/includes/Hook/UnitTestsListHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UnitTestsListHook {
+ /**
+ * Called when building a list of paths containing PHPUnit tests.
+ * Since 1.24: Paths pointing to a directory will be recursively scanned for
+ * test case files matching the suffix "Test.php".
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$paths list of test cases and directories to search.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUnitTestsList( &$paths );
+}
diff --git a/includes/Hook/UserToolLinksEditHook.php b/includes/Hook/UserToolLinksEditHook.php
new file mode 100644
index 000000000000..c2d34f5c11be
--- /dev/null
+++ b/includes/Hook/UserToolLinksEditHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserToolLinksEditHook {
+ /**
+ * Called when generating a list of user tool links, e.g.
+ * "Foobar (Talk | Contribs | Block)".
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $userId User id of the current user
+ * @param ?mixed $userText User name of the current user
+ * @param ?mixed &$items Array of user tool links as HTML fragments
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserToolLinksEdit( $userId, $userText, &$items );
+}
diff --git a/includes/Hook/WebRequestPathInfoRouterHook.php b/includes/Hook/WebRequestPathInfoRouterHook.php
new file mode 100644
index 000000000000..1665c4544007
--- /dev/null
+++ b/includes/Hook/WebRequestPathInfoRouterHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WebRequestPathInfoRouterHook {
+ /**
+ * While building the PathRouter to parse the
+ * REQUEST_URI.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $router The PathRouter instance
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWebRequestPathInfoRouter( $router );
+}
diff --git a/includes/Hook/WebResponseSetCookieHook.php b/includes/Hook/WebResponseSetCookieHook.php
new file mode 100644
index 000000000000..63354a80c8fd
--- /dev/null
+++ b/includes/Hook/WebResponseSetCookieHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WebResponseSetCookieHook {
+ /**
+ * when setting a cookie in WebResponse::setcookie().
+ * Return false to prevent setting of the cookie.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$name Cookie name passed to WebResponse::setcookie()
+ * @param ?mixed &$value Cookie value passed to WebResponse::setcookie()
+ * @param ?mixed &$expire Cookie expiration, as for PHP's setcookie()
+ * @param ?mixed &$options Options passed to WebResponse::setcookie()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWebResponseSetCookie( &$name, &$value, &$expire, &$options );
+}
diff --git a/includes/Permissions/Hook/GetUserPermissionsErrorsExpensiveHook.php b/includes/Permissions/Hook/GetUserPermissionsErrorsExpensiveHook.php
new file mode 100644
index 000000000000..aa938c3cb8f1
--- /dev/null
+++ b/includes/Permissions/Hook/GetUserPermissionsErrorsExpensiveHook.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace MediaWiki\Permissions\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetUserPermissionsErrorsExpensiveHook {
+ /**
+ * Equal to getUserPermissionsErrors, but is
+ * called only if expensive checks are enabled. Add a permissions error when
+ * permissions errors are checked for. Return false if the user can't do it, and
+ * populate $result with the reason in the form of [ messagename, param1, param2,
+ * ... ] or a MessageSpecifier instance (you might want to use ApiMessage to
+ * provide machine-readable details for the API). For consistency, error messages
+ * should be plain text with no special coloring, bolding, etc. to show that
+ * they're errors; presenting them properly to the user as errors is done by the
+ * caller.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object being checked against
+ * @param ?mixed $user Current user object
+ * @param ?mixed $action Action being checked
+ * @param ?mixed &$result User permissions error to add. If none, return true.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetUserPermissionsErrorsExpensive( $title, $user, $action,
+ &$result
+ );
+}
diff --git a/includes/Permissions/Hook/GetUserPermissionsErrorsHook.php b/includes/Permissions/Hook/GetUserPermissionsErrorsHook.php
new file mode 100644
index 000000000000..65e7e41b6764
--- /dev/null
+++ b/includes/Permissions/Hook/GetUserPermissionsErrorsHook.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace MediaWiki\Permissions\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetUserPermissionsErrorsHook {
+ /**
+ * Add a permissions error when permissions errors are
+ * checked for. Use instead of userCan for most cases. Return false if the user
+ * can't do it, and populate $result with the reason in the form of
+ * [ messagename, param1, param2, ... ] or a MessageSpecifier instance (you
+ * might want to use ApiMessage to provide machine-readable details for the API).
+ * For consistency, error messages
+ * should be plain text with no special coloring, bolding, etc. to show that
+ * they're errors; presenting them properly to the user as errors is done by the
+ * caller.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object being checked against
+ * @param ?mixed $user Current user object
+ * @param ?mixed $action Action being checked
+ * @param ?mixed &$result User permissions error to add. If none, return true.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetUserPermissionsErrors( $title, $user, $action, &$result );
+}
diff --git a/includes/Permissions/Hook/TitleQuickPermissionsHook.php b/includes/Permissions/Hook/TitleQuickPermissionsHook.php
new file mode 100644
index 000000000000..14cca88202d4
--- /dev/null
+++ b/includes/Permissions/Hook/TitleQuickPermissionsHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Permissions\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleQuickPermissionsHook {
+ /**
+ * Called from Title::checkQuickPermissions to add to
+ * or override the quick permissions check.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title The Title object being accessed
+ * @param ?mixed $user The User performing the action
+ * @param ?mixed $action Action being performed
+ * @param ?mixed &$errors Array of errors
+ * @param ?mixed $doExpensiveQueries Whether to do expensive DB queries
+ * @param ?mixed $short Whether to return immediately on first error
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleQuickPermissions( $title, $user, $action, &$errors,
+ $doExpensiveQueries, $short
+ );
+}
diff --git a/includes/Permissions/Hook/TitleReadWhitelistHook.php b/includes/Permissions/Hook/TitleReadWhitelistHook.php
new file mode 100644
index 000000000000..9b27e4438315
--- /dev/null
+++ b/includes/Permissions/Hook/TitleReadWhitelistHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Permissions\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface TitleReadWhitelistHook {
+ /**
+ * Called at the end of read permissions checks, just before
+ * adding the default error message if nothing allows the user to read the page. If
+ * a handler wants a title to *not* be whitelisted, it should also return false.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object being checked against
+ * @param ?mixed $user Current user object
+ * @param ?mixed &$whitelisted Boolean value of whether this title is whitelisted
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onTitleReadWhitelist( $title, $user, &$whitelisted );
+}
diff --git a/includes/Permissions/Hook/UserCanHook.php b/includes/Permissions/Hook/UserCanHook.php
new file mode 100644
index 000000000000..9d59ee739f12
--- /dev/null
+++ b/includes/Permissions/Hook/UserCanHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Permissions\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserCanHook {
+ /**
+ * To interrupt/advise the "user can do X to Y article" check. If you
+ * want to display an error message, try getUserPermissionsErrors.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object being checked against
+ * @param ?mixed $user Current user object
+ * @param ?mixed $action Action being checked
+ * @param ?mixed &$result Pointer to result returned if hook returns false. If null is returned,
+ * userCan checks are continued by internal code.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserCan( $title, $user, $action, &$result );
+}
diff --git a/includes/Permissions/Hook/UserGetAllRightsHook.php b/includes/Permissions/Hook/UserGetAllRightsHook.php
new file mode 100644
index 000000000000..f661c042c134
--- /dev/null
+++ b/includes/Permissions/Hook/UserGetAllRightsHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Permissions\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserGetAllRightsHook {
+ /**
+ * After calculating a list of all available rights.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$rights Array of rights, which may be added to.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserGetAllRights( &$rights );
+}
diff --git a/includes/Permissions/Hook/UserGetRightsHook.php b/includes/Permissions/Hook/UserGetRightsHook.php
new file mode 100644
index 000000000000..eab3c24304df
--- /dev/null
+++ b/includes/Permissions/Hook/UserGetRightsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Permissions\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserGetRightsHook {
+ /**
+ * Called in User::getRights().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User to get rights for
+ * @param ?mixed &$rights Current rights
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserGetRights( $user, &$rights );
+}
diff --git a/includes/Permissions/Hook/UserGetRightsRemoveHook.php b/includes/Permissions/Hook/UserGetRightsRemoveHook.php
new file mode 100644
index 000000000000..1a1f831626ff
--- /dev/null
+++ b/includes/Permissions/Hook/UserGetRightsRemoveHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Permissions\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserGetRightsRemoveHook {
+ /**
+ * Called in User::getRights(). This hook override
+ * the UserGetRights hook. It can be used to remove rights from user
+ * and ensure that will not be reinserted by the other hook callbacks
+ * therefore this hook should not be used to add any rights, use UserGetRights instead.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User to get rights for
+ * @param ?mixed &$rights Current rights
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserGetRightsRemove( $user, &$rights );
+}
diff --git a/includes/Permissions/Hook/UserIsBlockedFromHook.php b/includes/Permissions/Hook/UserIsBlockedFromHook.php
new file mode 100644
index 000000000000..7d61cdf41320
--- /dev/null
+++ b/includes/Permissions/Hook/UserIsBlockedFromHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Permissions\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserIsBlockedFromHook {
+ /**
+ * Check if a user is blocked from a specific page (for
+ * specific block exemptions if a user is already blocked).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User in question
+ * @param ?mixed $title Title of the page in question
+ * @param ?mixed &$blocked Out-param, whether or not the user is blocked from that page.
+ * @param ?mixed &$allowUsertalk If the user is blocked, whether or not the block allows users
+ * to edit their own user talk pages.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserIsBlockedFrom( $user, $title, &$blocked, &$allowUsertalk );
+}
diff --git a/includes/Permissions/Hook/UserIsEveryoneAllowedHook.php b/includes/Permissions/Hook/UserIsEveryoneAllowedHook.php
new file mode 100644
index 000000000000..be1dadb30537
--- /dev/null
+++ b/includes/Permissions/Hook/UserIsEveryoneAllowedHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Permissions\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserIsEveryoneAllowedHook {
+ /**
+ * Check if all users are allowed some user right; return
+ * false if a UserGetRights hook might remove the named right.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $right The user right being checked
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserIsEveryoneAllowed( $right );
+}
diff --git a/includes/Revision/Hook/ContentHandlerDefaultModelForHook.php b/includes/Revision/Hook/ContentHandlerDefaultModelForHook.php
new file mode 100644
index 000000000000..c3bc203e2b4a
--- /dev/null
+++ b/includes/Revision/Hook/ContentHandlerDefaultModelForHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Revision\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContentHandlerDefaultModelForHook {
+ /**
+ * Called when the default content model is
+ * determined for a given title. May be used to assign a different model for that
+ * title.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title the Title in question
+ * @param ?mixed &$model the model name. Use with CONTENT_MODEL_XXX constants.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContentHandlerDefaultModelFor( $title, &$model );
+}
diff --git a/includes/Revision/Hook/RevisionInsertCompleteHook.php b/includes/Revision/Hook/RevisionInsertCompleteHook.php
new file mode 100644
index 000000000000..ff3b0f055264
--- /dev/null
+++ b/includes/Revision/Hook/RevisionInsertCompleteHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Revision\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface RevisionInsertCompleteHook {
+ /**
+ * DEPRECATED since 1.31! Use RevisionRecordInserted hook
+ * instead. Called after a revision is inserted into the database.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $revision the Revision
+ * @param ?mixed $data DEPRECATED! Always null!
+ * @param ?mixed $flags DEPRECATED! Always null!
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onRevisionInsertComplete( $revision, $data, $flags );
+}
diff --git a/includes/Revision/Hook/RevisionRecordInsertedHook.php b/includes/Revision/Hook/RevisionRecordInsertedHook.php
new file mode 100644
index 000000000000..e8cd8d7a4e4a
--- /dev/null
+++ b/includes/Revision/Hook/RevisionRecordInsertedHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Revision\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface RevisionRecordInsertedHook {
+ /**
+ * Called after a revision is inserted into the database.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $revisionRecord the RevisionRecord that has just been inserted.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onRevisionRecordInserted( $revisionRecord );
+}
diff --git a/includes/Storage/Hook/ArticleEditUpdateNewTalkHook.php b/includes/Storage/Hook/ArticleEditUpdateNewTalkHook.php
new file mode 100644
index 000000000000..85dfeca2ff83
--- /dev/null
+++ b/includes/Storage/Hook/ArticleEditUpdateNewTalkHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Storage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleEditUpdateNewTalkHook {
+ /**
+ * Before updating user_newtalk when a user talk page
+ * was changed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage WikiPage (object) of the user talk page
+ * @param ?mixed $recipient User (object) who's talk page was edited
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleEditUpdateNewTalk( $wikiPage, $recipient );
+}
diff --git a/includes/Storage/Hook/ArticleEditUpdatesDeleteFromRecentchangesHook.php b/includes/Storage/Hook/ArticleEditUpdatesDeleteFromRecentchangesHook.php
new file mode 100644
index 000000000000..ea7e43929aa0
--- /dev/null
+++ b/includes/Storage/Hook/ArticleEditUpdatesDeleteFromRecentchangesHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Storage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleEditUpdatesDeleteFromRecentchangesHook {
+ /**
+ * DEPRECATED since 1.35, use RecentChange_save
+ * or similar instead. Before deleting old entries from
+ * recentchanges table, return false to not delete old entries.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage WikiPage (object) being modified
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleEditUpdatesDeleteFromRecentchanges( $wikiPage );
+}
diff --git a/includes/Storage/Hook/ArticleEditUpdatesHook.php b/includes/Storage/Hook/ArticleEditUpdatesHook.php
new file mode 100644
index 000000000000..abf09d457a11
--- /dev/null
+++ b/includes/Storage/Hook/ArticleEditUpdatesHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Storage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleEditUpdatesHook {
+ /**
+ * DEPRECATED since 1.35, use RevisionDataUpdates instead.
+ * When edit updates (mainly link tracking) are made when an article has been changed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage the WikiPage (object)
+ * @param ?mixed $editInfo data holder that includes the parser output ($editInfo->output) for
+ * that page after the change
+ * @param ?mixed $changed bool for if the page was changed
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleEditUpdates( $wikiPage, $editInfo, $changed );
+}
diff --git a/includes/Storage/Hook/ArticlePrepareTextForEditHook.php b/includes/Storage/Hook/ArticlePrepareTextForEditHook.php
new file mode 100644
index 000000000000..5baf6f3b3d0a
--- /dev/null
+++ b/includes/Storage/Hook/ArticlePrepareTextForEditHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Storage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticlePrepareTextForEditHook {
+ /**
+ * Called when preparing text to be saved.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage the WikiPage being saved
+ * @param ?mixed $popts parser options to be used for pre-save transformation
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticlePrepareTextForEdit( $wikiPage, $popts );
+}
diff --git a/includes/Storage/Hook/MultiContentSaveHook.php b/includes/Storage/Hook/MultiContentSaveHook.php
new file mode 100644
index 000000000000..9ff8ead76dbe
--- /dev/null
+++ b/includes/Storage/Hook/MultiContentSaveHook.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace MediaWiki\Storage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MultiContentSaveHook {
+ /**
+ * Before an article is saved.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $renderedRevision RenderedRevision (object) representing the planned revision.
+ * Provides access to: (1) ParserOutput of all slots,
+ * (2) RevisionRecord, which contains
+ * (2a) Title of the page that will be edited,
+ * (2b) RevisionSlots - content of all slots, including inherited slots,
+ * where content has already been modified by PreSaveTransform.
+ * NOTE: because this revision is not yet saved, slots don't have content ID
+ * or address, and revision itself doesn't have an ID.
+ * @param ?mixed $user UserIdentity (object): author of this new revision.
+ * @param ?mixed $summary CommentStoreComment (object): user-provided edit comment/summary
+ * (not an autosummary: will be empty if the user hasn't provided a comment).
+ * @param ?mixed $flags combination of EDIT_* flags, e.g. EDIT_MINOR.
+ * @param ?mixed $status if the hook is aborted, error code can be placed into this Status.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMultiContentSave( $renderedRevision, $user, $summary, $flags,
+ $status
+ );
+}
diff --git a/includes/Storage/Hook/PageContentInsertCompleteHook.php b/includes/Storage/Hook/PageContentInsertCompleteHook.php
new file mode 100644
index 000000000000..d7edab288687
--- /dev/null
+++ b/includes/Storage/Hook/PageContentInsertCompleteHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Storage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PageContentInsertCompleteHook {
+ /**
+ * After a new article is created.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage WikiPage created
+ * @param ?mixed $user User creating the article
+ * @param ?mixed $content New content as a Content object
+ * @param ?mixed $summary Edit summary/comment
+ * @param ?mixed $isMinor Whether or not the edit was marked as minor
+ * @param ?mixed $isWatch (No longer used)
+ * @param ?mixed $section (No longer used)
+ * @param ?mixed $flags Flags passed to WikiPage::doEditContent()
+ * @param ?mixed $revision New Revision of the article
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPageContentInsertComplete( $wikiPage, $user, $content,
+ $summary, $isMinor, $isWatch, $section, $flags, $revision
+ );
+}
diff --git a/includes/Storage/Hook/PageContentSaveCompleteHook.php b/includes/Storage/Hook/PageContentSaveCompleteHook.php
new file mode 100644
index 000000000000..ba2c2444490d
--- /dev/null
+++ b/includes/Storage/Hook/PageContentSaveCompleteHook.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace MediaWiki\Storage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PageContentSaveCompleteHook {
+ /**
+ * After an article has been updated.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage WikiPage modified
+ * @param ?mixed $user User performing the modification
+ * @param ?mixed $content New content, as a Content object
+ * @param ?mixed $summary Edit summary/comment
+ * @param ?mixed $isMinor Whether or not the edit was marked as minor
+ * @param ?mixed $isWatch (No longer used)
+ * @param ?mixed $section (No longer used)
+ * @param ?mixed $flags Flags passed to WikiPage::doEditContent()
+ * @param ?mixed $revision New Revision of the article
+ * @param ?mixed $status Status object about to be returned by doEditContent(). Since
+ * MediaWiki 1.32, replacing the Status object by assigning through the reference
+ * has had no effect.
+ * @param ?mixed $originalRevId if the edit restores or repeats an earlier revision (such as a
+ * rollback or a null revision), the ID of that earlier revision. False otherwise.
+ * (Used to be called $baseRevId.)
+ * @param ?mixed $undidRevId the rev ID (or 0) this edit undid
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPageContentSaveComplete( $wikiPage, $user, $content,
+ $summary, $isMinor, $isWatch, $section, $flags, $revision, $status,
+ $originalRevId, $undidRevId
+ );
+}
diff --git a/includes/Storage/Hook/PageContentSaveHook.php b/includes/Storage/Hook/PageContentSaveHook.php
new file mode 100644
index 000000000000..e0131bb4658a
--- /dev/null
+++ b/includes/Storage/Hook/PageContentSaveHook.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace MediaWiki\Storage\Hook;
+
+// phpcs:disable Generic.Files.LineLength -- Remove this after doc review
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PageContentSaveHook {
+ /**
+ * DEPRECATED since 1.35! Use MultiContentSave instead.
+ * Before an article is saved.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage the WikiPage (object) being saved
+ * @param ?mixed $user the user (object) saving the article
+ * @param ?mixed $content the new article content, as a Content object
+ * @param ?mixed &$summary CommentStoreComment object containing the edit comment. Can be replaced with a new one.
+ * @param ?mixed $isminor Boolean flag specifying if the edit was marked as minor.
+ * @param ?mixed $iswatch Previously a watch flag. Currently unused, always null.
+ * @param ?mixed $section Previously the section number being edited. Currently unused, always null.
+ * @param ?mixed $flags All EDIT_… flags (including EDIT_MINOR) as an integer number. See WikiPage::doEditContent
+ * documentation for flags' definition.
+ * @param ?mixed $status StatusValue object for the hook handlers resulting status. Either set $status->fatal() or
+ * return false to abort the save action.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPageContentSave( $wikiPage, $user, $content, &$summary,
+ $isminor, $iswatch, $section, $flags, $status
+ );
+}
diff --git a/includes/Storage/Hook/ParserOutputStashForEditHook.php b/includes/Storage/Hook/ParserOutputStashForEditHook.php
new file mode 100644
index 000000000000..97deae22e586
--- /dev/null
+++ b/includes/Storage/Hook/ParserOutputStashForEditHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Storage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserOutputStashForEditHook {
+ /**
+ * Called when an edit stash parse finishes, before the
+ * output is cached.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $page the WikiPage of the candidate edit
+ * @param ?mixed $content the Content object of the candidate edit
+ * @param ?mixed $output the ParserOutput result of the candidate edit
+ * @param ?mixed $summary the change summary of the candidate edit
+ * @param ?mixed $user the User considering the edit
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserOutputStashForEdit( $page, $content, $output, $summary,
+ $user
+ );
+}
diff --git a/includes/Storage/Hook/RevisionDataUpdatesHook.php b/includes/Storage/Hook/RevisionDataUpdatesHook.php
new file mode 100644
index 000000000000..39859f3fd511
--- /dev/null
+++ b/includes/Storage/Hook/RevisionDataUpdatesHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Storage\Hook;
+
+// phpcs:disable Generic.Files.LineLength -- Remove this after doc review
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface RevisionDataUpdatesHook {
+ /**
+ * Called when constructing a list of DeferrableUpdate to be
+ * executed to record secondary data about a revision.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title The Title of the page the revision belongs to
+ * @param ?mixed $renderedRevision a RenderedRevision object representing the new revision and providing access
+ * to the RevisionRecord as well as ParserOutput of that revision.
+ * @param ?mixed &$updates A list of DeferrableUpdate that can be manipulated by the hook handler.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onRevisionDataUpdates( $title, $renderedRevision, &$updates );
+}
diff --git a/includes/actions/Hook/ActionBeforeFormDisplayHook.php b/includes/actions/Hook/ActionBeforeFormDisplayHook.php
new file mode 100644
index 000000000000..d518359dec4f
--- /dev/null
+++ b/includes/actions/Hook/ActionBeforeFormDisplayHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ActionBeforeFormDisplayHook {
+ /**
+ * Before executing the HTMLForm object.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $name name of the action
+ * @param ?mixed $form HTMLForm object
+ * @param ?mixed $article Article object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onActionBeforeFormDisplay( $name, $form, $article );
+}
diff --git a/includes/actions/Hook/ActionModifyFormFieldsHook.php b/includes/actions/Hook/ActionModifyFormFieldsHook.php
new file mode 100644
index 000000000000..ae23bd1e8c59
--- /dev/null
+++ b/includes/actions/Hook/ActionModifyFormFieldsHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ActionModifyFormFieldsHook {
+ /**
+ * Before creating an HTMLForm object for a page action;
+ * Allows to change the fields on the form that will be generated.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $name name of the action
+ * @param ?mixed &$fields HTMLForm descriptor array
+ * @param ?mixed $article Article object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onActionModifyFormFields( $name, &$fields, $article );
+}
diff --git a/includes/actions/Hook/CustomEditorHook.php b/includes/actions/Hook/CustomEditorHook.php
new file mode 100644
index 000000000000..d54c3cf4612d
--- /dev/null
+++ b/includes/actions/Hook/CustomEditorHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface CustomEditorHook {
+ /**
+ * When invoking the page editor
+ * Return true to allow the normal editor to be used, or false if implementing
+ * a custom editor, e.g. for a special namespace, etc.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article Article being edited
+ * @param ?mixed $user User performing the edit
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onCustomEditor( $article, $user );
+}
diff --git a/includes/actions/Hook/HistoryPageToolLinksHook.php b/includes/actions/Hook/HistoryPageToolLinksHook.php
new file mode 100644
index 000000000000..50d10fa2e692
--- /dev/null
+++ b/includes/actions/Hook/HistoryPageToolLinksHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface HistoryPageToolLinksHook {
+ /**
+ * Add one or more links to revision history page subtitle.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $context IContextSource (object)
+ * @param ?mixed $linkRenderer LinkRenderer instance
+ * @param ?mixed &$links Array of HTML strings
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onHistoryPageToolLinks( $context, $linkRenderer, &$links );
+}
diff --git a/includes/actions/Hook/HistoryRevisionToolsHook.php b/includes/actions/Hook/HistoryRevisionToolsHook.php
new file mode 100644
index 000000000000..57c8696f0e39
--- /dev/null
+++ b/includes/actions/Hook/HistoryRevisionToolsHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface HistoryRevisionToolsHook {
+ /**
+ * Override or extend the revision tools available from the
+ * page history view, i.e. undo, rollback, etc.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $rev Revision object
+ * @param ?mixed &$links Array of HTML links
+ * @param ?mixed $prevRev Revision object, next in line in page history, or null
+ * @param ?mixed $user Current user object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onHistoryRevisionTools( $rev, &$links, $prevRev, $user );
+}
diff --git a/includes/actions/Hook/InfoActionHook.php b/includes/actions/Hook/InfoActionHook.php
new file mode 100644
index 000000000000..6c3cc940b90e
--- /dev/null
+++ b/includes/actions/Hook/InfoActionHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface InfoActionHook {
+ /**
+ * When building information to display on the action=info page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $context IContextSource object
+ * @param ?mixed &$pageInfo Array of information
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onInfoAction( $context, &$pageInfo );
+}
diff --git a/includes/actions/Hook/PageHistoryBeforeListHook.php b/includes/actions/Hook/PageHistoryBeforeListHook.php
new file mode 100644
index 000000000000..f646d7ee839d
--- /dev/null
+++ b/includes/actions/Hook/PageHistoryBeforeListHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PageHistoryBeforeListHook {
+ /**
+ * When a history page list is about to be constructed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article the article that the history is loading for
+ * @param ?mixed $context RequestContext object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPageHistoryBeforeList( $article, $context );
+}
diff --git a/includes/actions/Hook/PageHistoryLineEndingHook.php b/includes/actions/Hook/PageHistoryLineEndingHook.php
new file mode 100644
index 000000000000..4a0e72f925f8
--- /dev/null
+++ b/includes/actions/Hook/PageHistoryLineEndingHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PageHistoryLineEndingHook {
+ /**
+ * Right before the end <li> is added to a history line.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $historyAction the action object
+ * @param ?mixed &$row the revision row for this line
+ * @param ?mixed &$s the string representing this parsed line
+ * @param ?mixed &$classes array containing the <li> element classes
+ * @param ?mixed &$attribs associative array of other HTML attributes for the <li> element.
+ * Currently only data attributes reserved to MediaWiki are allowed
+ * (see Sanitizer::isReservedDataAttribute).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPageHistoryLineEnding( $historyAction, &$row, &$s, &$classes,
+ &$attribs
+ );
+}
diff --git a/includes/actions/Hook/PageHistoryPager__doBatchLookupsHook.php b/includes/actions/Hook/PageHistoryPager__doBatchLookupsHook.php
new file mode 100644
index 000000000000..d964ff8abb95
--- /dev/null
+++ b/includes/actions/Hook/PageHistoryPager__doBatchLookupsHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PageHistoryPager__doBatchLookupsHook {
+ /**
+ * Called after the pager query was run, before
+ * any output is generated, to allow batch lookups for prefetching information
+ * needed for display. If the hook handler returns false, the regular behavior of
+ * doBatchLookups() is skipped.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $pager the PageHistoryPager
+ * @param ?mixed $result a ResultWrapper representing the query result
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPageHistoryPager__doBatchLookups( $pager, $result );
+}
diff --git a/includes/actions/Hook/PageHistoryPager__getQueryInfoHook.php b/includes/actions/Hook/PageHistoryPager__getQueryInfoHook.php
new file mode 100644
index 000000000000..3616f4670171
--- /dev/null
+++ b/includes/actions/Hook/PageHistoryPager__getQueryInfoHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PageHistoryPager__getQueryInfoHook {
+ /**
+ * when a history pager query parameter set is
+ * constructed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $pager the pager
+ * @param ?mixed &$queryInfo the query parameters
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPageHistoryPager__getQueryInfo( $pager, &$queryInfo );
+}
diff --git a/includes/actions/Hook/RawPageViewBeforeOutputHook.php b/includes/actions/Hook/RawPageViewBeforeOutputHook.php
new file mode 100644
index 000000000000..96eee13193de
--- /dev/null
+++ b/includes/actions/Hook/RawPageViewBeforeOutputHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface RawPageViewBeforeOutputHook {
+ /**
+ * Right before the text is blown out in action=raw.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $obj RawAction object
+ * @param ?mixed &$text The text that's going to be the output
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onRawPageViewBeforeOutput( $obj, &$text );
+}
diff --git a/includes/actions/Hook/UnwatchArticleCompleteHook.php b/includes/actions/Hook/UnwatchArticleCompleteHook.php
new file mode 100644
index 000000000000..e15f72a19ae9
--- /dev/null
+++ b/includes/actions/Hook/UnwatchArticleCompleteHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UnwatchArticleCompleteHook {
+ /**
+ * After a watch is removed from an article.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user user that watched
+ * @param ?mixed $page WikiPage object that was watched
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUnwatchArticleComplete( $user, $page );
+}
diff --git a/includes/actions/Hook/UnwatchArticleHook.php b/includes/actions/Hook/UnwatchArticleHook.php
new file mode 100644
index 000000000000..435a5aee67a6
--- /dev/null
+++ b/includes/actions/Hook/UnwatchArticleHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UnwatchArticleHook {
+ /**
+ * Before a watch is removed from an article.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user user watching
+ * @param ?mixed $page WikiPage object to be removed
+ * @param ?mixed &$status Status object to be returned if the hook returns false
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUnwatchArticle( $user, $page, &$status );
+}
diff --git a/includes/actions/Hook/WatchArticleCompleteHook.php b/includes/actions/Hook/WatchArticleCompleteHook.php
new file mode 100644
index 000000000000..d237ead108fd
--- /dev/null
+++ b/includes/actions/Hook/WatchArticleCompleteHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WatchArticleCompleteHook {
+ /**
+ * After a watch is added to an article.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user user that watched
+ * @param ?mixed $page WikiPage object watched
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWatchArticleComplete( $user, $page );
+}
diff --git a/includes/actions/Hook/WatchArticleHook.php b/includes/actions/Hook/WatchArticleHook.php
new file mode 100644
index 000000000000..25f94969ae26
--- /dev/null
+++ b/includes/actions/Hook/WatchArticleHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WatchArticleHook {
+ /**
+ * Before a watch is added to an article.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user user that will watch
+ * @param ?mixed $page WikiPage object to be watched
+ * @param ?mixed &$status Status object to be returned if the hook returns false
+ * @param ?mixed $expiry Optional expiry timestamp in any format acceptable to wfTimestamp()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWatchArticle( $user, $page, &$status, $expiry );
+}
diff --git a/includes/api/Hook/APIAfterExecuteHook.php b/includes/api/Hook/APIAfterExecuteHook.php
new file mode 100644
index 000000000000..2f45875e566a
--- /dev/null
+++ b/includes/api/Hook/APIAfterExecuteHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIAfterExecuteHook {
+ /**
+ * After calling the execute() method of an API module. Use
+ * this to extend core API modules.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module Module object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIAfterExecute( $module );
+}
diff --git a/includes/api/Hook/APIGetAllowedParamsHook.php b/includes/api/Hook/APIGetAllowedParamsHook.php
new file mode 100644
index 000000000000..488ed36cb814
--- /dev/null
+++ b/includes/api/Hook/APIGetAllowedParamsHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIGetAllowedParamsHook {
+ /**
+ * Use this hook to modify a module's parameters.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module ApiBase Module object
+ * @param ?mixed &$params Array of parameters
+ * @param ?mixed $flags int zero or OR-ed flags like ApiBase::GET_VALUES_FOR_HELP
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIGetAllowedParams( $module, &$params, $flags );
+}
diff --git a/includes/api/Hook/APIGetDescriptionMessagesHook.php b/includes/api/Hook/APIGetDescriptionMessagesHook.php
new file mode 100644
index 000000000000..fb8426cd69ff
--- /dev/null
+++ b/includes/api/Hook/APIGetDescriptionMessagesHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIGetDescriptionMessagesHook {
+ /**
+ * Use this hook to modify a module's help message.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module ApiBase Module object
+ * @param ?mixed &$msg Array of Message objects
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIGetDescriptionMessages( $module, &$msg );
+}
diff --git a/includes/api/Hook/APIGetParamDescriptionMessagesHook.php b/includes/api/Hook/APIGetParamDescriptionMessagesHook.php
new file mode 100644
index 000000000000..3b7dc8aad403
--- /dev/null
+++ b/includes/api/Hook/APIGetParamDescriptionMessagesHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIGetParamDescriptionMessagesHook {
+ /**
+ * Use this hook to modify a module's parameter
+ * descriptions.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module ApiBase Module object
+ * @param ?mixed &$msg Array of arrays of Message objects
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIGetParamDescriptionMessages( $module, &$msg );
+}
diff --git a/includes/api/Hook/APIHelpModifyOutputHook.php b/includes/api/Hook/APIHelpModifyOutputHook.php
new file mode 100644
index 000000000000..b5fde73ca5da
--- /dev/null
+++ b/includes/api/Hook/APIHelpModifyOutputHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIHelpModifyOutputHook {
+ /**
+ * Use this hook to modify an API module's help output.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module ApiBase Module object
+ * @param ?mixed &$help Array of HTML strings to be joined for the output.
+ * @param ?mixed $options Array Options passed to ApiHelp::getHelp
+ * @param ?mixed &$tocData Array If a TOC is being generated, this array has keys as anchors in
+ * the page and values as for Linker::generateTOC().
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIHelpModifyOutput( $module, &$help, $options, &$tocData );
+}
diff --git a/includes/api/Hook/APIQueryAfterExecuteHook.php b/includes/api/Hook/APIQueryAfterExecuteHook.php
new file mode 100644
index 000000000000..38a69ff2fa50
--- /dev/null
+++ b/includes/api/Hook/APIQueryAfterExecuteHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIQueryAfterExecuteHook {
+ /**
+ * After calling the execute() method of an
+ * action=query submodule. Use this to extend core API modules.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module Module object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIQueryAfterExecute( $module );
+}
diff --git a/includes/api/Hook/APIQueryGeneratorAfterExecuteHook.php b/includes/api/Hook/APIQueryGeneratorAfterExecuteHook.php
new file mode 100644
index 000000000000..179dbfa1da53
--- /dev/null
+++ b/includes/api/Hook/APIQueryGeneratorAfterExecuteHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIQueryGeneratorAfterExecuteHook {
+ /**
+ * After calling the executeGenerator() method of
+ * an action=query submodule. Use this to extend core API modules.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module Module object
+ * @param ?mixed $resultPageSet ApiPageSet object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIQueryGeneratorAfterExecute( $module, $resultPageSet );
+}
diff --git a/includes/api/Hook/APIQueryInfoTokensHook.php b/includes/api/Hook/APIQueryInfoTokensHook.php
new file mode 100644
index 000000000000..2b0412057259
--- /dev/null
+++ b/includes/api/Hook/APIQueryInfoTokensHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIQueryInfoTokensHook {
+ /**
+ * DEPRECATED since 1.24! Use ApiQueryTokensRegisterTypes
+ * instead. Use this hook to add custom tokens to prop=info. Every token has an
+ * action, which will be used in the intoken parameter and in the output
+ * (actiontoken="..."), and a callback function which should return the token, or
+ * false if the user isn't allowed to obtain it. The prototype of the callback
+ * function is func($pageid, $title), where $pageid is the page ID of the page the
+ * token is requested for and $title is the associated Title object. In the hook,
+ * just add your callback to the $tokenFunctions array and return true (returning
+ * false makes no sense).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tokenFunctions [ action => callback ]
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIQueryInfoTokens( &$tokenFunctions );
+}
diff --git a/includes/api/Hook/APIQueryRecentChangesTokensHook.php b/includes/api/Hook/APIQueryRecentChangesTokensHook.php
new file mode 100644
index 000000000000..ab1a3df2191c
--- /dev/null
+++ b/includes/api/Hook/APIQueryRecentChangesTokensHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIQueryRecentChangesTokensHook {
+ /**
+ * DEPRECATED since 1.24! Use
+ * ApiQueryTokensRegisterTypes instead.
+ * Use this hook to add custom tokens to list=recentchanges. Every token has an
+ * action, which will be used in the rctoken parameter and in the output
+ * (actiontoken="..."), and a callback function which should return the token, or
+ * false if the user isn't allowed to obtain it. The prototype of the callback
+ * function is func($pageid, $title, $rc), where $pageid is the page ID of the
+ * page associated to the revision the token is requested for, $title the
+ * associated Title object and $rc the associated RecentChange object. In the
+ * hook, just add your callback to the $tokenFunctions array and return true
+ * (returning false makes no sense).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tokenFunctions [ action => callback ]
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIQueryRecentChangesTokens( &$tokenFunctions );
+}
diff --git a/includes/api/Hook/APIQueryRevisionsTokensHook.php b/includes/api/Hook/APIQueryRevisionsTokensHook.php
new file mode 100644
index 000000000000..6707881031bb
--- /dev/null
+++ b/includes/api/Hook/APIQueryRevisionsTokensHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIQueryRevisionsTokensHook {
+ /**
+ * DEPRECATED since 1.24! Use
+ * ApiQueryTokensRegisterTypes instead.
+ * Use this hook to add custom tokens to prop=revisions. Every token has an
+ * action, which will be used in the rvtoken parameter and in the output
+ * (actiontoken="..."), and a callback function which should return the token, or
+ * false if the user isn't allowed to obtain it. The prototype of the callback
+ * function is func($pageid, $title, $rev), where $pageid is the page ID of the
+ * page associated to the revision the token is requested for, $title the
+ * associated Title object and $rev the associated Revision object. In the hook,
+ * just add your callback to the $tokenFunctions array and return true (returning
+ * false makes no sense).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tokenFunctions [ action => callback ]
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIQueryRevisionsTokens( &$tokenFunctions );
+}
diff --git a/includes/api/Hook/APIQuerySiteInfoGeneralInfoHook.php b/includes/api/Hook/APIQuerySiteInfoGeneralInfoHook.php
new file mode 100644
index 000000000000..555f3c0706a6
--- /dev/null
+++ b/includes/api/Hook/APIQuerySiteInfoGeneralInfoHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIQuerySiteInfoGeneralInfoHook {
+ /**
+ * Use this hook to add extra information to the
+ * sites general information.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module the current ApiQuerySiteinfo module
+ * @param ?mixed &$results array of results, add things here
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIQuerySiteInfoGeneralInfo( $module, &$results );
+}
diff --git a/includes/api/Hook/APIQuerySiteInfoStatisticsInfoHook.php b/includes/api/Hook/APIQuerySiteInfoStatisticsInfoHook.php
new file mode 100644
index 000000000000..ddee14f56dbe
--- /dev/null
+++ b/includes/api/Hook/APIQuerySiteInfoStatisticsInfoHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIQuerySiteInfoStatisticsInfoHook {
+ /**
+ * Use this hook to add extra information to the
+ * sites statistics information.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$results array of results, add things here
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIQuerySiteInfoStatisticsInfo( &$results );
+}
diff --git a/includes/api/Hook/APIQueryUsersTokensHook.php b/includes/api/Hook/APIQueryUsersTokensHook.php
new file mode 100644
index 000000000000..4b5744376d35
--- /dev/null
+++ b/includes/api/Hook/APIQueryUsersTokensHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface APIQueryUsersTokensHook {
+ /**
+ * DEPRECATED since 1.24! Use ApiQueryTokensRegisterTypes
+ * instead.
+ * Use this hook to add custom token to list=users. Every token has an action,
+ * which will be used in the ustoken parameter and in the output
+ * (actiontoken="..."), and a callback function which should return the token, or
+ * false if the user isn't allowed to obtain it. The prototype of the callback
+ * function is func($user) where $user is the User object. In the hook, just add
+ * your callback to the $tokenFunctions array and return true (returning false
+ * makes no sense).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tokenFunctions [ action => callback ]
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAPIQueryUsersTokens( &$tokenFunctions );
+}
diff --git a/includes/api/Hook/ApiCheckCanExecuteHook.php b/includes/api/Hook/ApiCheckCanExecuteHook.php
new file mode 100644
index 000000000000..2de3e7cc57ce
--- /dev/null
+++ b/includes/api/Hook/ApiCheckCanExecuteHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiCheckCanExecuteHook {
+ /**
+ * Called during ApiMain::checkCanExecute. Use to further
+ * authenticate and authorize API clients before executing the module. Return
+ * false and set a message to cancel the request.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module Module object
+ * @param ?mixed $user Current user
+ * @param ?mixed &$message API message to die with. Specific values accepted depend on the
+ * MediaWiki version:
+ * * 1.29+: IApiMessage, Message, string message key, or key+parameters array to
+ * pass to ApiBase::dieWithError().
+ * * 1.27+: IApiMessage, or a key or key+parameters in ApiBase::$messageMap.
+ * * Earlier: A key or key+parameters in ApiBase::$messageMap.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiCheckCanExecute( $module, $user, &$message );
+}
diff --git a/includes/api/Hook/ApiDeprecationHelpHook.php b/includes/api/Hook/ApiDeprecationHelpHook.php
new file mode 100644
index 000000000000..623f2d1ad701
--- /dev/null
+++ b/includes/api/Hook/ApiDeprecationHelpHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiDeprecationHelpHook {
+ /**
+ * Add messages to the 'deprecation-help' warning generated
+ * from ApiBase::addDeprecation().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$msgs Message[] Messages to include in the help. Multiple messages will be
+ * joined with spaces.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiDeprecationHelp( &$msgs );
+}
diff --git a/includes/api/Hook/ApiFeedContributions__feedItemHook.php b/includes/api/Hook/ApiFeedContributions__feedItemHook.php
new file mode 100644
index 000000000000..34101872d48b
--- /dev/null
+++ b/includes/api/Hook/ApiFeedContributions__feedItemHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiFeedContributions__feedItemHook {
+ /**
+ * Called to convert the result of ContribsPager
+ * into a FeedItem instance that ApiFeedContributions can consume. Implementors of
+ * this hook may cancel the hook to signal that the item is not viewable in the
+ * provided context.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $row A row of data from ContribsPager. The set of data returned by
+ * ContribsPager can be adjusted by handling the ContribsPager::reallyDoQuery
+ * hook.
+ * @param ?mixed $context An IContextSource implementation.
+ * @param ?mixed &$feedItem Set this to a FeedItem instance if the callback can handle the
+ * provided row. This is provided to the hook as a null, if it is non null then
+ * another callback has already handled the hook.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiFeedContributions__feedItem( $row, $context, &$feedItem );
+}
diff --git a/includes/api/Hook/ApiFormatHighlightHook.php b/includes/api/Hook/ApiFormatHighlightHook.php
new file mode 100644
index 000000000000..780547febaa4
--- /dev/null
+++ b/includes/api/Hook/ApiFormatHighlightHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiFormatHighlightHook {
+ /**
+ * Use to syntax-highlight API pretty-printed output. When
+ * highlighting, add output to $context->getOutput() and return false.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $context An IContextSource.
+ * @param ?mixed $text Text to be highlighted.
+ * @param ?mixed $mime MIME type of $text.
+ * @param ?mixed $format API format code for $text.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiFormatHighlight( $context, $text, $mime, $format );
+}
diff --git a/includes/api/Hook/ApiMain__moduleManagerHook.php b/includes/api/Hook/ApiMain__moduleManagerHook.php
new file mode 100644
index 000000000000..c80f933f52c6
--- /dev/null
+++ b/includes/api/Hook/ApiMain__moduleManagerHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiMain__moduleManagerHook {
+ /**
+ * Called when ApiMain has finished initializing its
+ * module manager. Can be used to conditionally register API modules.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $moduleManager ApiModuleManager Module manager instance
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiMain__moduleManager( $moduleManager );
+}
diff --git a/includes/api/Hook/ApiMain__onExceptionHook.php b/includes/api/Hook/ApiMain__onExceptionHook.php
new file mode 100644
index 000000000000..9ffd3e5fdbfa
--- /dev/null
+++ b/includes/api/Hook/ApiMain__onExceptionHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiMain__onExceptionHook {
+ /**
+ * Called by ApiMain::executeActionWithErrorHandling() when
+ * an exception is thrown during API action execution.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $apiMain Calling ApiMain instance.
+ * @param ?mixed $e Exception object.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiMain__onException( $apiMain, $e );
+}
diff --git a/includes/api/Hook/ApiMakeParserOptionsHook.php b/includes/api/Hook/ApiMakeParserOptionsHook.php
new file mode 100644
index 000000000000..3e2630787aca
--- /dev/null
+++ b/includes/api/Hook/ApiMakeParserOptionsHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiMakeParserOptionsHook {
+ /**
+ * Called from ApiParse and ApiExpandTemplates to allow
+ * extensions to adjust the ParserOptions before parsing.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $options ParserOptions object
+ * @param ?mixed $title Title to be parsed
+ * @param ?mixed $params Parameter array for the API module
+ * @param ?mixed $module API module (which is also a ContextSource)
+ * @param ?mixed &$reset Set to a ScopedCallback used to reset any hooks after the parse is done.
+ * @param ?mixed &$suppressCache Set true if cache should be suppressed.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiMakeParserOptions( $options, $title, $params, $module,
+ &$reset, &$suppressCache
+ );
+}
diff --git a/includes/api/Hook/ApiMaxLagInfoHook.php b/includes/api/Hook/ApiMaxLagInfoHook.php
new file mode 100644
index 000000000000..062d6074900b
--- /dev/null
+++ b/includes/api/Hook/ApiMaxLagInfoHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiMaxLagInfoHook {
+ /**
+ * When lag information is being requested via API. Use this to
+ * override lag information. Generally a hook function should only replace
+ * $lagInfo if the new $lagInfo['lag'] is greater than the current $lagInfo['lag'].
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$lagInfo Maximum lag information array. Fields in the array are:
+ * 'lag' is the number of seconds of lag.
+ * 'host' is the host name on which the lag exists.
+ * 'type' is an indication of the type of lag,
+ * e.g. "db" for database replication lag or "jobqueue" for job queue size
+ * converted to pseudo-seconds.
+ * It is possible to add more fields and they will be returned to the user in
+ * the API response.
+ * @return bool|void This hook must not abort, it must return true or null.
+ */
+ public function onApiMaxLagInfo( &$lagInfo );
+}
diff --git a/includes/api/Hook/ApiOpenSearchSuggestHook.php b/includes/api/Hook/ApiOpenSearchSuggestHook.php
new file mode 100644
index 000000000000..67ad3eb667dd
--- /dev/null
+++ b/includes/api/Hook/ApiOpenSearchSuggestHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiOpenSearchSuggestHook {
+ /**
+ * Called when constructing the OpenSearch results. Hooks
+ * can alter or append to the array.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$results array with integer keys to associative arrays. Keys in associative
+ * array:
+ * - title: Title object.
+ * - redirect from: Title or null.
+ * - extract: Description for this result.
+ * - extract trimmed: If truthy, the extract will not be trimmed to
+ * $wgOpenSearchDescriptionLength.
+ * - image: Thumbnail for this result. Value is an array with subkeys 'source'
+ * (url), 'width', 'height', 'alt', 'align'.
+ * - url: Url for the given title.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiOpenSearchSuggest( &$results );
+}
diff --git a/includes/api/Hook/ApiOptionsHook.php b/includes/api/Hook/ApiOptionsHook.php
new file mode 100644
index 000000000000..fae5465d1853
--- /dev/null
+++ b/includes/api/Hook/ApiOptionsHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiOptionsHook {
+ /**
+ * Called by action=options before applying changes to user
+ * preferences.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $apiModule Calling ApiOptions object
+ * @param ?mixed $user User object whose preferences are being changed
+ * @param ?mixed $changes Associative array of preference name => value
+ * @param ?mixed $resetKinds Array of strings specifying which options kinds to reset.
+ * See User::resetOptions() and User::getOptionKinds() for possible
+ * values.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiOptions( $apiModule, $user, $changes, $resetKinds );
+}
diff --git a/includes/api/Hook/ApiParseMakeOutputPageHook.php b/includes/api/Hook/ApiParseMakeOutputPageHook.php
new file mode 100644
index 000000000000..54e2cfe3d6f9
--- /dev/null
+++ b/includes/api/Hook/ApiParseMakeOutputPageHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiParseMakeOutputPageHook {
+ /**
+ * Called when preparing the OutputPage object for
+ * ApiParse. This is mainly intended for calling OutputPage::addContentOverride()
+ * or OutputPage::addContentOverrideCallback().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module ApiBase (which is also a ContextSource)
+ * @param ?mixed $output OutputPage
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiParseMakeOutputPage( $module, $output );
+}
diff --git a/includes/api/Hook/ApiQueryBaseAfterQueryHook.php b/includes/api/Hook/ApiQueryBaseAfterQueryHook.php
new file mode 100644
index 000000000000..94874672a21d
--- /dev/null
+++ b/includes/api/Hook/ApiQueryBaseAfterQueryHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiQueryBaseAfterQueryHook {
+ /**
+ * Called for (some) API query modules after the
+ * database query has returned. An API query module wanting to use this hook
+ * should see the ApiQueryBase::select() and ApiQueryBase::processRow()
+ * documentation.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module ApiQueryBase module in question
+ * @param ?mixed $result ResultWrapper|bool returned from the IDatabase::select()
+ * @param ?mixed &$hookData array that was passed to the 'ApiQueryBaseBeforeQuery' hook and
+ * will be passed to the 'ApiQueryBaseProcessRow' hook, intended for inter-hook
+ * communication.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiQueryBaseAfterQuery( $module, $result, &$hookData );
+}
diff --git a/includes/api/Hook/ApiQueryBaseBeforeQueryHook.php b/includes/api/Hook/ApiQueryBaseBeforeQueryHook.php
new file mode 100644
index 000000000000..96603ec30f84
--- /dev/null
+++ b/includes/api/Hook/ApiQueryBaseBeforeQueryHook.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiQueryBaseBeforeQueryHook {
+ /**
+ * Called for (some) API query modules before a
+ * database query is made. WARNING: It would be very easy to misuse this hook and
+ * break the module! Any joins added *must* join on a unique key of the target
+ * table unless you really know what you're doing. An API query module wanting to
+ * use this hook should see the ApiQueryBase::select() and
+ * ApiQueryBase::processRow() documentation.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module ApiQueryBase module in question
+ * @param ?mixed &$tables array of tables to be queried
+ * @param ?mixed &$fields array of columns to select
+ * @param ?mixed &$conds array of WHERE conditionals for query
+ * @param ?mixed &$query_options array of options for the database request
+ * @param ?mixed &$join_conds join conditions for the tables
+ * @param ?mixed &$hookData array that will be passed to the 'ApiQueryBaseAfterQuery' and
+ * 'ApiQueryBaseProcessRow' hooks, intended for inter-hook communication.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiQueryBaseBeforeQuery( $module, &$tables, &$fields,
+ &$conds, &$query_options, &$join_conds, &$hookData
+ );
+}
diff --git a/includes/api/Hook/ApiQueryBaseProcessRowHook.php b/includes/api/Hook/ApiQueryBaseProcessRowHook.php
new file mode 100644
index 000000000000..1b9f01d89d2e
--- /dev/null
+++ b/includes/api/Hook/ApiQueryBaseProcessRowHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiQueryBaseProcessRowHook {
+ /**
+ * Called for (some) API query modules as each row of
+ * the database result is processed. Return false to stop processing the result
+ * set. An API query module wanting to use this hook should see the
+ * ApiQueryBase::select() and ApiQueryBase::processRow() documentation.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module ApiQueryBase module in question
+ * @param ?mixed $row stdClass Database result row
+ * @param ?mixed &$data array to be included in the ApiResult.
+ * @param ?mixed &$hookData array that was be passed to the 'ApiQueryBaseBeforeQuery' and
+ * 'ApiQueryBaseAfterQuery' hooks, intended for inter-hook communication.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiQueryBaseProcessRow( $module, $row, &$data, &$hookData );
+}
diff --git a/includes/api/Hook/ApiQueryTokensRegisterTypesHook.php b/includes/api/Hook/ApiQueryTokensRegisterTypesHook.php
new file mode 100644
index 000000000000..a109b091143c
--- /dev/null
+++ b/includes/api/Hook/ApiQueryTokensRegisterTypesHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiQueryTokensRegisterTypesHook {
+ /**
+ * Use this hook to add additional token types to
+ * action=query&meta=tokens. Note that most modules will probably be able to use
+ * the 'csrf' token instead of creating their own token types.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$salts [ type => salt to pass to User::getEditToken(), or array of salt
+ * and key to pass to Session::getToken() ]
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiQueryTokensRegisterTypes( &$salts );
+}
diff --git a/includes/api/Hook/ApiQueryWatchlistExtractOutputDataHook.php b/includes/api/Hook/ApiQueryWatchlistExtractOutputDataHook.php
new file mode 100644
index 000000000000..27235c8943ce
--- /dev/null
+++ b/includes/api/Hook/ApiQueryWatchlistExtractOutputDataHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiQueryWatchlistExtractOutputDataHook {
+ /**
+ * Extract row data for ApiQueryWatchlist.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module ApiQueryWatchlist instance
+ * @param ?mixed $watchedItem WatchedItem instance
+ * @param ?mixed $recentChangeInfo Array of recent change info data
+ * @param ?mixed &$vals Associative array of data to be output for the row
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiQueryWatchlistExtractOutputData( $module, $watchedItem,
+ $recentChangeInfo, &$vals
+ );
+}
diff --git a/includes/api/Hook/ApiQueryWatchlistPrepareWatchedItemQueryServiceOptionsHook.php b/includes/api/Hook/ApiQueryWatchlistPrepareWatchedItemQueryServiceOptionsHook.php
new file mode 100644
index 000000000000..f8e591e1b531
--- /dev/null
+++ b/includes/api/Hook/ApiQueryWatchlistPrepareWatchedItemQueryServiceOptionsHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+// phpcs:disable Generic.Files.LineLength -- Remove this after doc review
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiQueryWatchlistPrepareWatchedItemQueryServiceOptionsHook {
+ /**
+ * Populate the options
+ * to be passed from ApiQueryWatchlist to WatchedItemQueryService.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module ApiQueryWatchlist instance
+ * @param ?mixed $params Array of parameters, as would be returned by $module->extractRequestParams()
+ * @param ?mixed &$options Array of options for WatchedItemQueryService::getWatchedItemsWithRecentChangeInfo()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiQueryWatchlistPrepareWatchedItemQueryServiceOptions(
+ $module, $params, &$options
+ );
+}
diff --git a/includes/api/Hook/ApiQuery__moduleManagerHook.php b/includes/api/Hook/ApiQuery__moduleManagerHook.php
new file mode 100644
index 000000000000..c3795b0d7dba
--- /dev/null
+++ b/includes/api/Hook/ApiQuery__moduleManagerHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiQuery__moduleManagerHook {
+ /**
+ * Called when ApiQuery has finished initializing its
+ * module manager. Can be used to conditionally register API query modules.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $moduleManager ApiModuleManager Module manager instance
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiQuery__moduleManager( $moduleManager );
+}
diff --git a/includes/api/Hook/ApiRsdServiceApisHook.php b/includes/api/Hook/ApiRsdServiceApisHook.php
new file mode 100644
index 000000000000..a634c9f3380d
--- /dev/null
+++ b/includes/api/Hook/ApiRsdServiceApisHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiRsdServiceApisHook {
+ /**
+ * Add or remove APIs from the RSD services list. Each service
+ * should have its own entry in the $apis array and have a unique name, passed as
+ * key for the array that represents the service data. In this data array, the
+ * key-value-pair identified by the apiLink key is required.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$apis array of services
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiRsdServiceApis( &$apis );
+}
diff --git a/includes/api/Hook/ApiTokensGetTokenTypesHook.php b/includes/api/Hook/ApiTokensGetTokenTypesHook.php
new file mode 100644
index 000000000000..37e5c365b048
--- /dev/null
+++ b/includes/api/Hook/ApiTokensGetTokenTypesHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiTokensGetTokenTypesHook {
+ /**
+ * DEPRECATED since 1.24! Use ApiQueryTokensRegisterTypes instead.
+ * Use this hook to extend action=tokens with new token types.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tokenTypes supported token types in format 'type' => callback function
+ * used to retrieve this type of tokens.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiTokensGetTokenTypes( &$tokenTypes );
+}
diff --git a/includes/api/Hook/ApiValidatePasswordHook.php b/includes/api/Hook/ApiValidatePasswordHook.php
new file mode 100644
index 000000000000..28f58912b58b
--- /dev/null
+++ b/includes/api/Hook/ApiValidatePasswordHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ApiValidatePasswordHook {
+ /**
+ * Called from ApiValidatePassword.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $module ApiValidatePassword instance.
+ * @param ?mixed &$r Result array.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onApiValidatePassword( $module, &$r );
+}
diff --git a/includes/api/Hook/RequestHasSameOriginSecurityHook.php b/includes/api/Hook/RequestHasSameOriginSecurityHook.php
new file mode 100644
index 000000000000..4b14f93782e2
--- /dev/null
+++ b/includes/api/Hook/RequestHasSameOriginSecurityHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Api\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface RequestHasSameOriginSecurityHook {
+ /**
+ * Called to determine if the request is somehow
+ * flagged to lack same-origin security. Return false to indicate the lack. Note
+ * if the "somehow" involves HTTP headers, you'll probably need to make sure
+ * the header is varied on.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $request The WebRequest object.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onRequestHasSameOriginSecurity( $request );
+}
diff --git a/includes/auth/Hook/AuthManagerLoginAuthenticateAuditHook.php b/includes/auth/Hook/AuthManagerLoginAuthenticateAuditHook.php
new file mode 100644
index 000000000000..adfa407d7db7
--- /dev/null
+++ b/includes/auth/Hook/AuthManagerLoginAuthenticateAuditHook.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace MediaWiki\Auth\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AuthManagerLoginAuthenticateAuditHook {
+ /**
+ * A login attempt either succeeded or failed
+ * for a reason other than misconfiguration or session loss. No return data is
+ * accepted; this hook is for auditing only.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $response The MediaWiki\Auth\AuthenticationResponse in either a PASS or FAIL
+ * state.
+ * @param ?mixed $user The User object being authenticated against, or null if authentication
+ * failed before getting that far.
+ * @param ?mixed $username A guess at the user name being authenticated, or null if we can't
+ * even determine that. When $user is not null, it can be in the form of
+ * <username>@<more info> (e.g. for bot passwords).
+ * @param ?mixed $extraData An array (string => string) with extra information, intended to be
+ * added to log contexts. Fields it might include:
+ * - appId: the application ID, only if the login was with a bot password
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAuthManagerLoginAuthenticateAudit( $response, $user,
+ $username, $extraData
+ );
+}
diff --git a/includes/auth/Hook/ExemptFromAccountCreationThrottleHook.php b/includes/auth/Hook/ExemptFromAccountCreationThrottleHook.php
new file mode 100644
index 000000000000..82bf44fc0f4d
--- /dev/null
+++ b/includes/auth/Hook/ExemptFromAccountCreationThrottleHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Auth\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ExemptFromAccountCreationThrottleHook {
+ /**
+ * Exemption from the account creation
+ * throttle.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $ip The ip address of the user
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onExemptFromAccountCreationThrottle( $ip );
+}
diff --git a/includes/auth/Hook/LocalUserCreatedHook.php b/includes/auth/Hook/LocalUserCreatedHook.php
new file mode 100644
index 000000000000..e81a3cb281c5
--- /dev/null
+++ b/includes/auth/Hook/LocalUserCreatedHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Auth\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LocalUserCreatedHook {
+ /**
+ * Called when a local user has been created
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User object for the created user
+ * @param ?mixed $autocreated Boolean, whether this was an auto-creation
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLocalUserCreated( $user, $autocreated );
+}
diff --git a/includes/auth/Hook/ResetPasswordExpirationHook.php b/includes/auth/Hook/ResetPasswordExpirationHook.php
new file mode 100644
index 000000000000..2ace42596a36
--- /dev/null
+++ b/includes/auth/Hook/ResetPasswordExpirationHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Auth\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ResetPasswordExpirationHook {
+ /**
+ * Allow extensions to set a default password expiration
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user The user having their password expiration reset
+ * @param ?mixed &$newExpire The new expiration date
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onResetPasswordExpiration( $user, &$newExpire );
+}
diff --git a/includes/auth/Hook/SecuritySensitiveOperationStatusHook.php b/includes/auth/Hook/SecuritySensitiveOperationStatusHook.php
new file mode 100644
index 000000000000..f2dc494ad925
--- /dev/null
+++ b/includes/auth/Hook/SecuritySensitiveOperationStatusHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Auth\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SecuritySensitiveOperationStatusHook {
+ /**
+ * Affect the return value from
+ * MediaWiki\Auth\AuthManager::securitySensitiveOperationStatus().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$status (string) The status to be returned. One of the AuthManager::SEC_*
+ * constants. SEC_REAUTH will be automatically changed to SEC_FAIL if
+ * authentication isn't possible for the current session type.
+ * @param ?mixed $operation (string) The operation being checked.
+ * @param ?mixed $session (MediaWiki\Session\Session) The current session. The
+ * currently-authenticated user may be retrieved as $session->getUser().
+ * @param ?mixed $timeSinceAuth (int) The time since last authentication. PHP_INT_MAX if
+ * the time of last auth is unknown, or -1 if authentication is not possible.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSecuritySensitiveOperationStatus( &$status, $operation,
+ $session, $timeSinceAuth
+ );
+}
diff --git a/includes/auth/Hook/UserLoggedInHook.php b/includes/auth/Hook/UserLoggedInHook.php
new file mode 100644
index 000000000000..8d87bd954a5a
--- /dev/null
+++ b/includes/auth/Hook/UserLoggedInHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Auth\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserLoggedInHook {
+ /**
+ * Called after a user is logged in
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User object for the logged-in user
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserLoggedIn( $user );
+}
diff --git a/includes/block/Hook/AbortAutoblockHook.php b/includes/block/Hook/AbortAutoblockHook.php
new file mode 100644
index 000000000000..e43d3b1495f9
--- /dev/null
+++ b/includes/block/Hook/AbortAutoblockHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Block\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AbortAutoblockHook {
+ /**
+ * Return false to cancel an autoblock.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $autoblockip The IP going to be autoblocked.
+ * @param ?mixed $block The block from which the autoblock is coming.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAbortAutoblock( $autoblockip, $block );
+}
diff --git a/includes/block/Hook/GetUserBlockHook.php b/includes/block/Hook/GetUserBlockHook.php
new file mode 100644
index 000000000000..ae7bd7a2ed77
--- /dev/null
+++ b/includes/block/Hook/GetUserBlockHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Block\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetUserBlockHook {
+ /**
+ * Modify the block found by the block manager. This may be a
+ * single block or a composite block made from multiple blocks; the original
+ * blocks can be seen using CompositeBlock::getOriginalBlocks()
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User targeted by the block
+ * @param ?mixed $ip string|null The IP of the current request if $user is the current user
+ * and they're not exempted from IP blocks. Null otherwise.
+ * @param ?mixed &$block AbstractBlock|null The user's block, or null if none was found.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetUserBlock( $user, $ip, &$block );
+}
diff --git a/includes/block/Hook/PerformRetroactiveAutoblockHook.php b/includes/block/Hook/PerformRetroactiveAutoblockHook.php
new file mode 100644
index 000000000000..2f5f38bd02d1
--- /dev/null
+++ b/includes/block/Hook/PerformRetroactiveAutoblockHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Block\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PerformRetroactiveAutoblockHook {
+ /**
+ * Called before a retroactive autoblock is applied
+ * to a user.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $block Block object (which is set to be autoblocking)
+ * @param ?mixed &$blockIds Array of block IDs of the autoblock
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPerformRetroactiveAutoblock( $block, &$blockIds );
+}
diff --git a/includes/cache/Hook/BacklinkCacheGetConditionsHook.php b/includes/cache/Hook/BacklinkCacheGetConditionsHook.php
new file mode 100644
index 000000000000..f570fe4855a4
--- /dev/null
+++ b/includes/cache/Hook/BacklinkCacheGetConditionsHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Cache\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BacklinkCacheGetConditionsHook {
+ /**
+ * Allows to set conditions for query when links to
+ * certain title are fetched.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $table table name
+ * @param ?mixed $title title of the page to which backlinks are sought
+ * @param ?mixed &$conds query conditions
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBacklinkCacheGetConditions( $table, $title, &$conds );
+}
diff --git a/includes/cache/Hook/BacklinkCacheGetPrefixHook.php b/includes/cache/Hook/BacklinkCacheGetPrefixHook.php
new file mode 100644
index 000000000000..0cf76208a845
--- /dev/null
+++ b/includes/cache/Hook/BacklinkCacheGetPrefixHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Cache\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BacklinkCacheGetPrefixHook {
+ /**
+ * Allows to set prefix for a specific link table.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $table table name
+ * @param ?mixed &$prefix prefix
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBacklinkCacheGetPrefix( $table, &$prefix );
+}
diff --git a/includes/cache/Hook/HTMLFileCache__useFileCacheHook.php b/includes/cache/Hook/HTMLFileCache__useFileCacheHook.php
new file mode 100644
index 000000000000..44554a73db54
--- /dev/null
+++ b/includes/cache/Hook/HTMLFileCache__useFileCacheHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Cache\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface HTMLFileCache__useFileCacheHook {
+ /**
+ * Override whether a page should be cached in file
+ * cache.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $context An IContextSource object with information about the request being
+ * served.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onHTMLFileCache__useFileCache( $context );
+}
diff --git a/includes/cache/Hook/MessageCacheReplaceHook.php b/includes/cache/Hook/MessageCacheReplaceHook.php
new file mode 100644
index 000000000000..bc9a7789a12a
--- /dev/null
+++ b/includes/cache/Hook/MessageCacheReplaceHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Cache\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MessageCacheReplaceHook {
+ /**
+ * When a message page is changed. Useful for updating
+ * caches.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title name of the page changed.
+ * @param ?mixed $text new contents of the page.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMessageCacheReplace( $title, $text );
+}
diff --git a/includes/cache/Hook/MessageCache__getHook.php b/includes/cache/Hook/MessageCache__getHook.php
new file mode 100644
index 000000000000..96a2445559f9
--- /dev/null
+++ b/includes/cache/Hook/MessageCache__getHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Cache\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MessageCache__getHook {
+ /**
+ * When fetching a message. Can be used to override the key
+ * for customisations. Given and returned message key must be in special format:
+ * 1) first letter must be in lower case according to the content language.
+ * 2) spaces must be replaced with underscores
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$key message key (string)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMessageCache__get( &$key );
+}
diff --git a/includes/cache/Hook/MessagesPreLoadHook.php b/includes/cache/Hook/MessagesPreLoadHook.php
new file mode 100644
index 000000000000..2d67930d3bd2
--- /dev/null
+++ b/includes/cache/Hook/MessagesPreLoadHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Cache\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MessagesPreLoadHook {
+ /**
+ * When loading a message from the database.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title title of the message (string)
+ * @param ?mixed &$message value (string), change it to the message you want to define
+ * @param ?mixed $code code (string) denoting the language to try.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMessagesPreLoad( $title, &$message, $code );
+}
diff --git a/includes/cache/localisation/Hook/LocalisationCacheRecacheFallbackHook.php b/includes/cache/localisation/Hook/LocalisationCacheRecacheFallbackHook.php
new file mode 100644
index 000000000000..df303018b29b
--- /dev/null
+++ b/includes/cache/localisation/Hook/LocalisationCacheRecacheFallbackHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LocalisationCacheRecacheFallbackHook {
+ /**
+ * Called for each language when merging
+ * fallback data into the cache.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $cache The LocalisationCache object
+ * @param ?mixed $code language code
+ * @param ?mixed &$alldata The localisation data from core and extensions. Note some keys may
+ * be omitted if they won't be merged into the final result.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLocalisationCacheRecacheFallback( $cache, $code, &$alldata );
+}
diff --git a/includes/cache/localisation/Hook/LocalisationCacheRecacheHook.php b/includes/cache/localisation/Hook/LocalisationCacheRecacheHook.php
new file mode 100644
index 000000000000..9b3d34369650
--- /dev/null
+++ b/includes/cache/localisation/Hook/LocalisationCacheRecacheHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LocalisationCacheRecacheHook {
+ /**
+ * Called when loading the localisation data into
+ * cache.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $cache The LocalisationCache object
+ * @param ?mixed $code language code
+ * @param ?mixed &$alldata The localisation data from core and extensions
+ * @param ?mixed $unused Used to be $purgeBlobs, removed in 1.34
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLocalisationCacheRecache( $cache, $code, &$alldata, $unused );
+}
diff --git a/includes/changes/Hook/AbortEmailNotificationHook.php b/includes/changes/Hook/AbortEmailNotificationHook.php
new file mode 100644
index 000000000000..6c897cef42d1
--- /dev/null
+++ b/includes/changes/Hook/AbortEmailNotificationHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AbortEmailNotificationHook {
+ /**
+ * Can be used to cancel email notifications for an edit.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $editor The User who made the change.
+ * @param ?mixed $title The Title of the page that was edited.
+ * @param ?mixed $rc The current RecentChange object.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAbortEmailNotification( $editor, $title, $rc );
+}
diff --git a/includes/changes/Hook/ChangesListInitRowsHook.php b/includes/changes/Hook/ChangesListInitRowsHook.php
new file mode 100644
index 000000000000..54fe2aba6b5f
--- /dev/null
+++ b/includes/changes/Hook/ChangesListInitRowsHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangesListInitRowsHook {
+ /**
+ * Batch process change list rows prior to rendering.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $changesList ChangesList instance
+ * @param ?mixed $rows The data that will be rendered. May be a \Wikimedia\Rdbms\IResultWrapper
+ * instance or an array.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangesListInitRows( $changesList, $rows );
+}
diff --git a/includes/changes/Hook/ChangesListInsertArticleLinkHook.php b/includes/changes/Hook/ChangesListInsertArticleLinkHook.php
new file mode 100644
index 000000000000..fe795f717520
--- /dev/null
+++ b/includes/changes/Hook/ChangesListInsertArticleLinkHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangesListInsertArticleLinkHook {
+ /**
+ * Override or augment link to article in RC list.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $changesList ChangesList instance.
+ * @param ?mixed &$articlelink HTML of link to article (already filled-in).
+ * @param ?mixed &$s HTML of row that is being constructed.
+ * @param ?mixed $rc RecentChange instance.
+ * @param ?mixed $unpatrolled Whether or not we are showing unpatrolled changes.
+ * @param ?mixed $watched Whether or not the change is watched by the user.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangesListInsertArticleLink( $changesList, &$articlelink,
+ &$s, $rc, $unpatrolled, $watched
+ );
+}
diff --git a/includes/changes/Hook/EnhancedChangesListModifyBlockLineDataHook.php b/includes/changes/Hook/EnhancedChangesListModifyBlockLineDataHook.php
new file mode 100644
index 000000000000..b9fe204ff1ea
--- /dev/null
+++ b/includes/changes/Hook/EnhancedChangesListModifyBlockLineDataHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EnhancedChangesListModifyBlockLineDataHook {
+ /**
+ * to alter data used to build
+ * a non-grouped recent change line in EnhancedChangesList.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $changesList EnhancedChangesList object
+ * @param ?mixed &$data An array with all the components that will be joined in order to create
+ * the line
+ * @param ?mixed $rc The RecentChange object for this line
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEnhancedChangesListModifyBlockLineData( $changesList, &$data,
+ $rc
+ );
+}
diff --git a/includes/changes/Hook/EnhancedChangesListModifyLineDataHook.php b/includes/changes/Hook/EnhancedChangesListModifyLineDataHook.php
new file mode 100644
index 000000000000..26b5c56cd793
--- /dev/null
+++ b/includes/changes/Hook/EnhancedChangesListModifyLineDataHook.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EnhancedChangesListModifyLineDataHook {
+ /**
+ * to alter data used to build
+ * a grouped recent change inner line in EnhancedChangesList.
+ * Hook subscribers can return false to omit this line from recentchanges.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $changesList EnhancedChangesList object
+ * @param ?mixed &$data An array with all the components that will be joined in order to create
+ * the line
+ * @param ?mixed $block An array of RecentChange objects in that block
+ * @param ?mixed $rc The RecentChange object for this line
+ * @param ?mixed &$classes An array of classes to change
+ * @param ?mixed &$attribs associative array of other HTML attributes for the <tr> element.
+ * Currently only data attributes reserved to MediaWiki are allowed
+ * (see Sanitizer::isReservedDataAttribute).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEnhancedChangesListModifyLineData( $changesList, &$data,
+ $block, $rc, &$classes, &$attribs
+ );
+}
diff --git a/includes/changes/Hook/EnhancedChangesList__getLogTextHook.php b/includes/changes/Hook/EnhancedChangesList__getLogTextHook.php
new file mode 100644
index 000000000000..ab029966a042
--- /dev/null
+++ b/includes/changes/Hook/EnhancedChangesList__getLogTextHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EnhancedChangesList__getLogTextHook {
+ /**
+ * to alter, remove or add to the links of a
+ * group of changes in EnhancedChangesList.
+ * Hook subscribers can return false to omit this line from recentchanges.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $changesList EnhancedChangesList object
+ * @param ?mixed &$links The links that were generated by EnhancedChangesList
+ * @param ?mixed $block The RecentChanges objects in that block
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEnhancedChangesList__getLogText( $changesList, &$links,
+ $block
+ );
+}
diff --git a/includes/changes/Hook/FetchChangesListHook.php b/includes/changes/Hook/FetchChangesListHook.php
new file mode 100644
index 000000000000..30e3046b6df9
--- /dev/null
+++ b/includes/changes/Hook/FetchChangesListHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface FetchChangesListHook {
+ /**
+ * When fetching the ChangesList derivative for a particular
+ * user.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User the list is being fetched for
+ * @param ?mixed $skin Skin object to be used with the list
+ * @param ?mixed &$list List object (defaults to NULL, change it to an object instance and
+ * return false override the list derivative used)
+ * @param ?mixed $groups Array of ChangesListFilterGroup objects (added in 1.34)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onFetchChangesList( $user, $skin, &$list, $groups );
+}
diff --git a/includes/changes/Hook/MarkPatrolledCompleteHook.php b/includes/changes/Hook/MarkPatrolledCompleteHook.php
new file mode 100644
index 000000000000..342b4b82a345
--- /dev/null
+++ b/includes/changes/Hook/MarkPatrolledCompleteHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MarkPatrolledCompleteHook {
+ /**
+ * After an edit is marked patrolled.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $rcid ID of the revision marked as patrolled
+ * @param ?mixed $user user (object) who marked the edit patrolled
+ * @param ?mixed $wcOnlySysopsCanPatrol config setting indicating whether the user must be a
+ * sysop to patrol the edit.
+ * @param ?mixed $auto true if the edit is being marked as patrolled automatically
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMarkPatrolledComplete( $rcid, $user, $wcOnlySysopsCanPatrol,
+ $auto
+ );
+}
diff --git a/includes/changes/Hook/MarkPatrolledHook.php b/includes/changes/Hook/MarkPatrolledHook.php
new file mode 100644
index 000000000000..734a5bf21aa3
--- /dev/null
+++ b/includes/changes/Hook/MarkPatrolledHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface MarkPatrolledHook {
+ /**
+ * Before an edit is marked patrolled.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $rcid ID of the revision to be marked patrolled
+ * @param ?mixed $user the user (object) marking the revision as patrolled
+ * @param ?mixed $wcOnlySysopsCanPatrol config setting indicating whether the user needs to be a
+ * sysop in order to mark an edit patrolled.
+ * @param ?mixed $auto true if the edit is being marked as patrolled automatically
+ * @param ?mixed &$tags the tags to be applied to the patrol log entry
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onMarkPatrolled( $rcid, $user, $wcOnlySysopsCanPatrol, $auto,
+ &$tags
+ );
+}
diff --git a/includes/changes/Hook/OldChangesListRecentChangesLineHook.php b/includes/changes/Hook/OldChangesListRecentChangesLineHook.php
new file mode 100644
index 000000000000..d1608b5afb52
--- /dev/null
+++ b/includes/changes/Hook/OldChangesListRecentChangesLineHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface OldChangesListRecentChangesLineHook {
+ /**
+ * Customize entire recent changes line, or
+ * return false to omit the line from RecentChanges and Watchlist special pages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $changeslist The OldChangesList instance.
+ * @param ?mixed &$s HTML of the form "<li>...</li>" containing one RC entry.
+ * @param ?mixed $rc The RecentChange object.
+ * @param ?mixed &$classes array of css classes for the <li> element.
+ * @param ?mixed &$attribs associative array of other HTML attributes for the <li> element.
+ * Currently only data attributes reserved to MediaWiki are allowed
+ * (see Sanitizer::isReservedDataAttribute).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onOldChangesListRecentChangesLine( $changeslist, &$s, $rc,
+ &$classes, &$attribs
+ );
+}
diff --git a/includes/changes/Hook/RecentChange_saveHook.php b/includes/changes/Hook/RecentChange_saveHook.php
new file mode 100644
index 000000000000..f8bd18c2fb80
--- /dev/null
+++ b/includes/changes/Hook/RecentChange_saveHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface RecentChange_saveHook {
+ /**
+ * Called at the end of RecentChange::save().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $recentChange RecentChange object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onRecentChange_save( $recentChange );
+}
diff --git a/includes/changetags/Hook/ChangeTagAfterDeleteHook.php b/includes/changetags/Hook/ChangeTagAfterDeleteHook.php
new file mode 100644
index 000000000000..10d07c3eb2a5
--- /dev/null
+++ b/includes/changetags/Hook/ChangeTagAfterDeleteHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\ChangeTags\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangeTagAfterDeleteHook {
+ /**
+ * Called after a change tag has been deleted (that is,
+ * removed from all revisions and log entries to which it was applied). This gives
+ * extensions a chance to take it off their books.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $tag name of the tag
+ * @param ?mixed &$status Status object. Add warnings to this as required. There is no point
+ * setting errors, as the deletion has already been partly carried out by this
+ * point.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangeTagAfterDelete( $tag, &$status );
+}
diff --git a/includes/changetags/Hook/ChangeTagCanCreateHook.php b/includes/changetags/Hook/ChangeTagCanCreateHook.php
new file mode 100644
index 000000000000..d7f6b602d0cd
--- /dev/null
+++ b/includes/changetags/Hook/ChangeTagCanCreateHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\ChangeTags\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangeTagCanCreateHook {
+ /**
+ * Tell whether a change tag should be able to be created
+ * from the UI (Special:Tags) or via the API. You could use this hook if you want
+ * to reserve a specific "namespace" of tags, or something similar.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $tag name of the tag
+ * @param ?mixed $user user initiating the action
+ * @param ?mixed &$status Status object. Add your errors using `$status->fatal()` or warnings
+ * using `$status->warning()`. Errors and warnings will be relayed to the user.
+ * If you set an error, the user will be unable to create the tag.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangeTagCanCreate( $tag, $user, &$status );
+}
diff --git a/includes/changetags/Hook/ChangeTagCanDeleteHook.php b/includes/changetags/Hook/ChangeTagCanDeleteHook.php
new file mode 100644
index 000000000000..0b87e8daf935
--- /dev/null
+++ b/includes/changetags/Hook/ChangeTagCanDeleteHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\ChangeTags\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangeTagCanDeleteHook {
+ /**
+ * Tell whether a change tag should be able to be
+ * deleted from the UI (Special:Tags) or via the API. The default is that tags
+ * defined using the ListDefinedTags hook are not allowed to be deleted unless
+ * specifically allowed. If you wish to allow deletion of the tag, set
+ * `$status = Status::newGood()` to allow deletion, and then `return false` from
+ * the hook function. Ensure you consume the 'ChangeTagAfterDelete' hook to carry
+ * out custom deletion actions.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $tag name of the tag
+ * @param ?mixed $user user initiating the action
+ * @param ?mixed &$status Status object. See above.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangeTagCanDelete( $tag, $user, &$status );
+}
diff --git a/includes/changetags/Hook/ChangeTagsAfterUpdateTagsHook.php b/includes/changetags/Hook/ChangeTagsAfterUpdateTagsHook.php
new file mode 100644
index 000000000000..ac1b787c2bf5
--- /dev/null
+++ b/includes/changetags/Hook/ChangeTagsAfterUpdateTagsHook.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace MediaWiki\ChangeTags\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangeTagsAfterUpdateTagsHook {
+ /**
+ * Called after tags have been updated with the
+ * ChangeTags::updateTags function. Params:
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $addedTags tags effectively added in the update
+ * @param ?mixed $removedTags tags effectively removed in the update
+ * @param ?mixed $prevTags tags that were present prior to the update
+ * @param ?mixed $rc_id recentchanges table id
+ * @param ?mixed $rev_id revision table id
+ * @param ?mixed $log_id logging table id
+ * @param ?mixed $params tag params
+ * @param ?mixed $rc RecentChange being tagged when the tagging accompanies the action, or null
+ * @param ?mixed $user User who performed the tagging when the tagging is subsequent to the
+ * action, or null
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangeTagsAfterUpdateTags( $addedTags, $removedTags,
+ $prevTags, $rc_id, $rev_id, $log_id, $params, $rc, $user
+ );
+}
diff --git a/includes/changetags/Hook/ChangeTagsAllowedAddHook.php b/includes/changetags/Hook/ChangeTagsAllowedAddHook.php
new file mode 100644
index 000000000000..2b7b337beb67
--- /dev/null
+++ b/includes/changetags/Hook/ChangeTagsAllowedAddHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\ChangeTags\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangeTagsAllowedAddHook {
+ /**
+ * Called when checking if a user can add tags to a change.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$allowedTags List of all the tags the user is allowed to add. Any tags the
+ * user wants to add ($addTags) that are not in this array will cause it to fail.
+ * You may add or remove tags to this array as required.
+ * @param ?mixed $addTags List of tags user intends to add.
+ * @param ?mixed $user User who is adding the tags.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangeTagsAllowedAdd( &$allowedTags, $addTags, $user );
+}
diff --git a/includes/changetags/Hook/ChangeTagsListActiveHook.php b/includes/changetags/Hook/ChangeTagsListActiveHook.php
new file mode 100644
index 000000000000..b42bcb7e16d8
--- /dev/null
+++ b/includes/changetags/Hook/ChangeTagsListActiveHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\ChangeTags\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangeTagsListActiveHook {
+ /**
+ * Allows you to nominate which of the tags your extension
+ * uses are in active use.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tags list of all active tags. Append to this array.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangeTagsListActive( &$tags );
+}
diff --git a/includes/changetags/Hook/ListDefinedTagsHook.php b/includes/changetags/Hook/ListDefinedTagsHook.php
new file mode 100644
index 000000000000..64939b63e1dd
--- /dev/null
+++ b/includes/changetags/Hook/ListDefinedTagsHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\ChangeTags\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ListDefinedTagsHook {
+ /**
+ * When trying to find all defined tags.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tags The list of tags.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onListDefinedTags( &$tags );
+}
diff --git a/includes/collation/Hook/Collation__factoryHook.php b/includes/collation/Hook/Collation__factoryHook.php
new file mode 100644
index 000000000000..35356914faba
--- /dev/null
+++ b/includes/collation/Hook/Collation__factoryHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface Collation__factoryHook {
+ /**
+ * Called if $wgCategoryCollation is an unknown collation.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $collationName Name of the collation in question
+ * @param ?mixed &$collationObject Null. Replace with a subclass of the Collation class that
+ * implements the collation given in $collationName.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onCollation__factory( $collationName, &$collationObject );
+}
diff --git a/includes/content/Hook/ContentAlterParserOutputHook.php b/includes/content/Hook/ContentAlterParserOutputHook.php
new file mode 100644
index 000000000000..c8b5ebd15361
--- /dev/null
+++ b/includes/content/Hook/ContentAlterParserOutputHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContentAlterParserOutputHook {
+ /**
+ * Modify parser output for a given content object.
+ * Called by Content::getParserOutput after parsing has finished. Can be used
+ * for changes that depend on the result of the parsing but have to be done
+ * before LinksUpdate is called (such as adding tracking categories based on
+ * the rendered HTML).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $content The Content to render
+ * @param ?mixed $title Title of the page, as context
+ * @param ?mixed $parserOutput ParserOutput to manipulate
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContentAlterParserOutput( $content, $title, $parserOutput );
+}
diff --git a/includes/content/Hook/ContentGetParserOutputHook.php b/includes/content/Hook/ContentGetParserOutputHook.php
new file mode 100644
index 000000000000..4a8c9f857df5
--- /dev/null
+++ b/includes/content/Hook/ContentGetParserOutputHook.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContentGetParserOutputHook {
+ /**
+ * Customize parser output for a given content object,
+ * called by AbstractContent::getParserOutput. May be used to override the normal
+ * model-specific rendering of page content.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $content The Content to render
+ * @param ?mixed $title Title of the page, as context
+ * @param ?mixed $revId The revision ID, as context
+ * @param ?mixed $options ParserOptions for rendering. To avoid confusing the parser cache,
+ * the output can only depend on parameters provided to this hook function, not
+ * on global state.
+ * @param ?mixed $generateHtml boolean, indicating whether full HTML should be generated. If
+ * false, generation of HTML may be skipped, but other information should still
+ * be present in the ParserOutput object.
+ * @param ?mixed &$output ParserOutput, to manipulate or replace
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContentGetParserOutput( $content, $title, $revId, $options,
+ $generateHtml, &$output
+ );
+}
diff --git a/includes/content/Hook/ContentHandlerForModelIDHook.php b/includes/content/Hook/ContentHandlerForModelIDHook.php
new file mode 100644
index 000000000000..b5ca9d599090
--- /dev/null
+++ b/includes/content/Hook/ContentHandlerForModelIDHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContentHandlerForModelIDHook {
+ /**
+ * Called when a ContentHandler is requested for
+ * a given content model name, but no entry for that model exists in
+ * $wgContentHandlers.
+ * Note: if your extension implements additional models via this hook, please
+ * use GetContentModels hook to make them known to core.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $modeName the requested content model name
+ * @param ?mixed &$handler set this to a ContentHandler object, if desired.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContentHandlerForModelID( $modeName, &$handler );
+}
diff --git a/includes/content/Hook/ContentModelCanBeUsedOnHook.php b/includes/content/Hook/ContentModelCanBeUsedOnHook.php
new file mode 100644
index 000000000000..e0082d409958
--- /dev/null
+++ b/includes/content/Hook/ContentModelCanBeUsedOnHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContentModelCanBeUsedOnHook {
+ /**
+ * Called to determine whether that content model can
+ * be used on a given page. This is especially useful to prevent some content
+ * models to be used in some special location.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $contentModel ID of the content model in question
+ * @param ?mixed $title the Title in question.
+ * @param ?mixed &$ok Output parameter, whether it is OK to use $contentModel on $title.
+ * Handler functions that modify $ok should generally return false to prevent
+ * further hooks from further modifying $ok.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContentModelCanBeUsedOn( $contentModel, $title, &$ok );
+}
diff --git a/includes/content/Hook/ConvertContentHook.php b/includes/content/Hook/ConvertContentHook.php
new file mode 100644
index 000000000000..963db8e52342
--- /dev/null
+++ b/includes/content/Hook/ConvertContentHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ConvertContentHook {
+ /**
+ * Called by AbstractContent::convert when a conversion to
+ * another content model is requested.
+ * Handler functions that modify $result should generally return false to disable
+ * further attempts at conversion.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $content The Content object to be converted.
+ * @param ?mixed $toModel The ID of the content model to convert to.
+ * @param ?mixed $lossy boolean indicating whether lossy conversion is allowed.
+ * @param ?mixed &$result Output parameter, in case the handler function wants to provide a
+ * converted Content object. Note that $result->getContentModel() must return
+ * $toModel.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onConvertContent( $content, $toModel, $lossy, &$result );
+}
diff --git a/includes/content/Hook/GetContentModelsHook.php b/includes/content/Hook/GetContentModelsHook.php
new file mode 100644
index 000000000000..5bb369cc4157
--- /dev/null
+++ b/includes/content/Hook/GetContentModelsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+// phpcs:disable Generic.Files.LineLength -- Remove this after doc review
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetContentModelsHook {
+ /**
+ * Add content models to the list of available models.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$models array containing current model list, as strings. Extensions should add to this list.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetContentModels( &$models );
+}
diff --git a/includes/content/Hook/GetDifferenceEngineHook.php b/includes/content/Hook/GetDifferenceEngineHook.php
new file mode 100644
index 000000000000..680c59ea15bb
--- /dev/null
+++ b/includes/content/Hook/GetDifferenceEngineHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetDifferenceEngineHook {
+ /**
+ * Called when getting a new difference engine interface
+ * object. Can be used to decorate or replace the default difference engine.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $context IContextSource context to be used for diff
+ * @param ?mixed $old Revision ID to show and diff with
+ * @param ?mixed $new Either a revision ID or one of the strings 'cur', 'prev' or 'next'
+ * @param ?mixed $refreshCache If set, refreshes the diff cache
+ * @param ?mixed $unhide If set, allow viewing deleted revs
+ * @param ?mixed &$differenceEngine The difference engine object to be used for the diff
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetDifferenceEngine( $context, $old, $new, $refreshCache,
+ $unhide, &$differenceEngine
+ );
+}
diff --git a/includes/content/Hook/GetSlotDiffRendererHook.php b/includes/content/Hook/GetSlotDiffRendererHook.php
new file mode 100644
index 000000000000..b4cebcf42afd
--- /dev/null
+++ b/includes/content/Hook/GetSlotDiffRendererHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetSlotDiffRendererHook {
+ /**
+ * Replace or wrap the standard SlotDiffRenderer for some
+ * content type.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $contentHandler ContentHandler for which the slot diff renderer is fetched.
+ * @param ?mixed &$slotDiffRenderer SlotDiffRenderer to change or replace.
+ * @param ?mixed $context IContextSource
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetSlotDiffRenderer( $contentHandler, &$slotDiffRenderer,
+ $context
+ );
+}
diff --git a/includes/content/Hook/PageContentLanguageHook.php b/includes/content/Hook/PageContentLanguageHook.php
new file mode 100644
index 000000000000..7de29941c4f0
--- /dev/null
+++ b/includes/content/Hook/PageContentLanguageHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PageContentLanguageHook {
+ /**
+ * Allows changing the language in which the content of a
+ * page is written. Defaults to the wiki content language.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object
+ * @param ?mixed &$pageLang the page content language. Input can be anything (under control of
+ * hook subscribers), but hooks should return Language objects. Language code
+ * strings are deprecated.
+ * @param ?mixed $userLang the user language (Language object)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPageContentLanguage( $title, &$pageLang, $userLang );
+}
diff --git a/includes/content/Hook/PlaceNewSectionHook.php b/includes/content/Hook/PlaceNewSectionHook.php
new file mode 100644
index 000000000000..a2cf94fc6fc4
--- /dev/null
+++ b/includes/content/Hook/PlaceNewSectionHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PlaceNewSectionHook {
+ /**
+ * Override placement of new sections. Return false and put the
+ * merged text into $text to override the default behavior.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikipage WikiPage object
+ * @param ?mixed $oldtext the text of the article before editing
+ * @param ?mixed $subject subject of the new section
+ * @param ?mixed &$text text of the new section
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPlaceNewSection( $wikipage, $oldtext, $subject, &$text );
+}
diff --git a/includes/content/Hook/SearchDataForIndexHook.php b/includes/content/Hook/SearchDataForIndexHook.php
new file mode 100644
index 000000000000..84112e9e1ce8
--- /dev/null
+++ b/includes/content/Hook/SearchDataForIndexHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SearchDataForIndexHook {
+ /**
+ * Add data to search document. Allows to add any data to
+ * the field map used to index the document.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$fields Array of name => value pairs for fields
+ * @param ?mixed $handler ContentHandler for the content being indexed
+ * @param ?mixed $page WikiPage that is being indexed
+ * @param ?mixed $output ParserOutput that is produced from the page
+ * @param ?mixed $engine SearchEngine for which the indexing is intended
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSearchDataForIndex( &$fields, $handler, $page, $output,
+ $engine
+ );
+}
diff --git a/includes/content/Hook/SecondaryDataUpdatesHook.php b/includes/content/Hook/SecondaryDataUpdatesHook.php
new file mode 100644
index 000000000000..be07ce7a40e1
--- /dev/null
+++ b/includes/content/Hook/SecondaryDataUpdatesHook.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace MediaWiki\Content\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SecondaryDataUpdatesHook {
+ /**
+ * DEPRECATED since 1.32! Use RevisionDataUpdates or override
+ * ContentHandler::getSecondaryDataUpdates instead.
+ * Allows modification of the list of DataUpdates to perform when page content is modified.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title of the page that is being edited.
+ * @param ?mixed $oldContent Content object representing the page's content before the edit.
+ * @param ?mixed $recursive bool indicating whether DataUpdates should trigger recursive
+ * updates (relevant mostly for LinksUpdate).
+ * @param ?mixed $parserOutput ParserOutput representing the rendered version of the page
+ * after the edit.
+ * @param ?mixed &$updates a list of DataUpdate objects, to be modified or replaced by
+ * the hook handler.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSecondaryDataUpdates( $title, $oldContent, $recursive,
+ $parserOutput, &$updates
+ );
+}
diff --git a/includes/context/Hook/RequestContextCreateSkinHook.php b/includes/context/Hook/RequestContextCreateSkinHook.php
new file mode 100644
index 000000000000..e0f839735801
--- /dev/null
+++ b/includes/context/Hook/RequestContextCreateSkinHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface RequestContextCreateSkinHook {
+ /**
+ * Called when RequestContext::getSkin creates a skin
+ * instance. Can be used by an extension override what skin is used in certain
+ * contexts.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $context (IContextSource) The RequestContext the skin is being created for.
+ * @param ?mixed &$skin A variable reference you may set a Skin instance or string key on to
+ * override the skin that will be used for the context.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onRequestContextCreateSkin( $context, &$skin );
+}
diff --git a/includes/context/Hook/UserGetLanguageObjectHook.php b/includes/context/Hook/UserGetLanguageObjectHook.php
new file mode 100644
index 000000000000..f70428748e15
--- /dev/null
+++ b/includes/context/Hook/UserGetLanguageObjectHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserGetLanguageObjectHook {
+ /**
+ * Called when getting user's interface language object.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User object
+ * @param ?mixed &$code Language code that will be used to create the object
+ * @param ?mixed $context IContextSource object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserGetLanguageObject( $user, &$code, $context );
+}
diff --git a/includes/deferred/Hook/LinksUpdateAfterInsertHook.php b/includes/deferred/Hook/LinksUpdateAfterInsertHook.php
new file mode 100644
index 000000000000..37b02dd475d1
--- /dev/null
+++ b/includes/deferred/Hook/LinksUpdateAfterInsertHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LinksUpdateAfterInsertHook {
+ /**
+ * At the end of LinksUpdate::incrTableUpdate() after
+ * each link table insert. For example, pagelinks, imagelinks, externallinks.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $linksUpdate LinksUpdate object
+ * @param ?mixed $table the table to insert links to
+ * @param ?mixed $insertions an array of links to insert
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLinksUpdateAfterInsert( $linksUpdate, $table, $insertions );
+}
diff --git a/includes/deferred/Hook/LinksUpdateCompleteHook.php b/includes/deferred/Hook/LinksUpdateCompleteHook.php
new file mode 100644
index 000000000000..273fb5c5ded4
--- /dev/null
+++ b/includes/deferred/Hook/LinksUpdateCompleteHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LinksUpdateCompleteHook {
+ /**
+ * At the end of LinksUpdate::doUpdate() when updating,
+ * including delete and insert, has completed for all link tables
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $linksUpdate the LinksUpdate object
+ * @param ?mixed $ticket prior result of LBFactory::getEmptyTransactionTicket()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLinksUpdateComplete( $linksUpdate, $ticket );
+}
diff --git a/includes/deferred/Hook/LinksUpdateConstructedHook.php b/includes/deferred/Hook/LinksUpdateConstructedHook.php
new file mode 100644
index 000000000000..2c40389f9a74
--- /dev/null
+++ b/includes/deferred/Hook/LinksUpdateConstructedHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LinksUpdateConstructedHook {
+ /**
+ * At the end of LinksUpdate() is construction.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $linksUpdate the LinksUpdate object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLinksUpdateConstructed( $linksUpdate );
+}
diff --git a/includes/deferred/Hook/LinksUpdateHook.php b/includes/deferred/Hook/LinksUpdateHook.php
new file mode 100644
index 000000000000..54ad8c9ca4eb
--- /dev/null
+++ b/includes/deferred/Hook/LinksUpdateHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LinksUpdateHook {
+ /**
+ * At the beginning of LinksUpdate::doUpdate() just before the
+ * actual update.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $linksUpdate the LinksUpdate object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLinksUpdate( $linksUpdate );
+}
diff --git a/includes/diff/Hook/AbortDiffCacheHook.php b/includes/diff/Hook/AbortDiffCacheHook.php
new file mode 100644
index 000000000000..8bb28e84c815
--- /dev/null
+++ b/includes/diff/Hook/AbortDiffCacheHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AbortDiffCacheHook {
+ /**
+ * Can be used to cancel the caching of a diff.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $diffEngine DifferenceEngine object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAbortDiffCache( $diffEngine );
+}
diff --git a/includes/diff/Hook/ArticleContentOnDiffHook.php b/includes/diff/Hook/ArticleContentOnDiffHook.php
new file mode 100644
index 000000000000..7fe92877aaf2
--- /dev/null
+++ b/includes/diff/Hook/ArticleContentOnDiffHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleContentOnDiffHook {
+ /**
+ * Before showing the article content below a diff. Use
+ * this to change the content in this area or how it is loaded.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $diffEngine the DifferenceEngine
+ * @param ?mixed $output the OutputPage object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleContentOnDiff( $diffEngine, $output );
+}
diff --git a/includes/diff/Hook/DiffRevisionToolsHook.php b/includes/diff/Hook/DiffRevisionToolsHook.php
new file mode 100644
index 000000000000..dc468bdf4895
--- /dev/null
+++ b/includes/diff/Hook/DiffRevisionToolsHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DiffRevisionToolsHook {
+ /**
+ * Override or extend the revision tools available from the
+ * diff view, i.e. undo, etc.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $newRev Revision object of the "new" revision
+ * @param ?mixed &$links Array of HTML links
+ * @param ?mixed $oldRev Revision object of the "old" revision (may be null)
+ * @param ?mixed $user Current user object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDiffRevisionTools( $newRev, &$links, $oldRev, $user );
+}
diff --git a/includes/diff/Hook/DiffViewHeaderHook.php b/includes/diff/Hook/DiffViewHeaderHook.php
new file mode 100644
index 000000000000..580a6106f120
--- /dev/null
+++ b/includes/diff/Hook/DiffViewHeaderHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DiffViewHeaderHook {
+ /**
+ * Called before diff display
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $diff DifferenceEngine object that's calling
+ * @param ?mixed $oldRev Revision object of the "old" revision (may be null/invalid)
+ * @param ?mixed $newRev Revision object of the "new" revision
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDiffViewHeader( $diff, $oldRev, $newRev );
+}
diff --git a/includes/diff/Hook/DifferenceEngineAfterLoadNewTextHook.php b/includes/diff/Hook/DifferenceEngineAfterLoadNewTextHook.php
new file mode 100644
index 000000000000..e79218cfe970
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineAfterLoadNewTextHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineAfterLoadNewTextHook {
+ /**
+ * called in DifferenceEngine::loadNewText()
+ * after the new revision's content has been loaded into the class member variable
+ * $differenceEngine->mNewContent but before returning true from this function.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $differenceEngine DifferenceEngine object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineAfterLoadNewText( $differenceEngine );
+}
diff --git a/includes/diff/Hook/DifferenceEngineLoadTextAfterNewContentIsLoadedHook.php b/includes/diff/Hook/DifferenceEngineLoadTextAfterNewContentIsLoadedHook.php
new file mode 100644
index 000000000000..051a2f49fe1b
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineLoadTextAfterNewContentIsLoadedHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineLoadTextAfterNewContentIsLoadedHook {
+ /**
+ * called in
+ * DifferenceEngine::loadText() after the new revision's content has been loaded
+ * into the class member variable $differenceEngine->mNewContent but before
+ * checking if the variable's value is null.
+ * This hook can be used to inject content into said class member variable.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $differenceEngine DifferenceEngine object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineLoadTextAfterNewContentIsLoaded(
+ $differenceEngine
+ );
+}
diff --git a/includes/diff/Hook/DifferenceEngineMarkPatrolledLinkHook.php b/includes/diff/Hook/DifferenceEngineMarkPatrolledLinkHook.php
new file mode 100644
index 000000000000..296db56cf6c7
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineMarkPatrolledLinkHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineMarkPatrolledLinkHook {
+ /**
+ * Allows extensions to change the "mark as
+ * patrolled" link which is shown both on the diff header as well as on the bottom
+ * of a page, usually wrapped in a span element which has class="patrollink".
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $differenceEngine DifferenceEngine object
+ * @param ?mixed &$markAsPatrolledLink The "mark as patrolled" link HTML (string)
+ * @param ?mixed $rcid Recent change ID (rc_id) for this change (int)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineMarkPatrolledLink( $differenceEngine,
+ &$markAsPatrolledLink, $rcid
+ );
+}
diff --git a/includes/diff/Hook/DifferenceEngineMarkPatrolledRCIDHook.php b/includes/diff/Hook/DifferenceEngineMarkPatrolledRCIDHook.php
new file mode 100644
index 000000000000..1e828762fa10
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineMarkPatrolledRCIDHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineMarkPatrolledRCIDHook {
+ /**
+ * Allows extensions to possibly change the
+ * rcid parameter. For example the rcid might be set to zero due to the user being
+ * the same as the performer of the change but an extension might still want to
+ * show it under certain conditions.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$rcid rc_id (int) of the change or 0
+ * @param ?mixed $differenceEngine DifferenceEngine object
+ * @param ?mixed $change RecentChange object
+ * @param ?mixed $user User object representing the current user
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineMarkPatrolledRCID( &$rcid, $differenceEngine,
+ $change, $user
+ );
+}
diff --git a/includes/diff/Hook/DifferenceEngineNewHeaderHook.php b/includes/diff/Hook/DifferenceEngineNewHeaderHook.php
new file mode 100644
index 000000000000..68ed78aea706
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineNewHeaderHook.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineNewHeaderHook {
+ /**
+ * Allows extensions to change the $newHeader
+ * variable, which contains information about the new revision, such as the
+ * revision's author, whether the revision was marked as a minor edit or not, etc.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $differenceEngine DifferenceEngine object
+ * @param ?mixed &$newHeader The string containing the various #mw-diff-otitle[1-5] divs, which
+ * include things like revision author info, revision comment, RevisionDelete
+ * link and more
+ * @param ?mixed $formattedRevisionTools Array containing revision tools, some of which may have
+ * been injected with the DiffRevisionTools hook
+ * @param ?mixed $nextlink String containing the link to the next revision (if any); also
+ * included in $newHeader
+ * @param ?mixed $rollback Rollback link (string) to roll this revision back to the previous
+ * one, if any
+ * @param ?mixed $newminor String indicating if the new revision was marked as a minor edit
+ * @param ?mixed $diffOnly Boolean parameter passed to DifferenceEngine#showDiffPage, indicating
+ * whether we should show just the diff; passed in as a query string parameter to
+ * the various URLs constructed here (i.e. $nextlink)
+ * @param ?mixed $rdel RevisionDelete link for the new revision, if the current user is allowed
+ * to use the RevisionDelete feature
+ * @param ?mixed $unhide Boolean parameter indicating whether to show RevisionDeleted revisions
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineNewHeader( $differenceEngine, &$newHeader,
+ $formattedRevisionTools, $nextlink, $rollback, $newminor, $diffOnly, $rdel,
+ $unhide
+ );
+}
diff --git a/includes/diff/Hook/DifferenceEngineOldHeaderHook.php b/includes/diff/Hook/DifferenceEngineOldHeaderHook.php
new file mode 100644
index 000000000000..d00e8e1ccd66
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineOldHeaderHook.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineOldHeaderHook {
+ /**
+ * Allows extensions to change the $oldHeader
+ * variable, which contains information about the old revision, such as the
+ * revision's author, whether the revision was marked as a minor edit or not, etc.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $differenceEngine DifferenceEngine object
+ * @param ?mixed &$oldHeader The string containing the various #mw-diff-otitle[1-5] divs, which
+ * include things like revision author info, revision comment, RevisionDelete
+ * link and more
+ * @param ?mixed $prevlink String containing the link to the previous revision (if any); also
+ * included in $oldHeader
+ * @param ?mixed $oldminor String indicating if the old revision was marked as a minor edit
+ * @param ?mixed $diffOnly Boolean parameter passed to DifferenceEngine#showDiffPage, indicating
+ * whether we should show just the diff; passed in as a query string parameter to
+ * the various URLs constructed here (i.e. $prevlink)
+ * @param ?mixed $ldel RevisionDelete link for the old revision, if the current user is allowed
+ * to use the RevisionDelete feature
+ * @param ?mixed $unhide Boolean parameter indicating whether to show RevisionDeleted revisions
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineOldHeader( $differenceEngine, &$oldHeader,
+ $prevlink, $oldminor, $diffOnly, $ldel, $unhide
+ );
+}
diff --git a/includes/diff/Hook/DifferenceEngineOldHeaderNoOldRevHook.php b/includes/diff/Hook/DifferenceEngineOldHeaderNoOldRevHook.php
new file mode 100644
index 000000000000..8afe2533668d
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineOldHeaderNoOldRevHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineOldHeaderNoOldRevHook {
+ /**
+ * Change the $oldHeader variable in cases
+ * when there is no old revision
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$oldHeader empty string by default
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineOldHeaderNoOldRev( &$oldHeader );
+}
diff --git a/includes/diff/Hook/DifferenceEngineRenderRevisionAddParserOutputHook.php b/includes/diff/Hook/DifferenceEngineRenderRevisionAddParserOutputHook.php
new file mode 100644
index 000000000000..baae38a3cc88
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineRenderRevisionAddParserOutputHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineRenderRevisionAddParserOutputHook {
+ /**
+ * Allows extensions to change the
+ * parser output. Return false to not add parser output via OutputPage's
+ * addParserOutput method.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $differenceEngine DifferenceEngine object
+ * @param ?mixed $out OutputPage object
+ * @param ?mixed $parserOutput ParserOutput object
+ * @param ?mixed $wikiPage WikiPage object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineRenderRevisionAddParserOutput(
+ $differenceEngine, $out, $parserOutput, $wikiPage
+ );
+}
diff --git a/includes/diff/Hook/DifferenceEngineRenderRevisionShowFinalPatrolLinkHook.php b/includes/diff/Hook/DifferenceEngineRenderRevisionShowFinalPatrolLinkHook.php
new file mode 100644
index 000000000000..0b56979d0dbd
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineRenderRevisionShowFinalPatrolLinkHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineRenderRevisionShowFinalPatrolLinkHook {
+ /**
+ * An extension can hook into
+ * this hook point and return false to not show the final "mark as patrolled" link
+ * on the bottom of a page.
+ * This hook has no arguments.
+ *
+ * @since 1.35
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineRenderRevisionShowFinalPatrolLink();
+}
diff --git a/includes/diff/Hook/DifferenceEngineShowDiffHook.php b/includes/diff/Hook/DifferenceEngineShowDiffHook.php
new file mode 100644
index 000000000000..500be4e80f5d
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineShowDiffHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineShowDiffHook {
+ /**
+ * Allows extensions to affect the diff text which
+ * eventually gets sent to the OutputPage object.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $differenceEngine DifferenceEngine object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineShowDiff( $differenceEngine );
+}
diff --git a/includes/diff/Hook/DifferenceEngineShowDiffPageHook.php b/includes/diff/Hook/DifferenceEngineShowDiffPageHook.php
new file mode 100644
index 000000000000..7a6127b94b56
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineShowDiffPageHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineShowDiffPageHook {
+ /**
+ * Add additional output via the available
+ * OutputPage object into the diff view
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $out OutputPage object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineShowDiffPage( $out );
+}
diff --git a/includes/diff/Hook/DifferenceEngineShowDiffPageMaybeShowMissingRevisionHook.php b/includes/diff/Hook/DifferenceEngineShowDiffPageMaybeShowMissingRevisionHook.php
new file mode 100644
index 000000000000..0ccc3576437e
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineShowDiffPageMaybeShowMissingRevisionHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineShowDiffPageMaybeShowMissingRevisionHook {
+ /**
+ * called in
+ * DifferenceEngine::showDiffPage() when revision data cannot be loaded.
+ * Return false in order to prevent displaying the missing revision message
+ * (i.e. to prevent DifferenceEngine::showMissingRevision() from being called).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $differenceEngine DifferenceEngine object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineShowDiffPageMaybeShowMissingRevision(
+ $differenceEngine
+ );
+}
diff --git a/includes/diff/Hook/DifferenceEngineShowEmptyOldContentHook.php b/includes/diff/Hook/DifferenceEngineShowEmptyOldContentHook.php
new file mode 100644
index 000000000000..f9084ba1c98d
--- /dev/null
+++ b/includes/diff/Hook/DifferenceEngineShowEmptyOldContentHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DifferenceEngineShowEmptyOldContentHook {
+ /**
+ * Allows extensions to change the diff
+ * table body (without header) in cases when there is no old revision or the old
+ * and new revisions are identical.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $differenceEngine DifferenceEngine object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDifferenceEngineShowEmptyOldContent( $differenceEngine );
+}
diff --git a/includes/diff/Hook/NewDifferenceEngineHook.php b/includes/diff/Hook/NewDifferenceEngineHook.php
new file mode 100644
index 000000000000..111002833a22
--- /dev/null
+++ b/includes/diff/Hook/NewDifferenceEngineHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Diff\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface NewDifferenceEngineHook {
+ /**
+ * Called when a new DifferenceEngine object is made
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title the diff page title (nullable)
+ * @param ?mixed &$oldId the actual old Id to use in the diff
+ * @param ?mixed &$newId the actual new Id to use in the diff (0 means current)
+ * @param ?mixed $old the ?old= param value from the url
+ * @param ?mixed $new the ?new= param value from the url
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onNewDifferenceEngine( $title, &$oldId, &$newId, $old, $new );
+}
diff --git a/includes/exception/Hook/LogExceptionHook.php b/includes/exception/Hook/LogExceptionHook.php
new file mode 100644
index 000000000000..0b1ab109a1d6
--- /dev/null
+++ b/includes/exception/Hook/LogExceptionHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LogExceptionHook {
+ /**
+ * Called before an exception (or PHP error) is logged. This is
+ * meant for integration with external error aggregation services; returning false
+ * will NOT prevent logging.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $e The exception (in case of a plain old PHP error, a wrapping ErrorException)
+ * @param ?mixed $suppressed true if the error was suppressed via
+ * error_reporting()/wfSuppressWarnings()
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLogException( $e, $suppressed );
+}
diff --git a/includes/export/Hook/ModifyExportQueryHook.php b/includes/export/Hook/ModifyExportQueryHook.php
new file mode 100644
index 000000000000..b4017eaaf63c
--- /dev/null
+++ b/includes/export/Hook/ModifyExportQueryHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ModifyExportQueryHook {
+ /**
+ * Modify the query used by the exporter.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $db The database object to be queried.
+ * @param ?mixed &$tables Tables in the query.
+ * @param ?mixed &$conds Conditions in the query.
+ * @param ?mixed &$opts Options for the query.
+ * @param ?mixed &$join_conds Join conditions for the query.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onModifyExportQuery( $db, &$tables, &$conds, &$opts,
+ &$join_conds
+ );
+}
diff --git a/includes/export/Hook/WikiExporter__dumpStableQueryHook.php b/includes/export/Hook/WikiExporter__dumpStableQueryHook.php
new file mode 100644
index 000000000000..7f8c813952cb
--- /dev/null
+++ b/includes/export/Hook/WikiExporter__dumpStableQueryHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WikiExporter__dumpStableQueryHook {
+ /**
+ * Get the SELECT query for "stable" revisions
+ * dumps. One, and only one hook should set this, and return false.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tables Database tables to use in the SELECT query
+ * @param ?mixed &$opts Options to use for the query
+ * @param ?mixed &$join Join conditions
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWikiExporter__dumpStableQuery( &$tables, &$opts, &$join );
+}
diff --git a/includes/export/Hook/XmlDumpWriterOpenPageHook.php b/includes/export/Hook/XmlDumpWriterOpenPageHook.php
new file mode 100644
index 000000000000..4aff843d3890
--- /dev/null
+++ b/includes/export/Hook/XmlDumpWriterOpenPageHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface XmlDumpWriterOpenPageHook {
+ /**
+ * Called at the end of XmlDumpWriter::openPage, to allow
+ * extra metadata to be added.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $obj The XmlDumpWriter object.
+ * @param ?mixed &$out The output string.
+ * @param ?mixed $row The database row for the page.
+ * @param ?mixed $title The title of the page.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onXmlDumpWriterOpenPage( $obj, &$out, $row, $title );
+}
diff --git a/includes/export/Hook/XmlDumpWriterWriteRevisionHook.php b/includes/export/Hook/XmlDumpWriterWriteRevisionHook.php
new file mode 100644
index 000000000000..defd16b23090
--- /dev/null
+++ b/includes/export/Hook/XmlDumpWriterWriteRevisionHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface XmlDumpWriterWriteRevisionHook {
+ /**
+ * Called at the end of a revision in an XML dump, to
+ * add extra metadata.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $obj The XmlDumpWriter object.
+ * @param ?mixed &$out The text being output.
+ * @param ?mixed $row The database row for the revision being dumped. DEPRECATED, use $rev instead.
+ * @param ?mixed $text The revision text to be dumped. DEPRECATED, use $rev instead.
+ * @param ?mixed $rev The RevisionRecord that is being dumped to XML
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onXmlDumpWriterWriteRevision( $obj, &$out, $row, $text, $rev );
+}
diff --git a/includes/filerepo/Hook/FileTransformedHook.php b/includes/filerepo/Hook/FileTransformedHook.php
new file mode 100644
index 000000000000..75fe46d6dff9
--- /dev/null
+++ b/includes/filerepo/Hook/FileTransformedHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface FileTransformedHook {
+ /**
+ * When a file is transformed and moved into storage.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $file reference to the File object
+ * @param ?mixed $thumb the MediaTransformOutput object
+ * @param ?mixed $tmpThumbPath The temporary file system path of the transformed file
+ * @param ?mixed $thumbPath The permanent storage path of the transformed file
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onFileTransformed( $file, $thumb, $tmpThumbPath, $thumbPath );
+}
diff --git a/includes/filerepo/Hook/FileUploadHook.php b/includes/filerepo/Hook/FileUploadHook.php
new file mode 100644
index 000000000000..ea3305580ae8
--- /dev/null
+++ b/includes/filerepo/Hook/FileUploadHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface FileUploadHook {
+ /**
+ * When a file upload occurs.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $file Image object representing the file that was uploaded
+ * @param ?mixed $reupload Boolean indicating if there was a previously another image there or
+ * not (since 1.17)
+ * @param ?mixed $hasDescription Boolean indicating that there was already a description page
+ * and a new one from the comment wasn't created (since 1.17)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onFileUpload( $file, $reupload, $hasDescription );
+}
diff --git a/includes/filerepo/Hook/LocalFilePurgeThumbnailsHook.php b/includes/filerepo/Hook/LocalFilePurgeThumbnailsHook.php
new file mode 100644
index 000000000000..dfb5b060dc94
--- /dev/null
+++ b/includes/filerepo/Hook/LocalFilePurgeThumbnailsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LocalFilePurgeThumbnailsHook {
+ /**
+ * Called before thumbnails for a local file a purged.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $file the File object
+ * @param ?mixed $archiveName name of an old file version or false if it's the current one
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLocalFilePurgeThumbnails( $file, $archiveName );
+}
diff --git a/includes/filerepo/Hook/LocalFile__getHistoryHook.php b/includes/filerepo/Hook/LocalFile__getHistoryHook.php
new file mode 100644
index 000000000000..83aed5e0129b
--- /dev/null
+++ b/includes/filerepo/Hook/LocalFile__getHistoryHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LocalFile__getHistoryHook {
+ /**
+ * Called before file history query performed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $file the File object
+ * @param ?mixed &$tables tables
+ * @param ?mixed &$fields select fields
+ * @param ?mixed &$conds conditions
+ * @param ?mixed &$opts query options
+ * @param ?mixed &$join_conds JOIN conditions
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLocalFile__getHistory( $file, &$tables, &$fields, &$conds,
+ &$opts, &$join_conds
+ );
+}
diff --git a/includes/gallery/Hook/GalleryGetModesHook.php b/includes/gallery/Hook/GalleryGetModesHook.php
new file mode 100644
index 000000000000..db90284956aa
--- /dev/null
+++ b/includes/gallery/Hook/GalleryGetModesHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GalleryGetModesHook {
+ /**
+ * Get list of classes that can render different modes of a
+ * gallery.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$modeArray An associative array mapping mode names to classes that implement
+ * that mode. It is expected all registered classes are a subclass of
+ * ImageGalleryBase.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGalleryGetModes( &$modeArray );
+}
diff --git a/includes/import/Hook/AfterImportPageHook.php b/includes/import/Hook/AfterImportPageHook.php
new file mode 100644
index 000000000000..15feb20fe2d6
--- /dev/null
+++ b/includes/import/Hook/AfterImportPageHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AfterImportPageHook {
+ /**
+ * When a page import is completed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title under which the revisions were imported
+ * @param ?mixed $foreignTitle ForeignTitle object based on data provided by the XML file
+ * @param ?mixed $revCount Number of revisions in the XML file
+ * @param ?mixed $sRevCount Number of successfully imported revisions
+ * @param ?mixed $pageInfo associative array of page information
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAfterImportPage( $title, $foreignTitle, $revCount,
+ $sRevCount, $pageInfo
+ );
+}
diff --git a/includes/import/Hook/ImportHandleLogItemXMLTagHook.php b/includes/import/Hook/ImportHandleLogItemXMLTagHook.php
new file mode 100644
index 000000000000..bdaed3d34b41
--- /dev/null
+++ b/includes/import/Hook/ImportHandleLogItemXMLTagHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImportHandleLogItemXMLTagHook {
+ /**
+ * When parsing a XML tag in a log item.
+ * Return false to stop further processing of the tag
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $reader XMLReader object
+ * @param ?mixed $logInfo Array of information
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImportHandleLogItemXMLTag( $reader, $logInfo );
+}
diff --git a/includes/import/Hook/ImportHandlePageXMLTagHook.php b/includes/import/Hook/ImportHandlePageXMLTagHook.php
new file mode 100644
index 000000000000..d70a526df5cf
--- /dev/null
+++ b/includes/import/Hook/ImportHandlePageXMLTagHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImportHandlePageXMLTagHook {
+ /**
+ * When parsing a XML tag in a page.
+ * Return false to stop further processing of the tag
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $reader XMLReader object
+ * @param ?mixed &$pageInfo Array of information
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImportHandlePageXMLTag( $reader, &$pageInfo );
+}
diff --git a/includes/import/Hook/ImportHandleRevisionXMLTagHook.php b/includes/import/Hook/ImportHandleRevisionXMLTagHook.php
new file mode 100644
index 000000000000..a413ee8d6352
--- /dev/null
+++ b/includes/import/Hook/ImportHandleRevisionXMLTagHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImportHandleRevisionXMLTagHook {
+ /**
+ * When parsing a XML tag in a page revision.
+ * Return false to stop further processing of the tag
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $reader XMLReader object
+ * @param ?mixed $pageInfo Array of page information
+ * @param ?mixed $revisionInfo Array of revision information
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImportHandleRevisionXMLTag( $reader, $pageInfo,
+ $revisionInfo
+ );
+}
diff --git a/includes/import/Hook/ImportHandleToplevelXMLTagHook.php b/includes/import/Hook/ImportHandleToplevelXMLTagHook.php
new file mode 100644
index 000000000000..c2a4f352ef82
--- /dev/null
+++ b/includes/import/Hook/ImportHandleToplevelXMLTagHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImportHandleToplevelXMLTagHook {
+ /**
+ * When parsing a top level XML tag.
+ * Return false to stop further processing of the tag
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $reader XMLReader object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImportHandleToplevelXMLTag( $reader );
+}
diff --git a/includes/import/Hook/ImportHandleUploadXMLTagHook.php b/includes/import/Hook/ImportHandleUploadXMLTagHook.php
new file mode 100644
index 000000000000..3c46117f68e6
--- /dev/null
+++ b/includes/import/Hook/ImportHandleUploadXMLTagHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImportHandleUploadXMLTagHook {
+ /**
+ * When parsing a XML tag in a file upload.
+ * Return false to stop further processing of the tag
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $reader XMLReader object
+ * @param ?mixed $revisionInfo Array of information
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImportHandleUploadXMLTag( $reader, $revisionInfo );
+}
diff --git a/includes/installer/Hook/LoadExtensionSchemaUpdatesHook.php b/includes/installer/Hook/LoadExtensionSchemaUpdatesHook.php
new file mode 100644
index 000000000000..e2ea97783e7c
--- /dev/null
+++ b/includes/installer/Hook/LoadExtensionSchemaUpdatesHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Installer\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LoadExtensionSchemaUpdatesHook {
+ /**
+ * Called during database installation and updates.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $updater A DatabaseUpdater subclass
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLoadExtensionSchemaUpdates( $updater );
+}
diff --git a/includes/interwiki/Hook/InterwikiLoadPrefixHook.php b/includes/interwiki/Hook/InterwikiLoadPrefixHook.php
new file mode 100644
index 000000000000..acfc9d18e022
--- /dev/null
+++ b/includes/interwiki/Hook/InterwikiLoadPrefixHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Interwiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface InterwikiLoadPrefixHook {
+ /**
+ * When resolving if a given prefix is an interwiki or not.
+ * Return true without providing an interwiki to continue interwiki search.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $prefix interwiki prefix we are looking for.
+ * @param ?mixed &$iwData output array describing the interwiki with keys iw_url, iw_local,
+ * iw_trans and optionally iw_api and iw_wikiid.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onInterwikiLoadPrefix( $prefix, &$iwData );
+}
diff --git a/includes/jobqueue/jobs/Hook/RecentChangesPurgeRowsHook.php b/includes/jobqueue/jobs/Hook/RecentChangesPurgeRowsHook.php
new file mode 100644
index 000000000000..c6dd5abcaa84
--- /dev/null
+++ b/includes/jobqueue/jobs/Hook/RecentChangesPurgeRowsHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface RecentChangesPurgeRowsHook {
+ /**
+ * Called when old recentchanges rows are purged, after
+ * deleting those rows but within the same transaction.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $rows The deleted rows as an array of recentchanges row objects (with up to
+ * $wgUpdateRowsPerQuery items).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onRecentChangesPurgeRows( $rows );
+}
diff --git a/includes/language/Hook/LanguageGetTranslatedLanguageNamesHook.php b/includes/language/Hook/LanguageGetTranslatedLanguageNamesHook.php
new file mode 100644
index 000000000000..0a2e6d0b36b2
--- /dev/null
+++ b/includes/language/Hook/LanguageGetTranslatedLanguageNamesHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Languages\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LanguageGetTranslatedLanguageNamesHook {
+ /**
+ * Provide translated language names.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$names array of language code => language name
+ * @param ?mixed $code language of the preferred translations
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLanguageGetTranslatedLanguageNames( &$names, $code );
+}
diff --git a/includes/language/Hook/Language__getMessagesFileNameHook.php b/includes/language/Hook/Language__getMessagesFileNameHook.php
new file mode 100644
index 000000000000..ec5eb03a2967
--- /dev/null
+++ b/includes/language/Hook/Language__getMessagesFileNameHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Languages\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface Language__getMessagesFileNameHook {
+ /**
+ * @since 1.35
+ *
+ * @param ?mixed $code The language code or the language we're looking for a messages file for
+ * @param ?mixed &$file The messages file path, you can override this to change the location.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLanguage__getMessagesFileName( $code, &$file );
+}
diff --git a/includes/linker/Hook/HtmlPageLinkRendererBeginHook.php b/includes/linker/Hook/HtmlPageLinkRendererBeginHook.php
new file mode 100644
index 000000000000..c1cd0b37e4e1
--- /dev/null
+++ b/includes/linker/Hook/HtmlPageLinkRendererBeginHook.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace MediaWiki\Linker\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface HtmlPageLinkRendererBeginHook {
+ /**
+ * Used when generating internal and interwiki links in
+ * LinkRenderer, before processing starts. Return false to skip default
+ * processing and return $ret.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $linkRenderer the LinkRenderer object
+ * @param ?mixed $target the LinkTarget that the link is pointing to
+ * @param ?mixed &$text the contents that the <a> tag should have; either a plain, unescaped
+ * string or a HtmlArmor object; null means "default".
+ * @param ?mixed &$customAttribs the HTML attributes that the <a> tag should have, in
+ * associative array form, with keys and values unescaped. Should be merged
+ * with default values, with a value of false meaning to suppress the
+ * attribute.
+ * @param ?mixed &$query the query string to add to the generated URL (the bit after the "?"),
+ * in associative array form, with keys and values unescaped.
+ * @param ?mixed &$ret the value to return if your hook returns false.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onHtmlPageLinkRendererBegin( $linkRenderer, $target, &$text,
+ &$customAttribs, &$query, &$ret
+ );
+}
diff --git a/includes/linker/Hook/HtmlPageLinkRendererEndHook.php b/includes/linker/Hook/HtmlPageLinkRendererEndHook.php
new file mode 100644
index 000000000000..8a8e1f0bc5a0
--- /dev/null
+++ b/includes/linker/Hook/HtmlPageLinkRendererEndHook.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace MediaWiki\Linker\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface HtmlPageLinkRendererEndHook {
+ /**
+ * Used when generating internal and interwiki links in LinkRenderer,
+ * just before the function returns a value. If you return true, an <a> element
+ * with HTML attributes $attribs and contents $html will be returned. If you
+ * return false, $ret will be returned.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $linkRenderer the LinkRenderer object
+ * @param ?mixed $target the LinkTarget object that the link is pointing to
+ * @param ?mixed $isKnown boolean indicating whether the page is known or not
+ * @param ?mixed &$text the contents that the <a> tag should have; either a plain, unescaped
+ * string or a HtmlArmor object.
+ * @param ?mixed &$attribs the final HTML attributes of the <a> tag, after processing, in
+ * associative array form.
+ * @param ?mixed &$ret the value to return if your hook returns false.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onHtmlPageLinkRendererEnd( $linkRenderer, $target, $isKnown,
+ &$text, &$attribs, &$ret
+ );
+}
diff --git a/includes/linker/Hook/LinkBeginHook.php b/includes/linker/Hook/LinkBeginHook.php
new file mode 100644
index 000000000000..71466be4f72f
--- /dev/null
+++ b/includes/linker/Hook/LinkBeginHook.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace MediaWiki\Linker\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LinkBeginHook {
+ /**
+ * DEPRECATED since 1.28! Use HtmlPageLinkRendererBegin instead.
+ * Used when generating internal and interwiki links in Linker::link(), before
+ * processing starts. Return false to skip default processing and return $ret. See
+ * documentation for Linker::link() for details on the expected meanings of
+ * parameters.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $skin the Skin object
+ * @param ?mixed $target the Title that the link is pointing to
+ * @param ?mixed &$html the contents that the <a> tag should have (raw HTML); null means
+ * "default".
+ * @param ?mixed &$customAttribs the HTML attributes that the <a> tag should have, in
+ * associative array form, with keys and values unescaped. Should be merged
+ * with default values, with a value of false meaning to suppress the
+ * attribute.
+ * @param ?mixed &$query the query string to add to the generated URL (the bit after the "?"),
+ * in associative array form, with keys and values unescaped.
+ * @param ?mixed &$options array of options. Can include 'known', 'broken', 'noclasses'.
+ * @param ?mixed &$ret the value to return if your hook returns false.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLinkBegin( $skin, $target, &$html, &$customAttribs, &$query,
+ &$options, &$ret
+ );
+}
diff --git a/includes/linker/Hook/LinkEndHook.php b/includes/linker/Hook/LinkEndHook.php
new file mode 100644
index 000000000000..7d1c7355557f
--- /dev/null
+++ b/includes/linker/Hook/LinkEndHook.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace MediaWiki\Linker\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LinkEndHook {
+ /**
+ * DEPRECATED since 1.28! Use HtmlPageLinkRendererEnd hook instead
+ * Used when generating internal and interwiki links in Linker::link(),
+ * just before the function returns a value. If you return true, an <a> element
+ * with HTML attributes $attribs and contents $html will be returned. If you
+ * return false, $ret will be returned.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $skin the Skin object
+ * @param ?mixed $target the Title object that the link is pointing to
+ * @param ?mixed $options the options. Will always include either 'known' or 'broken', and may
+ * include 'noclasses'.
+ * @param ?mixed &$html the final (raw HTML) contents of the <a> tag, after processing.
+ * @param ?mixed &$attribs the final HTML attributes of the <a> tag, after processing, in
+ * associative array form.
+ * @param ?mixed &$ret the value to return if your hook returns false.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLinkEnd( $skin, $target, $options, &$html, &$attribs, &$ret );
+}
diff --git a/includes/logging/Hook/LogEventsListGetExtraInputsHook.php b/includes/logging/Hook/LogEventsListGetExtraInputsHook.php
new file mode 100644
index 000000000000..4c5880e42b85
--- /dev/null
+++ b/includes/logging/Hook/LogEventsListGetExtraInputsHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LogEventsListGetExtraInputsHook {
+ /**
+ * When getting extra inputs to display on
+ * Special:Log for a specific log type
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $type String of log type being displayed
+ * @param ?mixed $logEventsList LogEventsList object for context and access to the WebRequest
+ * @param ?mixed &$input string HTML of an input element (deprecated, use $formDescriptor instead)
+ * @param ?mixed &$formDescriptor array HTMLForm's form descriptor
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLogEventsListGetExtraInputs( $type, $logEventsList, &$input,
+ &$formDescriptor
+ );
+}
diff --git a/includes/logging/Hook/LogEventsListLineEndingHook.php b/includes/logging/Hook/LogEventsListLineEndingHook.php
new file mode 100644
index 000000000000..db93ab65fa30
--- /dev/null
+++ b/includes/logging/Hook/LogEventsListLineEndingHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LogEventsListLineEndingHook {
+ /**
+ * Called before a Special:Log line is finished
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $page the LogEventsList object
+ * @param ?mixed &$ret the HTML line
+ * @param ?mixed $entry the DatabaseLogEntry object for this row
+ * @param ?mixed &$classes the classes to add to the surrounding <li>
+ * @param ?mixed &$attribs associative array of other HTML attributes for the <li> element.
+ * Currently only data attributes reserved to MediaWiki are allowed
+ * (see Sanitizer::isReservedDataAttribute).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLogEventsListLineEnding( $page, &$ret, $entry, &$classes,
+ &$attribs
+ );
+}
diff --git a/includes/logging/Hook/LogEventsListShowLogExtractHook.php b/includes/logging/Hook/LogEventsListShowLogExtractHook.php
new file mode 100644
index 000000000000..b5de7bb3a4a1
--- /dev/null
+++ b/includes/logging/Hook/LogEventsListShowLogExtractHook.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LogEventsListShowLogExtractHook {
+ /**
+ * Called before the string is added to OutputPage.
+ * Returning false will prevent the string from being added to the OutputPage.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$s html string to show for the log extract
+ * @param ?mixed $types String or Array Log types to show
+ * @param ?mixed $page String or Title The page title to show log entries for
+ * @param ?mixed $user String The user who made the log entries
+ * @param ?mixed $param Associative Array with the following additional options:
+ * - lim Integer Limit of items to show, default is 50
+ * - conds Array Extra conditions for the query (e.g. "log_action != 'revision'")
+ * - showIfEmpty boolean Set to false if you don't want any output in case the
+ * loglist is empty if set to true (default), "No matching items in log" is
+ * displayed if loglist is empty
+ * - msgKey Array If you want a nice box with a message, set this to the key of
+ * the message. First element is the message key, additional optional elements
+ * are parameters for the key that are processed with
+ * wfMessage()->params()->parseAsBlock()
+ * - offset Set to overwrite offset parameter in $wgRequest set to '' to unset
+ * offset
+ * - wrap String Wrap the message in html (usually something like
+ * "&lt;div ...>$1&lt;/div>").
+ * - flags Integer display flags (NO_ACTION_LINK,NO_EXTRA_USER_LINKS)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLogEventsListShowLogExtract( &$s, $types, $page, $user,
+ $param
+ );
+}
diff --git a/includes/logging/Hook/LogLineHook.php b/includes/logging/Hook/LogLineHook.php
new file mode 100644
index 000000000000..93f80210d6a9
--- /dev/null
+++ b/includes/logging/Hook/LogLineHook.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LogLineHook {
+ /**
+ * Processes a single log entry on Special:Log.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $log_type string for the type of log entry (e.g. 'move'). Corresponds to
+ * logging.log_type database field.
+ * @param ?mixed $log_action string for the type of log action (e.g. 'delete', 'block',
+ * 'create2'). Corresponds to logging.log_action database field.
+ * @param ?mixed $title Title object that corresponds to logging.log_namespace and
+ * logging.log_title database fields.
+ * @param ?mixed $paramArray Array of parameters that corresponds to logging.log_params field.
+ * Note that only $paramArray[0] appears to contain anything.
+ * @param ?mixed &$comment string that corresponds to logging.log_comment database field, and
+ * which is displayed in the UI.
+ * @param ?mixed &$revert string that is displayed in the UI, similar to $comment.
+ * @param ?mixed $time timestamp of the log entry (added in 1.12)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLogLine( $log_type, $log_action, $title, $paramArray,
+ &$comment, &$revert, $time
+ );
+}
diff --git a/includes/logging/Hook/ManualLogEntryBeforePublishHook.php b/includes/logging/Hook/ManualLogEntryBeforePublishHook.php
new file mode 100644
index 000000000000..b783ea25f907
--- /dev/null
+++ b/includes/logging/Hook/ManualLogEntryBeforePublishHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ManualLogEntryBeforePublishHook {
+ /**
+ * Allows to access or modify log entry just before it is
+ * published.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $logEntry ManualLogEntry object
+ * @return bool|void This hook must not abort, it must return true or null.
+ */
+ public function onManualLogEntryBeforePublish( $logEntry );
+}
diff --git a/includes/mail/Hook/AbortTalkPageEmailNotificationHook.php b/includes/mail/Hook/AbortTalkPageEmailNotificationHook.php
new file mode 100644
index 000000000000..436210caccf9
--- /dev/null
+++ b/includes/mail/Hook/AbortTalkPageEmailNotificationHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AbortTalkPageEmailNotificationHook {
+ /**
+ * Return false to cancel talk page email
+ * notification
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $targetUser the user whom to send talk page email notification
+ * @param ?mixed $title the page title
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAbortTalkPageEmailNotification( $targetUser, $title );
+}
diff --git a/includes/mail/Hook/AlternateUserMailerHook.php b/includes/mail/Hook/AlternateUserMailerHook.php
new file mode 100644
index 000000000000..f8cce0224374
--- /dev/null
+++ b/includes/mail/Hook/AlternateUserMailerHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AlternateUserMailerHook {
+ /**
+ * Called before mail is sent so that mail could be logged
+ * (or something else) instead of using PEAR or PHP's mail(). Return false to skip
+ * the regular method of sending mail. Return a string to return a php-mail-error
+ * message containing the error. Returning true will continue with sending email
+ * in the regular way.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $headers Associative array of headers for the email
+ * @param ?mixed $to MailAddress object or array
+ * @param ?mixed $from From address
+ * @param ?mixed $subject Subject of the email
+ * @param ?mixed $body Body of the message
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAlternateUserMailer( $headers, $to, $from, $subject, $body );
+}
diff --git a/includes/mail/Hook/SendWatchlistEmailNotificationHook.php b/includes/mail/Hook/SendWatchlistEmailNotificationHook.php
new file mode 100644
index 000000000000..f5dbba897fb2
--- /dev/null
+++ b/includes/mail/Hook/SendWatchlistEmailNotificationHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SendWatchlistEmailNotificationHook {
+ /**
+ * Return true to send watchlist email
+ * notification
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $targetUser the user whom to send watchlist email notification
+ * @param ?mixed $title the page title
+ * @param ?mixed $enotif EmailNotification object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSendWatchlistEmailNotification( $targetUser, $title, $enotif );
+}
diff --git a/includes/mail/Hook/UpdateUserMailerFormattedPageStatusHook.php b/includes/mail/Hook/UpdateUserMailerFormattedPageStatusHook.php
new file mode 100644
index 000000000000..36b5ffc06e73
--- /dev/null
+++ b/includes/mail/Hook/UpdateUserMailerFormattedPageStatusHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UpdateUserMailerFormattedPageStatusHook {
+ /**
+ * Before notification email gets sent.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$formattedPageStatus list of valid page states
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUpdateUserMailerFormattedPageStatus( &$formattedPageStatus );
+}
diff --git a/includes/mail/Hook/UserMailerChangeReturnPathHook.php b/includes/mail/Hook/UserMailerChangeReturnPathHook.php
new file mode 100644
index 000000000000..9ec19a1ce573
--- /dev/null
+++ b/includes/mail/Hook/UserMailerChangeReturnPathHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserMailerChangeReturnPathHook {
+ /**
+ * Called to generate a VERP return address
+ * when UserMailer sends an email, with a bounce handling extension.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $to Array of MailAddress objects for the recipients
+ * @param ?mixed &$returnPath The return address string
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserMailerChangeReturnPath( $to, &$returnPath );
+}
diff --git a/includes/mail/Hook/UserMailerSplitToHook.php b/includes/mail/Hook/UserMailerSplitToHook.php
new file mode 100644
index 000000000000..6d816575d344
--- /dev/null
+++ b/includes/mail/Hook/UserMailerSplitToHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserMailerSplitToHook {
+ /**
+ * Called in UserMailer::send() to give extensions a chance
+ * to split up an email with multiple the To: field into separate emails.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$to array of MailAddress objects; unset the ones which should be mailed
+ * separately
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserMailerSplitTo( &$to );
+}
diff --git a/includes/mail/Hook/UserMailerTransformContentHook.php b/includes/mail/Hook/UserMailerTransformContentHook.php
new file mode 100644
index 000000000000..276afe6bfaca
--- /dev/null
+++ b/includes/mail/Hook/UserMailerTransformContentHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserMailerTransformContentHook {
+ /**
+ * Called in UserMailer::send() to change email
+ * contents. Extensions can block sending the email by returning false and setting
+ * $error.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $to array of MailAdresses of the targets
+ * @param ?mixed $from MailAddress of the sender
+ * @param ?mixed &$body email body, either a string (for plaintext emails) or an array with
+ * 'text' and 'html' keys
+ * @param ?mixed &$error should be set to an error message string
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserMailerTransformContent( $to, $from, &$body, &$error );
+}
diff --git a/includes/mail/Hook/UserMailerTransformMessageHook.php b/includes/mail/Hook/UserMailerTransformMessageHook.php
new file mode 100644
index 000000000000..2b4508fd32de
--- /dev/null
+++ b/includes/mail/Hook/UserMailerTransformMessageHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserMailerTransformMessageHook {
+ /**
+ * Called in UserMailer::send() to change email after
+ * it has gone through the MIME transform. Extensions can block sending the email
+ * by returning false and setting $error.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $to array of MailAdresses of the targets
+ * @param ?mixed $from MailAddress of the sender
+ * @param ?mixed &$subject email subject (not MIME encoded)
+ * @param ?mixed &$headers email headers (except To: and Subject:) as an array of header
+ * name => value pairs
+ * @param ?mixed &$body email body (in MIME format) as a string
+ * @param ?mixed &$error should be set to an error message string
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserMailerTransformMessage( $to, $from, &$subject, &$headers,
+ &$body, &$error
+ );
+}
diff --git a/includes/media/Hook/BitmapHandlerCheckImageAreaHook.php b/includes/media/Hook/BitmapHandlerCheckImageAreaHook.php
new file mode 100644
index 000000000000..b3de2265fb81
--- /dev/null
+++ b/includes/media/Hook/BitmapHandlerCheckImageAreaHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BitmapHandlerCheckImageAreaHook {
+ /**
+ * By BitmapHandler::normaliseParams, after all
+ * normalizations have been performed, except for the $wgMaxImageArea check.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $image File
+ * @param ?mixed &$params Array of parameters
+ * @param ?mixed &$checkImageAreaHookResult null, set to true or false to override the
+ * $wgMaxImageArea check result.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBitmapHandlerCheckImageArea( $image, &$params,
+ &$checkImageAreaHookResult
+ );
+}
diff --git a/includes/media/Hook/BitmapHandlerTransformHook.php b/includes/media/Hook/BitmapHandlerTransformHook.php
new file mode 100644
index 000000000000..f5da6a64a333
--- /dev/null
+++ b/includes/media/Hook/BitmapHandlerTransformHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BitmapHandlerTransformHook {
+ /**
+ * before a file is transformed, gives extension the
+ * possibility to transform it themselves
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $handler BitmapHandler
+ * @param ?mixed $image File
+ * @param ?mixed &$scalerParams Array with scaler parameters
+ * @param ?mixed &$mto null, set to a MediaTransformOutput
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBitmapHandlerTransform( $handler, $image, &$scalerParams,
+ &$mto
+ );
+}
diff --git a/includes/media/Hook/GetExtendedMetadataHook.php b/includes/media/Hook/GetExtendedMetadataHook.php
new file mode 100644
index 000000000000..1483d74d5349
--- /dev/null
+++ b/includes/media/Hook/GetExtendedMetadataHook.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetExtendedMetadataHook {
+ /**
+ * Get extended file metadata for the API
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$combinedMeta Array of the form:
+ * 'MetadataPropName' => [
+ * value' => prop value,
+ * 'source' => 'name of hook'
+ * ].
+ * @param ?mixed $file File object of file in question
+ * @param ?mixed $context RequestContext (including language to use)
+ * @param ?mixed $single Only extract the current language; if false, the prop value should
+ * be in the metadata multi-language array format:
+ * mediawiki.org/wiki/Manual:File_metadata_handling#Multi-language_array_format
+ * @param ?mixed &$maxCacheTime how long the results can be cached
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetExtendedMetadata( &$combinedMeta, $file, $context,
+ $single, &$maxCacheTime
+ );
+}
diff --git a/includes/media/Hook/GetMetadataVersionHook.php b/includes/media/Hook/GetMetadataVersionHook.php
new file mode 100644
index 000000000000..11c2c56aa716
--- /dev/null
+++ b/includes/media/Hook/GetMetadataVersionHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetMetadataVersionHook {
+ /**
+ * Modify the image metadata version currently in use. This
+ * is used when requesting image metadata from a ForeignApiRepo. Media handlers
+ * that need to have versioned metadata should add an element to the end of the
+ * version array of the form 'handler_name=version'. Most media handlers won't need
+ * to do this unless they broke backwards compatibility with a previous version of
+ * the media handler metadata output.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$version Array of version strings
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetMetadataVersion( &$version );
+}
diff --git a/includes/media/Hook/ThumbnailBeforeProduceHTMLHook.php b/includes/media/Hook/ThumbnailBeforeProduceHTMLHook.php
new file mode 100644
index 000000000000..297932cffb44
--- /dev/null
+++ b/includes/media/Hook/ThumbnailBeforeProduceHTMLHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ThumbnailBeforeProduceHTMLHook {
+ /**
+ * Called before an image HTML is about to be
+ * rendered (by ThumbnailImage:toHtml method).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $thumbnail the ThumbnailImage object
+ * @param ?mixed &$attribs image attribute array
+ * @param ?mixed &$linkAttribs image link attribute array
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onThumbnailBeforeProduceHTML( $thumbnail, &$attribs,
+ &$linkAttribs
+ );
+}
diff --git a/includes/media/Hook/ValidateExtendedMetadataCacheHook.php b/includes/media/Hook/ValidateExtendedMetadataCacheHook.php
new file mode 100644
index 000000000000..f2789fbf7928
--- /dev/null
+++ b/includes/media/Hook/ValidateExtendedMetadataCacheHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ValidateExtendedMetadataCacheHook {
+ /**
+ * Called to validate the cached metadata in
+ * FormatMetadata::getExtendedMeta (return false means cache will be
+ * invalidated and GetExtendedMetadata hook called again).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $timestamp The timestamp metadata was generated
+ * @param ?mixed $file The file the metadata is for
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onValidateExtendedMetadataCache( $timestamp, $file );
+}
diff --git a/includes/page/Hook/ArticleConfirmDeleteHook.php b/includes/page/Hook/ArticleConfirmDeleteHook.php
new file mode 100644
index 000000000000..cf49df780071
--- /dev/null
+++ b/includes/page/Hook/ArticleConfirmDeleteHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleConfirmDeleteHook {
+ /**
+ * Before writing the confirmation form for article
+ * deletion.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article the article (object) being deleted
+ * @param ?mixed $output the OutputPage object
+ * @param ?mixed &$reason the reason (string) the article is being deleted
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleConfirmDelete( $article, $output, &$reason );
+}
diff --git a/includes/page/Hook/ArticleDeleteAfterSuccessHook.php b/includes/page/Hook/ArticleDeleteAfterSuccessHook.php
new file mode 100644
index 000000000000..b76e0454fe9b
--- /dev/null
+++ b/includes/page/Hook/ArticleDeleteAfterSuccessHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleDeleteAfterSuccessHook {
+ /**
+ * Output after an article has been deleted.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title of the article that has been deleted.
+ * @param ?mixed $outputPage OutputPage that can be used to append the output.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleDeleteAfterSuccess( $title, $outputPage );
+}
diff --git a/includes/page/Hook/ArticleDeleteCompleteHook.php b/includes/page/Hook/ArticleDeleteCompleteHook.php
new file mode 100644
index 000000000000..9526c5578cc7
--- /dev/null
+++ b/includes/page/Hook/ArticleDeleteCompleteHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleDeleteCompleteHook {
+ /**
+ * After an article is deleted.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage the WikiPage that was deleted
+ * @param ?mixed $user the user that deleted the article
+ * @param ?mixed $reason the reason the article was deleted
+ * @param ?mixed $id id of the article that was deleted
+ * @param ?mixed $content the Content of the deleted page (or null, when deleting a broken page)
+ * @param ?mixed $logEntry the ManualLogEntry used to record the deletion
+ * @param ?mixed $archivedRevisionCount the number of revisions archived during the deletion
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleDeleteComplete( $wikiPage, $user, $reason, $id,
+ $content, $logEntry, $archivedRevisionCount
+ );
+}
diff --git a/includes/page/Hook/ArticleDeleteHook.php b/includes/page/Hook/ArticleDeleteHook.php
new file mode 100644
index 000000000000..d18872871a55
--- /dev/null
+++ b/includes/page/Hook/ArticleDeleteHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleDeleteHook {
+ /**
+ * Before an article is deleted.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage the WikiPage (object) being deleted
+ * @param ?mixed $user the user (object) deleting the article
+ * @param ?mixed &$reason the reason (string) the article is being deleted
+ * @param ?mixed &$error if the deletion was prohibited, the (raw HTML) error message to display
+ * (added in 1.13)
+ * @param ?mixed &$status Status object, modify this to throw an error. Overridden by $error
+ * (added in 1.20)
+ * @param ?mixed $suppress Whether this is a suppression deletion or not (added in 1.27)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleDelete( $wikiPage, $user, &$reason, &$error, &$status,
+ $suppress
+ );
+}
diff --git a/includes/page/Hook/ArticleFromTitleHook.php b/includes/page/Hook/ArticleFromTitleHook.php
new file mode 100644
index 000000000000..c0cf3990c26b
--- /dev/null
+++ b/includes/page/Hook/ArticleFromTitleHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleFromTitleHook {
+ /**
+ * when creating an article object from a title object using
+ * Wiki::articleFromTitle().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title (object) used to create the article object
+ * @param ?mixed &$article Article (object) that will be returned
+ * @param ?mixed $context IContextSource (object)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleFromTitle( $title, &$article, $context );
+}
diff --git a/includes/page/Hook/ArticlePageDataAfterHook.php b/includes/page/Hook/ArticlePageDataAfterHook.php
new file mode 100644
index 000000000000..d49a4ef70695
--- /dev/null
+++ b/includes/page/Hook/ArticlePageDataAfterHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticlePageDataAfterHook {
+ /**
+ * After loading data of an article from the database.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage WikiPage (object) whose data were loaded
+ * @param ?mixed &$row row (object) returned from the database server
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticlePageDataAfter( $wikiPage, &$row );
+}
diff --git a/includes/page/Hook/ArticlePageDataBeforeHook.php b/includes/page/Hook/ArticlePageDataBeforeHook.php
new file mode 100644
index 000000000000..b46ef9f14a9e
--- /dev/null
+++ b/includes/page/Hook/ArticlePageDataBeforeHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticlePageDataBeforeHook {
+ /**
+ * Before loading data of an article from the database.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage WikiPage (object) that data will be loaded
+ * @param ?mixed &$fields fields (array) to load from the database
+ * @param ?mixed &$tables tables (array) to load from the database
+ * @param ?mixed &$joinConds join conditions (array) to load from the database
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticlePageDataBefore( $wikiPage, &$fields, &$tables,
+ &$joinConds
+ );
+}
diff --git a/includes/page/Hook/ArticleProtectCompleteHook.php b/includes/page/Hook/ArticleProtectCompleteHook.php
new file mode 100644
index 000000000000..be49e2fcd3c4
--- /dev/null
+++ b/includes/page/Hook/ArticleProtectCompleteHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleProtectCompleteHook {
+ /**
+ * After an article is protected.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage the WikiPage that was protected
+ * @param ?mixed $user the user who did the protection
+ * @param ?mixed $protect Set of restriction keys
+ * @param ?mixed $reason Reason for protect
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleProtectComplete( $wikiPage, $user, $protect, $reason );
+}
diff --git a/includes/page/Hook/ArticleProtectHook.php b/includes/page/Hook/ArticleProtectHook.php
new file mode 100644
index 000000000000..c36e996e4820
--- /dev/null
+++ b/includes/page/Hook/ArticleProtectHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleProtectHook {
+ /**
+ * Before an article is protected.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage the WikiPage being protected
+ * @param ?mixed $user the user doing the protection
+ * @param ?mixed $protect Set of restriction keys
+ * @param ?mixed $reason Reason for protect
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleProtect( $wikiPage, $user, $protect, $reason );
+}
diff --git a/includes/page/Hook/ArticlePurgeHook.php b/includes/page/Hook/ArticlePurgeHook.php
new file mode 100644
index 000000000000..696fa94bf48f
--- /dev/null
+++ b/includes/page/Hook/ArticlePurgeHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticlePurgeHook {
+ /**
+ * Before executing "&action=purge".
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage WikiPage (object) to purge
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticlePurge( $wikiPage );
+}
diff --git a/includes/page/Hook/ArticleRevisionUndeletedHook.php b/includes/page/Hook/ArticleRevisionUndeletedHook.php
new file mode 100644
index 000000000000..97be0359201d
--- /dev/null
+++ b/includes/page/Hook/ArticleRevisionUndeletedHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleRevisionUndeletedHook {
+ /**
+ * After an article revision is restored.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title the article title
+ * @param ?mixed $revision the revision
+ * @param ?mixed $oldPageID the page ID of the revision when archived (may be null)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleRevisionUndeleted( $title, $revision, $oldPageID );
+}
diff --git a/includes/page/Hook/ArticleRevisionViewCustomHook.php b/includes/page/Hook/ArticleRevisionViewCustomHook.php
new file mode 100644
index 000000000000..5534ddf446ad
--- /dev/null
+++ b/includes/page/Hook/ArticleRevisionViewCustomHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleRevisionViewCustomHook {
+ /**
+ * Allows custom rendering of an article's content.
+ * Note that it is preferable to implement proper handing for a custom data type using
+ * the ContentHandler facility.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $revision content of the page, as a RevisionRecord object, or null if the revision
+ * could not be loaded. May also be a fake that wraps content supplied by an extension.
+ * @param ?mixed $title title of the page
+ * @param ?mixed $oldid the requested revision id, or 0 for the currrent revision.
+ * @param ?mixed $output a ParserOutput object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleRevisionViewCustom( $revision, $title, $oldid,
+ $output
+ );
+}
diff --git a/includes/page/Hook/ArticleRollbackCompleteHook.php b/includes/page/Hook/ArticleRollbackCompleteHook.php
new file mode 100644
index 000000000000..69782afb0867
--- /dev/null
+++ b/includes/page/Hook/ArticleRollbackCompleteHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleRollbackCompleteHook {
+ /**
+ * After an article rollback is completed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage the WikiPage that was edited
+ * @param ?mixed $user the user who did the rollback
+ * @param ?mixed $revision the revision the page was reverted back to
+ * @param ?mixed $current the reverted revision
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleRollbackComplete( $wikiPage, $user, $revision,
+ $current
+ );
+}
diff --git a/includes/page/Hook/ArticleShowPatrolFooterHook.php b/includes/page/Hook/ArticleShowPatrolFooterHook.php
new file mode 100644
index 000000000000..1b02ed06c4fc
--- /dev/null
+++ b/includes/page/Hook/ArticleShowPatrolFooterHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleShowPatrolFooterHook {
+ /**
+ * Called at the beginning of Article#showPatrolFooter.
+ * Extensions can use this to not show the [mark as patrolled] link in certain
+ * circumstances.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article the Article object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleShowPatrolFooter( $article );
+}
diff --git a/includes/page/Hook/ArticleUndeleteHook.php b/includes/page/Hook/ArticleUndeleteHook.php
new file mode 100644
index 000000000000..1e8c5e252fc5
--- /dev/null
+++ b/includes/page/Hook/ArticleUndeleteHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+// phpcs:disable Generic.Files.LineLength -- Remove this after doc review
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleUndeleteHook {
+ /**
+ * When one or more revisions of an article are restored.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title corresponding to the article restored
+ * @param ?mixed $create Whether or not the restoration caused the page to be created (i.e. it
+ * didn't exist before).
+ * @param ?mixed $comment The comment associated with the undeletion.
+ * @param ?mixed $oldPageId ID of page previously deleted (from archive table). This ID will be used
+ * for the restored page.
+ * @param ?mixed $restoredPages Set of page IDs that have revisions restored for this undelete,
+ * with keys being page IDs and values are 'true'.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleUndelete( $title, $create, $comment, $oldPageId,
+ $restoredPages
+ );
+}
diff --git a/includes/page/Hook/ArticleUndeleteLogEntryHook.php b/includes/page/Hook/ArticleUndeleteLogEntryHook.php
new file mode 100644
index 000000000000..7d91efb07db5
--- /dev/null
+++ b/includes/page/Hook/ArticleUndeleteLogEntryHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleUndeleteLogEntryHook {
+ /**
+ * When a log entry is generated but not yet saved.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $pageArchive the PageArchive object
+ * @param ?mixed &$logEntry ManualLogEntry object
+ * @param ?mixed $user User who is performing the log action
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleUndeleteLogEntry( $pageArchive, &$logEntry, $user );
+}
diff --git a/includes/page/Hook/ArticleViewFooterHook.php b/includes/page/Hook/ArticleViewFooterHook.php
new file mode 100644
index 000000000000..415798d70098
--- /dev/null
+++ b/includes/page/Hook/ArticleViewFooterHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleViewFooterHook {
+ /**
+ * After showing the footer section of an ordinary page view
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article Article object
+ * @param ?mixed $patrolFooterShown boolean whether patrol footer is shown
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleViewFooter( $article, $patrolFooterShown );
+}
diff --git a/includes/page/Hook/ArticleViewHeaderHook.php b/includes/page/Hook/ArticleViewHeaderHook.php
new file mode 100644
index 000000000000..c2e943f1f3c3
--- /dev/null
+++ b/includes/page/Hook/ArticleViewHeaderHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleViewHeaderHook {
+ /**
+ * Control article output. Called before the parser cache is about
+ * to be tried for article viewing.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article the article
+ * @param ?mixed &$pcache whether to try the parser cache or not
+ * @param ?mixed &$outputDone whether the output for this page finished or not. Set to
+ * a ParserOutput object to both indicate that the output is done and what
+ * parser output was used.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleViewHeader( $article, &$pcache, &$outputDone );
+}
diff --git a/includes/page/Hook/ArticleViewRedirectHook.php b/includes/page/Hook/ArticleViewRedirectHook.php
new file mode 100644
index 000000000000..9709b0c346df
--- /dev/null
+++ b/includes/page/Hook/ArticleViewRedirectHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleViewRedirectHook {
+ /**
+ * Before setting "Redirected from ..." subtitle when a
+ * redirect was followed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article target article (object)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleViewRedirect( $article );
+}
diff --git a/includes/page/Hook/Article__MissingArticleConditionsHook.php b/includes/page/Hook/Article__MissingArticleConditionsHook.php
new file mode 100644
index 000000000000..514e6a91623e
--- /dev/null
+++ b/includes/page/Hook/Article__MissingArticleConditionsHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface Article__MissingArticleConditionsHook {
+ /**
+ * Before fetching deletion & move log entries
+ * to display a message of a non-existing page being deleted/moved, give extensions
+ * a chance to hide their (unrelated) log entries.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$conds Array of query conditions (all of which have to be met; conditions will
+ * AND in the final query)
+ * @param ?mixed $logTypes Array of log types being queried
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticle__MissingArticleConditions( &$conds, $logTypes );
+}
diff --git a/includes/page/Hook/BeforeDisplayNoArticleTextHook.php b/includes/page/Hook/BeforeDisplayNoArticleTextHook.php
new file mode 100644
index 000000000000..f21e86cd486a
--- /dev/null
+++ b/includes/page/Hook/BeforeDisplayNoArticleTextHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BeforeDisplayNoArticleTextHook {
+ /**
+ * Before displaying message key "noarticletext" or
+ * "noarticletext-nopermission" at Article::showMissingArticle().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article article object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBeforeDisplayNoArticleText( $article );
+}
diff --git a/includes/page/Hook/CategoryAfterPageAddedHook.php b/includes/page/Hook/CategoryAfterPageAddedHook.php
new file mode 100644
index 000000000000..125f988d26a9
--- /dev/null
+++ b/includes/page/Hook/CategoryAfterPageAddedHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface CategoryAfterPageAddedHook {
+ /**
+ * After a page is added to a category.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $category Category that page was added to
+ * @param ?mixed $wikiPage WikiPage that was added
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onCategoryAfterPageAdded( $category, $wikiPage );
+}
diff --git a/includes/page/Hook/CategoryAfterPageRemovedHook.php b/includes/page/Hook/CategoryAfterPageRemovedHook.php
new file mode 100644
index 000000000000..4f1dac0d384b
--- /dev/null
+++ b/includes/page/Hook/CategoryAfterPageRemovedHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface CategoryAfterPageRemovedHook {
+ /**
+ * After a page is removed from a category.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $category Category that page was removed from
+ * @param ?mixed $wikiPage WikiPage that was removed
+ * @param ?mixed $id the page ID (original ID in case of page deletions)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onCategoryAfterPageRemoved( $category, $wikiPage, $id );
+}
diff --git a/includes/page/Hook/CategoryPageViewHook.php b/includes/page/Hook/CategoryPageViewHook.php
new file mode 100644
index 000000000000..122d4c31fad6
--- /dev/null
+++ b/includes/page/Hook/CategoryPageViewHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface CategoryPageViewHook {
+ /**
+ * Before viewing a categorypage in CategoryPage::view.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $catpage CategoryPage instance
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onCategoryPageView( $catpage );
+}
diff --git a/includes/page/Hook/DisplayOldSubtitleHook.php b/includes/page/Hook/DisplayOldSubtitleHook.php
new file mode 100644
index 000000000000..da4285bc4310
--- /dev/null
+++ b/includes/page/Hook/DisplayOldSubtitleHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DisplayOldSubtitleHook {
+ /**
+ * before creating subtitle when browsing old versions of
+ * an article
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article article (object) being viewed
+ * @param ?mixed &$oldid oldid (int) being viewed
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDisplayOldSubtitle( $article, &$oldid );
+}
diff --git a/includes/page/Hook/ImageOpenShowImageInlineBeforeHook.php b/includes/page/Hook/ImageOpenShowImageInlineBeforeHook.php
new file mode 100644
index 000000000000..397b69bc2c51
--- /dev/null
+++ b/includes/page/Hook/ImageOpenShowImageInlineBeforeHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImageOpenShowImageInlineBeforeHook {
+ /**
+ * Call potential extension just before showing
+ * the image on an image page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $imagePage ImagePage object ($this)
+ * @param ?mixed $output $wgOut
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImageOpenShowImageInlineBefore( $imagePage, $output );
+}
diff --git a/includes/page/Hook/ImagePageAfterImageLinksHook.php b/includes/page/Hook/ImagePageAfterImageLinksHook.php
new file mode 100644
index 000000000000..49ed9a51f77d
--- /dev/null
+++ b/includes/page/Hook/ImagePageAfterImageLinksHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImagePageAfterImageLinksHook {
+ /**
+ * Called after the image links section on an image
+ * page is built.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $imagePage ImagePage object ($this)
+ * @param ?mixed &$html HTML for the hook to add
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImagePageAfterImageLinks( $imagePage, &$html );
+}
diff --git a/includes/page/Hook/ImagePageFileHistoryLineHook.php b/includes/page/Hook/ImagePageFileHistoryLineHook.php
new file mode 100644
index 000000000000..cb3379d983c0
--- /dev/null
+++ b/includes/page/Hook/ImagePageFileHistoryLineHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImagePageFileHistoryLineHook {
+ /**
+ * Called when a file history line is constructed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $imagePage ImagePage object ($this)
+ * @param ?mixed $file the file
+ * @param ?mixed &$line the HTML of the history line
+ * @param ?mixed &$css the line CSS class
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImagePageFileHistoryLine( $imagePage, $file, &$line, &$css );
+}
diff --git a/includes/page/Hook/ImagePageFindFileHook.php b/includes/page/Hook/ImagePageFindFileHook.php
new file mode 100644
index 000000000000..0ae6c00d3051
--- /dev/null
+++ b/includes/page/Hook/ImagePageFindFileHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImagePageFindFileHook {
+ /**
+ * Called when fetching the file associated with an image
+ * page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $page ImagePage object
+ * @param ?mixed &$file File object
+ * @param ?mixed &$displayFile displayed File object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImagePageFindFile( $page, &$file, &$displayFile );
+}
diff --git a/includes/page/Hook/ImagePageShowTOCHook.php b/includes/page/Hook/ImagePageShowTOCHook.php
new file mode 100644
index 000000000000..4b3efaa07d73
--- /dev/null
+++ b/includes/page/Hook/ImagePageShowTOCHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImagePageShowTOCHook {
+ /**
+ * Called when the file toc on an image page is generated.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $page ImagePage object
+ * @param ?mixed &$toc Array of <li> strings
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImagePageShowTOC( $page, &$toc );
+}
diff --git a/includes/page/Hook/IsFileCacheableHook.php b/includes/page/Hook/IsFileCacheableHook.php
new file mode 100644
index 000000000000..bac7e750c7e5
--- /dev/null
+++ b/includes/page/Hook/IsFileCacheableHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface IsFileCacheableHook {
+ /**
+ * Override the result of Article::isFileCacheable() (if true)
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article article (object) being checked
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onIsFileCacheable( $article );
+}
diff --git a/includes/page/Hook/NewRevisionFromEditCompleteHook.php b/includes/page/Hook/NewRevisionFromEditCompleteHook.php
new file mode 100644
index 000000000000..615019f77f4c
--- /dev/null
+++ b/includes/page/Hook/NewRevisionFromEditCompleteHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface NewRevisionFromEditCompleteHook {
+ /**
+ * Called when a revision was inserted due to an
+ * edit, file upload, import or page move.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikiPage the WikiPage edited
+ * @param ?mixed $rev the new revision
+ * @param ?mixed $originalRevId if the edit restores or repeats an earlier revision (such as a
+ * rollback or a null revision), the ID of that earlier revision. False otherwise.
+ * (Used to be called $baseID.)
+ * @param ?mixed $user the editing user
+ * @param ?mixed &$tags tags to apply to the edit and recent change. This is empty, and
+ * replacement is ignored, in the case of import or page move.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onNewRevisionFromEditComplete( $wikiPage, $rev, $originalRevId,
+ $user, &$tags
+ );
+}
diff --git a/includes/page/Hook/OpportunisticLinksUpdateHook.php b/includes/page/Hook/OpportunisticLinksUpdateHook.php
new file mode 100644
index 000000000000..2736befbdde8
--- /dev/null
+++ b/includes/page/Hook/OpportunisticLinksUpdateHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface OpportunisticLinksUpdateHook {
+ /**
+ * Called by WikiPage::triggerOpportunisticLinksUpdate
+ * when a page view triggers a re-rendering of the page. This may happen
+ * particularly if the parser cache is split by user language, and no cached
+ * rendering of the page exists in the user's language. The hook is called
+ * before checking whether page_links_updated indicates that the links are up
+ * to date. Returning false will cause triggerOpportunisticLinksUpdate() to abort
+ * without triggering any updates.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $page the Page that was rendered.
+ * @param ?mixed $title the Title of the rendered page.
+ * @param ?mixed $parserOutput ParserOutput resulting from rendering the page.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onOpportunisticLinksUpdate( $page, $title, $parserOutput );
+}
diff --git a/includes/page/Hook/PageDeletionDataUpdatesHook.php b/includes/page/Hook/PageDeletionDataUpdatesHook.php
new file mode 100644
index 000000000000..657f0cdfaa8b
--- /dev/null
+++ b/includes/page/Hook/PageDeletionDataUpdatesHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+// phpcs:disable Generic.Files.LineLength -- Remove this after doc review
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PageDeletionDataUpdatesHook {
+ /**
+ * Called when constructing a list of DeferrableUpdate to be
+ * executed when a page is deleted.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title The Title of the page being deleted.
+ * @param ?mixed $revision A RevisionRecord representing the page's current revision at the time of deletion.
+ * @param ?mixed &$updates A list of DeferrableUpdate that can be manipulated by the hook handler.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPageDeletionDataUpdates( $title, $revision, &$updates );
+}
diff --git a/includes/page/Hook/PageViewUpdatesHook.php b/includes/page/Hook/PageViewUpdatesHook.php
new file mode 100644
index 000000000000..e632d4f8989f
--- /dev/null
+++ b/includes/page/Hook/PageViewUpdatesHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PageViewUpdatesHook {
+ /**
+ * Allow database (or other) changes to be made after a
+ * page view is seen by MediaWiki. Note this does not capture views made
+ * via external caches such as Squid.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wikipage WikiPage (object) for the page being viewed.
+ * @param ?mixed $user User (object) for the user who is viewing.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPageViewUpdates( $wikipage, $user );
+}
diff --git a/includes/page/Hook/ShowMissingArticleHook.php b/includes/page/Hook/ShowMissingArticleHook.php
new file mode 100644
index 000000000000..ef994b2f1984
--- /dev/null
+++ b/includes/page/Hook/ShowMissingArticleHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ShowMissingArticleHook {
+ /**
+ * Called when generating the output for a non-existent page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $article The article object corresponding to the page
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onShowMissingArticle( $article );
+}
diff --git a/includes/page/Hook/WikiPageDeletionUpdatesHook.php b/includes/page/Hook/WikiPageDeletionUpdatesHook.php
new file mode 100644
index 000000000000..8aa98016ce81
--- /dev/null
+++ b/includes/page/Hook/WikiPageDeletionUpdatesHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WikiPageDeletionUpdatesHook {
+ /**
+ * DEPRECATED since 1.32! Use PageDeletionDataUpdates or
+ * override ContentHandler::getDeletionDataUpdates instead.
+ * Manipulates the list of DeferrableUpdates to be applied when a page is deleted.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $page the WikiPage
+ * @param ?mixed $content the Content to generate updates for, or null in case the page revision
+ * could not be loaded. The delete will succeed despite this.
+ * @param ?mixed &$updates the array of objects that implement DeferrableUpdate. Hook function
+ * may want to add to it.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWikiPageDeletionUpdates( $page, $content, &$updates );
+}
diff --git a/includes/page/Hook/WikiPageFactoryHook.php b/includes/page/Hook/WikiPageFactoryHook.php
new file mode 100644
index 000000000000..91bdbc135865
--- /dev/null
+++ b/includes/page/Hook/WikiPageFactoryHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Page\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WikiPageFactoryHook {
+ /**
+ * Override WikiPage class used for a title
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title of the page
+ * @param ?mixed &$page Variable to set the created WikiPage to.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWikiPageFactory( $title, &$page );
+}
diff --git a/includes/parser/Hook/AfterParserFetchFileAndTitleHook.php b/includes/parser/Hook/AfterParserFetchFileAndTitleHook.php
new file mode 100644
index 000000000000..f6eaaa4c2b74
--- /dev/null
+++ b/includes/parser/Hook/AfterParserFetchFileAndTitleHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AfterParserFetchFileAndTitleHook {
+ /**
+ * After an image gallery is formed by Parser,
+ * just before adding its HTML to parser output.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object that called the hook
+ * @param ?mixed $ig Gallery, an object of one of the gallery classes (inheriting from
+ * ImageGalleryBase)
+ * @param ?mixed &$html HTML generated by the gallery
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAfterParserFetchFileAndTitle( $parser, $ig, &$html );
+}
diff --git a/includes/parser/Hook/BeforeParserFetchFileAndTitleHook.php b/includes/parser/Hook/BeforeParserFetchFileAndTitleHook.php
new file mode 100644
index 000000000000..4ab8fb97a5f3
--- /dev/null
+++ b/includes/parser/Hook/BeforeParserFetchFileAndTitleHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BeforeParserFetchFileAndTitleHook {
+ /**
+ * Before an image is rendered by Parser.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object
+ * @param ?mixed $nt the image title
+ * @param ?mixed &$options array of options to RepoGroup::findFile. If it contains 'broken'
+ * as a key then the file will appear as a broken thumbnail.
+ * @param ?mixed &$descQuery query string to add to thumbnail URL
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBeforeParserFetchFileAndTitle( $parser, $nt, &$options,
+ &$descQuery
+ );
+}
diff --git a/includes/parser/Hook/BeforeParserFetchTemplateAndtitleHook.php b/includes/parser/Hook/BeforeParserFetchTemplateAndtitleHook.php
new file mode 100644
index 000000000000..f73c9ea75c3b
--- /dev/null
+++ b/includes/parser/Hook/BeforeParserFetchTemplateAndtitleHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BeforeParserFetchTemplateAndtitleHook {
+ /**
+ * Before a template is fetched by Parser.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object
+ * @param ?mixed $title title of the template
+ * @param ?mixed &$skip skip this template and link it?
+ * @param ?mixed &$id the id of the revision being parsed
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBeforeParserFetchTemplateAndtitle( $parser, $title, &$skip,
+ &$id
+ );
+}
diff --git a/includes/parser/Hook/BeforeParserrenderImageGalleryHook.php b/includes/parser/Hook/BeforeParserrenderImageGalleryHook.php
new file mode 100644
index 000000000000..226963f6da07
--- /dev/null
+++ b/includes/parser/Hook/BeforeParserrenderImageGalleryHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BeforeParserrenderImageGalleryHook {
+ /**
+ * Before an image gallery is rendered by Parser.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object
+ * @param ?mixed $ig ImageGallery object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBeforeParserrenderImageGallery( $parser, $ig );
+}
diff --git a/includes/parser/Hook/GetLinkColoursHook.php b/includes/parser/Hook/GetLinkColoursHook.php
new file mode 100644
index 000000000000..6c22271f3924
--- /dev/null
+++ b/includes/parser/Hook/GetLinkColoursHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetLinkColoursHook {
+ /**
+ * modify the CSS class of an array of page links.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $linkcolour_ids array of prefixed DB keys of the pages linked to,
+ * indexed by page_id.
+ * @param ?mixed &$colours (output) array of CSS classes, indexed by prefixed DB keys
+ * @param ?mixed $title Title object of the page being parsed, on which the links will be shown
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetLinkColours( $linkcolour_ids, &$colours, $title );
+}
diff --git a/includes/parser/Hook/InternalParseBeforeLinksHook.php b/includes/parser/Hook/InternalParseBeforeLinksHook.php
new file mode 100644
index 000000000000..ed8a706910ad
--- /dev/null
+++ b/includes/parser/Hook/InternalParseBeforeLinksHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface InternalParseBeforeLinksHook {
+ /**
+ * during Parser's internalParse method before links
+ * but after nowiki/noinclude/includeonly/onlyinclude and other processings.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object
+ * @param ?mixed &$text string containing partially parsed text
+ * @param ?mixed $stripState Parser's internal StripState object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onInternalParseBeforeLinks( $parser, &$text, $stripState );
+}
diff --git a/includes/parser/Hook/InternalParseBeforeSanitizeHook.php b/includes/parser/Hook/InternalParseBeforeSanitizeHook.php
new file mode 100644
index 000000000000..ce13d8d1a680
--- /dev/null
+++ b/includes/parser/Hook/InternalParseBeforeSanitizeHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface InternalParseBeforeSanitizeHook {
+ /**
+ * during Parser's internalParse method just before
+ * the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/
+ * includeonly/onlyinclude and other processings. Ideal for syntax-extensions after
+ * template/parser function execution which respect nowiki and HTML-comments.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object
+ * @param ?mixed &$text string containing partially parsed text
+ * @param ?mixed $stripState Parser's internal StripState object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onInternalParseBeforeSanitize( $parser, &$text, $stripState );
+}
diff --git a/includes/parser/Hook/IsValidEmailAddrHook.php b/includes/parser/Hook/IsValidEmailAddrHook.php
new file mode 100644
index 000000000000..b6250899c603
--- /dev/null
+++ b/includes/parser/Hook/IsValidEmailAddrHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface IsValidEmailAddrHook {
+ /**
+ * Override the result of Sanitizer::validateEmail(), for
+ * instance to return false if the domain name doesn't match your organization.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $addr The e-mail address entered by the user
+ * @param ?mixed &$result Set this and return false to override the internal checks
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onIsValidEmailAddr( $addr, &$result );
+}
diff --git a/includes/parser/Hook/PageRenderingHashHook.php b/includes/parser/Hook/PageRenderingHashHook.php
new file mode 100644
index 000000000000..aa37bf3a8135
--- /dev/null
+++ b/includes/parser/Hook/PageRenderingHashHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PageRenderingHashHook {
+ /**
+ * NOTE: Consider using ParserOptionsRegister instead.
+ * Alter the parser cache option hash key. A parser extension
+ * which depends on user options should install this hook and append its values to
+ * the key.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$confstr reference to a hash key string which can be modified
+ * @param ?mixed $user User (object) requesting the page
+ * @param ?mixed &$forOptions array of options the hash is for
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPageRenderingHash( &$confstr, $user, &$forOptions );
+}
diff --git a/includes/parser/Hook/ParserAfterParseHook.php b/includes/parser/Hook/ParserAfterParseHook.php
new file mode 100644
index 000000000000..3c3f291b8266
--- /dev/null
+++ b/includes/parser/Hook/ParserAfterParseHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserAfterParseHook {
+ /**
+ * Called from Parser::parse() just after the call to
+ * Parser::internalParse() returns.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser parser object
+ * @param ?mixed &$text text being parsed
+ * @param ?mixed $stripState stripState used (object)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserAfterParse( $parser, &$text, $stripState );
+}
diff --git a/includes/parser/Hook/ParserAfterStripHook.php b/includes/parser/Hook/ParserAfterStripHook.php
new file mode 100644
index 000000000000..f449c94ef764
--- /dev/null
+++ b/includes/parser/Hook/ParserAfterStripHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserAfterStripHook {
+ /**
+ * Called at end of parsing time.
+ * TODO: No more strip, deprecated ?
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser parser object
+ * @param ?mixed &$text text being parsed
+ * @param ?mixed $stripState stripState used (object)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserAfterStrip( $parser, &$text, $stripState );
+}
diff --git a/includes/parser/Hook/ParserAfterTidyHook.php b/includes/parser/Hook/ParserAfterTidyHook.php
new file mode 100644
index 000000000000..436a6726541c
--- /dev/null
+++ b/includes/parser/Hook/ParserAfterTidyHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserAfterTidyHook {
+ /**
+ * Called after Parser::tidy() in Parser::parse()
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object being used
+ * @param ?mixed &$text text that will be returned
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserAfterTidy( $parser, &$text );
+}
diff --git a/includes/parser/Hook/ParserBeforeInternalParseHook.php b/includes/parser/Hook/ParserBeforeInternalParseHook.php
new file mode 100644
index 000000000000..63a00c55af5b
--- /dev/null
+++ b/includes/parser/Hook/ParserBeforeInternalParseHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserBeforeInternalParseHook {
+ /**
+ * Called at the beginning of Parser::internalParse().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object
+ * @param ?mixed &$text text to parse
+ * @param ?mixed $stripState StripState instance being used
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserBeforeInternalParse( $parser, &$text, $stripState );
+}
diff --git a/includes/parser/Hook/ParserBeforeStripHook.php b/includes/parser/Hook/ParserBeforeStripHook.php
new file mode 100644
index 000000000000..12b53016c84e
--- /dev/null
+++ b/includes/parser/Hook/ParserBeforeStripHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserBeforeStripHook {
+ /**
+ * Called at start of parsing time.
+ * TODO: No more strip, deprecated ?
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser parser object
+ * @param ?mixed &$text text being parsed
+ * @param ?mixed $stripState stripState used (object)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserBeforeStrip( $parser, &$text, $stripState );
+}
diff --git a/includes/parser/Hook/ParserBeforeTidyHook.php b/includes/parser/Hook/ParserBeforeTidyHook.php
new file mode 100644
index 000000000000..17c0b94cac77
--- /dev/null
+++ b/includes/parser/Hook/ParserBeforeTidyHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserBeforeTidyHook {
+ /**
+ * Called before tidy and custom tags replacements.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object being used
+ * @param ?mixed &$text actual text
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserBeforeTidy( $parser, &$text );
+}
diff --git a/includes/parser/Hook/ParserCacheSaveCompleteHook.php b/includes/parser/Hook/ParserCacheSaveCompleteHook.php
new file mode 100644
index 000000000000..0a5cf0387c5b
--- /dev/null
+++ b/includes/parser/Hook/ParserCacheSaveCompleteHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserCacheSaveCompleteHook {
+ /**
+ * Called after a ParserOutput has been committed to
+ * the parser cache.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parserCache ParserCache object $parserOutput was stored in
+ * @param ?mixed $parserOutput ParserOutput object that was stored
+ * @param ?mixed $title Title of the page that was parsed to generate $parserOutput
+ * @param ?mixed $popts ParserOptions used for generating $parserOutput
+ * @param ?mixed $revId ID of the revision that was parsed to create $parserOutput
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserCacheSaveComplete( $parserCache, $parserOutput, $title,
+ $popts, $revId
+ );
+}
diff --git a/includes/parser/Hook/ParserClearStateHook.php b/includes/parser/Hook/ParserClearStateHook.php
new file mode 100644
index 000000000000..fecd82bf570b
--- /dev/null
+++ b/includes/parser/Hook/ParserClearStateHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserClearStateHook {
+ /**
+ * Called at the end of Parser::clearState().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object being cleared
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserClearState( $parser );
+}
diff --git a/includes/parser/Hook/ParserClonedHook.php b/includes/parser/Hook/ParserClonedHook.php
new file mode 100644
index 000000000000..6cdc0b561235
--- /dev/null
+++ b/includes/parser/Hook/ParserClonedHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserClonedHook {
+ /**
+ * Called when the parser is cloned.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Newly-cloned Parser object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserCloned( $parser );
+}
diff --git a/includes/parser/Hook/ParserFetchTemplateHook.php b/includes/parser/Hook/ParserFetchTemplateHook.php
new file mode 100644
index 000000000000..85f04f523e59
--- /dev/null
+++ b/includes/parser/Hook/ParserFetchTemplateHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserFetchTemplateHook {
+ /**
+ * Called when the parser fetches a template
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser Parser object or false
+ * @param ?mixed $title Title object of the template to be fetched
+ * @param ?mixed $rev Revision object of the template
+ * @param ?mixed &$text Transclusion text of the template or false or null
+ * @param ?mixed &$deps Array of template dependencies with 'title', 'page_id', 'rev_id' keys
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserFetchTemplate( $parser, $title, $rev, &$text, &$deps );
+}
diff --git a/includes/parser/Hook/ParserFirstCallInitHook.php b/includes/parser/Hook/ParserFirstCallInitHook.php
new file mode 100644
index 000000000000..7b7fccef9d32
--- /dev/null
+++ b/includes/parser/Hook/ParserFirstCallInitHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserFirstCallInitHook {
+ /**
+ * Called when the parser initialises for the first time.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object being cleared
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserFirstCallInit( $parser );
+}
diff --git a/includes/parser/Hook/ParserGetVariableValueSwitchHook.php b/includes/parser/Hook/ParserGetVariableValueSwitchHook.php
new file mode 100644
index 000000000000..30c25d48536e
--- /dev/null
+++ b/includes/parser/Hook/ParserGetVariableValueSwitchHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserGetVariableValueSwitchHook {
+ /**
+ * Called when the parser needs the value of a
+ * custom magic word
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object
+ * @param ?mixed &$variableCache array to cache the value; when you return
+ * $variableCache[$magicWordId] should be the same as $ret
+ * @param ?mixed $magicWordId index (string) of the magic word (hook should not mutate it!)
+ * @param ?mixed &$ret value of the magic word (the hook should set it)
+ * @param ?mixed $frame PPFrame object to use for expanding any template variables
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserGetVariableValueSwitch( $parser, &$variableCache,
+ $magicWordId, &$ret, $frame
+ );
+}
diff --git a/includes/parser/Hook/ParserGetVariableValueTsHook.php b/includes/parser/Hook/ParserGetVariableValueTsHook.php
new file mode 100644
index 000000000000..8214f479e4cf
--- /dev/null
+++ b/includes/parser/Hook/ParserGetVariableValueTsHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserGetVariableValueTsHook {
+ /**
+ * Use this to change the value of the time for the
+ * {{LOCAL...}} magic word.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object
+ * @param ?mixed &$time actual time (timestamp)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserGetVariableValueTs( $parser, &$time );
+}
diff --git a/includes/parser/Hook/ParserGetVariableValueVarCacheHook.php b/includes/parser/Hook/ParserGetVariableValueVarCacheHook.php
new file mode 100644
index 000000000000..f99e66abaed8
--- /dev/null
+++ b/includes/parser/Hook/ParserGetVariableValueVarCacheHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserGetVariableValueVarCacheHook {
+ /**
+ * DEPRECATED since 1.35! Use this to
+ * change the value of the variable cache or return false to not use it.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object
+ * @param ?mixed &$varCache variable cache (array)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserGetVariableValueVarCache( $parser, &$varCache );
+}
diff --git a/includes/parser/Hook/ParserLimitReportFormatHook.php b/includes/parser/Hook/ParserLimitReportFormatHook.php
new file mode 100644
index 000000000000..20196988e2ef
--- /dev/null
+++ b/includes/parser/Hook/ParserLimitReportFormatHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserLimitReportFormatHook {
+ /**
+ * Called for each row in the parser limit report that
+ * needs formatting. If nothing handles this hook, the default is to use "$key" to
+ * get the label, and "$key-value" or "$key-value-text"/"$key-value-html" to
+ * format the value.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $key Key for the limit report item (string)
+ * @param ?mixed &$value Value of the limit report item
+ * @param ?mixed &$report String onto which to append the data
+ * @param ?mixed $isHTML If true, $report is an HTML table with two columns; if false, it's
+ * text intended for display in a monospaced font.
+ * @param ?mixed $localize If false, $report should be output in English.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserLimitReportFormat( $key, &$value, &$report, $isHTML,
+ $localize
+ );
+}
diff --git a/includes/parser/Hook/ParserLimitReportPrepareHook.php b/includes/parser/Hook/ParserLimitReportPrepareHook.php
new file mode 100644
index 000000000000..8e0e5e1f8d29
--- /dev/null
+++ b/includes/parser/Hook/ParserLimitReportPrepareHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserLimitReportPrepareHook {
+ /**
+ * Called at the end of Parser:parse() when the parser
+ * will include comments about size of the text parsed. Hooks should use
+ * $output->setLimitReportData() to populate data. Functions for this hook should
+ * not use $wgLang; do that in ParserLimitReportFormat instead.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser Parser object
+ * @param ?mixed $output ParserOutput object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserLimitReportPrepare( $parser, $output );
+}
diff --git a/includes/parser/Hook/ParserMakeImageParamsHook.php b/includes/parser/Hook/ParserMakeImageParamsHook.php
new file mode 100644
index 000000000000..84b543ce05d6
--- /dev/null
+++ b/includes/parser/Hook/ParserMakeImageParamsHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserMakeImageParamsHook {
+ /**
+ * Called before the parser make an image link, use this
+ * to modify the parameters of the image.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title title object representing the file
+ * @param ?mixed $file file object that will be used to create the image
+ * @param ?mixed &$params 2-D array of parameters
+ * @param ?mixed $parser Parser object that called the hook
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserMakeImageParams( $title, $file, &$params, $parser );
+}
diff --git a/includes/parser/Hook/ParserOptionsRegisterHook.php b/includes/parser/Hook/ParserOptionsRegisterHook.php
new file mode 100644
index 000000000000..e290fa92540e
--- /dev/null
+++ b/includes/parser/Hook/ParserOptionsRegisterHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserOptionsRegisterHook {
+ /**
+ * Register additional parser options. Note that if you
+ * change the default value for an option, all existing parser cache entries will
+ * be invalid. To avoid bugs, you'll need to handle that somehow (e.g. with the
+ * RejectParserCacheValue hook) because MediaWiki won't do it for you.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$defaults Set the default value for your option here.
+ * @param ?mixed &$inCacheKey To fragment the parser cache on your option, set a truthy value
+ * here.
+ * @param ?mixed &$lazyLoad To lazy-initialize your option, set it null in $defaults and set a
+ * callable here. The callable is passed the ParserOptions object and the option
+ * name.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserOptionsRegister( &$defaults, &$inCacheKey, &$lazyLoad );
+}
diff --git a/includes/parser/Hook/ParserOutputPostCacheTransformHook.php b/includes/parser/Hook/ParserOutputPostCacheTransformHook.php
new file mode 100644
index 000000000000..d045037114e0
--- /dev/null
+++ b/includes/parser/Hook/ParserOutputPostCacheTransformHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserOutputPostCacheTransformHook {
+ /**
+ * Called from ParserOutput::getText() to do
+ * post-cache transforms.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parserOutput The ParserOutput object.
+ * @param ?mixed &$text The text being transformed, before core transformations are done.
+ * @param ?mixed &$options The options array being used for the transformation.
+ * @return bool|void This hook must not abort, it must return true or null.
+ */
+ public function onParserOutputPostCacheTransform( $parserOutput, &$text,
+ &$options
+ );
+}
diff --git a/includes/parser/Hook/ParserPreSaveTransformCompleteHook.php b/includes/parser/Hook/ParserPreSaveTransformCompleteHook.php
new file mode 100644
index 000000000000..27a259816820
--- /dev/null
+++ b/includes/parser/Hook/ParserPreSaveTransformCompleteHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserPreSaveTransformCompleteHook {
+ /**
+ * Called from Parser::preSaveTransform() after
+ * processing is complete, giving the extension a chance to further modify the
+ * wikitext.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser the calling Parser instance
+ * @param ?mixed &$text The transformed text, which can be modified by the hook
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserPreSaveTransformComplete( $parser, &$text );
+}
diff --git a/includes/parser/Hook/ParserSectionCreateHook.php b/includes/parser/Hook/ParserSectionCreateHook.php
new file mode 100644
index 000000000000..400f92c43eed
--- /dev/null
+++ b/includes/parser/Hook/ParserSectionCreateHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ParserSectionCreateHook {
+ /**
+ * Called each time the parser creates a document section
+ * from wikitext. Use this to apply per-section modifications to HTML (like
+ * wrapping the section in a DIV). Caveat: DIVs are valid wikitext, and a DIV
+ * can begin in one section and end in another. Make sure your code can handle
+ * that case gracefully. See the EditSectionClearerLink extension for an example.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parser the calling Parser instance
+ * @param ?mixed $section the section number, zero-based, but section 0 is usually empty
+ * @param ?mixed &$sectionContent ref to the content of the section. modify this.
+ * @param ?mixed $showEditLinks boolean describing whether this section has an edit link
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onParserSectionCreate( $parser, $section, &$sectionContent,
+ $showEditLinks
+ );
+}
diff --git a/includes/parser/Hook/RejectParserCacheValueHook.php b/includes/parser/Hook/RejectParserCacheValueHook.php
new file mode 100644
index 000000000000..a07d6240e27a
--- /dev/null
+++ b/includes/parser/Hook/RejectParserCacheValueHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface RejectParserCacheValueHook {
+ /**
+ * Return false to reject an otherwise usable
+ * cached value from the Parser cache. NOTE: CARELESS USE OF THIS HOOK CAN
+ * HAVE CATASTROPHIC CONSEQUENCES FOR HIGH-TRAFFIC INSTALLATIONS. USE WITH
+ * EXTREME CARE.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $parserOutput ParserOutput value.
+ * @param ?mixed $wikiPage WikiPage object.
+ * @param ?mixed $parserOptions ParserOptions object.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onRejectParserCacheValue( $parserOutput, $wikiPage,
+ $parserOptions
+ );
+}
diff --git a/includes/password/Hook/PasswordPoliciesForUserHook.php b/includes/password/Hook/PasswordPoliciesForUserHook.php
new file mode 100644
index 000000000000..a07582bd09af
--- /dev/null
+++ b/includes/password/Hook/PasswordPoliciesForUserHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PasswordPoliciesForUserHook {
+ /**
+ * Alter the effective password policy for a user.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User object whose policy you are modifying
+ * @param ?mixed &$effectivePolicy Array of policy statements that apply to this user
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPasswordPoliciesForUser( $user, &$effectivePolicy );
+}
diff --git a/includes/preferences/Hook/GetPreferencesHook.php b/includes/preferences/Hook/GetPreferencesHook.php
new file mode 100644
index 000000000000..acaaeacc2ec2
--- /dev/null
+++ b/includes/preferences/Hook/GetPreferencesHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Preferences\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetPreferencesHook {
+ /**
+ * Modify user preferences.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User whose preferences are being modified.
+ * @param ?mixed &$preferences Preferences description array, to be fed to an HTMLForm object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetPreferences( $user, &$preferences );
+}
diff --git a/includes/preferences/Hook/PreferencesFormPreSaveHook.php b/includes/preferences/Hook/PreferencesFormPreSaveHook.php
new file mode 100644
index 000000000000..85d4aec56223
--- /dev/null
+++ b/includes/preferences/Hook/PreferencesFormPreSaveHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Preferences\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PreferencesFormPreSaveHook {
+ /**
+ * Override preferences being saved
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $formData array of user submitted data
+ * @param ?mixed $form HTMLForm object, also a ContextSource
+ * @param ?mixed $user User object with preferences to be saved set
+ * @param ?mixed &$result boolean indicating success
+ * @param ?mixed $oldUserOptions array with user old options (before save)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPreferencesFormPreSave( $formData, $form, $user, &$result,
+ $oldUserOptions
+ );
+}
diff --git a/includes/rcfeed/Hook/IRCLineURLHook.php b/includes/rcfeed/Hook/IRCLineURLHook.php
new file mode 100644
index 000000000000..ecb62883a147
--- /dev/null
+++ b/includes/rcfeed/Hook/IRCLineURLHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface IRCLineURLHook {
+ /**
+ * When constructing the URL to use in an IRC notification.
+ * Callee may modify $url and $query, URL will be constructed as $url . $query
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$url URL to index.php
+ * @param ?mixed &$query Query string
+ * @param ?mixed $rc RecentChange object that triggered url generation
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onIRCLineURL( &$url, &$query, $rc );
+}
diff --git a/includes/resourceloader/Hook/ResourceLoaderForeignApiModulesHook.php b/includes/resourceloader/Hook/ResourceLoaderForeignApiModulesHook.php
new file mode 100644
index 000000000000..65ad1da5425a
--- /dev/null
+++ b/includes/resourceloader/Hook/ResourceLoaderForeignApiModulesHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ResourceLoaderForeignApiModulesHook {
+ /**
+ * Called from ResourceLoaderForeignApiModule.
+ * Use this to add dependencies to 'mediawiki.ForeignApi' module when you wish
+ * to override its behavior. See the module docs for more information.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$dependencies string[] List of modules that 'mediawiki.ForeignApi' should
+ * depend on
+ * @param ?mixed $context ResourceLoaderContext|null
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onResourceLoaderForeignApiModules( &$dependencies, $context );
+}
diff --git a/includes/resourceloader/Hook/ResourceLoaderGetConfigVarsHook.php b/includes/resourceloader/Hook/ResourceLoaderGetConfigVarsHook.php
new file mode 100644
index 000000000000..39928c5ec3d2
--- /dev/null
+++ b/includes/resourceloader/Hook/ResourceLoaderGetConfigVarsHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ResourceLoaderGetConfigVarsHook {
+ /**
+ * Called at the end of
+ * ResourceLoaderStartUpModule::getConfigSettings(). Use this to export static
+ * configuration variables to JavaScript. Things that depend on the current page
+ * or request state must be added through MakeGlobalVariablesScript instead.
+ * Skin is made available for skin specific config.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$vars [ variable name => value ]
+ * @param ?mixed $skin Skin
+ * @param ?mixed $config Config object (since 1.34)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onResourceLoaderGetConfigVars( &$vars, $skin, $config );
+}
diff --git a/includes/resourceloader/Hook/ResourceLoaderJqueryMsgModuleMagicWordsHook.php b/includes/resourceloader/Hook/ResourceLoaderJqueryMsgModuleMagicWordsHook.php
new file mode 100644
index 000000000000..917e28a700d1
--- /dev/null
+++ b/includes/resourceloader/Hook/ResourceLoaderJqueryMsgModuleMagicWordsHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ResourceLoaderJqueryMsgModuleMagicWordsHook {
+ /**
+ * Called in
+ * ResourceLoaderJqueryMsgModule to allow adding magic words for jQueryMsg.
+ * The value should be a string, and they can depend only on the
+ * ResourceLoaderContext.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $context ResourceLoaderContext
+ * @param ?mixed &$magicWords Associative array mapping all-caps magic word to a string value
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onResourceLoaderJqueryMsgModuleMagicWords( $context,
+ &$magicWords
+ );
+}
diff --git a/includes/resourceloader/Hook/ResourceLoaderSiteModulePagesHook.php b/includes/resourceloader/Hook/ResourceLoaderSiteModulePagesHook.php
new file mode 100644
index 000000000000..5385a2c8d8a3
--- /dev/null
+++ b/includes/resourceloader/Hook/ResourceLoaderSiteModulePagesHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ResourceLoaderSiteModulePagesHook {
+ /**
+ * Modify list of pages for a given skin
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $skin string of the current skin key
+ * @param ?mixed &$pages array of pages and their types.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onResourceLoaderSiteModulePages( $skin, &$pages );
+}
diff --git a/includes/resourceloader/Hook/ResourceLoaderSiteStylesModulePagesHook.php b/includes/resourceloader/Hook/ResourceLoaderSiteStylesModulePagesHook.php
new file mode 100644
index 000000000000..c05a4a47991e
--- /dev/null
+++ b/includes/resourceloader/Hook/ResourceLoaderSiteStylesModulePagesHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ResourceLoaderSiteStylesModulePagesHook {
+ /**
+ * Modify list of pages for a given skin
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $skin string of the current skin key
+ * @param ?mixed &$pages array of pages and their types.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onResourceLoaderSiteStylesModulePages( $skin, &$pages );
+}
diff --git a/includes/resourceloader/Hook/ResourceLoaderTestModulesHook.php b/includes/resourceloader/Hook/ResourceLoaderTestModulesHook.php
new file mode 100644
index 000000000000..5a69f548a76c
--- /dev/null
+++ b/includes/resourceloader/Hook/ResourceLoaderTestModulesHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ResourceLoaderTestModulesHook {
+ /**
+ * DEPRECATED since 1.33! Register ResourceLoader modules
+ * that are only available when `$wgEnableJavaScriptTest` is true. Use this for test
+ * suites and other test-only resources.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$testModules one array of modules per test framework. The modules array
+ * follows the same format as `$wgResourceModules`. For example:
+ * $testModules['qunit']['ext.Example.test'] = [
+ * 'localBasePath' => __DIR__ . '/tests/qunit',
+ * 'remoteExtPath' => 'Example/tests/qunit',
+ * 'script' => [ 'tests/qunit/foo.js' ],
+ * 'dependencies' => [ 'ext.Example.foo' ]
+ * ];
+ * @param ?mixed $ResourceLoader object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onResourceLoaderTestModules( &$testModules, $ResourceLoader );
+}
diff --git a/includes/revisiondelete/Hook/ArticleRevisionVisibilitySetHook.php b/includes/revisiondelete/Hook/ArticleRevisionVisibilitySetHook.php
new file mode 100644
index 000000000000..a74386535f18
--- /dev/null
+++ b/includes/revisiondelete/Hook/ArticleRevisionVisibilitySetHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ArticleRevisionVisibilitySetHook {
+ /**
+ * Called when changing visibility of one or more
+ * revisions of an article.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Title object of the article
+ * @param ?mixed $ids Ids to set the visibility for
+ * @param ?mixed $visibilityChangeMap Map of revision id to oldBits and newBits. This array can be
+ * examined to determine exactly what visibility bits have changed for each
+ * revision. This array is of the form
+ * [id => ['oldBits' => $oldBits, 'newBits' => $newBits], ... ]
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onArticleRevisionVisibilitySet( $title, $ids,
+ $visibilityChangeMap
+ );
+}
diff --git a/includes/search/Hook/PrefixSearchBackendHook.php b/includes/search/Hook/PrefixSearchBackendHook.php
new file mode 100644
index 000000000000..5da9333d6cf2
--- /dev/null
+++ b/includes/search/Hook/PrefixSearchBackendHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PrefixSearchBackendHook {
+ /**
+ * DEPRECATED since 1.27! Override
+ * SearchEngine::completionSearchBackend instead.
+ * Override the title prefix search used for OpenSearch and
+ * AJAX search suggestions. Put results into &$results outparam and return false.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $ns array of int namespace keys to search in
+ * @param ?mixed $search search term (not guaranteed to be conveniently normalized)
+ * @param ?mixed $limit maximum number of results to return
+ * @param ?mixed &$results out param: array of page names (strings)
+ * @param ?mixed $offset number of results to offset from the beginning
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPrefixSearchBackend( $ns, $search, $limit, &$results,
+ $offset
+ );
+}
diff --git a/includes/search/Hook/PrefixSearchExtractNamespaceHook.php b/includes/search/Hook/PrefixSearchExtractNamespaceHook.php
new file mode 100644
index 000000000000..84025ba01742
--- /dev/null
+++ b/includes/search/Hook/PrefixSearchExtractNamespaceHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PrefixSearchExtractNamespaceHook {
+ /**
+ * Called if core was not able to extract a
+ * namespace from the search string so that extensions can attempt it.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$namespaces array of int namespace keys to search in (change this if you can
+ * extract namespaces)
+ * @param ?mixed &$search search term (replace this with term without the namespace if you can
+ * extract one)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPrefixSearchExtractNamespace( &$namespaces, &$search );
+}
diff --git a/includes/search/Hook/SearchAfterNoDirectMatchHook.php b/includes/search/Hook/SearchAfterNoDirectMatchHook.php
new file mode 100644
index 000000000000..2d44d4eaa8d8
--- /dev/null
+++ b/includes/search/Hook/SearchAfterNoDirectMatchHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SearchAfterNoDirectMatchHook {
+ /**
+ * If there was no match for the exact result. This
+ * runs before lettercase variants are attempted, whereas 'SearchGetNearMatch'
+ * runs after.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $term Search term string
+ * @param ?mixed &$title Outparam; set to $title object and return false for a match
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSearchAfterNoDirectMatch( $term, &$title );
+}
diff --git a/includes/search/Hook/SearchGetNearMatchBeforeHook.php b/includes/search/Hook/SearchGetNearMatchBeforeHook.php
new file mode 100644
index 000000000000..b95547b476aa
--- /dev/null
+++ b/includes/search/Hook/SearchGetNearMatchBeforeHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SearchGetNearMatchBeforeHook {
+ /**
+ * Perform exact-title-matches in "go" searches before
+ * the normal operations.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $allSearchTerms Array of the search terms in all content languages
+ * @param ?mixed &$titleResult Outparam; the value to return. A Title object or null.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSearchGetNearMatchBefore( $allSearchTerms, &$titleResult );
+}
diff --git a/includes/search/Hook/SearchGetNearMatchCompleteHook.php b/includes/search/Hook/SearchGetNearMatchCompleteHook.php
new file mode 100644
index 000000000000..036debc26686
--- /dev/null
+++ b/includes/search/Hook/SearchGetNearMatchCompleteHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SearchGetNearMatchCompleteHook {
+ /**
+ * A chance to modify exact-title-matches in "go"
+ * searches.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $term Search term string
+ * @param ?mixed &$title Current Title object that is being returned (null if none found).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSearchGetNearMatchComplete( $term, &$title );
+}
diff --git a/includes/search/Hook/SearchGetNearMatchHook.php b/includes/search/Hook/SearchGetNearMatchHook.php
new file mode 100644
index 000000000000..676793923ee2
--- /dev/null
+++ b/includes/search/Hook/SearchGetNearMatchHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SearchGetNearMatchHook {
+ /**
+ * An extra chance for exact-title-matches in "go" searches
+ * if nothing was found.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $term Search term string
+ * @param ?mixed &$title Outparam; set to $title object and return false for a match
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSearchGetNearMatch( $term, &$title );
+}
diff --git a/includes/search/Hook/SearchIndexFieldsHook.php b/includes/search/Hook/SearchIndexFieldsHook.php
new file mode 100644
index 000000000000..66d478be3d50
--- /dev/null
+++ b/includes/search/Hook/SearchIndexFieldsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SearchIndexFieldsHook {
+ /**
+ * Add fields to search index mapping.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$fields Array of fields, all implement SearchIndexField
+ * @param ?mixed $engine SearchEngine instance for which mapping is being built.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSearchIndexFields( &$fields, $engine );
+}
diff --git a/includes/search/Hook/SearchResultInitFromTitleHook.php b/includes/search/Hook/SearchResultInitFromTitleHook.php
new file mode 100644
index 000000000000..a769f3dc5b46
--- /dev/null
+++ b/includes/search/Hook/SearchResultInitFromTitleHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SearchResultInitFromTitleHook {
+ /**
+ * Set the revision used when displaying a page in
+ * search results.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title Current Title object being displayed in search results.
+ * @param ?mixed &$id Revision ID (default is false, for latest)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSearchResultInitFromTitle( $title, &$id );
+}
diff --git a/includes/search/Hook/SearchResultsAugmentHook.php b/includes/search/Hook/SearchResultsAugmentHook.php
new file mode 100644
index 000000000000..f817b8c5a7cb
--- /dev/null
+++ b/includes/search/Hook/SearchResultsAugmentHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SearchResultsAugmentHook {
+ /**
+ * Allows extension to add its code to the list of search
+ * result augmentors.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$setAugmentors List of whole-set augmentor objects, must implement
+ * ResultSetAugmentor.
+ * @param ?mixed &$rowAugmentors List of per-row augmentor objects, must implement
+ * ResultAugmentor.
+ * Note that lists should be in the format name => object and the names in both
+ * lists should be distinct.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSearchResultsAugment( &$setAugmentors, &$rowAugmentors );
+}
diff --git a/includes/search/Hook/SearchableNamespacesHook.php b/includes/search/Hook/SearchableNamespacesHook.php
new file mode 100644
index 000000000000..70f297dbcdc8
--- /dev/null
+++ b/includes/search/Hook/SearchableNamespacesHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SearchableNamespacesHook {
+ /**
+ * An option to modify which namespaces are searchable.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$arr Array of namespaces ($nsId => $name) which will be used.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSearchableNamespaces( &$arr );
+}
diff --git a/includes/search/Hook/ShowSearchHitHook.php b/includes/search/Hook/ShowSearchHitHook.php
new file mode 100644
index 000000000000..3cf33af6560b
--- /dev/null
+++ b/includes/search/Hook/ShowSearchHitHook.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ShowSearchHitHook {
+ /**
+ * Customize display of search hit.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $searchPage The SpecialSearch instance.
+ * @param ?mixed $result The SearchResult to show
+ * @param ?mixed $terms Search terms, for highlighting (unreliable as search engine dependent).
+ * @param ?mixed &$link HTML of link to the matching page. May be modified.
+ * @param ?mixed &$redirect HTML of redirect info. May be modified.
+ * @param ?mixed &$section HTML of matching section. May be modified.
+ * @param ?mixed &$extract HTML of content extract. May be modified.
+ * @param ?mixed &$score HTML of score. May be modified.
+ * @param ?mixed &$size HTML of page size. May be modified.
+ * @param ?mixed &$date HTML of of page modification date. May be modified.
+ * @param ?mixed &$related HTML of additional info for the matching page. May be modified.
+ * @param ?mixed &$html May be set to the full HTML that should be used to represent the search
+ * hit. Must include the <li> ... </li> tags. Will only be used if the hook
+ * function returned false.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onShowSearchHit( $searchPage, $result, $terms, &$link,
+ &$redirect, &$section, &$extract, &$score, &$size, &$date, &$related, &$html
+ );
+}
diff --git a/includes/search/Hook/ShowSearchHitTitleHook.php b/includes/search/Hook/ShowSearchHitTitleHook.php
new file mode 100644
index 000000000000..aeefbb69db6b
--- /dev/null
+++ b/includes/search/Hook/ShowSearchHitTitleHook.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ShowSearchHitTitleHook {
+ /**
+ * Customise display of search hit title/link.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$title Title to link to
+ * @param ?mixed &$titleSnippet Label for the link representing the search result. Typically the
+ * article title.
+ * @param ?mixed $result The SearchResult object
+ * @param ?mixed $terms array of search terms extracted by SearchDatabase search engines
+ * (may not be populated by other search engines).
+ * @param ?mixed $specialSearch The SpecialSearch object
+ * @param ?mixed &$query Array of query string parameters for the link representing the search
+ * result.
+ * @param ?mixed &$attributes Array of title link attributes, can be modified by extension.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onShowSearchHitTitle( &$title, &$titleSnippet, $result, $terms,
+ $specialSearch, &$query, &$attributes
+ );
+}
diff --git a/includes/search/Hook/SpecialSearchPowerBoxHook.php b/includes/search/Hook/SpecialSearchPowerBoxHook.php
new file mode 100644
index 000000000000..aaa0fad1f520
--- /dev/null
+++ b/includes/search/Hook/SpecialSearchPowerBoxHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialSearchPowerBoxHook {
+ /**
+ * The equivalent of SpecialSearchProfileForm for
+ * the advanced form, a.k.a. power search box.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$showSections an array to add values with more options to
+ * @param ?mixed $term the search term (not a title object)
+ * @param ?mixed &$opts an array of hidden options (containing 'redirs' and 'profile')
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialSearchPowerBox( &$showSections, $term, &$opts );
+}
diff --git a/includes/search/Hook/SpecialSearchProfileFormHook.php b/includes/search/Hook/SpecialSearchProfileFormHook.php
new file mode 100644
index 000000000000..8c370dfd8768
--- /dev/null
+++ b/includes/search/Hook/SpecialSearchProfileFormHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Search\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialSearchProfileFormHook {
+ /**
+ * Allows modification of search profile forms.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $search special page object
+ * @param ?mixed &$form String: form html
+ * @param ?mixed $profile String: current search profile
+ * @param ?mixed $term String: search term
+ * @param ?mixed $opts Array: key => value of hidden options for inclusion in custom forms
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialSearchProfileForm( $search, &$form, $profile, $term,
+ $opts
+ );
+}
diff --git a/includes/session/Hook/SessionCheckInfoHook.php b/includes/session/Hook/SessionCheckInfoHook.php
new file mode 100644
index 000000000000..befc6a6c0326
--- /dev/null
+++ b/includes/session/Hook/SessionCheckInfoHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Session\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SessionCheckInfoHook {
+ /**
+ * Validate a MediaWiki\Session\SessionInfo as it's being
+ * loaded from storage. Return false to prevent it from being used.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$reason String rejection reason to be logged
+ * @param ?mixed $info MediaWiki\Session\SessionInfo being validated
+ * @param ?mixed $request WebRequest being loaded from
+ * @param ?mixed $metadata Array|false Metadata array for the MediaWiki\Session\Session
+ * @param ?mixed $data Array|false Data array for the MediaWiki\Session\Session
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSessionCheckInfo( &$reason, $info, $request, $metadata,
+ $data
+ );
+}
diff --git a/includes/session/Hook/SessionMetadataHook.php b/includes/session/Hook/SessionMetadataHook.php
new file mode 100644
index 000000000000..9a1cd3e3813f
--- /dev/null
+++ b/includes/session/Hook/SessionMetadataHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Session\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SessionMetadataHook {
+ /**
+ * Add metadata to a session being saved.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $backend MediaWiki\Session\SessionBackend being saved.
+ * @param ?mixed &$metadata Array Metadata to be stored. Add new keys here.
+ * @param ?mixed $requests Array of WebRequests potentially being saved to. Generally 0-1 real
+ * request and 0+ FauxRequests.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSessionMetadata( $backend, &$metadata, $requests );
+}
diff --git a/includes/session/Hook/UserSetCookiesHook.php b/includes/session/Hook/UserSetCookiesHook.php
new file mode 100644
index 000000000000..4b96c7969ea7
--- /dev/null
+++ b/includes/session/Hook/UserSetCookiesHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Session\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserSetCookiesHook {
+ /**
+ * DEPRECATED since 1.27! If you're trying to replace core
+ * session cookie handling, you want to create a subclass of
+ * MediaWiki\Session\CookieSessionProvider instead. Otherwise, you can no longer
+ * count on user data being saved to cookies versus some other mechanism.
+ * Called when setting user cookies.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User object
+ * @param ?mixed &$session session array, will be added to the session
+ * @param ?mixed &$cookies cookies array mapping cookie name to its value
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserSetCookies( $user, &$session, &$cookies );
+}
diff --git a/includes/shell/Hook/WfShellWikiCmdHook.php b/includes/shell/Hook/WfShellWikiCmdHook.php
new file mode 100644
index 000000000000..58d27fa995dc
--- /dev/null
+++ b/includes/shell/Hook/WfShellWikiCmdHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Shell\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WfShellWikiCmdHook {
+ /**
+ * Called when generating a shell-escaped command line string to
+ * run a MediaWiki cli script.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$script MediaWiki cli script path
+ * @param ?mixed &$parameters Array of arguments and options to the script
+ * @param ?mixed &$options Associative array of options, may contain the 'php' and 'wrapper'
+ * keys
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWfShellWikiCmd( &$script, &$parameters, &$options );
+}
diff --git a/includes/skins/Hook/BaseTemplateAfterPortletHook.php b/includes/skins/Hook/BaseTemplateAfterPortletHook.php
new file mode 100644
index 000000000000..d4b4d5d3d335
--- /dev/null
+++ b/includes/skins/Hook/BaseTemplateAfterPortletHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BaseTemplateAfterPortletHook {
+ /**
+ * After output of portlets, allow injecting
+ * custom HTML after the section. Any uses of the hook need to handle escaping.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $template BaseTemplate
+ * @param ?mixed $portlet string portlet name
+ * @param ?mixed &$html string
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBaseTemplateAfterPortlet( $template, $portlet, &$html );
+}
diff --git a/includes/skins/Hook/BaseTemplateToolboxHook.php b/includes/skins/Hook/BaseTemplateToolboxHook.php
new file mode 100644
index 000000000000..adff4c22252f
--- /dev/null
+++ b/includes/skins/Hook/BaseTemplateToolboxHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BaseTemplateToolboxHook {
+ /**
+ * Called by BaseTemplate when building the $toolbox array
+ * and returning it for the skin to output. You can add items to the toolbox while
+ * still letting the skin make final decisions on skin-specific markup conventions
+ * using this hook.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sk The BaseTemplate base skin template
+ * @param ?mixed &$toolbox An array of toolbox items, see BaseTemplate::getToolbox and
+ * BaseTemplate::makeListItem for details on the format of individual items
+ * inside of this array.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBaseTemplateToolbox( $sk, &$toolbox );
+}
diff --git a/includes/skins/Hook/GetNewMessagesAlertHook.php b/includes/skins/Hook/GetNewMessagesAlertHook.php
new file mode 100644
index 000000000000..105240122841
--- /dev/null
+++ b/includes/skins/Hook/GetNewMessagesAlertHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetNewMessagesAlertHook {
+ /**
+ * Disable or modify the new messages alert
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$newMessagesAlert An empty string by default. If the user has new talk page
+ * messages, this should be populated with an alert message to that effect
+ * @param ?mixed $newtalks An empty array if the user has no new messages or an array
+ * containing links and revisions if there are new messages (See
+ * User::getNewMessageLinks)
+ * @param ?mixed $user The user object of the user who is loading the page
+ * @param ?mixed $out OutputPage object (to check what type of page the user is on)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetNewMessagesAlert( &$newMessagesAlert, $newtalks, $user,
+ $out
+ );
+}
diff --git a/includes/skins/Hook/PersonalUrlsHook.php b/includes/skins/Hook/PersonalUrlsHook.php
new file mode 100644
index 000000000000..32738196e1a2
--- /dev/null
+++ b/includes/skins/Hook/PersonalUrlsHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PersonalUrlsHook {
+ /**
+ * Alter the user-specific navigation links (e.g. "my page,
+ * my talk page, my contributions" etc).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$personal_urls Array of link specifiers (see SkinTemplate.php)
+ * @param ?mixed &$title Title object representing the current page
+ * @param ?mixed $skin SkinTemplate object providing context (e.g. to check if the user is
+ * logged in, etc.)
+ * @return bool|void This hook must not abort, it must return true or null.
+ */
+ public function onPersonalUrls( &$personal_urls, &$title, $skin );
+}
diff --git a/includes/skins/Hook/SidebarBeforeOutputHook.php b/includes/skins/Hook/SidebarBeforeOutputHook.php
new file mode 100644
index 000000000000..785a50bb3728
--- /dev/null
+++ b/includes/skins/Hook/SidebarBeforeOutputHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SidebarBeforeOutputHook {
+ /**
+ * Allows to edit sidebar just before it is output by skins.
+ * Warning: This hook is run on each display. You should consider to use
+ * 'SkinBuildSidebar' that is aggressively cached.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $skin Skin object
+ * @param ?mixed &$bar Sidebar content
+ * Modify $bar to add or modify sidebar portlets.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSidebarBeforeOutput( $skin, &$bar );
+}
diff --git a/includes/skins/Hook/SiteNoticeAfterHook.php b/includes/skins/Hook/SiteNoticeAfterHook.php
new file mode 100644
index 000000000000..19f0c8744412
--- /dev/null
+++ b/includes/skins/Hook/SiteNoticeAfterHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SiteNoticeAfterHook {
+ /**
+ * After the sitenotice/anonnotice is composed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$siteNotice HTML sitenotice. Alter the contents of $siteNotice to add to/alter
+ * the sitenotice/anonnotice.
+ * @param ?mixed $skin Skin object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSiteNoticeAfter( &$siteNotice, $skin );
+}
diff --git a/includes/skins/Hook/SiteNoticeBeforeHook.php b/includes/skins/Hook/SiteNoticeBeforeHook.php
new file mode 100644
index 000000000000..6e4b1ec43b47
--- /dev/null
+++ b/includes/skins/Hook/SiteNoticeBeforeHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SiteNoticeBeforeHook {
+ /**
+ * Before the sitenotice/anonnotice is composed. Return true to
+ * allow the normal method of notice selection/rendering to work, or change the
+ * value of $siteNotice and return false to alter it.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$siteNotice HTML returned as the sitenotice
+ * @param ?mixed $skin Skin object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSiteNoticeBefore( &$siteNotice, $skin );
+}
diff --git a/includes/skins/Hook/SkinAfterBottomScriptsHook.php b/includes/skins/Hook/SkinAfterBottomScriptsHook.php
new file mode 100644
index 000000000000..d3a3829df03d
--- /dev/null
+++ b/includes/skins/Hook/SkinAfterBottomScriptsHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinAfterBottomScriptsHook {
+ /**
+ * At the end of Skin::bottomScripts().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $skin Skin object
+ * @param ?mixed &$text bottomScripts Text. Append to $text to add additional text/scripts after
+ * the stock bottom scripts.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinAfterBottomScripts( $skin, &$text );
+}
diff --git a/includes/skins/Hook/SkinAfterContentHook.php b/includes/skins/Hook/SkinAfterContentHook.php
new file mode 100644
index 000000000000..c7ef98af1767
--- /dev/null
+++ b/includes/skins/Hook/SkinAfterContentHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinAfterContentHook {
+ /**
+ * Allows extensions to add text after the page content and
+ * article metadata. This hook should work in all skins. Set the &$data variable to
+ * the text you're going to add.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$data (string) Text to be printed out directly (without parsing)
+ * @param ?mixed $skin Skin object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinAfterContent( &$data, $skin );
+}
diff --git a/includes/skins/Hook/SkinBuildSidebarHook.php b/includes/skins/Hook/SkinBuildSidebarHook.php
new file mode 100644
index 000000000000..83820155aa8b
--- /dev/null
+++ b/includes/skins/Hook/SkinBuildSidebarHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinBuildSidebarHook {
+ /**
+ * At the end of Skin::buildSidebar().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $skin Skin object
+ * @param ?mixed &$bar Sidebar contents
+ * Modify $bar to add or modify sidebar portlets.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinBuildSidebar( $skin, &$bar );
+}
diff --git a/includes/skins/Hook/SkinCopyrightFooterHook.php b/includes/skins/Hook/SkinCopyrightFooterHook.php
new file mode 100644
index 000000000000..ab1f916cc2b8
--- /dev/null
+++ b/includes/skins/Hook/SkinCopyrightFooterHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinCopyrightFooterHook {
+ /**
+ * Allow for site and per-namespace customization of
+ * copyright notice.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title displayed page title
+ * @param ?mixed $type 'normal' or 'history' for old/diff views
+ * @param ?mixed &$msg overridable message; usually 'copyright' or 'history_copyright'. This
+ * message must be in HTML format, not wikitext!
+ * @param ?mixed &$link overridable HTML link to be passed into the message as $1
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinCopyrightFooter( $title, $type, &$msg, &$link );
+}
diff --git a/includes/skins/Hook/SkinEditSectionLinksHook.php b/includes/skins/Hook/SkinEditSectionLinksHook.php
new file mode 100644
index 000000000000..e36785e76027
--- /dev/null
+++ b/includes/skins/Hook/SkinEditSectionLinksHook.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinEditSectionLinksHook {
+ /**
+ * Modify the section edit links
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $skin Skin object rendering the UI
+ * @param ?mixed $title Title object for the title being linked to (may not be the same as
+ * the page title, if the section is included from a template)
+ * @param ?mixed $section The designation of the section being pointed to, to be included in
+ * the link, like "&section=$section"
+ * @param ?mixed $tooltip The default tooltip. Escape before using.
+ * By default, this is wrapped in the 'editsectionhint' message.
+ * @param ?mixed &$result Array containing all link detail arrays. Each link detail array should
+ * contain the following keys:
+ * - targetTitle - Target Title object
+ * - text - String for the text
+ * - attribs - Array of attributes
+ * - query - Array of query parameters to add to the URL
+ * @param ?mixed $lang The language code to use for the link in the wfMessage function
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinEditSectionLinks( $skin, $title, $section, $tooltip,
+ &$result, $lang
+ );
+}
diff --git a/includes/skins/Hook/SkinGetPoweredByHook.php b/includes/skins/Hook/SkinGetPoweredByHook.php
new file mode 100644
index 000000000000..950a8512549b
--- /dev/null
+++ b/includes/skins/Hook/SkinGetPoweredByHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinGetPoweredByHook {
+ /**
+ * TODO
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$text additional 'powered by' icons in HTML. Note: Modern skin does not use
+ * the MediaWiki icon but plain text instead.
+ * @param ?mixed $skin Skin object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinGetPoweredBy( &$text, $skin );
+}
diff --git a/includes/skins/Hook/SkinPreloadExistenceHook.php b/includes/skins/Hook/SkinPreloadExistenceHook.php
new file mode 100644
index 000000000000..cd23c3e4c47d
--- /dev/null
+++ b/includes/skins/Hook/SkinPreloadExistenceHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinPreloadExistenceHook {
+ /**
+ * Supply titles that should be added to link existence
+ * cache before the page is rendered.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$titles Array of Title objects
+ * @param ?mixed $skin Skin object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinPreloadExistence( &$titles, $skin );
+}
diff --git a/includes/skins/Hook/SkinSubPageSubtitleHook.php b/includes/skins/Hook/SkinSubPageSubtitleHook.php
new file mode 100644
index 000000000000..c9d37e6cfc19
--- /dev/null
+++ b/includes/skins/Hook/SkinSubPageSubtitleHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinSubPageSubtitleHook {
+ /**
+ * At the beginning of Skin::subPageSubtitle().
+ * If false is returned $subpages will be used instead of the HTML
+ * subPageSubtitle() generates.
+ * If true is returned, $subpages will be ignored and the rest of
+ * subPageSubtitle() will run.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$subpages Subpage links HTML
+ * @param ?mixed $skin Skin object
+ * @param ?mixed $out OutputPage object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinSubPageSubtitle( &$subpages, $skin, $out );
+}
diff --git a/includes/skins/Hook/SkinTemplateBuildNavUrlsNav_urlsAfterPermalinkHook.php b/includes/skins/Hook/SkinTemplateBuildNavUrlsNav_urlsAfterPermalinkHook.php
new file mode 100644
index 000000000000..e11da9a9f8aa
--- /dev/null
+++ b/includes/skins/Hook/SkinTemplateBuildNavUrlsNav_urlsAfterPermalinkHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinTemplateBuildNavUrlsNav_urlsAfterPermalinkHook {
+ /**
+ * After creating the "permanent
+ * link" tab.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sktemplate SkinTemplate object
+ * @param ?mixed &$nav_urls array of tabs
+ * @param ?mixed &$revid The revision id of the permanent link
+ * @param ?mixed &$revid2 The revision id of the permanent link, second time
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinTemplateBuildNavUrlsNav_urlsAfterPermalink( $sktemplate,
+ &$nav_urls, &$revid, &$revid2
+ );
+}
diff --git a/includes/skins/Hook/SkinTemplateGetLanguageLinkHook.php b/includes/skins/Hook/SkinTemplateGetLanguageLinkHook.php
new file mode 100644
index 000000000000..af0ef7482eb4
--- /dev/null
+++ b/includes/skins/Hook/SkinTemplateGetLanguageLinkHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinTemplateGetLanguageLinkHook {
+ /**
+ * After building the data for a language link from
+ * which the actual html is constructed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$languageLink array containing data about the link. The following keys can be
+ * modified: href, text, title, class, lang, hreflang. Each of them is a string.
+ * @param ?mixed $languageLinkTitle Title object belonging to the external language link.
+ * @param ?mixed $title Title object of the page the link belongs to.
+ * @param ?mixed $outputPage The OutputPage object the links are built from.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinTemplateGetLanguageLink( &$languageLink,
+ $languageLinkTitle, $title, $outputPage
+ );
+}
diff --git a/includes/skins/Hook/SkinTemplateNavigationHook.php b/includes/skins/Hook/SkinTemplateNavigationHook.php
new file mode 100644
index 000000000000..726625aa7a2e
--- /dev/null
+++ b/includes/skins/Hook/SkinTemplateNavigationHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinTemplateNavigationHook {
+ /**
+ * Called on content pages after the tabs have been
+ * added, but before variants have been added.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sktemplate SkinTemplate object
+ * @param ?mixed &$links Structured navigation links. This is used to alter the navigation for
+ * skins which use buildNavigationUrls such as Vector.
+ * @return bool|void This hook must not abort, it must return true or null.
+ */
+ public function onSkinTemplateNavigation( $sktemplate, &$links );
+}
diff --git a/includes/skins/Hook/SkinTemplateNavigation__SpecialPageHook.php b/includes/skins/Hook/SkinTemplateNavigation__SpecialPageHook.php
new file mode 100644
index 000000000000..ce0577b48518
--- /dev/null
+++ b/includes/skins/Hook/SkinTemplateNavigation__SpecialPageHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinTemplateNavigation__SpecialPageHook {
+ /**
+ * Called on special pages after the special
+ * tab is added but before variants have been added.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sktemplate SkinTemplate object
+ * @param ?mixed &$links Structured navigation links. This is used to alter the navigation for
+ * skins which use buildNavigationUrls such as Vector.
+ * @return bool|void This hook must not abort, it must return true or null.
+ */
+ public function onSkinTemplateNavigation__SpecialPage( $sktemplate, &$links );
+}
diff --git a/includes/skins/Hook/SkinTemplateNavigation__UniversalHook.php b/includes/skins/Hook/SkinTemplateNavigation__UniversalHook.php
new file mode 100644
index 000000000000..92b8ff407189
--- /dev/null
+++ b/includes/skins/Hook/SkinTemplateNavigation__UniversalHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinTemplateNavigation__UniversalHook {
+ /**
+ * Called on both content and special pages
+ * after variants have been added.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sktemplate SkinTemplate object
+ * @param ?mixed &$links Structured navigation links. This is used to alter the navigation for
+ * skins which use buildNavigationUrls such as Vector.
+ * @return bool|void This hook must not abort, it must return true or null.
+ */
+ public function onSkinTemplateNavigation__Universal( $sktemplate, &$links );
+}
diff --git a/includes/skins/Hook/SkinTemplateOutputPageBeforeExecHook.php b/includes/skins/Hook/SkinTemplateOutputPageBeforeExecHook.php
new file mode 100644
index 000000000000..6dd4d7779fb8
--- /dev/null
+++ b/includes/skins/Hook/SkinTemplateOutputPageBeforeExecHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinTemplateOutputPageBeforeExecHook {
+ /**
+ * Before SkinTemplate::outputPage() starts
+ * page output.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sktemplate SkinTemplate object
+ * @param ?mixed $tpl QuickTemplate engine object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinTemplateOutputPageBeforeExec( $sktemplate, $tpl );
+}
diff --git a/includes/skins/Hook/SkinTemplatePreventOtherActiveTabsHook.php b/includes/skins/Hook/SkinTemplatePreventOtherActiveTabsHook.php
new file mode 100644
index 000000000000..967fa70e8cb9
--- /dev/null
+++ b/includes/skins/Hook/SkinTemplatePreventOtherActiveTabsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinTemplatePreventOtherActiveTabsHook {
+ /**
+ * Use this to prevent showing active tabs.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sktemplate SkinTemplate object
+ * @param ?mixed &$res set to true to prevent active tabs
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinTemplatePreventOtherActiveTabs( $sktemplate, &$res );
+}
diff --git a/includes/skins/Hook/SkinTemplateTabActionHook.php b/includes/skins/Hook/SkinTemplateTabActionHook.php
new file mode 100644
index 000000000000..aafa8f16257e
--- /dev/null
+++ b/includes/skins/Hook/SkinTemplateTabActionHook.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinTemplateTabActionHook {
+ /**
+ * Override SkinTemplate::tabAction().
+ * You can either create your own array, or alter the parameters for
+ * the normal one.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sktemplate The SkinTemplate instance.
+ * @param ?mixed $title Title instance for the page.
+ * @param ?mixed $message Visible label of tab.
+ * @param ?mixed $selected Whether this is a selected tab.
+ * @param ?mixed $checkEdit Whether or not the action=edit query should be added if appropriate.
+ * @param ?mixed &$classes Array of CSS classes to apply.
+ * @param ?mixed &$query Query string to add to link.
+ * @param ?mixed &$text Link text.
+ * @param ?mixed &$result Complete assoc. array if you want to return true.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinTemplateTabAction( $sktemplate, $title, $message,
+ $selected, $checkEdit, &$classes, &$query, &$text, &$result
+ );
+}
diff --git a/includes/skins/Hook/SkinTemplateToolboxEndHook.php b/includes/skins/Hook/SkinTemplateToolboxEndHook.php
new file mode 100644
index 000000000000..48ee4e7040a5
--- /dev/null
+++ b/includes/skins/Hook/SkinTemplateToolboxEndHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SkinTemplateToolboxEndHook {
+ /**
+ * Called by SkinTemplate skins after toolbox links have
+ * been rendered (useful for adding more).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sk The QuickTemplate based skin template running the hook.
+ * @param ?mixed $dummy Called when SkinTemplateToolboxEnd is used from a BaseTemplate skin,
+ * extensions that add support for BaseTemplateToolbox should watch for this
+ * dummy parameter with "$dummy=false" in their code and return without echoing
+ * any HTML to avoid creating duplicate toolbox items.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSkinTemplateToolboxEnd( $sk, $dummy );
+}
diff --git a/includes/skins/Hook/UndeletePageToolLinksHook.php b/includes/skins/Hook/UndeletePageToolLinksHook.php
new file mode 100644
index 000000000000..3fccbdd9b4c1
--- /dev/null
+++ b/includes/skins/Hook/UndeletePageToolLinksHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UndeletePageToolLinksHook {
+ /**
+ * Add one or more links to edit page subtitle when a page
+ * has been previously deleted.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $context IContextSource (object)
+ * @param ?mixed $linkRenderer LinkRenderer instance
+ * @param ?mixed &$links Array of HTML strings
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUndeletePageToolLinks( $context, $linkRenderer, &$links );
+}
diff --git a/includes/specialpage/Hook/AuthChangeFormFieldsHook.php b/includes/specialpage/Hook/AuthChangeFormFieldsHook.php
new file mode 100644
index 000000000000..11dcc9b386f9
--- /dev/null
+++ b/includes/specialpage/Hook/AuthChangeFormFieldsHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\SpecialPage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AuthChangeFormFieldsHook {
+ /**
+ * After converting a field information array obtained
+ * from a set of AuthenticationRequest classes into a form descriptor; hooks
+ * can tweak the array to change how login etc. forms should look.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $requests array of AuthenticationRequests the fields are created from
+ * @param ?mixed $fieldInfo field information array (union of all
+ * AuthenticationRequest::getFieldInfo() responses).
+ * @param ?mixed &$formDescriptor HTMLForm descriptor. The special key 'weight' can be set
+ * to change the order of the fields.
+ * @param ?mixed $action one of the AuthManager::ACTION_* constants.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAuthChangeFormFields( $requests, $fieldInfo,
+ &$formDescriptor, $action
+ );
+}
diff --git a/includes/specialpage/Hook/ChangeAuthenticationDataAuditHook.php b/includes/specialpage/Hook/ChangeAuthenticationDataAuditHook.php
new file mode 100644
index 000000000000..ca7b6508807d
--- /dev/null
+++ b/includes/specialpage/Hook/ChangeAuthenticationDataAuditHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\SpecialPage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangeAuthenticationDataAuditHook {
+ /**
+ * Called when user changes his password.
+ * No return data is accepted; this hook is for auditing only.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $req AuthenticationRequest object describing the change (and target user)
+ * @param ?mixed $status StatusValue with the result of the action
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangeAuthenticationDataAudit( $req, $status );
+}
diff --git a/includes/specialpage/Hook/ChangesListSpecialPageQueryHook.php b/includes/specialpage/Hook/ChangesListSpecialPageQueryHook.php
new file mode 100644
index 000000000000..ef0150bed843
--- /dev/null
+++ b/includes/specialpage/Hook/ChangesListSpecialPageQueryHook.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace MediaWiki\SpecialPage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangesListSpecialPageQueryHook {
+ /**
+ * Called when building SQL query on pages
+ * inheriting from ChangesListSpecialPage (in core: RecentChanges,
+ * RecentChangesLinked and Watchlist).
+ * Do not use this to implement individual filters if they are compatible with the
+ * ChangesListFilter and ChangesListFilterGroup structure.
+ * Instead, use sub-classes of those classes, in conjunction with the
+ * ChangesListSpecialPageStructuredFilters hook.
+ * This hook can be used to implement filters that do not implement that structure,
+ * or custom behavior that is not an individual filter.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $name name of the special page, e.g. 'Watchlist'
+ * @param ?mixed &$tables array of tables to be queried
+ * @param ?mixed &$fields array of columns to select
+ * @param ?mixed &$conds array of WHERE conditionals for query
+ * @param ?mixed &$query_options array of options for the database request
+ * @param ?mixed &$join_conds join conditions for the tables
+ * @param ?mixed $opts FormOptions for this request
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangesListSpecialPageQuery( $name, &$tables, &$fields,
+ &$conds, &$query_options, &$join_conds, $opts
+ );
+}
diff --git a/includes/specialpage/Hook/ChangesListSpecialPageStructuredFiltersHook.php b/includes/specialpage/Hook/ChangesListSpecialPageStructuredFiltersHook.php
new file mode 100644
index 000000000000..5e56b4d003bb
--- /dev/null
+++ b/includes/specialpage/Hook/ChangesListSpecialPageStructuredFiltersHook.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace MediaWiki\SpecialPage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangesListSpecialPageStructuredFiltersHook {
+ /**
+ * Called to allow extensions to register
+ * filters for pages inheriting from ChangesListSpecialPage (in core: RecentChanges,
+ * RecentChangesLinked, and Watchlist). Generally, you will want to construct
+ * new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects.
+ * When constructing them, you specify which group they belong to. You can reuse
+ * existing groups (accessed through $special->getFilterGroup), or create your own
+ * (ChangesListBooleanFilterGroup or ChangesListStringOptionsFilterGroup).
+ * If you create new groups, you must register them with $special->registerFilterGroup.
+ * Note that this is called regardless of whether the user is currently using
+ * the new (structured) or old (unstructured) filter UI. If you want your boolean
+ * filter to show on both the new and old UI, specify all the supported fields.
+ * These include showHide, label, and description.
+ * See the constructor of each ChangesList* class for documentation of supported
+ * fields.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $special ChangesListSpecialPage instance
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangesListSpecialPageStructuredFilters( $special );
+}
diff --git a/includes/specialpage/Hook/RedirectSpecialArticleRedirectParamsHook.php b/includes/specialpage/Hook/RedirectSpecialArticleRedirectParamsHook.php
new file mode 100644
index 000000000000..25e27c33f194
--- /dev/null
+++ b/includes/specialpage/Hook/RedirectSpecialArticleRedirectParamsHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\SpecialPage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface RedirectSpecialArticleRedirectParamsHook {
+ /**
+ * Lets you alter the set of parameter
+ * names such as "oldid" that are preserved when using redirecting special pages
+ * such as Special:MyPage and Special:MyTalk.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$redirectParams An array of parameters preserved by redirecting special pages.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onRedirectSpecialArticleRedirectParams( &$redirectParams );
+}
diff --git a/includes/specialpage/Hook/SpecialPageAfterExecuteHook.php b/includes/specialpage/Hook/SpecialPageAfterExecuteHook.php
new file mode 100644
index 000000000000..a57c40bdcef0
--- /dev/null
+++ b/includes/specialpage/Hook/SpecialPageAfterExecuteHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\SpecialPage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialPageAfterExecuteHook {
+ /**
+ * Called after SpecialPage::execute.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $special the SpecialPage object
+ * @param ?mixed $subPage the subpage string or null if no subpage was specified
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialPageAfterExecute( $special, $subPage );
+}
diff --git a/includes/specialpage/Hook/SpecialPageBeforeExecuteHook.php b/includes/specialpage/Hook/SpecialPageBeforeExecuteHook.php
new file mode 100644
index 000000000000..03fc4a31dfaa
--- /dev/null
+++ b/includes/specialpage/Hook/SpecialPageBeforeExecuteHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\SpecialPage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialPageBeforeExecuteHook {
+ /**
+ * Called before SpecialPage::execute.
+ * Return false to prevent execution.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $special the SpecialPage object
+ * @param ?mixed $subPage the subpage string or null if no subpage was specified
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialPageBeforeExecute( $special, $subPage );
+}
diff --git a/includes/specialpage/Hook/SpecialPageBeforeFormDisplayHook.php b/includes/specialpage/Hook/SpecialPageBeforeFormDisplayHook.php
new file mode 100644
index 000000000000..dc6f430fbfdc
--- /dev/null
+++ b/includes/specialpage/Hook/SpecialPageBeforeFormDisplayHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\SpecialPage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialPageBeforeFormDisplayHook {
+ /**
+ * Before executing the HTMLForm object.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $name name of the special page
+ * @param ?mixed $form HTMLForm object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialPageBeforeFormDisplay( $name, $form );
+}
diff --git a/includes/specialpage/Hook/SpecialPage_initListHook.php b/includes/specialpage/Hook/SpecialPage_initListHook.php
new file mode 100644
index 000000000000..70d6aaea3814
--- /dev/null
+++ b/includes/specialpage/Hook/SpecialPage_initListHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\SpecialPage\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialPage_initListHook {
+ /**
+ * Called when setting up SpecialPageFactory::$list, use
+ * this hook to remove a core special page or conditionally register special pages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$list list (array) of core special pages
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialPage_initList( &$list );
+}
diff --git a/includes/specialpage/Hook/WgQueryPagesHook.php b/includes/specialpage/Hook/WgQueryPagesHook.php
new file mode 100644
index 000000000000..a719bfdb94c1
--- /dev/null
+++ b/includes/specialpage/Hook/WgQueryPagesHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\SpecialPage\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WgQueryPagesHook {
+ /**
+ * Called when initialising list of QueryPage subclasses, use this
+ * to add new query pages to be updated with maintenance/updateSpecialPages.php.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$qp The list of QueryPages
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWgQueryPages( &$qp );
+}
diff --git a/includes/specials/Hook/AddNewAccountHook.php b/includes/specials/Hook/AddNewAccountHook.php
new file mode 100644
index 000000000000..17f0cfa3bb3f
--- /dev/null
+++ b/includes/specials/Hook/AddNewAccountHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AddNewAccountHook {
+ /**
+ * DEPRECATED since 1.27! Use LocalUserCreated.
+ * After a user account is created.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user the User object that was created. (Parameter added in 1.7)
+ * @param ?mixed $byEmail true when account was created "by email" (added in 1.12)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAddNewAccount( $user, $byEmail );
+}
diff --git a/includes/specials/Hook/AncientPagesQueryHook.php b/includes/specials/Hook/AncientPagesQueryHook.php
new file mode 100644
index 000000000000..d0152dce4286
--- /dev/null
+++ b/includes/specials/Hook/AncientPagesQueryHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface AncientPagesQueryHook {
+ /**
+ * Allow extensions to modify the query used by
+ * Special:AncientPages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tables tables to join in the query
+ * @param ?mixed &$conds conditions for the query
+ * @param ?mixed &$joinConds join conditions for the query
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onAncientPagesQuery( &$tables, &$conds, &$joinConds );
+}
diff --git a/includes/specials/Hook/BeforeWelcomeCreationHook.php b/includes/specials/Hook/BeforeWelcomeCreationHook.php
new file mode 100644
index 000000000000..b80d8d66d25e
--- /dev/null
+++ b/includes/specials/Hook/BeforeWelcomeCreationHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BeforeWelcomeCreationHook {
+ /**
+ * Before the welcomecreation message is displayed to a
+ * newly created user.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$welcome_creation_msg MediaWiki message name to display on the welcome screen
+ * to a newly created user account.
+ * @param ?mixed &$injected_html Any HTML to inject after the "logged in" message of a newly
+ * created user account
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBeforeWelcomeCreation( &$welcome_creation_msg,
+ &$injected_html
+ );
+}
diff --git a/includes/specials/Hook/BlockIpCompleteHook.php b/includes/specials/Hook/BlockIpCompleteHook.php
new file mode 100644
index 000000000000..817e41cc8e31
--- /dev/null
+++ b/includes/specials/Hook/BlockIpCompleteHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BlockIpCompleteHook {
+ /**
+ * After an IP address or user is blocked.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $block the Block object that was saved
+ * @param ?mixed $user the user who did the block (not the one being blocked)
+ * @param ?mixed $priorBlock the Block object for the prior block or null if there was none
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBlockIpComplete( $block, $user, $priorBlock );
+}
diff --git a/includes/specials/Hook/BlockIpHook.php b/includes/specials/Hook/BlockIpHook.php
new file mode 100644
index 000000000000..d73bb74b406a
--- /dev/null
+++ b/includes/specials/Hook/BlockIpHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BlockIpHook {
+ /**
+ * Before an IP address or user is blocked.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $block the Block object about to be saved
+ * @param ?mixed $user the user _doing_ the block (not the one being blocked)
+ * @param ?mixed &$reason if the hook is aborted, the error message to be returned in an array
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBlockIp( $block, $user, &$reason );
+}
diff --git a/includes/specials/Hook/BookInformationHook.php b/includes/specials/Hook/BookInformationHook.php
new file mode 100644
index 000000000000..99c1d38470b3
--- /dev/null
+++ b/includes/specials/Hook/BookInformationHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BookInformationHook {
+ /**
+ * Before information output on Special:Booksources.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $isbn ISBN to show information for
+ * @param ?mixed $output OutputPage object in use
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBookInformation( $isbn, $output );
+}
diff --git a/includes/specials/Hook/ChangeUserGroupsHook.php b/includes/specials/Hook/ChangeUserGroupsHook.php
new file mode 100644
index 000000000000..30cc81dd6a69
--- /dev/null
+++ b/includes/specials/Hook/ChangeUserGroupsHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ChangeUserGroupsHook {
+ /**
+ * Called before user groups are changed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $performer The User who will perform the change
+ * @param ?mixed $user The User whose groups will be changed
+ * @param ?mixed &$add The groups that will be added
+ * @param ?mixed &$remove The groups that will be removed
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onChangeUserGroups( $performer, $user, &$add, &$remove );
+}
diff --git a/includes/specials/Hook/ContribsPager__getQueryInfoHook.php b/includes/specials/Hook/ContribsPager__getQueryInfoHook.php
new file mode 100644
index 000000000000..624175f16a60
--- /dev/null
+++ b/includes/specials/Hook/ContribsPager__getQueryInfoHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContribsPager__getQueryInfoHook {
+ /**
+ * Before the contributions query is about to run
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $pager Pager object for contributions
+ * @param ?mixed &$queryInfo The query for the contribs Pager
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContribsPager__getQueryInfo( $pager, &$queryInfo );
+}
diff --git a/includes/specials/Hook/ContribsPager__reallyDoQueryHook.php b/includes/specials/Hook/ContribsPager__reallyDoQueryHook.php
new file mode 100644
index 000000000000..2884ba31d700
--- /dev/null
+++ b/includes/specials/Hook/ContribsPager__reallyDoQueryHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContribsPager__reallyDoQueryHook {
+ /**
+ * Called before really executing the query for My
+ * Contributions
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$data an array of results of all contribs queries
+ * @param ?mixed $pager The ContribsPager object hooked into
+ * @param ?mixed $offset Index offset, inclusive
+ * @param ?mixed $limit Exact query limit
+ * @param ?mixed $descending Query direction, false for ascending, true for descending
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContribsPager__reallyDoQuery( &$data, $pager, $offset,
+ $limit, $descending
+ );
+}
diff --git a/includes/specials/Hook/ContributionsLineEndingHook.php b/includes/specials/Hook/ContributionsLineEndingHook.php
new file mode 100644
index 000000000000..078d1a9f5e0d
--- /dev/null
+++ b/includes/specials/Hook/ContributionsLineEndingHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContributionsLineEndingHook {
+ /**
+ * Called before a contributions HTML line is finished
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $page SpecialPage object for contributions
+ * @param ?mixed &$ret the HTML line
+ * @param ?mixed $row the DB row for this line
+ * @param ?mixed &$classes the classes to add to the surrounding <li>
+ * @param ?mixed &$attribs associative array of other HTML attributes for the <li> element.
+ * Currently only data attributes reserved to MediaWiki are allowed
+ * (see Sanitizer::isReservedDataAttribute).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContributionsLineEnding( $page, &$ret, $row, &$classes,
+ &$attribs
+ );
+}
diff --git a/includes/specials/Hook/ContributionsToolLinksHook.php b/includes/specials/Hook/ContributionsToolLinksHook.php
new file mode 100644
index 000000000000..9566ee13dd40
--- /dev/null
+++ b/includes/specials/Hook/ContributionsToolLinksHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ContributionsToolLinksHook {
+ /**
+ * Change tool links above Special:Contributions
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $id User identifier
+ * @param ?mixed $title User page title
+ * @param ?mixed &$tools Array of tool links
+ * @param ?mixed $specialPage SpecialPage instance for context and services. Can be either
+ * SpecialContributions or DeletedContributionsPage. Extensions should type
+ * hint against a generic SpecialPage though.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onContributionsToolLinks( $id, $title, &$tools, $specialPage );
+}
diff --git a/includes/specials/Hook/DeletedContribsPager__reallyDoQueryHook.php b/includes/specials/Hook/DeletedContribsPager__reallyDoQueryHook.php
new file mode 100644
index 000000000000..ce6cb5a3e27c
--- /dev/null
+++ b/includes/specials/Hook/DeletedContribsPager__reallyDoQueryHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DeletedContribsPager__reallyDoQueryHook {
+ /**
+ * Called before really executing the query
+ * for Special:DeletedContributions
+ * Similar to ContribsPager::reallyDoQuery
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$data an array of results of all contribs queries
+ * @param ?mixed $pager The DeletedContribsPager object hooked into
+ * @param ?mixed $offset Index offset, inclusive
+ * @param ?mixed $limit Exact query limit
+ * @param ?mixed $descending Query direction, false for ascending, true for descending
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDeletedContribsPager__reallyDoQuery( &$data, $pager, $offset,
+ $limit, $descending
+ );
+}
diff --git a/includes/specials/Hook/DeletedContributionsLineEndingHook.php b/includes/specials/Hook/DeletedContributionsLineEndingHook.php
new file mode 100644
index 000000000000..d310984fe1fa
--- /dev/null
+++ b/includes/specials/Hook/DeletedContributionsLineEndingHook.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface DeletedContributionsLineEndingHook {
+ /**
+ * Called before a DeletedContributions HTML line
+ * is finished.
+ * Similar to ContributionsLineEnding
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $page SpecialPage object for DeletedContributions
+ * @param ?mixed &$ret the HTML line
+ * @param ?mixed $row the DB row for this line
+ * @param ?mixed &$classes the classes to add to the surrounding <li>
+ * @param ?mixed &$attribs associative array of other HTML attributes for the <li> element.
+ * Currently only data attributes reserved to MediaWiki are allowed
+ * (see Sanitizer::isReservedDataAttribute).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onDeletedContributionsLineEnding( $page, &$ret, $row,
+ &$classes, &$attribs
+ );
+}
diff --git a/includes/specials/Hook/EmailUserCCHook.php b/includes/specials/Hook/EmailUserCCHook.php
new file mode 100644
index 000000000000..dad517fdebb3
--- /dev/null
+++ b/includes/specials/Hook/EmailUserCCHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EmailUserCCHook {
+ /**
+ * Before sending the copy of the email to the author.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$to MailAddress object of receiving user
+ * @param ?mixed &$from MailAddress object of sending user
+ * @param ?mixed &$subject subject of the mail
+ * @param ?mixed &$text text of the mail
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEmailUserCC( &$to, &$from, &$subject, &$text );
+}
diff --git a/includes/specials/Hook/EmailUserCompleteHook.php b/includes/specials/Hook/EmailUserCompleteHook.php
new file mode 100644
index 000000000000..a5ca5b132f2e
--- /dev/null
+++ b/includes/specials/Hook/EmailUserCompleteHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EmailUserCompleteHook {
+ /**
+ * After sending email from one user to another.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $to MailAddress object of receiving user
+ * @param ?mixed $from MailAddress object of sending user
+ * @param ?mixed $subject subject of the mail
+ * @param ?mixed $text text of the mail
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEmailUserComplete( $to, $from, $subject, $text );
+}
diff --git a/includes/specials/Hook/EmailUserFormHook.php b/includes/specials/Hook/EmailUserFormHook.php
new file mode 100644
index 000000000000..56f9452a0daf
--- /dev/null
+++ b/includes/specials/Hook/EmailUserFormHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EmailUserFormHook {
+ /**
+ * After building the email user form object.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$form HTMLForm object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEmailUserForm( &$form );
+}
diff --git a/includes/specials/Hook/EmailUserHook.php b/includes/specials/Hook/EmailUserHook.php
new file mode 100644
index 000000000000..ca2d45045ffa
--- /dev/null
+++ b/includes/specials/Hook/EmailUserHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EmailUserHook {
+ /**
+ * Before sending email from one user to another.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$to MailAddress object of receiving user
+ * @param ?mixed &$from MailAddress object of sending user
+ * @param ?mixed &$subject subject of the mail
+ * @param ?mixed &$text text of the mail
+ * @param ?mixed &$error Out-param for an error. Should be set to a Status object or boolean
+ * false.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEmailUser( &$to, &$from, &$subject, &$text, &$error );
+}
diff --git a/includes/specials/Hook/EmailUserPermissionsErrorsHook.php b/includes/specials/Hook/EmailUserPermissionsErrorsHook.php
new file mode 100644
index 000000000000..923686057072
--- /dev/null
+++ b/includes/specials/Hook/EmailUserPermissionsErrorsHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EmailUserPermissionsErrorsHook {
+ /**
+ * to retrieve permissions errors for emailing a
+ * user.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user The user who is trying to email another user.
+ * @param ?mixed $editToken The user's edit token.
+ * @param ?mixed &$hookErr Out-param for the error. Passed as the parameters to
+ * OutputPage::showErrorPage.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEmailUserPermissionsErrors( $user, $editToken, &$hookErr );
+}
diff --git a/includes/specials/Hook/ExtensionTypesHook.php b/includes/specials/Hook/ExtensionTypesHook.php
new file mode 100644
index 000000000000..3ea710ce3b9b
--- /dev/null
+++ b/includes/specials/Hook/ExtensionTypesHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ExtensionTypesHook {
+ /**
+ * Called when generating the extensions credits, use this to
+ * change the tables headers.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$extTypes associative array of extensions types
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onExtensionTypes( &$extTypes );
+}
diff --git a/includes/specials/Hook/FileUndeleteCompleteHook.php b/includes/specials/Hook/FileUndeleteCompleteHook.php
new file mode 100644
index 000000000000..b68c668a92f8
--- /dev/null
+++ b/includes/specials/Hook/FileUndeleteCompleteHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface FileUndeleteCompleteHook {
+ /**
+ * When a file is undeleted
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title title object to the file
+ * @param ?mixed $fileVersions array of undeleted versions. Empty if all versions were restored
+ * @param ?mixed $user user who performed the undeletion
+ * @param ?mixed $reason reason
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onFileUndeleteComplete( $title, $fileVersions, $user, $reason );
+}
diff --git a/includes/specials/Hook/GetLogTypesOnUserHook.php b/includes/specials/Hook/GetLogTypesOnUserHook.php
new file mode 100644
index 000000000000..70b4a55c6fc9
--- /dev/null
+++ b/includes/specials/Hook/GetLogTypesOnUserHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface GetLogTypesOnUserHook {
+ /**
+ * Add log types where the target is a userpage
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$types Array of log types
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onGetLogTypesOnUser( &$types );
+}
diff --git a/includes/specials/Hook/ImportLogInterwikiLinkHook.php b/includes/specials/Hook/ImportLogInterwikiLinkHook.php
new file mode 100644
index 000000000000..7578ebc9a93a
--- /dev/null
+++ b/includes/specials/Hook/ImportLogInterwikiLinkHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImportLogInterwikiLinkHook {
+ /**
+ * Hook to change the interwiki link used in log entries
+ * and edit summaries for transwiki imports.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$fullInterwikiPrefix Interwiki prefix, may contain colons.
+ * @param ?mixed &$pageTitle String that contains page title.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImportLogInterwikiLink( &$fullInterwikiPrefix, &$pageTitle );
+}
diff --git a/includes/specials/Hook/ImportSourcesHook.php b/includes/specials/Hook/ImportSourcesHook.php
new file mode 100644
index 000000000000..b37889c87b4c
--- /dev/null
+++ b/includes/specials/Hook/ImportSourcesHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ImportSourcesHook {
+ /**
+ * Called when reading from the $wgImportSources configuration
+ * variable. Can be used to lazy-load the import sources list.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$importSources The value of $wgImportSources. Modify as necessary. See the
+ * comment in DefaultSettings.php for the detail of how to structure this array.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onImportSources( &$importSources );
+}
diff --git a/includes/specials/Hook/LanguageSelectorHook.php b/includes/specials/Hook/LanguageSelectorHook.php
new file mode 100644
index 000000000000..04e41c760ddb
--- /dev/null
+++ b/includes/specials/Hook/LanguageSelectorHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LanguageSelectorHook {
+ /**
+ * Hook to change the language selector available on a page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $out The output page.
+ * @param ?mixed $cssClassName CSS class name of the language selector.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLanguageSelector( $out, $cssClassName );
+}
diff --git a/includes/specials/Hook/LoginFormValidErrorMessagesHook.php b/includes/specials/Hook/LoginFormValidErrorMessagesHook.php
new file mode 100644
index 000000000000..109c60e765ec
--- /dev/null
+++ b/includes/specials/Hook/LoginFormValidErrorMessagesHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LoginFormValidErrorMessagesHook {
+ /**
+ * Called in LoginForm when a function gets valid
+ * error messages. Allows to add additional error messages (except messages already
+ * in LoginForm::$validErrorMessages).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$messages Already added messages (inclusive messages from
+ * LoginForm::$validErrorMessages)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLoginFormValidErrorMessages( &$messages );
+}
diff --git a/includes/specials/Hook/LonelyPagesQueryHook.php b/includes/specials/Hook/LonelyPagesQueryHook.php
new file mode 100644
index 000000000000..833fbdc45efd
--- /dev/null
+++ b/includes/specials/Hook/LonelyPagesQueryHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface LonelyPagesQueryHook {
+ /**
+ * Allow extensions to modify the query used by
+ * Special:LonelyPages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tables tables to join in the query
+ * @param ?mixed &$conds conditions for the query
+ * @param ?mixed &$joinConds join conditions for the query
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onLonelyPagesQuery( &$tables, &$conds, &$joinConds );
+}
diff --git a/includes/specials/Hook/NewPagesLineEndingHook.php b/includes/specials/Hook/NewPagesLineEndingHook.php
new file mode 100644
index 000000000000..b15e365ef781
--- /dev/null
+++ b/includes/specials/Hook/NewPagesLineEndingHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface NewPagesLineEndingHook {
+ /**
+ * Called before a NewPages line is finished.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $page the SpecialNewPages object
+ * @param ?mixed &$ret the HTML line
+ * @param ?mixed $row the database row for this page (the recentchanges record and a few extras
+ * - see NewPagesPager::getQueryInfo)
+ * @param ?mixed &$classes the classes to add to the surrounding <li>
+ * @param ?mixed &$attribs associative array of other HTML attributes for the <li> element.
+ * Currently only data attributes reserved to MediaWiki are allowed
+ * (see Sanitizer::isReservedDataAttribute).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onNewPagesLineEnding( $page, &$ret, $row, &$classes, &$attribs );
+}
diff --git a/includes/specials/Hook/OtherAutoblockLogLinkHook.php b/includes/specials/Hook/OtherAutoblockLogLinkHook.php
new file mode 100644
index 000000000000..6ddbc8379f2c
--- /dev/null
+++ b/includes/specials/Hook/OtherAutoblockLogLinkHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface OtherAutoblockLogLinkHook {
+ /**
+ * Get links to the autoblock log from extensions which
+ * autoblocks users and/or IP addresses too.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$otherBlockLink An array with links to other autoblock logs
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onOtherAutoblockLogLink( &$otherBlockLink );
+}
diff --git a/includes/specials/Hook/OtherBlockLogLinkHook.php b/includes/specials/Hook/OtherBlockLogLinkHook.php
new file mode 100644
index 000000000000..82b2e1b8aba6
--- /dev/null
+++ b/includes/specials/Hook/OtherBlockLogLinkHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface OtherBlockLogLinkHook {
+ /**
+ * Get links to the block log from extensions which blocks
+ * users and/or IP addresses too.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$otherBlockLink An array with links to other block logs
+ * @param ?mixed $ip The requested IP address or username
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onOtherBlockLogLink( &$otherBlockLink, $ip );
+}
diff --git a/includes/specials/Hook/PostLoginRedirectHook.php b/includes/specials/Hook/PostLoginRedirectHook.php
new file mode 100644
index 000000000000..fbb60a636c74
--- /dev/null
+++ b/includes/specials/Hook/PostLoginRedirectHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PostLoginRedirectHook {
+ /**
+ * Modify the post login redirect behavior.
+ * Occurs after signing up or logging in, allows for interception of redirect.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$returnTo The page name to return to, as a string
+ * @param ?mixed &$returnToQuery array of url parameters, mapping parameter names to values
+ * @param ?mixed &$type type of login redirect as string;
+ * error: display a return to link ignoring $wgRedirectOnLogin
+ * signup: display a return to link using $wgRedirectOnLogin if needed
+ * success: display a return to link using $wgRedirectOnLogin if needed
+ * successredirect: send an HTTP redirect using $wgRedirectOnLogin if needed
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPostLoginRedirect( &$returnTo, &$returnToQuery, &$type );
+}
diff --git a/includes/specials/Hook/PreferencesGetLegendHook.php b/includes/specials/Hook/PreferencesGetLegendHook.php
new file mode 100644
index 000000000000..10e7a65e9776
--- /dev/null
+++ b/includes/specials/Hook/PreferencesGetLegendHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PreferencesGetLegendHook {
+ /**
+ * Override the text used for the <legend> of a
+ * preferences section.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $form the HTMLForm object. This is a ContextSource as well
+ * @param ?mixed $key the section name
+ * @param ?mixed &$legend the legend text. Defaults to wfMessage( "prefs-$key" )->text() but may
+ * be overridden
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPreferencesGetLegend( $form, $key, &$legend );
+}
diff --git a/includes/specials/Hook/PrefsEmailAuditHook.php b/includes/specials/Hook/PrefsEmailAuditHook.php
new file mode 100644
index 000000000000..e46238ceb6ff
--- /dev/null
+++ b/includes/specials/Hook/PrefsEmailAuditHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PrefsEmailAuditHook {
+ /**
+ * Called when user changes their email address.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User (object) changing his email address
+ * @param ?mixed $oldaddr old email address (string)
+ * @param ?mixed $newaddr new email address (string)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPrefsEmailAudit( $user, $oldaddr, $newaddr );
+}
diff --git a/includes/specials/Hook/RandomPageQueryHook.php b/includes/specials/Hook/RandomPageQueryHook.php
new file mode 100644
index 000000000000..3452f724f446
--- /dev/null
+++ b/includes/specials/Hook/RandomPageQueryHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface RandomPageQueryHook {
+ /**
+ * Lets you modify the query used by Special:Random to select
+ * random pages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tables Database tables to be used in the query
+ * @param ?mixed &$conds Conditions to be applied in the query
+ * @param ?mixed &$joinConds Join conditions to be applied in the query
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onRandomPageQuery( &$tables, &$conds, &$joinConds );
+}
diff --git a/includes/specials/Hook/ShortPagesQueryHook.php b/includes/specials/Hook/ShortPagesQueryHook.php
new file mode 100644
index 000000000000..f039a24433c4
--- /dev/null
+++ b/includes/specials/Hook/ShortPagesQueryHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ShortPagesQueryHook {
+ /**
+ * Allow extensions to modify the query used by
+ * Special:ShortPages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tables tables to join in the query
+ * @param ?mixed &$conds conditions for the query
+ * @param ?mixed &$joinConds join conditions for the query
+ * @param ?mixed &$options options for the query
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onShortPagesQuery( &$tables, &$conds, &$joinConds, &$options );
+}
diff --git a/includes/specials/Hook/SoftwareInfoHook.php b/includes/specials/Hook/SoftwareInfoHook.php
new file mode 100644
index 000000000000..cde4710f5cf6
--- /dev/null
+++ b/includes/specials/Hook/SoftwareInfoHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SoftwareInfoHook {
+ /**
+ * Called by Special:Version for returning information about the
+ * software.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$software The array of software in format 'name' => 'version'. See
+ * SpecialVersion::softwareInformation().
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSoftwareInfo( &$software );
+}
diff --git a/includes/specials/Hook/SpecialBlockModifyFormFieldsHook.php b/includes/specials/Hook/SpecialBlockModifyFormFieldsHook.php
new file mode 100644
index 000000000000..5a36a88a2a07
--- /dev/null
+++ b/includes/specials/Hook/SpecialBlockModifyFormFieldsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialBlockModifyFormFieldsHook {
+ /**
+ * Add more fields to Special:Block
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sp SpecialPage object, for context
+ * @param ?mixed &$fields Current HTMLForm fields
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialBlockModifyFormFields( $sp, &$fields );
+}
diff --git a/includes/specials/Hook/SpecialContributionsBeforeMainOutputHook.php b/includes/specials/Hook/SpecialContributionsBeforeMainOutputHook.php
new file mode 100644
index 000000000000..3aa2646d6348
--- /dev/null
+++ b/includes/specials/Hook/SpecialContributionsBeforeMainOutputHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialContributionsBeforeMainOutputHook {
+ /**
+ * Before the form on Special:Contributions
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $id User id number, only provided for backwards-compatibility
+ * @param ?mixed $user User object representing user contributions are being fetched for
+ * @param ?mixed $sp SpecialPage instance, providing context
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialContributionsBeforeMainOutput( $id, $user, $sp );
+}
diff --git a/includes/specials/Hook/SpecialContributions__formatRow__flagsHook.php b/includes/specials/Hook/SpecialContributions__formatRow__flagsHook.php
new file mode 100644
index 000000000000..076b455fbd81
--- /dev/null
+++ b/includes/specials/Hook/SpecialContributions__formatRow__flagsHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialContributions__formatRow__flagsHook {
+ /**
+ * Called before rendering a
+ * Special:Contributions row.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $context IContextSource object
+ * @param ?mixed $row Revision information from the database
+ * @param ?mixed &$flags List of flags on this row
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialContributions__formatRow__flags( $context, $row,
+ &$flags
+ );
+}
diff --git a/includes/specials/Hook/SpecialContributions__getForm__filtersHook.php b/includes/specials/Hook/SpecialContributions__getForm__filtersHook.php
new file mode 100644
index 000000000000..493a4315c74a
--- /dev/null
+++ b/includes/specials/Hook/SpecialContributions__getForm__filtersHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialContributions__getForm__filtersHook {
+ /**
+ * Called with a list of filters to render
+ * on Special:Contributions.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sp SpecialContributions object, for context
+ * @param ?mixed &$filters List of filter object definitions (compatible with OOUI form)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialContributions__getForm__filters( $sp, &$filters );
+}
diff --git a/includes/specials/Hook/SpecialListusersDefaultQueryHook.php b/includes/specials/Hook/SpecialListusersDefaultQueryHook.php
new file mode 100644
index 000000000000..58d59b9e923b
--- /dev/null
+++ b/includes/specials/Hook/SpecialListusersDefaultQueryHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialListusersDefaultQueryHook {
+ /**
+ * Called right before the end of
+ * UsersPager::getDefaultQuery().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $pager The UsersPager instance
+ * @param ?mixed &$query The query array to be returned
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialListusersDefaultQuery( $pager, &$query );
+}
diff --git a/includes/specials/Hook/SpecialListusersFormatRowHook.php b/includes/specials/Hook/SpecialListusersFormatRowHook.php
new file mode 100644
index 000000000000..fe885ef36edd
--- /dev/null
+++ b/includes/specials/Hook/SpecialListusersFormatRowHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialListusersFormatRowHook {
+ /**
+ * Called right before the end of
+ * UsersPager::formatRow().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$item HTML to be returned. Will be wrapped in an <li> after the hook finishes
+ * @param ?mixed $row Database row object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialListusersFormatRow( &$item, $row );
+}
diff --git a/includes/specials/Hook/SpecialListusersHeaderFormHook.php b/includes/specials/Hook/SpecialListusersHeaderFormHook.php
new file mode 100644
index 000000000000..2d99acd2eb81
--- /dev/null
+++ b/includes/specials/Hook/SpecialListusersHeaderFormHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialListusersHeaderFormHook {
+ /**
+ * Called before adding the submit button in
+ * UsersPager::getPageHeader().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $pager The UsersPager instance
+ * @param ?mixed &$out The header HTML
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialListusersHeaderForm( $pager, &$out );
+}
diff --git a/includes/specials/Hook/SpecialListusersHeaderHook.php b/includes/specials/Hook/SpecialListusersHeaderHook.php
new file mode 100644
index 000000000000..14c88325046f
--- /dev/null
+++ b/includes/specials/Hook/SpecialListusersHeaderHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialListusersHeaderHook {
+ /**
+ * Called after adding the submit button in
+ * UsersPager::getPageHeader().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $pager The UsersPager instance
+ * @param ?mixed &$out The header HTML
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialListusersHeader( $pager, &$out );
+}
diff --git a/includes/specials/Hook/SpecialListusersQueryInfoHook.php b/includes/specials/Hook/SpecialListusersQueryInfoHook.php
new file mode 100644
index 000000000000..2c8c42b5bec7
--- /dev/null
+++ b/includes/specials/Hook/SpecialListusersQueryInfoHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialListusersQueryInfoHook {
+ /**
+ * Called right before the end of.
+ * UsersPager::getQueryInfo()
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $pager The UsersPager instance
+ * @param ?mixed &$query The query array to be returned
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialListusersQueryInfo( $pager, &$query );
+}
diff --git a/includes/specials/Hook/SpecialLogAddLogSearchRelationsHook.php b/includes/specials/Hook/SpecialLogAddLogSearchRelationsHook.php
new file mode 100644
index 000000000000..fe24e5e4b8a7
--- /dev/null
+++ b/includes/specials/Hook/SpecialLogAddLogSearchRelationsHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialLogAddLogSearchRelationsHook {
+ /**
+ * Add log relations to the current log
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $type String of the log type
+ * @param ?mixed $request WebRequest object for getting the value provided by the current user
+ * @param ?mixed &$qc Array for query conditions to add
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialLogAddLogSearchRelations( $type, $request, &$qc );
+}
diff --git a/includes/specials/Hook/SpecialMovepageAfterMoveHook.php b/includes/specials/Hook/SpecialMovepageAfterMoveHook.php
new file mode 100644
index 000000000000..1c1644b5f1d0
--- /dev/null
+++ b/includes/specials/Hook/SpecialMovepageAfterMoveHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialMovepageAfterMoveHook {
+ /**
+ * Called after moving a page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $movePage MovePageForm object
+ * @param ?mixed $oldTitle old title (object)
+ * @param ?mixed $newTitle new title (object)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialMovepageAfterMove( $movePage, $oldTitle, $newTitle );
+}
diff --git a/includes/specials/Hook/SpecialMuteModifyFormFieldsHook.php b/includes/specials/Hook/SpecialMuteModifyFormFieldsHook.php
new file mode 100644
index 000000000000..75ecc5bece5c
--- /dev/null
+++ b/includes/specials/Hook/SpecialMuteModifyFormFieldsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialMuteModifyFormFieldsHook {
+ /**
+ * Add more fields to Special:Mute
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $sp SpecialPage object, for context
+ * @param ?mixed &$fields Current HTMLForm fields descriptors
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialMuteModifyFormFields( $sp, &$fields );
+}
diff --git a/includes/specials/Hook/SpecialMuteSubmitHook.php b/includes/specials/Hook/SpecialMuteSubmitHook.php
new file mode 100644
index 000000000000..10e52a20dab1
--- /dev/null
+++ b/includes/specials/Hook/SpecialMuteSubmitHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialMuteSubmitHook {
+ /**
+ * DEPRECATED since 1.34! Used only for instrumentation on SpecialMute
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $data Array containing information about submitted options on SpecialMute form
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialMuteSubmit( $data );
+}
diff --git a/includes/specials/Hook/SpecialNewPagesFiltersHook.php b/includes/specials/Hook/SpecialNewPagesFiltersHook.php
new file mode 100644
index 000000000000..20a1aa3fcd0f
--- /dev/null
+++ b/includes/specials/Hook/SpecialNewPagesFiltersHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialNewPagesFiltersHook {
+ /**
+ * Called after building form options at NewPages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $special the special page object
+ * @param ?mixed &$filters associative array of filter definitions. The keys are the HTML
+ * name/URL parameters. Each key maps to an associative array with a 'msg'
+ * (message key) and a 'default' value.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialNewPagesFilters( $special, &$filters );
+}
diff --git a/includes/specials/Hook/SpecialNewpagesConditionsHook.php b/includes/specials/Hook/SpecialNewpagesConditionsHook.php
new file mode 100644
index 000000000000..1f172dd5b652
--- /dev/null
+++ b/includes/specials/Hook/SpecialNewpagesConditionsHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialNewpagesConditionsHook {
+ /**
+ * Called when building sql query for
+ * Special:NewPages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $special NewPagesPager object (subclass of ReverseChronologicalPager)
+ * @param ?mixed $opts FormOptions object containing special page options
+ * @param ?mixed &$conds array of WHERE conditionals for query
+ * @param ?mixed &$tables array of tables to be queried
+ * @param ?mixed &$fields array of columns to select
+ * @param ?mixed &$join_conds join conditions for the tables
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialNewpagesConditions( $special, $opts, &$conds,
+ &$tables, &$fields, &$join_conds
+ );
+}
diff --git a/includes/specials/Hook/SpecialRandomGetRandomTitleHook.php b/includes/specials/Hook/SpecialRandomGetRandomTitleHook.php
new file mode 100644
index 000000000000..960fcbf06d46
--- /dev/null
+++ b/includes/specials/Hook/SpecialRandomGetRandomTitleHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialRandomGetRandomTitleHook {
+ /**
+ * Called during the execution of Special:Random,
+ * use this to change some selection criteria or substitute a different title.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$randstr The random number from wfRandom()
+ * @param ?mixed &$isRedir Boolean, whether to select a redirect or non-redirect
+ * @param ?mixed &$namespaces An array of namespace indexes to get the title from
+ * @param ?mixed &$extra An array of extra SQL statements
+ * @param ?mixed &$title If the hook returns false, a Title object to use instead of the
+ * result from the normal query
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialRandomGetRandomTitle( &$randstr, &$isRedir,
+ &$namespaces, &$extra, &$title
+ );
+}
diff --git a/includes/specials/Hook/SpecialRecentChangesPanelHook.php b/includes/specials/Hook/SpecialRecentChangesPanelHook.php
new file mode 100644
index 000000000000..7d3ccd026754
--- /dev/null
+++ b/includes/specials/Hook/SpecialRecentChangesPanelHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialRecentChangesPanelHook {
+ /**
+ * Called when building form options in
+ * SpecialRecentChanges.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$extraOpts array of added items, to which can be added
+ * @param ?mixed $opts FormOptions for this request
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialRecentChangesPanel( &$extraOpts, $opts );
+}
diff --git a/includes/specials/Hook/SpecialResetTokensTokensHook.php b/includes/specials/Hook/SpecialResetTokensTokensHook.php
new file mode 100644
index 000000000000..46b6d1e4c877
--- /dev/null
+++ b/includes/specials/Hook/SpecialResetTokensTokensHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialResetTokensTokensHook {
+ /**
+ * Called when building token list for
+ * SpecialResetTokens.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tokens array of token information arrays in the format of
+ * [
+ * 'preference' => '<preference-name>',
+ * 'label-message' => '<message-key>',
+ * ]
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialResetTokensTokens( &$tokens );
+}
diff --git a/includes/specials/Hook/SpecialSearchCreateLinkHook.php b/includes/specials/Hook/SpecialSearchCreateLinkHook.php
new file mode 100644
index 000000000000..543de2e6e72a
--- /dev/null
+++ b/includes/specials/Hook/SpecialSearchCreateLinkHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialSearchCreateLinkHook {
+ /**
+ * Called when making the message to create a page or
+ * go to the existing page.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $t title object searched for
+ * @param ?mixed &$params an array of the default message name and page title (as parameter)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialSearchCreateLink( $t, &$params );
+}
diff --git a/includes/specials/Hook/SpecialSearchGoResultHook.php b/includes/specials/Hook/SpecialSearchGoResultHook.php
new file mode 100644
index 000000000000..9739bf4b54cb
--- /dev/null
+++ b/includes/specials/Hook/SpecialSearchGoResultHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialSearchGoResultHook {
+ /**
+ * If a hook returns false the 'go' feature will be
+ * canceled and a normal search will be performed. Returning true without setting
+ * $url does a standard redirect to $title. Setting $url redirects to the
+ * specified URL.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $term The string the user searched for
+ * @param ?mixed $title The title the 'go' feature has decided to forward the user to
+ * @param ?mixed &$url Initially null, hook subscribers can set this to specify the final url to
+ * redirect to
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialSearchGoResult( $term, $title, &$url );
+}
diff --git a/includes/specials/Hook/SpecialSearchNogomatchHook.php b/includes/specials/Hook/SpecialSearchNogomatchHook.php
new file mode 100644
index 000000000000..3d024690c609
--- /dev/null
+++ b/includes/specials/Hook/SpecialSearchNogomatchHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialSearchNogomatchHook {
+ /**
+ * Called when the 'Go' feature is triggered (generally
+ * from autocomplete search other than the main bar on Special:Search) and the
+ * target doesn't exist. Full text search results are generated after this hook is
+ * called.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$title title object generated from the text entered by the user
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialSearchNogomatch( &$title );
+}
diff --git a/includes/specials/Hook/SpecialSearchProfilesHook.php b/includes/specials/Hook/SpecialSearchProfilesHook.php
new file mode 100644
index 000000000000..d0bc544a7289
--- /dev/null
+++ b/includes/specials/Hook/SpecialSearchProfilesHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialSearchProfilesHook {
+ /**
+ * Allows modification of search profiles.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$profiles profiles, which can be modified.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialSearchProfiles( &$profiles );
+}
diff --git a/includes/specials/Hook/SpecialSearchResultsAppendHook.php b/includes/specials/Hook/SpecialSearchResultsAppendHook.php
new file mode 100644
index 000000000000..09669a2d0cd6
--- /dev/null
+++ b/includes/specials/Hook/SpecialSearchResultsAppendHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialSearchResultsAppendHook {
+ /**
+ * Called immediately before returning HTML
+ * on the search results page. Useful for including a feedback link.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $specialSearch SpecialSearch object ($this)
+ * @param ?mixed $output $wgOut
+ * @param ?mixed $term Search term specified by the user
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialSearchResultsAppend( $specialSearch, $output, $term );
+}
diff --git a/includes/specials/Hook/SpecialSearchResultsHook.php b/includes/specials/Hook/SpecialSearchResultsHook.php
new file mode 100644
index 000000000000..9e1a22d5372a
--- /dev/null
+++ b/includes/specials/Hook/SpecialSearchResultsHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialSearchResultsHook {
+ /**
+ * Called before search result display
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $term string of search term
+ * @param ?mixed &$titleMatches empty or ISearchResultSet object
+ * @param ?mixed &$textMatches empty or ISearchResultSet object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialSearchResults( $term, &$titleMatches, &$textMatches );
+}
diff --git a/includes/specials/Hook/SpecialSearchResultsPrependHook.php b/includes/specials/Hook/SpecialSearchResultsPrependHook.php
new file mode 100644
index 000000000000..7cd8b347ba63
--- /dev/null
+++ b/includes/specials/Hook/SpecialSearchResultsPrependHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialSearchResultsPrependHook {
+ /**
+ * Called immediately before returning HTML
+ * on the search results page. Useful for including an external search
+ * provider. To disable the output of MediaWiki search output, return
+ * false.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $specialSearch SpecialSearch object ($this)
+ * @param ?mixed $output $wgOut
+ * @param ?mixed $term Search term specified by the user
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialSearchResultsPrepend( $specialSearch, $output, $term );
+}
diff --git a/includes/specials/Hook/SpecialSearchSetupEngineHook.php b/includes/specials/Hook/SpecialSearchSetupEngineHook.php
new file mode 100644
index 000000000000..5f8ccd05cfd2
--- /dev/null
+++ b/includes/specials/Hook/SpecialSearchSetupEngineHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialSearchSetupEngineHook {
+ /**
+ * Allows passing custom data to search engine.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $search SpecialSearch special page object
+ * @param ?mixed $profile String: current search profile
+ * @param ?mixed $engine the search engine
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialSearchSetupEngine( $search, $profile, $engine );
+}
diff --git a/includes/specials/Hook/SpecialStatsAddExtraHook.php b/includes/specials/Hook/SpecialStatsAddExtraHook.php
new file mode 100644
index 000000000000..337a7514d724
--- /dev/null
+++ b/includes/specials/Hook/SpecialStatsAddExtraHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialStatsAddExtraHook {
+ /**
+ * Add extra statistic at the end of Special:Statistics.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$extraStats Array to save the new stats
+ * $extraStats['<name of statistic>'] => <value>;
+ * <value> can be an array with the keys "name" and "number":
+ * "name" is the HTML to be displayed in the name column
+ * "number" is the number to be displayed.
+ * or, <value> can be the number to be displayed and <name> is the
+ * message key to use in the name column,
+ * @param ?mixed $context IContextSource object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialStatsAddExtra( &$extraStats, $context );
+}
diff --git a/includes/specials/Hook/SpecialTrackingCategories__generateCatLinkHook.php b/includes/specials/Hook/SpecialTrackingCategories__generateCatLinkHook.php
new file mode 100644
index 000000000000..dfc3cabc3989
--- /dev/null
+++ b/includes/specials/Hook/SpecialTrackingCategories__generateCatLinkHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialTrackingCategories__generateCatLinkHook {
+ /**
+ * Called for each cat link on
+ * Special:TrackingCategories
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $specialPage The SpecialTrackingCategories object
+ * @param ?mixed $catTitle The Title object of the linked category
+ * @param ?mixed &$html The Result html
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialTrackingCategories__generateCatLink( $specialPage,
+ $catTitle, &$html
+ );
+}
diff --git a/includes/specials/Hook/SpecialTrackingCategories__preprocessHook.php b/includes/specials/Hook/SpecialTrackingCategories__preprocessHook.php
new file mode 100644
index 000000000000..95a51d66c912
--- /dev/null
+++ b/includes/specials/Hook/SpecialTrackingCategories__preprocessHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialTrackingCategories__preprocessHook {
+ /**
+ * Called after LinkBatch on
+ * Special:TrackingCategories
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $specialPage The SpecialTrackingCategories object
+ * @param ?mixed $trackingCategories Array of data from Special:TrackingCategories with msg and
+ * cats
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialTrackingCategories__preprocess( $specialPage,
+ $trackingCategories
+ );
+}
diff --git a/includes/specials/Hook/SpecialUploadCompleteHook.php b/includes/specials/Hook/SpecialUploadCompleteHook.php
new file mode 100644
index 000000000000..0d118806465d
--- /dev/null
+++ b/includes/specials/Hook/SpecialUploadCompleteHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialUploadCompleteHook {
+ /**
+ * Called after successfully uploading a file from
+ * Special:Upload.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $form The SpecialUpload object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialUploadComplete( $form );
+}
diff --git a/includes/specials/Hook/SpecialVersionVersionUrlHook.php b/includes/specials/Hook/SpecialVersionVersionUrlHook.php
new file mode 100644
index 000000000000..eb48dfc1aee9
--- /dev/null
+++ b/includes/specials/Hook/SpecialVersionVersionUrlHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialVersionVersionUrlHook {
+ /**
+ * Called when building the URL for Special:Version.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $version Current MediaWiki version
+ * @param ?mixed &$versionUrl Raw url to link to (eg: release notes)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialVersionVersionUrl( $version, &$versionUrl );
+}
diff --git a/includes/specials/Hook/SpecialWatchlistGetNonRevisionTypesHook.php b/includes/specials/Hook/SpecialWatchlistGetNonRevisionTypesHook.php
new file mode 100644
index 000000000000..b88952cbb837
--- /dev/null
+++ b/includes/specials/Hook/SpecialWatchlistGetNonRevisionTypesHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialWatchlistGetNonRevisionTypesHook {
+ /**
+ * Called when building sql query for
+ * SpecialWatchlist. Allows extensions to register custom values they have
+ * inserted to rc_type so they can be returned as part of the watchlist.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$nonRevisionTypes array of values in the rc_type field of recentchanges table
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialWatchlistGetNonRevisionTypes( &$nonRevisionTypes );
+}
diff --git a/includes/specials/Hook/UnblockUserCompleteHook.php b/includes/specials/Hook/UnblockUserCompleteHook.php
new file mode 100644
index 000000000000..f09a5256dbca
--- /dev/null
+++ b/includes/specials/Hook/UnblockUserCompleteHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UnblockUserCompleteHook {
+ /**
+ * After an IP address or user has been unblocked.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $block The Block object that was saved
+ * @param ?mixed $user The user who performed the unblock (not the one being unblocked)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUnblockUserComplete( $block, $user );
+}
diff --git a/includes/specials/Hook/UnblockUserHook.php b/includes/specials/Hook/UnblockUserHook.php
new file mode 100644
index 000000000000..4670a59fbf7a
--- /dev/null
+++ b/includes/specials/Hook/UnblockUserHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UnblockUserHook {
+ /**
+ * Before an IP address or user is unblocked.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $block The Block object about to be saved
+ * @param ?mixed $user The user performing the unblock (not the one being unblocked)
+ * @param ?mixed &$reason If the hook is aborted, the error message to be returned in an array
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUnblockUser( $block, $user, &$reason );
+}
diff --git a/includes/specials/Hook/UndeleteForm__showHistoryHook.php b/includes/specials/Hook/UndeleteForm__showHistoryHook.php
new file mode 100644
index 000000000000..a85e033e68dd
--- /dev/null
+++ b/includes/specials/Hook/UndeleteForm__showHistoryHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UndeleteForm__showHistoryHook {
+ /**
+ * Called in UndeleteForm::showHistory, after a
+ * PageArchive object has been created but before any further processing is done.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$archive PageArchive object
+ * @param ?mixed $title Title object of the page that we're viewing
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUndeleteForm__showHistory( &$archive, $title );
+}
diff --git a/includes/specials/Hook/UndeleteForm__showRevisionHook.php b/includes/specials/Hook/UndeleteForm__showRevisionHook.php
new file mode 100644
index 000000000000..fce2f9db6a05
--- /dev/null
+++ b/includes/specials/Hook/UndeleteForm__showRevisionHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UndeleteForm__showRevisionHook {
+ /**
+ * Called in UndeleteForm::showRevision, after a
+ * PageArchive object has been created but before any further processing is done.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$archive PageArchive object
+ * @param ?mixed $title Title object of the page that we're viewing
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUndeleteForm__showRevision( &$archive, $title );
+}
diff --git a/includes/specials/Hook/UndeleteForm__undeleteHook.php b/includes/specials/Hook/UndeleteForm__undeleteHook.php
new file mode 100644
index 000000000000..d773537579df
--- /dev/null
+++ b/includes/specials/Hook/UndeleteForm__undeleteHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UndeleteForm__undeleteHook {
+ /**
+ * Called in UndeleteForm::undelete, after checking that
+ * the site is not in read-only mode, that the Title object is not null and after
+ * a PageArchive object has been constructed but before performing any further
+ * processing.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$archive PageArchive object
+ * @param ?mixed $title Title object of the page that we're about to undelete
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUndeleteForm__undelete( &$archive, $title );
+}
diff --git a/includes/specials/Hook/UndeleteShowRevisionHook.php b/includes/specials/Hook/UndeleteShowRevisionHook.php
new file mode 100644
index 000000000000..7334ab8f1190
--- /dev/null
+++ b/includes/specials/Hook/UndeleteShowRevisionHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UndeleteShowRevisionHook {
+ /**
+ * Called when showing a revision in Special:Undelete.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $title title object related to the revision
+ * @param ?mixed $rev revision (object) that will be viewed
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUndeleteShowRevision( $title, $rev );
+}
diff --git a/includes/specials/Hook/UploadFormInitDescriptorHook.php b/includes/specials/Hook/UploadFormInitDescriptorHook.php
new file mode 100644
index 000000000000..a17bdf207240
--- /dev/null
+++ b/includes/specials/Hook/UploadFormInitDescriptorHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UploadFormInitDescriptorHook {
+ /**
+ * After the descriptor for the upload form as been
+ * assembled.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$descriptor (array) the HTMLForm descriptor
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUploadFormInitDescriptor( &$descriptor );
+}
diff --git a/includes/specials/Hook/UploadFormSourceDescriptorsHook.php b/includes/specials/Hook/UploadFormSourceDescriptorsHook.php
new file mode 100644
index 000000000000..d9f9a7ed51a7
--- /dev/null
+++ b/includes/specials/Hook/UploadFormSourceDescriptorsHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UploadFormSourceDescriptorsHook {
+ /**
+ * after the standard source inputs have been
+ * added to the descriptor
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$descriptor (array) the HTMLForm descriptor
+ * @param ?mixed &$radio Boolean, if source type should be shown as radio button
+ * @param ?mixed $selectedSourceType The selected source type
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUploadFormSourceDescriptors( &$descriptor, &$radio,
+ $selectedSourceType
+ );
+}
diff --git a/includes/specials/Hook/UploadForm_BeforeProcessingHook.php b/includes/specials/Hook/UploadForm_BeforeProcessingHook.php
new file mode 100644
index 000000000000..a7fa1b99a18e
--- /dev/null
+++ b/includes/specials/Hook/UploadForm_BeforeProcessingHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UploadForm_BeforeProcessingHook {
+ /**
+ * At the beginning of processUpload(). Lets you
+ * poke at member variables like $mUploadDescription before the file is saved.
+ * Do not use this hook to break upload processing.
+ * This will return the user to a blank form with no error message;
+ * use UploadVerifyUpload or UploadVerifyFile instead.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $upload SpecialUpload object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUploadForm_BeforeProcessing( $upload );
+}
diff --git a/includes/specials/Hook/UploadForm_getInitialPageTextHook.php b/includes/specials/Hook/UploadForm_getInitialPageTextHook.php
new file mode 100644
index 000000000000..49371163d4c2
--- /dev/null
+++ b/includes/specials/Hook/UploadForm_getInitialPageTextHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UploadForm_getInitialPageTextHook {
+ /**
+ * After the initial page text for file uploads
+ * is generated, to allow it to be altered.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$pageText the page text
+ * @param ?mixed $msg array of header messages
+ * @param ?mixed $config Config object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUploadForm_getInitialPageText( &$pageText, $msg, $config );
+}
diff --git a/includes/specials/Hook/UploadForm_initialHook.php b/includes/specials/Hook/UploadForm_initialHook.php
new file mode 100644
index 000000000000..e546979bb585
--- /dev/null
+++ b/includes/specials/Hook/UploadForm_initialHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UploadForm_initialHook {
+ /**
+ * Before the upload form is generated. You might set the
+ * member-variables $uploadFormTextTop and $uploadFormTextAfterSummary to inject
+ * text (HTML) either before or after the editform.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $upload SpecialUpload object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUploadForm_initial( $upload );
+}
diff --git a/includes/specials/Hook/UserLoginCompleteHook.php b/includes/specials/Hook/UserLoginCompleteHook.php
new file mode 100644
index 000000000000..62c5a1e6f51b
--- /dev/null
+++ b/includes/specials/Hook/UserLoginCompleteHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserLoginCompleteHook {
+ /**
+ * Show custom content after a user has logged in via the Web
+ * interface. For functionality that needs to run after any login (API or web) use
+ * UserLoggedIn.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user the user object that was created on login
+ * @param ?mixed &$inject_html Any HTML to inject after the "logged in" message.
+ * @param ?mixed $direct (bool) The hook is called directly after a successful login. This will
+ * only happen once per login. A UserLoginComplete call with direct=false can
+ * happen when the user visits the login page while already logged in.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserLoginComplete( $user, &$inject_html, $direct );
+}
diff --git a/includes/specials/Hook/UserLogoutCompleteHook.php b/includes/specials/Hook/UserLogoutCompleteHook.php
new file mode 100644
index 000000000000..ee808a2bb08b
--- /dev/null
+++ b/includes/specials/Hook/UserLogoutCompleteHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserLogoutCompleteHook {
+ /**
+ * After a user has logged out.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user the user object _after_ logout (won't have name, ID, etc.)
+ * @param ?mixed &$inject_html Any HTML to inject after the "logged out" message.
+ * @param ?mixed $oldName name of the user before logout (string)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserLogoutComplete( $user, &$inject_html, $oldName );
+}
diff --git a/includes/specials/Hook/UsersPagerDoBatchLookupsHook.php b/includes/specials/Hook/UsersPagerDoBatchLookupsHook.php
new file mode 100644
index 000000000000..42585602b208
--- /dev/null
+++ b/includes/specials/Hook/UsersPagerDoBatchLookupsHook.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UsersPagerDoBatchLookupsHook {
+ /**
+ * Called in UsersPager::doBatchLookups() to give
+ * extensions providing user group data from an alternate source a chance to add
+ * their data into the cache array so that things like global user groups are
+ * displayed correctly in Special:ListUsers.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $dbr Read-only database handle
+ * @param ?mixed $userIds Array of user IDs whose groups we should look up
+ * @param ?mixed &$cache Array of user ID -> (array of internal group name (e.g. 'sysop') ->
+ * UserGroupMembership object)
+ * @param ?mixed &$groups Array of group name -> bool true mappings for members of a given user
+ * group
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUsersPagerDoBatchLookups( $dbr, $userIds, &$cache, &$groups );
+}
diff --git a/includes/specials/Hook/WantedPages__getQueryInfoHook.php b/includes/specials/Hook/WantedPages__getQueryInfoHook.php
new file mode 100644
index 000000000000..1ecdb59686e5
--- /dev/null
+++ b/includes/specials/Hook/WantedPages__getQueryInfoHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WantedPages__getQueryInfoHook {
+ /**
+ * Called in WantedPagesPage::getQueryInfo(), can be
+ * used to alter the SQL query which gets the list of wanted pages.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $wantedPages WantedPagesPage object
+ * @param ?mixed &$query query array, see QueryPage::getQueryInfo() for format documentation
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWantedPages__getQueryInfo( $wantedPages, &$query );
+}
diff --git a/includes/specials/Hook/WatchlistEditorBeforeFormRenderHook.php b/includes/specials/Hook/WatchlistEditorBeforeFormRenderHook.php
new file mode 100644
index 000000000000..9409ed9d1856
--- /dev/null
+++ b/includes/specials/Hook/WatchlistEditorBeforeFormRenderHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WatchlistEditorBeforeFormRenderHook {
+ /**
+ * Before building the Special:EditWatchlist
+ * form, used to manipulate the list of pages or preload data based on that list.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$watchlistInfo array of watchlisted pages in
+ * [namespaceId => ['title1' => 1, 'title2' => 1]] format
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWatchlistEditorBeforeFormRender( &$watchlistInfo );
+}
diff --git a/includes/specials/Hook/WatchlistEditorBuildRemoveLineHook.php b/includes/specials/Hook/WatchlistEditorBuildRemoveLineHook.php
new file mode 100644
index 000000000000..451dc2267ba2
--- /dev/null
+++ b/includes/specials/Hook/WatchlistEditorBuildRemoveLineHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WatchlistEditorBuildRemoveLineHook {
+ /**
+ * when building remove lines in
+ * Special:Watchlist/edit.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$tools array of extra links
+ * @param ?mixed $title Title object
+ * @param ?mixed $redirect whether the page is a redirect
+ * @param ?mixed $skin Skin object
+ * @param ?mixed &$link HTML link to title
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWatchlistEditorBuildRemoveLine( &$tools, $title, $redirect,
+ $skin, &$link
+ );
+}
diff --git a/includes/specials/Hook/WhatLinksHerePropsHook.php b/includes/specials/Hook/WhatLinksHerePropsHook.php
new file mode 100644
index 000000000000..9bb7d0bd5afa
--- /dev/null
+++ b/includes/specials/Hook/WhatLinksHerePropsHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WhatLinksHerePropsHook {
+ /**
+ * Allows annotations to be added to WhatLinksHere
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $row The DB row of the entry.
+ * @param ?mixed $title The Title of the page where the link comes FROM
+ * @param ?mixed $target The Title of the page where the link goes TO
+ * @param ?mixed &$props Array of HTML strings to display after the title.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWhatLinksHereProps( $row, $title, $target, &$props );
+}
diff --git a/includes/title/Hook/CanonicalNamespacesHook.php b/includes/title/Hook/CanonicalNamespacesHook.php
new file mode 100644
index 000000000000..6b79b32403f3
--- /dev/null
+++ b/includes/title/Hook/CanonicalNamespacesHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface CanonicalNamespacesHook {
+ /**
+ * For extensions adding their own namespaces or altering
+ * the defaults.
+ * Note that if you need to specify namespace protection or content model for
+ * a namespace that is added in a CanonicalNamespaces hook handler, you
+ * should do so by altering $wgNamespaceProtection and
+ * $wgNamespaceContentModels outside the handler, in top-level scope. The
+ * point at which the CanonicalNamespaces hook fires is too late for altering
+ * these variables. This applies even if the namespace addition is
+ * conditional; it is permissible to declare a content model and protection
+ * for a namespace and then decline to actually register it.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$namespaces Array of namespace numbers with corresponding canonical names
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onCanonicalNamespaces( &$namespaces );
+}
diff --git a/includes/title/Hook/NamespaceIsMovableHook.php b/includes/title/Hook/NamespaceIsMovableHook.php
new file mode 100644
index 000000000000..a0aa526c61fc
--- /dev/null
+++ b/includes/title/Hook/NamespaceIsMovableHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface NamespaceIsMovableHook {
+ /**
+ * Called when determining if it is possible to pages in a
+ * namespace.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $index Integer; the index of the namespace being checked.
+ * @param ?mixed &$result Boolean; whether MediaWiki currently thinks that pages in this
+ * namespace are movable. Hooks may change this value to override the return
+ * value of NamespaceInfo::isMovable().
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onNamespaceIsMovable( $index, &$result );
+}
diff --git a/includes/upload/Hook/IsUploadAllowedFromUrlHook.php b/includes/upload/Hook/IsUploadAllowedFromUrlHook.php
new file mode 100644
index 000000000000..4d303c73ffe0
--- /dev/null
+++ b/includes/upload/Hook/IsUploadAllowedFromUrlHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface IsUploadAllowedFromUrlHook {
+ /**
+ * Override the result of UploadFromUrl::isAllowedUrl()
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $url URL used to upload from
+ * @param ?mixed &$allowed Boolean indicating if uploading is allowed for given URL
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onIsUploadAllowedFromUrl( $url, &$allowed );
+}
diff --git a/includes/upload/Hook/UploadCompleteHook.php b/includes/upload/Hook/UploadCompleteHook.php
new file mode 100644
index 000000000000..82ebe97112e8
--- /dev/null
+++ b/includes/upload/Hook/UploadCompleteHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UploadCompleteHook {
+ /**
+ * Upon completion of a file upload.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $uploadBase UploadBase (or subclass) object. File can be accessed by
+ * $uploadBase->getLocalFile().
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUploadComplete( $uploadBase );
+}
diff --git a/includes/upload/Hook/UploadCreateFromRequestHook.php b/includes/upload/Hook/UploadCreateFromRequestHook.php
new file mode 100644
index 000000000000..099da988e5dd
--- /dev/null
+++ b/includes/upload/Hook/UploadCreateFromRequestHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UploadCreateFromRequestHook {
+ /**
+ * When UploadBase::createFromRequest has been called.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $type (string) the requested upload type
+ * @param ?mixed &$className the class name of the Upload instance to be created
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUploadCreateFromRequest( $type, &$className );
+}
diff --git a/includes/upload/Hook/UploadStashFileHook.php b/includes/upload/Hook/UploadStashFileHook.php
new file mode 100644
index 000000000000..1c6b958ea424
--- /dev/null
+++ b/includes/upload/Hook/UploadStashFileHook.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UploadStashFileHook {
+ /**
+ * Before a file is stashed (uploaded to stash).
+ * Note that code which has not been updated for MediaWiki 1.28 may not call this
+ * hook. If your extension absolutely, positively must prevent some files from
+ * being uploaded, use UploadVerifyFile or UploadVerifyUpload.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $upload (object) An instance of UploadBase, with all info about the upload
+ * @param ?mixed $user (object) An instance of User, the user uploading this file
+ * @param ?mixed $props (array|null) File properties, as returned by
+ * MWFileProps::getPropsFromPath(). Note this is not always guaranteed to be set,
+ * e.g. in test scenarios. Call MWFileProps::getPropsFromPath() yourself in case
+ * you need the information.
+ * @param ?mixed &$error output: If the file stashing should be prevented, set this to the
+ * reason in the form of [ messagename, param1, param2, ... ] or a
+ * MessageSpecifier instance (you might want to use ApiMessage to provide machine
+ * -readable details for the API).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUploadStashFile( $upload, $user, $props, &$error );
+}
diff --git a/includes/upload/Hook/UploadVerifyFileHook.php b/includes/upload/Hook/UploadVerifyFileHook.php
new file mode 100644
index 000000000000..7d65c6e99703
--- /dev/null
+++ b/includes/upload/Hook/UploadVerifyFileHook.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UploadVerifyFileHook {
+ /**
+ * extra file verification, based on MIME type, etc.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $upload (object) an instance of UploadBase, with all info about the upload
+ * @param ?mixed $mime (string) The uploaded file's MIME type, as detected by MediaWiki.
+ * Handlers will typically only apply for specific MIME types.
+ * @param ?mixed &$error (object) output: true if the file is valid. Otherwise, set this to the
+ * reason in the form of [ messagename, param1, param2, ... ] or a
+ * MessageSpecifier instance (you might want to use ApiMessage to provide machine
+ * -readable details for the API).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUploadVerifyFile( $upload, $mime, &$error );
+}
diff --git a/includes/upload/Hook/UploadVerifyUploadHook.php b/includes/upload/Hook/UploadVerifyUploadHook.php
new file mode 100644
index 000000000000..1ac88e5a6d1c
--- /dev/null
+++ b/includes/upload/Hook/UploadVerifyUploadHook.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UploadVerifyUploadHook {
+ /**
+ * Upload verification, based on both file properties like
+ * MIME type (same as UploadVerifyFile) and the information entered by the user
+ * (upload comment, file page contents etc.).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $upload (object) An instance of UploadBase, with all info about the upload
+ * @param ?mixed $user (object) An instance of User, the user uploading this file
+ * @param ?mixed $props (array|null) File properties, as returned by
+ * MWFileProps::getPropsFromPath(). Note this is not always guaranteed to be set,
+ * e.g. in test scenarios. Call MWFileProps::getPropsFromPath() yourself in case
+ * you need the information.
+ * @param ?mixed $comment (string) Upload log comment (also used as edit summary)
+ * @param ?mixed $pageText (string) File description page text (only used for new uploads)
+ * @param ?mixed &$error output: If the file upload should be prevented, set this to the reason
+ * in the form of [ messagename, param1, param2, ... ] or a MessageSpecifier
+ * instance (you might want to use ApiMessage to provide machine-readable details
+ * for the API).
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUploadVerifyUpload( $upload, $user, $props, $comment,
+ $pageText, &$error
+ );
+}
diff --git a/includes/user/Hook/ConfirmEmailCompleteHook.php b/includes/user/Hook/ConfirmEmailCompleteHook.php
new file mode 100644
index 000000000000..ac6d5ce27c11
--- /dev/null
+++ b/includes/user/Hook/ConfirmEmailCompleteHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface ConfirmEmailCompleteHook {
+ /**
+ * Called after a user's email has been confirmed
+ * successfully.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user user (object) whose email is being confirmed
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onConfirmEmailComplete( $user );
+}
diff --git a/includes/user/Hook/EmailConfirmedHook.php b/includes/user/Hook/EmailConfirmedHook.php
new file mode 100644
index 000000000000..10ae4a5f697b
--- /dev/null
+++ b/includes/user/Hook/EmailConfirmedHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface EmailConfirmedHook {
+ /**
+ * When checking that the user's email address is "confirmed".
+ * This runs before the other checks, such as anonymity and the real check; return
+ * true to allow those checks to occur, and false if checking is done.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User being checked
+ * @param ?mixed &$confirmed Whether or not the email address is confirmed
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onEmailConfirmed( $user, &$confirmed );
+}
diff --git a/includes/user/Hook/InvalidateEmailCompleteHook.php b/includes/user/Hook/InvalidateEmailCompleteHook.php
new file mode 100644
index 000000000000..497f977bd865
--- /dev/null
+++ b/includes/user/Hook/InvalidateEmailCompleteHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface InvalidateEmailCompleteHook {
+ /**
+ * Called after a user's email has been invalidated
+ * successfully.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user user (object) whose email is being invalidated
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onInvalidateEmailComplete( $user );
+}
diff --git a/includes/user/Hook/IsValidPasswordHook.php b/includes/user/Hook/IsValidPasswordHook.php
new file mode 100644
index 000000000000..ae65c9317430
--- /dev/null
+++ b/includes/user/Hook/IsValidPasswordHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface IsValidPasswordHook {
+ /**
+ * Override the result of User::isValidPassword()
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $password The password entered by the user
+ * @param ?mixed &$result Set this and return false to override the internal checks
+ * @param ?mixed $user User the password is being validated for
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onIsValidPassword( $password, &$result, $user );
+}
diff --git a/includes/user/Hook/PingLimiterHook.php b/includes/user/Hook/PingLimiterHook.php
new file mode 100644
index 000000000000..5d63f12eef48
--- /dev/null
+++ b/includes/user/Hook/PingLimiterHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface PingLimiterHook {
+ /**
+ * Allows extensions to override the results of User::pingLimiter().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User performing the action
+ * @param ?mixed $action Action being performed
+ * @param ?mixed &$result Whether or not the action should be prevented
+ * Change $result and return false to give a definitive answer, otherwise
+ * the built-in rate limiting checks are used, if enabled.
+ * @param ?mixed $incrBy Amount to increment counter by
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onPingLimiter( $user, $action, &$result, $incrBy );
+}
diff --git a/includes/user/Hook/SpecialPasswordResetOnSubmitHook.php b/includes/user/Hook/SpecialPasswordResetOnSubmitHook.php
new file mode 100644
index 000000000000..f59adbe4230d
--- /dev/null
+++ b/includes/user/Hook/SpecialPasswordResetOnSubmitHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface SpecialPasswordResetOnSubmitHook {
+ /**
+ * When executing a form submission on
+ * Special:PasswordReset.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$users array of User objects.
+ * @param ?mixed $data array of data submitted by the user
+ * @param ?mixed &$error string, error code (message key) used to describe to error (out
+ * parameter). The hook needs to return false when setting this, otherwise it
+ * will have no effect.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onSpecialPasswordResetOnSubmit( &$users, $data, &$error );
+}
diff --git a/includes/user/Hook/UserAddGroupHook.php b/includes/user/Hook/UserAddGroupHook.php
new file mode 100644
index 000000000000..900abcf92ac2
--- /dev/null
+++ b/includes/user/Hook/UserAddGroupHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserAddGroupHook {
+ /**
+ * Called when adding a group or changing a group's expiry; return
+ * false to override stock group addition.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user the user object that is to have a group added
+ * @param ?mixed &$group the group to add; can be modified
+ * @param ?mixed &$expiry the expiry time in TS_MW format, or null if the group is not to
+ * expire; can be modified
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserAddGroup( $user, &$group, &$expiry );
+}
diff --git a/includes/user/Hook/UserArrayFromResultHook.php b/includes/user/Hook/UserArrayFromResultHook.php
new file mode 100644
index 000000000000..f0d0b356faff
--- /dev/null
+++ b/includes/user/Hook/UserArrayFromResultHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserArrayFromResultHook {
+ /**
+ * Called when creating an UserArray object from a database
+ * result.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$userArray set this to an object to override the default object returned
+ * @param ?mixed $res database result used to create the object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserArrayFromResult( &$userArray, $res );
+}
diff --git a/includes/user/Hook/UserCanSendEmailHook.php b/includes/user/Hook/UserCanSendEmailHook.php
new file mode 100644
index 000000000000..daf2c69130cd
--- /dev/null
+++ b/includes/user/Hook/UserCanSendEmailHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserCanSendEmailHook {
+ /**
+ * To override User::canSendEmail() permission check.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User (object) whose permission is being checked
+ * @param ?mixed &$canSend bool set on input, can override on output
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserCanSendEmail( $user, &$canSend );
+}
diff --git a/includes/user/Hook/UserClearNewTalkNotificationHook.php b/includes/user/Hook/UserClearNewTalkNotificationHook.php
new file mode 100644
index 000000000000..7f9ee38c696b
--- /dev/null
+++ b/includes/user/Hook/UserClearNewTalkNotificationHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserClearNewTalkNotificationHook {
+ /**
+ * Called when clearing the "You have new
+ * messages!" message, return false to not delete it.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User (object) that will clear the message
+ * @param ?mixed $oldid ID of the talk page revision being viewed (0 means the most recent one)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserClearNewTalkNotification( $user, $oldid );
+}
diff --git a/includes/user/Hook/UserEffectiveGroupsHook.php b/includes/user/Hook/UserEffectiveGroupsHook.php
new file mode 100644
index 000000000000..f77755b14290
--- /dev/null
+++ b/includes/user/Hook/UserEffectiveGroupsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserEffectiveGroupsHook {
+ /**
+ * Called in User::getEffectiveGroups().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User to get groups for
+ * @param ?mixed &$groups Current effective groups
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserEffectiveGroups( $user, &$groups );
+}
diff --git a/includes/user/Hook/UserGetDefaultOptionsHook.php b/includes/user/Hook/UserGetDefaultOptionsHook.php
new file mode 100644
index 000000000000..d0a71bd37134
--- /dev/null
+++ b/includes/user/Hook/UserGetDefaultOptionsHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserGetDefaultOptionsHook {
+ /**
+ * After fetching the core default, this hook is run right
+ * before returning the options to the caller. Warning: This hook is called for
+ * every call to User::getDefaultOptions(), which means it's potentially called
+ * dozens or hundreds of times. You may want to cache the results of non-trivial
+ * operations in your hook function for this reason.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$defaultOptions Array of preference keys and their default values.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserGetDefaultOptions( &$defaultOptions );
+}
diff --git a/includes/user/Hook/UserGetEmailAuthenticationTimestampHook.php b/includes/user/Hook/UserGetEmailAuthenticationTimestampHook.php
new file mode 100644
index 000000000000..d1a6c49e0277
--- /dev/null
+++ b/includes/user/Hook/UserGetEmailAuthenticationTimestampHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserGetEmailAuthenticationTimestampHook {
+ /**
+ * Called when getting the timestamp of
+ * email authentication.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User object
+ * @param ?mixed &$timestamp timestamp, change this to override local email authentication
+ * timestamp
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserGetEmailAuthenticationTimestamp( $user, &$timestamp );
+}
diff --git a/includes/user/Hook/UserGetEmailHook.php b/includes/user/Hook/UserGetEmailHook.php
new file mode 100644
index 000000000000..0d3205231e51
--- /dev/null
+++ b/includes/user/Hook/UserGetEmailHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserGetEmailHook {
+ /**
+ * Called when getting an user email address.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User object
+ * @param ?mixed &$email email, change this to override local email
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserGetEmail( $user, &$email );
+}
diff --git a/includes/user/Hook/UserGetReservedNamesHook.php b/includes/user/Hook/UserGetReservedNamesHook.php
new file mode 100644
index 000000000000..b71ce8493961
--- /dev/null
+++ b/includes/user/Hook/UserGetReservedNamesHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserGetReservedNamesHook {
+ /**
+ * Allows to modify $wgReservedUsernames at run time.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$reservedUsernames $wgReservedUsernames
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserGetReservedNames( &$reservedUsernames );
+}
diff --git a/includes/user/Hook/UserGroupsChangedHook.php b/includes/user/Hook/UserGroupsChangedHook.php
new file mode 100644
index 000000000000..d388825ec347
--- /dev/null
+++ b/includes/user/Hook/UserGroupsChangedHook.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserGroupsChangedHook {
+ /**
+ * Called after user groups are changed.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User whose groups changed
+ * @param ?mixed $added Groups added
+ * @param ?mixed $removed Groups removed
+ * @param ?mixed $performer User who performed the change, false if via autopromotion
+ * @param ?mixed $reason The reason, if any, given by the user performing the change,
+ * false if via autopromotion.
+ * @param ?mixed $oldUGMs An associative array (group name => UserGroupMembership object) of
+ * the user's group memberships before the change.
+ * @param ?mixed $newUGMs An associative array (group name => UserGroupMembership object) of
+ * the user's current group memberships.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserGroupsChanged( $user, $added, $removed, $performer,
+ $reason, $oldUGMs, $newUGMs
+ );
+}
diff --git a/includes/user/Hook/UserIsBlockedGloballyHook.php b/includes/user/Hook/UserIsBlockedGloballyHook.php
new file mode 100644
index 000000000000..54170eea6557
--- /dev/null
+++ b/includes/user/Hook/UserIsBlockedGloballyHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserIsBlockedGloballyHook {
+ /**
+ * Check if user is blocked on all wikis.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User object
+ * @param ?mixed $ip User's IP address
+ * @param ?mixed &$blocked Whether the user is blocked, to be modified by the hook
+ * @param ?mixed &$block The Block object, to be modified by the hook
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserIsBlockedGlobally( $user, $ip, &$blocked, &$block );
+}
diff --git a/includes/user/Hook/UserIsBotHook.php b/includes/user/Hook/UserIsBotHook.php
new file mode 100644
index 000000000000..9d9d988f08d8
--- /dev/null
+++ b/includes/user/Hook/UserIsBotHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserIsBotHook {
+ /**
+ * when determining whether a user is a bot account
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user the user
+ * @param ?mixed &$isBot whether this is user a bot or not (boolean)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserIsBot( $user, &$isBot );
+}
diff --git a/includes/user/Hook/UserIsLockedHook.php b/includes/user/Hook/UserIsLockedHook.php
new file mode 100644
index 000000000000..479e0d02ba00
--- /dev/null
+++ b/includes/user/Hook/UserIsLockedHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserIsLockedHook {
+ /**
+ * Check if the user is locked. See User::isLocked().
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User in question.
+ * @param ?mixed &$locked Set true if the user should be locked.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserIsLocked( $user, &$locked );
+}
diff --git a/includes/user/Hook/UserLoadAfterLoadFromSessionHook.php b/includes/user/Hook/UserLoadAfterLoadFromSessionHook.php
new file mode 100644
index 000000000000..0c556a222c4e
--- /dev/null
+++ b/includes/user/Hook/UserLoadAfterLoadFromSessionHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserLoadAfterLoadFromSessionHook {
+ /**
+ * Called to authenticate users on external or
+ * environmental means; occurs after session is loaded.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user user object being loaded
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserLoadAfterLoadFromSession( $user );
+}
diff --git a/includes/user/Hook/UserLoadDefaultsHook.php b/includes/user/Hook/UserLoadDefaultsHook.php
new file mode 100644
index 000000000000..53b770e8b845
--- /dev/null
+++ b/includes/user/Hook/UserLoadDefaultsHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserLoadDefaultsHook {
+ /**
+ * Called when loading a default user.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user user object
+ * @param ?mixed $name user name
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserLoadDefaults( $user, $name );
+}
diff --git a/includes/user/Hook/UserLoadFromDatabaseHook.php b/includes/user/Hook/UserLoadFromDatabaseHook.php
new file mode 100644
index 000000000000..a4136e80dc71
--- /dev/null
+++ b/includes/user/Hook/UserLoadFromDatabaseHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserLoadFromDatabaseHook {
+ /**
+ * Called when loading a user from the database.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user user object
+ * @param ?mixed &$s database query object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserLoadFromDatabase( $user, &$s );
+}
diff --git a/includes/user/Hook/UserLoadOptionsHook.php b/includes/user/Hook/UserLoadOptionsHook.php
new file mode 100644
index 000000000000..75c5dcb2ac93
--- /dev/null
+++ b/includes/user/Hook/UserLoadOptionsHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserLoadOptionsHook {
+ /**
+ * When user options/preferences are being loaded from the
+ * database.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User object
+ * @param ?mixed &$options Options, can be modified.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserLoadOptions( $user, &$options );
+}
diff --git a/includes/user/Hook/UserLogoutHook.php b/includes/user/Hook/UserLogoutHook.php
new file mode 100644
index 000000000000..144325519683
--- /dev/null
+++ b/includes/user/Hook/UserLogoutHook.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserLogoutHook {
+ /**
+ * Before a user logs out.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user the user object that is about to be logged out
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserLogout( $user );
+}
diff --git a/includes/user/Hook/UserRemoveGroupHook.php b/includes/user/Hook/UserRemoveGroupHook.php
new file mode 100644
index 000000000000..31c256c2fbd2
--- /dev/null
+++ b/includes/user/Hook/UserRemoveGroupHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserRemoveGroupHook {
+ /**
+ * Called when removing a group; return false to override stock
+ * group removal.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user the user object that is to have a group removed
+ * @param ?mixed &$group the group to be removed, can be modified
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserRemoveGroup( $user, &$group );
+}
diff --git a/includes/user/Hook/UserRequiresHTTPSHook.php b/includes/user/Hook/UserRequiresHTTPSHook.php
new file mode 100644
index 000000000000..bed173dddede
--- /dev/null
+++ b/includes/user/Hook/UserRequiresHTTPSHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserRequiresHTTPSHook {
+ /**
+ * Called to determine whether a user needs
+ * to be switched to HTTPS.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User in question.
+ * @param ?mixed &$https Boolean whether $user should be switched to HTTPS.
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserRequiresHTTPS( $user, &$https );
+}
diff --git a/includes/user/Hook/UserResetAllOptionsHook.php b/includes/user/Hook/UserResetAllOptionsHook.php
new file mode 100644
index 000000000000..0ff92c088efe
--- /dev/null
+++ b/includes/user/Hook/UserResetAllOptionsHook.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserResetAllOptionsHook {
+ /**
+ * Called in User::resetOptions() when user preferences
+ * have been requested to be reset. This hook can be used to exclude certain
+ * options from being reset even when the user has requested all prefs to be reset,
+ * because certain options might be stored in the user_properties database table
+ * despite not being visible and editable via Special:Preferences.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user the User (object) whose preferences are being reset
+ * @param ?mixed &$newOptions array of new (site default) preferences
+ * @param ?mixed $options array of the user's old preferences
+ * @param ?mixed $resetKinds array containing the kinds of preferences to reset
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserResetAllOptions( $user, &$newOptions, $options,
+ $resetKinds
+ );
+}
diff --git a/includes/user/Hook/UserRetrieveNewTalksHook.php b/includes/user/Hook/UserRetrieveNewTalksHook.php
new file mode 100644
index 000000000000..9238208c6300
--- /dev/null
+++ b/includes/user/Hook/UserRetrieveNewTalksHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserRetrieveNewTalksHook {
+ /**
+ * Called when retrieving "You have new messages!"
+ * message(s).
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user user retrieving new talks messages
+ * @param ?mixed &$talks array of new talks page(s)
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserRetrieveNewTalks( $user, &$talks );
+}
diff --git a/includes/user/Hook/UserSaveOptionsHook.php b/includes/user/Hook/UserSaveOptionsHook.php
new file mode 100644
index 000000000000..ccc7dd65fecd
--- /dev/null
+++ b/includes/user/Hook/UserSaveOptionsHook.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserSaveOptionsHook {
+ /**
+ * Called just before saving user preferences. Hook handlers can
+ * either add or manipulate options, or reset one back to it's default to block
+ * changing it. Hook handlers are also allowed to abort the process by returning
+ * false, e.g. to save to a global profile instead. Compare to the UserSaveSettings
+ * hook, which is called after the preferences have been saved.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user The User for which the options are going to be saved
+ * @param ?mixed &$options The users options as an associative array, modifiable
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserSaveOptions( $user, &$options );
+}
diff --git a/includes/user/Hook/UserSaveSettingsHook.php b/includes/user/Hook/UserSaveSettingsHook.php
new file mode 100644
index 000000000000..387815213510
--- /dev/null
+++ b/includes/user/Hook/UserSaveSettingsHook.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserSaveSettingsHook {
+ /**
+ * Called directly after user preferences (user_properties in
+ * the database) have been saved. Compare to the UserSaveOptions hook, which is
+ * called before.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user The User for which the options have been saved
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserSaveSettings( $user );
+}
diff --git a/includes/user/Hook/UserSendConfirmationMailHook.php b/includes/user/Hook/UserSendConfirmationMailHook.php
new file mode 100644
index 000000000000..c04b10d05173
--- /dev/null
+++ b/includes/user/Hook/UserSendConfirmationMailHook.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserSendConfirmationMailHook {
+ /**
+ * Called just before a confirmation email is sent to
+ * a user. Hook handlers can modify the email that will be sent.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user The User for which the confirmation email is going to be sent
+ * @param ?mixed &$mail Associative array describing the email, with the following keys:
+ * - subject: Subject line of the email
+ * - body: Email body. Can be a string, or an array with keys 'text' and 'html'
+ * - from: User object, or null meaning $wgPasswordSender will be used
+ * - replyTo: MailAddress object or null
+ * @param ?mixed $info Associative array with additional information:
+ * - type: 'created' if the user's account was just created; 'set' if the user
+ * set an email address when they previously didn't have one; 'changed' if
+ * the user had an email address and changed it
+ * - ip: The IP address from which the user set/changed their email address
+ * - confirmURL: URL the user should visit to confirm their email
+ * - invalidateURL: URL the user should visit to invalidate confirmURL
+ * - expiration: time and date when confirmURL expires
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserSendConfirmationMail( $user, &$mail, $info );
+}
diff --git a/includes/user/Hook/UserSetEmailAuthenticationTimestampHook.php b/includes/user/Hook/UserSetEmailAuthenticationTimestampHook.php
new file mode 100644
index 000000000000..d455aee28e12
--- /dev/null
+++ b/includes/user/Hook/UserSetEmailAuthenticationTimestampHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserSetEmailAuthenticationTimestampHook {
+ /**
+ * Called when setting the timestamp of
+ * email authentication.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User object
+ * @param ?mixed &$timestamp new timestamp, change this to override local email
+ * authentication timestamp
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserSetEmailAuthenticationTimestamp( $user, &$timestamp );
+}
diff --git a/includes/user/Hook/UserSetEmailHook.php b/includes/user/Hook/UserSetEmailHook.php
new file mode 100644
index 000000000000..df29d021fb13
--- /dev/null
+++ b/includes/user/Hook/UserSetEmailHook.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface UserSetEmailHook {
+ /**
+ * Called when changing user email address.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user User object
+ * @param ?mixed &$email new email, change this to override new email address
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUserSetEmail( $user, &$email );
+}
diff --git a/includes/user/Hook/User__mailPasswordInternalHook.php b/includes/user/Hook/User__mailPasswordInternalHook.php
new file mode 100644
index 000000000000..fc49bd7592f0
--- /dev/null
+++ b/includes/user/Hook/User__mailPasswordInternalHook.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace MediaWiki\User\Hook;
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface User__mailPasswordInternalHook {
+ /**
+ * before creation and mailing of a user's new
+ * temporary password
+ *
+ * @since 1.35
+ *
+ * @param ?mixed $user the user who sent the message out
+ * @param ?mixed $ip IP of the user who sent the message out
+ * @param ?mixed $u the account whose new password will be set
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onUser__mailPasswordInternal( $user, $ip, $u );
+}
diff --git a/includes/watcheditem/Hook/BeforeResetNotificationTimestampHook.php b/includes/watcheditem/Hook/BeforeResetNotificationTimestampHook.php
new file mode 100644
index 000000000000..e1f63a7191ac
--- /dev/null
+++ b/includes/watcheditem/Hook/BeforeResetNotificationTimestampHook.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface BeforeResetNotificationTimestampHook {
+ /**
+ * Before the notification timestamp of a
+ * watched item is reset.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$userObj User object
+ * @param ?mixed &$titleObj Title object
+ * @param ?mixed $force If this is the string "force", then the reset will be done even if the
+ * page is not watched.
+ * @param ?mixed &$oldid The revision ID
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onBeforeResetNotificationTimestamp( &$userObj, &$titleObj,
+ $force, &$oldid
+ );
+}
diff --git a/includes/watcheditem/Hook/WatchedItemQueryServiceExtensionsHook.php b/includes/watcheditem/Hook/WatchedItemQueryServiceExtensionsHook.php
new file mode 100644
index 000000000000..acd6bfce6fe9
--- /dev/null
+++ b/includes/watcheditem/Hook/WatchedItemQueryServiceExtensionsHook.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace MediaWiki\Hook;
+
+/**
+ * @stable for implementation
+ * @ingroup Hooks
+ */
+interface WatchedItemQueryServiceExtensionsHook {
+ /**
+ * Create a WatchedItemQueryServiceExtension.
+ *
+ * @since 1.35
+ *
+ * @param ?mixed &$extensions Add WatchedItemQueryServiceExtension objects to this array
+ * @param ?mixed $watchedItemQueryService Service object
+ * @return bool|void True or no return value to continue or false to abort
+ */
+ public function onWatchedItemQueryServiceExtensions( &$extensions,
+ $watchedItemQueryService
+ );
+}