Removed configuration storage in the MediaWiki class:
[lhc/web/wiklou.git] / includes / Import.php
index 7228d23..8bd65a6 100644 (file)
@@ -35,6 +35,7 @@ class WikiImporter {
        private $mLogItemCallback, $mUploadCallback, $mRevisionCallback, $mPageCallback;
        private $mSiteInfoCallback, $mTargetNamespace, $mPageOutCallback;
        private $mDebug;
+       private $mImportUploads, $mImageBasePath;
 
        /**
         * Creates an ImportXMLReader drawing from the source provided
@@ -169,6 +170,16 @@ class WikiImporter {
                        return false;
                }
        }
+       
+       /**
+        * 
+        */
+       public function setImageBasePath( $dir ) {
+               $this->mImageBasePath = $dir;
+       }
+       public function setImportUploads( $import ) {
+               $this->mImportUploads = $import;
+       }
 
        /**
         * Default per-revision callback, performs the import.
@@ -192,10 +203,8 @@ class WikiImporter {
         * Dummy for now...
         */
        public function importUpload( $revision ) {
-               $revision->importUpload();
-               //$dbw = wfGetDB( DB_MASTER );
-               //return $dbw->deadlockLoop( array( $revision, 'importUpload' ) );
-               return false;
+               $dbw = wfGetDB( DB_MASTER );
+               return $dbw->deadlockLoop( array( $revision, 'importUpload' ) );
        }
 
        /**
@@ -546,18 +555,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'] );
                }
@@ -573,7 +591,7 @@ class WikiImporter {
                $uploadInfo = array();
 
                $normalFields = array( 'timestamp', 'comment', 'filename', 'text',
-                                       'src', 'size' );
+                                       'src', 'size', 'sha1base36', 'archivename', 'rel' );
 
                $skip = false;
 
@@ -592,26 +610,59 @@ class WikiImporter {
                                $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 ) );
+                                       $uploadInfo['isTempSrc'] = true;
+                               }
                        } 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;
+                               $uploadInfo['isTempSrc'] = false;
+                       }
+               }
 
-               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'] : '';
+               $text = isset( $uploadInfo['text'] ) ? $uploadInfo['text'] : '';
 
                $revision->setTitle( $pageInfo['_title'] );
-               $revision->setID( $pageInfo['id'] );
+               $revision->setID( $pageInfo['id'] );
                $revision->setTimestamp( $uploadInfo['timestamp'] );
-               $revision->setText( $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'],
+                               !empty( $uploadInfo['isTempSrc'] ) );
+               }
+               if ( isset( $uploadInfo['sha1base36'] ) ) {
+                       $revision->setSha1Base36( $uploadInfo['sha1base36'] );
+               }
                $revision->setSize( intval( $uploadInfo['size'] ) );
                $revision->setComment( $uploadInfo['comment'] );
 
@@ -622,7 +673,7 @@ class WikiImporter {
                        $revision->setUserName( $uploadInfo['contributor']['username'] );
                }
 
-               return call_user_func( $this->mUploadCallback, $revision );
+               return call_user_func( $this->mUploadCallback, $revision );
        }
 
        private function handleContributor() {
@@ -781,6 +832,7 @@ class XMLReader2 extends XMLReader {
  * @ingroup SpecialPage
  */
 class WikiRevision {
+       var $importer = null;
        var $title = null;
        var $id = 0;
        var $timestamp = "20010115000000";
@@ -792,6 +844,10 @@ class WikiRevision {
        var $type = "";
        var $action = "";
        var $params = "";
+       var $fileSrc = '';
+       var $sha1base36 = false;
+       var $isTemp = false;
+       var $archiveName = '';
 
        function setTitle( $title ) {
                if( is_object( $title ) ) {
@@ -835,10 +891,20 @@ class WikiRevision {
        function setSrc( $src ) {
                $this->src = $src;
        }
+       function setFileSrc( $src, $isTemp ) {
+               $this->fileSrc = $src;
+               $this->fileIsTemp = $isTemp;
+       }
+       function setSha1Base36( $sha1base36 ) { 
+               $this->sha1base36 = $sha1base36;
+       }
 
        function setFilename( $filename ) {
                $this->filename = $filename;
        }
+       function setArchiveName( $archiveName ) {
+               $this->archiveName = $archiveName;
+       }
 
        function setSize( $size ) {
                $this->size = intval( $size );
@@ -856,6 +922,9 @@ class WikiRevision {
                $this->params = $params;
        }
 
+       /**
+        * @return Title
+        */
        function getTitle() {
                return $this->title;
        }
@@ -887,10 +956,25 @@ class WikiRevision {
        function getSrc() {
                return $this->src;
        }
+       function getSha1() {
+               if ( $this->sha1base36 ) {
+                       return wfBaseConvert( $this->sha1base36, 36, 16 );
+               }
+               return false;
+       }
+       function getFileSrc() {
+               return $this->fileSrc;
+       }
+       function isTempSrc() {
+               return $this->isTemp;
+       }
 
        function getFilename() {
                return $this->filename;
        }
+       function getArchiveName() {
+               return $this->archiveName;
+       }
 
        function getSize() {
                return $this->size;
@@ -967,25 +1051,25 @@ class WikiRevision {
                $tempTitle = $GLOBALS['wgTitle'];
                $GLOBALS['wgTitle'] = $this->title;
 
-               if( $created ) {
+               if ( $created ) {
                        wfDebug( __METHOD__ . ": running onArticleCreate\n" );
                        Article::onArticleCreate( $this->title );
-
-                       wfDebug( __METHOD__ . ": running create updates\n" );
-                       $article->createUpdates( $revision );
-
                } elseif( $changed ) {
                        wfDebug( __METHOD__ . ": running onArticleEdit\n" );
                        Article::onArticleEdit( $this->title );
-
-                       wfDebug( __METHOD__ . ": running edit updates\n" );
-                       $article->editUpdates(
-                               $this->getText(),
-                               $this->getComment(),
-                               $this->minor,
-                               $this->timestamp,
-                               $revId );
                }
+
+               wfDebug( __METHOD__ . ": running updates\n" );
+               $article->editUpdates(
+                       $this->getText(),
+                       $this->getComment(),
+                       $this->minor,
+                       $this->timestamp,
+                       $revId,
+                       true,
+                       null,
+                       $created );
+
                $GLOBALS['wgTitle'] = $tempTitle;
 
                return true;
@@ -1035,62 +1119,62 @@ 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: it may 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();
+               $flags = $this->isTempSrc() ? File::DELETE_SOURCE : 0;
+               if ( !$source ) {
+                       $source = $this->downloadSource();
+                       $flags |= File::DELETE_SOURCE;
+               }
                if( !$source ) {
-                       wfDebug( "IMPORT: Could not fetch remote file. :(\n" );
+                       wfDebug( __METHOD__ . ": Could not fetch remote file.\n" );
+                       return false;
+               }
+               $sha1 = $this->getSha1();
+               if ( $sha1 && ( $sha1 !== sha1_file( $source ) ) ) {
+                       wfDebug( __METHOD__ . ": Corrupt file $source.\n" );
                        return false;
                }
 
-               $user = User::newFromName( $this->user_text );
-
-               $status = $file->upload( $source,
-                       $this->getComment(),
-                       $this->getComment(), // Initial page, if none present...
-                       File::DELETE_SOURCE,
-                       false, // props...
-                       $this->getTimestamp(),
-                       is_object( $user ) ? ( $user->isLoggedIn() ? $user : null ) : null );
-
-               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, $flags );
+               } else {
+                       $status = $file->upload( $source, $this->getComment(), $this->getComment(), 
+                               $flags, 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() {