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(
142 $this->msg(
'pt-movepage-logreason', $this->oldTitle )->inContentLanguage()->text(),
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()->addWikiMsg(
219 $this->getLogPageWikiLink(
220 $this->bundleFactory->getBundle( Title::newFromText( $this->oldText ) )
224 HTMLForm::factory(
'ooui', $this->getCommonFormFields(), $this->getContext() )
225 ->setMethod(
'post' )
226 ->setAction( $this->getPageTitle( $this->oldText )->getLocalURL() )
227 ->setSubmitName(
'subaction' )
228 ->setSubmitTextMsg(
'pt-movepage-action-check' )
229 ->setWrapperLegendMsg(
230 $bundle instanceof
MessageBundle ?
'pt-movepage-messagebundle-legend' :
'pt-movepage-legend'
233 ->displayForm(
false );
241 $out = $this->getOutput();
245 $this->getLogPageWikiLink(
246 $this->bundleFactory->getBundle( Title::newFromText( $this->oldText ) )
256 'pt-movepage-list-pages' => [ $pageCollection->getTranslatablePage() ],
263 $pagesToMove[
'pt-movepage-list-other'] = $subpages;
266 foreach ( $pagesToMove as $type => $pages ) {
267 $this->addSectionHeaderAndMessage( $out, $type, $pages );
275 foreach ( $pages as $pagePairs ) {
278 if ( $type ===
'pt-movepage-list-other' ) {
282 $old = $pagePairs->getOldTitle();
283 $new = $pagePairs->getNewTitle();
284 $line =
'* ' . $old->getPrefixedText() .
' → ' . $new->getPrefixedText();
285 if ( $pagePairs->hasTalkpage() ) {
288 $line .=
' ' . $this->msg(
'pt-movepage-talkpage-exists' )->text();
294 $out->addWikiTextAsInterface( implode(
"\n", $lines ) );
298 $sectionType =
'pt-movepage-list-translatable';
299 $this->addSectionHeaderAndMessage( $out, $sectionType, $translatableSubpages );
300 if ( $translatableSubpages ) {
302 $out->wrapWikiMsg(
"'''$1'''", $this->msg(
'pt-movepage-list-translatable-note' ) );
303 foreach ( $translatableSubpages as $page ) {
304 $lines[] =
'* ' . $page->getPrefixedText();
306 $out->addWikiTextAsInterface( implode(
"\n", $lines ) );
309 $out->addWikiTextAsInterface(
"----\n" );
311 'pt-movepage-list-count',
312 $this->getLanguage()->formatNum( $count ),
313 $this->getLanguage()->formatNum( $subpagesCount ),
314 $this->getLanguage()->formatNum( $talkpagesCount )
317 $formDescriptor = array_merge(
318 $this->getCommonFormFields(),
322 'name' =>
'subpages',
323 'id' =>
'mw-subpages',
324 'label-message' =>
'pt-movepage-subpages',
325 'default' => $this->moveSubpages,
329 'name' =>
'talkpages',
330 'id' =>
'mw-talkpages',
331 'label-message' =>
'pt-movepage-talkpages',
332 'default' => $this->moveTalkpages
337 $htmlForm = HTMLForm::factory(
'ooui', $formDescriptor, $this->getContext() );
340 'name' =>
'subaction',
341 'value' => $this->msg(
'pt-movepage-action-other' )->text(),
343 ->setMethod(
'post' )
344 ->setAction( $this->getPageTitle( $this->oldText )->getLocalURL() )
345 ->setSubmitName(
'subaction' )
346 ->setSubmitTextMsg(
'pt-movepage-action-perform' )
347 ->setWrapperLegendMsg(
348 $bundle instanceof MessageBundle ?
'pt-movepage-messagebundle-legend' :
'pt-movepage-legend'
351 ->displayForm( false );
355 private function addSectionHeaderAndMessage( OutputPage $out,
string $type, array $pages ): void {
356 $pageCount = count( $pages );
357 $out->wrapWikiMsg(
'=== $1 ===', [ $type, $pageCount ] );
360 $out->addWikiMsg(
'pt-movepage-list-no-pages' );
364 private function getSubactionFromRequest(
string $subactionText ): string {
365 switch ( $subactionText ) {
366 case $this->msg(
'pt-movepage-action-check' )->text():
368 case $this->msg(
'pt-movepage-action-perform' )->text():
370 case $this->msg(
'pt-movepage-action-other' )->text():
377 private function getCommonFormFields(): array {
381 'name' =>
'wpOldTitle',
382 'label-message' =>
'pt-movepage-current',
383 'default' => $this->oldText,
388 'name' =>
'wpNewTitle',
389 'label-message' =>
'pt-movepage-new',
394 'label-message' =>
'pt-movepage-reason',
395 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
396 'default' => $this->reason,
400 'name' =>
'subpages',
401 'default' => $this->moveSubpages,
405 'name' =>
'talkpages',
406 'default' => $this->moveTalkpages
411 private function getSpecialPageTitle( TranslatableBundle $bundle ): Message {
412 if ( $bundle instanceof TranslatablePage ) {
413 return $this->msg(
'pt-movepage-title', $this->oldText );
414 } elseif ( $bundle instanceof MessageBundle ) {
415 return $this->msg(
'pt-movepage-messagebundle-title', $this->oldText );
418 throw new InvalidArgumentException(
'TranslatableBundle is neither a TranslatablePage or MessageBundle' );
421 private function getLogPageWikiLink( ?TranslatableBundle $bundle ): string {
422 if ( $bundle instanceof MessageBundle ) {
423 return 'Special:Log/messagebundle';
427 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:GroupSynchronizationCache'=> static function(MediaWikiServices $services):GroupSynchronizationCache { return new GroupSynchronizationCache( $services->get( 'Translate:PersistentCache'));}, 'Translate:MessageBundleStore'=> static function(MediaWikiServices $services):MessageBundleStore { return new MessageBundleStore(new RevTagStore(), $services->getJobQueueGroup(), $services->getLanguageNameUtils(), $services->get( 'Translate:MessageIndex'));}, 'Translate:MessageGroupReview'=> static function(MediaWikiServices $services):MessageGroupReview { return new MessageGroupReview($services->getDBLoadBalancer(), $services->getHookContainer());}, 'Translate:MessageGroupStatsTableFactory'=> static function(MediaWikiServices $services):MessageGroupStatsTableFactory { return new MessageGroupStatsTableFactory($services->get( 'Translate:ProgressStatsTableFactory'), $services->getDBLoadBalancer(), $services->getLinkRenderer(), $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:SubpageListBuilder'=> static function(MediaWikiServices $services):SubpageListBuilder { return new SubpageListBuilder($services->get( 'Translate:TranslatableBundleFactory'), $services->getLinkBatchFactory());}, 'Translate:TranslatableBundleFactory'=> static function(MediaWikiServices $services):TranslatableBundleFactory { return new TranslatableBundleFactory($services->get( 'Translate:TranslatablePageStore'), $services->get( 'Translate:MessageBundleStore'));}, '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(), new RevTagStore(), $services->getDBLoadBalancer(), $services->get( 'Translate:TranslatableBundleStatusStore'));}, 'Translate:TranslationStashReader'=> static function(MediaWikiServices $services):TranslationStashReader { $db=$services->getDBLoadBalancer() ->getConnectionRef(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());}, '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