MediaWiki  master
Revision.php
Go to the documentation of this file.
1 <?php
38 
42 class Revision implements IDBAccessObject {
43 
45  protected $mRecord;
46 
47  // Revision deletion constants
54 
55  // Audience options for accessors
59 
60  const TEXT_CACHE_GROUP = SqlBlobStore::TEXT_CACHE_GROUP;
61 
65  protected static function getRevisionStore( $wiki = false ) {
66  if ( $wiki ) {
67  return MediaWikiServices::getInstance()->getRevisionStoreFactory()
68  ->getRevisionStore( $wiki );
69  } else {
70  return MediaWikiServices::getInstance()->getRevisionStore();
71  }
72  }
73 
77  protected static function getRevisionLookup() {
78  return MediaWikiServices::getInstance()->getRevisionLookup();
79  }
80 
84  protected static function getRevisionFactory() {
85  return MediaWikiServices::getInstance()->getRevisionFactory();
86  }
87 
93  protected static function getBlobStore( $wiki = false ) {
94  $store = MediaWikiServices::getInstance()
95  ->getBlobStoreFactory()
96  ->newSqlBlobStore( $wiki );
97 
98  if ( !$store instanceof SqlBlobStore ) {
99  throw new RuntimeException(
100  'The backwards compatibility code in Revision currently requires the BlobStore '
101  . 'service to be an SqlBlobStore instance, but it is a ' . get_class( $store )
102  );
103  }
104 
105  return $store;
106  }
107 
120  public static function newFromId( $id, $flags = 0 ) {
121  $rec = self::getRevisionLookup()->getRevisionById( $id, $flags );
122  return $rec === null ? null : new Revision( $rec, $flags );
123  }
124 
139  public static function newFromTitle( LinkTarget $linkTarget, $id = 0, $flags = 0 ) {
140  $rec = self::getRevisionLookup()->getRevisionByTitle( $linkTarget, $id, $flags );
141  return $rec === null ? null : new Revision( $rec, $flags );
142  }
143 
158  public static function newFromPageId( $pageId, $revId = 0, $flags = 0 ) {
159  $rec = self::getRevisionLookup()->getRevisionByPageId( $pageId, $revId, $flags );
160  return $rec === null ? null : new Revision( $rec, $flags );
161  }
162 
173  public static function newFromArchiveRow( $row, $overrides = [] ) {
180  if ( array_key_exists( 'page', $overrides ) ) {
181  $overrides['page_id'] = $overrides['page'];
182  unset( $overrides['page'] );
183  }
184 
190  $title = null;
191  if ( isset( $overrides['title'] ) ) {
192  if ( !( $overrides['title'] instanceof Title ) ) {
193  throw new MWException( 'title field override must contain a Title object.' );
194  }
195 
196  $title = $overrides['title'];
197  }
198  if ( $title !== null ) {
199  if ( isset( $row->ar_namespace ) && isset( $row->ar_title ) ) {
200  $title = Title::makeTitle( $row->ar_namespace, $row->ar_title );
201  } else {
202  throw new InvalidArgumentException(
203  'A Title or ar_namespace and ar_title must be given'
204  );
205  }
206  }
207 
208  $rec = self::getRevisionFactory()->newRevisionFromArchiveRow( $row, 0, $title, $overrides );
209  return new Revision( $rec, self::READ_NORMAL, $title );
210  }
211 
224  public static function newFromRow( $row ) {
225  if ( is_array( $row ) ) {
226  $rec = self::getRevisionFactory()->newMutableRevisionFromArray( $row );
227  } else {
228  $rec = self::getRevisionFactory()->newRevisionFromRow( $row );
229  }
230 
231  return new Revision( $rec );
232  }
233 
244  public static function loadFromId( $db, $id ) {
245  wfDeprecated( __METHOD__, '1.31' ); // no known callers
246  $rec = self::getRevisionStore()->loadRevisionFromId( $db, $id );
247  return $rec === null ? null : new Revision( $rec );
248  }
249 
262  public static function loadFromPageId( $db, $pageid, $id = 0 ) {
263  $rec = self::getRevisionStore()->loadRevisionFromPageId( $db, $pageid, $id );
264  return $rec === null ? null : new Revision( $rec );
265  }
266 
279  public static function loadFromTitle( $db, $title, $id = 0 ) {
280  $rec = self::getRevisionStore()->loadRevisionFromTitle( $db, $title, $id );
281  return $rec === null ? null : new Revision( $rec );
282  }
283 
297  public static function loadFromTimestamp( $db, $title, $timestamp ) {
298  $rec = self::getRevisionStore()->loadRevisionFromTimestamp( $db, $title, $timestamp );
299  return $rec === null ? null : new Revision( $rec );
300  }
301 
311  public static function fetchRevision( LinkTarget $title ) {
312  wfDeprecated( __METHOD__, '1.31' );
313  return new FakeResultWrapper( [] );
314  }
315 
323  public static function userJoinCond() {
325 
326  wfDeprecated( __METHOD__, '1.31' );
327  if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
328  // If code is using this instead of self::getQueryInfo(), there's
329  // no way the join it's trying to do can work once the old fields
330  // aren't being used anymore.
331  throw new BadMethodCallException(
332  'Cannot use ' . __METHOD__
333  . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
334  );
335  }
336 
337  return [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ];
338  }
339 
347  public static function pageJoinCond() {
348  wfDeprecated( __METHOD__, '1.31' );
349  return [ 'INNER JOIN', [ 'page_id = rev_page' ] ];
350  }
351 
358  public static function selectFields() {
361 
362  if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
363  // If code is using this instead of self::getQueryInfo(), there's a
364  // decent chance it's going to try to directly access
365  // $row->rev_user or $row->rev_user_text and we can't give it
366  // useful values here once those aren't being used anymore.
367  throw new BadMethodCallException(
368  'Cannot use ' . __METHOD__
369  . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
370  );
371  }
372 
373  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
374  // If code is using this instead of self::getQueryInfo(), there's a
375  // decent chance it's going to try to directly access
376  // $row->rev_text_id or $row->rev_content_model and we can't give it
377  // useful values here once those aren't being written anymore,
378  // and may not exist at all.
379  throw new BadMethodCallException(
380  'Cannot use ' . __METHOD__ . ' when $wgMultiContentRevisionSchemaMigrationStage '
381  . 'does not have SCHEMA_COMPAT_WRITE_OLD set.'
382  );
383  }
384 
385  wfDeprecated( __METHOD__, '1.31' );
386 
387  $fields = [
388  'rev_id',
389  'rev_page',
390  'rev_text_id',
391  'rev_timestamp',
392  'rev_user_text',
393  'rev_user',
394  'rev_actor' => 'NULL',
395  'rev_minor_edit',
396  'rev_deleted',
397  'rev_len',
398  'rev_parent_id',
399  'rev_sha1',
400  ];
401 
402  $fields += CommentStore::getStore()->getFields( 'rev_comment' );
403 
404  if ( $wgContentHandlerUseDB ) {
405  $fields[] = 'rev_content_format';
406  $fields[] = 'rev_content_model';
407  }
408 
409  return $fields;
410  }
411 
418  public static function selectArchiveFields() {
421 
422  if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
423  // If code is using this instead of self::getQueryInfo(), there's a
424  // decent chance it's going to try to directly access
425  // $row->ar_user or $row->ar_user_text and we can't give it
426  // useful values here once those aren't being used anymore.
427  throw new BadMethodCallException(
428  'Cannot use ' . __METHOD__
429  . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
430  );
431  }
432 
433  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
434  // If code is using this instead of self::getQueryInfo(), there's a
435  // decent chance it's going to try to directly access
436  // $row->ar_text_id or $row->ar_content_model and we can't give it
437  // useful values here once those aren't being written anymore,
438  // and may not exist at all.
439  throw new BadMethodCallException(
440  'Cannot use ' . __METHOD__ . ' when $wgMultiContentRevisionSchemaMigrationStage '
441  . 'does not have SCHEMA_COMPAT_WRITE_OLD set.'
442  );
443  }
444 
445  wfDeprecated( __METHOD__, '1.31' );
446 
447  $fields = [
448  'ar_id',
449  'ar_page_id',
450  'ar_rev_id',
451  'ar_text_id',
452  'ar_timestamp',
453  'ar_user_text',
454  'ar_user',
455  'ar_actor' => 'NULL',
456  'ar_minor_edit',
457  'ar_deleted',
458  'ar_len',
459  'ar_parent_id',
460  'ar_sha1',
461  ];
462 
463  $fields += CommentStore::getStore()->getFields( 'ar_comment' );
464 
465  if ( $wgContentHandlerUseDB ) {
466  $fields[] = 'ar_content_format';
467  $fields[] = 'ar_content_model';
468  }
469  return $fields;
470  }
471 
478  public static function selectTextFields() {
479  wfDeprecated( __METHOD__, '1.31' );
480  return [
481  'old_text',
482  'old_flags'
483  ];
484  }
485 
491  public static function selectPageFields() {
492  wfDeprecated( __METHOD__, '1.31' );
493  return [
494  'page_namespace',
495  'page_title',
496  'page_id',
497  'page_latest',
498  'page_is_redirect',
499  'page_len',
500  ];
501  }
502 
508  public static function selectUserFields() {
509  wfDeprecated( __METHOD__, '1.31' );
510  return [ 'user_name' ];
511  }
512 
527  public static function getQueryInfo( $options = [] ) {
528  return self::getRevisionStore()->getQueryInfo( $options );
529  }
530 
541  public static function getArchiveQueryInfo() {
542  return self::getRevisionStore()->getArchiveQueryInfo();
543  }
544 
554  public static function getParentLengths( $db, array $revIds ) {
555  return self::getRevisionStore()->listRevisionSizes( $db, $revIds );
556  }
557 
565  function __construct( $row, $queryFlags = 0, Title $title = null ) {
566  global $wgUser;
567 
568  if ( $row instanceof RevisionRecord ) {
569  $this->mRecord = $row;
570  } elseif ( is_array( $row ) ) {
571  // If no user is specified, fall back to using the global user object, to stay
572  // compatible with pre-1.31 behavior.
573  if ( !isset( $row['user'] ) && !isset( $row['user_text'] ) ) {
574  $row['user'] = $wgUser;
575  }
576 
577  $this->mRecord = self::getRevisionFactory()->newMutableRevisionFromArray(
578  $row,
579  $queryFlags,
580  $this->ensureTitle( $row, $queryFlags, $title )
581  );
582  } elseif ( is_object( $row ) ) {
583  $this->mRecord = self::getRevisionFactory()->newRevisionFromRow(
584  $row,
585  $queryFlags,
586  $this->ensureTitle( $row, $queryFlags, $title )
587  );
588  } else {
589  throw new InvalidArgumentException(
590  '$row must be a row object, an associative array, or a RevisionRecord'
591  );
592  }
593 
594  Assert::postcondition( $this->mRecord !== null, 'Failed to construct a RevisionRecord' );
595  }
596 
607  private function ensureTitle( $row, $queryFlags, $title = null ) {
608  if ( $title ) {
609  return $title;
610  }
611 
612  if ( is_array( $row ) ) {
613  if ( isset( $row['title'] ) ) {
614  if ( !( $row['title'] instanceof Title ) ) {
615  throw new MWException( 'title field must contain a Title object.' );
616  }
617 
618  return $row['title'];
619  }
620 
621  $pageId = $row['page'] ?? 0;
622  $revId = $row['id'] ?? 0;
623  } else {
624  $pageId = $row->rev_page ?? 0;
625  $revId = $row->rev_id ?? 0;
626  }
627 
628  try {
629  $title = self::getRevisionStore()->getTitle( $pageId, $revId, $queryFlags );
630  } catch ( RevisionAccessException $ex ) {
631  // construct a dummy title!
632  wfLogWarning( __METHOD__ . ': ' . $ex->getMessage() );
633 
634  // NOTE: this Title will only be used inside RevisionRecord
635  $title = Title::makeTitleSafe( NS_SPECIAL, "Badtitle/ID=$pageId" );
636  $title->resetArticleID( $pageId );
637  }
638 
639  return $title;
640  }
641 
645  public function getRevisionRecord() {
646  return $this->mRecord;
647  }
648 
654  public function getId() {
655  return $this->mRecord->getId();
656  }
657 
670  public function setId( $id ) {
671  if ( $this->mRecord instanceof MutableRevisionRecord ) {
672  $this->mRecord->setId( intval( $id ) );
673  } else {
674  throw new MWException( __METHOD__ . ' is not supported on this instance' );
675  }
676  }
677 
692  public function setUserIdAndName( $id, $name ) {
693  if ( $this->mRecord instanceof MutableRevisionRecord ) {
694  $user = User::newFromAnyId( intval( $id ), $name, null );
695  $this->mRecord->setUser( $user );
696  } else {
697  throw new MWException( __METHOD__ . ' is not supported on this instance' );
698  }
699  }
700 
704  private function getMainSlotRaw() {
705  return $this->mRecord->getSlot( SlotRecord::MAIN, RevisionRecord::RAW );
706  }
707 
720  public function getTextId() {
721  $slot = $this->getMainSlotRaw();
722  return $slot->hasAddress()
723  ? self::getBlobStore()->getTextIdFromAddress( $slot->getAddress() )
724  : null;
725  }
726 
733  public function getParentId() {
734  return $this->mRecord->getParentId();
735  }
736 
742  public function getSize() {
743  try {
744  return $this->mRecord->getSize();
745  } catch ( RevisionAccessException $ex ) {
746  return null;
747  }
748  }
749 
755  public function getSha1() {
756  try {
757  return $this->mRecord->getSha1();
758  } catch ( RevisionAccessException $ex ) {
759  return null;
760  }
761  }
762 
771  public function getTitle() {
772  $linkTarget = $this->mRecord->getPageAsLinkTarget();
773  return Title::newFromLinkTarget( $linkTarget );
774  }
775 
783  public function setTitle( $title ) {
784  if ( !$title->equals( $this->getTitle() ) ) {
785  throw new InvalidArgumentException(
786  $title->getPrefixedText()
787  . ' is not the same as '
788  . $this->mRecord->getPageAsLinkTarget()->__toString()
789  );
790  }
791  }
792 
798  public function getPage() {
799  return $this->mRecord->getPageId();
800  }
801 
815  public function getUser( $audience = self::FOR_PUBLIC, User $user = null ) {
816  global $wgUser;
817 
818  if ( $audience === self::FOR_THIS_USER && !$user ) {
819  $user = $wgUser;
820  }
821 
822  $user = $this->mRecord->getUser( $audience, $user );
823  return $user ? $user->getId() : 0;
824  }
825 
839  public function getUserText( $audience = self::FOR_PUBLIC, User $user = null ) {
840  global $wgUser;
841 
842  if ( $audience === self::FOR_THIS_USER && !$user ) {
843  $user = $wgUser;
844  }
845 
846  $user = $this->mRecord->getUser( $audience, $user );
847  return $user ? $user->getName() : '';
848  }
849 
863  function getComment( $audience = self::FOR_PUBLIC, User $user = null ) {
864  global $wgUser;
865 
866  if ( $audience === self::FOR_THIS_USER && !$user ) {
867  $user = $wgUser;
868  }
869 
870  $comment = $this->mRecord->getComment( $audience, $user );
871  return $comment === null ? null : $comment->text;
872  }
873 
877  public function isMinor() {
878  return $this->mRecord->isMinor();
879  }
880 
884  public function isUnpatrolled() {
885  return self::getRevisionStore()->getRcIdIfUnpatrolled( $this->mRecord );
886  }
887 
897  public function getRecentChange( $flags = 0 ) {
898  return self::getRevisionStore()->getRecentChange( $this->mRecord, $flags );
899  }
900 
906  public function isDeleted( $field ) {
907  return $this->mRecord->isDeleted( $field );
908  }
909 
915  public function getVisibility() {
916  return $this->mRecord->getVisibility();
917  }
918 
933  public function getContent( $audience = self::FOR_PUBLIC, User $user = null ) {
934  global $wgUser;
935 
936  if ( $audience === self::FOR_THIS_USER && !$user ) {
937  $user = $wgUser;
938  }
939 
940  try {
941  return $this->mRecord->getContent( SlotRecord::MAIN, $audience, $user );
942  }
943  catch ( RevisionAccessException $e ) {
944  return null;
945  }
946  }
947 
956  public function getSerializedData() {
957  $slot = $this->getMainSlotRaw();
958  return $slot->getContent()->serialize();
959  }
960 
973  public function getContentModel() {
974  return $this->getMainSlotRaw()->getModel();
975  }
976 
988  public function getContentFormat() {
989  $format = $this->getMainSlotRaw()->getFormat();
990 
991  if ( $format === null ) {
992  // if no format was stored along with the blob, fall back to default format
993  $format = $this->getContentHandler()->getDefaultFormat();
994  }
995 
996  return $format;
997  }
998 
1005  public function getContentHandler() {
1007  }
1008 
1012  public function getTimestamp() {
1013  return $this->mRecord->getTimestamp();
1014  }
1015 
1019  public function isCurrent() {
1020  return ( $this->mRecord instanceof RevisionStoreRecord ) && $this->mRecord->isCurrent();
1021  }
1022 
1028  public function getPrevious() {
1029  $title = $this->getTitle();
1030  $rec = self::getRevisionLookup()->getPreviousRevision( $this->mRecord, $title );
1031  return $rec === null ? null : new Revision( $rec, self::READ_NORMAL, $title );
1032  }
1033 
1039  public function getNext() {
1040  $title = $this->getTitle();
1041  $rec = self::getRevisionLookup()->getNextRevision( $this->mRecord, $title );
1042  return $rec === null ? null : new Revision( $rec, self::READ_NORMAL, $title );
1043  }
1044 
1066  public static function getRevisionText( $row, $prefix = 'old_', $wiki = false ) {
1068 
1069  if ( !$row ) {
1070  return false;
1071  }
1072 
1073  $textField = $prefix . 'text';
1074  $flagsField = $prefix . 'flags';
1075 
1076  if ( isset( $row->$textField ) ) {
1077  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
1078  // The text field was read, but it's no longer being populated!
1079  // We could gloss over this by using the text when it's there and loading
1080  // if when it's not, but it seems preferable to complain loudly about a
1081  // query that is no longer guaranteed to work reliably.
1082  throw new LogicException(
1083  'Cannot use ' . __METHOD__ . ' with the ' . $textField . ' field when'
1084  . ' $wgMultiContentRevisionSchemaMigrationStage does not include'
1085  . ' SCHEMA_COMPAT_WRITE_OLD. The field may not be populated for all revisions!'
1086  );
1087  }
1088 
1089  $text = $row->$textField;
1090  } else {
1091  // Missing text field, we are probably looking at the MCR-enabled DB schema.
1092 
1093  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
1094  // This method should no longer be used with the new schema. Ideally, we
1095  // would already trigger a deprecation warning when SCHEMA_COMPAT_READ_NEW is set.
1096  wfDeprecated( __METHOD__ . ' (MCR without SCHEMA_COMPAT_WRITE_OLD)', '1.32' );
1097  }
1098 
1099  $store = self::getRevisionStore( $wiki );
1100  $rev = $prefix === 'ar_'
1101  ? $store->newRevisionFromArchiveRow( $row )
1102  : $store->newRevisionFromRow( $row );
1103 
1104  $content = $rev->getContent( SlotRecord::MAIN );
1105  return $content ? $content->serialize() : false;
1106  }
1107 
1108  if ( isset( $row->$flagsField ) ) {
1109  $flags = explode( ',', $row->$flagsField );
1110  } else {
1111  $flags = [];
1112  }
1113 
1114  $cacheKey = isset( $row->old_id )
1115  ? SqlBlobStore::makeAddressFromTextId( $row->old_id )
1116  : null;
1117 
1118  $revisionText = self::getBlobStore( $wiki )->expandBlob( $text, $flags, $cacheKey );
1119 
1120  if ( $revisionText === false ) {
1121  if ( isset( $row->old_id ) ) {
1122  wfLogWarning( __METHOD__ . ": Bad data in text row {$row->old_id}! " );
1123  } else {
1124  wfLogWarning( __METHOD__ . ": Bad data in text row! " );
1125  }
1126  return false;
1127  }
1128 
1129  return $revisionText;
1130  }
1131 
1142  public static function compressRevisionText( &$text ) {
1143  return self::getBlobStore()->compressData( $text );
1144  }
1145 
1153  public static function decompressRevisionText( $text, $flags ) {
1154  if ( $text === false ) {
1155  // Text failed to be fetched; nothing to do
1156  return false;
1157  }
1158 
1159  return self::getBlobStore()->decompressData( $text, $flags );
1160  }
1161 
1170  public function insertOn( $dbw ) {
1171  global $wgUser;
1172 
1173  // Note that $this->mRecord->getId() will typically return null here, but not always,
1174  // e.g. not when restoring a revision.
1175 
1176  if ( $this->mRecord->getUser( RevisionRecord::RAW ) === null ) {
1177  if ( $this->mRecord instanceof MutableRevisionRecord ) {
1178  $this->mRecord->setUser( $wgUser );
1179  } else {
1180  throw new MWException( 'Cannot insert revision with no associated user.' );
1181  }
1182  }
1183 
1184  $rec = self::getRevisionStore()->insertRevisionOn( $this->mRecord, $dbw );
1185 
1186  $this->mRecord = $rec;
1187  Assert::postcondition( $this->mRecord !== null, 'Failed to acquire a RevisionRecord' );
1188 
1189  return $rec->getId();
1190  }
1191 
1197  public static function base36Sha1( $text ) {
1198  return SlotRecord::base36Sha1( $text );
1199  }
1200 
1216  public static function newNullRevision( $dbw, $pageId, $summary, $minor, $user = null ) {
1217  global $wgUser;
1218  if ( !$user ) {
1219  $user = $wgUser;
1220  }
1221 
1222  $comment = CommentStoreComment::newUnsavedComment( $summary, null );
1223 
1225  if ( $title === null ) {
1226  return null;
1227  }
1228 
1229  $rec = self::getRevisionStore()->newNullRevision( $dbw, $title, $comment, $minor, $user );
1230 
1231  return $rec ? new Revision( $rec ) : null;
1232  }
1233 
1244  public function userCan( $field, User $user = null ) {
1245  return self::userCanBitfield( $this->getVisibility(), $field, $user );
1246  }
1247 
1262  public static function userCanBitfield( $bitfield, $field, User $user = null,
1263  Title $title = null
1264  ) {
1265  global $wgUser;
1266 
1267  if ( !$user ) {
1268  $user = $wgUser;
1269  }
1270 
1271  return RevisionRecord::userCanBitfield( $bitfield, $field, $user, $title );
1272  }
1273 
1282  static function getTimestampFromId( $title, $id, $flags = 0 ) {
1283  return self::getRevisionStore()->getTimestampFromId( $title, $id, $flags );
1284  }
1285 
1293  static function countByPageId( $db, $id ) {
1294  return self::getRevisionStore()->countRevisionsByPageId( $db, $id );
1295  }
1296 
1304  static function countByTitle( $db, $title ) {
1305  return self::getRevisionStore()->countRevisionsByTitle( $db, $title );
1306  }
1307 
1324  public static function userWasLastToEdit( $db, $pageId, $userId, $since ) {
1325  if ( is_int( $db ) ) {
1326  $db = wfGetDB( $db );
1327  }
1328 
1329  return self::getRevisionStore()->userWasLastToEdit( $db, $pageId, $userId, $since );
1330  }
1331 
1345  public static function newKnownCurrent( IDatabase $db, $pageIdOrTitle, $revId = 0 ) {
1346  $title = $pageIdOrTitle instanceof Title
1347  ? $pageIdOrTitle
1348  : Title::newFromID( $pageIdOrTitle );
1349 
1350  if ( !$title ) {
1351  return false;
1352  }
1353 
1354  $record = self::getRevisionLookup()->getKnownCurrentRevision( $title, $revId );
1355  return $record ? new Revision( $record ) : false;
1356  }
1357 }
const SCHEMA_COMPAT_WRITE_OLD
Definition: Defines.php:284
The wiki should then use memcached to cache various data To use multiple just add more items to the array To increase the weight of a make its entry a array("192.168.0.1:11211", 2))
Service for storing and loading Content objects.
userCan( $field, User $user=null)
Determine if the current user is allowed to view a particular field of this revision, if it&#39;s marked as deleted.
Definition: Revision.php:1244
getUserText( $audience=self::FOR_PUBLIC, User $user=null)
Fetch revision&#39;s username if it&#39;s available to the specified audience.
Definition: Revision.php:839
const FOR_THIS_USER
Definition: Revision.php:57
static newFromArchiveRow( $row, $overrides=[])
Make a fake revision object from an archive table row.
Definition: Revision.php:173
const TEXT_CACHE_GROUP
Definition: Revision.php:60
A RevisionRecord representing an existing revision persisted in the revision table.
static getTimestampFromId( $title, $id, $flags=0)
Get rev_timestamp from rev_id, without loading the rest of the row.
Definition: Revision.php:1282
static fetchRevision(LinkTarget $title)
Return a wrapper for a series of database rows to fetch all of a given page&#39;s revisions in turn...
Definition: Revision.php:311
static newFromID( $id, $flags=0)
Create a new Title from an article ID.
Definition: Title.php:427
getRevisionRecord()
Definition: Revision.php:645
getPage()
Get the page ID.
Definition: Revision.php:798
static countByPageId( $db, $id)
Get count of revisions per page...not very efficient.
Definition: Revision.php:1293
int $wgMultiContentRevisionSchemaMigrationStage
RevisionStore table schema migration stage (content, slots, content_models & slot_roles tables)...
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
getTimestamp()
Definition: Revision.php:1012
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2172
setTitle( $title)
Set the title of the revision.
Definition: Revision.php:783
int $wgActorTableSchemaMigrationStage
Actor table schema migration stage.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
static loadFromTimestamp( $db, $title, $timestamp)
Load the revision for the given title with the given timestamp.
Definition: Revision.php:297
static getParentLengths( $db, array $revIds)
Do a batched query to get the parent revision lengths.
Definition: Revision.php:554
static getRevisionLookup()
Definition: Revision.php:77
setUserIdAndName( $id, $name)
Set the user ID/name.
Definition: Revision.php:692
const NS_SPECIAL
Definition: Defines.php:53
static newFromPageId( $pageId, $revId=0, $flags=0)
Load either the current, or a specified, revision that&#39;s attached to a given page ID...
Definition: Revision.php:158
const SCHEMA_COMPAT_READ_NEW
Definition: Defines.php:287
getRecentChange( $flags=0)
Get the RC object belonging to the current revision, if there&#39;s one.
Definition: Revision.php:897
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:23
static loadFromPageId( $db, $pageid, $id=0)
Load either the current, or a specified, revision that&#39;s attached to a given page.
Definition: Revision.php:262
isUnpatrolled()
Definition: Revision.php:884
wfLogWarning( $msg, $callerOffset=1, $level=E_USER_WARNING)
Send a warning as a PHP error and the debug log.
getContent( $audience=self::FOR_PUBLIC, User $user=null)
Fetch revision content if it&#39;s available to the specified audience.
Definition: Revision.php:933
static selectArchiveFields()
Return the list of revision fields that should be selected to create a new revision from an archive r...
Definition: Revision.php:418
static userWasLastToEdit( $db, $pageId, $userId, $since)
Check if no edits were made by other users since the time a user started editing the page...
Definition: Revision.php:1324
static newFromLinkTarget(LinkTarget $linkTarget)
Create a new Title from a LinkTarget.
Definition: Title.php:251
static decompressRevisionText( $text, $flags)
Re-converts revision text according to it&#39;s flags.
Definition: Revision.php:1153
static newFromTitle(LinkTarget $linkTarget, $id=0, $flags=0)
Load either the current, or a specified, revision that&#39;s attached to a given link target...
Definition: Revision.php:139
static newUnsavedComment( $comment, array $data=null)
Create a new, unsaved CommentStoreComment.
static getRevisionText( $row, $prefix='old_', $wiki=false)
Get revision text associated with an old or archive row.
Definition: Revision.php:1066
getSerializedData()
Get original serialized data (without checking view restrictions)
Definition: Revision.php:956
Mutable RevisionRecord implementation, for building new revision entries programmatically.
getMainSlotRaw()
Definition: Revision.php:704
The User object encapsulates all of the user-specific settings (user_id, name, rights, email address, options, last login time).
Definition: User.php:47
$wgContentHandlerUseDB
Set to false to disable use of the database fields introduced by the ContentHandler facility...
static getRevisionStore( $wiki=false)
Definition: Revision.php:65
RevisionRecord $mRecord
Definition: Revision.php:45
getTitle()
Returns the title of the page associated with this entry.
Definition: Revision.php:771
getParentId()
Get parent revision ID (the original previous page revision)
Definition: Revision.php:733
getUser( $audience=self::FOR_PUBLIC, User $user=null)
Fetch revision&#39;s user id if it&#39;s available to the specified audience.
Definition: Revision.php:815
const FOR_PUBLIC
Definition: Revision.php:56
static getForModelID( $modelId)
Returns the ContentHandler singleton for the given model ID.
__construct( $row, $queryFlags=0, Title $title=null)
Definition: Revision.php:565
isDeleted( $field)
Definition: Revision.php:906
static newKnownCurrent(IDatabase $db, $pageIdOrTitle, $revId=0)
Load a revision based on a known page ID and current revision ID from the DB.
Definition: Revision.php:1345
getId()
Get revision ID.
Definition: Revision.php:654
static userCanBitfield( $bitfield, $field, User $user=null, Title $title=null)
Determine if the current user is allowed to view a particular field of this revision, if it&#39;s marked as deleted.
Definition: Revision.php:1262
getContentHandler()
Returns the content handler appropriate for this revision&#39;s content model.
Definition: Revision.php:1005
const GAID_FOR_UPDATE
Used to be GAID_FOR_UPDATE define.
Definition: Title.php:54
static userCanBitfield( $bitfield, $field, User $user, Title $title=null)
Determine if the current user is allowed to view a particular field of this revision, if it&#39;s marked as deleted.
static compressRevisionText(&$text)
If $wgCompressRevisions is enabled, we will compress data.
Definition: Revision.php:1142
static getRevisionFactory()
Definition: Revision.php:84
static loadFromId( $db, $id)
Load a page revision from a given revision ID number.
Definition: Revision.php:244
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
Definition: hooks.txt:1995
static selectFields()
Return the list of revision fields that should be selected to create a new revision.
Definition: Revision.php:358
getComment( $audience=self::FOR_PUBLIC, User $user=null)
Fetch revision comment if it&#39;s available to the specified audience.
Definition: Revision.php:863
static selectTextFields()
Return the list of text fields that should be selected to read the revision text. ...
Definition: Revision.php:478
static loadFromTitle( $db, $title, $id=0)
Load either the current, or a specified, revision that&#39;s attached to a given page.
Definition: Revision.php:279
const DELETED_RESTRICTED
Definition: Revision.php:51
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition: hooks.txt:780
static getArchiveQueryInfo()
Return the tables, fields, and join conditions to be selected to create a new archived revision objec...
Definition: Revision.php:541
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:935
static getQueryInfo( $options=[])
Return the tables, fields, and join conditions to be selected to create a new revision object...
Definition: Revision.php:527
presenting them properly to the user as errors is done by the caller return true use this to change the list i e etc $rev
Definition: hooks.txt:1779
getPrevious()
Get previous revision for this title.
Definition: Revision.php:1028
const RAW
Definition: Revision.php:58
getContentModel()
Returns the content model for the main slot of this revision.
Definition: Revision.php:973
insertOn( $dbw)
Insert a new revision into the database, returning the new revision ID number on success and dies hor...
Definition: Revision.php:1170
const DELETED_TEXT
Definition: Revision.php:48
static countByTitle( $db, $title)
Get count of revisions per page...not very efficient.
Definition: Revision.php:1304
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:573
const SUPPRESSED_USER
Definition: Revision.php:52
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:545
static pageJoinCond()
Return the value of a select() page conds array for the page table.
Definition: Revision.php:347
getVisibility()
Get the deletion bitfield of the revision.
Definition: Revision.php:915
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
static base36Sha1( $blob)
Get the base 36 SHA-1 value for a string of text.
Definition: SlotRecord.php:607
static newFromAnyId( $userId, $userName, $actorId)
Static factory method for creation from an ID, name, and/or actor ID.
Definition: User.php:675
const DELETED_USER
Definition: Revision.php:50
static getStore()
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
static getBlobStore( $wiki=false)
Definition: Revision.php:93
getTextId()
Get the ID of the row of the text table that contains the content of the revision&#39;s main slot...
Definition: Revision.php:720
static newFromRow( $row)
Definition: Revision.php:224
Overloads the relevant methods of the real ResultsWrapper so it doesn&#39;t go anywhere near an actual da...
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
static base36Sha1( $text)
Get the base 36 SHA-1 value for a string of text.
Definition: Revision.php:1197
Exception representing a failure to look up a revision.
getNext()
Get next revision for this title.
Definition: Revision.php:1039
setId( $id)
Set the revision ID.
Definition: Revision.php:670
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:271
Page revision base class.
static selectPageFields()
Return the list of page fields that should be selected from page table.
Definition: Revision.php:491
const DELETED_COMMENT
Definition: Revision.php:49
ensureTitle( $row, $queryFlags, $title=null)
Make sure we have some Title object for use by the constructor.
Definition: Revision.php:607
static userJoinCond()
Return the value of a select() JOIN conds array for the user table.
Definition: Revision.php:323
static newFromId( $id, $flags=0)
Load a page revision from a given revision ID number.
Definition: Revision.php:120
getContentFormat()
Returns the content format for the main slot of this revision.
Definition: Revision.php:988
$content
Definition: pageupdater.txt:72
getSize()
Returns the length of the text in this revision, or null if unknown.
Definition: Revision.php:742
static selectUserFields()
Return the list of user fields that should be selected from user table.
Definition: Revision.php:508
static newNullRevision( $dbw, $pageId, $summary, $minor, $user=null)
Create a new null-revision for insertion into a page&#39;s history.
Definition: Revision.php:1216
getSha1()
Returns the base36 sha1 of the content in this revision, or null if unknown.
Definition: Revision.php:755
return true to allow those checks to and false if checking is done & $user
Definition: hooks.txt:1486
const SUPPRESSED_ALL
Definition: Revision.php:53