Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new HookContainer/HookRunner system. General principles: * Use DI if it is already used. We're not changing the way state is managed in this patch. * HookContainer is always injected, not HookRunner. HookContainer is a service, it's a more generic interface, it is the only thing that provides isRegistered() which is needed in some cases, and a HookRunner can be efficiently constructed from it (confirmed by benchmark). Because HookContainer is needed for object construction, it is also needed by all factories. * "Ask your friendly local base class". Big hierarchies like SpecialPage and ApiBase have getHookContainer() and getHookRunner() methods in the base class, and classes that extend that base class are not expected to know or care where the base class gets its HookContainer from. * ProtectedHookAccessorTrait provides protected getHookContainer() and getHookRunner() methods, getting them from the global service container. The point of this is to ease migration to DI by ensuring that call sites ask their local friendly base class rather than getting a HookRunner from the service container directly. * Private $this->hookRunner. In some smaller classes where accessor methods did not seem warranted, there is a private HookRunner property which is accessed directly. Very rarely (two cases), there is a protected property, for consistency with code that conventionally assumes protected=private, but in cases where the class might actually be overridden, a protected accessor is preferred over a protected property. * The last resort: Hooks::runner(). Mostly for static, file-scope and global code. In a few cases it was used for objects with broken construction schemes, out of horror or laziness. Constructors with new required arguments: * AuthManager * BadFileLookup * BlockManager * ClassicInterwikiLookup * ContentHandlerFactory * ContentSecurityPolicy * DefaultOptionsManager * DerivedPageDataUpdater * FullSearchResultWidget * HtmlCacheUpdater * LanguageFactory * LanguageNameUtils * LinkRenderer * LinkRendererFactory * LocalisationCache * MagicWordFactory * MessageCache * NamespaceInfo * PageEditStash * PageHandlerFactory * PageUpdater * ParserFactory * PermissionManager * RevisionStore * RevisionStoreFactory * SearchEngineConfig * SearchEngineFactory * SearchFormWidget * SearchNearMatcher * SessionBackend * SpecialPageFactory * UserNameUtils * UserOptionsManager * WatchedItemQueryService * WatchedItemStore Constructors with new optional arguments: * DefaultPreferencesFactory * Language * LinkHolderArray * MovePage * Parser * ParserCache * PasswordReset * Router setHookContainer() now required after construction: * AuthenticationProvider * ResourceLoaderModule * SearchEngine Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
This commit is contained in:
parent
2530009b8c
commit
68c433bd23
293 changed files with 2485 additions and 1420 deletions
|
|
@ -601,6 +601,49 @@ because of Phabricator reports.
|
|||
instead.
|
||||
* SpecialVersion::getExtensionCredits() and SpecialVersion::getSkinCredits()
|
||||
have become private without deprecation.
|
||||
* As part of the migration to a new hook system (T240307), the following classes
|
||||
now require an additional HookContainer constructor parameter:
|
||||
- AuthManager
|
||||
- BadFileLookup
|
||||
- BlockManager
|
||||
- ClassicInterwikiLookup
|
||||
- ContentHandlerFactory
|
||||
- ContentSecurityPolicy
|
||||
- DefaultOptionsManager
|
||||
- DerivedPageDataUpdater
|
||||
- FullSearchResultWidget
|
||||
- HtmlCacheUpdater
|
||||
- LanguageFactory
|
||||
- LanguageNameUtils
|
||||
- LinkRenderer
|
||||
- LinkRendererFactory
|
||||
- LocalisationCache
|
||||
- MagicWordFactory
|
||||
- MessageCache
|
||||
- NamespaceInfo
|
||||
- PageEditStash
|
||||
- PageHandlerFactory
|
||||
- PageUpdater
|
||||
- ParserFactory
|
||||
- PermissionManager
|
||||
- RevisionStore
|
||||
- RevisionStoreFactory
|
||||
- Router
|
||||
- SearchEngineConfig
|
||||
- SearchEngineFactory
|
||||
- SearchFormWidget
|
||||
- SearchNearMatcher
|
||||
- SessionBackend
|
||||
- SpecialPageFactory
|
||||
- UserNameUtils
|
||||
- UserOptionsManager
|
||||
- WatchedItemQueryService
|
||||
- WatchedItemStore
|
||||
* The following classes now require setHookContainer() to be called after
|
||||
construction:
|
||||
- AuthenticationProvider
|
||||
- ResourceLoaderModule
|
||||
- SearchEngine
|
||||
* …
|
||||
|
||||
=== Deprecations in 1.35 ===
|
||||
|
|
|
|||
2
api.php
2
api.php
|
|
@ -69,7 +69,7 @@ try {
|
|||
$processor = new ApiMain( RequestContext::getMain(), true );
|
||||
|
||||
// Last chance hook before executing the API
|
||||
Hooks::run( 'ApiBeforeMain', [ &$processor ] );
|
||||
Hooks::runner()->onApiBeforeMain( $processor );
|
||||
if ( !$processor instanceof ApiMain ) {
|
||||
throw new MWException( 'ApiBeforeMain hook set $processor to a non-ApiMain class' );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ function wfImageAuthMain() {
|
|||
// Run hook for extension authorization plugins
|
||||
/** @var array $result */
|
||||
$result = null;
|
||||
if ( !Hooks::run( 'ImgAuthBeforeStream', [ &$title, &$path, &$name, &$result ] ) ) {
|
||||
if ( !Hooks::runner()->onImgAuthBeforeStream( $title, $path, $name, $result ) ) {
|
||||
wfForbidden( $result[0], $result[1], array_slice( $result, 2 ) );
|
||||
return;
|
||||
}
|
||||
|
|
@ -183,7 +183,7 @@ function wfImageAuthMain() {
|
|||
}
|
||||
|
||||
// Allow modification of headers before streaming a file
|
||||
Hooks::run( 'ImgAuthModifyHeaders', [ $title->getTitleValue(), &$headers ] );
|
||||
Hooks::runner()->onImgAuthModifyHeaders( $title->getTitleValue(), $headers );
|
||||
|
||||
// Stream the requested file
|
||||
list( $headers, $options ) = HTTPFileStreamer::preprocessHeaders( $headers );
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class Autopromote {
|
|||
}
|
||||
}
|
||||
|
||||
Hooks::run( 'GetAutoPromoteGroups', [ $user, &$promote ] );
|
||||
Hooks::runner()->onGetAutoPromoteGroups( $user, $promote );
|
||||
|
||||
return $promote;
|
||||
}
|
||||
|
|
@ -208,8 +208,8 @@ class Autopromote {
|
|||
->getGroupPermissions( $user->getGroups() ) );
|
||||
default:
|
||||
$result = null;
|
||||
Hooks::run( 'AutopromoteCondition', [ $cond[0],
|
||||
array_slice( $cond, 1 ), $user, &$result ] );
|
||||
Hooks::runner()->onAutopromoteCondition( $cond[0],
|
||||
array_slice( $cond, 1 ), $user, $result );
|
||||
if ( $result === null ) {
|
||||
throw new MWException( "Unrecognized condition {$cond[0]} for autopromotion!" );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@
|
|||
namespace MediaWiki;
|
||||
|
||||
use BagOStuff;
|
||||
use Hooks;
|
||||
use MalformedTitleException;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Linker\LinkTarget;
|
||||
use RepoGroup;
|
||||
use TitleParser;
|
||||
|
|
@ -25,6 +26,9 @@ class BadFileLookup {
|
|||
/** @var array|null Parsed blacklist */
|
||||
private $badFiles;
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/**
|
||||
* Do not call directly. Use MediaWikiServices.
|
||||
*
|
||||
|
|
@ -32,17 +36,20 @@ class BadFileLookup {
|
|||
* @param BagOStuff $cache For caching parsed versions of the blacklist
|
||||
* @param RepoGroup $repoGroup
|
||||
* @param TitleParser $titleParser
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
public function __construct(
|
||||
callable $blacklistCallback,
|
||||
BagOStuff $cache,
|
||||
RepoGroup $repoGroup,
|
||||
TitleParser $titleParser
|
||||
TitleParser $titleParser,
|
||||
HookContainer $hookContainer
|
||||
) {
|
||||
$this->blacklistCallback = $blacklistCallback;
|
||||
$this->cache = $cache;
|
||||
$this->repoGroup = $repoGroup;
|
||||
$this->titleParser = $titleParser;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -70,7 +77,7 @@ class BadFileLookup {
|
|||
|
||||
// Run the extension hook
|
||||
$bad = false;
|
||||
if ( !Hooks::run( 'BadImage', [ $name, &$bad ] ) ) {
|
||||
if ( !$this->hookRunner->onBadImage( $name, $bad ) ) {
|
||||
return (bool)$bad;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,13 @@
|
|||
*
|
||||
* @file
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
class CategoryViewer extends ContextSource {
|
||||
use ProtectedHookAccessorTrait;
|
||||
|
||||
/** @var int */
|
||||
public $limit;
|
||||
|
||||
|
|
@ -194,7 +198,7 @@ class CategoryViewer extends ContextSource {
|
|||
|
||||
private function generateLink( $type, Title $title, $isRedirect, $html = null ) {
|
||||
$link = null;
|
||||
Hooks::run( 'CategoryViewer::generateLink', [ $type, $title, $html, &$link ] );
|
||||
$this->getHookRunner()->onCategoryViewer__generateLink( $type, $title, $html, $link );
|
||||
if ( $link === null ) {
|
||||
$linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
|
||||
if ( $html !== null ) {
|
||||
|
|
@ -347,7 +351,7 @@ class CategoryViewer extends ContextSource {
|
|||
]
|
||||
);
|
||||
|
||||
Hooks::run( 'CategoryViewer::doCategoryQuery', [ $type, $res ] );
|
||||
$this->getHookRunner()->onCategoryViewer__doCategoryQuery( $type, $res );
|
||||
$linkCache = MediaWikiServices::getInstance()->getLinkCache();
|
||||
|
||||
$count = 0;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
class ContentSecurityPolicy {
|
||||
|
|
@ -45,17 +47,24 @@ class ContentSecurityPolicy {
|
|||
/** @var array */
|
||||
private $extraStyleSrc = [];
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/**
|
||||
* @note As a general rule, you would not construct this class directly
|
||||
* but use the instance from OutputPage::getCSP()
|
||||
* @internal
|
||||
* @param WebResponse $response
|
||||
* @param Config $mwConfig
|
||||
* @param HookContainer $hookContainer
|
||||
* @since 1.35 Method signature changed
|
||||
*/
|
||||
public function __construct( WebResponse $response, Config $mwConfig ) {
|
||||
public function __construct( WebResponse $response, Config $mwConfig,
|
||||
HookContainer $hookContainer
|
||||
) {
|
||||
$this->response = $response;
|
||||
$this->mwConfig = $mwConfig;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -215,8 +224,8 @@ class ContentSecurityPolicy {
|
|||
|
||||
$cssSrc = array_merge( $defaultSrc, $this->extraStyleSrc, [ "'unsafe-inline'" ] );
|
||||
|
||||
Hooks::run( 'ContentSecurityPolicyDefaultSource', [ &$defaultSrc, $policyConfig, $mode ] );
|
||||
Hooks::run( 'ContentSecurityPolicyScriptSource', [ &$scriptSrc, $policyConfig, $mode ] );
|
||||
$this->hookRunner->onContentSecurityPolicyDefaultSource( $defaultSrc, $policyConfig, $mode );
|
||||
$this->hookRunner->onContentSecurityPolicyScriptSource( $scriptSrc, $policyConfig, $mode );
|
||||
|
||||
if ( isset( $policyConfig['report-uri'] ) && $policyConfig['report-uri'] !== true ) {
|
||||
if ( $policyConfig['report-uri'] === false ) {
|
||||
|
|
@ -282,7 +291,7 @@ class ContentSecurityPolicy {
|
|||
$directives[] = 'report-uri ' . $reportUri;
|
||||
}
|
||||
|
||||
Hooks::run( 'ContentSecurityPolicyDirectives', [ &$directives, $policyConfig, $mode ] );
|
||||
$this->hookRunner->onContentSecurityPolicyDirectives( $directives, $policyConfig, $mode );
|
||||
|
||||
return implode( '; ', $directives );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ use MediaWiki\Block\DatabaseBlock;
|
|||
use MediaWiki\Content\IContentHandlerFactory;
|
||||
use MediaWiki\EditPage\TextboxBuilder;
|
||||
use MediaWiki\EditPage\TextConflictHelper;
|
||||
use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
|
||||
use MediaWiki\Logger\LoggerFactory;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Permissions\PermissionManager;
|
||||
|
|
@ -49,8 +50,8 @@ use Wikimedia\ScopedCallback;
|
|||
* headaches, which may be fatal.
|
||||
*/
|
||||
class EditPage {
|
||||
|
||||
use DeprecationHelper;
|
||||
use ProtectedHookAccessorTrait;
|
||||
|
||||
/**
|
||||
* Used for Unicode support checks
|
||||
|
|
@ -627,7 +628,7 @@ class EditPage {
|
|||
*/
|
||||
public function edit() {
|
||||
// Allow extensions to modify/prevent this form or submission
|
||||
if ( !Hooks::run( 'AlternateEdit', [ $this ] ) ) {
|
||||
if ( !$this->getHookRunner()->onAlternateEdit( $this ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -749,9 +750,9 @@ class EditPage {
|
|||
}
|
||||
|
||||
if ( !$this->mTitle->getArticleID() ) {
|
||||
Hooks::run( 'EditFormPreloadText', [ &$this->textbox1, &$this->mTitle ] );
|
||||
$this->getHookRunner()->onEditFormPreloadText( $this->textbox1, $this->mTitle );
|
||||
} else {
|
||||
Hooks::run( 'EditFormInitialText', [ $this ] );
|
||||
$this->getHookRunner()->onEditFormInitialText( $this );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -848,7 +849,7 @@ class EditPage {
|
|||
*/
|
||||
protected function displayViewSourcePage( Content $content, $errorMessage = '' ) {
|
||||
$out = $this->context->getOutput();
|
||||
Hooks::run( 'EditPage::showReadOnlyForm:initial', [ $this, &$out ] );
|
||||
$this->getHookRunner()->onEditPage__showReadOnlyForm_initial( $this, $out );
|
||||
|
||||
$out->setRobotPolicy( 'noindex,nofollow' );
|
||||
$out->setPageTitle( $this->context->msg(
|
||||
|
|
@ -1180,7 +1181,7 @@ class EditPage {
|
|||
$this->section === 'new' ? 'MediaWiki:addsection-editintro' : '' );
|
||||
|
||||
// Allow extensions to modify form data
|
||||
Hooks::run( 'EditPage::importFormData', [ $this, $request ] );
|
||||
$this->getHookRunner()->onEditPage__importFormData( $this, $request );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1757,7 +1758,7 @@ class EditPage {
|
|||
&& $this->permManager->userHasRight( $this->context->getUser(), 'bot' );
|
||||
$status = $this->internalAttemptSave( $resultDetails, $markAsBot );
|
||||
|
||||
Hooks::run( 'EditPage::attemptSave:after', [ $this, $status, $resultDetails ] );
|
||||
$this->getHookRunner()->onEditPage__attemptSave_after( $this, $status, $resultDetails );
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
|
@ -1851,10 +1852,8 @@ class EditPage {
|
|||
$sectionanchor = $resultDetails['sectionanchor'];
|
||||
|
||||
// Give extensions a chance to modify URL query on update
|
||||
Hooks::run(
|
||||
'ArticleUpdateBeforeRedirect',
|
||||
[ $this->mArticle, &$sectionanchor, &$extraQuery ]
|
||||
);
|
||||
$this->getHookRunner()->onArticleUpdateBeforeRedirect( $this->mArticle,
|
||||
$sectionanchor, $extraQuery );
|
||||
|
||||
if ( $resultDetails['redirect'] ) {
|
||||
if ( $extraQuery !== '' ) {
|
||||
|
|
@ -1936,9 +1935,8 @@ class EditPage {
|
|||
}
|
||||
|
||||
// Run new style post-section-merge edit filter
|
||||
if ( !Hooks::run( 'EditFilterMergedContent',
|
||||
[ $this->context, $content, $status, $this->summary,
|
||||
$user, $this->minoredit ] )
|
||||
if ( !$this->getHookRunner()->onEditFilterMergedContent( $this->context, $content,
|
||||
$status, $this->summary, $user, $this->minoredit )
|
||||
) {
|
||||
# Error messages etc. could be handled within the hook...
|
||||
if ( $status->isGood() ) {
|
||||
|
|
@ -2049,7 +2047,7 @@ ERROR;
|
|||
$status = Status::newGood();
|
||||
$user = $this->context->getUser();
|
||||
|
||||
if ( !Hooks::run( 'EditPage::attemptSave', [ $this ] ) ) {
|
||||
if ( !$this->getHookRunner()->onEditPage__attemptSave( $this ) ) {
|
||||
wfDebug( "Hook 'EditPage::attemptSave' aborted article saving\n" );
|
||||
$status->fatal( 'hookaborted' );
|
||||
$status->value = self::AS_HOOK_ERROR;
|
||||
|
|
@ -2132,9 +2130,8 @@ ERROR;
|
|||
$status->value = self::AS_SPAM_ERROR;
|
||||
return $status;
|
||||
}
|
||||
if ( !Hooks::run(
|
||||
'EditFilter',
|
||||
[ $this, $this->textbox1, $this->section, &$this->hookError, $this->summary ] )
|
||||
if ( !$this->getHookRunner()->onEditFilter( $this, $this->textbox1, $this->section,
|
||||
$this->hookError, $this->summary )
|
||||
) {
|
||||
# Error messages etc. could be handled within the hook...
|
||||
$status->fatal( 'hookaborted' );
|
||||
|
|
@ -2994,9 +2991,7 @@ ERROR;
|
|||
|
||||
$out = $this->context->getOutput();
|
||||
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$editPage = $this;
|
||||
Hooks::run( 'EditPage::showEditForm:initial', [ &$editPage, &$out ] );
|
||||
$this->getHookRunner()->onEditPage__showEditForm_initial( $this, $out );
|
||||
|
||||
$this->setHeaders();
|
||||
|
||||
|
|
@ -3071,9 +3066,7 @@ ERROR;
|
|||
. Xml::closeElement( 'div' )
|
||||
);
|
||||
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$editPage = $this;
|
||||
Hooks::run( 'EditPage::showEditForm:fields', [ &$editPage, &$out ] );
|
||||
$this->getHookRunner()->onEditPage__showEditForm_fields( $this, $out );
|
||||
|
||||
// Put these up at the top to ensure they aren't lost on early form submission
|
||||
$this->showFormBeforeText();
|
||||
|
|
@ -3726,7 +3719,7 @@ ERROR;
|
|||
# This hook seems slightly odd here, but makes things more
|
||||
# consistent for extensions.
|
||||
$out = $this->context->getOutput();
|
||||
Hooks::run( 'OutputPageBeforeHTML', [ &$out, &$text ] );
|
||||
$this->getHookRunner()->onOutputPageBeforeHTML( $out, $text );
|
||||
$out->addHTML( $text );
|
||||
if ( $this->mArticle instanceof CategoryPage ) {
|
||||
$this->mArticle->closeShowCategory();
|
||||
|
|
@ -3767,7 +3760,7 @@ ERROR;
|
|||
}
|
||||
|
||||
if ( $newContent ) {
|
||||
Hooks::run( 'EditPageGetDiffContent', [ $this, &$newContent ] );
|
||||
$this->getHookRunner()->onEditPageGetDiffContent( $this, $newContent );
|
||||
|
||||
$user = $this->context->getUser();
|
||||
$popts = ParserOptions::newFromUserAndLang( $user,
|
||||
|
|
@ -3820,7 +3813,7 @@ ERROR;
|
|||
*/
|
||||
protected function showTosSummary() {
|
||||
$msg = 'editpage-tos-summary';
|
||||
Hooks::run( 'EditPageTosSummary', [ $this->mTitle, &$msg ] );
|
||||
$this->getHookRunner()->onEditPageTosSummary( $this->mTitle, $msg );
|
||||
if ( !$this->context->msg( $msg )->isDisabled() ) {
|
||||
$out = $this->context->getOutput();
|
||||
$out->addHTML( '<div class="mw-tos-summary">' );
|
||||
|
|
@ -3868,7 +3861,7 @@ ERROR;
|
|||
'[[' . wfMessage( 'copyrightpage' )->inContentLanguage()->text() . ']]' ];
|
||||
}
|
||||
// Allow for site and per-namespace customization of contribution/copyright notice.
|
||||
Hooks::run( 'EditPageCopyrightWarning', [ $title, &$copywarnMsg ] );
|
||||
Hooks::runner()->onEditPageCopyrightWarning( $title, $copywarnMsg );
|
||||
|
||||
$msg = wfMessage( ...$copywarnMsg )->title( $title );
|
||||
if ( $langcode ) {
|
||||
|
|
@ -3905,9 +3898,7 @@ ERROR;
|
|||
Html::openElement( 'tbody' );
|
||||
|
||||
foreach ( $output->getLimitReportData() as $key => $value ) {
|
||||
if ( Hooks::run( 'ParserLimitReportFormat',
|
||||
[ $key, &$value, &$limitReport, true, true ]
|
||||
) ) {
|
||||
if ( Hooks::runner()->onParserLimitReportFormat( $key, $value, $limitReport, true, true ) ) {
|
||||
$keyMsg = wfMessage( $key );
|
||||
$valueMsg = wfMessage( [ "$key-value-html", "$key-value" ] );
|
||||
if ( !$valueMsg->exists() ) {
|
||||
|
|
@ -3972,7 +3963,7 @@ ERROR;
|
|||
$out->addHTML( " <span class='editHelp'>{$edithelp}</span>\n" );
|
||||
$out->addHTML( "</div><!-- editButtons -->\n" );
|
||||
|
||||
Hooks::run( 'EditPage::showStandardInputs:options', [ $this, $out, &$tabindex ] );
|
||||
$this->getHookRunner()->onEditPage__showStandardInputs_options( $this, $out, $tabindex );
|
||||
|
||||
$out->addHTML( "</div><!-- editOptions -->\n" );
|
||||
}
|
||||
|
|
@ -3985,7 +3976,7 @@ ERROR;
|
|||
$out = $this->context->getOutput();
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$editPage = $this;
|
||||
if ( Hooks::run( 'EditPageBeforeConflictDiff', [ &$editPage, &$out ] ) ) {
|
||||
if ( $this->getHookRunner()->onEditPageBeforeConflictDiff( $editPage, $out ) ) {
|
||||
$this->incrementConflictStats();
|
||||
|
||||
$this->getEditConflictHelper()->showEditFormTextAfterFooters();
|
||||
|
|
@ -4139,9 +4130,8 @@ ERROR;
|
|||
$content = $this->toEditContent( $this->textbox1 );
|
||||
|
||||
$previewHTML = '';
|
||||
if ( !Hooks::run(
|
||||
'AlternateEditPreview',
|
||||
[ $this, &$content, &$previewHTML, &$this->mParserOutput ] )
|
||||
if ( !$this->getHookRunner()->onAlternateEditPreview(
|
||||
$this, $content, $previewHTML, $this->mParserOutput )
|
||||
) {
|
||||
return $previewHTML;
|
||||
}
|
||||
|
|
@ -4213,7 +4203,7 @@ ERROR;
|
|||
$content = $content->addSectionHeader( $this->summary );
|
||||
}
|
||||
|
||||
Hooks::run( 'EditPageGetPreviewContent', [ $this, &$content ] );
|
||||
$this->getHookRunner()->onEditPageGetPreviewContent( $this, $content );
|
||||
|
||||
$parserResult = $this->doPreviewParse( $content );
|
||||
$parserOutput = $parserResult['parserOutput'];
|
||||
|
|
@ -4349,7 +4339,7 @@ ERROR;
|
|||
$startingToolbar = '<div id="toolbar"></div>';
|
||||
$toolbar = $startingToolbar;
|
||||
|
||||
if ( !Hooks::run( 'EditPageBeforeEditToolbar', [ &$toolbar ] ) ) {
|
||||
if ( !Hooks::runner()->onEditPageBeforeEditToolbar( $toolbar ) ) {
|
||||
return null;
|
||||
}
|
||||
// Don't add a pointless `<div>` to the page unless a hook caller populated it
|
||||
|
|
@ -4403,8 +4393,7 @@ ERROR;
|
|||
];
|
||||
}
|
||||
|
||||
$editPage = $this;
|
||||
Hooks::run( 'EditPageGetCheckboxesDefinition', [ $editPage, &$checkboxes ] );
|
||||
$this->getHookRunner()->onEditPageGetCheckboxesDefinition( $this, $checkboxes );
|
||||
|
||||
return $checkboxes;
|
||||
}
|
||||
|
|
@ -4547,9 +4536,7 @@ ERROR;
|
|||
'accessKey' => Linker::accesskey( 'diff' ),
|
||||
] );
|
||||
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$editPage = $this;
|
||||
Hooks::run( 'EditPageBeforeEditButtons', [ &$editPage, &$buttons, &$tabindex ] );
|
||||
$this->getHookRunner()->onEditPageBeforeEditButtons( $this, $buttons, $tabindex );
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
|
|
@ -4564,9 +4551,7 @@ ERROR;
|
|||
|
||||
$res = $this->context->msg( 'nosuchsectiontext', $this->section )->parseAsBlock();
|
||||
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$editPage = $this;
|
||||
Hooks::run( 'EditPageNoSuchSection', [ &$editPage, &$res ] );
|
||||
$this->getHookRunner()->onEditPageNoSuchSection( $this, $res );
|
||||
$out->addHTML( $res );
|
||||
|
||||
$out->returnToMain( false, $this->mTitle );
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ class FileDeleteForm {
|
|||
}
|
||||
|
||||
if ( $status->isOK() ) {
|
||||
Hooks::run( 'FileDeleteComplete', [ &$file, &$oldimage, &$page, &$user, &$reason ] );
|
||||
Hooks::runner()->onFileDeleteComplete( $file, $oldimage, $page, $user, $reason );
|
||||
}
|
||||
|
||||
return $status;
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ class GitInfo {
|
|||
|
||||
if ( self::$viewers === false ) {
|
||||
self::$viewers = $wgGitRepositoryViewers;
|
||||
Hooks::run( 'GitViewers', [ &self::$viewers ] );
|
||||
Hooks::runner()->onGitViewers( self::$viewers );
|
||||
}
|
||||
|
||||
return self::$viewers;
|
||||
|
|
|
|||
|
|
@ -2128,7 +2128,7 @@ function wfShellWikiCmd( $script, array $parameters = [], array $options = [] )
|
|||
global $wgPhpCli;
|
||||
// Give site config file a chance to run the script in a wrapper.
|
||||
// The caller may likely want to call wfBasename() on $script.
|
||||
Hooks::run( 'wfShellWikiCmd', [ &$script, &$parameters, &$options ] );
|
||||
Hooks::runner()->onWfShellWikiCmd( $script, $parameters, $options );
|
||||
$cmd = [ $options['php'] ?? $wgPhpCli ];
|
||||
if ( isset( $options['wrapper'] ) ) {
|
||||
$cmd[] = $options['wrapper'];
|
||||
|
|
@ -2812,7 +2812,8 @@ function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) {
|
|||
},
|
||||
$services->getLocalServerObjectCache(),
|
||||
$services->getRepoGroup(),
|
||||
$services->getTitleParser()
|
||||
$services->getTitleParser(),
|
||||
$services->getHookContainer()
|
||||
) )->isBadFile( $name, $contextTitle ?: null );
|
||||
}
|
||||
return $services->getBadFileLookup()->isBadFile( $name, $contextTitle ?: null );
|
||||
|
|
@ -2827,7 +2828,7 @@ function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) {
|
|||
*/
|
||||
function wfCanIPUseHTTPS( $ip ) {
|
||||
$canDo = true;
|
||||
Hooks::run( 'CanIPUseHTTPS', [ $ip, &$canDo ] );
|
||||
Hooks::runner()->onCanIPUseHTTPS( $ip, $canDo );
|
||||
return (bool)$canDo;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ class Linker {
|
|||
public static function makeSelfLinkObj( $nt, $html = '', $query = '', $trail = '', $prefix = '' ) {
|
||||
$nt = Title::newFromLinkTarget( $nt );
|
||||
$ret = "<a class=\"mw-selflink selflink\">{$prefix}{$html}</a>{$trail}";
|
||||
if ( !Hooks::run( 'SelfLinkBegin', [ $nt, &$html, &$trail, &$prefix, &$ret ] ) ) {
|
||||
if ( !Hooks::runner()->onSelfLinkBegin( $nt, $html, $trail, $prefix, $ret ) ) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
|
@ -245,7 +245,7 @@ class Linker {
|
|||
$alt = self::fnamePart( $url );
|
||||
}
|
||||
$img = '';
|
||||
$success = Hooks::run( 'LinkerMakeExternalImage', [ &$url, &$alt, &$img ] );
|
||||
$success = Hooks::runner()->onLinkerMakeExternalImage( $url, $alt, $img );
|
||||
if ( !$success ) {
|
||||
wfDebug( "Hook LinkerMakeExternalImage changed the output of external image "
|
||||
. "with url {$url} and alt text {$alt} to {$img}\n", true );
|
||||
|
|
@ -303,10 +303,10 @@ class Linker {
|
|||
$title = Title::newFromLinkTarget( $title );
|
||||
$res = null;
|
||||
$dummy = new DummyLinker;
|
||||
if ( !Hooks::run( 'ImageBeforeProduceHTML', [ &$dummy, &$title,
|
||||
&$file, &$frameParams, &$handlerParams, &$time, &$res,
|
||||
$parser, &$query, &$widthOption
|
||||
] ) ) {
|
||||
if ( !Hooks::runner()->onImageBeforeProduceHTML( $dummy, $title,
|
||||
$file, $frameParams, $handlerParams, $time, $res,
|
||||
$parser, $query, $widthOption )
|
||||
) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
|
@ -796,8 +796,9 @@ class Linker {
|
|||
'title' => $alt
|
||||
];
|
||||
|
||||
if ( !Hooks::run( 'LinkerMakeMediaLinkFile',
|
||||
[ Title::castFromLinkTarget( $title ), $file, &$html, &$attribs, &$ret ] ) ) {
|
||||
if ( !Hooks::runner()->onLinkerMakeMediaLinkFile(
|
||||
Title::castFromLinkTarget( $title ), $file, $html, $attribs, $ret )
|
||||
) {
|
||||
wfDebug( "Hook LinkerMakeMediaLinkFile changed the output of link "
|
||||
. "with url {$url} and text {$html} to {$ret}\n", true );
|
||||
return $ret;
|
||||
|
|
@ -873,8 +874,8 @@ class Linker {
|
|||
$attribs['rel'] = implode( ' ', $combined );
|
||||
}
|
||||
$link = '';
|
||||
$success = Hooks::run( 'LinkerMakeExternalLink',
|
||||
[ &$url, &$text, &$link, &$attribs, $linktype ] );
|
||||
$success = Hooks::runner()->onLinkerMakeExternalLink(
|
||||
$url, $text, $link, $attribs, $linktype );
|
||||
if ( !$success ) {
|
||||
wfDebug( "Hook LinkerMakeExternalLink changed the output of link "
|
||||
. "with url {$url} and text {$text} to {$link}\n", true );
|
||||
|
|
@ -989,7 +990,7 @@ class Linker {
|
|||
$items[] = self::emailLink( $userId, $userText );
|
||||
}
|
||||
|
||||
Hooks::run( 'UserToolLinksEdit', [ $userId, $userText, &$items ] );
|
||||
Hooks::runner()->onUserToolLinksEdit( $userId, $userText, $items );
|
||||
|
||||
if ( !$items ) {
|
||||
return '';
|
||||
|
|
@ -1252,11 +1253,9 @@ class Linker {
|
|||
$post = $match[3] !== '';
|
||||
$comment = null;
|
||||
|
||||
Hooks::run(
|
||||
'FormatAutocomments',
|
||||
[ &$comment, $pre, $auto, $post, Title::castFromLinkTarget( $title ), $local,
|
||||
$wikiId ]
|
||||
);
|
||||
Hooks::runner()->onFormatAutocomments(
|
||||
$comment, $pre, $auto, $post, Title::castFromLinkTarget( $title ), $local,
|
||||
$wikiId );
|
||||
|
||||
if ( $comment === null ) {
|
||||
if ( $title ) {
|
||||
|
|
|
|||
|
|
@ -162,10 +162,9 @@ class MWTimestamp extends ConvertibleTimestamp {
|
|||
|
||||
$ts = '';
|
||||
$diff = $this->diff( $relativeTo );
|
||||
if ( Hooks::run(
|
||||
'GetRelativeTimestamp',
|
||||
[ &$ts, &$diff, $this, $relativeTo, $user, $lang ]
|
||||
) ) {
|
||||
if ( Hooks::runner()->onGetRelativeTimestamp(
|
||||
$ts, $diff, $this, $relativeTo, $user, $lang )
|
||||
) {
|
||||
$seconds = ( ( ( $diff->days * 24 + $diff->h ) * 60 + $diff->i ) * 60 + $diff->s );
|
||||
$ts = wfMessage( 'ago', $lang->formatDuration( $seconds, $chosenIntervals ) )
|
||||
->inLanguage( $lang )->text();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@
|
|||
* @ingroup Parser
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
|
||||
/**
|
||||
* A factory that stores information about MagicWords, and creates them on demand with caching.
|
||||
*
|
||||
|
|
@ -196,13 +199,18 @@ class MagicWordFactory {
|
|||
/** @var Language */
|
||||
private $contLang;
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/** #@- */
|
||||
|
||||
/**
|
||||
* @param Language $contLang Content language
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
public function __construct( Language $contLang ) {
|
||||
public function __construct( Language $contLang, HookContainer $hookContainer ) {
|
||||
$this->contLang = $contLang;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
}
|
||||
|
||||
public function getContentLanguage() {
|
||||
|
|
@ -233,7 +241,7 @@ class MagicWordFactory {
|
|||
public function getVariableIDs() {
|
||||
if ( !$this->mVariableIDsInitialised ) {
|
||||
# Get variable IDs
|
||||
Hooks::run( 'MagicWordwgVariableIDs', [ &$this->mVariableIDs ] );
|
||||
$this->hookRunner->onMagicWordwgVariableIDs( $this->mVariableIDs );
|
||||
$this->mVariableIDsInitialised = true;
|
||||
}
|
||||
return $this->mVariableIDs;
|
||||
|
|
@ -268,7 +276,7 @@ class MagicWordFactory {
|
|||
*/
|
||||
public function getDoubleUnderscoreArray() {
|
||||
if ( $this->mDoubleUnderscoreArray === null ) {
|
||||
Hooks::run( 'GetDoubleUnderscoreIDs', [ &$this->mDoubleUnderscoreIDs ] );
|
||||
$this->hookRunner->onGetDoubleUnderscoreIDs( $this->mDoubleUnderscoreIDs );
|
||||
$this->mDoubleUnderscoreArray = $this->newArray( $this->mDoubleUnderscoreIDs );
|
||||
}
|
||||
return $this->mDoubleUnderscoreArray;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
use Liuggio\StatsdClient\Sender\SocketSender;
|
||||
use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
|
||||
use MediaWiki\Logger\LoggerFactory;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
|
@ -33,6 +34,8 @@ use Wikimedia\Rdbms\ILBFactory;
|
|||
* The MediaWiki class is the helper class for the index.php entry point.
|
||||
*/
|
||||
class MediaWiki {
|
||||
use ProtectedHookAccessorTrait;
|
||||
|
||||
/** @var IContextSource */
|
||||
private $context;
|
||||
/** @var Config */
|
||||
|
|
@ -184,8 +187,7 @@ class MediaWiki {
|
|||
$output->setPrintable();
|
||||
}
|
||||
|
||||
$unused = null; // To pass it by reference
|
||||
Hooks::run( 'BeforeInitialize', [ &$title, &$unused, &$output, &$user, $request, $this ] );
|
||||
$this->getHookRunner()->onBeforeInitialize( $title, null, $output, $user, $request, $this );
|
||||
|
||||
// Invalid titles. T23776: The interwikis must redirect even if the page name is empty.
|
||||
if ( $title === null || ( $title->getDBkey() == '' && !$title->isExternal() )
|
||||
|
|
@ -345,7 +347,7 @@ class MediaWiki {
|
|||
|| ( $request->getCheck( 'title' )
|
||||
&& $title->getPrefixedDBkey() == $request->getVal( 'title' ) )
|
||||
|| count( $request->getValueNames( [ 'action', 'title' ] ) )
|
||||
|| !Hooks::run( 'TestCanonicalRedirect', [ $request, $title, $output ] )
|
||||
|| !$this->getHookRunner()->onTestCanonicalRedirect( $request, $title, $output )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -439,8 +441,8 @@ class MediaWiki {
|
|||
// Give extensions a change to ignore/handle redirects as needed
|
||||
$ignoreRedirect = $target = false;
|
||||
|
||||
Hooks::run( 'InitializeArticleMaybeRedirect',
|
||||
[ &$title, &$request, &$ignoreRedirect, &$target, &$article ] );
|
||||
$this->getHookRunner()->onInitializeArticleMaybeRedirect( $title, $request,
|
||||
$ignoreRedirect, $target, $article );
|
||||
$page = $article->getPage(); // reflect any hook changes
|
||||
|
||||
// Follow redirects only for... redirects.
|
||||
|
|
@ -487,8 +489,8 @@ class MediaWiki {
|
|||
$title = $this->context->getTitle();
|
||||
$user = $this->context->getUser();
|
||||
|
||||
if ( !Hooks::run( 'MediaWikiPerformAction',
|
||||
[ $output, $article, $title, $user, $request, $this ] )
|
||||
if ( !$this->getHookRunner()->onMediaWikiPerformAction(
|
||||
$output, $article, $title, $user, $request, $this )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -931,7 +933,7 @@ class MediaWiki {
|
|||
$redirUrl = preg_replace( '#^http://#', 'https://', $oldUrl );
|
||||
|
||||
// ATTENTION: This hook is likely to be removed soon due to overall design of the system.
|
||||
if ( Hooks::run( 'BeforeHttpsRedirect', [ $this->context, &$redirUrl ] ) ) {
|
||||
if ( $this->getHookRunner()->onBeforeHttpsRedirect( $this->context, $redirUrl ) ) {
|
||||
if ( $request->wasPosted() ) {
|
||||
// This is weird and we'd hope it almost never happens. This
|
||||
// means that a POST came in via HTTP and policy requires us
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ use ExternalStoreFactory;
|
|||
use FileBackendGroup;
|
||||
use GenderCache;
|
||||
use GlobalVarConfig;
|
||||
use Hooks;
|
||||
use HtmlCacheUpdater;
|
||||
use IBufferingStatsdDataFactory;
|
||||
use JobRunner;
|
||||
|
|
@ -37,6 +36,7 @@ use MediaWiki\EditPage\SpamChecker;
|
|||
use MediaWiki\FileBackend\FSFile\TempFSFileFactory;
|
||||
use MediaWiki\FileBackend\LockManager\LockManagerGroupFactory;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Http\HttpRequestFactory;
|
||||
use MediaWiki\Interwiki\InterwikiLookup;
|
||||
use MediaWiki\Languages\LanguageConverterFactory;
|
||||
|
|
@ -183,7 +183,8 @@ class MediaWikiServices extends ServiceContainer {
|
|||
|
||||
// Provides a traditional hook point to allow extensions to configure services.
|
||||
// NOTE: Ideally this would be in newInstance() but it causes an infinite run loop
|
||||
Hooks::run( 'MediaWikiServices', [ self::$instance ] );
|
||||
$runner = new HookRunner( self::$instance->getHookContainer() );
|
||||
$runner->onMediaWikiServices( self::$instance );
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
|
@ -268,7 +269,8 @@ class MediaWikiServices extends ServiceContainer {
|
|||
self::$instance = self::newInstance( $bootstrapConfig, 'load' );
|
||||
|
||||
// Provides a traditional hook point to allow extensions to configure services.
|
||||
Hooks::run( 'MediaWikiServices', [ self::$instance ] );
|
||||
$runner = new HookRunner( self::$instance->getHookContainer() );
|
||||
$runner->onMediaWikiServices( self::$instance );
|
||||
|
||||
self::$instance->importWiring( $oldInstance, [ 'BootstrapConfig' ] );
|
||||
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ class MergeHistory {
|
|||
$logId = $logEntry->insert();
|
||||
$logEntry->publish( $logId );
|
||||
|
||||
Hooks::run( 'ArticleMergeComplete', [ $this->source, $this->dest ] );
|
||||
Hooks::runner()->onArticleMergeComplete( $this->source, $this->dest );
|
||||
|
||||
$this->dbw->endAtomic( __METHOD__ );
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
use MediaWiki\Config\ServiceOptions;
|
||||
use MediaWiki\Content\IContentHandlerFactory;
|
||||
use MediaWiki\EditPage\SpamChecker;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Permissions\PermissionManager;
|
||||
use MediaWiki\Revision\MutableRevisionRecord;
|
||||
|
|
@ -94,6 +96,11 @@ class MovePage {
|
|||
*/
|
||||
private $spamChecker;
|
||||
|
||||
/**
|
||||
* @var HookRunner
|
||||
*/
|
||||
private $hookRunner;
|
||||
|
||||
public const CONSTRUCTOR_OPTIONS = [
|
||||
'CategoryCollation'
|
||||
];
|
||||
|
|
@ -112,6 +119,7 @@ class MovePage {
|
|||
* @param IContentHandlerFactory|null $contentHandlerFactory
|
||||
* @param RevisionStore|null $revisionStore
|
||||
* @param SpamChecker|null $spamChecker
|
||||
* @param HookContainer|null $hookContainer
|
||||
*/
|
||||
public function __construct(
|
||||
Title $oldTitle,
|
||||
|
|
@ -124,7 +132,8 @@ class MovePage {
|
|||
RepoGroup $repoGroup = null,
|
||||
IContentHandlerFactory $contentHandlerFactory = null,
|
||||
RevisionStore $revisionStore = null,
|
||||
SpamChecker $spamChecker = null
|
||||
SpamChecker $spamChecker = null,
|
||||
HookContainer $hookContainer = null
|
||||
) {
|
||||
$this->oldTitle = $oldTitle;
|
||||
$this->newTitle = $newTitle;
|
||||
|
|
@ -145,6 +154,8 @@ class MovePage {
|
|||
|
||||
$this->revisionStore = $revisionStore ?? $services->getRevisionStore();
|
||||
$this->spamChecker = $spamChecker ?? $services->getSpamChecker();
|
||||
$this->hookRunner = new HookRunner(
|
||||
$hookContainer ?? $services->getHookContainer() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -183,9 +194,8 @@ class MovePage {
|
|||
$status->fatal( 'cantmove-titleprotected' );
|
||||
}
|
||||
|
||||
Hooks::run( 'MovePageCheckPermissions',
|
||||
[ $this->oldTitle, $this->newTitle, $user, $reason, $status ]
|
||||
);
|
||||
$this->hookRunner->onMovePageCheckPermissions(
|
||||
$this->oldTitle, $this->newTitle, $user, $reason, $status );
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
|
@ -262,7 +272,7 @@ class MovePage {
|
|||
}
|
||||
|
||||
// Hook for extensions to say a title can't be moved for technical reasons
|
||||
Hooks::run( 'MovePageIsValidMove', [ $this->oldTitle, $this->newTitle, $status ] );
|
||||
$this->hookRunner->onMovePageIsValidMove( $this->oldTitle, $this->newTitle, $status );
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
|
@ -540,7 +550,7 @@ class MovePage {
|
|||
*/
|
||||
private function moveUnsafe( User $user, $reason, $createRedirect, array $changeTags ) {
|
||||
$status = Status::newGood();
|
||||
Hooks::run( 'TitleMove', [ $this->oldTitle, $this->newTitle, $user, $reason, &$status ] );
|
||||
$this->hookRunner->onTitleMove( $this->oldTitle, $this->newTitle, $user, $reason, $status );
|
||||
if ( !$status->isOK() ) {
|
||||
// Move was aborted by the hook
|
||||
return $status;
|
||||
|
|
@ -549,7 +559,7 @@ class MovePage {
|
|||
$dbw = $this->loadBalancer->getConnection( DB_MASTER );
|
||||
$dbw->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
|
||||
|
||||
Hooks::run( 'TitleMoveStarting', [ $this->oldTitle, $this->newTitle, $user ] );
|
||||
$this->hookRunner->onTitleMoveStarting( $this->oldTitle, $this->newTitle, $user );
|
||||
|
||||
$pageid = $this->oldTitle->getArticleID( Title::READ_LATEST );
|
||||
$protected = $this->oldTitle->isProtected();
|
||||
|
|
@ -685,11 +695,9 @@ class MovePage {
|
|||
}
|
||||
|
||||
$nullRevisionObj = new Revision( $nullRevision );
|
||||
Hooks::run(
|
||||
'TitleMoveCompleting',
|
||||
[ $this->oldTitle, $this->newTitle,
|
||||
$user, $pageid, $redirid, $reason, $nullRevisionObj ]
|
||||
);
|
||||
$this->hookRunner->onTitleMoveCompleting(
|
||||
$this->oldTitle, $this->newTitle,
|
||||
$user, $pageid, $redirid, $reason, $nullRevisionObj );
|
||||
|
||||
$dbw->endAtomic( __METHOD__ );
|
||||
|
||||
|
|
@ -699,15 +707,13 @@ class MovePage {
|
|||
$dbw,
|
||||
__METHOD__,
|
||||
function () use ( $user, $pageid, $redirid, $reason, $nullRevisionObj ) {
|
||||
Hooks::run( 'TitleMoveComplete', [
|
||||
&$this->oldTitle,
|
||||
&$this->newTitle,
|
||||
&$user,
|
||||
$pageid,
|
||||
$this->hookRunner->onTitleMoveComplete(
|
||||
$this->oldTitle,
|
||||
$this->newTitle,
|
||||
$user, $pageid,
|
||||
$redirid,
|
||||
$reason,
|
||||
$nullRevisionObj
|
||||
] );
|
||||
$nullRevisionObj );
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
@ -890,13 +896,13 @@ class MovePage {
|
|||
// TODO cleanup hooks and use of $nullRevisionObj
|
||||
$nullRevisionObj = new Revision( $nullRevision );
|
||||
$fakeTags = [];
|
||||
Hooks::run( 'RevisionFromEditComplete',
|
||||
[ $newpage, $nullRevision, $nullRevision->getParentId(), $user, &$fakeTags ] );
|
||||
$this->hookRunner->onRevisionFromEditComplete(
|
||||
$newpage, $nullRevision, $nullRevision->getParentId(), $user, $fakeTags );
|
||||
|
||||
// TODO hard deprecate hook
|
||||
$nullRevisionObj = new Revision( $nullRevision );
|
||||
Hooks::run( 'NewRevisionFromEditComplete',
|
||||
[ $newpage, $nullRevisionObj, $nullRevision->getParentId(), $user, &$fakeTags ] );
|
||||
$this->hookRunner->onNewRevisionFromEditComplete(
|
||||
$newpage, $nullRevisionObj, $nullRevision->getParentId(), $user, $fakeTags );
|
||||
|
||||
$newpage->doEditUpdates( $nullRevisionObj, $user,
|
||||
[ 'changed' => false, 'moved' => true, 'oldcountable' => $oldcountable ] );
|
||||
|
|
@ -925,18 +931,18 @@ class MovePage {
|
|||
$redirectArticle->updateRevisionOn( $dbw, $inserted, 0 );
|
||||
|
||||
$fakeTags = [];
|
||||
Hooks::run( 'RevisionFromEditComplete', [
|
||||
$this->hookRunner->onRevisionFromEditComplete(
|
||||
$redirectArticle,
|
||||
$inserted,
|
||||
false,
|
||||
$user,
|
||||
&$fakeTags
|
||||
] );
|
||||
$fakeTags
|
||||
);
|
||||
|
||||
// TODO hard deprecate hook
|
||||
$redirectRevisionObj = new Revision( $inserted );
|
||||
Hooks::run( 'NewRevisionFromEditComplete',
|
||||
[ $redirectArticle, $redirectRevisionObj, false, $user, &$fakeTags ] );
|
||||
$this->hookRunner->onNewRevisionFromEditComplete(
|
||||
$redirectArticle, $redirectRevisionObj, false, $user, $fakeTags );
|
||||
|
||||
// TODO WikiPage::doEditUpdates is deprecated
|
||||
$redirectArticle->doEditUpdates(
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
|
||||
use MediaWiki\Linker\LinkTarget;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Session\SessionManager;
|
||||
|
|
@ -44,6 +45,8 @@ use Wikimedia\WrappedStringList;
|
|||
* @todo document
|
||||
*/
|
||||
class OutputPage extends ContextSource {
|
||||
use ProtectedHookAccessorTrait;
|
||||
|
||||
/** @var string[][] Should be private. Used with addMeta() which adds "<meta>" */
|
||||
protected $mMetatags = [];
|
||||
|
||||
|
|
@ -345,7 +348,8 @@ class OutputPage extends ContextSource {
|
|||
$this->setContext( $context );
|
||||
$this->CSP = new ContentSecurityPolicy(
|
||||
$context->getRequest()->response(),
|
||||
$context->getConfig()
|
||||
$context->getConfig(),
|
||||
$this->getHookContainer()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -772,7 +776,7 @@ class OutputPage extends ContextSource {
|
|||
$config->get( 'CdnMaxAge' )
|
||||
) );
|
||||
}
|
||||
Hooks::run( 'OutputPageCheckLastModified', [ &$modifiedTimes, $this ] );
|
||||
$this->getHookRunner()->onOutputPageCheckLastModified( $modifiedTimes, $this );
|
||||
|
||||
$maxModified = max( $modifiedTimes );
|
||||
$this->mLastModified = wfTimestamp( TS_RFC2822, $maxModified );
|
||||
|
|
@ -1377,12 +1381,9 @@ class OutputPage extends ContextSource {
|
|||
}
|
||||
}
|
||||
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$outputPage = $this;
|
||||
# Add the remaining categories to the skin
|
||||
if ( Hooks::run(
|
||||
'OutputPageMakeCategoryLinks',
|
||||
[ &$outputPage, $categories, &$this->mCategoryLinks ] )
|
||||
if ( $this->getHookRunner()->onOutputPageMakeCategoryLinks(
|
||||
$this, $categories, $this->mCategoryLinks )
|
||||
) {
|
||||
$services = MediaWikiServices::getInstance();
|
||||
$linkRenderer = $services->getLinkRenderer();
|
||||
|
|
@ -1964,10 +1965,8 @@ class OutputPage extends ContextSource {
|
|||
// Link flags are ignored for now, but may in the future be
|
||||
// used to mark individual language links.
|
||||
$linkFlags = [];
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$outputPage = $this;
|
||||
Hooks::run( 'LanguageLinks', [ $this->getTitle(), &$this->mLanguageLinks, &$linkFlags ] );
|
||||
Hooks::runWithoutAbort( 'OutputPageParserOutput', [ &$outputPage, $parserOutput ] );
|
||||
$this->getHookRunner()->onLanguageLinks( $this->getTitle(), $this->mLanguageLinks, $linkFlags );
|
||||
$this->getHookRunner()->onOutputPageParserOutput( $this, $parserOutput );
|
||||
|
||||
// This check must be after 'OutputPageParserOutput' runs in addParserOutputMetadata
|
||||
// so that extensions may modify ParserOutput to toggle TOC.
|
||||
|
|
@ -2004,9 +2003,7 @@ class OutputPage extends ContextSource {
|
|||
*/
|
||||
public function addParserOutputText( ParserOutput $parserOutput, $poOptions = [] ) {
|
||||
$text = $parserOutput->getText( $poOptions );
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$outputPage = $this;
|
||||
Hooks::runWithoutAbort( 'OutputPageBeforeHTML', [ &$outputPage, &$text ] );
|
||||
$this->getHookRunner()->onOutputPageBeforeHTML( $this, $text );
|
||||
$this->addHTML( $text );
|
||||
}
|
||||
|
||||
|
|
@ -2231,7 +2228,7 @@ class OutputPage extends ContextSource {
|
|||
],
|
||||
$config->get( 'CacheVaryCookies' )
|
||||
) ) );
|
||||
Hooks::run( 'GetCacheVaryCookies', [ $this, &self::$cacheVaryCookies ] );
|
||||
$this->getHookRunner()->onGetCacheVaryCookies( $this, self::$cacheVaryCookies );
|
||||
}
|
||||
return self::$cacheVaryCookies;
|
||||
}
|
||||
|
|
@ -2532,7 +2529,7 @@ class OutputPage extends ContextSource {
|
|||
$redirect = $this->mRedirect;
|
||||
$code = $this->mRedirectCode;
|
||||
|
||||
if ( Hooks::run( "BeforePageRedirect", [ $this, &$redirect, &$code ] ) ) {
|
||||
if ( $this->getHookRunner()->onBeforePageRedirect( $this, $redirect, $code ) ) {
|
||||
if ( $code == '301' || $code == '303' ) {
|
||||
if ( !$config->get( 'DebugRedirects' ) ) {
|
||||
$response->statusHeader( $code );
|
||||
|
|
@ -2607,11 +2604,9 @@ class OutputPage extends ContextSource {
|
|||
|
||||
MWDebug::addModules( $this );
|
||||
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$outputPage = $this;
|
||||
// Hook that allows last minute changes to the output page, e.g.
|
||||
// adding of CSS or Javascript by extensions, adding CSP sources.
|
||||
Hooks::runWithoutAbort( 'BeforePageDisplay', [ &$outputPage, &$sk ] );
|
||||
$this->getHookRunner()->onBeforePageDisplay( $this, $sk );
|
||||
|
||||
$this->CSP->sendHeaders();
|
||||
|
||||
|
|
@ -2625,7 +2620,7 @@ class OutputPage extends ContextSource {
|
|||
|
||||
try {
|
||||
// This hook allows last minute changes to final overall output by modifying output buffer
|
||||
Hooks::runWithoutAbort( 'AfterFinalPageOutput', [ $this ] );
|
||||
$this->getHookRunner()->onAfterFinalPageOutput( $this );
|
||||
} catch ( Exception $e ) {
|
||||
ob_end_clean(); // bug T129657
|
||||
throw $e;
|
||||
|
|
@ -3134,7 +3129,7 @@ class OutputPage extends ContextSource {
|
|||
|
||||
// Allow skins and extensions to add body attributes they need
|
||||
$sk->addToBodyAttributes( $this, $bodyAttrs );
|
||||
Hooks::run( 'OutputPageBodyAttributes', [ $this, $sk, &$bodyAttrs ] );
|
||||
$this->getHookRunner()->onOutputPageBodyAttributes( $this, $sk, $bodyAttrs );
|
||||
|
||||
$pieces[] = Html::openElement( 'body', $bodyAttrs );
|
||||
|
||||
|
|
@ -3379,7 +3374,7 @@ class OutputPage extends ContextSource {
|
|||
// Use the 'ResourceLoaderGetConfigVars' hook if the variable is not
|
||||
// page-dependant but site-wide (without state).
|
||||
// Alternatively, you may want to use OutputPage->addJsConfigVars() instead.
|
||||
Hooks::run( 'MakeGlobalVariablesScript', [ &$vars, $this ] );
|
||||
$this->getHookRunner()->onMakeGlobalVariablesScript( $vars, $this );
|
||||
|
||||
// Merge in variables from addJsConfigVars last
|
||||
return array_merge( $vars, $this->getJsConfigVars() );
|
||||
|
|
@ -3661,7 +3656,7 @@ class OutputPage extends ContextSource {
|
|||
# Allow extensions to change the list pf feeds. This hook is primarily for changing,
|
||||
# manipulating or removing existing feed tags. If you want to add new feeds, you should
|
||||
# use OutputPage::addFeedLink() instead.
|
||||
Hooks::run( 'AfterBuildFeedLinks', [ &$feedLinks ] );
|
||||
$this->getHookRunner()->onAfterBuildFeedLinks( $feedLinks );
|
||||
|
||||
$tags += $feedLinks;
|
||||
}
|
||||
|
|
@ -3702,7 +3697,7 @@ class OutputPage extends ContextSource {
|
|||
// (or addHeadItems() for multiple items) method instead.
|
||||
// This hook is provided as a last resort for extensions to modify these
|
||||
// links before the output is sent to client.
|
||||
Hooks::run( 'OutputPageAfterGetHeadLinksArray', [ &$tags, $this ] );
|
||||
$this->getHookRunner()->onOutputPageAfterGetHeadLinksArray( $tags, $this );
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@ namespace MediaWiki\Permissions;
|
|||
use Action;
|
||||
use Article;
|
||||
use Exception;
|
||||
use Hooks;
|
||||
use MediaWiki\Block\BlockErrorFormatter;
|
||||
use MediaWiki\Config\ServiceOptions;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Linker\LinkTarget;
|
||||
use MediaWiki\Revision\RevisionLookup;
|
||||
use MediaWiki\Revision\RevisionRecord;
|
||||
|
|
@ -90,6 +91,9 @@ class PermissionManager {
|
|||
/** @var BlockErrorFormatter */
|
||||
private $blockErrorFormatter;
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/** @var string[][] Cached user rights */
|
||||
private $usersRights = null;
|
||||
|
||||
|
|
@ -197,13 +201,15 @@ class PermissionManager {
|
|||
* @param RevisionLookup $revisionLookup
|
||||
* @param NamespaceInfo $nsInfo
|
||||
* @param BlockErrorFormatter $blockErrorFormatter
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
public function __construct(
|
||||
ServiceOptions $options,
|
||||
SpecialPageFactory $specialPageFactory,
|
||||
RevisionLookup $revisionLookup,
|
||||
NamespaceInfo $nsInfo,
|
||||
BlockErrorFormatter $blockErrorFormatter
|
||||
BlockErrorFormatter $blockErrorFormatter,
|
||||
HookContainer $hookContainer
|
||||
) {
|
||||
$options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
|
||||
$this->options = $options;
|
||||
|
|
@ -211,6 +217,7 @@ class PermissionManager {
|
|||
$this->revisionLookup = $revisionLookup;
|
||||
$this->nsInfo = $nsInfo;
|
||||
$this->blockErrorFormatter = $blockErrorFormatter;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -330,7 +337,7 @@ class PermissionManager {
|
|||
$allowUsertalk = $user->isAllowUsertalk();
|
||||
|
||||
// Allow extensions to let a blocked user access a particular page
|
||||
Hooks::run( 'UserIsBlockedFrom', [ $user, $title, &$blocked, &$allowUsertalk ] );
|
||||
$this->hookRunner->onUserIsBlockedFrom( $user, $title, $blocked, $allowUsertalk );
|
||||
|
||||
return $blocked;
|
||||
}
|
||||
|
|
@ -437,18 +444,19 @@ class PermissionManager {
|
|||
$title = Title::newFromLinkTarget( $page );
|
||||
// Use getUserPermissionsErrors instead
|
||||
$result = '';
|
||||
if ( !Hooks::run( 'userCan', [ &$title, &$user, $action, &$result ] ) ) {
|
||||
if ( !$this->hookRunner->onUserCan( $title, $user, $action, $result ) ) {
|
||||
return $result ? [] : [ [ 'badaccess-group0' ] ];
|
||||
}
|
||||
// Check getUserPermissionsErrors hook
|
||||
if ( !Hooks::run( 'getUserPermissionsErrors', [ &$title, &$user, $action, &$result ] ) ) {
|
||||
if ( !$this->hookRunner->onGetUserPermissionsErrors( $title, $user, $action, $result ) ) {
|
||||
$errors = $this->resultToError( $errors, $result );
|
||||
}
|
||||
// Check getUserPermissionsErrorsExpensive hook
|
||||
if (
|
||||
$rigor !== self::RIGOR_QUICK
|
||||
&& !( $short && count( $errors ) > 0 )
|
||||
&& !Hooks::run( 'getUserPermissionsErrorsExpensive', [ &$title, &$user, $action, &$result ] )
|
||||
&& !$this->hookRunner->onGetUserPermissionsErrorsExpensive(
|
||||
$title, $user, $action, $result )
|
||||
) {
|
||||
$errors = $this->resultToError( $errors, $result );
|
||||
}
|
||||
|
|
@ -571,7 +579,7 @@ class PermissionManager {
|
|||
|
||||
if ( !$whitelisted ) {
|
||||
# If the title is not whitelisted, give extensions a chance to do so...
|
||||
Hooks::run( 'TitleReadWhitelist', [ $title, $user, &$whitelisted ] );
|
||||
$this->hookRunner->onTitleReadWhitelist( $title, $user, $whitelisted );
|
||||
if ( !$whitelisted ) {
|
||||
$errors[] = $this->missingPermissionError( $action, $short );
|
||||
}
|
||||
|
|
@ -742,8 +750,8 @@ class PermissionManager {
|
|||
// TODO: remove when LinkTarget usage will expand further
|
||||
$title = Title::newFromLinkTarget( $page );
|
||||
|
||||
if ( !Hooks::run( 'TitleQuickPermissions',
|
||||
[ $title, $user, $action, &$errors, ( $rigor !== self::RIGOR_QUICK ), $short ] )
|
||||
if ( !$this->hookRunner->onTitleQuickPermissions( $title, $user, $action,
|
||||
$errors, $rigor !== self::RIGOR_QUICK, $short )
|
||||
) {
|
||||
return $errors;
|
||||
}
|
||||
|
|
@ -1282,7 +1290,7 @@ class PermissionManager {
|
|||
$this->usersRights[ $rightsCacheKey ] = $this->getGroupPermissions(
|
||||
$user->getEffectiveGroups()
|
||||
);
|
||||
Hooks::run( 'UserGetRights', [ $user, &$this->usersRights[ $rightsCacheKey ] ] );
|
||||
$this->hookRunner->onUserGetRights( $user, $this->usersRights[ $rightsCacheKey ] );
|
||||
|
||||
// Deny any rights denied by the user's session, unless this
|
||||
// endpoint has no sessions.
|
||||
|
|
@ -1297,7 +1305,8 @@ class PermissionManager {
|
|||
}
|
||||
}
|
||||
|
||||
Hooks::run( 'UserGetRightsRemove', [ $user, &$this->usersRights[ $rightsCacheKey ] ] );
|
||||
$this->hookRunner->onUserGetRightsRemove(
|
||||
$user, $this->usersRights[ $rightsCacheKey ] );
|
||||
// Force reindexation of rights when a hook has unset one of them
|
||||
$this->usersRights[ $rightsCacheKey ] = array_values(
|
||||
array_unique( $this->usersRights[ $rightsCacheKey ] )
|
||||
|
|
@ -1466,7 +1475,7 @@ class PermissionManager {
|
|||
}
|
||||
|
||||
// Allow extensions to say false
|
||||
if ( !Hooks::run( 'UserIsEveryoneAllowed', [ $right ] ) ) {
|
||||
if ( !$this->hookRunner->onUserIsEveryoneAllowed( $right ) ) {
|
||||
$this->cachedRights[$right] = false;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1492,7 +1501,7 @@ class PermissionManager {
|
|||
} else {
|
||||
$this->allRights = $this->coreRights;
|
||||
}
|
||||
Hooks::run( 'UserGetAllRights', [ &$this->allRights ] );
|
||||
$this->hookRunner->onUserGetAllRights( $this->allRights );
|
||||
}
|
||||
return $this->allRights;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
*
|
||||
* @file
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Permissions\PermissionManager;
|
||||
|
||||
|
|
@ -77,6 +79,9 @@ class ProtectionForm {
|
|||
/** @var PermissionManager */
|
||||
private $permManager;
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
public function __construct( Article $article ) {
|
||||
// Set instance variables.
|
||||
$this->mArticle = $article;
|
||||
|
|
@ -84,7 +89,9 @@ class ProtectionForm {
|
|||
$this->mApplicableTypes = $this->mTitle->getRestrictionTypes();
|
||||
$this->mContext = $article->getContext();
|
||||
|
||||
$this->permManager = MediaWikiServices::getInstance()->getPermissionManager();
|
||||
$services = MediaWikiServices::getInstance();
|
||||
$this->permManager = $services->getPermissionManager();
|
||||
$this->hookRunner = new HookRunner( $services->getHookContainer() );
|
||||
|
||||
// Check if the form should be disabled.
|
||||
// If it is, the form will be available in read-only to show levels.
|
||||
|
|
@ -356,7 +363,7 @@ class ProtectionForm {
|
|||
* you can also return an array of message name and its parameters
|
||||
*/
|
||||
$errorMsg = '';
|
||||
if ( !Hooks::run( 'ProtectionForm::save', [ $this->mArticle, &$errorMsg, $reasonstr ] ) ) {
|
||||
if ( !$this->hookRunner->onProtectionForm__save( $this->mArticle, $errorMsg, $reasonstr ) ) {
|
||||
if ( $errorMsg == '' ) {
|
||||
$errorMsg = [ 'hookaborted' ];
|
||||
}
|
||||
|
|
@ -478,7 +485,7 @@ class ProtectionForm {
|
|||
"</td></tr>";
|
||||
}
|
||||
# Give extensions a chance to add items to the form
|
||||
Hooks::run( 'ProtectionForm::buildForm', [ $this->mArticle, &$out ] );
|
||||
$this->hookRunner->onProtectionForm__buildForm( $this->mArticle, $out );
|
||||
|
||||
$out .= Xml::closeElement( 'tbody' ) . Xml::closeElement( 'table' );
|
||||
|
||||
|
|
@ -656,6 +663,6 @@ class ProtectionForm {
|
|||
$out->addHTML( Xml::element( 'h2', null, $protectLogPage->getName()->text() ) );
|
||||
LogEventsList::showLogExtract( $out, 'protect', $this->mTitle );
|
||||
# Let extensions add other relevant log extracts
|
||||
Hooks::run( 'ProtectionForm::showLogExtract', [ $this->mArticle, $out ] );
|
||||
$this->hookRunner->onProtectionForm__showLogExtract( $this->mArticle, $out );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class ProxyLookup {
|
|||
*/
|
||||
public function isTrustedProxy( $ip ) {
|
||||
$trusted = $this->isConfiguredProxy( $ip );
|
||||
Hooks::run( 'IsTrustedProxy', [ &$ip, &$trusted ] );
|
||||
Hooks::runner()->onIsTrustedProxy( $ip, $trusted );
|
||||
return $trusted;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ class EntryPoint {
|
|||
$responseFactory,
|
||||
$authorizer,
|
||||
$objectFactory,
|
||||
$restValidator
|
||||
$restValidator,
|
||||
$services->getHookContainer()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace MediaWiki\Rest;
|
||||
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Rest\Validator\BodyValidator;
|
||||
use MediaWiki\Rest\Validator\NullBodyValidator;
|
||||
use MediaWiki\Rest\Validator\Validator;
|
||||
|
|
@ -35,6 +37,12 @@ abstract class Handler {
|
|||
/** @var ConditionalHeaderUtil */
|
||||
private $conditionalHeaderUtil;
|
||||
|
||||
/** @var HookContainer */
|
||||
private $hookContainer;
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/**
|
||||
* Initialise with dependencies from the Router. This is called after construction.
|
||||
* @internal
|
||||
|
|
@ -42,14 +50,17 @@ abstract class Handler {
|
|||
* @param RequestInterface $request
|
||||
* @param array $config
|
||||
* @param ResponseFactory $responseFactory
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
final public function init( Router $router, RequestInterface $request, array $config,
|
||||
ResponseFactory $responseFactory
|
||||
ResponseFactory $responseFactory, HookContainer $hookContainer
|
||||
) {
|
||||
$this->router = $router;
|
||||
$this->request = $request;
|
||||
$this->config = $config;
|
||||
$this->responseFactory = $responseFactory;
|
||||
$this->hookContainer = $hookContainer;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
$this->postInitSetup();
|
||||
}
|
||||
|
||||
|
|
@ -202,6 +213,28 @@ abstract class Handler {
|
|||
return $this->validatedBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a HookContainer, for running extension hooks or for hook metadata.
|
||||
*
|
||||
* @since 1.35
|
||||
* @return HookContainer
|
||||
*/
|
||||
protected function getHookContainer() {
|
||||
return $this->hookContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a HookRunner for running core hooks.
|
||||
*
|
||||
* @internal This is for use by core only. Hook interfaces may be removed
|
||||
* without notice.
|
||||
* @since 1.35
|
||||
* @return HookRunner
|
||||
*/
|
||||
protected function getHookRunner() {
|
||||
return $this->hookRunner;
|
||||
}
|
||||
|
||||
/**
|
||||
* The subclass should override this to provide the maximum last modified
|
||||
* timestamp for the current request. This is called before execute() in
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
namespace MediaWiki\Rest\Handler;
|
||||
|
||||
use Config;
|
||||
use Hooks;
|
||||
use InvalidArgumentException;
|
||||
use ISearchResultSet;
|
||||
use MediaWiki\Permissions\PermissionManager;
|
||||
|
|
@ -290,7 +289,7 @@ class SearchHandler extends Handler {
|
|||
private function buildDescriptionsFromPageIdentities( array $pageIdentities ) {
|
||||
$descriptions = array_fill_keys( array_keys( $pageIdentities ), null );
|
||||
|
||||
Hooks::run( 'SearchResultProvideDescription', [ $pageIdentities, &$descriptions ] );
|
||||
$this->getHookRunner()->onSearchResultProvideDescription( $pageIdentities, $descriptions );
|
||||
|
||||
return array_map( function ( $description ) {
|
||||
return [ 'description' => $description ];
|
||||
|
|
@ -311,7 +310,7 @@ class SearchHandler extends Handler {
|
|||
private function buildThumbnailsFromPageIdentities( array $pageIdentities ) {
|
||||
$thumbnails = array_fill_keys( array_keys( $pageIdentities ), null );
|
||||
|
||||
Hooks::run( 'SearchResultProvideThumbnail', [ $pageIdentities, &$thumbnails ] );
|
||||
$this->getHookRunner()->onSearchResultProvideThumbnail( $pageIdentities, $thumbnails );
|
||||
|
||||
return array_map( function ( $thumbnail ) {
|
||||
return [ 'thumbnail' => $this->serializeThumbnail( $thumbnail ) ];
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ namespace MediaWiki\Rest;
|
|||
use AppendIterator;
|
||||
use BagOStuff;
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Rest\BasicAccess\BasicAuthorizerInterface;
|
||||
use MediaWiki\Rest\PathTemplateMatcher\PathMatcher;
|
||||
use MediaWiki\Rest\Validator\Validator;
|
||||
|
|
@ -56,6 +58,9 @@ class Router {
|
|||
/** @var Validator */
|
||||
private $restValidator;
|
||||
|
||||
/** @var HookContainer */
|
||||
private $hookContainer;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param string[] $routeFiles List of names of JSON files containing routes
|
||||
|
|
@ -67,11 +72,12 @@ class Router {
|
|||
* @param BasicAuthorizerInterface $basicAuth
|
||||
* @param ObjectFactory $objectFactory
|
||||
* @param Validator $restValidator
|
||||
* @param HookContainer|null $hookContainer
|
||||
*/
|
||||
public function __construct( $routeFiles, $extraRoutes, $baseUrl, $rootPath,
|
||||
BagOStuff $cacheBag, ResponseFactory $responseFactory,
|
||||
BasicAuthorizerInterface $basicAuth, ObjectFactory $objectFactory,
|
||||
Validator $restValidator
|
||||
Validator $restValidator, HookContainer $hookContainer = null
|
||||
) {
|
||||
$this->routeFiles = $routeFiles;
|
||||
$this->extraRoutes = $extraRoutes;
|
||||
|
|
@ -82,6 +88,12 @@ class Router {
|
|||
$this->basicAuth = $basicAuth;
|
||||
$this->objectFactory = $objectFactory;
|
||||
$this->restValidator = $restValidator;
|
||||
|
||||
if ( !$hookContainer ) {
|
||||
// b/c for OAuth extension
|
||||
$hookContainer = MediaWikiServices::getInstance()->getHookContainer();
|
||||
}
|
||||
$this->hookContainer = $hookContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -322,7 +334,7 @@ class Router {
|
|||
[ 'factory' => true, 'class' => true, 'args' => true, 'services' => true ] );
|
||||
/** @var $handler Handler (annotation for PHPStorm) */
|
||||
$handler = $this->objectFactory->createObject( $objectFactorySpec );
|
||||
$handler->init( $this, $request, $spec, $this->responseFactory );
|
||||
$handler->init( $this, $request, $spec, $this->responseFactory, $this->hookContainer );
|
||||
|
||||
return $handler;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ class MainSlotRoleHandler extends SlotRoleHandler {
|
|||
|
||||
// Hook can determine default model
|
||||
$title = Title::newFromLinkTarget( $page );
|
||||
if ( !Hooks::run( 'ContentHandlerDefaultModelFor', [ $title, &$model ] ) && $model !== null ) {
|
||||
if ( !Hooks::runner()->onContentHandlerDefaultModelFor( $title, $model ) && $model !== null ) {
|
||||
return $model;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,10 +32,11 @@ use CommentStoreComment;
|
|||
use Content;
|
||||
use ContentHandler;
|
||||
use DBAccessObjectUtils;
|
||||
use Hooks;
|
||||
use IDBAccessObject;
|
||||
use InvalidArgumentException;
|
||||
use MediaWiki\Content\IContentHandlerFactory;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Linker\LinkTarget;
|
||||
use MediaWiki\Storage\BlobAccessException;
|
||||
use MediaWiki\Storage\BlobStore;
|
||||
|
|
@ -131,6 +132,9 @@ class RevisionStore
|
|||
/** @var IContentHandlerFactory */
|
||||
private $contentHandlerFactory;
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/**
|
||||
* @todo $blobStore should be allowed to be any BlobStore!
|
||||
*
|
||||
|
|
@ -148,6 +152,7 @@ class RevisionStore
|
|||
* @param SlotRoleRegistry $slotRoleRegistry
|
||||
* @param ActorMigration $actorMigration
|
||||
* @param IContentHandlerFactory $contentHandlerFactory
|
||||
* @param HookContainer $hookContainer
|
||||
* @param bool|string $dbDomain DB domain of the relevant wiki or false for the current one
|
||||
*/
|
||||
public function __construct(
|
||||
|
|
@ -160,6 +165,7 @@ class RevisionStore
|
|||
SlotRoleRegistry $slotRoleRegistry,
|
||||
ActorMigration $actorMigration,
|
||||
IContentHandlerFactory $contentHandlerFactory,
|
||||
HookContainer $hookContainer,
|
||||
$dbDomain = false
|
||||
) {
|
||||
Assert::parameterType( 'string|boolean', $dbDomain, '$dbDomain' );
|
||||
|
|
@ -175,6 +181,7 @@ class RevisionStore
|
|||
$this->dbDomain = $dbDomain;
|
||||
$this->logger = new NullLogger();
|
||||
$this->contentHandlerFactory = $contentHandlerFactory;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
}
|
||||
|
||||
public function setLogger( LoggerInterface $logger ) {
|
||||
|
|
@ -446,11 +453,11 @@ class RevisionStore
|
|||
);
|
||||
}
|
||||
|
||||
Hooks::run( 'RevisionRecordInserted', [ $rev ] );
|
||||
$this->hookRunner->onRevisionRecordInserted( $rev );
|
||||
|
||||
// Soft deprecated in 1.31, hard deprecated in 1.35
|
||||
$legacyRevision = new Revision( $rev );
|
||||
Hooks::run( 'RevisionInsertComplete', [ &$legacyRevision, null, null ], '1.31' );
|
||||
$this->hookRunner->onRevisionInsertComplete( $legacyRevision, null, null );
|
||||
|
||||
return $rev;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ namespace MediaWiki\Revision;
|
|||
use ActorMigration;
|
||||
use CommentStore;
|
||||
use MediaWiki\Content\IContentHandlerFactory;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\Storage\BlobStoreFactory;
|
||||
use MediaWiki\Storage\NameTableStoreFactory;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
|
@ -72,6 +73,9 @@ class RevisionStoreFactory {
|
|||
/** @var IContentHandlerFactory */
|
||||
private $contentHandlerFactory;
|
||||
|
||||
/** @var HookContainer */
|
||||
private $hookContainer;
|
||||
|
||||
/**
|
||||
* @param ILBFactory $dbLoadBalancerFactory
|
||||
* @param BlobStoreFactory $blobStoreFactory
|
||||
|
|
@ -82,6 +86,7 @@ class RevisionStoreFactory {
|
|||
* @param ActorMigration $actorMigration
|
||||
* @param LoggerInterface $logger
|
||||
* @param IContentHandlerFactory $contentHandlerFactory
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
public function __construct(
|
||||
ILBFactory $dbLoadBalancerFactory,
|
||||
|
|
@ -92,7 +97,8 @@ class RevisionStoreFactory {
|
|||
CommentStore $commentStore,
|
||||
ActorMigration $actorMigration,
|
||||
LoggerInterface $logger,
|
||||
IContentHandlerFactory $contentHandlerFactory
|
||||
IContentHandlerFactory $contentHandlerFactory,
|
||||
HookContainer $hookContainer
|
||||
) {
|
||||
$this->dbLoadBalancerFactory = $dbLoadBalancerFactory;
|
||||
$this->blobStoreFactory = $blobStoreFactory;
|
||||
|
|
@ -103,6 +109,7 @@ class RevisionStoreFactory {
|
|||
$this->actorMigration = $actorMigration;
|
||||
$this->logger = $logger;
|
||||
$this->contentHandlerFactory = $contentHandlerFactory;
|
||||
$this->hookContainer = $hookContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -125,6 +132,7 @@ class RevisionStoreFactory {
|
|||
$this->slotRoleRegistry,
|
||||
$this->actorMigration,
|
||||
$this->contentHandlerFactory,
|
||||
$this->hookContainer,
|
||||
$dbDomain
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use MediaWiki\Linker\LinkTarget;
|
|||
/**
|
||||
* SlotRoleHandler instances are used to declare the existence and behavior of slot roles.
|
||||
* Most importantly, they control which content model can be used for the slot, and how it is
|
||||
* represented in the rendered verswion of page content.
|
||||
* represented in the rendered version of page content.
|
||||
*
|
||||
* @since 1.33
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ use MediaWiki\FileBackend\LockManager\LockManagerGroupFactory;
|
|||
use MediaWiki\HookContainer\DeprecatedHooks;
|
||||
use MediaWiki\HookContainer\GlobalHookRegistry;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Http\HttpRequestFactory;
|
||||
use MediaWiki\Interwiki\ClassicInterwikiLookup;
|
||||
use MediaWiki\Interwiki\InterwikiLookup;
|
||||
|
|
@ -118,7 +119,8 @@ return [
|
|||
RequestContext::getMain()->getRequest(),
|
||||
$services->getMainConfig(),
|
||||
$services->getObjectFactory(),
|
||||
$services->getPermissionManager()
|
||||
$services->getPermissionManager(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
$authManager->setLogger( LoggerFactory::getInstance( 'authentication' ) );
|
||||
return $authManager;
|
||||
|
|
@ -131,7 +133,8 @@ return [
|
|||
},
|
||||
$services->getLocalServerObjectCache(),
|
||||
$services->getRepoGroup(),
|
||||
$services->getTitleParser()
|
||||
$services->getTitleParser(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -159,7 +162,8 @@ return [
|
|||
BlockManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
|
||||
),
|
||||
$services->getPermissionManager(),
|
||||
LoggerFactory::getInstance( 'BlockManager' )
|
||||
LoggerFactory::getInstance( 'BlockManager' ),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -208,7 +212,8 @@ return [
|
|||
|
||||
return new ContentHandlerFactory(
|
||||
$contentHandlerConfig,
|
||||
$services->getObjectFactory()
|
||||
$services->getObjectFactory(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -392,6 +397,7 @@ return [
|
|||
$config = $services->getMainConfig();
|
||||
|
||||
return new HtmlCacheUpdater(
|
||||
$services->getHookContainer(),
|
||||
$config->get( 'CdnReboundPurgeDelay' ),
|
||||
$config->get( 'UseFileCache' ),
|
||||
$config->get( 'CdnMaxAge' )
|
||||
|
|
@ -414,6 +420,7 @@ return [
|
|||
return new ClassicInterwikiLookup(
|
||||
$services->getContentLanguage(),
|
||||
$services->getMainWANObjectCache(),
|
||||
$services->getHookContainer(),
|
||||
$config->get( 'InterwikiExpiry' ),
|
||||
$config->get( 'InterwikiCache' ),
|
||||
$config->get( 'InterwikiScopes' ),
|
||||
|
|
@ -446,7 +453,8 @@ return [
|
|||
$services->getLocalisationCache(),
|
||||
$services->getLanguageNameUtils(),
|
||||
$services->getLanguageFallback(),
|
||||
$services->getLanguageConverterFactory()
|
||||
$services->getLanguageConverterFactory(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -459,10 +467,13 @@ return [
|
|||
},
|
||||
|
||||
'LanguageNameUtils' => function ( MediaWikiServices $services ) : LanguageNameUtils {
|
||||
return new LanguageNameUtils( new ServiceOptions(
|
||||
LanguageNameUtils::CONSTRUCTOR_OPTIONS,
|
||||
$services->getMainConfig()
|
||||
) );
|
||||
return new LanguageNameUtils(
|
||||
new ServiceOptions(
|
||||
LanguageNameUtils::CONSTRUCTOR_OPTIONS,
|
||||
$services->getMainConfig()
|
||||
),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
'LinkBatchFactory' => function ( MediaWikiServices $services ) : LinkBatchFactory {
|
||||
|
|
@ -500,7 +511,8 @@ return [
|
|||
$services->getTitleFormatter(),
|
||||
$services->getLinkCache(),
|
||||
$services->getNamespaceInfo(),
|
||||
$services->getSpecialPageFactory()
|
||||
$services->getSpecialPageFactory(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -534,7 +546,8 @@ return [
|
|||
// T231866: Avoid circular dependency via ResourceLoader.
|
||||
MessageBlobStore::clearGlobalCacheEntry( $services->getMainWANObjectCache() );
|
||||
} ],
|
||||
$services->getLanguageNameUtils()
|
||||
$services->getLanguageNameUtils(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -551,7 +564,10 @@ return [
|
|||
},
|
||||
|
||||
'MagicWordFactory' => function ( MediaWikiServices $services ) : MagicWordFactory {
|
||||
return new MagicWordFactory( $services->getContentLanguage() );
|
||||
return new MagicWordFactory(
|
||||
$services->getContentLanguage(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
'MainConfig' => function ( MediaWikiServices $services ) : Config {
|
||||
|
|
@ -655,7 +671,8 @@ return [
|
|||
$services->getLanguageFactory(),
|
||||
$services->getLocalisationCache(),
|
||||
$services->getLanguageNameUtils(),
|
||||
$services->getLanguageFallback()
|
||||
$services->getLanguageFallback(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -666,12 +683,14 @@ return [
|
|||
'MimeAnalyzer' => function ( MediaWikiServices $services ) : MimeAnalyzer {
|
||||
$logger = LoggerFactory::getInstance( 'Mime' );
|
||||
$mainConfig = $services->getMainConfig();
|
||||
$hookRunner = new HookRunner( $services->getHookContainer() );
|
||||
$params = [
|
||||
'typeFile' => $mainConfig->get( 'MimeTypeFile' ),
|
||||
'infoFile' => $mainConfig->get( 'MimeInfoFile' ),
|
||||
'xmlTypes' => $mainConfig->get( 'XMLMimeTypes' ),
|
||||
'guessCallback' =>
|
||||
function ( $mimeAnalyzer, &$head, &$tail, $file, &$mime ) use ( $logger ) {
|
||||
function ( $mimeAnalyzer, &$head, &$tail, $file, &$mime )
|
||||
use ( $logger, $hookRunner ) {
|
||||
// Also test DjVu
|
||||
$deja = new DjVuImage( $file );
|
||||
if ( $deja->isValid() ) {
|
||||
|
|
@ -681,18 +700,16 @@ return [
|
|||
return;
|
||||
}
|
||||
// Some strings by reference for performance - assuming well-behaved hooks
|
||||
Hooks::run(
|
||||
'MimeMagicGuessFromContent',
|
||||
[ $mimeAnalyzer, &$head, &$tail, $file, &$mime ]
|
||||
);
|
||||
$hookRunner->onMimeMagicGuessFromContent(
|
||||
$mimeAnalyzer, $head, $tail, $file, $mime );
|
||||
},
|
||||
'extCallback' => function ( $mimeAnalyzer, $ext, &$mime ) {
|
||||
'extCallback' => function ( $mimeAnalyzer, $ext, &$mime ) use ( $hookRunner ) {
|
||||
// Media handling extensions can improve the MIME detected
|
||||
Hooks::run( 'MimeMagicImproveFromExtension', [ $mimeAnalyzer, $ext, &$mime ] );
|
||||
$hookRunner->onMimeMagicImproveFromExtension( $mimeAnalyzer, $ext, $mime );
|
||||
},
|
||||
'initCallback' => function ( $mimeAnalyzer ) {
|
||||
'initCallback' => function ( $mimeAnalyzer ) use ( $hookRunner ) {
|
||||
// Allow media handling extensions adding MIME-types and MIME-info
|
||||
Hooks::run( 'MimeMagicInit', [ $mimeAnalyzer ] );
|
||||
$hookRunner->onMimeMagicInit( $mimeAnalyzer );
|
||||
},
|
||||
'logger' => $logger
|
||||
];
|
||||
|
|
@ -726,8 +743,10 @@ return [
|
|||
},
|
||||
|
||||
'NamespaceInfo' => function ( MediaWikiServices $services ) : NamespaceInfo {
|
||||
return new NamespaceInfo( new ServiceOptions( NamespaceInfo::CONSTRUCTOR_OPTIONS,
|
||||
$services->getMainConfig() ) );
|
||||
return new NamespaceInfo(
|
||||
new ServiceOptions( NamespaceInfo::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
'NameTableStoreFactory' => function ( MediaWikiServices $services ) : NameTableStoreFactory {
|
||||
|
|
@ -758,6 +777,7 @@ return [
|
|||
$services->getDBLoadBalancer(),
|
||||
LoggerFactory::getInstance( 'StashEdit' ),
|
||||
$services->getStatsdDataFactory(),
|
||||
$services->getHookContainer(),
|
||||
defined( 'MEDIAWIKI_JOB_RUNNER' ) || $config->get( 'CommandLineMode' )
|
||||
? PageEditStash::INITIATOR_JOB_OR_CLI
|
||||
: PageEditStash::INITIATOR_USER
|
||||
|
|
@ -775,7 +795,8 @@ return [
|
|||
|
||||
return new ParserCache(
|
||||
$cache,
|
||||
$config->get( 'CacheEpoch' )
|
||||
$config->get( 'CacheEpoch' ),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -803,7 +824,8 @@ return [
|
|||
$services->getNamespaceInfo(),
|
||||
LoggerFactory::getInstance( 'Parser' ),
|
||||
$services->getBadFileLookup(),
|
||||
$services->getLanguageConverterFactory()
|
||||
$services->getLanguageConverterFactory(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -822,7 +844,8 @@ return [
|
|||
AuthManager::singleton(),
|
||||
$services->getPermissionManager(),
|
||||
$services->getDBLoadBalancer(),
|
||||
LoggerFactory::getInstance( 'authentication' )
|
||||
LoggerFactory::getInstance( 'authentication' ),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -844,7 +867,8 @@ return [
|
|||
$services->getSpecialPageFactory(),
|
||||
$services->getRevisionLookup(),
|
||||
$services->getNamespaceInfo(),
|
||||
$services->getBlockErrorFormatter()
|
||||
$services->getBlockErrorFormatter(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -858,7 +882,8 @@ return [
|
|||
$services->getNamespaceInfo(),
|
||||
$services->getPermissionManager(),
|
||||
$services->getLanguageConverterFactory()->getLanguageConverter(),
|
||||
$services->getLanguageNameUtils()
|
||||
$services->getLanguageNameUtils(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
$factory->setLogger( LoggerFactory::getInstance( 'preferences' ) );
|
||||
|
||||
|
|
@ -916,7 +941,8 @@ return [
|
|||
// Core modules, then extension/skin modules
|
||||
$rl->register( include "$IP/resources/Resources.php" );
|
||||
$rl->register( $modules );
|
||||
Hooks::run( 'ResourceLoaderRegisterModules', [ &$rl ] );
|
||||
$hookRunner = new HookRunner( $services->getHookContainer() );
|
||||
$hookRunner->onResourceLoaderRegisterModules( $rl );
|
||||
|
||||
$msgPosterAttrib = $extRegistry->getAttribute( 'MessagePosterModule' );
|
||||
$rl->register( 'mediawiki.messagePoster', [
|
||||
|
|
@ -990,7 +1016,8 @@ return [
|
|||
$services->getCommentStore(),
|
||||
$services->getActorMigration(),
|
||||
LoggerFactory::getInstance( 'RevisionStore' ),
|
||||
$services->getContentHandlerFactory()
|
||||
$services->getContentHandlerFactory(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
|
||||
return $store;
|
||||
|
|
@ -1002,12 +1029,16 @@ return [
|
|||
return new SearchEngineConfig(
|
||||
$services->getMainConfig(),
|
||||
$services->getContentLanguage(),
|
||||
$services->getHookContainer(),
|
||||
ExtensionRegistry::getInstance()->getAttribute( 'SearchMappings' )
|
||||
);
|
||||
},
|
||||
|
||||
'SearchEngineFactory' => function ( MediaWikiServices $services ) : SearchEngineFactory {
|
||||
return new SearchEngineFactory( $services->getSearchEngineConfig() );
|
||||
return new SearchEngineFactory(
|
||||
$services->getSearchEngineConfig(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
'ShellCommandFactory' => function ( MediaWikiServices $services ) : CommandFactory {
|
||||
|
|
@ -1112,7 +1143,8 @@ return [
|
|||
new ServiceOptions(
|
||||
SpecialPageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
||||
$services->getContentLanguage(),
|
||||
$services->getObjectFactory()
|
||||
$services->getObjectFactory(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -1169,7 +1201,8 @@ return [
|
|||
$services->getService( 'TitleFactory' ),
|
||||
$messageFormatterFactory->getTextFormatter(
|
||||
$services->getContentLanguage()->getCode()
|
||||
)
|
||||
),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -1183,7 +1216,8 @@ return [
|
|||
$services->get( '_DefaultOptionsLookup' ),
|
||||
$services->getLanguageConverterFactory(),
|
||||
$services->getDBLoadBalancer(),
|
||||
LoggerFactory::getInstance( 'UserOptionsManager' )
|
||||
LoggerFactory::getInstance( 'UserOptionsManager' ),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -1212,6 +1246,7 @@ return [
|
|||
$services->getActorMigration(),
|
||||
$services->getWatchedItemStore(),
|
||||
$services->getPermissionManager(),
|
||||
$services->getHookContainer(),
|
||||
$services->getMainConfig()->get( 'WatchlistExpiry' )
|
||||
);
|
||||
},
|
||||
|
|
@ -1226,7 +1261,8 @@ return [
|
|||
new HashBagOStuff( [ 'maxKeys' => 100 ] ),
|
||||
$services->getReadOnlyMode(),
|
||||
$services->getNamespaceInfo(),
|
||||
$services->getRevisionLookup()
|
||||
$services->getRevisionLookup(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
$store->setStatsdDataFactory( $services->getStatsdDataFactory() );
|
||||
|
||||
|
|
@ -1249,7 +1285,8 @@ return [
|
|||
'_DefaultOptionsLookup' => function ( MediaWikiServices $services ) : DefaultOptionsLookup {
|
||||
return new DefaultOptionsLookup(
|
||||
new ServiceOptions( DefaultOptionsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
|
||||
$services->getContentLanguage()
|
||||
$services->getContentLanguage(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
@ -1273,7 +1310,8 @@ return [
|
|||
$services->getRepoGroup(),
|
||||
$services->getContentHandlerFactory(),
|
||||
$services->getRevisionStore(),
|
||||
$services->getSpamChecker()
|
||||
$services->getSpamChecker(),
|
||||
$services->getHookContainer()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -684,7 +684,7 @@ if ( $wgCommandLineMode ) {
|
|||
$wgMemc = ObjectCache::getLocalClusterInstance();
|
||||
|
||||
// Most of the config is out, some might want to run hooks here.
|
||||
Hooks::run( 'SetupAfterCache' );
|
||||
Hooks::runner()->onSetupAfterCache();
|
||||
|
||||
/**
|
||||
* @var Language $wgContLang
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ use Content;
|
|||
use ContentHandler;
|
||||
use DeferrableUpdate;
|
||||
use DeferredUpdates;
|
||||
use Hooks;
|
||||
use IDBAccessObject;
|
||||
use InvalidArgumentException;
|
||||
use JobQueueGroup;
|
||||
|
|
@ -37,6 +36,8 @@ use LinksUpdate;
|
|||
use LogicException;
|
||||
use MediaWiki\Content\IContentHandlerFactory;
|
||||
use MediaWiki\Edit\PreparedEdit;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Revision\MutableRevisionRecord;
|
||||
use MediaWiki\Revision\RenderedRevision;
|
||||
|
|
@ -141,6 +142,11 @@ class DerivedPageDataUpdater implements IDBAccessObject, LoggerAwareInterface {
|
|||
*/
|
||||
private $loadbalancerFactory;
|
||||
|
||||
/**
|
||||
* @var HookRunner
|
||||
*/
|
||||
private $hookRunner;
|
||||
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
|
|
@ -285,6 +291,7 @@ class DerivedPageDataUpdater implements IDBAccessObject, LoggerAwareInterface {
|
|||
* @param Language $contLang
|
||||
* @param ILBFactory $loadbalancerFactory
|
||||
* @param IContentHandlerFactory $contentHandlerFactory
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
public function __construct(
|
||||
WikiPage $wikiPage,
|
||||
|
|
@ -296,7 +303,8 @@ class DerivedPageDataUpdater implements IDBAccessObject, LoggerAwareInterface {
|
|||
MessageCache $messageCache,
|
||||
Language $contLang,
|
||||
ILBFactory $loadbalancerFactory,
|
||||
IContentHandlerFactory $contentHandlerFactory
|
||||
IContentHandlerFactory $contentHandlerFactory,
|
||||
HookContainer $hookContainer
|
||||
) {
|
||||
$this->wikiPage = $wikiPage;
|
||||
|
||||
|
|
@ -311,6 +319,7 @@ class DerivedPageDataUpdater implements IDBAccessObject, LoggerAwareInterface {
|
|||
// interface for that.
|
||||
$this->loadbalancerFactory = $loadbalancerFactory;
|
||||
$this->contentHandlerFactory = $contentHandlerFactory;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
|
||||
$this->logger = new NullLogger();
|
||||
}
|
||||
|
|
@ -780,7 +789,7 @@ class DerivedPageDataUpdater implements IDBAccessObject, LoggerAwareInterface {
|
|||
}
|
||||
|
||||
$userPopts = ParserOptions::newFromUserAndLang( $user, $this->contLang );
|
||||
Hooks::run( 'ArticlePrepareTextForEdit', [ $wikiPage, $userPopts ] );
|
||||
$this->hookRunner->onArticlePrepareTextForEdit( $wikiPage, $userPopts );
|
||||
|
||||
$this->user = $user;
|
||||
$this->slotsUpdate = $slotsUpdate;
|
||||
|
|
@ -1402,10 +1411,8 @@ class DerivedPageDataUpdater implements IDBAccessObject, LoggerAwareInterface {
|
|||
}
|
||||
|
||||
// TODO: hard deprecate SecondaryDataUpdates in favor of RevisionDataUpdates in 1.33!
|
||||
Hooks::run(
|
||||
'RevisionDataUpdates',
|
||||
[ $this->getTitle(), $renderedRevision, &$allUpdates ]
|
||||
);
|
||||
$this->hookRunner->onRevisionDataUpdates(
|
||||
$this->getTitle(), $renderedRevision, $allUpdates );
|
||||
|
||||
return $allUpdates;
|
||||
}
|
||||
|
|
@ -1476,13 +1483,10 @@ class DerivedPageDataUpdater implements IDBAccessObject, LoggerAwareInterface {
|
|||
// @note: Extensions should *avoid* calling getCannonicalParserOutput() when using
|
||||
// this hook whenever possible in order to avoid unnecessary additional parses.
|
||||
$editInfo = $this->getPreparedEdit();
|
||||
Hooks::run( 'ArticleEditUpdates',
|
||||
[ &$wikiPage, &$editInfo, $this->options['changed'] ],
|
||||
'1.35'
|
||||
);
|
||||
$this->hookRunner->onArticleEditUpdates( $wikiPage, $editInfo, $this->options['changed'] );
|
||||
|
||||
// TODO: replace legacy hook! Use a listener on PageEventEmitter instead!
|
||||
if ( Hooks::run( 'ArticleEditUpdatesDeleteFromRecentchanges', [ &$wikiPage ], '1.35' ) ) {
|
||||
if ( $this->hookRunner->onArticleEditUpdatesDeleteFromRecentchanges( $wikiPage ) ) {
|
||||
// Flush old entries from the `recentchanges` table
|
||||
if ( mt_rand( 0, 9 ) == 0 ) {
|
||||
$this->jobQueueGroup->lazyPush( RecentChangesUpdateJob::newPurgeJob() );
|
||||
|
|
@ -1548,7 +1552,7 @@ class DerivedPageDataUpdater implements IDBAccessObject, LoggerAwareInterface {
|
|||
// Allow extensions to prevent user notification
|
||||
// when a new message is added to their talk page
|
||||
// TODO: replace legacy hook! Use a listener on PageEventEmitter instead!
|
||||
if ( Hooks::run( 'ArticleEditUpdateNewTalk', [ &$wikiPage, $recipient ] ) ) {
|
||||
if ( $this->hookRunner->onArticleEditUpdateNewTalk( $wikiPage, $recipient ) ) {
|
||||
$revRecord = $legacyRevision->getRevisionRecord();
|
||||
$talkPageNotificationManager = MediaWikiServices::getInstance()
|
||||
->getTalkPageNotificationManager();
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@ namespace MediaWiki\Storage;
|
|||
use ActorMigration;
|
||||
use BagOStuff;
|
||||
use Content;
|
||||
use Hooks;
|
||||
use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Storage\Hook\ParserOutputStashForEditHook;
|
||||
use ParserOutput;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use stdClass;
|
||||
|
|
@ -50,6 +52,8 @@ class PageEditStash {
|
|||
private $logger;
|
||||
/** @var StatsdDataFactoryInterface */
|
||||
private $stats;
|
||||
/** @var ParserOutputStashForEditHook */
|
||||
private $hookRunner;
|
||||
/** @var int */
|
||||
private $initiator;
|
||||
|
||||
|
|
@ -73,6 +77,7 @@ class PageEditStash {
|
|||
* @param ILoadBalancer $lb
|
||||
* @param LoggerInterface $logger
|
||||
* @param StatsdDataFactoryInterface $stats
|
||||
* @param HookContainer $hookContainer
|
||||
* @param int $initiator Class INITIATOR__* constant
|
||||
*/
|
||||
public function __construct(
|
||||
|
|
@ -80,12 +85,14 @@ class PageEditStash {
|
|||
ILoadBalancer $lb,
|
||||
LoggerInterface $logger,
|
||||
StatsdDataFactoryInterface $stats,
|
||||
HookContainer $hookContainer,
|
||||
$initiator
|
||||
) {
|
||||
$this->cache = $cache;
|
||||
$this->lb = $lb;
|
||||
$this->logger = $logger;
|
||||
$this->stats = $stats;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
$this->initiator = $initiator;
|
||||
}
|
||||
|
||||
|
|
@ -136,8 +143,8 @@ class PageEditStash {
|
|||
|
||||
if ( $editInfo && $editInfo->output ) {
|
||||
// Let extensions add ParserOutput metadata or warm other caches
|
||||
Hooks::run( 'ParserOutputStashForEdit',
|
||||
[ $page, $content, $editInfo->output, $summary, $user ] );
|
||||
$this->hookRunner->onParserOutputStashForEdit(
|
||||
$page, $content, $editInfo->output, $summary, $user );
|
||||
|
||||
if ( $alreadyCached ) {
|
||||
$logger->debug( "Parser output for key '{cachekey}' already cached.", $context );
|
||||
|
|
|
|||
|
|
@ -30,11 +30,12 @@ use CommentStoreComment;
|
|||
use Content;
|
||||
use ContentHandler;
|
||||
use DeferredUpdates;
|
||||
use Hooks;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use ManualLogEntry;
|
||||
use MediaWiki\Content\IContentHandlerFactory;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Linker\LinkTarget;
|
||||
use MediaWiki\Revision\MutableRevisionRecord;
|
||||
use MediaWiki\Revision\RevisionAccessException;
|
||||
|
|
@ -109,6 +110,16 @@ class PageUpdater {
|
|||
*/
|
||||
private $contentHandlerFactory;
|
||||
|
||||
/**
|
||||
* @var HookRunner
|
||||
*/
|
||||
private $hookRunner;
|
||||
|
||||
/**
|
||||
* @var HookContainer
|
||||
*/
|
||||
private $hookContainer;
|
||||
|
||||
/**
|
||||
* @var boolean see $wgUseAutomaticEditSummaries
|
||||
* @see $wgUseAutomaticEditSummaries
|
||||
|
|
@ -163,6 +174,7 @@ class PageUpdater {
|
|||
* @param RevisionStore $revisionStore
|
||||
* @param SlotRoleRegistry $slotRoleRegistry
|
||||
* @param IContentHandlerFactory $contentHandlerFactory
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
public function __construct(
|
||||
User $user,
|
||||
|
|
@ -171,7 +183,8 @@ class PageUpdater {
|
|||
ILoadBalancer $loadBalancer,
|
||||
RevisionStore $revisionStore,
|
||||
SlotRoleRegistry $slotRoleRegistry,
|
||||
IContentHandlerFactory $contentHandlerFactory
|
||||
IContentHandlerFactory $contentHandlerFactory,
|
||||
HookContainer $hookContainer
|
||||
) {
|
||||
$this->user = $user;
|
||||
$this->wikiPage = $wikiPage;
|
||||
|
|
@ -181,6 +194,8 @@ class PageUpdater {
|
|||
$this->revisionStore = $revisionStore;
|
||||
$this->slotRoleRegistry = $slotRoleRegistry;
|
||||
$this->contentHandlerFactory = $contentHandlerFactory;
|
||||
$this->hookContainer = $hookContainer;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
|
||||
$this->slotsUpdate = new RevisionSlotsUpdate();
|
||||
}
|
||||
|
|
@ -735,22 +750,20 @@ class PageUpdater {
|
|||
// Trigger pre-save hook (using provided edit summary)
|
||||
$renderedRevision = $this->derivedDataUpdater->getRenderedRevision();
|
||||
$hookStatus = Status::newGood( [] );
|
||||
$allowedByHook = Hooks::run( 'MultiContentSave', [
|
||||
$allowedByHook = $this->hookRunner->onMultiContentSave(
|
||||
$renderedRevision, $user, $summary, $flags, $hookStatus
|
||||
] );
|
||||
if ( $allowedByHook && Hooks::isRegistered( 'PageContentSave' ) ) {
|
||||
);
|
||||
if ( $allowedByHook && $this->hookContainer->isRegistered( 'PageContentSave' ) ) {
|
||||
// Also run the legacy hook.
|
||||
// TODO: avoid pass-by-reference, see T193950
|
||||
// NOTE: WikiPage should only be used for the legacy hook,
|
||||
// and only if something uses the legacy hook.
|
||||
$mainContent = $this->derivedDataUpdater->getSlots()->getContent( SlotRecord::MAIN );
|
||||
$wikiPage = $this->getWikiPage();
|
||||
|
||||
// Deprecated since 1.35.
|
||||
$allowedByHook = Hooks::run( 'PageContentSave', [
|
||||
&$wikiPage, &$user, &$mainContent, &$summary,
|
||||
$flags & EDIT_MINOR, null, null, &$flags, &$hookStatus
|
||||
] );
|
||||
$allowedByHook = $this->hookRunner->onPageContentSave(
|
||||
$this->getWikiPage(), $user, $mainContent, $summary,
|
||||
$flags & EDIT_MINOR, null, null, $flags, $hookStatus
|
||||
);
|
||||
}
|
||||
|
||||
if ( !$allowedByHook ) {
|
||||
|
|
@ -1034,17 +1047,14 @@ class PageUpdater {
|
|||
}
|
||||
|
||||
$tags = $this->computeEffectiveTags( $flags );
|
||||
Hooks::run(
|
||||
'RevisionFromEditComplete',
|
||||
[ $wikiPage, $newRevisionRecord, $this->getOriginalRevisionId(), $user, &$tags ]
|
||||
$this->hookRunner->onRevisionFromEditComplete(
|
||||
$wikiPage, $newRevisionRecord, $this->getOriginalRevisionId(), $user, $tags
|
||||
);
|
||||
|
||||
// TODO: replace legacy hook!
|
||||
$newLegacyRevision = new Revision( $newRevisionRecord );
|
||||
Hooks::run(
|
||||
'NewRevisionFromEditComplete',
|
||||
[ $wikiPage, $newLegacyRevision, $this->getOriginalRevisionId(), $user, &$tags ]
|
||||
);
|
||||
$this->hookRunner->onNewRevisionFromEditComplete(
|
||||
$wikiPage, $newLegacyRevision, $this->getOriginalRevisionId(), $user, $tags );
|
||||
|
||||
// Update recentchanges
|
||||
if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
|
||||
|
|
@ -1173,17 +1183,14 @@ class PageUpdater {
|
|||
}
|
||||
|
||||
$tags = $this->computeEffectiveTags( $flags );
|
||||
Hooks::run(
|
||||
'RevisionFromEditComplete',
|
||||
[ $wikiPage, $newRevisionRecord, false, $user, &$tags ]
|
||||
$this->hookRunner->onRevisionFromEditComplete(
|
||||
$wikiPage, $newRevisionRecord, false, $user, $tags
|
||||
);
|
||||
|
||||
// TODO: replace legacy hook!
|
||||
$newLegacyRevision = new Revision( $newRevisionRecord );
|
||||
Hooks::run(
|
||||
'NewRevisionFromEditComplete',
|
||||
[ $wikiPage, $newLegacyRevision, false, $user, &$tags ]
|
||||
);
|
||||
$this->hookRunner->onNewRevisionFromEditComplete(
|
||||
$wikiPage, $newLegacyRevision, false, $user, $tags );
|
||||
|
||||
// Update recentchanges
|
||||
if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
|
||||
|
|
@ -1274,20 +1281,19 @@ class PageUpdater {
|
|||
$this->derivedDataUpdater->doUpdates();
|
||||
|
||||
// TODO: replace legacy hook!
|
||||
// TODO: avoid pass-by-reference, see T193950
|
||||
|
||||
if ( $hints['created'] ?? false ) {
|
||||
// Trigger post-create hook
|
||||
Hooks::run( 'PageContentInsertComplete', [ &$wikiPage, &$user,
|
||||
$mainContent, $summary->text, $flags & EDIT_MINOR, null, null,
|
||||
&$flags, $newLegacyRevision ] );
|
||||
$this->hookRunner->onPageContentInsertComplete( $wikiPage, $user,
|
||||
$mainContent, $summary->text, $flags & EDIT_MINOR,
|
||||
null, null, $flags, $newLegacyRevision );
|
||||
}
|
||||
|
||||
// Trigger post-save hook
|
||||
Hooks::run( 'PageContentSaveComplete', [ &$wikiPage, &$user,
|
||||
$mainContent, $summary->text, $flags & EDIT_MINOR, null, null,
|
||||
&$flags, $newLegacyRevision,
|
||||
&$status, $this->getOriginalRevisionId(), $this->undidRevId ] );
|
||||
$this->hookRunner->onPageContentSaveComplete( $wikiPage, $user, $mainContent,
|
||||
$summary->text, $flags & EDIT_MINOR, null,
|
||||
null, $flags, $newLegacyRevision, $status,
|
||||
$this->getOriginalRevisionId(), $this->undidRevId );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1364,7 +1364,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
}
|
||||
|
||||
$result = true;
|
||||
Hooks::run( 'TitleIsMovable', [ $this, &$result ] );
|
||||
Hooks::runner()->onTitleIsMovable( $this, $result );
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
|
@ -2114,9 +2114,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
|
||||
# Finally, add the fragment.
|
||||
$url .= $this->getFragmentForURL();
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$titleRef = $this;
|
||||
Hooks::run( 'GetFullURL', [ &$titleRef, &$url, $query ] );
|
||||
Hooks::runner()->onGetFullURL( $this, $url, $query );
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
|
@ -2189,9 +2187,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
$dbkey = wfUrlencode( $this->getPrefixedDBkey() );
|
||||
if ( $query == '' ) {
|
||||
$url = str_replace( '$1', $dbkey, $wgArticlePath );
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$titleRef = $this;
|
||||
Hooks::run( 'GetLocalURL::Article', [ &$titleRef, &$url ] );
|
||||
Hooks::runner()->onGetLocalURL__Article( $this, $url );
|
||||
} else {
|
||||
global $wgVariantArticlePath, $wgActionPaths;
|
||||
$url = false;
|
||||
|
|
@ -2238,9 +2234,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
$url = "{$wgScript}?title={$dbkey}&{$query}";
|
||||
}
|
||||
}
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$titleRef = $this;
|
||||
Hooks::run( 'GetLocalURL::Internal', [ &$titleRef, &$url, $query ] );
|
||||
Hooks::runner()->onGetLocalURL__Internal( $this, $url, $query );
|
||||
|
||||
// @todo FIXME: This causes breakage in various places when we
|
||||
// actually expected a local URL and end up with dupe prefixes.
|
||||
|
|
@ -2253,9 +2247,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
return '/';
|
||||
}
|
||||
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$titleRef = $this;
|
||||
Hooks::run( 'GetLocalURL', [ &$titleRef, &$url, $query ] );
|
||||
Hooks::runner()->onGetLocalURL( $this, $url, $query );
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
|
@ -2306,9 +2298,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
$query = self::fixUrlQueryArgs( $query, $query2 );
|
||||
$server = $wgInternalServer !== false ? $wgInternalServer : $wgServer;
|
||||
$url = wfExpandUrl( $server . $this->getLocalURL( $query ), PROTO_HTTP );
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$titleRef = $this;
|
||||
Hooks::run( 'GetInternalURL', [ &$titleRef, &$url, $query ] );
|
||||
Hooks::runner()->onGetInternalURL( $this, $url, $query );
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
|
@ -2328,9 +2318,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
public function getCanonicalURL( $query = '', $query2 = false ) {
|
||||
$query = self::fixUrlQueryArgs( $query, $query2 );
|
||||
$url = wfExpandUrl( $this->getLocalURL( $query ) . $this->getFragmentForURL(), PROTO_CANONICAL );
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$titleRef = $this;
|
||||
Hooks::run( 'GetCanonicalURL', [ &$titleRef, &$url, $query ] );
|
||||
Hooks::runner()->onGetCanonicalURL( $this, $url, $query );
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
|
@ -2485,7 +2473,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
$types = array_diff( $types, [ 'upload' ] );
|
||||
}
|
||||
|
||||
Hooks::run( 'TitleGetRestrictionTypes', [ $this, &$types ] );
|
||||
Hooks::runner()->onTitleGetRestrictionTypes( $this, $types );
|
||||
|
||||
wfDebug( __METHOD__ . ': applicable restrictions to [[' .
|
||||
$this->getPrefixedText() . ']] are {' . implode( ',', $types ) . "}\n" );
|
||||
|
|
@ -3955,7 +3943,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
*/
|
||||
public function exists( $flags = 0 ) {
|
||||
$exists = $this->getArticleID( $flags ) != 0;
|
||||
Hooks::run( 'TitleExists', [ $this, &$exists ] );
|
||||
Hooks::runner()->onTitleExists( $this, $exists );
|
||||
return $exists;
|
||||
}
|
||||
|
||||
|
|
@ -3988,7 +3976,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
* @param Title $title
|
||||
* @param bool|null $isKnown
|
||||
*/
|
||||
Hooks::run( 'TitleIsAlwaysKnown', [ $this, &$isKnown ] );
|
||||
Hooks::runner()->onTitleIsAlwaysKnown( $this, $isKnown );
|
||||
|
||||
if ( $isKnown !== null ) {
|
||||
return $isKnown;
|
||||
|
|
@ -4360,7 +4348,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
// on the Title object passed in, and should probably
|
||||
// tell the users to run updateCollations.php --force
|
||||
// in order to re-sort existing category relations.
|
||||
Hooks::run( 'GetDefaultSortkey', [ $this, &$unprefixed ] );
|
||||
Hooks::runner()->onGetDefaultSortkey( $this, $unprefixed );
|
||||
if ( $prefix !== '' ) {
|
||||
# Separate with a line feed, so the unprefixed part is only used as
|
||||
# a tiebreaker when two pages have the exact same prefix.
|
||||
|
|
@ -4556,7 +4544,7 @@ class Title implements LinkTarget, IDBAccessObject {
|
|||
}
|
||||
}
|
||||
|
||||
Hooks::run( 'TitleGetEditNotices', [ $this, $oldid, &$notices ] );
|
||||
Hooks::runner()->onTitleGetEditNotices( $this, $oldid, $notices );
|
||||
return $notices;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ abstract class TitleArray implements Iterator {
|
|||
*/
|
||||
public static function newFromResult( $res ) {
|
||||
$array = null;
|
||||
if ( !Hooks::run( 'TitleArrayFromResult', [ &$array, $res ] ) ) {
|
||||
if ( !Hooks::runner()->onTitleArrayFromResult( $array, $res ) ) {
|
||||
return null;
|
||||
}
|
||||
return $array ?? new TitleArrayFromResult( $res );
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ class WebRequest {
|
|||
);
|
||||
}
|
||||
|
||||
Hooks::run( 'WebRequestPathInfoRouter', [ $router ] );
|
||||
Hooks::runner()->onWebRequestPathInfoRouter( $router );
|
||||
|
||||
$matches = $router->parse( $path );
|
||||
} else {
|
||||
|
|
@ -1305,7 +1305,7 @@ class WebRequest {
|
|||
}
|
||||
|
||||
# Allow extensions to improve our guess
|
||||
Hooks::run( 'GetIP', [ &$ip ] );
|
||||
Hooks::runner()->onGetIP( $ip );
|
||||
|
||||
if ( !$ip ) {
|
||||
throw new MWException( "Unable to determine IP." );
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ class WebResponse {
|
|||
|
||||
$func = $options['raw'] ? 'setrawcookie' : 'setcookie';
|
||||
|
||||
if ( Hooks::run( 'WebResponseSetCookie', [ &$name, &$value, &$expire, &$options ] ) ) {
|
||||
if ( Hooks::runner()->onWebResponseSetCookie( $name, $value, $expire, $options ) ) {
|
||||
// Note: Don't try to move this earlier to reuse it for self::$disableForPostSend,
|
||||
// we need to use the altered values from the hook here. (T198525)
|
||||
$cookie = $options['prefix'] . $name;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
/**
|
||||
|
|
@ -308,6 +310,24 @@ abstract class Action implements MessageLocalizer {
|
|||
return $this->getContext()->msg( $key, ...$params );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.35
|
||||
* @return HookContainer
|
||||
*/
|
||||
protected function getHookContainer() {
|
||||
return MediaWikiServices::getInstance()->getHookContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.35
|
||||
* @internal This is for use by core only. Hook interfaces may be removed
|
||||
* without notice.
|
||||
* @return HookRunner
|
||||
*/
|
||||
protected function getHookRunner() {
|
||||
return new HookRunner( $this->getHookContainer() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Only public since 1.21
|
||||
*
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class EditAction extends FormlessAction {
|
|||
}
|
||||
|
||||
$article = $this->getArticle();
|
||||
if ( Hooks::run( 'CustomEditor', [ $article, $this->getUser() ] ) ) {
|
||||
if ( $this->getHookRunner()->onCustomEditor( $article, $this->getUser() ) ) {
|
||||
$editor = new EditPage( $article );
|
||||
$editor->setContextTitle( $this->getTitle() );
|
||||
$editor->edit();
|
||||
|
|
|
|||
|
|
@ -74,13 +74,10 @@ abstract class FormAction extends Action {
|
|||
$this->fields = $this->getFormFields();
|
||||
|
||||
// Give hooks a chance to alter the form, adding extra fields or text etc
|
||||
Hooks::run(
|
||||
'ActionModifyFormFields',
|
||||
[
|
||||
$this->getName(),
|
||||
&$this->fields,
|
||||
$this->getArticle()
|
||||
]
|
||||
$this->getHookRunner()->onActionModifyFormFields(
|
||||
$this->getName(),
|
||||
$this->fields,
|
||||
$this->getArticle()
|
||||
);
|
||||
|
||||
if ( $this->usesOOUI() ) {
|
||||
|
|
@ -106,11 +103,11 @@ abstract class FormAction extends Action {
|
|||
$this->alterForm( $form );
|
||||
|
||||
// Give hooks a chance to alter the form, adding extra fields or text etc
|
||||
Hooks::run( 'ActionBeforeFormDisplay', [
|
||||
$this->getHookRunner()->onActionBeforeFormDisplay(
|
||||
$this->getName(),
|
||||
&$form,
|
||||
$form,
|
||||
$this->getArticle()
|
||||
] );
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class HistoryAction extends FormlessAction {
|
|||
|
||||
$links = [];
|
||||
// Allow extensions to add more links
|
||||
Hooks::run( 'HistoryPageToolLinks', [ $this->getContext(), $linkRenderer, &$links ] );
|
||||
$this->getHookRunner()->onHistoryPageToolLinks( $this->getContext(), $linkRenderer, $links );
|
||||
if ( $links ) {
|
||||
$subtitle .= ''
|
||||
. $this->msg( 'word-separator' )->escaped()
|
||||
|
|
@ -283,13 +283,9 @@ class HistoryAction extends FormlessAction {
|
|||
|
||||
$out->addHTML( $htmlForm->getHTML( false ) );
|
||||
|
||||
$article = $this->getArticle(); // must be a variable for hook reference
|
||||
Hooks::run(
|
||||
'PageHistoryBeforeList',
|
||||
[
|
||||
&$article,
|
||||
$this->getContext()
|
||||
]
|
||||
$this->getHookRunner()->onPageHistoryBeforeList(
|
||||
$this->getArticle(),
|
||||
$this->getContext()
|
||||
);
|
||||
|
||||
// Create and output the list.
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ class InfoAction extends FormlessAction {
|
|||
$pageInfo = $this->pageInfo();
|
||||
|
||||
// Allow extensions to add additional information
|
||||
Hooks::run( 'InfoAction', [ $this->getContext(), &$pageInfo ] );
|
||||
$this->getHookRunner()->onInfoAction( $this->getContext(), $pageInfo );
|
||||
|
||||
// Render page information
|
||||
foreach ( $pageInfo as $header => $infoTable ) {
|
||||
|
|
|
|||
|
|
@ -164,9 +164,7 @@ class RawAction extends FormlessAction {
|
|||
$response->statusHeader( 404 );
|
||||
}
|
||||
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$rawAction = $this;
|
||||
if ( !Hooks::run( 'RawPageViewBeforeOutput', [ &$rawAction, &$text ] ) ) {
|
||||
if ( !$this->getHookRunner()->onRawPageViewBeforeOutput( $this, $text ) ) {
|
||||
wfDebug( __METHOD__ . ": RawPageViewBeforeOutput hook broke raw page output.\n" );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -212,10 +212,10 @@ class WatchAction extends FormAction {
|
|||
$page = WikiPage::factory( $title );
|
||||
|
||||
$status = Status::newFatal( 'hookaborted' );
|
||||
if ( Hooks::run( 'WatchArticle', [ &$user, &$page, &$status, $expiry ] ) ) {
|
||||
if ( Hooks::runner()->onWatchArticle( $user, $page, $status, $expiry ) ) {
|
||||
$status = Status::newGood();
|
||||
$user->addWatch( $title, $checkRights, $expiry );
|
||||
Hooks::run( 'WatchArticleComplete', [ &$user, &$page ] );
|
||||
Hooks::runner()->onWatchArticleComplete( $user, $page );
|
||||
}
|
||||
|
||||
return $status;
|
||||
|
|
@ -238,10 +238,10 @@ class WatchAction extends FormAction {
|
|||
$page = WikiPage::factory( $title );
|
||||
|
||||
$status = Status::newFatal( 'hookaborted' );
|
||||
if ( Hooks::run( 'UnwatchArticle', [ &$user, &$page, &$status ] ) ) {
|
||||
if ( Hooks::runner()->onUnwatchArticle( $user, $page, $status ) ) {
|
||||
$status = Status::newGood();
|
||||
$user->removeWatch( $title );
|
||||
Hooks::run( 'UnwatchArticleComplete', [ &$user, &$page ] );
|
||||
Hooks::runner()->onUnwatchArticleComplete( $user, $page );
|
||||
}
|
||||
|
||||
return $status;
|
||||
|
|
|
|||
|
|
@ -112,9 +112,7 @@ class HistoryPager extends ReverseChronologicalPager {
|
|||
$this->tagFilter
|
||||
);
|
||||
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$historyPager = $this;
|
||||
Hooks::run( 'PageHistoryPager::getQueryInfo', [ &$historyPager, &$queryInfo ] );
|
||||
$this->getHookRunner()->onPageHistoryPager__getQueryInfo( $this, $queryInfo );
|
||||
|
||||
return $queryInfo;
|
||||
}
|
||||
|
|
@ -146,7 +144,7 @@ class HistoryPager extends ReverseChronologicalPager {
|
|||
}
|
||||
|
||||
protected function doBatchLookups() {
|
||||
if ( !Hooks::run( 'PageHistoryPager::doBatchLookups', [ $this, $this->mResult ] ) ) {
|
||||
if ( !$this->getHookRunner()->onPageHistoryPager__doBatchLookups( $this, $this->mResult ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -482,12 +480,12 @@ class HistoryPager extends ReverseChronologicalPager {
|
|||
}
|
||||
// Allow extension to add their own links here
|
||||
// TODO replace hook with one using RevisionRecord
|
||||
Hooks::run( 'HistoryRevisionTools', [
|
||||
$this->getHookRunner()->onHistoryRevisionTools(
|
||||
new Revision( $revRecord ),
|
||||
&$tools,
|
||||
$tools,
|
||||
$previousRevRecord ? new Revision( $previousRevRecord ) : null,
|
||||
$user
|
||||
] );
|
||||
);
|
||||
|
||||
if ( $tools ) {
|
||||
$s2 .= ' ' . Html::openElement( 'span', [ 'class' => 'mw-changeslist-links' ] );
|
||||
|
|
@ -515,7 +513,7 @@ class HistoryPager extends ReverseChronologicalPager {
|
|||
|
||||
$attribs = [ 'data-mw-revid' => $revRecord->getId() ];
|
||||
|
||||
Hooks::run( 'PageHistoryLineEnding', [ $this, &$row, &$s, &$classes, &$attribs ] );
|
||||
$this->getHookRunner()->onPageHistoryLineEnding( $this, $row, $s, $classes, $attribs );
|
||||
$attribs = array_filter( $attribs,
|
||||
[ Sanitizer::class, 'isReservedDataAttribute' ],
|
||||
ARRAY_FILTER_USE_KEY
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
use MediaWiki\Api\ApiHookRunner;
|
||||
use MediaWiki\Api\Validator\SubmoduleDef;
|
||||
use MediaWiki\Block\AbstractBlock;
|
||||
use MediaWiki\Block\DatabaseBlock;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\Linker\LinkTarget;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\ParamValidator\TypeDef\NamespaceDef;
|
||||
|
|
@ -49,6 +51,12 @@ abstract class ApiBase extends ContextSource {
|
|||
|
||||
use ApiBlockInfoTrait;
|
||||
|
||||
/** @var HookContainer */
|
||||
private $hookContainer;
|
||||
|
||||
/** @var ApiHookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/**
|
||||
* @name Old constants for ::getAllowedParams() arrays
|
||||
* @deprecated since 1.35, use the equivalent ParamValidator or TypeDef constants instead.
|
||||
|
|
@ -609,6 +617,34 @@ abstract class ApiBase extends ContextSource {
|
|||
return MediaWikiServices::getInstance()->getPermissionManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a HookContainer, for running extension hooks or for hook metadata.
|
||||
*
|
||||
* @since 1.35
|
||||
* @return HookContainer
|
||||
*/
|
||||
protected function getHookContainer() {
|
||||
if ( !$this->hookContainer ) {
|
||||
$this->hookContainer = MediaWikiServices::getInstance()->getHookContainer();
|
||||
}
|
||||
return $this->hookContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an ApiHookRunner for running core API hooks.
|
||||
*
|
||||
* @internal This is for use by core only. Hook interfaces may be removed
|
||||
* without notice.
|
||||
* @since 1.35
|
||||
* @return ApiHookRunner
|
||||
*/
|
||||
protected function getHookRunner() {
|
||||
if ( !$this->hookRunner ) {
|
||||
$this->hookRunner = new ApiHookRunner( $this->getHookContainer() );
|
||||
}
|
||||
return $this->hookRunner;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/************************************************************************//**
|
||||
|
|
@ -1320,7 +1356,7 @@ abstract class ApiBase extends ContextSource {
|
|||
// No real need to deduplicate here, ApiErrorFormatter does that for
|
||||
// us (assuming the hook is deterministic).
|
||||
$msgs = [ $this->msg( 'api-usage-mailinglist-ref' ) ];
|
||||
Hooks::run( 'ApiDeprecationHelp', [ &$msgs ] );
|
||||
$this->getHookRunner()->onApiDeprecationHelp( $msgs );
|
||||
if ( count( $msgs ) > 1 ) {
|
||||
$key = '$' . implode( ' $', range( 1, count( $msgs ) ) );
|
||||
$msg = ( new RawMessage( $key ) )->params( $msgs );
|
||||
|
|
@ -1682,7 +1718,7 @@ abstract class ApiBase extends ContextSource {
|
|||
|
||||
$msgs = [ $summary, $extendedDescription ];
|
||||
|
||||
Hooks::run( 'APIGetDescriptionMessages', [ $this, &$msgs ] );
|
||||
$this->getHookRunner()->onAPIGetDescriptionMessages( $this, $msgs );
|
||||
|
||||
return $msgs;
|
||||
}
|
||||
|
|
@ -1714,9 +1750,7 @@ abstract class ApiBase extends ContextSource {
|
|||
] + ( $params['token'] ?? [] );
|
||||
}
|
||||
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$apiModule = $this;
|
||||
Hooks::run( 'APIGetAllowedParams', [ &$apiModule, &$params, $flags ] );
|
||||
$this->getHookRunner()->onAPIGetAllowedParams( $this, $params, $flags );
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
|
@ -1860,7 +1894,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
}
|
||||
|
||||
Hooks::run( 'APIGetParamDescriptionMessages', [ $this, &$msgs ] );
|
||||
$this->getHookRunner()->onAPIGetParamDescriptionMessages( $this, $msgs );
|
||||
|
||||
return $msgs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class ApiChangeAuthenticationData extends ApiBase {
|
|||
|
||||
// Make the change
|
||||
$status = $manager->allowsAuthenticationDataChange( $req, true );
|
||||
Hooks::run( 'ChangeAuthenticationDataAudit', [ $req, $status ] );
|
||||
$this->getHookRunner()->onChangeAuthenticationDataAudit( $req, $status );
|
||||
if ( !$status->isGood() ) {
|
||||
$this->dieStatus( $status );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,8 +90,8 @@ class ApiExpandTemplates extends ApiBase {
|
|||
|
||||
$reset = null;
|
||||
$suppressCache = false;
|
||||
Hooks::run( 'ApiMakeParserOptions',
|
||||
[ $options, $titleObj, $params, $this, &$reset, &$suppressCache ] );
|
||||
$this->getHookRunner()->onApiMakeParserOptions(
|
||||
$options, $titleObj, $params, $this, $reset, $suppressCache );
|
||||
|
||||
$retval = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -132,10 +132,8 @@ class ApiFeedContributions extends ApiBase {
|
|||
// ContributionsLineEnding hook. Hook implementers may cancel
|
||||
// the hook to signal the user is not allowed to read this item.
|
||||
$feedItem = null;
|
||||
$hookResult = Hooks::run(
|
||||
'ApiFeedContributions::feedItem',
|
||||
[ $row, $this->getContext(), &$feedItem ]
|
||||
);
|
||||
$hookResult = $this->getHookRunner()->onApiFeedContributions__feedItem(
|
||||
$row, $this->getContext(), $feedItem );
|
||||
// Hook returned a valid feed item
|
||||
if ( $feedItem instanceof FeedItem ) {
|
||||
return $feedItem;
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
}
|
||||
}
|
||||
|
||||
if ( Hooks::run( 'ApiFormatHighlight', [ $context, $result, $mime, $format ] ) ) {
|
||||
if ( $this->getHookRunner()->onApiFormatHighlight( $context, $result, $mime, $format ) ) {
|
||||
$out->addHTML(
|
||||
Html::element( 'pre', [ 'class' => 'api-pretty-content' ], $result )
|
||||
);
|
||||
|
|
|
|||
|
|
@ -620,7 +620,8 @@ class ApiHelp extends ApiBase {
|
|||
|
||||
$module->modifyHelp( $help, $suboptions, $haveModules );
|
||||
|
||||
Hooks::run( 'APIHelpModifyOutput', [ $module, &$help, $suboptions, &$haveModules ] );
|
||||
$module->getHookRunner()->onAPIHelpModifyOutput( $module, $help,
|
||||
$suboptions, $haveModules );
|
||||
|
||||
$out .= implode( "\n", $help );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ class ApiImport extends ApiBase {
|
|||
*/
|
||||
public function getAllowedImportSources() {
|
||||
$importSources = $this->getConfig()->get( 'ImportSources' );
|
||||
Hooks::run( 'ImportSources', [ &$importSources ] );
|
||||
$this->getHookRunner()->onImportSources( $importSources );
|
||||
|
||||
$result = [];
|
||||
foreach ( $importSources as $key => $value ) {
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ class ApiLogin extends ApiBase {
|
|||
|
||||
// Deprecated hook
|
||||
$injected_html = '';
|
||||
Hooks::run( 'UserLoginComplete', [ &$user, &$injected_html, true ] );
|
||||
$this->getHookRunner()->onUserLoginComplete( $user, $injected_html, true );
|
||||
|
||||
$result['lguserid'] = (int)$user->getId();
|
||||
$result['lgusername'] = $user->getName();
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class ApiLogout extends ApiBase {
|
|||
|
||||
// Give extensions to do something after user logout
|
||||
$injected_html = '';
|
||||
Hooks::run( 'UserLogoutComplete', [ &$user, &$injected_html, $oldName ] );
|
||||
$this->getHookRunner()->onUserLogoutComplete( $user, $injected_html, $oldName );
|
||||
}
|
||||
|
||||
public function mustBePosted() {
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ class ApiMain extends ApiBase {
|
|||
$this->mModuleMgr->addModules( self::$Formats, 'format' );
|
||||
$this->mModuleMgr->addModules( $config->get( 'APIFormatModules' ), 'format' );
|
||||
|
||||
Hooks::run( 'ApiMain::moduleManager', [ $this->mModuleMgr ] );
|
||||
$this->getHookRunner()->onApiMain__moduleManager( $this->mModuleMgr );
|
||||
|
||||
$this->mContinuationManager = null;
|
||||
$this->mEnableWrite = $enableWrite;
|
||||
|
|
@ -324,7 +324,8 @@ class ApiMain extends ApiBase {
|
|||
}
|
||||
|
||||
// Allow extensions to override.
|
||||
$this->lacksSameOriginSecurity = !Hooks::run( 'RequestHasSameOriginSecurity', [ $request ] );
|
||||
$this->lacksSameOriginSecurity = !$this->getHookRunner()
|
||||
->onRequestHasSameOriginSecurity( $request );
|
||||
return $this->lacksSameOriginSecurity;
|
||||
}
|
||||
|
||||
|
|
@ -576,7 +577,7 @@ class ApiMain extends ApiBase {
|
|||
}
|
||||
|
||||
// Allow extra cleanup and logging
|
||||
Hooks::run( 'ApiMain::onException', [ $this, $e ] );
|
||||
$this->getHookRunner()->onApiMain__onException( $this, $e );
|
||||
|
||||
// Handle any kind of exception by outputting properly formatted error message.
|
||||
// If this fails, an unhandled exception should be thrown so that global error
|
||||
|
|
@ -1234,7 +1235,7 @@ class ApiMain extends ApiBase {
|
|||
}
|
||||
}
|
||||
|
||||
Hooks::runWithoutAbort( 'ApiMaxLagInfo', [ &$lagInfo ] );
|
||||
$this->getHookRunner()->onApiMaxLagInfo( $lagInfo );
|
||||
|
||||
return $lagInfo;
|
||||
}
|
||||
|
|
@ -1361,7 +1362,7 @@ class ApiMain extends ApiBase {
|
|||
TS_MW, time() - $config->get( 'CdnMaxAge' )
|
||||
);
|
||||
}
|
||||
Hooks::run( 'OutputPageCheckLastModified', [ &$modifiedTimes, $this->getOutput() ] );
|
||||
$this->getHookRunner()->onOutputPageCheckLastModified( $modifiedTimes, $this->getOutput() );
|
||||
$lastMod = max( $modifiedTimes );
|
||||
$return304 = wfTimestamp( TS_MW, $lastMod ) <= $ts->getTimestamp( TS_MW );
|
||||
}
|
||||
|
|
@ -1413,7 +1414,7 @@ class ApiMain extends ApiBase {
|
|||
|
||||
// Allow extensions to stop execution for arbitrary reasons.
|
||||
$message = 'hookaborted';
|
||||
if ( !Hooks::run( 'ApiCheckCanExecute', [ $module, $user, &$message ] ) ) {
|
||||
if ( !$this->getHookRunner()->onApiCheckCanExecute( $module, $user, $message ) ) {
|
||||
$this->dieWithError( $message );
|
||||
}
|
||||
}
|
||||
|
|
@ -1581,7 +1582,7 @@ class ApiMain extends ApiBase {
|
|||
}
|
||||
|
||||
$module->execute();
|
||||
Hooks::run( 'APIAfterExecute', [ &$module ] );
|
||||
$this->getHookRunner()->onAPIAfterExecute( $module );
|
||||
|
||||
$this->reportUnusedParams();
|
||||
|
||||
|
|
|
|||
|
|
@ -91,12 +91,11 @@ class ApiOpenSearch extends ApiBase {
|
|||
$results = $this->search( $search, $params );
|
||||
|
||||
// Allow hooks to populate extracts and images
|
||||
Hooks::run( 'ApiOpenSearchSuggest', [ &$results ] );
|
||||
$this->getHookRunner()->onApiOpenSearchSuggest( $results );
|
||||
|
||||
// Trim extracts, if necessary
|
||||
$length = $this->getConfig()->get( 'OpenSearchDescriptionLength' );
|
||||
foreach ( $results as &$r ) {
|
||||
// @phan-suppress-next-line PhanTypeInvalidDimOffset
|
||||
if ( is_string( $r['extract'] ) && !$r['extract trimmed'] ) {
|
||||
$r['extract'] = self::trimExtract( $r['extract'], $length );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class ApiOptions extends ApiBase {
|
|||
$changes[$params['optionname']] = $newValue;
|
||||
}
|
||||
|
||||
Hooks::run( 'ApiOptions', [ $this, $user, $changes, $resetKinds ] );
|
||||
$this->getHookRunner()->onApiOptions( $this, $user, $changes, $resetKinds );
|
||||
|
||||
if ( $resetKinds ) {
|
||||
$this->resetPreferences( $resetKinds );
|
||||
|
|
|
|||
|
|
@ -178,9 +178,7 @@ class ApiPageSet extends ApiBase {
|
|||
if ( !$isDryRun ) {
|
||||
$generator->executeGenerator( $this );
|
||||
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$apiModule = $this;
|
||||
Hooks::run( 'APIQueryGeneratorAfterExecute', [ &$generator, &$apiModule ] );
|
||||
$this->getHookRunner()->onAPIQueryGeneratorAfterExecute( $generator, $this );
|
||||
} else {
|
||||
// Prevent warnings from being reported on these parameters
|
||||
$main = $this->getMain();
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ class ApiParse extends ApiBase {
|
|||
$outputPage->loadSkinModules( $skin );
|
||||
}
|
||||
|
||||
Hooks::run( 'ApiParseMakeOutputPage', [ $this, $outputPage ] );
|
||||
$this->getHookRunner()->onApiParseMakeOutputPage( $this, $outputPage );
|
||||
}
|
||||
|
||||
if ( $oldid !== null ) {
|
||||
|
|
@ -425,7 +425,7 @@ class ApiParse extends ApiBase {
|
|||
// one hook of OutputPage::addParserOutputMetadata here.
|
||||
if ( $params['effectivelanglinks'] ) {
|
||||
$linkFlags = [];
|
||||
Hooks::run( 'LanguageLinks', [ $titleObj, &$langlinks, &$linkFlags ] );
|
||||
$this->getHookRunner()->onLanguageLinks( $titleObj, $langlinks, $linkFlags );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -600,8 +600,8 @@ class ApiParse extends ApiBase {
|
|||
|
||||
$reset = null;
|
||||
$suppressCache = false;
|
||||
Hooks::run( 'ApiMakeParserOptions',
|
||||
[ $popts, $pageObj->getTitle(), $params, $this, &$reset, &$suppressCache ] );
|
||||
$this->getHookRunner()->onApiMakeParserOptions( $popts, $pageObj->getTitle(),
|
||||
$params, $this, $reset, $suppressCache );
|
||||
|
||||
// Force cache suppression when $popts aren't cacheable.
|
||||
$suppressCache = $suppressCache || !$popts->isSafeToCache();
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ class ApiQuery extends ApiBase {
|
|||
$this->mModuleMgr->addModules( self::$QueryMetaModules, 'meta' );
|
||||
$this->mModuleMgr->addModules( $config->get( 'APIMetaModules' ), 'meta' );
|
||||
|
||||
Hooks::run( 'ApiQuery::moduleManager', [ $this->mModuleMgr ] );
|
||||
$this->getHookRunner()->onApiQuery__moduleManager( $this->mModuleMgr );
|
||||
|
||||
// Create PageSet that will process titles/pageids/revids/generator
|
||||
$this->mPageSet = new ApiPageSet( $this );
|
||||
|
|
@ -261,7 +261,7 @@ class ApiQuery extends ApiBase {
|
|||
$cacheMode = $this->mergeCacheMode(
|
||||
$cacheMode, $module->getCacheMode( $params ) );
|
||||
$module->execute();
|
||||
Hooks::run( 'APIQueryAfterExecute', [ &$module ] );
|
||||
$this->getHookRunner()->onAPIQueryAfterExecute( $module );
|
||||
}
|
||||
|
||||
// Set the cache mode
|
||||
|
|
|
|||
|
|
@ -412,10 +412,10 @@ abstract class ApiQueryBase extends ApiBase {
|
|||
|
||||
if ( $hookData !== null && Hooks::isRegistered( 'ApiQueryBaseBeforeQuery' ) ) {
|
||||
$info = $queryBuilder->getQueryInfo();
|
||||
Hooks::run( 'ApiQueryBaseBeforeQuery', [
|
||||
$this, &$info['tables'], &$info['fields'], &$info['conds'],
|
||||
&$info['options'], &$info['join_conds'], &$hookData
|
||||
] );
|
||||
$this->getHookRunner()->onApiQueryBaseBeforeQuery(
|
||||
$this, $info['tables'], $info['fields'], $info['conds'],
|
||||
$info['options'], $info['join_conds'], $hookData
|
||||
);
|
||||
$queryBuilder = $this->getDB()->newSelectQueryBuilder()->queryInfo( $info );
|
||||
}
|
||||
|
||||
|
|
@ -423,7 +423,7 @@ abstract class ApiQueryBase extends ApiBase {
|
|||
$res = $queryBuilder->fetchResultSet();
|
||||
|
||||
if ( $hookData !== null ) {
|
||||
Hooks::run( 'ApiQueryBaseAfterQuery', [ $this, $res, &$hookData ] );
|
||||
$this->getHookRunner()->onApiQueryBaseAfterQuery( $this, $res, $hookData );
|
||||
}
|
||||
|
||||
return $res;
|
||||
|
|
@ -443,7 +443,7 @@ abstract class ApiQueryBase extends ApiBase {
|
|||
* @return bool Return false if row processing should end with continuation
|
||||
*/
|
||||
protected function processRow( $row, array &$data, array &$hookData ) {
|
||||
return Hooks::run( 'ApiQueryBaseProcessRow', [ $this, $row, &$data, &$hookData ] );
|
||||
return $this->getHookRunner()->onApiQueryBaseProcessRow( $this, $row, $data, $hookData );
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ class ApiQueryInfo extends ApiQueryBase {
|
|||
'import' => [ self::class, 'getImportToken' ],
|
||||
'watch' => [ self::class, 'getWatchToken' ],
|
||||
];
|
||||
Hooks::run( 'APIQueryInfoTokens', [ &$this->tokenFunctions ], '1.24' );
|
||||
$this->getHookRunner()->onAPIQueryInfoTokens( $this->tokenFunctions );
|
||||
|
||||
return $this->tokenFunctions;
|
||||
}
|
||||
|
|
@ -512,7 +512,7 @@ class ApiQueryInfo extends ApiQueryBase {
|
|||
$pageInfo['preload'] = '';
|
||||
} else {
|
||||
$text = null;
|
||||
Hooks::run( 'EditFormPreloadText', [ &$text, &$title ] );
|
||||
$this->getHookRunner()->onEditFormPreloadText( $text, $title );
|
||||
|
||||
$pageInfo['preload'] = $text;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
|
|||
$this->tokenFunctions = [
|
||||
'patrol' => [ self::class, 'getPatrolToken' ]
|
||||
];
|
||||
Hooks::run( 'APIQueryRecentChangesTokens', [ &$this->tokenFunctions ], '1.24' );
|
||||
$this->getHookRunner()->onAPIQueryRecentChangesTokens( $this->tokenFunctions );
|
||||
|
||||
return $this->tokenFunctions;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
|
|||
$this->tokenFunctions = [
|
||||
'rollback' => [ self::class, 'getRollbackToken' ]
|
||||
];
|
||||
Hooks::run( 'APIQueryRevisionsTokens', [ &$this->tokenFunctions ], '1.24' );
|
||||
$this->getHookRunner()->onAPIQueryRevisionsTokens( $this->tokenFunctions );
|
||||
|
||||
return $this->tokenFunctions;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
|
|||
|
||||
$data['categorycollation'] = $config->get( 'CategoryCollation' );
|
||||
|
||||
Hooks::run( 'APIQuerySiteInfoGeneralInfo', [ $this, &$data ] );
|
||||
$this->getHookRunner()->onAPIQuerySiteInfoGeneralInfo( $this, $data );
|
||||
|
||||
return $this->getResult()->addValue( 'query', $property, $data );
|
||||
}
|
||||
|
|
@ -503,7 +503,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
|
|||
$data['admins'] = (int)SiteStats::numberingroup( 'sysop' );
|
||||
$data['jobs'] = (int)SiteStats::jobs();
|
||||
|
||||
Hooks::run( 'APIQuerySiteInfoStatisticsInfo', [ &$data ] );
|
||||
$this->getHookRunner()->onAPIQuerySiteInfoStatisticsInfo( $data );
|
||||
|
||||
return $this->getResult()->addValue( 'query', $property, $data );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@
|
|||
* @since 1.24
|
||||
*/
|
||||
|
||||
use MediaWiki\Api\ApiHookRunner;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
/**
|
||||
* Module to fetch tokens via action=query&meta=tokens
|
||||
*
|
||||
|
|
@ -72,7 +75,9 @@ class ApiQueryTokens extends ApiQueryBase {
|
|||
'login' => [ '', 'login' ],
|
||||
'createaccount' => [ '', 'createaccount' ],
|
||||
];
|
||||
Hooks::run( 'ApiQueryTokensRegisterTypes', [ &$salts ] );
|
||||
$hookContainer = MediaWikiServices::getInstance()->getHookContainer();
|
||||
$hookRunner = new ApiHookRunner( $hookContainer );
|
||||
$hookRunner->onApiQueryTokensRegisterTypes( $salts );
|
||||
ksort( $salts );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class ApiQueryUsers extends ApiQueryBase {
|
|||
$this->tokenFunctions = [
|
||||
'userrights' => [ self::class, 'getUserrightsToken' ],
|
||||
];
|
||||
Hooks::run( 'APIQueryUsersTokens', [ &$this->tokenFunctions ], '1.24' );
|
||||
$this->getHookRunner()->onAPIQueryUsersTokens( $this->tokenFunctions );
|
||||
|
||||
return $this->tokenFunctions;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,9 +174,8 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
|
|||
|
||||
$options['limit'] = $params['limit'];
|
||||
|
||||
Hooks::run( 'ApiQueryWatchlistPrepareWatchedItemQueryServiceOptions', [
|
||||
$this, $params, &$options
|
||||
] );
|
||||
$this->getHookRunner()->onApiQueryWatchlistPrepareWatchedItemQueryServiceOptions(
|
||||
$this, $params, $options );
|
||||
|
||||
$ids = [];
|
||||
$services = MediaWikiServices::getInstance();
|
||||
|
|
@ -427,9 +426,8 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
|
|||
$vals['suppressed'] = true;
|
||||
}
|
||||
|
||||
Hooks::run( 'ApiQueryWatchlistExtractOutputData', [
|
||||
$this, $watchedItem, $recentChangeInfo, &$vals
|
||||
] );
|
||||
$this->getHookRunner()->onApiQueryWatchlistExtractOutputData(
|
||||
$this, $watchedItem, $recentChangeInfo, $vals );
|
||||
|
||||
return $vals;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class ApiRemoveAuthenticationData extends ApiBase {
|
|||
|
||||
// Perform the removal
|
||||
$status = $manager->allowsAuthenticationDataChange( $req, true );
|
||||
Hooks::run( 'ChangeAuthenticationDataAudit', [ $req, $status ] );
|
||||
$this->getHookRunner()->onChangeAuthenticationDataAudit( $req, $status );
|
||||
if ( !$status->isGood() ) {
|
||||
$this->dieStatus( $status );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class ApiRsd extends ApiBase {
|
|||
]
|
||||
],
|
||||
];
|
||||
Hooks::run( 'ApiRsdServiceApis', [ &$apis ] );
|
||||
$this->getHookRunner()->onApiRsdServiceApis( $apis );
|
||||
|
||||
return $apis;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class ApiTokens extends ApiBase {
|
|||
foreach ( $names as $name ) {
|
||||
$types[$name] = [ ApiQueryInfo::class, 'get' . ucfirst( $name ) . 'Token' ];
|
||||
}
|
||||
Hooks::run( 'ApiTokensGetTokenTypes', [ &$types ], '1.24' );
|
||||
$this->getHookRunner()->onApiTokensGetTokenTypes( $types );
|
||||
|
||||
// For forwards-compat, copy any token types from ApiQueryTokens that
|
||||
// we don't already have something for.
|
||||
|
|
|
|||
|
|
@ -78,8 +78,9 @@ class ApiUndelete extends ApiBase {
|
|||
}
|
||||
|
||||
if ( $retval[1] ) {
|
||||
Hooks::run( 'FileUndeleteComplete',
|
||||
[ $titleObj, $params['fileids'], $this->getUser(), $params['reason'] ] );
|
||||
$this->getHookRunner()->onFileUndeleteComplete(
|
||||
$titleObj, $params['fileids'],
|
||||
$this->getUser(), $params['reason'] );
|
||||
}
|
||||
|
||||
$this->setWatch( $params['watchlist'], $titleObj );
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class ApiValidatePassword extends ApiBase {
|
|||
$r['validitymessages'] = $messages;
|
||||
}
|
||||
|
||||
Hooks::run( 'ApiValidatePassword', [ $this, &$r ] );
|
||||
$this->getHookRunner()->onApiValidatePassword( $this, $r );
|
||||
|
||||
$this->getResult()->addValue( null, $this->getModuleName(), $r );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
namespace MediaWiki\Auth;
|
||||
|
||||
use Config;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -36,6 +38,10 @@ abstract class AbstractAuthenticationProvider implements AuthenticationProvider
|
|||
protected $manager;
|
||||
/** @var Config */
|
||||
protected $config;
|
||||
/** @var HookContainer */
|
||||
private $hookContainer;
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
public function setLogger( LoggerInterface $logger ) {
|
||||
$this->logger = $logger;
|
||||
|
|
@ -49,6 +55,11 @@ abstract class AbstractAuthenticationProvider implements AuthenticationProvider
|
|||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function setHookContainer( HookContainer $hookContainer ) {
|
||||
$this->hookContainer = $hookContainer;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @note Override this if it makes sense to support more than one instance
|
||||
|
|
@ -56,4 +67,22 @@ abstract class AbstractAuthenticationProvider implements AuthenticationProvider
|
|||
public function getUniqueId() {
|
||||
return static::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.35
|
||||
* @return HookContainer
|
||||
*/
|
||||
protected function getHookContainer() : HookContainer {
|
||||
return $this->hookContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal This is for use by core only. Hook interfaces may be removed
|
||||
* without notice.
|
||||
* @since 1.35
|
||||
* @return HookRunner
|
||||
*/
|
||||
protected function getHookRunner() : HookRunner {
|
||||
return $this->hookRunner;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,7 +158,8 @@ abstract class AbstractPasswordPrimaryAuthenticationProvider
|
|||
$expires = $days ? wfTimestamp( TS_MW, time() + $days * 86400 ) : null;
|
||||
|
||||
// Give extensions a chance to force an expiration
|
||||
\Hooks::run( 'ResetPasswordExpiration', [ \User::newFromName( $username ), &$expires ] );
|
||||
$this->getHookRunner()->onResetPasswordExpiration(
|
||||
\User::newFromName( $username ), $expires );
|
||||
|
||||
return $expires;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
namespace MediaWiki\Auth;
|
||||
|
||||
use Config;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Permissions\PermissionManager;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
|
|
@ -155,6 +157,12 @@ class AuthManager implements LoggerAwareInterface {
|
|||
/** @var CreatedAccountAuthenticationRequest[] */
|
||||
private $createdAccountAuthenticationRequests = [];
|
||||
|
||||
/** @var HookContainer */
|
||||
private $hookContainer;
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/**
|
||||
* Get the global AuthManager
|
||||
* @return AuthManager
|
||||
|
|
@ -169,17 +177,21 @@ class AuthManager implements LoggerAwareInterface {
|
|||
* @param Config $config
|
||||
* @param ObjectFactory $objectFactory
|
||||
* @param PermissionManager $permManager
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
public function __construct(
|
||||
WebRequest $request,
|
||||
Config $config,
|
||||
ObjectFactory $objectFactory,
|
||||
PermissionManager $permManager
|
||||
PermissionManager $permManager,
|
||||
HookContainer $hookContainer
|
||||
) {
|
||||
$this->request = $request;
|
||||
$this->config = $config;
|
||||
$this->objectFactory = $objectFactory;
|
||||
$this->permManager = $permManager;
|
||||
$this->hookContainer = $hookContainer;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
$this->setLogger( new NullLogger() );
|
||||
}
|
||||
|
||||
|
|
@ -233,6 +245,7 @@ class AuthManager implements LoggerAwareInterface {
|
|||
$provider->setLogger( $this->logger );
|
||||
$provider->setManager( $this );
|
||||
$provider->setConfig( $this->config );
|
||||
$provider->setHookContainer( $this->hookContainer );
|
||||
$id = $provider->getUniqueId();
|
||||
if ( isset( $this->allAuthenticationProviders[$id] ) ) {
|
||||
throw new \RuntimeException(
|
||||
|
|
@ -336,7 +349,8 @@ class AuthManager implements LoggerAwareInterface {
|
|||
$this->setSessionDataForUser( $user );
|
||||
$this->callMethodOnProviders( 7, 'postAuthentication', [ $user, $ret ] );
|
||||
$session->remove( 'AuthManager::authnState' );
|
||||
\Hooks::run( 'AuthManagerLoginAuthenticateAudit', [ $ret, $user, $user->getName(), [] ] );
|
||||
$this->getHookRunner()->onAuthManagerLoginAuthenticateAudit(
|
||||
$ret, $user, $user->getName(), [] );
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
|
@ -352,7 +366,7 @@ class AuthManager implements LoggerAwareInterface {
|
|||
$this->callMethodOnProviders( 7, 'postAuthentication',
|
||||
[ User::newFromName( $guessUserName ) ?: null, $ret ]
|
||||
);
|
||||
\Hooks::run( 'AuthManagerLoginAuthenticateAudit', [ $ret, null, $guessUserName, [] ] );
|
||||
$this->getHookRunner()->onAuthManagerLoginAuthenticateAudit( $ret, null, $guessUserName, [] );
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
|
@ -468,7 +482,8 @@ class AuthManager implements LoggerAwareInterface {
|
|||
[ User::newFromName( $guessUserName ) ?: null, $res ]
|
||||
);
|
||||
$session->remove( 'AuthManager::authnState' );
|
||||
\Hooks::run( 'AuthManagerLoginAuthenticateAudit', [ $res, null, $guessUserName, [] ] );
|
||||
$this->getHookRunner()->onAuthManagerLoginAuthenticateAudit(
|
||||
$res, null, $guessUserName, [] );
|
||||
return $res;
|
||||
case AuthenticationResponse::ABSTAIN;
|
||||
// Continue loop
|
||||
|
|
@ -534,7 +549,8 @@ class AuthManager implements LoggerAwareInterface {
|
|||
[ User::newFromName( $guessUserName ) ?: null, $res ]
|
||||
);
|
||||
$session->remove( 'AuthManager::authnState' );
|
||||
\Hooks::run( 'AuthManagerLoginAuthenticateAudit', [ $res, null, $guessUserName, [] ] );
|
||||
$this->getHookRunner()->onAuthManagerLoginAuthenticateAudit(
|
||||
$res, null, $guessUserName, [] );
|
||||
return $res;
|
||||
case AuthenticationResponse::REDIRECT;
|
||||
case AuthenticationResponse::UI;
|
||||
|
|
@ -625,7 +641,8 @@ class AuthManager implements LoggerAwareInterface {
|
|||
);
|
||||
$this->callMethodOnProviders( 7, 'postAuthentication', [ $user, $ret ] );
|
||||
$session->remove( 'AuthManager::authnState' );
|
||||
\Hooks::run( 'AuthManagerLoginAuthenticateAudit', [ $ret, $user, $user->getName(), [] ] );
|
||||
$this->getHookRunner()->onAuthManagerLoginAuthenticateAudit(
|
||||
$ret, $user, $user->getName(), [] );
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
|
@ -658,7 +675,8 @@ class AuthManager implements LoggerAwareInterface {
|
|||
$this->logger->debug( "Login failed in secondary authentication by $id" );
|
||||
$this->callMethodOnProviders( 7, 'postAuthentication', [ $user, $res ] );
|
||||
$session->remove( 'AuthManager::authnState' );
|
||||
\Hooks::run( 'AuthManagerLoginAuthenticateAudit', [ $res, $user, $user->getName(), [] ] );
|
||||
$this->getHookRunner()->onAuthManagerLoginAuthenticateAudit(
|
||||
$res, $user, $user->getName(), [] );
|
||||
return $res;
|
||||
case AuthenticationResponse::REDIRECT;
|
||||
case AuthenticationResponse::UI;
|
||||
|
|
@ -694,7 +712,8 @@ class AuthManager implements LoggerAwareInterface {
|
|||
$this->callMethodOnProviders( 7, 'postAuthentication', [ $user, $ret ] );
|
||||
$session->remove( 'AuthManager::authnState' );
|
||||
$this->removeAuthenticationSessionData( null );
|
||||
\Hooks::run( 'AuthManagerLoginAuthenticateAudit', [ $ret, $user, $user->getName(), [] ] );
|
||||
$this->getHookRunner()->onAuthManagerLoginAuthenticateAudit(
|
||||
$ret, $user, $user->getName(), [] );
|
||||
return $ret;
|
||||
} catch ( \Exception $ex ) {
|
||||
$session->remove( 'AuthManager::authnState' );
|
||||
|
|
@ -763,9 +782,8 @@ class AuthManager implements LoggerAwareInterface {
|
|||
}
|
||||
}
|
||||
|
||||
\Hooks::run( 'SecuritySensitiveOperationStatus', [
|
||||
&$status, $operation, $session, $timeSinceLogin
|
||||
] );
|
||||
$this->getHookRunner()->onSecuritySensitiveOperationStatus(
|
||||
$status, $operation, $session, $timeSinceLogin );
|
||||
|
||||
// If authentication is not possible, downgrade from "REAUTH" to "FAIL".
|
||||
if ( !$this->canAuthenticateNow() && $status === self::SEC_REAUTH ) {
|
||||
|
|
@ -1425,7 +1443,7 @@ class AuthManager implements LoggerAwareInterface {
|
|||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
$this->setDefaultUserOptions( $user, $creator->isAnon() );
|
||||
\Hooks::runWithoutAbort( 'LocalUserCreated', [ $user, false ] );
|
||||
$this->getHookRunner()->onLocalUserCreated( $user, false );
|
||||
$user->saveSettings();
|
||||
$state['userid'] = $user->getId();
|
||||
|
||||
|
|
@ -1745,7 +1763,7 @@ class AuthManager implements LoggerAwareInterface {
|
|||
// Inform the providers
|
||||
$this->callMethodOnProviders( 6, 'autoCreatedAccount', [ $user, $source ] );
|
||||
|
||||
\Hooks::run( 'LocalUserCreated', [ $user, true ] );
|
||||
$this->getHookRunner()->onLocalUserCreated( $user, true );
|
||||
$user->saveSettings();
|
||||
|
||||
// Update user count
|
||||
|
|
@ -2322,6 +2340,7 @@ class AuthManager implements LoggerAwareInterface {
|
|||
$provider->setLogger( $this->logger );
|
||||
$provider->setManager( $this );
|
||||
$provider->setConfig( $this->config );
|
||||
$provider->setHookContainer( $this->getHookContainer() );
|
||||
$id = $provider->getUniqueId();
|
||||
if ( isset( $this->allAuthenticationProviders[$id] ) ) {
|
||||
throw new \RuntimeException(
|
||||
|
|
@ -2409,7 +2428,7 @@ class AuthManager implements LoggerAwareInterface {
|
|||
|
||||
\Wikimedia\ScopedCallback::consume( $delay );
|
||||
|
||||
\Hooks::run( 'UserLoggedIn', [ $user ] );
|
||||
$this->getHookRunner()->onUserLoggedIn( $user );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2466,6 +2485,20 @@ class AuthManager implements LoggerAwareInterface {
|
|||
self::$instance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HookContainer
|
||||
*/
|
||||
private function getHookContainer() {
|
||||
return $this->hookContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HookRunner
|
||||
*/
|
||||
private function getHookRunner() {
|
||||
return $this->hookRunner;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
namespace MediaWiki\Auth;
|
||||
|
||||
use Config;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -50,6 +51,12 @@ interface AuthenticationProvider extends LoggerAwareInterface {
|
|||
*/
|
||||
public function setConfig( Config $config );
|
||||
|
||||
/**
|
||||
* Set the HookContainer
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
public function setHookContainer( HookContainer $hookContainer );
|
||||
|
||||
/**
|
||||
* Return a unique identifier for this instance
|
||||
*
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ class TemporaryPasswordPrimaryAuthenticationProvider
|
|||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
\Hooks::run( 'User::mailPasswordInternal', [ &$creatingUser, &$ip, &$user ] );
|
||||
$this->getHookRunner()->onUser__mailPasswordInternal( $creatingUser, $ip, $user );
|
||||
|
||||
$mainPageUrl = \Title::newMainPage()->getCanonicalURL();
|
||||
$userLanguage = $user->getOption( 'language' );
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ class ThrottlePreAuthenticationProvider extends AbstractPreAuthenticationProvide
|
|||
|
||||
$ip = $this->manager->getRequest()->getIP();
|
||||
|
||||
if ( !\Hooks::run( 'ExemptFromAccountCreationThrottle', [ $ip ] ) ) {
|
||||
if ( !$this->getHookRunner()->onExemptFromAccountCreationThrottle( $ip ) ) {
|
||||
$this->logger->debug( __METHOD__ . ": a hook allowed account creation w/o throttle\n" );
|
||||
return \StatusValue::newGood();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@ namespace MediaWiki\Block;
|
|||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use Hooks;
|
||||
use LogicException;
|
||||
use MediaWiki\Config\ServiceOptions;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Permissions\PermissionManager;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
use Message;
|
||||
|
|
@ -68,20 +69,26 @@ class BlockManager {
|
|||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/**
|
||||
* @param ServiceOptions $options
|
||||
* @param PermissionManager $permissionManager
|
||||
* @param LoggerInterface $logger
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
public function __construct(
|
||||
ServiceOptions $options,
|
||||
PermissionManager $permissionManager,
|
||||
LoggerInterface $logger
|
||||
LoggerInterface $logger,
|
||||
HookContainer $hookContainer
|
||||
) {
|
||||
$options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
|
||||
$this->options = $options;
|
||||
$this->permissionManager = $permissionManager;
|
||||
$this->logger = $logger;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -159,7 +166,7 @@ class BlockManager {
|
|||
}
|
||||
}
|
||||
|
||||
Hooks::run( 'GetUserBlock', [ clone $user, $ip, &$block ] );
|
||||
$this->hookRunner->onGetUserBlock( clone $user, $ip, $block );
|
||||
|
||||
return $block;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -710,8 +710,7 @@ class DatabaseBlock extends AbstractBlock {
|
|||
if ( $this->isAutoblocking() && $this->getType() == self::TYPE_USER ) {
|
||||
wfDebug( "Doing retroactive autoblocks for " . $this->getTarget() . "\n" );
|
||||
|
||||
$continue = Hooks::run(
|
||||
'PerformRetroactiveAutoblock', [ $this, &$blockIds ] );
|
||||
$continue = Hooks::runner()->onPerformRetroactiveAutoblock( $this, $blockIds );
|
||||
|
||||
if ( $continue ) {
|
||||
self::defaultRetroactiveAutoblock( $this, $blockIds );
|
||||
|
|
@ -837,10 +836,8 @@ class DatabaseBlock extends AbstractBlock {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Avoid PHP 7.1 warning of passing $this by reference
|
||||
$block = $this;
|
||||
# Allow hooks to cancel the autoblock.
|
||||
if ( !Hooks::run( 'AbortAutoblock', [ $autoblockIP, &$block ] ) ) {
|
||||
if ( !Hooks::runner()->onAbortAutoblock( $autoblockIP, $this ) ) {
|
||||
wfDebug( "Autoblock aborted by hook.\n" );
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
7
includes/cache/BacklinkCache.php
vendored
7
includes/cache/BacklinkCache.php
vendored
|
|
@ -25,6 +25,7 @@
|
|||
* @copyright © 2011, Antoine Musso
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use Wikimedia\Rdbms\FakeResultWrapper;
|
||||
use Wikimedia\Rdbms\IDatabase;
|
||||
|
|
@ -44,6 +45,8 @@ use Wikimedia\Rdbms\IResultWrapper;
|
|||
* Introduced by r47317
|
||||
*/
|
||||
class BacklinkCache {
|
||||
use ProtectedHookAccessorTrait;
|
||||
|
||||
/** @var BacklinkCache */
|
||||
protected static $instance;
|
||||
|
||||
|
|
@ -256,7 +259,7 @@ class BacklinkCache {
|
|||
return $prefixes[$table];
|
||||
} else {
|
||||
$prefix = null;
|
||||
Hooks::run( 'BacklinkCacheGetPrefix', [ $table, &$prefix ] );
|
||||
$this->getHookRunner()->onBacklinkCacheGetPrefix( $table, $prefix );
|
||||
if ( $prefix ) {
|
||||
return $prefix;
|
||||
} else {
|
||||
|
|
@ -304,7 +307,7 @@ class BacklinkCache {
|
|||
break;
|
||||
default:
|
||||
$conds = null;
|
||||
Hooks::run( 'BacklinkCacheGetConditions', [ $table, $this->title, &$conds ] );
|
||||
$this->getHookRunner()->onBacklinkCacheGetConditions( $table, $this->title, $conds );
|
||||
if ( !$conds ) {
|
||||
throw new MWException( "Invalid table \"$table\" in " . __CLASS__ );
|
||||
}
|
||||
|
|
|
|||
2
includes/cache/HTMLFileCache.php
vendored
2
includes/cache/HTMLFileCache.php
vendored
|
|
@ -131,7 +131,7 @@ class HTMLFileCache extends FileCacheBase {
|
|||
}
|
||||
|
||||
// Allow extensions to disable caching
|
||||
return Hooks::run( 'HTMLFileCache::useFileCache', [ $context ] );
|
||||
return Hooks::runner()->onHTMLFileCache__useFileCache( $context );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
18
includes/cache/HtmlCacheUpdater.php
vendored
18
includes/cache/HtmlCacheUpdater.php
vendored
|
|
@ -18,6 +18,9 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
|
||||
/**
|
||||
* Class to invalidate the CDN and HTMLFileCache entries associated with URLs/titles
|
||||
*
|
||||
|
|
@ -32,6 +35,9 @@ class HtmlCacheUpdater {
|
|||
/** @var int Max seconds for CDN to served cached objects without revalidation */
|
||||
private $cdnMaxAge;
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/** @var int Issue purge immediately and do not schedule a rebound purge */
|
||||
public const PURGE_NAIVE = 0;
|
||||
/**
|
||||
|
|
@ -75,12 +81,16 @@ class HtmlCacheUpdater {
|
|||
public const UNLESS_CACHE_MTIME_AFTER = 'unless-timestamp-exceeds';
|
||||
|
||||
/**
|
||||
* @param HookContainer $hookContainer
|
||||
* @param int $reboundDelay $wgCdnReboundPurgeDelay
|
||||
* @param bool $useFileCache $wgUseFileCache
|
||||
* @param int $cdnMaxAge $wgCdnMaxAge
|
||||
* @internal For use with MediaWikiServices->getHtmlCacheUpdater()
|
||||
*/
|
||||
public function __construct( $reboundDelay, $useFileCache, $cdnMaxAge ) {
|
||||
public function __construct( HookContainer $hookContainer, $reboundDelay,
|
||||
$useFileCache, $cdnMaxAge
|
||||
) {
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
$this->reboundDelay = $reboundDelay;
|
||||
$this->useFileCache = $useFileCache;
|
||||
$this->cdnMaxAge = $cdnMaxAge;
|
||||
|
|
@ -192,16 +202,16 @@ class HtmlCacheUpdater {
|
|||
// Extensions may add novel ways to access this content
|
||||
$append = [];
|
||||
$mode = $flags & self::PURGE_URLS_LINKSUPDATE_ONLY;
|
||||
Hooks::run( 'HtmlCacheUpdaterAppendUrls', [ $title, $mode, &$append ] );
|
||||
$this->hookRunner->onHtmlCacheUpdaterAppendUrls( $title, $mode, $append );
|
||||
$urls = array_merge( $urls, $append );
|
||||
|
||||
// Extensions may add novel ways to access the site overall
|
||||
$append = [];
|
||||
Hooks::run( 'HtmlCacheUpdaterVaryUrls', [ $urls, &$append ] );
|
||||
$this->hookRunner->onHtmlCacheUpdaterVaryUrls( $urls, $append );
|
||||
$urls = array_merge( $urls, $append );
|
||||
|
||||
// Legacy. TODO: Deprecate this
|
||||
Hooks::run( 'TitleSquidURLs', [ $title, &$urls ] );
|
||||
$this->hookRunner->onTitleSquidURLs( $title, $urls );
|
||||
|
||||
return $urls;
|
||||
}
|
||||
|
|
|
|||
16
includes/cache/MessageCache.php
vendored
16
includes/cache/MessageCache.php
vendored
|
|
@ -20,6 +20,9 @@
|
|||
* @file
|
||||
* @ingroup Cache
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Languages\LanguageFactory;
|
||||
use MediaWiki\Languages\LanguageFallback;
|
||||
use MediaWiki\Languages\LanguageNameUtils;
|
||||
|
|
@ -117,6 +120,8 @@ class MessageCache implements LoggerAwareInterface {
|
|||
protected $languageNameUtils;
|
||||
/** @var LanguageFallback */
|
||||
protected $languageFallback;
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/**
|
||||
* Get the singleton instance of this class
|
||||
|
|
@ -161,6 +166,7 @@ class MessageCache implements LoggerAwareInterface {
|
|||
* @param LocalisationCache $localisationCache
|
||||
* @param LanguageNameUtils $languageNameUtils
|
||||
* @param LanguageFallback $languageFallback
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
public function __construct(
|
||||
WANObjectCache $wanCache,
|
||||
|
|
@ -173,7 +179,8 @@ class MessageCache implements LoggerAwareInterface {
|
|||
LanguageFactory $langFactory,
|
||||
LocalisationCache $localisationCache,
|
||||
LanguageNameUtils $languageNameUtils,
|
||||
LanguageFallback $languageFallback
|
||||
LanguageFallback $languageFallback,
|
||||
HookContainer $hookContainer
|
||||
) {
|
||||
$this->wanCache = $wanCache;
|
||||
$this->clusterCache = $clusterCache;
|
||||
|
|
@ -185,6 +192,7 @@ class MessageCache implements LoggerAwareInterface {
|
|||
$this->localisationCache = $localisationCache;
|
||||
$this->languageNameUtils = $languageNameUtils;
|
||||
$this->languageFallback = $languageFallback;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
|
||||
$this->cache = new MapCacheLRU( 5 ); // limit size for sanity
|
||||
|
||||
|
|
@ -754,7 +762,7 @@ class MessageCache implements LoggerAwareInterface {
|
|||
$blobStore = MediaWikiServices::getInstance()->getResourceLoader()->getMessageBlobStore();
|
||||
foreach ( $replacements as list( $title, $msg ) ) {
|
||||
$blobStore->updateMessage( $this->contLang->lcfirst( $msg ) );
|
||||
Hooks::run( 'MessageCacheReplace', [ $title, $newTextByTitle[$title] ] );
|
||||
$this->hookRunner->onMessageCacheReplace( $title, $newTextByTitle[$title] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -913,7 +921,7 @@ class MessageCache implements LoggerAwareInterface {
|
|||
// Normalise title-case input (with some inlining)
|
||||
$lckey = self::normalizeKey( $key );
|
||||
|
||||
Hooks::run( 'MessageCache::get', [ &$lckey ] );
|
||||
$this->hookRunner->onMessageCache__get( $lckey );
|
||||
|
||||
// Loop through each language in the fallback list until we find something useful
|
||||
$message = $this->getMessageFromFallbackChain(
|
||||
|
|
@ -1115,7 +1123,7 @@ class MessageCache implements LoggerAwareInterface {
|
|||
if ( $entry === null || substr( $entry, 0, 1 ) !== ' ' ) {
|
||||
// Message does not have a MediaWiki page definition; try hook handlers
|
||||
$message = false;
|
||||
Hooks::run( 'MessagesPreLoad', [ $title, &$message, $code ] );
|
||||
$this->hookRunner->onMessagesPreLoad( $title, $message, $code );
|
||||
if ( $message !== false ) {
|
||||
$this->cache->setField( $code, $title, ' ' . $message );
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
use CLDRPluralRuleParser\Error as CLDRPluralRuleError;
|
||||
use CLDRPluralRuleParser\Evaluator;
|
||||
use MediaWiki\Config\ServiceOptions;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Languages\LanguageNameUtils;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
|
|
@ -71,6 +73,9 @@ class LocalisationCache {
|
|||
*/
|
||||
private $logger;
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/** @var callable[] See comment for parameter in constructor */
|
||||
private $clearStoreCallbacks;
|
||||
|
||||
|
|
@ -249,6 +254,7 @@ class LocalisationCache {
|
|||
* used to clear other caches that depend on this one, such as ResourceLoader's
|
||||
* MessageBlobStore.
|
||||
* @param LanguageNameUtils $langNameUtils
|
||||
* @param HookContainer $hookContainer
|
||||
* @throws MWException
|
||||
*/
|
||||
public function __construct(
|
||||
|
|
@ -256,7 +262,8 @@ class LocalisationCache {
|
|||
LCStore $store,
|
||||
LoggerInterface $logger,
|
||||
array $clearStoreCallbacks,
|
||||
LanguageNameUtils $langNameUtils
|
||||
LanguageNameUtils $langNameUtils,
|
||||
HookContainer $hookContainer
|
||||
) {
|
||||
$options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
|
||||
|
||||
|
|
@ -265,6 +272,7 @@ class LocalisationCache {
|
|||
$this->logger = $logger;
|
||||
$this->clearStoreCallbacks = $clearStoreCallbacks;
|
||||
$this->langNameUtils = $langNameUtils;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
|
||||
// Keep this separate from $this->options so it can be mutable
|
||||
$this->manualRecache = $options->get( 'manualRecache' );
|
||||
|
|
@ -957,7 +965,7 @@ class LocalisationCache {
|
|||
|
||||
# Allow extensions an opportunity to adjust the data for this
|
||||
# fallback
|
||||
Hooks::run( 'LocalisationCacheRecacheFallback', [ $this, $csCode, &$csData ] );
|
||||
$this->hookRunner->onLocalisationCacheRecacheFallback( $this, $csCode, $csData );
|
||||
|
||||
# Merge the data for this fallback into the final array
|
||||
if ( $csCode === $code ) {
|
||||
|
|
@ -1014,7 +1022,7 @@ class LocalisationCache {
|
|||
}
|
||||
# Run hooks
|
||||
$unused = true; // Used to be $purgeBlobs, removed in 1.34
|
||||
Hooks::run( 'LocalisationCacheRecache', [ $this, $code, &$allData, &$unused ] );
|
||||
$this->hookRunner->onLocalisationCacheRecache( $this, $code, $allData, $unused );
|
||||
|
||||
if ( $allData['namespaceNames'] === null ) {
|
||||
throw new MWException( __METHOD__ . ': Localisation data failed sanity check! ' .
|
||||
|
|
|
|||
|
|
@ -387,9 +387,7 @@ class RecentChange implements Taggable {
|
|||
$this->mAttribs['rc_id'] = $dbw->insertId();
|
||||
|
||||
# Notify extensions
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$rc = $this;
|
||||
Hooks::run( 'RecentChange_save', [ &$rc ] );
|
||||
Hooks::runner()->onRecentChange_save( $this );
|
||||
|
||||
if ( count( $this->tags ) ) {
|
||||
ChangeTags::addTags( $this->tags, $this->mAttribs['rc_id'],
|
||||
|
|
@ -408,7 +406,7 @@ class RecentChange implements Taggable {
|
|||
|
||||
// Never send an RC notification email about categorization changes
|
||||
if (
|
||||
Hooks::run( 'AbortEmailNotification', [ $editor, $title, $this ] ) &&
|
||||
Hooks::runner()->onAbortEmailNotification( $editor, $title, $this ) &&
|
||||
$this->mAttribs['rc_type'] != RC_CATEGORIZE
|
||||
) {
|
||||
// @FIXME: This would be better as an extension hook
|
||||
|
|
@ -564,8 +562,8 @@ class RecentChange implements Taggable {
|
|||
$errors,
|
||||
$permManager->getPermissionErrors( $right, $user, $this->getTitle() )
|
||||
);
|
||||
if ( !Hooks::run( 'MarkPatrolled',
|
||||
[ $this->getAttribute( 'rc_id' ), &$user, false, $auto, &$tags ] )
|
||||
if ( !Hooks::runner()->onMarkPatrolled(
|
||||
$this->getAttribute( 'rc_id' ), $user, false, $auto, $tags )
|
||||
) {
|
||||
$errors[] = [ 'hookaborted' ];
|
||||
}
|
||||
|
|
@ -588,10 +586,8 @@ class RecentChange implements Taggable {
|
|||
// Log this patrol event
|
||||
PatrolLog::record( $this, $auto, $user, $tags );
|
||||
|
||||
Hooks::run(
|
||||
'MarkPatrolledComplete',
|
||||
[ $this->getAttribute( 'rc_id' ), &$user, false, $auto ]
|
||||
);
|
||||
Hooks::runner()->onMarkPatrolledComplete(
|
||||
$this->getAttribute( 'rc_id' ), $user, false, $auto );
|
||||
|
||||
return [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
* @ingroup Change tagging
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Storage\NameTableAccessException;
|
||||
use Wikimedia\Rdbms\Database;
|
||||
|
|
@ -451,8 +452,8 @@ class ChangeTags {
|
|||
}
|
||||
}
|
||||
|
||||
Hooks::run( 'ChangeTagsAfterUpdateTags', [ $tagsToAdd, $tagsToRemove, $prevTags,
|
||||
$rc_id, $rev_id, $log_id, $params, $rc, $user ] );
|
||||
Hooks::runner()->onChangeTagsAfterUpdateTags( $tagsToAdd, $tagsToRemove, $prevTags,
|
||||
$rc_id, $rev_id, $log_id, $params, $rc, $user );
|
||||
|
||||
return [ $tagsToAdd, $tagsToRemove, $prevTags ];
|
||||
}
|
||||
|
|
@ -538,7 +539,7 @@ class ChangeTags {
|
|||
|
||||
// to be applied, a tag has to be explicitly defined
|
||||
$allowedTags = self::listExplicitlyDefinedTags();
|
||||
Hooks::run( 'ChangeTagsAllowedAdd', [ &$allowedTags, $tags, $user ] );
|
||||
Hooks::runner()->onChangeTagsAllowedAdd( $allowedTags, $tags, $user );
|
||||
$disallowedTags = array_diff( $tags, $allowedTags );
|
||||
if ( $disallowedTags ) {
|
||||
return self::restrictedTagError( 'tags-apply-not-allowed-one',
|
||||
|
|
@ -1219,7 +1220,7 @@ class ChangeTags {
|
|||
|
||||
// check with hooks
|
||||
$canCreateResult = Status::newGood();
|
||||
Hooks::run( 'ChangeTagCanCreate', [ $tag, $user, &$canCreateResult ] );
|
||||
Hooks::runner()->onChangeTagCanCreate( $tag, $user, $canCreateResult );
|
||||
return $canCreateResult;
|
||||
}
|
||||
|
||||
|
|
@ -1291,7 +1292,7 @@ class ChangeTags {
|
|||
|
||||
// give extensions a chance
|
||||
$status = Status::newGood();
|
||||
Hooks::run( 'ChangeTagAfterDelete', [ $tag, &$status ] );
|
||||
Hooks::runner()->onChangeTagAfterDelete( $tag, $status );
|
||||
// let's not allow error results, as the actual tag deletion succeeded
|
||||
if ( !$status->isOK() ) {
|
||||
wfDebug( 'ChangeTagAfterDelete error condition downgraded to warning' );
|
||||
|
|
@ -1350,7 +1351,7 @@ class ChangeTags {
|
|||
$status = Status::newGood();
|
||||
}
|
||||
|
||||
Hooks::run( 'ChangeTagCanDelete', [ $tag, $user, &$status ] );
|
||||
Hooks::runner()->onChangeTagCanDelete( $tag, $user, $status );
|
||||
return $status;
|
||||
}
|
||||
|
||||
|
|
@ -1408,18 +1409,20 @@ class ChangeTags {
|
|||
public static function listSoftwareActivatedTags() {
|
||||
// core active tags
|
||||
$tags = self::getSoftwareTags();
|
||||
if ( !Hooks::isRegistered( 'ChangeTagsListActive' ) ) {
|
||||
$hookContainer = MediaWikiServices::getInstance()->getHookContainer();
|
||||
if ( !$hookContainer->isRegistered( 'ChangeTagsListActive' ) ) {
|
||||
return $tags;
|
||||
}
|
||||
$hookRunner = new HookRunner( $hookContainer );
|
||||
$cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
|
||||
return $cache->getWithSetCallback(
|
||||
$cache->makeKey( 'active-tags' ),
|
||||
WANObjectCache::TTL_MINUTE * 5,
|
||||
function ( $oldValue, &$ttl, array &$setOpts ) use ( $tags ) {
|
||||
function ( $oldValue, &$ttl, array &$setOpts ) use ( $tags, $hookRunner ) {
|
||||
$setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
|
||||
|
||||
// Ask extensions which tags they consider active
|
||||
Hooks::run( 'ChangeTagsListActive', [ &$tags ] );
|
||||
$hookRunner->onChangeTagsListActive( $tags );
|
||||
return $tags;
|
||||
},
|
||||
[
|
||||
|
|
@ -1491,17 +1494,19 @@ class ChangeTags {
|
|||
public static function listSoftwareDefinedTags() {
|
||||
// core defined tags
|
||||
$tags = self::getSoftwareTags( true );
|
||||
if ( !Hooks::isRegistered( 'ListDefinedTags' ) ) {
|
||||
$hookContainer = MediaWikiServices::getInstance()->getHookContainer();
|
||||
if ( !$hookContainer->isRegistered( 'ListDefinedTags' ) ) {
|
||||
return $tags;
|
||||
}
|
||||
$hookRunner = new HookRunner( $hookContainer );
|
||||
$cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
|
||||
return $cache->getWithSetCallback(
|
||||
$cache->makeKey( 'valid-tags-hook' ),
|
||||
WANObjectCache::TTL_MINUTE * 5,
|
||||
function ( $oldValue, &$ttl, array &$setOpts ) use ( $tags ) {
|
||||
function ( $oldValue, &$ttl, array &$setOpts ) use ( $tags, $hookRunner ) {
|
||||
$setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
|
||||
|
||||
Hooks::run( 'ListDefinedTags', [ &$tags ] );
|
||||
$hookRunner->onListDefinedTags( $tags );
|
||||
return array_filter( array_unique( $tags ) );
|
||||
},
|
||||
[
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ abstract class Collation {
|
|||
|
||||
# Provide a mechanism for extensions to hook in.
|
||||
$collationObject = null;
|
||||
Hooks::run( 'Collation::factory', [ $collationName, &$collationObject ] );
|
||||
Hooks::runner()->onCollation__factory( $collationName, $collationObject );
|
||||
|
||||
if ( $collationObject instanceof self ) {
|
||||
return $collationObject;
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ abstract class AbstractContent implements Content {
|
|||
new LinksUpdate( $title, $parserOutput, $recursive )
|
||||
];
|
||||
|
||||
Hooks::run( 'SecondaryDataUpdates', [ $title, $old, $recursive, $parserOutput, &$updates ] );
|
||||
Hooks::runner()->onSecondaryDataUpdates( $title, $old, $recursive, $parserOutput, $updates );
|
||||
|
||||
return $updates;
|
||||
}
|
||||
|
|
@ -520,7 +520,7 @@ abstract class AbstractContent implements Content {
|
|||
$lossy = ( $lossy === 'lossy' ); // string flag, convert to boolean for convenience
|
||||
$result = false;
|
||||
|
||||
Hooks::run( 'ConvertContent', [ $this, $toModel, $lossy, &$result ] );
|
||||
Hooks::runner()->onConvertContent( $this, $toModel, $lossy, $result );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
|
@ -555,8 +555,8 @@ abstract class AbstractContent implements Content {
|
|||
$po = new ParserOutput();
|
||||
$options->registerWatcher( [ $po, 'recordOption' ] );
|
||||
|
||||
if ( Hooks::run( 'ContentGetParserOutput',
|
||||
[ $this, $title, $revId, $options, $generateHtml, &$po ] )
|
||||
if ( Hooks::runner()->onContentGetParserOutput(
|
||||
$this, $title, $revId, $options, $generateHtml, $po )
|
||||
) {
|
||||
// Save and restore the old value, just in case something is reusing
|
||||
// the ParserOptions object in some weird way.
|
||||
|
|
@ -566,7 +566,7 @@ abstract class AbstractContent implements Content {
|
|||
$options->setRedirectTarget( $oldRedir );
|
||||
}
|
||||
|
||||
Hooks::run( 'ContentAlterParserOutput', [ $this, $title, $po ] );
|
||||
Hooks::runner()->onContentAlterParserOutput( $this, $title, $po );
|
||||
$options->registerWatcher( null );
|
||||
|
||||
return $po;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
* @author Daniel Kinzler
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
|
||||
use MediaWiki\Logger\LoggerFactory;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Revision\RevisionRecord;
|
||||
|
|
@ -54,6 +55,8 @@ use Wikimedia\Assert\Assert;
|
|||
* @ingroup Content
|
||||
*/
|
||||
abstract class ContentHandler {
|
||||
use ProtectedHookAccessorTrait;
|
||||
|
||||
/**
|
||||
* Convenience function for getting flat text from a Content object. This
|
||||
* should only be used in the context of backwards compatibility with code
|
||||
|
|
@ -584,8 +587,8 @@ abstract class ContentHandler {
|
|||
) {
|
||||
$diffEngineClass = $this->getDiffEngineClass();
|
||||
$differenceEngine = new $diffEngineClass( $context, $old, $new, $rcid, $refreshCache, $unhide );
|
||||
Hooks::run( 'GetDifferenceEngine', [ $context, $old, $new, $refreshCache, $unhide,
|
||||
&$differenceEngine ] );
|
||||
$this->getHookRunner()->onGetDifferenceEngine(
|
||||
$context, $old, $new, $refreshCache, $unhide, $differenceEngine );
|
||||
return $differenceEngine;
|
||||
}
|
||||
|
||||
|
|
@ -612,7 +615,7 @@ abstract class ContentHandler {
|
|||
$slotDiffRenderer = new DifferenceEngineSlotDiffRenderer( $differenceEngine );
|
||||
}
|
||||
}
|
||||
Hooks::run( 'GetSlotDiffRenderer', [ $this, &$slotDiffRenderer, $context ] );
|
||||
$this->getHookRunner()->onGetSlotDiffRenderer( $this, $slotDiffRenderer, $context );
|
||||
return $slotDiffRenderer;
|
||||
}
|
||||
|
||||
|
|
@ -700,7 +703,7 @@ abstract class ContentHandler {
|
|||
// else has unstubbed the StubUserLang object by now.
|
||||
StubObject::unstub( $wgLang );
|
||||
|
||||
Hooks::run( 'PageContentLanguage', [ $title, &$pageLang, $wgLang ] );
|
||||
$this->getHookRunner()->onPageContentLanguage( $title, $pageLang, $wgLang );
|
||||
|
||||
return wfGetLangObj( $pageLang );
|
||||
}
|
||||
|
|
@ -762,7 +765,7 @@ abstract class ContentHandler {
|
|||
public function canBeUsedOn( Title $title ) {
|
||||
$ok = true;
|
||||
|
||||
Hooks::run( 'ContentModelCanBeUsedOn', [ $this->getModelID(), $title, &$ok ] );
|
||||
$this->getHookRunner()->onContentModelCanBeUsedOn( $this->getModelID(), $title, $ok );
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
|
@ -1341,7 +1344,7 @@ abstract class ContentHandler {
|
|||
$fieldData['content_model'] = $content->getModel();
|
||||
}
|
||||
|
||||
Hooks::run( 'SearchDataForIndex', [ &$fieldData, $this, $page, $output, $engine ] );
|
||||
$this->getHookRunner()->onSearchDataForIndex( $fieldData, $this, $page, $output, $engine );
|
||||
return $fieldData;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,9 @@ namespace MediaWiki\Content;
|
|||
|
||||
use ContentHandler;
|
||||
use FatalError;
|
||||
use Hooks;
|
||||
use InvalidArgumentException;
|
||||
use MediaWiki\HookContainer\HookContainer;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MWException;
|
||||
use MWUnknownContentModelException;
|
||||
use UnexpectedValueException;
|
||||
|
|
@ -56,6 +57,11 @@ final class ContentHandlerFactory implements IContentHandlerFactory {
|
|||
*/
|
||||
private $objectFactory;
|
||||
|
||||
/**
|
||||
* @var HookRunner
|
||||
*/
|
||||
private $hookRunner;
|
||||
|
||||
/**
|
||||
* @since 1.35
|
||||
* @internal Use @see MediaWikiServices::getContentHandlerFactory
|
||||
|
|
@ -64,10 +70,14 @@ final class ContentHandlerFactory implements IContentHandlerFactory {
|
|||
* content model to the ObjectFactory spec used to construct its ContentHandler.
|
||||
* This array typically comes from $wgContentHandlers.
|
||||
* @param ObjectFactory $objectFactory
|
||||
* @param HookContainer $hookContainer
|
||||
*/
|
||||
public function __construct( array $handlerSpecs, ObjectFactory $objectFactory ) {
|
||||
public function __construct( array $handlerSpecs, ObjectFactory $objectFactory,
|
||||
HookContainer $hookContainer
|
||||
) {
|
||||
$this->handlerSpecs = $handlerSpecs;
|
||||
$this->objectFactory = $objectFactory;
|
||||
$this->hookRunner = new HookRunner( $hookContainer );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -117,7 +127,7 @@ final class ContentHandlerFactory implements IContentHandlerFactory {
|
|||
*/
|
||||
public function getContentModels(): array {
|
||||
$modelsFromHook = [];
|
||||
Hooks::run( 'GetContentModels', [ &$modelsFromHook ] );
|
||||
$this->hookRunner->onGetContentModels( $modelsFromHook );
|
||||
$models = array_merge( // auto-registered from config and MediaServiceWiki or manual
|
||||
array_keys( $this->handlerSpecs ),
|
||||
|
||||
|
|
@ -246,7 +256,7 @@ final class ContentHandlerFactory implements IContentHandlerFactory {
|
|||
*/
|
||||
private function createContentHandlerFromHook( string $modelID ): ContentHandler {
|
||||
$contentHandler = null;
|
||||
Hooks::run( 'ContentHandlerForModelID', [ $modelID, &$contentHandler ] );
|
||||
$this->hookRunner->onContentHandlerForModelID( $modelID, $contentHandler );
|
||||
$this->validateContentHandler( $modelID, $contentHandler );
|
||||
|
||||
'@phan-var ContentHandler $contentHandler';
|
||||
|
|
|
|||
|
|
@ -256,9 +256,8 @@ class ContentModelChange {
|
|||
|
||||
$newContent = $this->newContent;
|
||||
|
||||
if ( !Hooks::run( 'EditFilterMergedContent',
|
||||
[ $derivativeContext, $newContent, $status, $reason,
|
||||
$user, false ] )
|
||||
if ( !Hooks::runner()->onEditFilterMergedContent( $derivativeContext, $newContent,
|
||||
$status, $reason, $user, false )
|
||||
) {
|
||||
if ( $status->isGood() ) {
|
||||
// TODO: extensions should really specify an error message
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ class WikitextContent extends TextContent {
|
|||
# Inserting a new section
|
||||
$subject = $sectionTitle ? wfMessage( 'newsectionheaderdefaultlevel' )
|
||||
->plaintextParams( $sectionTitle )->inContentLanguage()->text() . "\n\n" : '';
|
||||
if ( Hooks::run( 'PlaceNewSection', [ $this, $oldtext, $subject, &$text ] ) ) {
|
||||
if ( Hooks::runner()->onPlaceNewSection( $this, $oldtext, $subject, $text ) ) {
|
||||
$text = strlen( trim( $oldtext ) ) > 0
|
||||
? "{$oldtext}\n\n{$subject}{$text}"
|
||||
: "{$subject}{$text}";
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ class RequestContext implements IContextSource, MutableContext {
|
|||
// NFC form given this will not convert to normalised form.
|
||||
$code = self::sanitizeLangCode( $code );
|
||||
|
||||
Hooks::run( 'UserGetLanguageObject', [ $user, &$code, $this ] );
|
||||
Hooks::runner()->onUserGetLanguageObject( $user, $code, $this );
|
||||
|
||||
if ( $code === $this->getConfig()->get( 'LanguageCode' ) ) {
|
||||
$this->lang = MediaWikiServices::getInstance()->getContentLanguage();
|
||||
|
|
@ -395,7 +395,7 @@ class RequestContext implements IContextSource, MutableContext {
|
|||
public function getSkin() {
|
||||
if ( $this->skin === null ) {
|
||||
$skin = null;
|
||||
Hooks::run( 'RequestContextCreateSkin', [ $this, &$skin ] );
|
||||
Hooks::runner()->onRequestContextCreateSkin( $this, $skin );
|
||||
$factory = MediaWikiServices::getInstance()->getSkinFactory();
|
||||
|
||||
if ( $skin instanceof Skin ) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
|
||||
use MediaWiki\Logger\LoggerFactory;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Revision\RevisionRecord;
|
||||
|
|
@ -34,6 +35,8 @@ use Wikimedia\ScopedCallback;
|
|||
* See docs/deferred.txt
|
||||
*/
|
||||
class LinksUpdate extends DataUpdate {
|
||||
use ProtectedHookAccessorTrait;
|
||||
|
||||
// @todo make members protected, but make sure extensions don't break
|
||||
|
||||
/** @var int Page ID of the article linked from */
|
||||
|
|
@ -169,9 +172,7 @@ class LinksUpdate extends DataUpdate {
|
|||
|
||||
$this->mRecursive = $recursive;
|
||||
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$linksUpdate = $this;
|
||||
Hooks::run( 'LinksUpdateConstructed', [ &$linksUpdate ] );
|
||||
$this->getHookRunner()->onLinksUpdateConstructed( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -189,9 +190,7 @@ class LinksUpdate extends DataUpdate {
|
|||
}
|
||||
}
|
||||
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$linksUpdate = $this;
|
||||
Hooks::run( 'LinksUpdate', [ &$linksUpdate ] );
|
||||
$this->getHookRunner()->onLinksUpdate( $this );
|
||||
$this->doIncrementalUpdate();
|
||||
|
||||
// Commit and release the lock (if set)
|
||||
|
|
@ -201,9 +200,7 @@ class LinksUpdate extends DataUpdate {
|
|||
$this->getDB(),
|
||||
__METHOD__,
|
||||
function () {
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$linksUpdate = $this;
|
||||
Hooks::run( 'LinksUpdateComplete', [ &$linksUpdate, $this->ticket ] );
|
||||
$this->getHookRunner()->onLinksUpdateComplete( $this, $this->ticket );
|
||||
}
|
||||
) );
|
||||
}
|
||||
|
|
@ -517,7 +514,7 @@ class LinksUpdate extends DataUpdate {
|
|||
}
|
||||
|
||||
if ( count( $insertions ) ) {
|
||||
Hooks::run( 'LinksUpdateAfterInsert', [ $this, $table, $insertions ] );
|
||||
$this->getHookRunner()->onLinksUpdateAfterInsert( $this, $table, $insertions );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
|
||||
use MediaWiki\Content\IContentHandlerFactory;
|
||||
use MediaWiki\HookContainer\HookRunner;
|
||||
use MediaWiki\Linker\LinkRenderer;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Revision\RevisionRecord;
|
||||
|
|
@ -218,6 +219,9 @@ class DifferenceEngine extends ContextSource {
|
|||
*/
|
||||
private $revisionStore;
|
||||
|
||||
/** @var HookRunner */
|
||||
private $hookRunner;
|
||||
|
||||
/** #@- */
|
||||
|
||||
/**
|
||||
|
|
@ -256,6 +260,7 @@ class DifferenceEngine extends ContextSource {
|
|||
$this->linkRenderer = $services->getLinkRenderer();
|
||||
$this->contentHandlerFactory = $services->getContentHandlerFactory();
|
||||
$this->revisionStore = $services->getRevisionStore();
|
||||
$this->hookRunner = new HookRunner( $services->getHookContainer() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -597,10 +602,10 @@ class DifferenceEngine extends ContextSource {
|
|||
$out->setRobotPolicy( 'noindex,nofollow' );
|
||||
|
||||
// Allow extensions to add any extra output here
|
||||
Hooks::run( 'DifferenceEngineShowDiffPage', [ $out ] );
|
||||
$this->hookRunner->onDifferenceEngineShowDiffPage( $out );
|
||||
|
||||
if ( !$this->loadRevisionData() ) {
|
||||
if ( Hooks::run( 'DifferenceEngineShowDiffPageMaybeShowMissingRevision', [ $this ] ) ) {
|
||||
if ( $this->hookRunner->onDifferenceEngineShowDiffPageMaybeShowMissingRevision( $this ) ) {
|
||||
$this->showMissingRevision();
|
||||
}
|
||||
return;
|
||||
|
|
@ -641,7 +646,7 @@ class DifferenceEngine extends ContextSource {
|
|||
$samePage = true;
|
||||
$oldHeader = '';
|
||||
// Allow extensions to change the $oldHeader variable
|
||||
Hooks::run( 'DifferenceEngineOldHeaderNoOldRev', [ &$oldHeader ] );
|
||||
$this->hookRunner->onDifferenceEngineOldHeaderNoOldRev( $oldHeader );
|
||||
} else {
|
||||
// TODO replace hook with one that uses RevisionRecords
|
||||
// If old or new are falsey, keeps those values
|
||||
|
|
@ -651,7 +656,7 @@ class DifferenceEngine extends ContextSource {
|
|||
$legacyNewRev = $this->mNewRevisionRecord ?
|
||||
new Revision( $this->mNewRevisionRecord ) :
|
||||
null;
|
||||
Hooks::run( 'DiffViewHeader', [ $this, $legacyOldRev, $legacyNewRev ] );
|
||||
$this->hookRunner->onDiffViewHeader( $this, $legacyOldRev, $legacyNewRev );
|
||||
|
||||
if ( !$this->mOldPage || !$this->mNewPage ) {
|
||||
// XXX say something to the user?
|
||||
|
|
@ -736,8 +741,8 @@ class DifferenceEngine extends ContextSource {
|
|||
'<div id="mw-diff-otitle4">' . $prevlink . '</div>';
|
||||
|
||||
// Allow extensions to change the $oldHeader variable
|
||||
Hooks::run( 'DifferenceEngineOldHeader', [ $this, &$oldHeader, $prevlink, $oldminor,
|
||||
$diffOnly, $ldel, $this->unhide ] );
|
||||
$this->hookRunner->onDifferenceEngineOldHeader(
|
||||
$this, $oldHeader, $prevlink, $oldminor, $diffOnly, $ldel, $this->unhide );
|
||||
}
|
||||
|
||||
$out->addJsConfigVars( [
|
||||
|
|
@ -775,8 +780,8 @@ class DifferenceEngine extends ContextSource {
|
|||
$legacyNewRev = $this->mNewRevisionRecord ?
|
||||
new Revision( $this->mNewRevisionRecord ) :
|
||||
null;
|
||||
Hooks::run( 'DiffRevisionTools',
|
||||
[ $legacyNewRev, &$revisionTools, $legacyOldRev, $user ] );
|
||||
$this->hookRunner->onDiffRevisionTools(
|
||||
$legacyNewRev, $revisionTools, $legacyOldRev, $user );
|
||||
|
||||
$formattedRevisionTools = [];
|
||||
// Put each one in parentheses (poor man's button)
|
||||
|
|
@ -805,8 +810,9 @@ class DifferenceEngine extends ContextSource {
|
|||
'<div id="mw-diff-ntitle4">' . $nextlink . $this->markPatrolledLink() . '</div>';
|
||||
|
||||
// Allow extensions to change the $newHeader variable
|
||||
Hooks::run( 'DifferenceEngineNewHeader', [ $this, &$newHeader, $formattedRevisionTools,
|
||||
$nextlink, $rollback, $newminor, $diffOnly, $rdel, $this->unhide ] );
|
||||
$this->hookRunner->onDifferenceEngineNewHeader( $this, $newHeader,
|
||||
$formattedRevisionTools, $nextlink, $rollback, $newminor, $diffOnly,
|
||||
$rdel, $this->unhide );
|
||||
|
||||
# If the diff cannot be shown due to a deleted revision, then output
|
||||
# the diff header and links to unhide (if available)...
|
||||
|
|
@ -874,8 +880,8 @@ class DifferenceEngine extends ContextSource {
|
|||
]
|
||||
) . ']</span>';
|
||||
// Allow extensions to change the markpatrolled link
|
||||
Hooks::run( 'DifferenceEngineMarkPatrolledLink', [ $this,
|
||||
&$this->mMarkPatrolledLink, $linkInfo['rcid'] ] );
|
||||
$this->hookRunner->onDifferenceEngineMarkPatrolledLink( $this,
|
||||
$this->mMarkPatrolledLink, $linkInfo['rcid'] );
|
||||
}
|
||||
}
|
||||
return $this->mMarkPatrolledLink;
|
||||
|
|
@ -924,7 +930,7 @@ class DifferenceEngine extends ContextSource {
|
|||
// 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
|
||||
Hooks::run( 'DifferenceEngineMarkPatrolledRCID', [ &$rcid, $this, $change, $user ] );
|
||||
$this->hookRunner->onDifferenceEngineMarkPatrolledRCID( $rcid, $this, $change, $user );
|
||||
|
||||
// Build the link
|
||||
if ( $rcid ) {
|
||||
|
|
@ -983,7 +989,7 @@ class DifferenceEngine extends ContextSource {
|
|||
$out->addHTML( "<hr class='diff-hr' id='mw-oldid' />
|
||||
<h2 class='diff-currentversion-title'>{$revHeader}</h2>\n" );
|
||||
# Page content may be handled by a hooked call instead...
|
||||
if ( Hooks::run( 'ArticleContentOnDiff', [ $this, $out ] ) ) {
|
||||
if ( $this->hookRunner->onArticleContentOnDiff( $this, $out ) ) {
|
||||
$this->loadNewText();
|
||||
if ( !$this->mNewPage ) {
|
||||
// New revision is unsaved; bail out.
|
||||
|
|
@ -996,8 +1002,8 @@ class DifferenceEngine extends ContextSource {
|
|||
$out->setRevisionTimestamp( $this->mNewRevisionRecord->getTimestamp() );
|
||||
$out->setArticleFlag( true );
|
||||
|
||||
if ( !Hooks::run( 'ArticleRevisionViewCustom',
|
||||
[ $this->mNewRevisionRecord, $this->mNewPage, $this->mOldid, $out ] )
|
||||
if ( !$this->hookRunner->onArticleRevisionViewCustom(
|
||||
$this->mNewRevisionRecord, $this->mNewPage, $this->mOldid, $out )
|
||||
) {
|
||||
// Handled by extension
|
||||
// NOTE: sync with hooks called in Article::view()
|
||||
|
|
@ -1018,8 +1024,8 @@ class DifferenceEngine extends ContextSource {
|
|||
# WikiPage::getParserOutput() should not return false, but just in case
|
||||
if ( $parserOutput ) {
|
||||
// Allow extensions to change parser output here
|
||||
if ( Hooks::run( 'DifferenceEngineRenderRevisionAddParserOutput',
|
||||
[ $this, $out, $parserOutput, $wikiPage ] )
|
||||
if ( $this->hookRunner->onDifferenceEngineRenderRevisionAddParserOutput(
|
||||
$this, $out, $parserOutput, $wikiPage )
|
||||
) {
|
||||
$out->addParserOutput( $parserOutput, [
|
||||
'enableSectionEditLinks' => $this->mNewRevisionRecord->isCurrent()
|
||||
|
|
@ -1035,7 +1041,7 @@ class DifferenceEngine extends ContextSource {
|
|||
}
|
||||
|
||||
// Allow extensions to optionally not show the final patrolled link
|
||||
if ( Hooks::run( 'DifferenceEngineRenderRevisionShowFinalPatrolLink' ) ) {
|
||||
if ( $this->hookRunner->onDifferenceEngineRenderRevisionShowFinalPatrolLink() ) {
|
||||
# Add redundant patrol link on bottom...
|
||||
$out->addHTML( $this->markPatrolledLink() );
|
||||
}
|
||||
|
|
@ -1073,7 +1079,7 @@ class DifferenceEngine extends ContextSource {
|
|||
*/
|
||||
public function showDiff( $otitle, $ntitle, $notice = '' ) {
|
||||
// Allow extensions to affect the output here
|
||||
Hooks::run( 'DifferenceEngineShowDiff', [ $this ] );
|
||||
$this->hookRunner->onDifferenceEngineShowDiff( $this );
|
||||
|
||||
$diff = $this->getDiff( $otitle, $ntitle, $notice );
|
||||
if ( $diff === false ) {
|
||||
|
|
@ -1164,7 +1170,7 @@ class DifferenceEngine extends ContextSource {
|
|||
$this->mOldRevisionRecord->getId() &&
|
||||
$this->mOldRevisionRecord->getId() == $this->mNewRevisionRecord->getId()
|
||||
) ) {
|
||||
if ( Hooks::run( 'DifferenceEngineShowEmptyOldContent', [ $this ] ) ) {
|
||||
if ( $this->hookRunner->onDifferenceEngineShowEmptyOldContent( $this ) ) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
|
@ -1217,11 +1223,8 @@ class DifferenceEngine extends ContextSource {
|
|||
$difftext .= $slotDiff;
|
||||
}
|
||||
|
||||
// Avoid PHP 7.1 warning from passing $this by reference
|
||||
$diffEngine = $this;
|
||||
|
||||
// Save to cache for 7 days
|
||||
if ( !Hooks::run( 'AbortDiffCache', [ &$diffEngine ] ) ) {
|
||||
if ( !$this->hookRunner->onAbortDiffCache( $this ) ) {
|
||||
$stats->updateCount( 'diff_cache.uncacheable', 1 );
|
||||
} elseif ( $key !== false && $difftext !== false ) {
|
||||
$stats->updateCount( 'diff_cache.miss', 1 );
|
||||
|
|
@ -1915,6 +1918,7 @@ class DifferenceEngine extends ContextSource {
|
|||
* @return array List of two revision ids, older first, later second.
|
||||
* Zero signifies invalid argument passed.
|
||||
* false signifies that there is no previous/next revision ($old is the oldest/newest one).
|
||||
* @phan-return (int|false)[]
|
||||
*/
|
||||
public function mapDiffPrevNext( $old, $new ) {
|
||||
$rl = MediaWikiServices::getInstance()->getRevisionLookup();
|
||||
|
|
@ -1968,10 +1972,8 @@ class DifferenceEngine extends ContextSource {
|
|||
$this->mNewid = 0;
|
||||
}
|
||||
|
||||
Hooks::run(
|
||||
'NewDifferenceEngine',
|
||||
[ $this->getTitle(), &$this->mOldid, &$this->mNewid, $old, $new ]
|
||||
);
|
||||
$this->hookRunner->onNewDifferenceEngine(
|
||||
$this->getTitle(), $this->mOldid, $this->mNewid, $old, $new );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2127,7 +2129,7 @@ class DifferenceEngine extends ContextSource {
|
|||
RevisionRecord::FOR_THIS_USER,
|
||||
$this->getUser()
|
||||
);
|
||||
Hooks::run( 'DifferenceEngineLoadTextAfterNewContentIsLoaded', [ $this ] );
|
||||
$this->hookRunner->onDifferenceEngineLoadTextAfterNewContentIsLoaded( $this );
|
||||
if ( $this->mNewContent === null ) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2157,7 +2159,7 @@ class DifferenceEngine extends ContextSource {
|
|||
$this->getUser()
|
||||
);
|
||||
|
||||
Hooks::run( 'DifferenceEngineAfterLoadNewText', [ $this ] );
|
||||
$this->hookRunner->onDifferenceEngineAfterLoadNewText( $this );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -664,7 +664,7 @@ TXT;
|
|||
$logger->error( $json, [ 'private' => true ] );
|
||||
}
|
||||
|
||||
Hooks::run( 'LogException', [ $e, false ] );
|
||||
Hooks::runner()->onLogException( $e, false );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -709,6 +709,6 @@ TXT;
|
|||
$logger->log( $unfilteredLevel, $json, [ 'private' => true ] );
|
||||
}
|
||||
|
||||
Hooks::run( 'LogException', [ $e, $suppressed ] );
|
||||
Hooks::runner()->onLogException( $e, $suppressed );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue