diff --git a/hooks.txt b/hooks.txt index 709f8104..b696fc93 100644 --- a/hooks.txt +++ b/hooks.txt @@ -7,3 +7,6 @@ directory, and then find /docs/Hooks.md. ;ReplaceTextFilterPageTitlesForEdit: Provides other extension the ability to avoid editing content on pages based on their titles. \TitleArrayFromResult &$titles: Array of page titles whose content will be edited + +;ReplaceTextFilterPageTitlesForRename: Provides other extension the ability to avoid renaming pages based on their titles. +\TitleArrayFromResult &$titles: Array of page titles being renamed diff --git a/maintenance/replaceAll.php b/maintenance/replaceAll.php index c6d13330..3abd4809 100755 --- a/maintenance/replaceAll.php +++ b/maintenance/replaceAll.php @@ -32,7 +32,6 @@ namespace MediaWiki\Extension\ReplaceText; use Maintenance; use MediaWiki\MediaWikiServices; -use MediaWiki\Title\TitleArrayFromResult; use MWException; $IP = getenv( 'MW_INSTALL_PATH' ) ?: __DIR__ . '/../../..'; @@ -388,6 +387,7 @@ EOF; $this->output( ".\n" ); } + $hookRunner = new HookRunner( MediaWikiServices::getInstance()->getHookContainer() ); if ( $this->rename ) { $res = Search::getMatchingTitles( $target, @@ -396,7 +396,7 @@ EOF; $this->prefix, $useRegex ); - $titlesToProcess = new TitleArrayFromResult( $res ); + $titlesToProcess = $hookRunner->filterPageTitlesForRename( $res ); } else { $res = Search::doSearchQuery( $target, @@ -405,7 +405,6 @@ EOF; $this->prefix, $useRegex ); - $hookRunner = new HookRunner( MediaWikiServices::getInstance()->getHookContainer() ); $titlesToProcess = $hookRunner->filterPageTitlesForEdit( $res ); } diff --git a/src/HookRunner.php b/src/HookRunner.php index c0f88e9b..bd99ac20 100644 --- a/src/HookRunner.php +++ b/src/HookRunner.php @@ -25,6 +25,23 @@ class HookRunner { $filteredTitles = iterator_to_array( $titles ); $this->hookContainer->run( 'ReplaceTextFilterPageTitlesForEdit', [ &$filteredTitles ] ); + return $this->normalizeTitlesToProcess( $filteredTitles, $titles ); + } + + /** + * Runs the ReplaceTextFilterPageTitlesForRename hook and returns titles to be edited + * @param IResultWrapper $resultWrapper + * @return Title[] + */ + public function filterPageTitlesForRename( IResultWrapper $resultWrapper ): array { + $titles = new TitleArrayFromResult( $resultWrapper ); + $filteredTitles = iterator_to_array( $titles ); + $this->hookContainer->run( 'ReplaceTextFilterPageTitlesForRename', [ &$filteredTitles ] ); + + return $this->normalizeTitlesToProcess( $filteredTitles, $titles ); + } + + private function normalizeTitlesToProcess( array $filteredTitles, TitleArrayFromResult $titles ): array { foreach ( $filteredTitles as $title ) { $filteredTitles[ $title->getPrefixedText() ] = $title; } diff --git a/src/SpecialReplaceText.php b/src/SpecialReplaceText.php index 7ec54d26..3a5ce481 100644 --- a/src/SpecialReplaceText.php +++ b/src/SpecialReplaceText.php @@ -444,12 +444,19 @@ class SpecialReplaceText extends SpecialPage { $this->use_regex ); + $titles_to_process = $this->hookRunner->filterPageTitlesForRename( $res ); + foreach ( $res as $row ) { $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title ); if ( !$title ) { continue; } + if ( !isset( $titles_to_process[ $title->getPrefixedText() ] ) ) { + $unmoveable_titles[] = $title; + continue; + } + $new_title = Search::getReplacedTitle( $title, $this->target, @@ -515,7 +522,8 @@ class SpecialReplaceText extends SpecialPage { $this->prefix, $this->use_regex ); - $count = $res->numRows(); + $titles = $this->hookRunner->filterPageTitlesForRename( $res ); + $count = count( $titles ); if ( $count > 0 ) { return $this->msg( 'replacetext_warning' )->numParams( $count ) ->params( $this->replacement )->parse();