MediaWiki  master
Revision.php
Go to the documentation of this file.
1 <?php
36 
40 class Revision implements IDBAccessObject {
41 
43  protected $mRecord;
44 
45  // Revision deletion constants
52 
53  // Audience options for accessors
57 
58  const TEXT_CACHE_GROUP = SqlBlobStore::TEXT_CACHE_GROUP;
59 
63  protected static function getRevisionStore( $wiki = false ) {
64  if ( $wiki ) {
65  return MediaWikiServices::getInstance()->getRevisionStoreFactory()
66  ->getRevisionStore( $wiki );
67  } else {
68  return MediaWikiServices::getInstance()->getRevisionStore();
69  }
70  }
71 
75  protected static function getRevisionLookup() {
76  return MediaWikiServices::getInstance()->getRevisionLookup();
77  }
78 
82  protected static function getRevisionFactory() {
83  return MediaWikiServices::getInstance()->getRevisionFactory();
84  }
85 
91  protected static function getBlobStore( $wiki = false ) {
92  $store = MediaWikiServices::getInstance()
93  ->getBlobStoreFactory()
94  ->newSqlBlobStore( $wiki );
95 
96  if ( !$store instanceof SqlBlobStore ) {
97  throw new RuntimeException(
98  'The backwards compatibility code in Revision currently requires the BlobStore '
99  . 'service to be an SqlBlobStore instance, but it is a ' . get_class( $store )
100  );
101  }
102 
103  return $store;
104  }
105 
118  public static function newFromId( $id, $flags = 0 ) {
119  $rec = self::getRevisionLookup()->getRevisionById( $id, $flags );
120  return $rec ? new Revision( $rec, $flags ) : null;
121  }
122 
137  public static function newFromTitle( LinkTarget $linkTarget, $id = 0, $flags = 0 ) {
138  $rec = self::getRevisionLookup()->getRevisionByTitle( $linkTarget, $id, $flags );
139  return $rec ? new Revision( $rec, $flags ) : null;
140  }
141 
156  public static function newFromPageId( $pageId, $revId = 0, $flags = 0 ) {
157  $rec = self::getRevisionLookup()->getRevisionByPageId( $pageId, $revId, $flags );
158  return $rec ? new Revision( $rec, $flags ) : null;
159  }
160 
171  public static function newFromArchiveRow( $row, $overrides = [] ) {
178  if ( array_key_exists( 'page', $overrides ) ) {
179  $overrides['page_id'] = $overrides['page'];
180  unset( $overrides['page'] );
181  }
182 
188  $title = null;
189  if ( isset( $overrides['title'] ) ) {
190  if ( !( $overrides['title'] instanceof Title ) ) {
191  throw new MWException( 'title field override must contain a Title object.' );
192  }
193 
194  $title = $overrides['title'];
195  }
196  if ( $title !== null ) {
197  if ( isset( $row->ar_namespace ) && isset( $row->ar_title ) ) {
198  $title = Title::makeTitle( $row->ar_namespace, $row->ar_title );
199  } else {
200  throw new InvalidArgumentException(
201  'A Title or ar_namespace and ar_title must be given'
202  );
203  }
204  }
205 
206  $rec = self::getRevisionFactory()->newRevisionFromArchiveRow( $row, 0, $title, $overrides );
207  return new Revision( $rec, self::READ_NORMAL, $title );
208  }
209 
222  public static function newFromRow( $row ) {
223  if ( is_array( $row ) ) {
224  $rec = self::getRevisionFactory()->newMutableRevisionFromArray( $row );
225  } else {
226  $rec = self::getRevisionFactory()->newRevisionFromRow( $row );
227  }
228 
229  return new Revision( $rec );
230  }
231 
242  public static function loadFromId( $db, $id ) {
243  wfDeprecated( __METHOD__, '1.31' ); // no known callers
244  $rec = self::getRevisionStore()->loadRevisionFromId( $db, $id );
245  return $rec ? new Revision( $rec ) : null;
246  }
247 
260  public static function loadFromPageId( $db, $pageid, $id = 0 ) {
261  $rec = self::getRevisionStore()->loadRevisionFromPageId( $db, $pageid, $id );
262  return $rec ? new Revision( $rec ) : null;
263  }
264 
277  public static function loadFromTitle( $db, $title, $id = 0 ) {
278  $rec = self::getRevisionStore()->loadRevisionFromTitle( $db, $title, $id );
279  return $rec ? new Revision( $rec ) : null;
280  }
281 
295  public static function loadFromTimestamp( $db, $title, $timestamp ) {
296  $rec = self::getRevisionStore()->loadRevisionFromTimestamp( $db, $title, $timestamp );
297  return $rec ? new Revision( $rec ) : null;
298  }
299 
307  public static function userJoinCond() {
309 
310  wfDeprecated( __METHOD__, '1.31' );
311  if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
312  // If code is using this instead of self::getQueryInfo(), there's
313  // no way the join it's trying to do can work once the old fields
314  // aren't being used anymore.
315  throw new BadMethodCallException(
316  'Cannot use ' . __METHOD__
317  . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
318  );
319  }
320 
321  return [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ];
322  }
323 
331  public static function pageJoinCond() {
332  wfDeprecated( __METHOD__, '1.31' );
333  return [ 'JOIN', [ 'page_id = rev_page' ] ];
334  }
335 
342  public static function selectFields() {
345 
346  if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
347  // If code is using this instead of self::getQueryInfo(), there's a
348  // decent chance it's going to try to directly access
349  // $row->rev_user or $row->rev_user_text and we can't give it
350  // useful values here once those aren't being used anymore.
351  throw new BadMethodCallException(
352  'Cannot use ' . __METHOD__
353  . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
354  );
355  }
356 
357  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
358  // If code is using this instead of self::getQueryInfo(), there's a
359  // decent chance it's going to try to directly access
360  // $row->rev_text_id or $row->rev_content_model and we can't give it
361  // useful values here once those aren't being written anymore,
362  // and may not exist at all.
363  throw new BadMethodCallException(
364  'Cannot use ' . __METHOD__ . ' when $wgMultiContentRevisionSchemaMigrationStage '
365  . 'does not have SCHEMA_COMPAT_WRITE_OLD set.'
366  );
367  }
368 
369  wfDeprecated( __METHOD__, '1.31' );
370 
371  $fields = [
372  'rev_id',
373  'rev_page',
374  'rev_text_id',
375  'rev_timestamp',
376  'rev_user_text',
377  'rev_user',
378  'rev_actor' => 'NULL',
379  'rev_minor_edit',
380  'rev_deleted',
381  'rev_len',
382  'rev_parent_id',
383  'rev_sha1',
384  ];
385 
386  $fields += CommentStore::getStore()->getFields( 'rev_comment' );
387 
388  if ( $wgContentHandlerUseDB ) {
389  $fields[] = 'rev_content_format';
390  $fields[] = 'rev_content_model';
391  }
392 
393  return $fields;
394  }
395 
402  public static function selectArchiveFields() {
405 
406  if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
407  // If code is using this instead of self::getQueryInfo(), there's a
408  // decent chance it's going to try to directly access
409  // $row->ar_user or $row->ar_user_text and we can't give it
410  // useful values here once those aren't being used anymore.
411  throw new BadMethodCallException(
412  'Cannot use ' . __METHOD__
413  . ' when $wgActorTableSchemaMigrationStage has SCHEMA_COMPAT_READ_NEW'
414  );
415  }
416 
417  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
418  // If code is using this instead of self::getQueryInfo(), there's a
419  // decent chance it's going to try to directly access
420  // $row->ar_text_id or $row->ar_content_model and we can't give it
421  // useful values here once those aren't being written anymore,
422  // and may not exist at all.
423  throw new BadMethodCallException(
424  'Cannot use ' . __METHOD__ . ' when $wgMultiContentRevisionSchemaMigrationStage '
425  . 'does not have SCHEMA_COMPAT_WRITE_OLD set.'
426  );
427  }
428 
429  wfDeprecated( __METHOD__, '1.31' );
430 
431  $fields = [
432  'ar_id',
433  'ar_page_id',
434  'ar_rev_id',
435  'ar_text_id',
436  'ar_timestamp',
437  'ar_user_text',
438  'ar_user',
439  'ar_actor' => 'NULL',
440  'ar_minor_edit',
441  'ar_deleted',
442  'ar_len',
443  'ar_parent_id',
444  'ar_sha1',
445  ];
446 
447  $fields += CommentStore::getStore()->getFields( 'ar_comment' );
448 
449  if ( $wgContentHandlerUseDB ) {
450  $fields[] = 'ar_content_format';
451  $fields[] = 'ar_content_model';
452  }
453  return $fields;
454  }
455 
462  public static function selectTextFields() {
463  wfDeprecated( __METHOD__, '1.31' );
464  return [
465  'old_text',
466  'old_flags'
467  ];
468  }
469 
475  public static function selectPageFields() {
476  wfDeprecated( __METHOD__, '1.31' );
477  return [
478  'page_namespace',
479  'page_title',
480  'page_id',
481  'page_latest',
482  'page_is_redirect',
483  'page_len',
484  ];
485  }
486 
492  public static function selectUserFields() {
493  wfDeprecated( __METHOD__, '1.31' );
494  return [ 'user_name' ];
495  }
496 
511  public static function getQueryInfo( $options = [] ) {
512  return self::getRevisionStore()->getQueryInfo( $options );
513  }
514 
525  public static function getArchiveQueryInfo() {
526  return self::getRevisionStore()->getArchiveQueryInfo();
527  }
528 
538  public static function getParentLengths( $db, array $revIds ) {
539  return self::getRevisionStore()->listRevisionSizes( $db, $revIds );
540  }
541 
549  function __construct( $row, $queryFlags = 0, Title $title = null ) {
550  global $wgUser;
551 
552  if ( $row instanceof RevisionRecord ) {
553  $this->mRecord = $row;
554  } elseif ( is_array( $row ) ) {
555  // If no user is specified, fall back to using the global user object, to stay
556  // compatible with pre-1.31 behavior.
557  if ( !isset( $row['user'] ) && !isset( $row['user_text'] ) ) {
558  $row['user'] = $wgUser;
559  }
560 
561  $this->mRecord = self::getRevisionFactory()->newMutableRevisionFromArray(
562  $row,
563  $queryFlags,
564  $this->ensureTitle( $row, $queryFlags, $title )
565  );
566  } elseif ( is_object( $row ) ) {
567  $this->mRecord = self::getRevisionFactory()->newRevisionFromRow(
568  $row,
569  $queryFlags,
570  $this->ensureTitle( $row, $queryFlags, $title )
571  );
572  } else {
573  throw new InvalidArgumentException(
574  '$row must be a row object, an associative array, or a RevisionRecord'
575  );
576  }
577 
578  Assert::postcondition( $this->mRecord !== null, 'Failed to construct a RevisionRecord' );
579  }
580 
591  private function ensureTitle( $row, $queryFlags, $title = null ) {
592  if ( $title ) {
593  return $title;
594  }
595 
596  if ( is_array( $row ) ) {
597  if ( isset( $row['title'] ) ) {
598  if ( !( $row['title'] instanceof Title ) ) {
599  throw new MWException( 'title field must contain a Title object.' );
600  }
601 
602  return $row['title'];
603  }
604 
605  $pageId = $row['page'] ?? 0;
606  $revId = $row['id'] ?? 0;
607  } else {
608  $pageId = $row->rev_page ?? 0;
609  $revId = $row->rev_id ?? 0;
610  }
611 
612  try {
613  $title = self::getRevisionStore()->getTitle( $pageId, $revId, $queryFlags );
614  } catch ( RevisionAccessException $ex ) {
615  // construct a dummy title!
616  wfLogWarning( __METHOD__ . ': ' . $ex->getMessage() );
617 
618  // NOTE: this Title will only be used inside RevisionRecord
619  $title = Title::makeTitleSafe( NS_SPECIAL, "Badtitle/ID=$pageId" );
620  $title->resetArticleID( $pageId );
621  }
622 
623  return $title;
624  }
625 
629  public function getRevisionRecord() {
630  return $this->mRecord;
631  }
632 
638  public function getId() {
639  return $this->mRecord->getId();
640  }
641 
654  public function setId( $id ) {
655  if ( $this->mRecord instanceof MutableRevisionRecord ) {
656  $this->mRecord->setId( intval( $id ) );
657  } else {
658  throw new MWException( __METHOD__ . ' is not supported on this instance' );
659  }
660  }
661 
676  public function setUserIdAndName( $id, $name ) {
677  if ( $this->mRecord instanceof MutableRevisionRecord ) {
678  $user = User::newFromAnyId( intval( $id ), $name, null );
679  $this->mRecord->setUser( $user );
680  } else {
681  throw new MWException( __METHOD__ . ' is not supported on this instance' );
682  }
683  }
684 
688  private function getMainSlotRaw() {
689  return $this->mRecord->getSlot( SlotRecord::MAIN, RevisionRecord::RAW );
690  }
691 
704  public function getTextId() {
705  $slot = $this->getMainSlotRaw();
706  return $slot->hasAddress()
707  ? self::getBlobStore()->getTextIdFromAddress( $slot->getAddress() )
708  : null;
709  }
710 
717  public function getParentId() {
718  return $this->mRecord->getParentId();
719  }
720 
726  public function getSize() {
727  try {
728  return $this->mRecord->getSize();
729  } catch ( RevisionAccessException $ex ) {
730  return null;
731  }
732  }
733 
739  public function getSha1() {
740  try {
741  return $this->mRecord->getSha1();
742  } catch ( RevisionAccessException $ex ) {
743  return null;
744  }
745  }
746 
755  public function getTitle() {
756  $linkTarget = $this->mRecord->getPageAsLinkTarget();
757  return Title::newFromLinkTarget( $linkTarget );
758  }
759 
767  public function setTitle( $title ) {
768  if ( !$title->equals( $this->getTitle() ) ) {
769  throw new InvalidArgumentException(
770  $title->getPrefixedText()
771  . ' is not the same as '
772  . $this->mRecord->getPageAsLinkTarget()->__toString()
773  );
774  }
775  }
776 
782  public function getPage() {
783  return $this->mRecord->getPageId();
784  }
785 
799  public function getUser( $audience = self::FOR_PUBLIC, User $user = null ) {
800  global $wgUser;
801 
802  if ( $audience === self::FOR_THIS_USER && !$user ) {
803  $user = $wgUser;
804  }
805 
806  $user = $this->mRecord->getUser( $audience, $user );
807  return $user ? $user->getId() : 0;
808  }
809 
823  public function getUserText( $audience = self::FOR_PUBLIC, User $user = null ) {
824  global $wgUser;
825 
826  if ( $audience === self::FOR_THIS_USER && !$user ) {
827  $user = $wgUser;
828  }
829 
830  $user = $this->mRecord->getUser( $audience, $user );
831  return $user ? $user->getName() : '';
832  }
833 
845  function getComment( $audience = self::FOR_PUBLIC, User $user = null ) {
846  global $wgUser;
847 
848  if ( $audience === self::FOR_THIS_USER && !$user ) {
849  $user = $wgUser;
850  }
851 
852  $comment = $this->mRecord->getComment( $audience, $user );
853  return $comment === null ? null : $comment->text;
854  }
855 
859  public function isMinor() {
860  return $this->mRecord->isMinor();
861  }
862 
866  public function isUnpatrolled() {
867  return self::getRevisionStore()->getRcIdIfUnpatrolled( $this->mRecord );
868  }
869 
879  public function getRecentChange( $flags = 0 ) {
880  return self::getRevisionStore()->getRecentChange( $this->mRecord, $flags );
881  }
882 
888  public function isDeleted( $field ) {
889  return $this->mRecord->isDeleted( $field );
890  }
891 
897  public function getVisibility() {
898  return $this->mRecord->getVisibility();
899  }
900 
915  public function getContent( $audience = self::FOR_PUBLIC, User $user = null ) {
916  global $wgUser;
917 
918  if ( $audience === self::FOR_THIS_USER && !$user ) {
919  $user = $wgUser;
920  }
921 
922  try {
923  return $this->mRecord->getContent( SlotRecord::MAIN, $audience, $user );
924  }
925  catch ( RevisionAccessException $e ) {
926  return null;
927  }
928  }
929 
938  public function getSerializedData() {
939  $slot = $this->getMainSlotRaw();
940  return $slot->getContent()->serialize();
941  }
942 
955  public function getContentModel() {
956  return $this->getMainSlotRaw()->getModel();
957  }
958 
970  public function getContentFormat() {
971  $format = $this->getMainSlotRaw()->getFormat();
972 
973  if ( $format === null ) {
974  // if no format was stored along with the blob, fall back to default format
975  $format = $this->getContentHandler()->getDefaultFormat();
976  }
977 
978  return $format;
979  }
980 
987  public function getContentHandler() {
989  }
990 
994  public function getTimestamp() {
995  return $this->mRecord->getTimestamp();
996  }
997 
1001  public function isCurrent() {
1002  return ( $this->mRecord instanceof RevisionStoreRecord ) && $this->mRecord->isCurrent();
1003  }
1004 
1010  public function getPrevious() {
1011  $title = $this->getTitle();
1012  $rec = self::getRevisionLookup()->getPreviousRevision( $this->mRecord, $title );
1013  return $rec ? new Revision( $rec, self::READ_NORMAL, $title ) : null;
1014  }
1015 
1021  public function getNext() {
1022  $title = $this->getTitle();
1023  $rec = self::getRevisionLookup()->getNextRevision( $this->mRecord, $title );
1024  return $rec ? new Revision( $rec, self::READ_NORMAL, $title ) : null;
1025  }
1026 
1048  public static function getRevisionText( $row, $prefix = 'old_', $wiki = false ) {
1050 
1051  if ( !$row ) {
1052  return false;
1053  }
1054 
1055  $textField = $prefix . 'text';
1056  $flagsField = $prefix . 'flags';
1057 
1058  if ( isset( $row->$textField ) ) {
1059  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
1060  // The text field was read, but it's no longer being populated!
1061  // We could gloss over this by using the text when it's there and loading
1062  // if when it's not, but it seems preferable to complain loudly about a
1063  // query that is no longer guaranteed to work reliably.
1064  throw new LogicException(
1065  'Cannot use ' . __METHOD__ . ' with the ' . $textField . ' field when'
1066  . ' $wgMultiContentRevisionSchemaMigrationStage does not include'
1067  . ' SCHEMA_COMPAT_WRITE_OLD. The field may not be populated for all revisions!'
1068  );
1069  }
1070 
1071  $text = $row->$textField;
1072  } else {
1073  // Missing text field, we are probably looking at the MCR-enabled DB schema.
1074 
1075  if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
1076  // This method should no longer be used with the new schema. Ideally, we
1077  // would already trigger a deprecation warning when SCHEMA_COMPAT_READ_NEW is set.
1078  wfDeprecated( __METHOD__ . ' (MCR without SCHEMA_COMPAT_WRITE_OLD)', '1.32' );
1079  }
1080 
1081  $store = self::getRevisionStore( $wiki );
1082  $rev = $prefix === 'ar_'
1083  ? $store->newRevisionFromArchiveRow( $row )
1084  : $store->newRevisionFromRow( $row );
1085 
1086  $content = $rev->getContent( SlotRecord::MAIN );
1087  return $content ? $content->serialize() : false;
1088  }
1089 
1090  if ( isset( $row->$flagsField ) ) {
1091  $flags = explode( ',', $row->$flagsField );
1092  } else {
1093  $flags = [];
1094  }
1095 
1096  $cacheKey = isset( $row->old_id )
1097  ? SqlBlobStore::makeAddressFromTextId( $row->old_id )
1098  : null;
1099 
1100  $revisionText = self::getBlobStore( $wiki )->expandBlob( $text, $flags, $cacheKey );
1101 
1102  if ( $revisionText === false ) {
1103  if ( isset( $row->old_id ) ) {
1104  wfLogWarning( __METHOD__ . ": Bad data in text row {$row->old_id}! " );
1105  } else {
1106  wfLogWarning( __METHOD__ . ": Bad data in text row! " );
1107  }
1108  return false;
1109  }
1110 
1111  return $revisionText;
1112  }
1113 
1124  public static function compressRevisionText( &$text ) {
1125  return self::getBlobStore()->compressData( $text );
1126  }
1127 
1135  public static function decompressRevisionText( $text, $flags ) {
1136  if ( $text === false ) {
1137  // Text failed to be fetched; nothing to do
1138  return false;
1139  }
1140 
1141  return self::getBlobStore()->decompressData( $text, $flags );
1142  }
1143 
1152  public function insertOn( $dbw ) {
1153  global $wgUser;
1154 
1155  // Note that $this->mRecord->getId() will typically return null here, but not always,
1156  // e.g. not when restoring a revision.
1157 
1158  if ( $this->mRecord->getUser( RevisionRecord::RAW ) === null ) {
1159  if ( $this->mRecord instanceof MutableRevisionRecord ) {
1160  $this->mRecord->setUser( $wgUser );
1161  } else {
1162  throw new MWException( 'Cannot insert revision with no associated user.' );
1163  }
1164  }
1165 
1166  $rec = self::getRevisionStore()->insertRevisionOn( $this->mRecord, $dbw );
1167 
1168  $this->mRecord = $rec;
1169  Assert::postcondition( $this->mRecord !== null, 'Failed to acquire a RevisionRecord' );
1170 
1171  return $rec->getId();
1172  }
1173 
1179  public static function base36Sha1( $text ) {
1180  return SlotRecord::base36Sha1( $text );
1181  }
1182 
1198  public static function newNullRevision( $dbw, $pageId, $summary, $minor, $user = null ) {
1199  global $wgUser;
1200  if ( !$user ) {
1201  $user = $wgUser;
1202  }
1203 
1204  $comment = CommentStoreComment::newUnsavedComment( $summary, null );
1205 
1207  if ( $title === null ) {
1208  return null;
1209  }
1210 
1211  $rec = self::getRevisionStore()->newNullRevision( $dbw, $title, $comment, $minor, $user );
1212 
1213  return $rec ? new Revision( $rec ) : null;
1214  }
1215 
1226  public function userCan( $field, User $user = null ) {
1227  return self::userCanBitfield( $this->getVisibility(), $field, $user );
1228  }
1229 
1244  public static function userCanBitfield( $bitfield, $field, User $user = null,
1245  Title $title = null
1246  ) {
1247  global $wgUser;
1248 
1249  if ( !$user ) {
1250  $user = $wgUser;
1251  }
1252 
1253  return RevisionRecord::userCanBitfield( $bitfield, $field, $user, $title );
1254  }
1255 
1264  static function getTimestampFromId( $title, $id, $flags = 0 ) {
1265  return self::getRevisionStore()->getTimestampFromId( $title, $id, $flags );
1266  }
1267 
1275  static function countByPageId( $db, $id ) {
1276  return self::getRevisionStore()->countRevisionsByPageId( $db, $id );
1277  }
1278 
1286  static function countByTitle( $db, $title ) {
1287  return self::getRevisionStore()->countRevisionsByTitle( $db, $title );
1288  }
1289 
1306  public static function userWasLastToEdit( $db, $pageId, $userId, $since ) {
1307  if ( is_int( $db ) ) {
1308  $db = wfGetDB( $db );
1309  }
1310 
1311  return self::getRevisionStore()->userWasLastToEdit( $db, $pageId, $userId, $since );
1312  }
1313 
1327  public static function newKnownCurrent( IDatabase $db, $pageIdOrTitle, $revId = 0 ) {
1328  $title = $pageIdOrTitle instanceof Title
1329  ? $pageIdOrTitle
1330  : Title::newFromID( $pageIdOrTitle );
1331 
1332  if ( !$title ) {
1333  return false;
1334  }
1335 
1336  $record = self::getRevisionLookup()->getKnownCurrentRevision( $title, $revId );
1337  return $record ? new Revision( $record ) : false;
1338  }
1339 }
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:1226
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:823
const FOR_THIS_USER
Definition: Revision.php:55
static newFromArchiveRow( $row, $overrides=[])
Make a fake revision object from an archive table row.
Definition: Revision.php:171
const TEXT_CACHE_GROUP
Definition: Revision.php:58
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:1264
static newFromID( $id, $flags=0)
Create a new Title from an article ID.
Definition: Title.php:427
getRevisionRecord()
Definition: Revision.php:629
getPage()
Get the page ID.
Definition: Revision.php:782
static countByPageId( $db, $id)
Get count of revisions per page...not very efficient.
Definition: Revision.php:1275
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:994
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2162
setTitle( $title)
Set the title of the revision.
Definition: Revision.php:767
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:295
static getParentLengths( $db, array $revIds)
Do a batched query to get the parent revision lengths.
Definition: Revision.php:538
static getRevisionLookup()
Definition: Revision.php:75
setUserIdAndName( $id, $name)
Set the user ID/name.
Definition: Revision.php:676
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:156
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:879
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:260
isUnpatrolled()
Definition: Revision.php:866
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:915
static selectArchiveFields()
Return the list of revision fields that should be selected to create a new revision from an archive r...
Definition: Revision.php:402
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:1306
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:1135
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:137
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:1048
getSerializedData()
Get original serialized data (without checking view restrictions)
Definition: Revision.php:938
Mutable RevisionRecord implementation, for building new revision entries programmatically.
getMainSlotRaw()
Definition: Revision.php:688
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:63
RevisionRecord $mRecord
Definition: Revision.php:43
getTitle()
Returns the title of the page associated with this entry.
Definition: Revision.php:755
getParentId()
Get parent revision ID (the original previous page revision)
Definition: Revision.php:717
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:799
const FOR_PUBLIC
Definition: Revision.php:54
static getForModelID( $modelId)
Returns the ContentHandler singleton for the given model ID.
__construct( $row, $queryFlags=0, Title $title=null)
Definition: Revision.php:549
isDeleted( $field)
Definition: Revision.php:888
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:1327
getId()
Get revision ID.
Definition: Revision.php:638
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:1244
getContentHandler()
Returns the content handler appropriate for this revision&#39;s content model.
Definition: Revision.php:987
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:1124
static getRevisionFactory()
Definition: Revision.php:82
static loadFromId( $db, $id)
Load a page revision from a given revision ID number.
Definition: Revision.php:242
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:1985
static selectFields()
Return the list of revision fields that should be selected to create a new revision.
Definition: Revision.php:342
getComment( $audience=self::FOR_PUBLIC, User $user=null)
Definition: Revision.php:845
static selectTextFields()
Return the list of text fields that should be selected to read the revision text. ...
Definition: Revision.php:462
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:277
const DELETED_RESTRICTED
Definition: Revision.php:49
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:525
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:925
static getQueryInfo( $options=[])
Return the tables, fields, and join conditions to be selected to create a new revision object...
Definition: Revision.php:511
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:1769
getPrevious()
Get previous revision for this title.
Definition: Revision.php:1010
const RAW
Definition: Revision.php:56
getContentModel()
Returns the content model for the main slot of this revision.
Definition: Revision.php:955
insertOn( $dbw)
Insert a new revision into the database, returning the new revision ID number on success and dies hor...
Definition: Revision.php:1152
const DELETED_TEXT
Definition: Revision.php:46
static countByTitle( $db, $title)
Get count of revisions per page...not very efficient.
Definition: Revision.php:1286
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:574
const SUPPRESSED_USER
Definition: Revision.php:50
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:546
static pageJoinCond()
Return the value of a select() page conds array for the page table.
Definition: Revision.php:331
getVisibility()
Get the deletion bitfield of the revision.
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 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:48
static getStore()
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
static getBlobStore( $wiki=false)
Definition: Revision.php:91
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:704
static newFromRow( $row)
Definition: Revision.php:222
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:1179
Exception representing a failure to look up a revision.
getNext()
Get next revision for this title.
Definition: Revision.php:1021
setId( $id)
Set the revision ID.
Definition: Revision.php:654
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:475
const DELETED_COMMENT
Definition: Revision.php:47
ensureTitle( $row, $queryFlags, $title=null)
Make sure we have some Title object for use by the constructor.
Definition: Revision.php:591
static userJoinCond()
Return the value of a select() JOIN conds array for the user table.
Definition: Revision.php:307
static newFromId( $id, $flags=0)
Load a page revision from a given revision ID number.
Definition: Revision.php:118
getContentFormat()
Returns the content format for the main slot of this revision.
Definition: Revision.php:970
$content
Definition: pageupdater.txt:72
getSize()
Returns the length of the text in this revision, or null if unknown.
Definition: Revision.php:726
static selectUserFields()
Return the list of user fields that should be selected from user table.
Definition: Revision.php:492
static newNullRevision( $dbw, $pageId, $summary, $minor, $user=null)
Create a new null-revision for insertion into a page&#39;s history.
Definition: Revision.php:1198
getSha1()
Returns the base36 sha1 of the content in this revision, or null if unknown.
Definition: Revision.php:739
return true to allow those checks to and false if checking is done & $user
Definition: hooks.txt:1476
const SUPPRESSED_ALL
Definition: Revision.php:51