32 use Wikimedia\Assert\Assert;
56 const RAW = RevisionRecord::RAW;
65 return MediaWikiServices::getInstance()->getRevisionStoreFactory()
66 ->getRevisionStore( $wiki );
68 return MediaWikiServices::getInstance()->getRevisionStore();
76 return MediaWikiServices::getInstance()->getRevisionLookup();
83 return MediaWikiServices::getInstance()->getRevisionFactory();
93 $store = MediaWikiServices::getInstance()
94 ->getBlobStoreFactory()
95 ->newSqlBlobStore( $wiki );
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 )
121 return $rec ?
new Revision( $rec, $flags ) :
null;
140 return $rec ?
new Revision( $rec, $flags ) :
null;
159 return $rec ?
new Revision( $rec, $flags ) :
null;
179 if ( array_key_exists(
'page', $overrides ) ) {
180 $overrides[
'page_id'] = $overrides[
'page'];
181 unset( $overrides[
'page'] );
190 if ( isset( $overrides[
'title'] ) ) {
191 if ( !( $overrides[
'title'] instanceof
Title ) ) {
192 throw new MWException(
'title field override must contain a Title object.' );
195 $title = $overrides[
'title'];
198 if ( isset( $row->ar_namespace ) && isset( $row->ar_title ) ) {
201 throw new InvalidArgumentException(
202 'A Title or ar_namespace and ar_title must be given'
224 if ( is_array( $row ) ) {
246 return $rec ?
new Revision( $rec ) :
null;
263 return $rec ?
new Revision( $rec ) :
null;
280 return $rec ?
new Revision( $rec ) :
null;
298 return $rec ?
new Revision( $rec ) :
null;
357 $this->mRecord = $row;
358 } elseif ( is_array( $row ) ) {
361 if ( !isset( $row[
'user'] ) && !isset( $row[
'user_text'] ) ) {
362 $row[
'user'] = $wgUser;
370 } elseif ( is_object( $row ) ) {
377 throw new InvalidArgumentException(
378 '$row must be a row object, an associative array, or a RevisionRecord'
382 Assert::postcondition( $this->mRecord !==
null,
'Failed to construct a RevisionRecord' );
400 if ( is_array( $row ) ) {
401 if ( isset( $row[
'title'] ) ) {
402 if ( !( $row[
'title'] instanceof
Title ) ) {
403 throw new MWException(
'title field must contain a Title object.' );
406 return $row[
'title'];
409 $pageId = $row[
'page'] ?? 0;
410 $revId = $row[
'id'] ?? 0;
412 $pageId = $row->rev_page ?? 0;
413 $revId = $row->rev_id ?? 0;
424 $title->resetArticleID( $pageId );
443 return $this->mRecord->getId();
460 $this->mRecord->setId( intval( $id ) );
462 throw new MWException( __METHOD__ .
' is not supported on this instance' );
483 $this->mRecord->setUser( $user );
485 throw new MWException( __METHOD__ .
' is not supported on this instance' );
493 return $this->mRecord->getSlot( SlotRecord::MAIN, RevisionRecord::RAW );
510 return $slot->hasAddress()
522 return $this->mRecord->getParentId();
532 return $this->mRecord->getSize();
545 return $this->mRecord->getSha1();
560 $linkTarget = $this->mRecord->getPageAsLinkTarget();
572 if ( !
$title->equals( $this->getTitle() ) ) {
573 throw new InvalidArgumentException(
575 .
' is not the same as '
576 . $this->mRecord->getPageAsLinkTarget()->__toString()
587 return $this->mRecord->getPageId();
603 public function getUser( $audience = self::FOR_PUBLIC,
User $user =
null ) {
606 if ( $audience === self::FOR_THIS_USER && !$user ) {
610 $user = $this->mRecord->getUser( $audience, $user );
611 return $user ? $user->getId() : 0;
630 if ( $audience === self::FOR_THIS_USER && !$user ) {
634 $user = $this->mRecord->getUser( $audience, $user );
635 return $user ? $user->getName() :
'';
652 if ( $audience === self::FOR_THIS_USER && !$user ) {
656 $comment = $this->mRecord->getComment( $audience, $user );
657 return $comment ===
null ? null : $comment->text;
664 return $this->mRecord->isMinor();
693 return $this->mRecord->isDeleted( $field );
702 return $this->mRecord->getVisibility();
722 if ( $audience === self::FOR_THIS_USER && !$user ) {
727 return $this->mRecord->getContent( SlotRecord::MAIN, $audience, $user );
744 return $slot->getContent()->serialize();
777 if ( $format ===
null ) {
799 return $this->mRecord->getTimestamp();
816 return $rec ?
new Revision( $rec, self::READ_NORMAL, $this->
getTitle() ) :
null;
826 return $rec ?
new Revision( $rec, self::READ_NORMAL, $this->
getTitle() ) :
null;
857 $textField = $prefix .
'text';
858 $flagsField = $prefix .
'flags';
860 if ( isset( $row->$textField ) ) {
866 throw new LogicException(
867 'Cannot use ' . __METHOD__ .
' with the ' . $textField .
' field when'
868 .
' $wgMultiContentRevisionSchemaMigrationStage does not include'
869 .
' SCHEMA_COMPAT_WRITE_OLD. The field may not be populated for all revisions!'
873 $text = $row->$textField;
880 wfDeprecated( __METHOD__ .
' (MCR without SCHEMA_COMPAT_WRITE_OLD)',
'1.32' );
884 $rev = $prefix ===
'ar_'
885 ? $store->newRevisionFromArchiveRow( $row )
886 : $store->newRevisionFromRow( $row );
888 $content = $rev->getContent( SlotRecord::MAIN );
892 if ( isset( $row->$flagsField ) ) {
893 $flags = explode(
',', $row->$flagsField );
898 $cacheKey = isset( $row->old_id )
899 ? SqlBlobStore::makeAddressFromTextId( $row->old_id )
904 if ( $revisionText ===
false ) {
905 if ( isset( $row->old_id ) ) {
906 wfLogWarning( __METHOD__ .
": Bad data in text row {$row->old_id}! " );
908 wfLogWarning( __METHOD__ .
": Bad data in text row! " );
913 return $revisionText;
938 if ( $text ===
false ) {
960 if ( $this->mRecord->getUser( RevisionRecord::RAW ) === null ) {
962 $this->mRecord->setUser( $wgUser );
964 throw new MWException(
'Cannot insert revision with no associated user.' );
970 $this->mRecord = $rec;
971 Assert::postcondition( $this->mRecord !==
null,
'Failed to acquire a RevisionRecord' );
973 return $rec->getId();
982 return SlotRecord::base36Sha1( $text );
1015 return $rec ?
new Revision( $rec ) :
null;
1055 return RevisionRecord::userCanBitfield( $bitfield, $field, $user,
$title );
1109 if ( is_int( $db ) ) {
1139 return $record ?
new Revision( $record ) :
false;