40 private $moveTalkpages =
true;
42 private $moveSubpages =
true;
45 private $objectFactory;
49 private $permissionManager;
51 private $bundleFactory;
52 private $movePageSpec;
57 public function __construct(
58 ObjectFactory $objectFactory,
59 PermissionManager $permissionManager,
64 parent::__construct(
'Movepage' );
65 $this->objectFactory = $objectFactory;
66 $this->permissionManager = $permissionManager;
67 $this->bundleMover = $bundleMover;
68 $this->bundleFactory = $bundleFactory;
69 $this->movePageSpec = $movePageSpec;
72 public function doesWrites():
bool {
76 protected function getGroupName():
string {
82 $request = $this->getRequest();
83 $user = $this->getUser();
84 $this->addHelpLink(
'Help:Extension:Translate/Move_translatable_page' );
86 $this->oldText = $request->getText(
88 $request->getText(
'target', $par ??
'' )
90 $newText = $request->getText(
'wpNewTitle' );
92 $this->oldTitle = Title::newFromText( $this->oldText );
93 $newTitle = Title::newFromText( $newText );
95 if ( $this->oldTitle ) {
96 $this->oldText = $this->oldTitle->getPrefixedText();
99 $this->reason = $request->getText(
'reason' );
105 $bundle = $this->bundleFactory->getBundle( $this->oldTitle );
106 if ( $bundle && $bundle->isMoveable() ) {
107 $this->getOutput()->setPageTitle( $this->getSpecialPageTitle( $bundle ) );
109 if ( !$user->isAllowed(
'pagetranslation' ) ) {
110 throw new PermissionsError(
'pagetranslation' );
113 $subaction = $this->getSubactionFromRequest( $request->getText(
'subaction' ) );
115 $isValidPostRequest = $this->
checkToken() && $request->wasPosted();
116 if ( $isValidPostRequest && $subaction ===
'check' ) {
118 $pageCollection = $this->bundleMover->getPageMoveCollection(
133 } elseif ( $isValidPostRequest && $subaction ===
'perform' ) {
134 $this->moveSubpages = $request->getBool(
'subpages' );
135 $this->moveTalkpages = $request->getBool(
'talkpages' );
137 $this->bundleMover->moveAsynchronously(
145 $this->getOutput()->addWikiMsg(
146 'pt-movepage-started',
147 $this->getLogPageWikiLink( $this->bundleFactory->getValidBundle( $this->oldTitle ) )
154 $sp = $this->objectFactory->createObject( $this->movePageSpec );
155 $sp->execute( $par );
165 $this->checkReadOnly();
167 if ( $this->oldTitle ===
null ) {
168 throw new ErrorPageError(
'notargettitle',
'notargettext' );
171 if ( !$this->oldTitle->exists() ) {
172 throw new ErrorPageError(
'nopagetitle',
'nopagetext' );
175 if ( $this->getUser()->pingLimiter(
'move' ) ) {
176 throw new ThrottledError;
180 $permErrors = $this->permissionManager
181 ->getPermissionErrors(
'move', $this->getUser(), $this->oldTitle );
182 if ( count( $permErrors ) ) {
183 throw new PermissionsError(
'move', $permErrors );
189 return $this->getContext()->getCsrfTokenSet()->matchTokenField(
'wpEditToken' );
193 protected function showErrors( SplObjectStorage $errors ): void {
196 $context =
'pt-movepage-error-placeholder';
197 foreach ( $errors as $title ) {
198 $titleText = $title->getPrefixedText();
199 $s .=
"'''$titleText'''\n\n";
200 $s .= $errors[ $title ]->getWikiText(
false, $context );
203 $out = $this->getOutput();
207 'pt-movepage-blockers',
208 $this->getLanguage()->formatNum( count( $errors ) )
210 $out->parseAsContent( $s )
217 $this->getOutput()->addBacklinkSubtitle( $this->oldTitle );
218 $this->getOutput()->addWikiMsg(
220 $this->getLogPageWikiLink(
221 $this->bundleFactory->getBundle( Title::newFromText( $this->oldText ) )
225 HTMLForm::factory(
'ooui', $this->getCommonFormFields(), $this->getContext() )
226 ->setMethod(
'post' )
227 ->setAction( $this->getPageTitle( $this->oldText )->getLocalURL() )
228 ->setSubmitName(
'subaction' )
229 ->setSubmitTextMsg(
'pt-movepage-action-check' )
230 ->setWrapperLegendMsg(
231 $bundle instanceof
MessageBundle ?
'pt-movepage-messagebundle-legend' :
'pt-movepage-legend'
234 ->displayForm(
false );
242 $out = $this->getOutput();
243 $out->addBacklinkSubtitle( $this->oldTitle );
246 $this->getLogPageWikiLink(
247 $this->bundleFactory->getBundle( Title::newFromText( $this->oldText ) )
257 'pt-movepage-list-pages' => [ $pageCollection->getTranslatablePage() ],
264 $pagesToMove[
'pt-movepage-list-other'] = $subpages;
267 foreach ( $pagesToMove as $type => $pages ) {
268 $this->addSectionHeaderAndMessage( $out, $type, $pages );
276 foreach ( $pages as $pagePairs ) {
279 if ( $type ===
'pt-movepage-list-other' ) {
283 $old = $pagePairs->getOldTitle();
284 $new = $pagePairs->getNewTitle();
285 $line =
'* ' . $old->getPrefixedText() .
' → ' . $new->getPrefixedText();
286 if ( $pagePairs->hasTalkpage() ) {
289 $line .=
' ' . $this->msg(
'pt-movepage-talkpage-exists' )->text();
295 $out->addWikiTextAsInterface( implode(
"\n", $lines ) );
299 $sectionType =
'pt-movepage-list-translatable';
300 $this->addSectionHeaderAndMessage( $out, $sectionType, $translatableSubpages );
301 if ( $translatableSubpages ) {
303 $out->wrapWikiMsg(
"'''$1'''", $this->msg(
'pt-movepage-list-translatable-note' ) );
304 foreach ( $translatableSubpages as $page ) {
305 $lines[] =
'* ' . $page->getPrefixedText();
307 $out->addWikiTextAsInterface( implode(
"\n", $lines ) );
310 $out->addWikiTextAsInterface(
"----\n" );
312 'pt-movepage-list-count',
313 $this->getLanguage()->formatNum( $count ),
314 $this->getLanguage()->formatNum( $subpagesCount ),
315 $this->getLanguage()->formatNum( $talkpagesCount )
318 $formDescriptor = array_merge(
319 $this->getCommonFormFields(),
323 'name' =>
'subpages',
324 'id' =>
'mw-subpages',
325 'label-message' =>
'pt-movepage-subpages',
326 'default' => $this->moveSubpages,
330 'name' =>
'talkpages',
331 'id' =>
'mw-talkpages',
332 'label-message' =>
'pt-movepage-talkpages',
333 'default' => $this->moveTalkpages
338 $htmlForm = HTMLForm::factory(
'ooui', $formDescriptor, $this->getContext() );
341 'name' =>
'subaction',
342 'value' => $this->msg(
'pt-movepage-action-other' )->text(),
344 ->setMethod(
'post' )
345 ->setAction( $this->getPageTitle( $this->oldText )->getLocalURL() )
346 ->setSubmitName(
'subaction' )
347 ->setSubmitTextMsg(
'pt-movepage-action-perform' )
348 ->setWrapperLegendMsg(
349 $bundle instanceof MessageBundle ?
'pt-movepage-messagebundle-legend' :
'pt-movepage-legend'
352 ->displayForm( false );
356 private function addSectionHeaderAndMessage( OutputPage $out,
string $type, array $pages ): void {
357 $pageCount = count( $pages );
358 $out->wrapWikiMsg(
'=== $1 ===', [ $type, $pageCount ] );
361 $out->addWikiMsg(
'pt-movepage-list-no-pages' );
365 private function getSubactionFromRequest(
string $subactionText ): string {
366 switch ( $subactionText ) {
367 case $this->msg(
'pt-movepage-action-check' )->text():
369 case $this->msg(
'pt-movepage-action-perform' )->text():
371 case $this->msg(
'pt-movepage-action-other' )->text():
378 private function getCommonFormFields(): array {
382 'name' =>
'wpOldTitle',
383 'label-message' =>
'pt-movepage-current',
384 'default' => $this->oldText,
389 'name' =>
'wpNewTitle',
390 'label-message' =>
'pt-movepage-new',
395 'label-message' =>
'pt-movepage-reason',
396 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
397 'default' => $this->reason,
401 'name' =>
'subpages',
402 'default' => $this->moveSubpages,
406 'name' =>
'talkpages',
407 'default' => $this->moveTalkpages
412 private function getSpecialPageTitle( TranslatableBundle $bundle ): Message {
413 if ( $bundle instanceof TranslatablePage ) {
414 return $this->msg(
'pt-movepage-title', $this->oldText );
415 } elseif ( $bundle instanceof MessageBundle ) {
416 return $this->msg(
'pt-movepage-messagebundle-title', $this->oldText );
419 throw new InvalidArgumentException(
'TranslatableBundle is neither a TranslatablePage or MessageBundle' );
422 private function getLogPageWikiLink( ?TranslatableBundle $bundle ): string {
423 if ( $bundle instanceof MessageBundle ) {
424 return 'Special:Log/messagebundle';
428 return 'Special:Log/pagetranslation';
return[ 'Translate:ConfigHelper'=> static function():ConfigHelper { return new ConfigHelper();}, 'Translate:CsvTranslationImporter'=> static function(MediaWikiServices $services):CsvTranslationImporter { return new CsvTranslationImporter( $services->getWikiPageFactory());}, 'Translate:EntitySearch'=> static function(MediaWikiServices $services):EntitySearch { return new EntitySearch($services->getMainWANObjectCache(), $services->getCollationFactory() ->makeCollation( 'uca-default-u-kn'), MessageGroups::singleton(), $services->getNamespaceInfo(), $services->get( 'Translate:MessageIndex'), $services->getTitleParser(), $services->getTitleFormatter());}, 'Translate:ExternalMessageSourceStateImporter'=> static function(MediaWikiServices $services):ExternalMessageSourceStateImporter { return new ExternalMessageSourceStateImporter($services->getMainConfig(), $services->get( 'Translate:GroupSynchronizationCache'), $services->getJobQueueGroup(), LoggerFactory::getInstance( 'Translate.GroupSynchronization'), $services->get( 'Translate:MessageIndex'));}, 'Translate:FileFormatFactory'=> static function(MediaWikiServices $services):FileFormatFactory { return new FileFormatFactory( $services->getObjectFactory());}, 'Translate:GroupSynchronizationCache'=> static function(MediaWikiServices $services):GroupSynchronizationCache { return new GroupSynchronizationCache( $services->get( 'Translate:PersistentCache'));}, 'Translate:HookRunner'=> static function(MediaWikiServices $services):HookRunner { return new HookRunner( $services->getHookContainer());}, 'Translate:MessageBundleStore'=> static function(MediaWikiServices $services):MessageBundleStore { return new MessageBundleStore($services->get( 'Translate:RevTagStore'), $services->getJobQueueGroup(), $services->getLanguageNameUtils(), $services->get( 'Translate:MessageIndex'));}, 'Translate:MessageGroupReviewStore'=> static function(MediaWikiServices $services):MessageGroupReviewStore { return new MessageGroupReviewStore($services->getDBLoadBalancer(), $services->get( 'Translate:HookRunner'));}, 'Translate:MessageGroupStatsTableFactory'=> static function(MediaWikiServices $services):MessageGroupStatsTableFactory { return new MessageGroupStatsTableFactory($services->get( 'Translate:ProgressStatsTableFactory'), $services->getDBLoadBalancer(), $services->getLinkRenderer(), $services->get( 'Translate:MessageGroupReviewStore'), $services->getMainConfig() ->get( 'TranslateWorkflowStates') !==false);}, 'Translate:MessageIndex'=> static function(MediaWikiServices $services):MessageIndex { $params=$services->getMainConfig() ->get( 'TranslateMessageIndex');if(is_string( $params)) { $params=(array) $params;} $class=array_shift( $params);return new $class( $params);}, 'Translate:MessagePrefixStats'=> static function(MediaWikiServices $services):MessagePrefixStats { return new MessagePrefixStats( $services->getTitleParser());}, 'Translate:ParsingPlaceholderFactory'=> static function():ParsingPlaceholderFactory { return new ParsingPlaceholderFactory();}, 'Translate:PersistentCache'=> static function(MediaWikiServices $services):PersistentCache { return new PersistentDatabaseCache($services->getDBLoadBalancer(), $services->getJsonCodec());}, 'Translate:ProgressStatsTableFactory'=> static function(MediaWikiServices $services):ProgressStatsTableFactory { return new ProgressStatsTableFactory($services->getLinkRenderer(), $services->get( 'Translate:ConfigHelper'));}, 'Translate:RevTagStore'=> static function(MediaWikiServices $services):RevTagStore { return new RevTagStore($services->getDBLoadBalancerFactory());}, 'Translate:SubpageListBuilder'=> static function(MediaWikiServices $services):SubpageListBuilder { return new SubpageListBuilder($services->get( 'Translate:TranslatableBundleFactory'), $services->getLinkBatchFactory());}, 'Translate:TranslatableBundleExporter'=> static function(MediaWikiServices $services):TranslatableBundleExporter { return new TranslatableBundleExporter($services->get( 'Translate:SubpageListBuilder'), $services->getWikiExporterFactory(), $services->getDBLoadBalancer());}, 'Translate:TranslatableBundleFactory'=> static function(MediaWikiServices $services):TranslatableBundleFactory { return new TranslatableBundleFactory($services->get( 'Translate:TranslatablePageStore'), $services->get( 'Translate:MessageBundleStore'));}, 'Translate:TranslatableBundleImporter'=> static function(MediaWikiServices $services):TranslatableBundleImporter { return new TranslatableBundleImporter($services->getWikiImporterFactory(), $services->get( 'Translate:TranslatablePageParser'), $services->getRevisionLookup());}, 'Translate:TranslatableBundleMover'=> static function(MediaWikiServices $services):TranslatableBundleMover { return new TranslatableBundleMover($services->getMovePageFactory(), $services->getJobQueueGroup(), $services->getLinkBatchFactory(), $services->get( 'Translate:TranslatableBundleFactory'), $services->get( 'Translate:SubpageListBuilder'), $services->getMainConfig() ->get( 'TranslatePageMoveLimit'));}, 'Translate:TranslatableBundleStatusStore'=> static function(MediaWikiServices $services):TranslatableBundleStatusStore { return new TranslatableBundleStatusStore($services->getDBLoadBalancer() ->getConnection(DB_PRIMARY), $services->getCollationFactory() ->makeCollation( 'uca-default-u-kn'), $services->getDBLoadBalancer() ->getMaintenanceConnectionRef(DB_PRIMARY));}, 'Translate:TranslatablePageParser'=> static function(MediaWikiServices $services):TranslatablePageParser { return new TranslatablePageParser($services->get( 'Translate:ParsingPlaceholderFactory'));}, 'Translate:TranslatablePageStore'=> static function(MediaWikiServices $services):TranslatablePageStore { return new TranslatablePageStore($services->get( 'Translate:MessageIndex'), $services->getJobQueueGroup(), $services->get( 'Translate:RevTagStore'), $services->getDBLoadBalancer(), $services->get( 'Translate:TranslatableBundleStatusStore'), $services->get( 'Translate:TranslatablePageParser'),);}, 'Translate:TranslationStashReader'=> static function(MediaWikiServices $services):TranslationStashReader { $db=$services->getDBLoadBalancer() ->getConnection(DB_REPLICA);return new TranslationStashStorage( $db);}, 'Translate:TranslationStatsDataProvider'=> static function(MediaWikiServices $services):TranslationStatsDataProvider { return new TranslationStatsDataProvider(new ServiceOptions(TranslationStatsDataProvider::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getObjectFactory(), $services->getDBLoadBalancer());}, 'Translate:TranslationUnitStoreFactory'=> static function(MediaWikiServices $services):TranslationUnitStoreFactory { return new TranslationUnitStoreFactory( $services->getDBLoadBalancer());}, 'Translate:TranslatorActivity'=> static function(MediaWikiServices $services):TranslatorActivity { $query=new TranslatorActivityQuery($services->getMainConfig(), $services->getDBLoadBalancer());return new TranslatorActivity($services->getMainObjectStash(), $query, $services->getJobQueueGroup());}, 'Translate:TtmServerFactory'=> static function(MediaWikiServices $services):TtmServerFactory { $config=$services->getMainConfig();$default=$config->get( 'TranslateTranslationDefaultService');if( $default===false) { $default=null;} return new TtmServerFactory( $config->get( 'TranslateTranslationServices'), $default);}]
@phpcs-require-sorted-array