MediaWiki master
ApiImport.php
Go to the documentation of this file.
1<?php
9namespace MediaWiki\Api;
10
11use Exception;
18
24class ApiImport extends ApiBase {
25
26 public function __construct(
27 ApiMain $main,
28 string $action,
29 private readonly WikiImporterFactory $wikiImporterFactory,
30 private readonly PermissionManager $permissionManager,
31 ) {
32 parent::__construct( $main, $action );
33 }
34
35 public function execute() {
37 $params = $this->extractRequestParams();
38
39 $this->requireMaxOneParameter( $params, 'namespace', 'rootpage' );
40
41 $isUpload = false;
42 if ( isset( $params['interwikisource'] ) ) {
43 if ( !$this->getAuthority()->isAllowed( 'import' ) ) {
44 $this->dieWithError( 'apierror-cantimport' );
45 }
46 if ( !isset( $params['interwikipage'] ) ) {
47 $this->dieWithError( [ 'apierror-missingparam', 'interwikipage' ] );
48 }
50 $params['interwikisource'],
51 $params['interwikipage'],
52 $params['fullhistory'],
53 $params['templates']
54 );
55 $usernamePrefix = $params['interwikisource'];
56 } else {
57 $isUpload = true;
58 if ( !$this->getAuthority()->isAllowed( 'importupload' ) ) {
59 $this->dieWithError( 'apierror-cantimport-upload' );
60 }
62 $usernamePrefix = (string)$params['interwikiprefix'];
63 if ( $usernamePrefix === '' ) {
64 $encParamName = $this->encodeParamName( 'interwikiprefix' );
65 $this->dieWithError( [ 'apierror-missingparam', $encParamName ] );
66 }
67 }
68 if ( !$source->isOK() ) {
69 $this->dieStatus( $source );
70 }
71
72 // Check if user can add the log entry tags which were requested
73 if ( $params['tags'] ) {
74 $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $this->getAuthority() );
75 if ( !$ableToTag->isOK() ) {
76 $this->dieStatus( $ableToTag );
77 }
78 }
79
80 $importer = $this->wikiImporterFactory->getWikiImporter( $source->value, $this->getAuthority() );
81 if ( isset( $params['namespace'] ) ) {
82 $importer->setTargetNamespace( $params['namespace'] );
83 } elseif ( isset( $params['rootpage'] ) ) {
84 $statusRootPage = $importer->setTargetRootPage( $params['rootpage'] );
85 if ( !$statusRootPage->isGood() ) {
86 $this->dieStatus( $statusRootPage );
87 }
88 }
89 $importer->setUsernamePrefix( $usernamePrefix, $params['assignknownusers'] );
90
91 // T432713#12228661 - temporarily add noratelimit for import
92 $scopedNoRateLimit = $this->permissionManager->addTemporaryUserRights(
93 $this->getUser(), 'noratelimit'
94 );
95
96 $importer->setAuthorizeOnly( true );
97 $importer->doImport();
98 if ( $importer->getReauthOperation() !== null ) {
99 $this->dieWithError(
100 [ 'badaccess-cannotreauthenticate', $importer->getReauthOperation() ],
101 'reauthenticate'
102 );
103 }
104
105 // Re-open the source; the pre-pass consumed the stream
106 $source = $isUpload
109 $params['interwikisource'],
110 $params['interwikipage'],
111 $params['fullhistory'],
112 $params['templates']
113 );
114 if ( !$source->isOK() ) {
115 $this->dieStatus( $source );
116 }
117 $importer = $this->wikiImporterFactory->getWikiImporter( $source->value, $this->getAuthority() );
118 if ( isset( $params['namespace'] ) ) {
119 $importer->setTargetNamespace( $params['namespace'] );
120 } elseif ( isset( $params['rootpage'] ) ) {
121 $importer->setTargetRootPage( $params['rootpage'] );
122 }
123 $importer->setUsernamePrefix( $usernamePrefix, $params['assignknownusers'] );
124 $importer->setAuthorizeOnly( false );
125
126 $reporter = new ApiImportReporter(
127 $importer,
128 $isUpload,
129 $params['interwikisource'],
130 $params['summary'],
131 $this
132 );
133 if ( $params['tags'] ) {
134 $reporter->setChangeTags( $params['tags'] );
135 }
136
137 try {
138 $importer->doImport();
139 } catch ( Exception $e ) {
140 $this->dieWithException( $e, [ 'wrap' => 'apierror-import-unknownerror' ] );
141 }
142
143 $resultData = $reporter->getData();
144 $result = $this->getResult();
145 ApiResult::setIndexedTagName( $resultData, 'page' );
146 $result->addValue( null, $this->getModuleName(), $resultData );
147 }
148
156 public function getAllowedImportSources() {
157 $importSources = $this->getConfig()->get( MainConfigNames::ImportSources );
158 $this->getHookRunner()->onImportSources( $importSources );
159
160 $result = [];
161 foreach ( $importSources as $key => $value ) {
162 if ( is_int( $key ) ) {
163 $result[] = $value;
164 } else {
165 foreach ( $value as $subproject ) {
166 $result[] = "$key:$subproject";
167 }
168 }
169 }
170 return $result;
171 }
172
174 public function mustBePosted() {
175 return true;
176 }
177
179 public function isWriteMode() {
180 return true;
181 }
182
184 public function getAllowedParams() {
185 return [
186 'summary' => null,
187 'xml' => [
188 ParamValidator::PARAM_TYPE => 'upload',
189 ],
190 'interwikiprefix' => [
191 ParamValidator::PARAM_TYPE => 'string',
192 ],
193 'interwikisource' => [
194 ParamValidator::PARAM_TYPE => $this->getAllowedImportSources(),
195 ],
196 'interwikipage' => null,
197 'fullhistory' => false,
198 'templates' => false,
199 'namespace' => [
200 ParamValidator::PARAM_TYPE => 'namespace'
201 ],
202 'assignknownusers' => false,
203 'rootpage' => null,
204 'tags' => [
205 ParamValidator::PARAM_TYPE => 'tags',
206 ParamValidator::PARAM_ISMULTI => true,
207 ],
208 ];
209 }
210
212 public function needsToken() {
213 return 'csrf';
214 }
215
217 protected function getExamplesMessages() {
218 return [
219 'action=import&interwikisource=meta&interwikipage=Help:ParserFunctions&' .
220 'namespace=100&fullhistory=&token=123ABC'
221 => 'apihelp-import-example-import',
222 ];
223 }
224
226 public function getHelpUrls() {
227 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Import';
228 }
229}
230
232class_alias( ApiImport::class, 'ApiImport' );
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:59
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1488
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:556
getHookRunner()
Get an ApiHookRunner for running core API hooks.
Definition ApiBase.php:780
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition ApiBase.php:1335
getResult()
Get the result object.
Definition ApiBase.php:695
requireMaxOneParameter( $params,... $required)
Dies if more than one parameter from a certain set of parameters are set and not false.
Definition ApiBase.php:1011
dieWithException(Throwable $exception, array $options=[])
Abort execution with an error derived from a throwable.
Definition ApiBase.php:1501
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
Definition ApiBase.php:814
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition ApiBase.php:1539
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:836
Import reporter for the API.
API module that imports an XML file like Special:Import does.
Definition ApiImport.php:24
needsToken()
Returns the token type this module requires in order to execute.Modules are strongly encouraged to us...
getHelpUrls()
Return links to more detailed help pages about the module.1.25, returning boolean false is deprecated...
mustBePosted()
Indicates whether this module must be called with a POST request.Implementations of this method must ...
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
Definition ApiImport.php:35
isWriteMode()
Indicates whether this module requires write access to the wiki.API modules must override this method...
__construct(ApiMain $main, string $action, private readonly WikiImporterFactory $wikiImporterFactory, private readonly PermissionManager $permissionManager,)
Definition ApiImport.php:26
getAllowedImportSources()
Returns a list of interwiki prefixes corresponding to each defined import source.
getExamplesMessages()
Returns usage examples for this module.Return value has query strings as keys, with values being eith...
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:66
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Recent changes tagging.
Imports a XML dump from a file (either from file upload, files on disk, or HTTP)
static newFromUpload( $fieldname="xmlimport")
static newFromInterwiki( $interwiki, $page, $history=false, $templates=false, $pageLinkDepth=0)
Factory service for WikiImporter instances.
A class containing constants representing the names of configuration variables.
const ImportSources
Name constant for the ImportSources setting, for use with Config::get()
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
Service for formatting and validating API parameters.
$source