use MediaWiki\Revision\RevisionStoreRecord;
use MediaWiki\Revision\SlotRecord;
use MediaWiki\Storage\SqlBlobStore;
+use Wikimedia\Assert\Assert;
use Wikimedia\Rdbms\IDatabase;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\MediaWikiServices;
-use Wikimedia\Rdbms\ResultWrapper;
-use Wikimedia\Rdbms\FakeResultWrapper;
/**
* @deprecated since 1.31, use RevisionRecord, RevisionStore, and BlobStore instead.
/**
* @return RevisionStore
*/
- protected static function getRevisionStore() {
- return MediaWikiServices::getInstance()->getRevisionStore();
+ protected static function getRevisionStore( $wiki = false ) {
+ if ( $wiki ) {
+ return MediaWikiServices::getInstance()->getRevisionStoreFactory()
+ ->getRevisionStore( $wiki );
+ } else {
+ return MediaWikiServices::getInstance()->getRevisionStore();
+ }
}
/**
*/
public static function newFromId( $id, $flags = 0 ) {
$rec = self::getRevisionLookup()->getRevisionById( $id, $flags );
- return $rec === null ? null : new Revision( $rec, $flags );
+ return $rec ? new Revision( $rec, $flags ) : null;
}
/**
*/
public static function newFromTitle( LinkTarget $linkTarget, $id = 0, $flags = 0 ) {
$rec = self::getRevisionLookup()->getRevisionByTitle( $linkTarget, $id, $flags );
- return $rec === null ? null : new Revision( $rec, $flags );
+ return $rec ? new Revision( $rec, $flags ) : null;
}
/**
*/
public static function newFromPageId( $pageId, $revId = 0, $flags = 0 ) {
$rec = self::getRevisionLookup()->getRevisionByPageId( $pageId, $revId, $flags );
- return $rec === null ? null : new Revision( $rec, $flags );
+ return $rec ? new Revision( $rec, $flags ) : null;
}
/**
public static function loadFromId( $db, $id ) {
wfDeprecated( __METHOD__, '1.31' ); // no known callers
$rec = self::getRevisionStore()->loadRevisionFromId( $db, $id );
- return $rec === null ? null : new Revision( $rec );
+ return $rec ? new Revision( $rec ) : null;
}
/**
*/
public static function loadFromPageId( $db, $pageid, $id = 0 ) {
$rec = self::getRevisionStore()->loadRevisionFromPageId( $db, $pageid, $id );
- return $rec === null ? null : new Revision( $rec );
+ return $rec ? new Revision( $rec ) : null;
}
/**
*/
public static function loadFromTitle( $db, $title, $id = 0 ) {
$rec = self::getRevisionStore()->loadRevisionFromTitle( $db, $title, $id );
- return $rec === null ? null : new Revision( $rec );
+ return $rec ? new Revision( $rec ) : null;
}
/**
*/
public static function loadFromTimestamp( $db, $title, $timestamp ) {
$rec = self::getRevisionStore()->loadRevisionFromTimestamp( $db, $title, $timestamp );
- return $rec === null ? null : new Revision( $rec );
- }
-
- /**
- * Return a wrapper for a series of database rows to
- * fetch all of a given page's revisions in turn.
- * Each row can be fed to the constructor to get objects.
- *
- * @param LinkTarget $title
- * @return ResultWrapper
- * @deprecated Since 1.28, no callers in core nor in known extensions. No-op since 1.31.
- */
- public static function fetchRevision( LinkTarget $title ) {
- wfDeprecated( __METHOD__, '1.31' );
- return new FakeResultWrapper( [] );
+ return $rec ? new Revision( $rec ) : null;
}
/**
*/
public static function pageJoinCond() {
wfDeprecated( __METHOD__, '1.31' );
- return [ 'INNER JOIN', [ 'page_id = rev_page' ] ];
+ return [ 'JOIN', [ 'page_id = rev_page' ] ];
}
/**
* @param int $queryFlags
* @param Title|null $title
*
- * @access private
+ * @private
*/
function __construct( $row, $queryFlags = 0, Title $title = null ) {
global $wgUser;
'$row must be a row object, an associative array, or a RevisionRecord'
);
}
+
+ Assert::postcondition( $this->mRecord !== null, 'Failed to construct a RevisionRecord' );
}
/**
$user = $this->mRecord->getUser( $audience, $user );
return $user ? $user->getName() : '';
}
+
/**
- * Fetch revision comment if it's available to the specified audience.
- * If the specified audience does not have access to the comment, an
- * empty string will be returned.
- *
* @param int $audience One of:
* Revision::FOR_PUBLIC to be displayed to all users
* Revision::FOR_THIS_USER to be displayed to the given user
* Revision::RAW get the text regardless of permissions
* @param User|null $user User object to check for, only if FOR_THIS_USER is passed
* to the $audience parameter
- * @return string
+ *
+ * @return string|null Returns null if the specified audience does not have access to the
+ * comment.
*/
function getComment( $audience = self::FOR_PUBLIC, User $user = null ) {
global $wgUser;
* @return Revision|null
*/
public function getPrevious() {
- $title = $this->getTitle();
- $rec = self::getRevisionLookup()->getPreviousRevision( $this->mRecord, $title );
- return $rec === null ? null : new Revision( $rec, self::READ_NORMAL, $title );
+ $rec = self::getRevisionLookup()->getPreviousRevision( $this->mRecord );
+ return $rec ? new Revision( $rec, self::READ_NORMAL, $this->getTitle() ) : null;
}
/**
* @return Revision|null
*/
public function getNext() {
- $title = $this->getTitle();
- $rec = self::getRevisionLookup()->getNextRevision( $this->mRecord, $title );
- return $rec === null ? null : new Revision( $rec, self::READ_NORMAL, $title );
+ $rec = self::getRevisionLookup()->getNextRevision( $this->mRecord );
+ return $rec ? new Revision( $rec, self::READ_NORMAL, $this->getTitle() ) : null;
}
/**
* Get revision text associated with an old or archive row
*
- * Both the flags and the text field must be included. Including the old_id
+ * If the text field is not included, this uses RevisionStore to load the appropriate slot
+ * and return its serialized content. This is the default backwards-compatibility behavior
+ * when reading from the MCR aware database schema is enabled. For this to work, either
+ * the revision ID or the page ID must be included in the row.
+ *
+ * When using the old text field, the flags field must also be set. Including the old_id
* field will activate cache usage as long as the $wiki parameter is not set.
*
- * @param stdClass $row The text data
+ * @deprecated since 1.32, use RevisionStore::newRevisionFromRow instead.
+ *
+ * @param stdClass $row The text data. If a falsy value is passed instead, false is returned.
* @param string $prefix Table prefix (default 'old_')
* @param string|bool $wiki The name of the wiki to load the revision text from
* (same as the wiki $row was loaded from) or false to indicate the local
* @return string|false Text the text requested or false on failure
*/
public static function getRevisionText( $row, $prefix = 'old_', $wiki = false ) {
+ global $wgMultiContentRevisionSchemaMigrationStage;
+
+ if ( !$row ) {
+ return false;
+ }
+
$textField = $prefix . 'text';
$flagsField = $prefix . 'flags';
- if ( isset( $row->$flagsField ) ) {
- $flags = explode( ',', $row->$flagsField );
+ if ( isset( $row->$textField ) ) {
+ if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
+ // The text field was read, but it's no longer being populated!
+ // We could gloss over this by using the text when it's there and loading
+ // if when it's not, but it seems preferable to complain loudly about a
+ // query that is no longer guaranteed to work reliably.
+ throw new LogicException(
+ 'Cannot use ' . __METHOD__ . ' with the ' . $textField . ' field when'
+ . ' $wgMultiContentRevisionSchemaMigrationStage does not include'
+ . ' SCHEMA_COMPAT_WRITE_OLD. The field may not be populated for all revisions!'
+ );
+ }
+
+ $text = $row->$textField;
} else {
- $flags = [];
+ // Missing text field, we are probably looking at the MCR-enabled DB schema.
+
+ if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
+ // This method should no longer be used with the new schema. Ideally, we
+ // would already trigger a deprecation warning when SCHEMA_COMPAT_READ_NEW is set.
+ wfDeprecated( __METHOD__ . ' (MCR without SCHEMA_COMPAT_WRITE_OLD)', '1.32' );
+ }
+
+ $store = self::getRevisionStore( $wiki );
+ $rev = $prefix === 'ar_'
+ ? $store->newRevisionFromArchiveRow( $row )
+ : $store->newRevisionFromRow( $row );
+
+ $content = $rev->getContent( SlotRecord::MAIN );
+ return $content ? $content->serialize() : false;
}
- if ( isset( $row->$textField ) ) {
- $text = $row->$textField;
+ if ( isset( $row->$flagsField ) ) {
+ $flags = explode( ',', $row->$flagsField );
} else {
- return false;
+ $flags = [];
}
$cacheKey = isset( $row->old_id )
$rec = self::getRevisionStore()->insertRevisionOn( $this->mRecord, $dbw );
$this->mRecord = $rec;
-
- // Avoid PHP 7.1 warning of passing $this by reference
- $revision = $this;
+ Assert::postcondition( $this->mRecord !== null, 'Failed to acquire a RevisionRecord' );
return $rec->getId();
}
/**
* Get rev_timestamp from rev_id, without loading the rest of the row
*
- * @param Title $title
+ * @param Title $title (ignored since 1.34)
* @param int $id
* @param int $flags
* @return string|bool False if not found
*/
static function getTimestampFromId( $title, $id, $flags = 0 ) {
- return self::getRevisionStore()->getTimestampFromId( $title, $id, $flags );
+ return self::getRevisionStore()->getTimestampFromId( $id, $flags );
}
/**