112 $this->sink =&
$sink;
117 $this->sink->writeOpenStream(
$output );
122 $this->sink->writeCloseStream(
$output );
144 $condition =
'rev_page >= ' . intval( $start );
146 $condition .=
' AND rev_page < ' . intval( $end );
149 $condition =
'page_id >= ' . intval( $start );
151 $condition .=
' AND page_id < ' . intval( $end );
154 $this->
dumpFrom( $condition, $orderRevs );
165 $condition =
'rev_id >= ' . intval( $start );
167 $condition .=
' AND rev_id < ' . intval( $end );
177 'page_namespace=' . $title->getNamespace() .
178 ' AND page_title=' . $this->db->addQuotes( $title->getDBkey() ) );
186 $title = Title::newFromText( $name );
187 if ( is_null( $title ) ) {
188 throw new MWException(
"Can't export invalid title" );
198 foreach ( $names as $name ) {
212 $condition =
'log_id >= ' . intval( $start );
214 $condition .=
' AND log_id < ' . intval( $end );
227 $this->author_list =
"<contributors>";
230 $res = $this->db->select(
231 [
'page',
'revision' ],
232 [
'DISTINCT rev_user_text',
'rev_user' ],
241 foreach (
$res as $row ) {
242 $this->author_list .=
"<contributor>" .
244 htmlentities( $row->rev_user_text ) .
251 $this->author_list .=
"</contributors>";
260 protected function dumpFrom( $cond =
'', $orderRevs =
false ) {
261 # For logging dumps...
262 if ( $this->
history & self::LOGS ) {
267 $where[] = $hideLogs;
269 # Add on any caller specified conditions
273 # Get logging table name for logging.* clause
274 $logging = $this->db->tableName(
'logging' );
276 if ( $this->buffer == self::STREAM ) {
277 $prev = $this->db->bufferResults(
false );
284 $result = $this->db->select( [
'logging',
'user' ] + $commentQuery[
'tables'],
285 [
"{$logging}.*",
'user_name' ] + $commentQuery[
'fields'],
288 [
'ORDER BY' =>
'log_id',
'USE INDEX' => [
'logging' =>
'PRIMARY' ] ],
289 [
'user' => [
'JOIN',
'user_id = log_user' ] ] + $commentQuery[
'joins']
292 if ( $this->buffer == self::STREAM ) {
293 $this->db->bufferResults( $prev );
295 }
catch ( Exception
$e ) {
304 }
catch ( Exception $e2 ) {
311 if ( $this->buffer == self::STREAM ) {
312 $this->db->bufferResults( $prev );
314 }
catch ( Exception $e2 ) {
324 $tables = [
'page',
'revision' ];
325 $opts = [
'ORDER BY' =>
'page_id ASC' ];
326 $opts[
'USE INDEX'] = [];
328 if ( is_array( $this->
history ) ) {
329 # Time offset/limit for all pages/history...
330 $revJoin =
'page_id=rev_page';
332 if ( $this->
history[
'dir'] ==
'asc' ) {
334 $opts[
'ORDER BY'] =
'rev_timestamp ASC';
337 $opts[
'ORDER BY'] =
'rev_timestamp DESC';
340 if ( !empty( $this->
history[
'offset'] ) ) {
341 $revJoin .=
" AND rev_timestamp $op " .
342 $this->db->addQuotes( $this->db->timestamp( $this->history[
'offset'] ) );
344 $join[
'revision'] = [
'INNER JOIN', $revJoin ];
346 if ( !empty( $this->
history[
'limit'] ) ) {
347 $opts[
'LIMIT'] = intval( $this->
history[
'limit'] );
349 } elseif ( $this->
history & self::FULL ) {
350 # Full history dumps...
351 # query optimization for history stub dumps
352 if ( $this->text == self::STUB && $orderRevs ) {
353 $tables = [
'revision',
'page' ];
354 $opts[] =
'STRAIGHT_JOIN';
355 $opts[
'ORDER BY'] = [
'rev_page ASC',
'rev_id ASC' ];
356 $opts[
'USE INDEX'][
'revision'] =
'rev_page_id';
357 $join[
'page'] = [
'INNER JOIN',
'rev_page=page_id' ];
359 $join[
'revision'] = [
'INNER JOIN',
'page_id=rev_page' ];
361 } elseif ( $this->
history & self::CURRENT ) {
362 # Latest revision dumps...
363 if ( $this->list_authors && $cond !=
'' ) {
366 $join[
'revision'] = [
'INNER JOIN',
'page_id=rev_page AND page_latest=rev_id' ];
367 } elseif ( $this->
history & self::STABLE ) {
368 # "Stable" revision dumps...
369 # Default JOIN, to be overridden...
370 $join[
'revision'] = [
'INNER JOIN',
'page_id=rev_page AND page_latest=rev_id' ];
371 # One, and only one hook should set this, and return false
372 if ( Hooks::run(
'WikiExporter::dumpStableQuery', [ &
$tables, &$opts, &$join ] ) ) {
373 throw new MWException( __METHOD__ .
" given invalid history dump type." );
375 } elseif ( $this->
history & self::RANGE ) {
376 # Dump of revisions within a specified range
377 $join[
'revision'] = [
'INNER JOIN',
'page_id=rev_page' ];
378 $opts[
'ORDER BY'] = [
'rev_page ASC',
'rev_id ASC' ];
380 # Unknown history specification parameter?
381 throw new MWException( __METHOD__ .
" given invalid history dump type." );
383 # Query optimization hacks
385 $opts[] =
'STRAIGHT_JOIN';
386 $opts[
'USE INDEX'][
'page'] =
'PRIMARY';
388 # Build text join options
389 if ( $this->text != self::STUB ) {
391 $join[
'text'] = [
'INNER JOIN',
'rev_text_id=old_id' ];
394 if ( $this->buffer == self::STREAM ) {
395 $prev = $this->db->bufferResults(
false );
399 Hooks::run(
'ModifyExportQuery',
400 [ $this->db, &
$tables, &$cond, &$opts, &$join ] );
405 $result = $this->db->select(
406 $tables + $commentQuery[
'tables'],
407 [
'*' ] + $commentQuery[
'fields'],
411 $join + $commentQuery[
'joins']
413 # Output dump results
416 if ( $this->buffer == self::STREAM ) {
417 $this->db->bufferResults( $prev );
419 }
catch ( Exception
$e ) {
428 }
catch ( Exception $e2 ) {
435 if ( $this->buffer == self::STREAM ) {
436 $this->db->bufferResults( $prev );
438 }
catch ( Exception $e2 ) {
463 foreach ( $resultset as $row ) {
464 if (
$last ===
null ||
465 $last->page_namespace != $row->page_namespace ||
466 $last->page_title != $row->page_title ) {
467 if (
$last !==
null ) {
469 if ( $this->dumpUploads ) {
473 $this->sink->writeClosePage(
$output );
476 $this->sink->writeOpenPage( $row,
$output );
480 $this->sink->writeRevision( $row,
$output );
482 if (
$last !==
null ) {
484 if ( $this->dumpUploads ) {
489 $this->sink->writeClosePage(
$output );
497 foreach ( $resultset as $row ) {
499 $this->sink->writeLogItem( $row,
$output );
static getExcludeClause( $db, $audience='public', User $user=null)
SQL clause to skip forbidden log types for this user.
revsByRange( $start, $end)
Dumps a series of page and revision records for those pages in the database with revisions falling wi...
dumpFrom( $cond='', $orderRevs=false)
setOutputSink(&$sink)
Set the DumpOutput or DumpFilter object which will receive various row objects and XML output for fil...
pagesByRange( $start, $end, $orderRevs)
Dumps a series of page and revision records for those pages in the database falling within the page_i...
bool $dumpUploadFileContents
outputPageStream( $resultset)
Runs through a query result set dumping page and revision records.
allPages()
Dumps a series of page and revision records for all pages in the database, either including complete ...
logsByRange( $start, $end)
do_list_authors( $cond)
Generates the distinct list of authors of an article Not called by default (depends on $this->list_au...
outputLogStream( $resultset)
static schemaVersion()
Returns the export schema version.
__construct( $db, $history=self::CURRENT, $buffer=self::BUFFER, $text=self::TEXT)
If using WikiExporter::STREAM to stream a large amount of data, provide a database connection which i...
bool $list_authors
Return distinct author list (when not returning full history)
static configuration should be added through ResourceLoaderGetConfigVars instead can be used to get the real title after the basic globals have been set but before ordinary actions take place $output
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist & $tables
presenting them properly to the user as errors is done by the caller return true use this to change the list i e etc next in line in page history
returning false will NOT prevent logging $e