Whitespace fixes
[lhc/web/wiklou.git] / includes / Import.php
index 15fd151..1c3bbd9 100644 (file)
@@ -35,12 +35,13 @@ class WikiImporter {
        private $mLogItemCallback, $mUploadCallback, $mRevisionCallback, $mPageCallback;
        private $mSiteInfoCallback, $mTargetNamespace, $mPageOutCallback;
        private $mDebug;
+       private $mImportUploads, $mImageBasePath;
 
        /**
         * Creates an ImportXMLReader drawing from the source provided
        */
        function __construct( $source ) {
-               $this->reader = new XMLReader2();
+               $this->reader = new XMLReader();
 
                stream_wrapper_register( 'uploadsource', 'UploadSourceAdapter' );
                $id = UploadSourceAdapter::registerSource( $source );
@@ -169,6 +170,13 @@ class WikiImporter {
                        return false;
                }
        }
+       
+       /**
+        * 
+        */
+       public function setImageBasePath( $dir ) {
+               $this->mImageBasePath = $dir;
+       }
 
        /**
         * Default per-revision callback, performs the import.
@@ -192,9 +200,8 @@ class WikiImporter {
         * Dummy for now...
         */
        public function importUpload( $revision ) {
-               //$dbw = wfGetDB( DB_MASTER );
-               //return $dbw->deadlockLoop( array( $revision, 'importUpload' ) );
-               return false;
+               $dbw = wfGetDB( DB_MASTER );
+               return $dbw->deadlockLoop( array( $revision, 'importUpload' ) );
        }
 
        /**
@@ -281,7 +288,23 @@ class WikiImporter {
         * @access private
         */
        private function nodeContents() {
-               return $this->reader->nodeContents();
+               if( $this->reader->isEmptyElement ) {
+                       return "";
+               }
+               $buffer = "";
+               while( $this->reader->read() ) {
+                       switch( $this->reader->nodeType ) {
+                       case XmlReader::TEXT:
+                       case XmlReader::SIGNIFICANT_WHITESPACE:
+                               $buffer .= $this->reader->value;
+                               break;
+                       case XmlReader::END_ELEMENT:
+                               return $buffer;
+                       }
+               }
+
+               $this->reader->close();
+               return '';
        }
 
        # --------------
@@ -344,7 +367,7 @@ class WikiImporter {
                        $tag = $this->reader->name;
                        $type = $this->reader->nodeType;
 
-                       if ( !wfRunHooks( 'ImportHandleToplevelXMLTag', $this->reader ) ) {
+                       if ( !wfRunHooks( 'ImportHandleToplevelXMLTag', $this ) ) {
                                // Do nothing
                        } elseif ( $tag == 'mediawiki' && $type == XmlReader::END_ELEMENT ) {
                                break;
@@ -399,7 +422,7 @@ class WikiImporter {
                        $tag = $this->reader->name;
 
                        if ( !wfRunHooks( 'ImportHandleLogItemXMLTag',
-                                               $this->reader, $logInfo ) ) {
+                                               $this, $logInfo ) ) {
                                // Do nothing
                        } elseif ( in_array( $tag, $normalFields ) ) {
                                $logInfo[$tag] = $this->nodeContents();
@@ -459,7 +482,7 @@ class WikiImporter {
                        if ( $badTitle ) {
                                // The title is invalid, bail out of this page
                                $skip = true;
-                       } elseif ( !wfRunHooks( 'ImportHandlePageXMLTag', array( $this->reader,
+                       } elseif ( !wfRunHooks( 'ImportHandlePageXMLTag', array( $this,
                                                &$pageInfo ) ) ) {
                                // Do nothing
                        } elseif ( in_array( $tag, $normalFields ) ) {
@@ -507,7 +530,7 @@ class WikiImporter {
 
                        $tag = $this->reader->name;
 
-                       if ( !wfRunHooks( 'ImportHandleRevisionXMLTag', $this->reader,
+                       if ( !wfRunHooks( 'ImportHandleRevisionXMLTag', $this,
                                                $pageInfo, $revisionInfo ) ) {
                                // Do nothing
                        } elseif ( in_array( $tag, $normalFields ) ) {
@@ -529,18 +552,27 @@ class WikiImporter {
        private function processRevision( $pageInfo, $revisionInfo ) {
                $revision = new WikiRevision;
 
-               $revision->setID( $revisionInfo['id'] );
-               $revision->setText( $revisionInfo['text'] );
+               if( isset( $revisionInfo['id'] ) ) {
+                       $revision->setID( $revisionInfo['id'] );
+               }
+               if ( isset( $revisionInfo['text'] ) ) {
+                       $revision->setText( $revisionInfo['text'] );
+               }
                $revision->setTitle( $pageInfo['_title'] );
-               $revision->setTimestamp( $revisionInfo['timestamp'] );
+
+               if ( isset( $revisionInfo['timestamp'] ) ) {
+                       $revision->setTimestamp( $revisionInfo['timestamp'] );
+               } else {
+                       $revision->setTimestamp( wfTimestampNow() );
+               }
 
                if ( isset( $revisionInfo['comment'] ) ) {
                        $revision->setComment( $revisionInfo['comment'] );
                }
 
-               if ( isset( $revisionInfo['minor'] ) )
+               if ( isset( $revisionInfo['minor'] ) ) {
                        $revision->setMinor( true );
-
+               }
                if ( isset( $revisionInfo['contributor']['ip'] ) ) {
                        $revision->setUserIP( $revisionInfo['contributor']['ip'] );
                }
@@ -556,7 +588,7 @@ class WikiImporter {
                $uploadInfo = array();
 
                $normalFields = array( 'timestamp', 'comment', 'filename', 'text',
-                                       'src', 'size' );
+                                       'src', 'size', 'sha1base36', 'archivename', 'rel' );
 
                $skip = false;
 
@@ -568,31 +600,60 @@ class WikiImporter {
 
                        $tag = $this->reader->name;
 
-                       if ( !wfRunHooks( 'ImportHandleUploadXMLTag', $this->reader,
+                       if ( !wfRunHooks( 'ImportHandleUploadXMLTag', $this,
                                                $pageInfo ) ) {
                                // Do nothing
                        } elseif ( in_array( $tag, $normalFields ) ) {
                                $uploadInfo[$tag] = $this->nodeContents();
                        } elseif ( $tag == 'contributor' ) {
                                $uploadInfo['contributor'] = $this->handleContributor();
+                       } elseif ( $tag == 'contents' ) {
+                               $contents = $this->nodeContents();
+                               $encoding = $this->reader->getAttribute( 'encoding' );
+                               if ( $encoding === 'base64' ) {
+                                       $uploadInfo['fileSrc'] = $this->dumpTemp( base64_decode( $contents ) );
+                               }
                        } elseif ( $tag != '#text' ) {
                                $this->warn( "Unhandled upload XML tag $tag" );
                                $skip = true;
                        }
                }
+               
+               if ( $this->mImageBasePath && isset( $uploadInfo['rel'] ) ) {
+                       $path = "{$this->mImageBasePath}/{$uploadInfo['rel']}";
+                       if ( file_exists( $path ) ) {
+                               $uploadInfo['fileSrc'] = $path;
+                       }
+               }
 
-               return $this->processUpload( $pageInfo, $uploadInfo );
+               if ( $this->mImportUploads ) {
+                       return $this->processUpload( $pageInfo, $uploadInfo );
+               }
        }
+       
+       private function dumpTemp( $contents ) {
+               $filename = tempnam( wfTempDir(), 'importupload' );
+               file_put_contents( $filename, $contents );
+               return $filename;
+       }
+
 
        private function processUpload( $pageInfo, $uploadInfo ) {
                $revision = new WikiRevision;
+               $text = isset( $uploadInfo['text'] ) ? $uploadInfo['text'] : '';
 
                $revision->setTitle( $pageInfo['_title'] );
-               $revision->setID( $uploadInfo['id'] );
+               $revision->setID( $pageInfo['id'] );
                $revision->setTimestamp( $uploadInfo['timestamp'] );
-               $revision->setText( $uploadInfo['text'] );
+               $revision->setText( $text );
                $revision->setFilename( $uploadInfo['filename'] );
+               if ( isset( $uploadInfo['archivename'] ) ) {
+                       $revision->setArchiveName( $uploadInfo['archivename'] );
+               }
                $revision->setSrc( $uploadInfo['src'] );
+               if ( isset( $uploadInfo['fileSrc'] ) ) {
+                       $revision->setFileSrc( $uploadInfo['fileSrc'] );
+               }
                $revision->setSize( intval( $uploadInfo['size'] ) );
                $revision->setComment( $uploadInfo['comment'] );
 
@@ -603,7 +664,7 @@ class WikiImporter {
                        $revision->setUserName( $uploadInfo['contributor']['username'] );
                }
 
-               return $this->uploadCallback( $revision );
+               return call_user_func( $this->mUploadCallback, $revision );
        }
 
        private function handleContributor() {
@@ -646,7 +707,7 @@ class WikiImporter {
                        return false;
                }
 
-               return array( $origTitle, $title );
+               return array( $title, $origTitle );
        }
 }
 
@@ -762,6 +823,7 @@ class XMLReader2 extends XMLReader {
  * @ingroup SpecialPage
  */
 class WikiRevision {
+       var $importer = null;
        var $title = null;
        var $id = 0;
        var $timestamp = "20010115000000";
@@ -773,6 +835,8 @@ class WikiRevision {
        var $type = "";
        var $action = "";
        var $params = "";
+       var $fileSrc = '';
+       var $archiveName = '';
 
        function setTitle( $title ) {
                if( is_object( $title ) ) {
@@ -816,27 +880,36 @@ class WikiRevision {
        function setSrc( $src ) {
                $this->src = $src;
        }
+       function setFileSrc( $src ) {
+               $this->fileSrc = $src;
+       }
 
        function setFilename( $filename ) {
                $this->filename = $filename;
        }
+       function setArchiveName( $archiveName ) {
+               $this->archiveName = $archiveName;
+       }
 
        function setSize( $size ) {
                $this->size = intval( $size );
        }
-       
+
        function setType( $type ) {
                $this->type = $type;
        }
-       
+
        function setAction( $action ) {
                $this->action = $action;
        }
-       
+
        function setParams( $params ) {
                $this->params = $params;
        }
 
+       /**
+        * @return Title
+        */
        function getTitle() {
                return $this->title;
        }
@@ -868,23 +941,29 @@ class WikiRevision {
        function getSrc() {
                return $this->src;
        }
+       function getFileSrc() {
+               return $this->fileSrc;
+       }
 
        function getFilename() {
                return $this->filename;
        }
+       function getArchiveName() {
+               return $this->archiveName;
+       }
 
        function getSize() {
                return $this->size;
        }
-       
+
        function getType() {
                return $this->type;
        }
-       
+
        function getAction() {
                return $this->action;
        }
-       
+
        function getParams() {
                return $this->params;
        }
@@ -943,7 +1022,7 @@ class WikiRevision {
                        ) );
                $revId = $revision->insertOn( $dbw );
                $changed = $article->updateIfNewerOn( $dbw, $revision );
-               
+
                # To be on the safe side...
                $tempTitle = $GLOBALS['wgTitle'];
                $GLOBALS['wgTitle'] = $this->title;
@@ -971,12 +1050,12 @@ class WikiRevision {
 
                return true;
        }
-       
+
        function importLogItem() {
                $dbw = wfGetDB( DB_MASTER );
                # FIXME: this will not record autoblocks
                if( !$this->getTitle() ) {
-                       wfDebug( __METHOD__ . ": skipping invalid {$this->type}/{$this->action} log time, timestamp " . 
+                       wfDebug( __METHOD__ . ": skipping invalid {$this->type}/{$this->action} log time, timestamp " .
                                $this->timestamp . "\n" );
                        return;
                }
@@ -995,7 +1074,7 @@ class WikiRevision {
                );
                // FIXME: this could fail slightly for multiple matches :P
                if( $prior ) {
-                       wfDebug( __METHOD__ . ": skipping existing item for Log:{$this->type}/{$this->action}, timestamp " . 
+                       wfDebug( __METHOD__ . ": skipping existing item for Log:{$this->type}/{$this->action}, timestamp " .
                                $this->timestamp . "\n" );
                        return false;
                }
@@ -1016,60 +1095,55 @@ class WikiRevision {
        }
 
        function importUpload() {
-               wfDebug( __METHOD__ . ": STUB\n" );
-
-               /**
-                       // from file revert...
-                       $source = $this->file->getArchiveVirtualUrl( $this->oldimage );
-                       $comment = $wgRequest->getText( 'wpComment' );
-                       // TODO: Preserve file properties from database instead of reloading from file
-                       $status = $this->file->upload( $source, $comment, $comment );
-                       if( $status->isGood() ) {
-               */
-
-               /**
-                       // from file upload...
-               $this->mLocalFile = wfLocalFile( $nt );
-               $this->mDestName = $this->mLocalFile->getName();
-               //....
-                       $status = $this->mLocalFile->upload( $this->mTempPath, $this->mComment, $pageText,
-                       File::DELETE_SOURCE, $this->mFileProps );
-                       if ( !$status->isGood() ) {
-                               $resultDetails = array( 'internal' => $status->getWikiText() );
-               */
-
-               // @todo Fixme: upload() uses $wgUser, which is wrong here
-               // it may also create a page without our desire, also wrong potentially.
-               // and, it will record a *current* upload, but we might want an archive version here
-
-               $file = wfLocalFile( $this->getTitle() );
+               # Construct a file
+               $archiveName = $this->getArchiveName();
+               if ( $archiveName ) {
+                       wfDebug( __METHOD__ . "Importing archived file as $archiveName\n" );
+                       $file = OldLocalFile::newFromArchiveName( $this->getTitle(), 
+                               RepoGroup::singleton()->getLocalRepo(), $archiveName );                 
+               } else {
+                       $file = wfLocalFile( $this->getTitle() );
+                       wfDebug( __METHOD__ . 'Importing new file as ' . $file->getName() . "\n" );
+                       if ( $file->exists() && $file->getTimestamp() > $this->getTimestamp() ) {
+                               $archiveName = $file->getTimestamp() . '!' . $file->getName();
+                               $file = OldLocalFile::newFromArchiveName( $this->getTitle(), 
+                                       RepoGroup::singleton()->getLocalRepo(), $archiveName );
+                               wfDebug( __METHOD__ . "File already exists; importing as $archiveName\n" );
+                       }
+               }
                if( !$file ) {
-                       wfDebug( "IMPORT: Bad file. :(\n" );
+                       wfDebug( __METHOD__ . ': Bad file for ' . $this->getTitle() . "\n" );
                        return false;
                }
-
-               $source = $this->downloadSource();
+               
+               # Get the file source or download if necessary
+               $source = $this->getFileSrc();
+               if ( !$source ) {
+                       $source = $this->downloadSource();
+               }
                if( !$source ) {
-                       wfDebug( "IMPORT: Could not fetch remote file. :(\n" );
+                       wfDebug( __METHOD__ . ": Could not fetch remote file.\n" );
                        return false;
                }
 
-               $status = $file->upload( $source,
-                       $this->getComment(),
-                       $this->getComment(), // Initial page, if none present...
-                       File::DELETE_SOURCE,
-                       false, // props...
-                       $this->getTimestamp() );
-
-               if( $status->isGood() ) {
-                       // yay?
-                       wfDebug( "IMPORT: is ok?\n" );
+               $user = User::newFromName( $this->user_text );
+               
+               # Do the actual upload
+               if ( $archiveName ) {
+                       $status = $file->uploadOld( $source, $archiveName, 
+                               $this->getTimestamp(), $this->getComment(), $user, File::DELETE_SOURCE );
+               } else {
+                       $status = $file->upload( $source, $this->getComment(), $this->getComment(), 
+                               File::DELETE_SOURCE, false, $this->getTimestamp(), $user );
+               }
+               
+               if ( $status->isGood() ) {
+                       wfDebug( __METHOD__ . ": Succesful\n" );
                        return true;
+               } else {
+                       wfDebug( __METHOD__ . ': failed: ' . $status->getXml() . "\n" );
+                       return false;
                }
-
-               wfDebug( "IMPORT: is bad? " . $status->getXml() . "\n" );
-               return false;
-
        }
 
        function downloadSource() {