MediaWiki  master
Revision.php
Go to the documentation of this file.
1 <?php
37 
41 class Revision implements IDBAccessObject {
42 
44  protected $mRecord;
45 
46  // Revision deletion constants
53 
54  // Audience options for accessors
58 
59  const TEXT_CACHE_GROUP = SqlBlobStore::TEXT_CACHE_GROUP;
60 
64  protected static function getRevisionStore( $wiki = false ) {
65  if ( $wiki ) {
66  return MediaWikiServices::getInstance()->getRevisionStoreFactory()
67  ->getRevisionStore( $wiki );
68  } else {
69  return MediaWikiServices::getInstance()->getRevisionStore();
70  }
71  }
72 
76  protected static function getRevisionLookup() {
77  return MediaWikiServices::getInstance()->getRevisionLookup();
78  }
79 
83  protected static function getRevisionFactory() {
84  return MediaWikiServices::getInstance()->getRevisionFactory();
85  }
86 
92  protected static function getBlobStore( $wiki = false ) {
93  $store = MediaWikiServices::getInstance()
94  ->getBlobStoreFactory()
95  ->newSqlBlobStore( $wiki );
96 
97  if ( !$store instanceof SqlBlobStore ) {
98  throw new RuntimeException(
99  'The backwards compatibility code in Revision currently requires the BlobStore '
100  . 'service to be an SqlBlobStore instance, but it is a ' . get_class( $store )
101  );
102  }
103 
104  return $store;
105  }
106 
119  public static function newFromId( $id, $flags = 0 ) {
120  $rec = self::getRevisionLookup()->getRevisionById( $id, $flags );
121  return $rec === null ? null : new Revision( $rec, $flags );
122  }
123 
138  public static function newFromTitle( LinkTarget $linkTarget, $id = 0, $flags = 0 ) {
139  $rec = self::getRevisionLookup()->getRevisionByTitle( $linkTarget, $id, $flags );
140  return $rec === null ? null : new Revision( $rec, $flags );
141  }
142 
157  public static function newFromPageId( $pageId, $revId = 0, $flags = 0 ) {
158  $rec = self::getRevisionLookup()->getRevisionByPageId( $pageId, $revId, $flags );
159  return $rec === null ? null : new Revision( $rec, $flags );
160  }
161 
172  public static function newFromArchiveRow( $row, $overrides = [] ) {
179  if ( array_key_exists( 'page', $overrides ) ) {
180  $overrides['page_id'] = $overrides['page'];
181  unset( $overrides['page'] );
182  }
183 
189  $title = null;
190  if ( isset( $overrides['title'] ) ) {
191  if ( !( $overrides['title'] instanceof Title ) ) {
192  throw new MWException( 'title field override must contain a Title object.' );
193  }
194 
195  $title = $overrides['title'];
196  }
197  if ( $title !== null ) {
198  if ( isset( $row->ar_namespace ) && isset( $row->ar_title ) ) {
199  $title = Title::makeTitle( $row->ar_namespace, $row->ar_title );
200  } else {
201  throw new InvalidArgumentException(
202  'A Title or ar_namespace and ar_title must be given'
203  );
204  }
205  }
206 
207  $rec = self::getRevisionFactory()->newRevisionFromArchiveRow( $row, 0, $title, $overrides );
208  return new Revision( $rec, self::READ_NORMAL, $title );
209  }
210 
223  public static function newFromRow( $row ) {
224  if ( is_array( $row ) ) {
225  $rec = self::getRevisionFactory()->newMutableRevisionFromArray( $row );
226  } else {
227  $rec = self::getRevisionFactory()->newRevisionFromRow( $row );
228  }
229 
230  return new Revision( $rec );
231  }
232 
243  public static function loadFromId( $db, $id ) {
244  wfDeprecated( __METHOD__, '1.31' ); // no known callers
245  $rec = self::getRevisionStore()->loadRevisionFromId( $db, $id );
246  return $rec === null ? null : new Revision( $rec );
247  }
248 
261  public static function loadFromPageId( $db, $pageid, $id = 0 ) {
262  $rec = self::getRevisionStore()->loadRevisionFromPageId( $db, $pageid, $id );
263  return $rec === null ? null : new Revision( $rec );
264  }
265 
278  public static function loadFromTitle( $db, $title, $id = 0 ) {
279  $rec = self::getRevisionStore()->loadRevisionFromTitle( $db, $title, $id );
280  return $rec === null ? null : new Revision( $rec );
281  }
282 
296  public static function loadFromTimestamp( $db, $title, $timestamp ) {
297  $rec = self::getRevisionStore()->loadRevisionFromTimestamp( $db, $title, $timestamp );
298  return $rec === null ? null : new Revision( $rec );
299  }
300 
310  public static function fetchRevision( LinkTarget $title ) {
311  wfDeprecated( __METHOD__, '1.31' );
312  return new FakeResultWrapper( [] );
313  }
314 
322  public static function userJoinCond() {
324 
325  wfDeprecated( __METHOD__, '1.31' );
326  if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
327  // If code is using this instead of self::getQueryInfo(), there's
328  // no way the join it's trying to do can work once the old fields
329  // aren't being used anymore.
330  throw new BadMethodCallException(
331  'Cannot use ' . __METHOD__
332  . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
333  );
334  }
335 
336  return [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ];
337  }
338 
346  public static function pageJoinCond() {
347  wfDeprecated( __METHOD__, '1.31' );
348  return [ 'INNER JOIN', [ 'page_id = rev_page' ] ];
349  }
350 
357  public static function selectFields() {
360 
361  if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
362  // If code is using this instead of self::getQueryInfo(), there's a
363  // decent chance it's going to try to directly access
364  // $row->rev_user or $row->rev_user_text and we can't give it
365  // useful values here once those aren't being used anymore.
366  throw new BadMethodCallException(
367  'Cannot use ' . __METHOD__
368  . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
369  );
370  }
371 
372  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
373  // If code is using this instead of self::getQueryInfo(), there's a
374  // decent chance it's going to try to directly access
375  // $row->rev_text_id or $row->rev_content_model and we can't give it
376  // useful values here once those aren't being written anymore,
377  // and may not exist at all.
378  throw new BadMethodCallException(
379  'Cannot use ' . __METHOD__ . ' when $wgMultiContentRevisionSchemaMigrationStage '
380  . 'does not have SCHEMA_COMPAT_WRITE_OLD set.'
381  );
382  }
383 
384  wfDeprecated( __METHOD__, '1.31' );
385 
386  $fields = [
387  'rev_id',
388  'rev_page',
389  'rev_text_id',
390  'rev_timestamp',
391  'rev_user_text',
392  'rev_user',
393  'rev_actor' => 'NULL',
394  'rev_minor_edit',
395  'rev_deleted',
396  'rev_len',
397  'rev_parent_id',
398  'rev_sha1',
399  ];
400 
401  $fields += CommentStore::getStore()->getFields( 'rev_comment' );
402 
403  if ( $wgContentHandlerUseDB ) {
404  $fields[] = 'rev_content_format';
405  $fields[] = 'rev_content_model';
406  }
407 
408  return $fields;
409  }
410 
417  public static function selectArchiveFields() {
420 
421  if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
422  // If code is using this instead of self::getQueryInfo(), there's a
423  // decent chance it's going to try to directly access
424  // $row->ar_user or $row->ar_user_text and we can't give it
425  // useful values here once those aren't being used anymore.
426  throw new BadMethodCallException(
427  'Cannot use ' . __METHOD__
428  . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
429  );
430  }
431 
432  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
433  // If code is using this instead of self::getQueryInfo(), there's a
434  // decent chance it's going to try to directly access
435  // $row->ar_text_id or $row->ar_content_model and we can't give it
436  // useful values here once those aren't being written anymore,
437  // and may not exist at all.
438  throw new BadMethodCallException(
439  'Cannot use ' . __METHOD__ . ' when $wgMultiContentRevisionSchemaMigrationStage '
440  . 'does not have SCHEMA_COMPAT_WRITE_OLD set.'
441  );
442  }
443 
444  wfDeprecated( __METHOD__, '1.31' );
445 
446  $fields = [
447  'ar_id',
448  'ar_page_id',
449  'ar_rev_id',
450  'ar_text_id',
451  'ar_timestamp',
452  'ar_user_text',
453  'ar_user',
454  'ar_actor' => 'NULL',
455  'ar_minor_edit',
456  'ar_deleted',
457  'ar_len',
458  'ar_parent_id',
459  'ar_sha1',
460  ];
461 
462  $fields += CommentStore::getStore()->getFields( 'ar_comment' );
463 
464  if ( $wgContentHandlerUseDB ) {
465  $fields[] = 'ar_content_format';
466  $fields[] = 'ar_content_model';
467  }
468  return $fields;
469  }
470 
477  public static function selectTextFields() {
478  wfDeprecated( __METHOD__, '1.31' );
479  return [
480  'old_text',
481  'old_flags'
482  ];
483  }
484 
490  public static function selectPageFields() {
491  wfDeprecated( __METHOD__, '1.31' );
492  return [
493  'page_namespace',
494  'page_title',
495  'page_id',
496  'page_latest',
497  'page_is_redirect',
498  'page_len',
499  ];
500  }
501 
507  public static function selectUserFields() {
508  wfDeprecated( __METHOD__, '1.31' );
509  return [ 'user_name' ];
510  }
511 
526  public static function getQueryInfo( $options = [] ) {
527  return self::getRevisionStore()->getQueryInfo( $options );
528  }
529 
540  public static function getArchiveQueryInfo() {
541  return self::getRevisionStore()->getArchiveQueryInfo();
542  }
543 
553  public static function getParentLengths( $db, array $revIds ) {
554  return self::getRevisionStore()->listRevisionSizes( $db, $revIds );
555  }
556 
564  function __construct( $row, $queryFlags = 0, Title $title = null ) {
565  global $wgUser;
566 
567  if ( $row instanceof RevisionRecord ) {
568  $this->mRecord = $row;
569  } elseif ( is_array( $row ) ) {
570  // If no user is specified, fall back to using the global user object, to stay
571  // compatible with pre-1.31 behavior.
572  if ( !isset( $row['user'] ) && !isset( $row['user_text'] ) ) {
573  $row['user'] = $wgUser;
574  }
575 
576  $this->mRecord = self::getRevisionFactory()->newMutableRevisionFromArray(
577  $row,
578  $queryFlags,
579  $this->ensureTitle( $row, $queryFlags, $title )
580  );
581  } elseif ( is_object( $row ) ) {
582  $this->mRecord = self::getRevisionFactory()->newRevisionFromRow(
583  $row,
584  $queryFlags,
585  $this->ensureTitle( $row, $queryFlags, $title )
586  );
587  } else {
588  throw new InvalidArgumentException(
589  '$row must be a row object, an associative array, or a RevisionRecord'
590  );
591  }
592  }
593 
604  private function ensureTitle( $row, $queryFlags, $title = null ) {
605  if ( $title ) {
606  return $title;
607  }
608 
609  if ( is_array( $row ) ) {
610  if ( isset( $row['title'] ) ) {
611  if ( !( $row['title'] instanceof Title ) ) {
612  throw new MWException( 'title field must contain a Title object.' );
613  }
614 
615  return $row['title'];
616  }
617 
618  $pageId = $row['page'] ?? 0;
619  $revId = $row['id'] ?? 0;
620  } else {
621  $pageId = $row->rev_page ?? 0;
622  $revId = $row->rev_id ?? 0;
623  }
624 
625  try {
626  $title = self::getRevisionStore()->getTitle( $pageId, $revId, $queryFlags );
627  } catch ( RevisionAccessException $ex ) {
628  // construct a dummy title!
629  wfLogWarning( __METHOD__ . ': ' . $ex->getMessage() );
630 
631  // NOTE: this Title will only be used inside RevisionRecord
632  $title = Title::makeTitleSafe( NS_SPECIAL, "Badtitle/ID=$pageId" );
633  $title->resetArticleID( $pageId );
634  }
635 
636  return $title;
637  }
638 
642  public function getRevisionRecord() {
643  return $this->mRecord;
644  }
645 
651  public function getId() {
652  return $this->mRecord->getId();
653  }
654 
667  public function setId( $id ) {
668  if ( $this->mRecord instanceof MutableRevisionRecord ) {
669  $this->mRecord->setId( intval( $id ) );
670  } else {
671  throw new MWException( __METHOD__ . ' is not supported on this instance' );
672  }
673  }
674 
689  public function setUserIdAndName( $id, $name ) {
690  if ( $this->mRecord instanceof MutableRevisionRecord ) {
691  $user = User::newFromAnyId( intval( $id ), $name, null );
692  $this->mRecord->setUser( $user );
693  } else {
694  throw new MWException( __METHOD__ . ' is not supported on this instance' );
695  }
696  }
697 
701  private function getMainSlotRaw() {
702  return $this->mRecord->getSlot( SlotRecord::MAIN, RevisionRecord::RAW );
703  }
704 
717  public function getTextId() {
718  $slot = $this->getMainSlotRaw();
719  return $slot->hasAddress()
720  ? self::getBlobStore()->getTextIdFromAddress( $slot->getAddress() )
721  : null;
722  }
723 
730  public function getParentId() {
731  return $this->mRecord->getParentId();
732  }
733 
739  public function getSize() {
740  try {
741  return $this->mRecord->getSize();
742  } catch ( RevisionAccessException $ex ) {
743  return null;
744  }
745  }
746 
752  public function getSha1() {
753  try {
754  return $this->mRecord->getSha1();
755  } catch ( RevisionAccessException $ex ) {
756  return null;
757  }
758  }
759 
768  public function getTitle() {
769  $linkTarget = $this->mRecord->getPageAsLinkTarget();
770  return Title::newFromLinkTarget( $linkTarget );
771  }
772 
780  public function setTitle( $title ) {
781  if ( !$title->equals( $this->getTitle() ) ) {
782  throw new InvalidArgumentException(
783  $title->getPrefixedText()
784  . ' is not the same as '
785  . $this->mRecord->getPageAsLinkTarget()->__toString()
786  );
787  }
788  }
789 
795  public function getPage() {
796  return $this->mRecord->getPageId();
797  }
798 
812  public function getUser( $audience = self::FOR_PUBLIC, User $user = null ) {
813  global $wgUser;
814 
815  if ( $audience === self::FOR_THIS_USER && !$user ) {
816  $user = $wgUser;
817  }
818 
819  $user = $this->mRecord->getUser( $audience, $user );
820  return $user ? $user->getId() : 0;
821  }
822 
836  public function getUserText( $audience = self::FOR_PUBLIC, User $user = null ) {
837  global $wgUser;
838 
839  if ( $audience === self::FOR_THIS_USER && !$user ) {
840  $user = $wgUser;
841  }
842 
843  $user = $this->mRecord->getUser( $audience, $user );
844  return $user ? $user->getName() : '';
845  }
859  function getComment( $audience = self::FOR_PUBLIC, User $user = null ) {
860  global $wgUser;
861 
862  if ( $audience === self::FOR_THIS_USER && !$user ) {
863  $user = $wgUser;
864  }
865 
866  $comment = $this->mRecord->getComment( $audience, $user );
867  return $comment === null ? null : $comment->text;
868  }
869 
873  public function isMinor() {
874  return $this->mRecord->isMinor();
875  }
876 
880  public function isUnpatrolled() {
881  return self::getRevisionStore()->getRcIdIfUnpatrolled( $this->mRecord );
882  }
883 
893  public function getRecentChange( $flags = 0 ) {
894  return self::getRevisionStore()->getRecentChange( $this->mRecord, $flags );
895  }
896 
902  public function isDeleted( $field ) {
903  return $this->mRecord->isDeleted( $field );
904  }
905 
911  public function getVisibility() {
912  return $this->mRecord->getVisibility();
913  }
914 
929  public function getContent( $audience = self::FOR_PUBLIC, User $user = null ) {
930  global $wgUser;
931 
932  if ( $audience === self::FOR_THIS_USER && !$user ) {
933  $user = $wgUser;
934  }
935 
936  try {
937  return $this->mRecord->getContent( SlotRecord::MAIN, $audience, $user );
938  }
939  catch ( RevisionAccessException $e ) {
940  return null;
941  }
942  }
943 
952  public function getSerializedData() {
953  $slot = $this->getMainSlotRaw();
954  return $slot->getContent()->serialize();
955  }
956 
969  public function getContentModel() {
970  return $this->getMainSlotRaw()->getModel();
971  }
972 
984  public function getContentFormat() {
985  $format = $this->getMainSlotRaw()->getFormat();
986 
987  if ( $format === null ) {
988  // if no format was stored along with the blob, fall back to default format
989  $format = $this->getContentHandler()->getDefaultFormat();
990  }
991 
992  return $format;
993  }
994 
1001  public function getContentHandler() {
1003  }
1004 
1008  public function getTimestamp() {
1009  return $this->mRecord->getTimestamp();
1010  }
1011 
1015  public function isCurrent() {
1016  return ( $this->mRecord instanceof RevisionStoreRecord ) && $this->mRecord->isCurrent();
1017  }
1018 
1024  public function getPrevious() {
1025  $title = $this->getTitle();
1026  $rec = self::getRevisionLookup()->getPreviousRevision( $this->mRecord, $title );
1027  return $rec === null ? null : new Revision( $rec, self::READ_NORMAL, $title );
1028  }
1029 
1035  public function getNext() {
1036  $title = $this->getTitle();
1037  $rec = self::getRevisionLookup()->getNextRevision( $this->mRecord, $title );
1038  return $rec === null ? null : new Revision( $rec, self::READ_NORMAL, $title );
1039  }
1040 
1062  public static function getRevisionText( $row, $prefix = 'old_', $wiki = false ) {
1064 
1065  if ( !$row ) {
1066  return false;
1067  }
1068 
1069  $textField = $prefix . 'text';
1070  $flagsField = $prefix . 'flags';
1071 
1072  if ( isset( $row->$textField ) ) {
1073  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
1074  // The text field was read, but it's no longer being populated!
1075  // We could gloss over this by using the text when it's there and loading
1076  // if when it's not, but it seems preferable to complain loudly about a
1077  // query that is no longer guaranteed to work reliably.
1078  throw new LogicException(
1079  'Cannot use ' . __METHOD__ . ' with the ' . $textField . ' field when'
1080  . ' $wgMultiContentRevisionSchemaMigrationStage does not include'
1081  . ' SCHEMA_COMPAT_WRITE_OLD. The field may not be populated for all revisions!'
1082  );
1083  }
1084 
1085  $text = $row->$textField;
1086  } else {
1087  // Missing text field, we are probably looking at the MCR-enabled DB schema.
1088 
1089  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
1090  // This method should no longer be used with the new schema. Ideally, we
1091  // would already trigger a deprecation warning when SCHEMA_COMPAT_READ_NEW is set.
1092  wfDeprecated( __METHOD__ . ' (MCR without SCHEMA_COMPAT_WRITE_OLD)', '1.32' );
1093  }
1094 
1095  $store = self::getRevisionStore( $wiki );
1096  $rev = $prefix === 'ar_'
1097  ? $store->newRevisionFromArchiveRow( $row )
1098  : $store->newRevisionFromRow( $row );
1099 
1100  $content = $rev->getContent( SlotRecord::MAIN );
1101  return $content ? $content->serialize() : false;
1102  }
1103 
1104  if ( isset( $row->$flagsField ) ) {
1105  $flags = explode( ',', $row->$flagsField );
1106  } else {
1107  $flags = [];
1108  }
1109 
1110  $cacheKey = isset( $row->old_id )
1111  ? SqlBlobStore::makeAddressFromTextId( $row->old_id )
1112  : null;
1113 
1114  $revisionText = self::getBlobStore( $wiki )->expandBlob( $text, $flags, $cacheKey );
1115 
1116  if ( $revisionText === false ) {
1117  if ( isset( $row->old_id ) ) {
1118  wfLogWarning( __METHOD__ . ": Bad data in text row {$row->old_id}! " );
1119  } else {
1120  wfLogWarning( __METHOD__ . ": Bad data in text row! " );
1121  }
1122  return false;
1123  }
1124 
1125  return $revisionText;
1126  }
1127 
1138  public static function compressRevisionText( &$text ) {
1139  return self::getBlobStore()->compressData( $text );
1140  }
1141 
1149  public static function decompressRevisionText( $text, $flags ) {
1150  if ( $text === false ) {
1151  // Text failed to be fetched; nothing to do
1152  return false;
1153  }
1154 
1155  return self::getBlobStore()->decompressData( $text, $flags );
1156  }
1157 
1166  public function insertOn( $dbw ) {
1167  global $wgUser;
1168 
1169  // Note that $this->mRecord->getId() will typically return null here, but not always,
1170  // e.g. not when restoring a revision.
1171 
1172  if ( $this->mRecord->getUser( RevisionRecord::RAW ) === null ) {
1173  if ( $this->mRecord instanceof MutableRevisionRecord ) {
1174  $this->mRecord->setUser( $wgUser );
1175  } else {
1176  throw new MWException( 'Cannot insert revision with no associated user.' );
1177  }
1178  }
1179 
1180  $rec = self::getRevisionStore()->insertRevisionOn( $this->mRecord, $dbw );
1181 
1182  $this->mRecord = $rec;
1183 
1184  // Avoid PHP 7.1 warning of passing $this by reference
1185  $revision = $this;
1186 
1187  return $rec->getId();
1188  }
1189 
1195  public static function base36Sha1( $text ) {
1196  return SlotRecord::base36Sha1( $text );
1197  }
1198 
1214  public static function newNullRevision( $dbw, $pageId, $summary, $minor, $user = null ) {
1215  global $wgUser;
1216  if ( !$user ) {
1217  $user = $wgUser;
1218  }
1219 
1220  $comment = CommentStoreComment::newUnsavedComment( $summary, null );
1221 
1223  if ( $title === null ) {
1224  return null;
1225  }
1226 
1227  $rec = self::getRevisionStore()->newNullRevision( $dbw, $title, $comment, $minor, $user );
1228 
1229  return $rec ? new Revision( $rec ) : null;
1230  }
1231 
1242  public function userCan( $field, User $user = null ) {
1243  return self::userCanBitfield( $this->getVisibility(), $field, $user );
1244  }
1245 
1260  public static function userCanBitfield( $bitfield, $field, User $user = null,
1261  Title $title = null
1262  ) {
1263  global $wgUser;
1264 
1265  if ( !$user ) {
1266  $user = $wgUser;
1267  }
1268 
1269  return RevisionRecord::userCanBitfield( $bitfield, $field, $user, $title );
1270  }
1271 
1280  static function getTimestampFromId( $title, $id, $flags = 0 ) {
1281  return self::getRevisionStore()->getTimestampFromId( $title, $id, $flags );
1282  }
1283 
1291  static function countByPageId( $db, $id ) {
1292  return self::getRevisionStore()->countRevisionsByPageId( $db, $id );
1293  }
1294 
1302  static function countByTitle( $db, $title ) {
1303  return self::getRevisionStore()->countRevisionsByTitle( $db, $title );
1304  }
1305 
1322  public static function userWasLastToEdit( $db, $pageId, $userId, $since ) {
1323  if ( is_int( $db ) ) {
1324  $db = wfGetDB( $db );
1325  }
1326 
1327  return self::getRevisionStore()->userWasLastToEdit( $db, $pageId, $userId, $since );
1328  }
1329 
1343  public static function newKnownCurrent( IDatabase $db, $pageIdOrTitle, $revId = 0 ) {
1344  $title = $pageIdOrTitle instanceof Title
1345  ? $pageIdOrTitle
1346  : Title::newFromID( $pageIdOrTitle );
1347 
1348  if ( !$title ) {
1349  return false;
1350  }
1351 
1352  $record = self::getRevisionLookup()->getKnownCurrentRevision( $title, $revId );
1353  return $record ? new Revision( $record ) : false;
1354  }
1355 }
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:1242
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:836
const FOR_THIS_USER
Definition: Revision.php:56
static newFromArchiveRow( $row, $overrides=[])
Make a fake revision object from an archive table row.
Definition: Revision.php:172
const TEXT_CACHE_GROUP
Definition: Revision.php:59
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:1280
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:310
static newFromID( $id, $flags=0)
Create a new Title from an article ID.
Definition: Title.php:427
getRevisionRecord()
Definition: Revision.php:642
getPage()
Get the page ID.
Definition: Revision.php:795
static countByPageId( $db, $id)
Get count of revisions per page...not very efficient.
Definition: Revision.php:1291
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:1008
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2174
setTitle( $title)
Set the title of the revision.
Definition: Revision.php:780
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:296
static getParentLengths( $db, array $revIds)
Do a batched query to get the parent revision lengths.
Definition: Revision.php:553
static getRevisionLookup()
Definition: Revision.php:76
setUserIdAndName( $id, $name)
Set the user ID/name.
Definition: Revision.php:689
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:157
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:893
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:261
isUnpatrolled()
Definition: Revision.php:880
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:929
static selectArchiveFields()
Return the list of revision fields that should be selected to create a new revision from an archive r...
Definition: Revision.php:417
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:1322
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:1149
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:138
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:1062
getSerializedData()
Get original serialized data (without checking view restrictions)
Definition: Revision.php:952
Mutable RevisionRecord implementation, for building new revision entries programmatically.
getMainSlotRaw()
Definition: Revision.php:701
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:64
RevisionRecord $mRecord
Definition: Revision.php:44
getTitle()
Returns the title of the page associated with this entry.
Definition: Revision.php:768
getParentId()
Get parent revision ID (the original previous page revision)
Definition: Revision.php:730
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:812
const FOR_PUBLIC
Definition: Revision.php:55
static getForModelID( $modelId)
Returns the ContentHandler singleton for the given model ID.
__construct( $row, $queryFlags=0, Title $title=null)
Definition: Revision.php:564
isDeleted( $field)
Definition: Revision.php:902
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:1343
getId()
Get revision ID.
Definition: Revision.php:651
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:1260
getContentHandler()
Returns the content handler appropriate for this revision&#39;s content model.
Definition: Revision.php:1001
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:1138
static getRevisionFactory()
Definition: Revision.php:83
static loadFromId( $db, $id)
Load a page revision from a given revision ID number.
Definition: Revision.php:243
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:1997
static selectFields()
Return the list of revision fields that should be selected to create a new revision.
Definition: Revision.php:357
getComment( $audience=self::FOR_PUBLIC, User $user=null)
Fetch revision comment if it&#39;s available to the specified audience.
Definition: Revision.php:859
static selectTextFields()
Return the list of text fields that should be selected to read the revision text. ...
Definition: Revision.php:477
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:278
const DELETED_RESTRICTED
Definition: Revision.php:50
static getArchiveQueryInfo()
Return the tables, fields, and join conditions to be selected to create a new archived revision objec...
Definition: Revision.php:540
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:936
static getQueryInfo( $options=[])
Return the tables, fields, and join conditions to be selected to create a new revision object...
Definition: Revision.php:526
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:1781
getPrevious()
Get previous revision for this title.
Definition: Revision.php:1024
const RAW
Definition: Revision.php:57
getContentModel()
Returns the content model for the main slot of this revision.
Definition: Revision.php:969
insertOn( $dbw)
Insert a new revision into the database, returning the new revision ID number on success and dies hor...
Definition: Revision.php:1166
const DELETED_TEXT
Definition: Revision.php:47
static countByTitle( $db, $title)
Get count of revisions per page...not very efficient.
Definition: Revision.php:1302
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:51
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:346
getVisibility()
Get the deletion bitfield of the revision.
Definition: Revision.php:911
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:609
static newFromAnyId( $userId, $userName, $actorId)
Static factory method for creation from an ID, name, and/or actor ID.
Definition: User.php:682
const DELETED_USER
Definition: Revision.php:49
static getStore()
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
static getBlobStore( $wiki=false)
Definition: Revision.php:92
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:717
static newFromRow( $row)
Definition: Revision.php:223
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:1195
Exception representing a failure to look up a revision.
getNext()
Get next revision for this title.
Definition: Revision.php:1035
setId( $id)
Set the revision ID.
Definition: Revision.php:667
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:276
Page revision base class.
static selectPageFields()
Return the list of page fields that should be selected from page table.
Definition: Revision.php:490
const DELETED_COMMENT
Definition: Revision.php:48
ensureTitle( $row, $queryFlags, $title=null)
Make sure we have some Title object for use by the constructor.
Definition: Revision.php:604
static userJoinCond()
Return the value of a select() JOIN conds array for the user table.
Definition: Revision.php:322
static newFromId( $id, $flags=0)
Load a page revision from a given revision ID number.
Definition: Revision.php:119
getContentFormat()
Returns the content format for the main slot of this revision.
Definition: Revision.php:984
$content
Definition: pageupdater.txt:72
getSize()
Returns the length of the text in this revision, or null if unknown.
Definition: Revision.php:739
static selectUserFields()
Return the list of user fields that should be selected from user table.
Definition: Revision.php:507
static newNullRevision( $dbw, $pageId, $summary, $minor, $user=null)
Create a new null-revision for insertion into a page&#39;s history.
Definition: Revision.php:1214
getSha1()
Returns the base36 sha1 of the content in this revision, or null if unknown.
Definition: Revision.php:752
return true to allow those checks to and false if checking is done & $user
Definition: hooks.txt:1487
const SUPPRESSED_ALL
Definition: Revision.php:52