34 private $importSources;
41 parent::__construct(
'Import',
'import' );
43 $this->wikiImporterFactory = $wikiImporterFactory;
63 if ( !is_array( $this->importSources ) ) {
64 throw new UnexpectedValueException(
'$wgImportSources must be an array' );
66 $this->
getHookRunner()->onImportSources( $this->importSources );
69 $statusImport = PermissionStatus::newEmpty();
70 $authority->isDefinitelyAllowed(
'import', $statusImport );
71 $statusImportUpload = PermissionStatus::newEmpty();
72 $authority->isDefinitelyAllowed(
'importupload', $statusImportUpload );
77 if ( !$statusImport->isGood() && !$statusImportUpload->isGood() ) {
80 $out->prepareErrorPage();
81 $out->setPageTitleMsg( $this->
msg(
'permissionserrors' ) );
82 $out->addModuleStyles(
'mediawiki.codex.messagebox.styles' );
83 $out->addWikiTextAsInterface( Html::errorBox(
84 $out->formatPermissionStatus( $statusImport,
'import' )
86 $out->addWikiTextAsInterface( Html::errorBox(
87 $out->formatPermissionStatus( $statusImportUpload,
'importupload' )
92 $out->addModules(
'mediawiki.misc-authed-ooui' );
93 $out->addModuleStyles(
'mediawiki.special.import.styles.ooui' );
98 if ( $request->wasPosted() && $request->getRawVal(
'action' ) ==
'submit' ) {
107 private function doImport() {
110 $sourceName = $request->getVal(
'source' );
111 $assignKnownUsers = $request->getCheck(
'assignKnownUsers' );
113 $logcomment = $request->getText(
'log-comment' );
116 : $request->getIntOrNull(
'pagelink-depth' );
119 $mapping = $request->getVal(
'mapping' );
121 if ( $mapping ===
'namespace' ) {
122 $namespace = $request->getIntOrNull(
'namespace' );
123 } elseif ( $mapping ===
'subpage' ) {
124 $rootpage = $request->getText(
'rootpage' );
129 $status = PermissionStatus::newEmpty();
131 $fullInterwikiPrefix =
null;
132 if ( !$user->matchEditToken( $request->getVal(
'wpEditToken' ) ) ) {
133 $source = Status::newFatal(
'import-token-mismatch' );
134 } elseif ( $sourceName ===
'upload' ) {
136 $fullInterwikiPrefix = $request->getVal(
'usernamePrefix' );
137 if ( $authority->authorizeAction(
'importupload', $status ) ) {
138 $source = ImportStreamSource::newFromUpload(
"xmlimport" );
140 throw new PermissionsError(
'importupload', $status );
142 } elseif ( $sourceName ===
'interwiki' ) {
143 if ( !$authority->authorizeAction(
'import', $status ) ) {
144 throw new PermissionsError(
'import', $status );
146 $interwiki = $fullInterwikiPrefix = $request->getVal(
'interwiki' );
148 $hasSubprojects = array_key_exists( $interwiki, $this->importSources );
149 if ( !$hasSubprojects && !in_array( $interwiki, $this->importSources ) ) {
150 $source = Status::newFatal(
"import-invalid-interwiki" );
153 if ( $hasSubprojects ) {
154 $subproject = $request->getVal(
'subproject' );
156 if ( str_starts_with( $subproject, $interwiki .
'::' ) ) {
157 $subproject = substr( $subproject, strlen( $interwiki .
'::' ) );
159 $fullInterwikiPrefix .=
':' . $subproject;
161 if ( $hasSubprojects &&
162 !in_array( $subproject, $this->importSources[$interwiki] )
164 $source = Status::newFatal(
'import-invalid-interwiki' );
166 $history = $request->getCheck(
'interwikiHistory' );
167 $frompage = $request->getText(
'frompage' );
168 $includeTemplates = $request->getCheck(
'interwikiTemplates' );
169 $source = ImportStreamSource::newFromInterwiki(
171 $fullInterwikiPrefix,
179 $source = Status::newFatal(
"importunknownsource" );
182 if ( (
string)$fullInterwikiPrefix ===
'' ) {
183 $source->fatal(
'importnoprefix' );
189 Html::errorBox(
'$1' ),
192 $source->getWikiText(
false,
false, $this->getLanguage() ),
193 count(
$source->getMessages() )
197 $importer = $this->wikiImporterFactory->getWikiImporter(
$source->value, $this->getAuthority() );
198 if ( $namespace !==
null ) {
199 $importer->setTargetNamespace( $namespace );
200 } elseif ( $rootpage !==
null ) {
201 $statusRootPage = $importer->setTargetRootPage( $rootpage );
202 if ( !$statusRootPage->isGood() ) {
204 Html::errorBox(
'$1' ),
206 'import-options-wrong',
207 $statusRootPage->getWikiText(
false,
false, $this->getLanguage() ),
208 count( $statusRootPage->getMessages() )
216 $importer->setUsernamePrefix( $fullInterwikiPrefix, $assignKnownUsers );
218 $out->addWikiMsg(
"importstart" );
224 $fullInterwikiPrefix,
232 $importer->doImport();
233 }
catch ( DBError | TimeoutException $e ) {
236 }
catch ( Exception $e ) {
239 $result = $reporter->close();
243 # No source or XML parse error
245 Html::errorBox(
'$1' ),
248 } elseif ( !$result->isGood() ) {
251 Html::errorBox(
'$1' ),
254 $result->getWikiText(
false,
false, $this->getLanguage() ),
255 count( $result->getMessages() )
260 $out->addWikiMsg(
'importsuccess' );
265 private function getMappingFormPart(
string $sourceName ): array {
266 $defaultNamespace = $this->
getConfig()->get( MainConfigNames::ImportTargetNamespace );
272 'id' =>
"mw-import-mapping-$sourceName",
273 'options-messages' => [
274 'import-mapping-default' =>
'default',
275 'import-mapping-namespace' =>
'namespace',
276 'import-mapping-subpage' =>
'subpage'
278 'default' => $defaultNamespace !==
null ?
'namespace' :
'default'
281 'type' =>
'namespaceselect',
282 'name' =>
'namespace',
284 'id' =>
"mw-import-namespace-$sourceName",
285 'default' => $defaultNamespace ?:
'',
287 'disable-if' => [
'!==',
'mapping',
'namespace' ],
291 'name' =>
'rootpage',
294 'id' =>
"mw-interwiki-rootpage-$sourceName",
295 'disable-if' => [
'!==',
'mapping',
'subpage' ],
300 private function showForm() {
301 $action = $this->getPageTitle()->getLocalURL( [
'action' =>
'submit' ] );
304 $this->addHelpLink(
'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Import',
true );
306 $interwikiFormDescriptor = [];
307 $uploadFormDescriptor = [];
309 if ( $authority->isDefinitelyAllowed(
'importupload' ) ) {
310 $mappingSelection = $this->getMappingFormPart(
'upload' );
311 $uploadFormDescriptor += [
315 'default' => $this->
msg(
'importtext' )->parseAsBlock()
319 'name' =>
'xmlimport',
320 'accept' => [
'application/xml',
'text/xml' ],
321 'label-message' =>
'import-upload-filename',
324 'usernamePrefix' => [
326 'name' =>
'usernamePrefix',
327 'label-message' =>
'import-upload-username-prefix',
330 'assignKnownUsers' => [
332 'name' =>
'assignKnownUsers',
333 'label-message' =>
'import-assign-known-users'
337 'name' =>
'log-comment',
338 'label-message' =>
'import-comment'
343 'default' =>
'upload',
348 $uploadFormDescriptor += $mappingSelection;
350 $htmlForm = HTMLForm::factory(
'ooui', $uploadFormDescriptor, $this->
getContext() );
351 $htmlForm->setAction( $action );
352 $htmlForm->setId(
'mw-import-upload-form' );
353 $htmlForm->setWrapperLegendMsg(
'import-upload' );
354 $htmlForm->setSubmitTextMsg(
'uploadbtn' );
355 $htmlForm->prepareForm()->displayForm(
false );
357 } elseif ( !$this->importSources ) {
358 $out->addWikiMsg(
'importnosources' );
361 if ( $authority->isDefinitelyAllowed(
'import' ) && $this->importSources ) {
364 $needSubprojectField =
false;
365 foreach ( $this->importSources as $key => $value ) {
366 if ( is_int( $key ) ) {
368 } elseif ( $value !== $key ) {
369 $needSubprojectField =
true;
372 $projects[ $key ] = $key;
375 $interwikiFormDescriptor += [
379 'default' => $this->
msg(
'import-interwiki-text' )->parseAsBlock()
383 'name' =>
'interwiki',
384 'label-message' =>
'import-interwiki-sourcewiki',
385 'options' => $projects
389 if ( $needSubprojectField ) {
391 foreach ( $this->importSources as $key => $value ) {
392 if ( is_array( $value ) ) {
393 foreach ( $value as $subproject ) {
394 $subprojects[ $subproject ] = $key .
'::' . $subproject;
399 $interwikiFormDescriptor += [
402 'name' =>
'subproject',
403 'options' => $subprojects
408 $interwikiFormDescriptor += [
411 'name' =>
'frompage',
412 'label-message' =>
'import-interwiki-sourcepage'
414 'interwikiHistory' => [
416 'name' =>
'interwikiHistory',
417 'label-message' =>
'import-interwiki-history'
419 'interwikiTemplates' => [
421 'name' =>
'interwikiTemplates',
422 'label-message' =>
'import-interwiki-templates'
424 'assignKnownUsers' => [
426 'name' =>
'assignKnownUsers',
427 'label-message' =>
'import-assign-known-users'
432 $interwikiFormDescriptor += [
433 'pagelink-depth' => [
435 'name' =>
'pagelink-depth',
436 'label-message' =>
'export-pagelinks',
442 $interwikiFormDescriptor += [
445 'name' =>
'log-comment',
446 'label-message' =>
'import-comment'
451 'default' =>
'interwiki',
455 $mappingSelection = $this->getMappingFormPart(
'interwiki' );
457 $interwikiFormDescriptor += $mappingSelection;
459 $htmlForm = HTMLForm::factory(
'ooui', $interwikiFormDescriptor, $this->
getContext() );
460 $htmlForm->setAction( $action );
461 $htmlForm->setId(
'mw-import-interwiki-form' );
462 $htmlForm->setWrapperLegendMsg(
'importinterwiki' );
463 $htmlForm->setSubmitTextMsg(
'import-interwiki-submit' );
464 $htmlForm->prepareForm()->displayForm(
false );