MediaWiki  master
XmlDumpWriter.php
Go to the documentation of this file.
1 <?php
33 use Wikimedia\Assert\Assert;
34 use Wikimedia\IPUtils;
35 
40 
42  public const WRITE_CONTENT = 0;
43 
45  public const WRITE_STUB = 1;
46 
51  private const WRITE_STUB_DELETED = 2;
52 
57  public static $supportedSchemas = [
60  ];
61 
67  private $schemaVersion;
68 
74  private $currentTitle = null;
75 
79  private $contentMode;
80 
82  private $hookRunner;
83 
90  public function __construct(
91  $contentMode = self::WRITE_CONTENT,
93  ) {
94  Assert::parameter(
95  in_array( $contentMode, [ self::WRITE_CONTENT, self::WRITE_STUB ] ),
96  '$contentMode',
97  'must be one of the following constants: WRITE_CONTENT or WRITE_STUB.'
98  );
99 
100  Assert::parameter(
101  in_array( $schemaVersion, self::$supportedSchemas ),
102  '$schemaVersion',
103  'must be one of the following schema versions: '
104  . implode( ',', self::$supportedSchemas )
105  );
106 
107  $this->contentMode = $contentMode;
108  $this->schemaVersion = $schemaVersion;
109  $this->hookRunner = new HookRunner( MediaWikiServices::getInstance()->getHookContainer() );
110  }
111 
122  public function openStream() {
123  $ver = $this->schemaVersion;
124  return Xml::element( 'mediawiki', [
125  'xmlns' => "http://www.mediawiki.org/xml/export-$ver/",
126  'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
127  /*
128  * When a new version of the schema is created, it needs staging on mediawiki.org.
129  * This requires a change in the operations/mediawiki-config git repo.
130  *
131  * Create a changeset like https://gerrit.wikimedia.org/r/#/c/149643/ in which
132  * you copy in the new xsd file.
133  *
134  * After it is reviewed, merged and deployed (sync-docroot), the index.html needs purging.
135  * echo "https://www.mediawiki.org/xml/index.html" | mwscript purgeList.php --wiki=aawiki
136  */
137  'xsi:schemaLocation' => "http://www.mediawiki.org/xml/export-$ver/ " .
138  "http://www.mediawiki.org/xml/export-$ver.xsd",
139  'version' => $ver,
140  'xml:lang' => MediaWikiServices::getInstance()->getContentLanguage()->getHtmlCode() ],
141  null ) .
142  "\n" .
143  $this->siteInfo();
144  }
145 
149  private function siteInfo() {
150  $info = [
151  $this->sitename(),
152  $this->dbname(),
153  $this->homelink(),
154  $this->generator(),
155  $this->caseSetting(),
156  $this->namespaces() ];
157  return " <siteinfo>\n " .
158  implode( "\n ", $info ) .
159  "\n </siteinfo>\n";
160  }
161 
165  private function sitename() {
166  global $wgSitename;
167  return Xml::element( 'sitename', [], $wgSitename );
168  }
169 
173  private function dbname() {
174  global $wgDBname;
175  return Xml::element( 'dbname', [], $wgDBname );
176  }
177 
181  private function generator() {
182  return Xml::element( 'generator', [], 'MediaWiki ' . MW_VERSION );
183  }
184 
188  private function homelink() {
189  return Xml::element( 'base', [], Title::newMainPage()->getCanonicalURL() );
190  }
191 
195  private function caseSetting() {
196  global $wgCapitalLinks;
197  // "case-insensitive" option is reserved for future
198  $sensitivity = $wgCapitalLinks ? 'first-letter' : 'case-sensitive';
199  return Xml::element( 'case', [], $sensitivity );
200  }
201 
205  private function namespaces() {
206  $spaces = "<namespaces>\n";
207  $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
208  foreach (
209  MediaWikiServices::getInstance()->getContentLanguage()->getFormattedNamespaces()
210  as $ns => $title
211  ) {
212  $spaces .= ' ' .
213  Xml::element( 'namespace',
214  [
215  'key' => $ns,
216  'case' => $nsInfo->isCapitalized( $ns )
217  ? 'first-letter' : 'case-sensitive',
218  ], $title ) . "\n";
219  }
220  $spaces .= " </namespaces>";
221  return $spaces;
222  }
223 
230  public function closeStream() {
231  return "</mediawiki>\n";
232  }
233 
241  public function openPage( $row ) {
242  $out = " <page>\n";
243  $this->currentTitle = Title::newFromRow( $row );
244  $canonicalTitle = self::canonicalTitle( $this->currentTitle );
245  $out .= ' ' . Xml::elementClean( 'title', [], $canonicalTitle ) . "\n";
246  $out .= ' ' . Xml::element( 'ns', [], strval( $row->page_namespace ) ) . "\n";
247  $out .= ' ' . Xml::element( 'id', [], strval( $row->page_id ) ) . "\n";
248  if ( $row->page_is_redirect ) {
249  $page = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $this->currentTitle );
250  $redirect = $this->invokeLenient(
251  static function () use ( $page ) {
252  return $page->getRedirectTarget();
253  },
254  'Failed to get redirect target of page ' . $page->getId()
255  );
256  if ( $redirect instanceof Title && $redirect->isValidRedirectTarget() ) {
257  $out .= ' ';
258  $out .= Xml::element( 'redirect', [ 'title' => self::canonicalTitle( $redirect ) ] );
259  $out .= "\n";
260  }
261  }
262 
263  if ( $row->page_restrictions != '' ) {
264  $out .= ' ' . Xml::element( 'restrictions', [],
265  strval( $row->page_restrictions ) ) . "\n";
266  }
267 
268  $this->hookRunner->onXmlDumpWriterOpenPage( $this, $out, $row, $this->currentTitle );
269 
270  return $out;
271  }
272 
279  public function closePage() {
280  if ( $this->currentTitle !== null ) {
281  $linkCache = MediaWikiServices::getInstance()->getLinkCache();
282  // In rare cases, link cache has the same key for some pages which
283  // might be read as part of the same batch. T220424 and T220316
284  $linkCache->clearLink( $this->currentTitle );
285  }
286  return " </page>\n";
287  }
288 
292  private function getRevisionStore() {
293  return MediaWikiServices::getInstance()->getRevisionStore();
294  }
295 
299  private function getBlobStore() {
300  // @phan-suppress-next-line PhanTypeMismatchReturnSuperType
301  return MediaWikiServices::getInstance()->getBlobStore();
302  }
303 
315  private function invokeLenient( $callback, $warning ) {
316  try {
317  return $callback();
318  } catch ( SuppressedDataException $ex ) {
319  return null;
320  } catch ( Exception $ex ) {
321  if ( $ex instanceof MWException || $ex instanceof RuntimeException ||
322  $ex instanceof InvalidArgumentException ) {
323  MWDebug::warning( $warning . ': ' . $ex->getMessage() );
324  return null;
325  } else {
326  throw $ex;
327  }
328  }
329  }
330 
342  public function writeRevision( $row, $slotRows = null ) {
343  $rev = $this->getRevisionStore()->newRevisionFromRowAndSlots(
344  $row,
345  $slotRows,
346  0,
347  $this->currentTitle
348  );
349 
350  $out = " <revision>\n";
351  $out .= " " . Xml::element( 'id', null, strval( $rev->getId() ) ) . "\n";
352 
353  if ( $rev->getParentId() ) {
354  $out .= " " . Xml::element( 'parentid', null, strval( $rev->getParentId() ) ) . "\n";
355  }
356 
357  $out .= $this->writeTimestamp( $rev->getTimestamp() );
358 
359  if ( $rev->isDeleted( RevisionRecord::DELETED_USER ) ) {
360  $out .= " " . Xml::element( 'contributor', [ 'deleted' => 'deleted' ] ) . "\n";
361  } else {
362  // empty values get written out as uid 0, see T224221
363  $user = $rev->getUser();
364  $out .= $this->writeContributor(
365  $user ? $user->getId() : 0,
366  $user ? $user->getName() : ''
367  );
368  }
369 
370  if ( $rev->isMinor() ) {
371  $out .= " <minor/>\n";
372  }
373  if ( $rev->isDeleted( RevisionRecord::DELETED_COMMENT ) ) {
374  $out .= " " . Xml::element( 'comment', [ 'deleted' => 'deleted' ] ) . "\n";
375  } else {
376  if ( $rev->getComment()->text != '' ) {
377  $out .= " "
378  // @phan-suppress-next-line SecurityCheck-DoubleEscaped getComment is polluted by truncate
379  . Xml::elementClean( 'comment', [], strval( $rev->getComment()->text ) )
380  . "\n";
381  }
382  }
383 
384  $contentMode = $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ? self::WRITE_STUB_DELETED
386 
387  $slots = $rev->getSlots()->getSlots();
388 
389  // use predictable order, put main slot first
390  ksort( $slots );
391  $out .= $this->writeSlot( $slots[SlotRecord::MAIN], $contentMode );
392 
393  foreach ( $slots as $role => $slot ) {
394  if ( $role === SlotRecord::MAIN ) {
395  continue;
396  }
397  $out .= $this->writeSlot( $slot, $contentMode );
398  }
399 
400  if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
401  $out .= " <sha1/>\n";
402  } else {
403  $sha1 = $this->invokeLenient(
404  static function () use ( $rev ) {
405  return $rev->getSha1();
406  },
407  'failed to determine sha1 for revision ' . $rev->getId()
408  );
409  $out .= " " . Xml::element( 'sha1', null, strval( $sha1 ) ) . "\n";
410  }
411 
412  // Avoid PHP 7.1 warning from passing $this by reference
413  $writer = $this;
414  $text = '';
415  if ( $contentMode === self::WRITE_CONTENT ) {
417  $content = $this->invokeLenient(
418  static function () use ( $rev ) {
419  return $rev->getContent( SlotRecord::MAIN, RevisionRecord::RAW );
420  },
421  'Failed to load main slot content of revision ' . $rev->getId()
422  );
423 
424  $text = $content ? $content->serialize() : '';
425  }
426  $this->hookRunner->onXmlDumpWriterWriteRevision( $writer, $out, $row, $text, $rev );
427 
428  $out .= " </revision>\n";
429 
430  return $out;
431  }
432 
439  private function writeSlot( SlotRecord $slot, $contentMode ) {
440  $isMain = $slot->getRole() === SlotRecord::MAIN;
441  $isV11 = $this->schemaVersion >= XML_DUMP_SCHEMA_VERSION_11;
442 
443  if ( !$isV11 && !$isMain ) {
444  // ignore extra slots
445  return '';
446  }
447 
448  $out = '';
449  $indent = ' ';
450 
451  if ( !$isMain ) {
452  // non-main slots are wrapped into an additional element.
453  $out .= ' ' . Xml::openElement( 'content' ) . "\n";
454  $indent .= ' ';
455  $out .= $indent . Xml::element( 'role', null, strval( $slot->getRole() ) ) . "\n";
456  }
457 
458  if ( $isV11 ) {
459  $out .= $indent . Xml::element( 'origin', null, strval( $slot->getOrigin() ) ) . "\n";
460  }
461 
462  $contentModel = $slot->getModel();
463  $contentHandler = MediaWikiServices::getInstance()
464  ->getContentHandlerFactory()
465  ->getContentHandler( $contentModel );
466  $contentFormat = $contentHandler->getDefaultFormat();
467 
468  // XXX: The content format is only relevant when actually outputting serialized content.
469  // It should probably be an attribute on the text tag.
470  $out .= $indent . Xml::element( 'model', null, strval( $contentModel ) ) . "\n";
471  $out .= $indent . Xml::element( 'format', null, strval( $contentFormat ) ) . "\n";
472 
473  $textAttributes = [
474  'bytes' => $this->invokeLenient(
475  static function () use ( $slot ) {
476  return $slot->getSize();
477  },
478  'failed to determine size for slot ' . $slot->getRole() . ' of revision '
479  . $slot->getRevision()
480  ) ?: '0'
481  ];
482 
483  if ( $isV11 ) {
484  $textAttributes['sha1'] = $this->invokeLenient(
485  static function () use ( $slot ) {
486  return $slot->getSha1();
487  },
488  'failed to determine sha1 for slot ' . $slot->getRole() . ' of revision '
489  . $slot->getRevision()
490  ) ?: '';
491  }
492 
493  if ( $contentMode === self::WRITE_CONTENT ) {
494  $content = $this->invokeLenient(
495  static function () use ( $slot ) {
496  return $slot->getContent();
497  },
498  'failed to load content for slot ' . $slot->getRole() . ' of revision '
499  . $slot->getRevision()
500  );
501 
502  if ( $content === null ) {
503  $out .= $indent . Xml::element( 'text', $textAttributes ) . "\n";
504  } else {
505  $out .= $this->writeText( $content, $textAttributes, $indent );
506  }
507  } elseif ( $contentMode === self::WRITE_STUB_DELETED ) {
508  // write <text> placeholder tag
509  $textAttributes['deleted'] = 'deleted';
510  $out .= $indent . Xml::element( 'text', $textAttributes ) . "\n";
511  } else {
512  // write <text> stub tag
513  if ( $isV11 ) {
514  $textAttributes['location'] = $slot->getAddress();
515  }
516 
517  if ( $isMain ) {
518  // Output the numerical text ID if possible, for backwards compatibility.
519  // Note that this is currently the ONLY reason we have a BlobStore here at all.
520  // When removing this line, check whether the BlobStore has become unused.
521  try {
522  // NOTE: this will only work for addresses of the form "tt:12345".
523  // If we want to support other kinds of addresses in the future,
524  // we will have to silently ignore failures here.
525  // For now, this fails for "tt:0", which is present in the WMF production
526  // database as of July 2019, due to data corruption.
527  $textId = $this->getBlobStore()->getTextIdFromAddress( $slot->getAddress() );
528  } catch ( InvalidArgumentException $ex ) {
529  MWDebug::warning( 'Bad content address for slot ' . $slot->getRole()
530  . ' of revision ' . $slot->getRevision() . ': ' . $ex->getMessage() );
531  $textId = 0;
532  }
533 
534  if ( is_int( $textId ) ) {
535  $textAttributes['id'] = $textId;
536  }
537  }
538 
539  $out .= $indent . Xml::element( 'text', $textAttributes ) . "\n";
540  }
541 
542  if ( !$isMain ) {
543  $out .= ' ' . Xml::closeElement( 'content' ) . "\n";
544  }
545 
546  return $out;
547  }
548 
556  private function writeText( Content $content, $textAttributes, $indent ) {
557  $out = '';
558 
559  $contentHandler = $content->getContentHandler();
560  $contentFormat = $contentHandler->getDefaultFormat();
561 
562  if ( $content instanceof TextContent ) {
563  // HACK: For text based models, bypass the serialization step. This allows extensions (like Flow)
564  // that use incompatible combinations of serialization format and content model.
565  $data = $content->getNativeData();
566  } else {
567  $data = $content->serialize( $contentFormat );
568  }
569 
570  $data = $contentHandler->exportTransform( $data, $contentFormat );
571  $textAttributes['bytes'] = $size = strlen( $data ); // make sure to use the actual size
572  $textAttributes['xml:space'] = 'preserve';
573  $out .= $indent . Xml::elementClean( 'text', $textAttributes, strval( $data ) ) . "\n";
574 
575  return $out;
576  }
577 
585  public function writeLogItem( $row ) {
586  $out = " <logitem>\n";
587  $out .= " " . Xml::element( 'id', null, strval( $row->log_id ) ) . "\n";
588 
589  $out .= $this->writeTimestamp( $row->log_timestamp, " " );
590 
591  if ( $row->log_deleted & LogPage::DELETED_USER ) {
592  $out .= " " . Xml::element( 'contributor', [ 'deleted' => 'deleted' ] ) . "\n";
593  } else {
594  $out .= $this->writeContributor( $row->actor_user, $row->actor_name, " " );
595  }
596 
597  if ( $row->log_deleted & LogPage::DELETED_COMMENT ) {
598  $out .= " " . Xml::element( 'comment', [ 'deleted' => 'deleted' ] ) . "\n";
599  } else {
600  $comment = CommentStore::getStore()->getComment( 'log_comment', $row )->text;
601  if ( $comment != '' ) {
602  // @phan-suppress-next-line SecurityCheck-DoubleEscaped CommentStore is polluted by truncate
603  $out .= " " . Xml::elementClean( 'comment', null, strval( $comment ) ) . "\n";
604  }
605  }
606 
607  $out .= " " . Xml::element( 'type', null, strval( $row->log_type ) ) . "\n";
608  $out .= " " . Xml::element( 'action', null, strval( $row->log_action ) ) . "\n";
609 
610  if ( $row->log_deleted & LogPage::DELETED_ACTION ) {
611  $out .= " " . Xml::element( 'text', [ 'deleted' => 'deleted' ] ) . "\n";
612  } else {
613  $title = Title::makeTitle( $row->log_namespace, $row->log_title );
614  $out .= " " . Xml::elementClean( 'logtitle', null, self::canonicalTitle( $title ) ) . "\n";
615  $out .= " " . Xml::elementClean( 'params',
616  [ 'xml:space' => 'preserve' ],
617  strval( $row->log_params ) ) . "\n";
618  }
619 
620  $out .= " </logitem>\n";
621 
622  return $out;
623  }
624 
630  public function writeTimestamp( $timestamp, $indent = " " ) {
631  $ts = wfTimestamp( TS_ISO_8601, $timestamp );
632  return $indent . Xml::element( 'timestamp', null, $ts ) . "\n";
633  }
634 
641  public function writeContributor( $id, $text, $indent = " " ) {
642  $out = $indent . "<contributor>\n";
643  if ( $id || !IPUtils::isValid( $text ) ) {
644  $out .= $indent . " " . Xml::elementClean( 'username', null, strval( $text ) ) . "\n";
645  $out .= $indent . " " . Xml::element( 'id', null, strval( $id ) ) . "\n";
646  } else {
647  $out .= $indent . " " . Xml::elementClean( 'ip', null, strval( $text ) ) . "\n";
648  }
649  $out .= $indent . "</contributor>\n";
650  return $out;
651  }
652 
659  public function writeUploads( $row, $dumpContents = false ) {
660  if ( $row->page_namespace == NS_FILE ) {
661  $img = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo()
662  ->newFile( $row->page_title );
663  if ( $img && $img->exists() ) {
664  $out = '';
665  foreach ( array_reverse( $img->getHistory() ) as $ver ) {
666  $out .= $this->writeUpload( $ver, $dumpContents );
667  }
668  $out .= $this->writeUpload( $img, $dumpContents );
669  return $out;
670  }
671  }
672  return '';
673  }
674 
680  private function writeUpload( $file, $dumpContents = false ) {
681  if ( $file->isOld() ) {
683  '@phan-var OldLocalFile $file';
684  $archiveName = " " .
685  Xml::element( 'archivename', null, $file->getArchiveName() ) . "\n";
686  } else {
687  $archiveName = '';
688  }
689  if ( $dumpContents ) {
690  $be = $file->getRepo()->getBackend();
691  # Dump file as base64
692  # Uses only XML-safe characters, so does not need escaping
693  # @todo Too bad this loads the contents into memory (script might swap)
694  $contents = ' <contents encoding="base64">' .
695  chunk_split( base64_encode(
696  $be->getFileContents( [ 'src' => $file->getPath() ] ) ) ) .
697  " </contents>\n";
698  } else {
699  $contents = '';
700  }
701  $uploader = $file->getUploader( File::FOR_PUBLIC );
702  if ( $uploader ) {
703  $uploader = $this->writeContributor( $uploader->getId(), $uploader->getName() );
704  } else {
705  $uploader = Xml::element( 'contributor', [ 'deleted' => 'deleted' ] ) . "\n";
706  }
707  $comment = $file->getDescription( File::FOR_PUBLIC );
708  if ( $comment ) {
709  $comment = Xml::elementClean( 'comment', null, $comment );
710  } else {
711  $comment = Xml::element( 'comment', [ 'deleted' => 'deleted' ] );
712  }
713  return " <upload>\n" .
714  $this->writeTimestamp( $file->getTimestamp() ) .
715  $uploader .
716  " " . $comment . "\n" .
717  " " . Xml::element( 'filename', null, $file->getName() ) . "\n" .
718  $archiveName .
719  " " . Xml::element( 'src', null, $file->getCanonicalUrl() ) . "\n" .
720  " " . Xml::element( 'size', null, $file->getSize() ) . "\n" .
721  " " . Xml::element( 'sha1base36', null, $file->getSha1() ) . "\n" .
722  " " . Xml::element( 'rel', null, $file->getRel() ) . "\n" .
723  $contents .
724  " </upload>\n";
725  }
726 
737  public static function canonicalTitle( Title $title ) {
738  if ( $title->isExternal() ) {
739  return $title->getPrefixedText();
740  }
741 
742  $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
743  getFormattedNsText( $title->getNamespace() );
744 
745  // @todo Emit some kind of warning to the user if $title->getNamespace() !==
746  // NS_MAIN and $prefix === '' (viz. pages in an unregistered namespace)
747 
748  if ( $prefix !== '' ) {
749  $prefix .= ':';
750  }
751 
752  return $prefix . $title->getText();
753  }
754 }
XmlDumpWriter\openStream
openStream()
Opens the XML output stream's root "<mediawiki>" element.
Definition: XmlDumpWriter.php:122
XmlDumpWriter\getBlobStore
getBlobStore()
Definition: XmlDumpWriter.php:299
MediaWiki\Revision\RevisionRecord
Page revision base class.
Definition: RevisionRecord.php:47
$wgDBname
$wgDBname
Current wiki database name.
Definition: DefaultSettings.php:2060
XmlDumpWriter\writeSlot
writeSlot(SlotRecord $slot, $contentMode)
Definition: XmlDumpWriter.php:439
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:195
MediaWiki\Revision\SuppressedDataException
Exception raised in response to an audience check when attempting to access suppressed information wi...
Definition: SuppressedDataException.php:33
XmlDumpWriter\openPage
openPage( $row)
Opens a "<page>" section on the output stream, with data from the given database row.
Definition: XmlDumpWriter.php:241
XmlDumpWriter\dbname
dbname()
Definition: XmlDumpWriter.php:173
MediaWiki\Revision\RevisionStore
Service for looking up page revisions.
Definition: RevisionStore.php:88
XML_DUMP_SCHEMA_VERSION_10
const XML_DUMP_SCHEMA_VERSION_10
Definition: Defines.php:313
MediaWiki\Storage\SqlBlobStore
Service for storing and loading Content objects.
Definition: SqlBlobStore.php:52
XmlDumpWriter\siteInfo
siteInfo()
Definition: XmlDumpWriter.php:149
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1668
MW_VERSION
const MW_VERSION
The running version of MediaWiki.
Definition: Defines.php:36
XmlDumpWriter\homelink
homelink()
Definition: XmlDumpWriter.php:188
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
MediaWiki\Revision\SlotRecord\getSha1
getSha1()
Returns the content size.
Definition: SlotRecord.php:556
Title\newMainPage
static newMainPage(MessageLocalizer $localizer=null)
Create a new Title for the Main Page.
Definition: Title.php:712
XmlDumpWriter\$supportedSchemas
static string[] $supportedSchemas
the schema versions supported for output @final
Definition: XmlDumpWriter.php:57
Xml\openElement
static openElement( $element, $attribs=null)
This opens an XML element.
Definition: Xml.php:110
File\FOR_PUBLIC
const FOR_PUBLIC
Definition: File.php:86
XmlDumpWriter\writeLogItem
writeLogItem( $row)
Dumps a "<logitem>" section on the output stream, with data filled in from the given database row.
Definition: XmlDumpWriter.php:585
Xml\elementClean
static elementClean( $element, $attribs=[], $contents='')
Format an XML element as with self::element(), but run text through the content language's normalize(...
Definition: Xml.php:92
MWException
MediaWiki exception.
Definition: MWException.php:29
XmlDumpWriter\WRITE_CONTENT
const WRITE_CONTENT
Output serialized revision content.
Definition: XmlDumpWriter.php:42
LogPage\DELETED_COMMENT
const DELETED_COMMENT
Definition: LogPage.php:40
XmlDumpWriter\canonicalTitle
static canonicalTitle(Title $title)
Return prefixed text form of title, but using the content language's canonical namespace.
Definition: XmlDumpWriter.php:737
Title\newFromRow
static newFromRow( $row)
Make a Title object from a DB row.
Definition: Title.php:579
LogPage\DELETED_USER
const DELETED_USER
Definition: LogPage.php:41
XmlDumpWriter\writeContributor
writeContributor( $id, $text, $indent=" ")
Definition: XmlDumpWriter.php:641
Title\isValidRedirectTarget
isValidRedirectTarget()
Check if this Title is a valid redirect target.
Definition: Title.php:3872
Xml\element
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:41
XML_DUMP_SCHEMA_VERSION_11
const XML_DUMP_SCHEMA_VERSION_11
Definition: Defines.php:314
$title
$title
Definition: testCompression.php:38
XmlDumpWriter\__construct
__construct( $contentMode=self::WRITE_CONTENT, $schemaVersion=XML_DUMP_SCHEMA_VERSION_11)
Definition: XmlDumpWriter.php:90
Title\makeTitle
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:650
XmlDumpWriter\namespaces
namespaces()
Definition: XmlDumpWriter.php:205
XmlDumpWriter\closeStream
closeStream()
Closes the output stream with the closing root element.
Definition: XmlDumpWriter.php:230
LogPage\DELETED_ACTION
const DELETED_ACTION
Definition: LogPage.php:39
XmlDumpWriter\WRITE_STUB_DELETED
const WRITE_STUB_DELETED
Only output subs for revision content, indicating that the content has been deleted/suppressed.
Definition: XmlDumpWriter.php:51
MediaWiki\Revision\SlotRecord\getAddress
getAddress()
Returns the address of this slot's content.
Definition: SlotRecord.php:517
$content
$content
Definition: router.php:76
MediaWiki\Revision\SlotRecord\getOrigin
getOrigin()
Returns the revision ID of the revision that originated the slot's content.
Definition: SlotRecord.php:423
XmlDumpWriter\writeText
writeText(Content $content, $textAttributes, $indent)
Definition: XmlDumpWriter.php:556
XmlDumpWriter\getRevisionStore
getRevisionStore()
Definition: XmlDumpWriter.php:292
XmlDumpWriter\caseSetting
caseSetting()
Definition: XmlDumpWriter.php:195
$wgSitename
$wgSitename
Name of the site.
Definition: DefaultSettings.php:82
XmlDumpWriter\writeUpload
writeUpload( $file, $dumpContents=false)
Definition: XmlDumpWriter.php:680
XmlDumpWriter\writeTimestamp
writeTimestamp( $timestamp, $indent=" ")
Definition: XmlDumpWriter.php:630
TextContent
Content object implementation for representing flat text.
Definition: TextContent.php:39
XmlDumpWriter\sitename
sitename()
Definition: XmlDumpWriter.php:165
Content
Base interface for content objects.
Definition: Content.php:35
XmlDumpWriter\WRITE_STUB
const WRITE_STUB
Only output subs for revision content.
Definition: XmlDumpWriter.php:45
Title
Represents a title within MediaWiki.
Definition: Title.php:47
MediaWiki\Revision\SlotRecord\getSize
getSize()
Returns the content size.
Definition: SlotRecord.php:540
Xml\closeElement
static closeElement( $element)
Shortcut to close an XML element.
Definition: Xml.php:119
$wgCapitalLinks
$wgCapitalLinks
Set this to false to avoid forcing the first letter of links to capitals.
Definition: DefaultSettings.php:4665
XmlDumpWriter\$contentMode
int $contentMode
Whether to output revision content or just stubs.
Definition: XmlDumpWriter.php:79
XmlDumpWriter
Definition: XmlDumpWriter.php:39
XmlDumpWriter\writeRevision
writeRevision( $row, $slotRows=null)
Dumps a "<revision>" section on the output stream, with data filled in from the given database row.
Definition: XmlDumpWriter.php:342
XmlDumpWriter\generator
generator()
Definition: XmlDumpWriter.php:181
XmlDumpWriter\$currentTitle
Title null $currentTitle
Title of the currently processed page.
Definition: XmlDumpWriter.php:74
XmlDumpWriter\$hookRunner
HookRunner $hookRunner
Definition: XmlDumpWriter.php:82
MediaWiki\Revision\SlotRecord\getRole
getRole()
Returns the role of the slot.
Definition: SlotRecord.php:507
XmlDumpWriter\$schemaVersion
string $schemaVersion
which schema version the generated XML should comply to.
Definition: XmlDumpWriter.php:67
MediaWiki\HookContainer\HookRunner
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:557
NS_FILE
const NS_FILE
Definition: Defines.php:70
MWDebug\warning
static warning( $msg, $callerOffset=1, $level=E_USER_NOTICE, $log='auto')
Adds a warning entry to the log.
Definition: MWDebug.php:180
CommentStore\getStore
static getStore()
Definition: CommentStore.php:120
MediaWiki\Revision\SlotRecord\getContent
getContent()
Returns the Content of the given slot.
Definition: SlotRecord.php:317
MediaWiki\Revision\SlotRecord\getModel
getModel()
Returns the content model.
Definition: SlotRecord.php:584
XmlDumpWriter\closePage
closePage()
Closes a "<page>" section on the output stream.
Definition: XmlDumpWriter.php:279
XmlDumpWriter\writeUploads
writeUploads( $row, $dumpContents=false)
Warning! This data is potentially inconsistent.
Definition: XmlDumpWriter.php:659
MediaWiki\Revision\SlotRecord
Value object representing a content slot associated with a page revision.
Definition: SlotRecord.php:40
MediaWiki\Revision\SlotRecord\getRevision
getRevision()
Returns the ID of the revision this slot is associated with.
Definition: SlotRecord.php:414
XmlDumpWriter\invokeLenient
invokeLenient( $callback, $warning)
Invokes the given callback, catching and logging any storage related exceptions.
Definition: XmlDumpWriter.php:315