1<?php 2/** 3 * Copyright © 2009 Roan Kattouw "<Firstname>.<Lastname>@gmail.com" 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 * http://www.gnu.org/copyleft/gpl.html 19 * 20 * @file 21 */ 22 23/** 24 * API module that imports an XML file like Special:Import does 25 * 26 * @ingroup API 27 */ 28class ApiImport extends ApiBase { 29 30 public function execute() { 31 $this->useTransactionalTimeLimit(); 32 $user = $this->getUser(); 33 $params = $this->extractRequestParams(); 34 35 $this->requireMaxOneParameter( $params, 'namespace', 'rootpage' ); 36 37 $isUpload = false; 38 if ( isset( $params['interwikisource'] ) ) { 39 if ( !$this->getAuthority()->isAllowed( 'import' ) ) { 40 $this->dieWithError( 'apierror-cantimport' ); 41 } 42 if ( !isset( $params['interwikipage'] ) ) { 43 $this->dieWithError( [ 'apierror-missingparam', 'interwikipage' ] ); 44 } 45 $source = ImportStreamSource::newFromInterwiki( 46 $params['interwikisource'], 47 $params['interwikipage'], 48 $params['fullhistory'], 49 $params['templates'] 50 ); 51 $usernamePrefix = $params['interwikisource']; 52 } else { 53 $isUpload = true; 54 if ( !$this->getAuthority()->isAllowed( 'importupload' ) ) { 55 $this->dieWithError( 'apierror-cantimport-upload' ); 56 } 57 $source = ImportStreamSource::newFromUpload( 'xml' ); 58 $usernamePrefix = (string)$params['interwikiprefix']; 59 if ( $usernamePrefix === '' ) { 60 $encParamName = $this->encodeParamName( 'interwikiprefix' ); 61 $this->dieWithError( [ 'apierror-missingparam', $encParamName ] ); 62 } 63 } 64 if ( !$source->isOK() ) { 65 $this->dieStatus( $source ); 66 } 67 68 // Check if user can add the log entry tags which were requested 69 if ( $params['tags'] ) { 70 $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $this->getAuthority() ); 71 if ( !$ableToTag->isOK() ) { 72 $this->dieStatus( $ableToTag ); 73 } 74 } 75 76 $importer = new WikiImporter( $source->value, $this->getConfig() ); 77 if ( isset( $params['namespace'] ) ) { 78 $importer->setTargetNamespace( $params['namespace'] ); 79 } elseif ( isset( $params['rootpage'] ) ) { 80 $statusRootPage = $importer->setTargetRootPage( $params['rootpage'] ); 81 if ( !$statusRootPage->isGood() ) { 82 $this->dieStatus( $statusRootPage ); 83 } 84 } 85 $importer->setUsernamePrefix( $usernamePrefix, $params['assignknownusers'] ); 86 $reporter = new ApiImportReporter( 87 $importer, 88 $isUpload, 89 $params['interwikisource'], 90 $params['summary'] 91 ); 92 if ( $params['tags'] ) { 93 $reporter->setChangeTags( $params['tags'] ); 94 } 95 96 try { 97 $importer->doImport(); 98 } catch ( Exception $e ) { 99 $this->dieWithException( $e, [ 'wrap' => 'apierror-import-unknownerror' ] ); 100 } 101 102 $resultData = $reporter->getData(); 103 $result = $this->getResult(); 104 ApiResult::setIndexedTagName( $resultData, 'page' ); 105 $result->addValue( null, $this->getModuleName(), $resultData ); 106 } 107 108 /** 109 * Returns a list of interwiki prefixes corresponding to each defined import 110 * source. 111 * 112 * @return array 113 * @since 1.27 114 */ 115 public function getAllowedImportSources() { 116 $importSources = $this->getConfig()->get( 'ImportSources' ); 117 $this->getHookRunner()->onImportSources( $importSources ); 118 119 $result = []; 120 foreach ( $importSources as $key => $value ) { 121 if ( is_int( $key ) ) { 122 $result[] = $value; 123 } else { 124 foreach ( $value as $subproject ) { 125 $result[] = "$key:$subproject"; 126 } 127 } 128 } 129 return $result; 130 } 131 132 public function mustBePosted() { 133 return true; 134 } 135 136 public function isWriteMode() { 137 return true; 138 } 139 140 public function getAllowedParams() { 141 return [ 142 'summary' => null, 143 'xml' => [ 144 ApiBase::PARAM_TYPE => 'upload', 145 ], 146 'interwikiprefix' => [ 147 ApiBase::PARAM_TYPE => 'string', 148 ], 149 'interwikisource' => [ 150 ApiBase::PARAM_TYPE => $this->getAllowedImportSources(), 151 ], 152 'interwikipage' => null, 153 'fullhistory' => false, 154 'templates' => false, 155 'namespace' => [ 156 ApiBase::PARAM_TYPE => 'namespace' 157 ], 158 'assignknownusers' => false, 159 'rootpage' => null, 160 'tags' => [ 161 ApiBase::PARAM_TYPE => 'tags', 162 ApiBase::PARAM_ISMULTI => true, 163 ], 164 ]; 165 } 166 167 public function needsToken() { 168 return 'csrf'; 169 } 170 171 protected function getExamplesMessages() { 172 return [ 173 'action=import&interwikisource=meta&interwikipage=Help:ParserFunctions&' . 174 'namespace=100&fullhistory=&token=123ABC' 175 => 'apihelp-import-example-import', 176 ]; 177 } 178 179 public function getHelpUrls() { 180 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Import'; 181 } 182} 183