MediaWiki
REL1_19
|
00001 <?php 00032 class SpecialImport extends SpecialPage { 00033 00034 private $interwiki = false; 00035 private $namespace; 00036 private $frompage = ''; 00037 private $logcomment= false; 00038 private $history = true; 00039 private $includeTemplates = false; 00040 private $pageLinkDepth; 00041 00045 public function __construct() { 00046 parent::__construct( 'Import', 'import' ); 00047 global $wgImportTargetNamespace; 00048 $this->namespace = $wgImportTargetNamespace; 00049 } 00050 00054 function execute( $par ) { 00055 $this->setHeaders(); 00056 $this->outputHeader(); 00057 00058 $user = $this->getUser(); 00059 if ( !$user->isAllowedAny( 'import', 'importupload' ) ) { 00060 throw new PermissionsError( 'import' ); 00061 } 00062 00063 # @todo Allow Title::getUserPermissionsErrors() to take an array 00064 # @todo FIXME: Title::checkSpecialsAndNSPermissions() has a very wierd expectation of what 00065 # getUserPermissionsErrors() might actually be used for, hence the 'ns-specialprotected' 00066 $errors = wfMergeErrorArrays( 00067 $this->getTitle()->getUserPermissionsErrors( 00068 'import', $user, true, 00069 array( 'ns-specialprotected', 'badaccess-group0', 'badaccess-groups' ) 00070 ), 00071 $this->getTitle()->getUserPermissionsErrors( 00072 'importupload', $user, true, 00073 array( 'ns-specialprotected', 'badaccess-group0', 'badaccess-groups' ) 00074 ) 00075 ); 00076 00077 if ( $errors ) { 00078 throw new PermissionsError( 'import', $errors ); 00079 } 00080 00081 $this->checkReadOnly(); 00082 00083 $request = $this->getRequest(); 00084 if ( $request->wasPosted() && $request->getVal( 'action' ) == 'submit' ) { 00085 $this->doImport(); 00086 } 00087 $this->showForm(); 00088 } 00089 00093 private function doImport() { 00094 global $wgImportSources, $wgExportMaxLinkDepth; 00095 00096 $isUpload = false; 00097 $request = $this->getRequest(); 00098 $this->namespace = $request->getIntOrNull( 'namespace' ); 00099 $sourceName = $request->getVal( "source" ); 00100 00101 $this->logcomment = $request->getText( 'log-comment' ); 00102 $this->pageLinkDepth = $wgExportMaxLinkDepth == 0 ? 0 : $request->getIntOrNull( 'pagelink-depth' ); 00103 00104 $user = $this->getUser(); 00105 if ( !$user->matchEditToken( $request->getVal( 'editToken' ) ) ) { 00106 $source = Status::newFatal( 'import-token-mismatch' ); 00107 } elseif ( $sourceName == 'upload' ) { 00108 $isUpload = true; 00109 if( $user->isAllowed( 'importupload' ) ) { 00110 $source = ImportStreamSource::newFromUpload( "xmlimport" ); 00111 } else { 00112 throw new PermissionsError( 'importupload' ); 00113 } 00114 } elseif ( $sourceName == "interwiki" ) { 00115 if( !$user->isAllowed( 'import' ) ){ 00116 throw new PermissionsError( 'import' ); 00117 } 00118 $this->interwiki = $request->getVal( 'interwiki' ); 00119 if ( !in_array( $this->interwiki, $wgImportSources ) ) { 00120 $source = Status::newFatal( "import-invalid-interwiki" ); 00121 } else { 00122 $this->history = $request->getCheck( 'interwikiHistory' ); 00123 $this->frompage = $request->getText( "frompage" ); 00124 $this->includeTemplates = $request->getCheck( 'interwikiTemplates' ); 00125 $source = ImportStreamSource::newFromInterwiki( 00126 $this->interwiki, 00127 $this->frompage, 00128 $this->history, 00129 $this->includeTemplates, 00130 $this->pageLinkDepth ); 00131 } 00132 } else { 00133 $source = Status::newFatal( "importunknownsource" ); 00134 } 00135 00136 $out = $this->getOutput(); 00137 if( !$source->isGood() ) { 00138 $out->wrapWikiMsg( "<p class=\"error\">\n$1\n</p>", array( 'importfailed', $source->getWikiText() ) ); 00139 } else { 00140 $out->addWikiMsg( "importstart" ); 00141 00142 $importer = new WikiImporter( $source->value ); 00143 if( !is_null( $this->namespace ) ) { 00144 $importer->setTargetNamespace( $this->namespace ); 00145 } 00146 $reporter = new ImportReporter( $importer, $isUpload, $this->interwiki , $this->logcomment); 00147 $reporter->setContext( $this->getContext() ); 00148 $exception = false; 00149 00150 $reporter->open(); 00151 try { 00152 $importer->doImport(); 00153 } catch ( MWException $e ) { 00154 $exception = $e; 00155 } 00156 $result = $reporter->close(); 00157 00158 if ( $exception ) { 00159 # No source or XML parse error 00160 $out->wrapWikiMsg( "<p class=\"error\">\n$1\n</p>", array( 'importfailed', $exception->getMessage() ) ); 00161 } elseif( !$result->isGood() ) { 00162 # Zero revisions 00163 $out->wrapWikiMsg( "<p class=\"error\">\n$1\n</p>", array( 'importfailed', $result->getWikiText() ) ); 00164 } else { 00165 # Success! 00166 $out->addWikiMsg( 'importsuccess' ); 00167 } 00168 $out->addHTML( '<hr />' ); 00169 } 00170 } 00171 00172 private function showForm() { 00173 global $wgImportSources, $wgExportMaxLinkDepth; 00174 00175 $action = $this->getTitle()->getLocalUrl( array( 'action' => 'submit' ) ); 00176 $user = $this->getUser(); 00177 $out = $this->getOutput(); 00178 00179 if( $user->isAllowed( 'importupload' ) ) { 00180 $out->addWikiMsg( "importtext" ); 00181 $out->addHTML( 00182 Xml::fieldset( wfMsg( 'import-upload' ) ). 00183 Xml::openElement( 'form', array( 'enctype' => 'multipart/form-data', 'method' => 'post', 00184 'action' => $action, 'id' => 'mw-import-upload-form' ) ) . 00185 Html::hidden( 'action', 'submit' ) . 00186 Html::hidden( 'source', 'upload' ) . 00187 Xml::openElement( 'table', array( 'id' => 'mw-import-table' ) ) . 00188 00189 "<tr> 00190 <td class='mw-label'>" . 00191 Xml::label( wfMsg( 'import-upload-filename' ), 'xmlimport' ) . 00192 "</td> 00193 <td class='mw-input'>" . 00194 Xml::input( 'xmlimport', 50, '', array( 'type' => 'file' ) ) . ' ' . 00195 "</td> 00196 </tr> 00197 <tr> 00198 <td class='mw-label'>" . 00199 Xml::label( wfMsg( 'import-comment' ), 'mw-import-comment' ) . 00200 "</td> 00201 <td class='mw-input'>" . 00202 Xml::input( 'log-comment', 50, '', 00203 array( 'id' => 'mw-import-comment', 'type' => 'text' ) ) . ' ' . 00204 "</td> 00205 </tr> 00206 <tr> 00207 <td></td> 00208 <td class='mw-submit'>" . 00209 Xml::submitButton( wfMsg( 'uploadbtn' ) ) . 00210 "</td> 00211 </tr>" . 00212 Xml::closeElement( 'table' ). 00213 Html::hidden( 'editToken', $user->getEditToken() ) . 00214 Xml::closeElement( 'form' ) . 00215 Xml::closeElement( 'fieldset' ) 00216 ); 00217 } else { 00218 if( empty( $wgImportSources ) ) { 00219 $out->addWikiMsg( 'importnosources' ); 00220 } 00221 } 00222 00223 if( $user->isAllowed( 'import' ) && !empty( $wgImportSources ) ) { 00224 # Show input field for import depth only if $wgExportMaxLinkDepth > 0 00225 $importDepth = ''; 00226 if( $wgExportMaxLinkDepth > 0 ) { 00227 $importDepth = "<tr> 00228 <td class='mw-label'>" . 00229 wfMsgExt( 'export-pagelinks', 'parseinline' ) . 00230 "</td> 00231 <td class='mw-input'>" . 00232 Xml::input( 'pagelink-depth', 3, 0 ) . 00233 "</td> 00234 </tr>"; 00235 } 00236 00237 $out->addHTML( 00238 Xml::fieldset( wfMsg( 'importinterwiki' ) ) . 00239 Xml::openElement( 'form', array( 'method' => 'post', 'action' => $action, 'id' => 'mw-import-interwiki-form' ) ) . 00240 wfMsgExt( 'import-interwiki-text', array( 'parse' ) ) . 00241 Html::hidden( 'action', 'submit' ) . 00242 Html::hidden( 'source', 'interwiki' ) . 00243 Html::hidden( 'editToken', $user->getEditToken() ) . 00244 Xml::openElement( 'table', array( 'id' => 'mw-import-table' ) ) . 00245 "<tr> 00246 <td class='mw-label'>" . 00247 Xml::label( wfMsg( 'import-interwiki-source' ), 'interwiki' ) . 00248 "</td> 00249 <td class='mw-input'>" . 00250 Xml::openElement( 'select', array( 'name' => 'interwiki' ) ) 00251 ); 00252 foreach( $wgImportSources as $prefix ) { 00253 $selected = ( $this->interwiki === $prefix ) ? ' selected="selected"' : ''; 00254 $out->addHTML( Xml::option( $prefix, $prefix, $selected ) ); 00255 } 00256 00257 $out->addHTML( 00258 Xml::closeElement( 'select' ) . 00259 Xml::input( 'frompage', 50, $this->frompage ) . 00260 "</td> 00261 </tr> 00262 <tr> 00263 <td> 00264 </td> 00265 <td class='mw-input'>" . 00266 Xml::checkLabel( wfMsg( 'import-interwiki-history' ), 'interwikiHistory', 'interwikiHistory', $this->history ) . 00267 "</td> 00268 </tr> 00269 <tr> 00270 <td> 00271 </td> 00272 <td class='mw-input'>" . 00273 Xml::checkLabel( wfMsg( 'import-interwiki-templates' ), 'interwikiTemplates', 'interwikiTemplates', $this->includeTemplates ) . 00274 "</td> 00275 </tr> 00276 $importDepth 00277 <tr> 00278 <td class='mw-label'>" . 00279 Xml::label( wfMsg( 'import-interwiki-namespace' ), 'namespace' ) . 00280 "</td> 00281 <td class='mw-input'>" . 00282 Xml::namespaceSelector( $this->namespace, '' ) . 00283 "</td> 00284 </tr> 00285 <tr> 00286 <td class='mw-label'>" . 00287 Xml::label( wfMsg( 'import-comment' ), 'mw-interwiki-comment' ) . 00288 "</td> 00289 <td class='mw-input'>" . 00290 Xml::input( 'log-comment', 50, '', 00291 array( 'id' => 'mw-interwiki-comment', 'type' => 'text' ) ) . ' ' . 00292 "</td> 00293 </tr> 00294 <tr> 00295 <td> 00296 </td> 00297 <td class='mw-submit'>" . 00298 Xml::submitButton( wfMsg( 'import-interwiki-submit' ), Linker::tooltipAndAccesskeyAttribs( 'import' ) ) . 00299 "</td> 00300 </tr>" . 00301 Xml::closeElement( 'table' ). 00302 Xml::closeElement( 'form' ) . 00303 Xml::closeElement( 'fieldset' ) 00304 ); 00305 } 00306 } 00307 } 00308 00313 class ImportReporter extends ContextSource { 00314 private $reason=false; 00315 private $mOriginalLogCallback = null; 00316 private $mOriginalPageOutCallback = null; 00317 private $mLogItemCount = 0; 00318 00319 function __construct( $importer, $upload, $interwiki , $reason=false ) { 00320 $this->mOriginalPageOutCallback = 00321 $importer->setPageOutCallback( array( $this, 'reportPage' ) ); 00322 $this->mOriginalLogCallback = 00323 $importer->setLogItemCallback( array( $this, 'reportLogItem' ) ); 00324 $importer->setNoticeCallback( array( $this, 'reportNotice' ) ); 00325 $this->mPageCount = 0; 00326 $this->mIsUpload = $upload; 00327 $this->mInterwiki = $interwiki; 00328 $this->reason = $reason; 00329 } 00330 00331 function open() { 00332 $this->getOutput()->addHTML( "<ul>\n" ); 00333 } 00334 00335 function reportNotice( $msg, array $params ) { 00336 $this->getOutput()->addHTML( Html::element( 'li', array(), $this->msg( $msg, $params )->text() ) ); 00337 } 00338 00339 function reportLogItem( /* ... */ ) { 00340 $this->mLogItemCount++; 00341 if ( is_callable( $this->mOriginalLogCallback ) ) { 00342 call_user_func_array( $this->mOriginalLogCallback, func_get_args() ); 00343 } 00344 } 00345 00354 function reportPage( $title, $origTitle, $revisionCount, $successCount, $pageInfo ) { 00355 global $wgContLang; 00356 00357 $args = func_get_args(); 00358 call_user_func_array( $this->mOriginalPageOutCallback, $args ); 00359 00360 if ( $title === null ) { 00361 # Invalid or non-importable title; a notice is already displayed 00362 return; 00363 } 00364 00365 $this->mPageCount++; 00366 00367 $localCount = $this->getLanguage()->formatNum( $successCount ); 00368 $contentCount = $wgContLang->formatNum( $successCount ); 00369 00370 if( $successCount > 0 ) { 00371 $this->getOutput()->addHTML( "<li>" . Linker::linkKnown( $title ) . " " . 00372 wfMsgExt( 'import-revision-count', array( 'parsemag', 'escape' ), $localCount ) . 00373 "</li>\n" 00374 ); 00375 00376 $log = new LogPage( 'import' ); 00377 if( $this->mIsUpload ) { 00378 $detail = wfMsgExt( 'import-logentry-upload-detail', array( 'content', 'parsemag' ), 00379 $contentCount ); 00380 if ( $this->reason ) { 00381 $detail .= wfMsgForContent( 'colon-separator' ) . $this->reason; 00382 } 00383 $log->addEntry( 'upload', $title, $detail ); 00384 } else { 00385 $interwiki = '[[:' . $this->mInterwiki . ':' . 00386 $origTitle->getPrefixedText() . ']]'; 00387 $detail = wfMsgExt( 'import-logentry-interwiki-detail', array( 'content', 'parsemag' ), 00388 $contentCount, $interwiki ); 00389 if ( $this->reason ) { 00390 $detail .= wfMsgForContent( 'colon-separator' ) . $this->reason; 00391 } 00392 $log->addEntry( 'interwiki', $title, $detail ); 00393 } 00394 00395 $comment = $detail; // quick 00396 $dbw = wfGetDB( DB_MASTER ); 00397 $latest = $title->getLatestRevID(); 00398 $nullRevision = Revision::newNullRevision( $dbw, $title->getArticleId(), $comment, true ); 00399 if (!is_null($nullRevision)) { 00400 $nullRevision->insertOn( $dbw ); 00401 $page = WikiPage::factory( $title ); 00402 # Update page record 00403 $page->updateRevisionOn( $dbw, $nullRevision ); 00404 wfRunHooks( 'NewRevisionFromEditComplete', array( $page, $nullRevision, $latest, $this->getUser() ) ); 00405 } 00406 } else { 00407 $this->getOutput()->addHTML( "<li>" . Linker::linkKnown( $title ) . " " . 00408 wfMsgHtml( 'import-nonewrevisions' ) . "</li>\n" ); 00409 } 00410 } 00411 00412 function close() { 00413 $out = $this->getOutput(); 00414 if ( $this->mLogItemCount > 0 ) { 00415 $msg = wfMsgExt( 'imported-log-entries', 'parseinline', 00416 $this->getLanguage()->formatNum( $this->mLogItemCount ) ); 00417 $out->addHTML( Xml::tags( 'li', null, $msg ) ); 00418 } elseif( $this->mPageCount == 0 && $this->mLogItemCount == 0 ) { 00419 $out->addHTML( "</ul>\n" ); 00420 return Status::newFatal( 'importnopages' ); 00421 } 00422 $out->addHTML( "</ul>\n" ); 00423 00424 return Status::newGood( $this->mPageCount ); 00425 } 00426 }