* Special:Import/importDump fixes: report XML parse errors, accept <minor/>
authorBrion Vibber <brion@users.mediawiki.org>
Sat, 17 Sep 2005 11:10:15 +0000 (11:10 +0000)
committerBrion Vibber <brion@users.mediawiki.org>
Sat, 17 Sep 2005 11:10:15 +0000 (11:10 +0000)
RELEASE-NOTES
includes/SpecialImport.php
includes/WikiError.php
maintenance/importDump.php

index 40fe815..c5198d2 100644 (file)
@@ -112,6 +112,7 @@ fully support the editing toolbar, but was found to be too confusing.
 * Correct blob caching to reduce redundant blob loads on backups
 * (bug 3485) Fix bogus warning about filename capitalization when off
 * (bug 2792) Update rebuildrecentchanges.inc for new schema
+* Special:Import/importDump fixes: report XML parse errors, accept <minor/>
 
 
 === Caveats ===
index 5765a50..5a7db20 100644 (file)
@@ -128,6 +128,7 @@ class WikiRevision {
        var $user_text = "";
        var $text = "";
        var $comment = "";
+       var $minor = false;
        
        function setTitle( $text ) {
                $this->title = Title::newFromText( $text );
@@ -154,6 +155,10 @@ class WikiRevision {
                $this->comment = $text;
        }
        
+       function setMinor( $minor ) {
+               $this->minor = (bool)$minor;
+       }
+       
        function getTitle() {
                return $this->title;
        }
@@ -173,6 +178,10 @@ class WikiRevision {
        function getComment() {
                return $this->comment;
        }
+       
+       function getMinor() {
+               return $this->minor;
+       }
 
        function importOldRevision() {
                $fname = "WikiImporter::importOldRevision";
@@ -211,7 +220,7 @@ class WikiRevision {
                        'user'       => $userId,
                        'user_text'  => $userText,
                        'timestamp'  => $this->timestamp,
-                       'minor_edit' => 0
+                       'minor_edit' => $this->minor,
                        ) );
                $revId = $revision->insertOn( $dbw );
                $article->updateIfNewerOn( $dbw, $revision );
@@ -239,6 +248,7 @@ class WikiImporter {
        
        function throwXmlError( $err ) {
                $this->debug( "FAILURE: $err" );
+               wfDebug( "WikiImporter XML error: $err\n" );
        }
        
        # --------------
@@ -256,11 +266,14 @@ class WikiImporter {
                xml_set_object( $parser, &$this );
                xml_set_element_handler( $parser, "in_start", "" );
                
+               $offset = 0; // for context extraction on error reporting
                do {
                        $chunk = $this->mSource->readChunk();
                        if( !xml_parse( $parser, $chunk, $this->mSource->atEnd() ) ) {
-                               return new WikiXmlError( $parser );
+                               wfDebug( "WikiImporter::doImport encountered XML parsing error\n" );
+                               return new WikiXmlError( $parser, 'XML import parse failure', $chunk, $offset );
                        }
+                       $offset += strlen( $chunk );
                } while( $chunk !== false && !$this->mSource->atEnd() );
                xml_parser_free( $parser );
                
@@ -380,6 +393,7 @@ class WikiImporter {
                $this->debug( "in_siteinfo $name" );
                switch( $name ) {
                case "sitename":
+               case "base":
                case "generator":
                case "case":
                case "namespaces":
@@ -466,6 +480,9 @@ class WikiImporter {
                case "comment":
                        $this->workRevision->setComment( $this->appenddata );
                        break;
+               case "minor":
+                       $this->workRevision->setMinor( true );
+                       break;
                default:
                        $this->debug( "Bad append: {$this->appendfield}" );
                }
@@ -479,6 +496,7 @@ class WikiImporter {
                case "id":
                case "timestamp":
                case "comment":
+               case "minor":
                case "text":
                        $this->parenttag = "revision";
                        $this->appendfield = $name;
@@ -514,6 +532,7 @@ class WikiImporter {
                switch( $name ) {
                case "username":
                case "ip":
+               case "id":
                        $this->parenttag = "contributor";
                        $this->appendfield = $name;
                        xml_set_element_handler( $parser, "in_nothing", "out_append" );
index f693003..46738fc 100644 (file)
@@ -89,15 +89,36 @@ class WikiXmlError extends WikiError {
         * @param resource $parser
         * @param string $message
         */
-       function WikiXmlError( $parser, $message = '' ) {
+       function WikiXmlError( $parser, $message = 'XML parsing error', $context = null, $offset = 0 ) {
                $this->mXmlError = xml_get_error_code( $parser );
+               $this->mColumn = xml_get_current_column_number( $parser );
+               $this->mLine = xml_get_current_line_number( $parser );
+               $this->mByte = xml_get_current_byte_index( $parser );
+               $this->mContext = $this->_extractContext( $context, $offset );
                $this->mMessage = $message;
                xml_parser_free( $parser );
+               wfDebug( "WikiXmlError: " . $this->getMessage() . "\n" );
        }
 
        /** @return string */   
        function getMessage() {
-               return $this->mMessage . ': ' . xml_error_string( $this->mXmlError );
+               return sprintf( '%s at line %d, col %d (byte %d%s): %s',
+                       $this->mMessage,
+                       $this->mLine,
+                       $this->mColumn,
+                       $this->mByte,
+                       $this->mContext,
+                       xml_error_string( $this->mXmlError ) );
+       }
+       
+       function _extractContext( $context, $offset ) {
+               if( is_null( $context ) ) {
+                       return null;
+               } else {
+                       // Hopefully integer overflow will be handled transparently here
+                       $inlineOffset = $this->mByte - $offset;
+                       return '; "' . substr( $context, $inlineOffset, 16 ) . '"';
+               }
        }
 }
 
index 21894a6..15110ff 100644 (file)
@@ -88,12 +88,12 @@ class BackupReader {
                        $filename = 'compress.zlib://' . $filename;
                }
                $file = fopen( $filename, 'rt' );
-               $this->importFromHandle( $file );
+               return $this->importFromHandle( $file );
        }
 
        function importFromStdin() {
                $file = fopen( 'php://stdin', 'rt' );
-               $this->importFromHandle( $file );
+               return $this->importFromHandle( $file );
        }
 
        function importFromHandle( $handle ) {
@@ -106,7 +106,7 @@ class BackupReader {
                $this->importCallback =  $importer->setRevisionCallback(
                        array( &$this, 'handleRevision' ) );
 
-               $importer->doImport();
+               return $importer->doImport();
        }
 }
 
@@ -122,9 +122,15 @@ if( isset( $options['dry-run'] ) ) {
 }
 
 if( isset( $args[0] ) ) {
-       $reader->importFromFile( $args[0] );
+       $result = $reader->importFromFile( $args[0] );
 } else {
-       $reader->importFromStdin();
+       $result = $reader->importFromStdin();
+}
+
+if( WikiError::isError( $result ) ) {
+       echo $result->getMessage() . "\n";
+} else {
+       echo "Done!\n";
 }
 
 ?>