var $author_list = "" ;
var $dumpUploads = false;
- var $multiPart = false;
- var $files = array();
+ var $dumpUploadFileContents = false;
const FULL = 1;
const CURRENT = 2;
public function openStream() {
$output = $this->writer->openStream();
-
- if ( $this->multiPart ) {
- $this->openMultipart();
- $this->sink->write( $output );
- } else {
- $this->sink->writeOpenStream( $output );
- }
+ $this->sink->writeOpenStream( $output );
}
public function closeStream() {
$output = $this->writer->closeStream();
- if ( $this->multiPart ) {
- $this->sink->write( $output );
- $this->closeMultipart();
- } else {
- $this->sink->writeCloseStream( $output );
- }
+ $this->sink->writeCloseStream( $output );
}
/**
# Generates the distinct list of authors of an article
# Not called by default (depends on $this->list_authors)
# Can be set by Special:Export when not exporting whole history
- protected function do_list_authors( $page , $revision , $cond ) {
+ protected function do_list_authors( $cond ) {
wfProfileIn( __METHOD__ );
$this->author_list = "<contributors>";
// rev_deleted
- $nothidden = '(' . $this->db->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ') = 0';
- $sql = "SELECT DISTINCT rev_user_text,rev_user FROM {$page},{$revision}
- WHERE page_id=rev_page AND $nothidden AND " . $cond ;
- $result = $this->db->query( $sql, __METHOD__ );
- $resultset = $this->db->resultObject( $result );
- foreach ( $resultset as $row ) {
+ $res = $this->db->select(
+ array( 'page', 'revision' ),
+ array( 'DISTINCT rev_user_text', 'rev_user' ),
+ array(
+ $this->db->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0',
+ $cond,
+ 'page_id = rev_id',
+ ),
+ __METHOD__
+ );
+
+ foreach ( $res as $row ) {
$this->author_list .= "<contributor>" .
"<username>" .
htmlentities( $row->rev_user_text ) .
} elseif ( $this->history & WikiExporter::CURRENT ) {
# Latest revision dumps...
if ( $this->list_authors && $cond != '' ) { // List authors, if so desired
- list( $page, $revision ) = $this->db->tableNamesN( 'page', 'revision' );
- $this->do_list_authors( $page, $revision, $cond );
+ $this->do_list_authors( $cond );
}
$join['revision'] = array( 'INNER JOIN', 'page_id=rev_page AND page_latest=rev_id' );
} elseif ( $this->history & WikiExporter::STABLE ) {
if ( isset( $last ) ) {
$output = '';
if ( $this->dumpUploads ) {
- $output .= $this->writer->writeUploads( $last );
- $this->attachUploads( $last );
+ $output .= $this->writer->writeUploads( $last, $this->dumpUploadFileContents );
}
$output .= $this->writer->closePage();
$this->sink->writeClosePage( $output );
if ( isset( $last ) ) {
$output = '';
if ( $this->dumpUploads ) {
- $output .= $this->writer->writeUploads( $last );
- $this->attachUploads( $last );
+ $output .= $this->writer->writeUploads( $last, $this->dumpUploadFileContents );
}
$output .= $this->author_list;
$output .= $this->writer->closePage();
$this->sink->writeLogItem( $row, $output );
}
}
-
- protected function attachUploads( $row ) {
- $title = Title::newFromRow( $row );
- $file = wfLocalFile( $title );
- $this->files[] = $file;
- $this->files = array_merge( $this->files, $file->getHistory() );
- }
-
- protected function openMultipart() {
- # Multipart boundary purposely invalid XML
- $this->boundary = '<' . dechex( mt_rand() ) . dechex( mt_rand() ) . '<';
- $this->sink->writeOpenStream(
- "Content-Type: multipart/related; boundary={$this->boundary};" .
- " type=text/xml\n\n" .
- "--{$this->boundary}\nContent-Type: text/xml\n\n"
- );
- }
-
- protected function closeMultipart() {
- $output = '';
-
- foreach ( $this->files as $file ) {
- $output .= "\n--{$this->boundary}\n" .
- 'Content-Type: ' . $file->getMimeType() . "\n" .
- 'Content-ID: ' . $file->getRel() . "\n" .
- 'Content-Length: ' . $file->getSize() . "\n" .
- 'X-Sha1Base36: ' . $file->getSha1() . "\n\n";
- $this->sink->write( $output );
- $this->sink->write( file_get_contents( $file->getPath() ) );
- }
- $this->sink->writeCloseStream( "\n--{$this->boundary}\n" );
- }
}
/**
/**
* Warning! This data is potentially inconsistent. :(
*/
- function writeUploads( $row ) {
+ function writeUploads( $row, $dumpContents = false ) {
if ( $row->page_namespace == NS_IMAGE ) {
$img = wfFindFile( $row->page_title );
if ( $img ) {
$out = '';
foreach ( array_reverse( $img->getHistory() ) as $ver ) {
- $out .= $this->writeUpload( $ver );
+ $out .= $this->writeUpload( $ver, $dumpContents );
}
- $out .= $this->writeUpload( $img );
+ $out .= $this->writeUpload( $img, $dumpContents );
return $out;
}
}
return '';
}
- function writeUpload( $file ) {
+ function writeUpload( $file, $dumpContents = false ) {
+ if ( $file->isOld() ) {
+ $archiveName = " " .
+ Xml::element( 'archivename', null, $file->getArchiveName() ) . "\n";
+ } else {
+ $archiveName = '';
+ }
+ if ( $dumpContents ) {
+ # Dump file as base64
+ # Uses only XML-safe characters, so does not need escaping
+ $contents = ' <contents encoding="base64">' .
+ chunk_split( base64_encode( file_get_contents( $file->getPath() ) ) ) .
+ " </contents>\n";
+ } else {
+ $contents = '';
+ }
return " <upload>\n" .
$this->writeTimestamp( $file->getTimestamp() ) .
$this->writeContributor( $file->getUser( 'id' ), $file->getUser( 'text' ) ) .
" " . Xml::elementClean( 'comment', null, $file->getDescription() ) . "\n" .
" " . Xml::element( 'filename', null, $file->getName() ) . "\n" .
+ $archiveName .
" " . Xml::element( 'src', null, $file->getFullUrl() ) . "\n" .
" " . Xml::element( 'size', null, $file->getSize() ) . "\n" .
+ " " . Xml::element( 'sha1base36', null, $file->getSha1() ) . "\n" .
+ " " . Xml::element( 'rel', null, $file->getRel() ) . "\n" .
+ $contents .
" </upload>\n";
}