*
* MCR migration note: this corresponds to Revision::getTitle
*
+ * @note this method should be private, external use should be avoided!
+ *
* @param int|null $pageId
* @param int|null $revId
* @param int $queryFlags
* @return Title
* @throws RevisionAccessException
*/
- private function getTitle( $pageId, $revId, $queryFlags = 0 ) {
+ public function getTitle( $pageId, $revId, $queryFlags = 0 ) {
if ( !$pageId && !$revId ) {
throw new InvalidArgumentException( '$pageId and $revId cannot both be 0 or null' );
}
+ list( $dbMode, $dbOptions, , ) = DBAccessObjectUtils::getDBOptions( $queryFlags );
+ $titleFlags = $dbMode == DB_MASTER ? Title::GAID_FOR_UPDATE : 0;
$title = null;
// Loading by ID is best, but Title::newFromID does not support that for foreign IDs.
if ( $pageId !== null && $pageId > 0 && $this->wikiId === false ) {
// TODO: better foreign title handling (introduce TitleFactory)
- $title = Title::newFromID( $pageId, $queryFlags );
+ $title = Title::newFromID( $pageId, $titleFlags );
}
// rev_id is defined as NOT NULL, but this revision may not yet have been inserted.
if ( !$title && $revId !== null && $revId > 0 ) {
- list( $dbMode, $dbOptions, , ) = DBAccessObjectUtils::getDBOptions( $queryFlags );
-
- $dbr = $this->getDbConnectionRef( $dbMode );
+ $dbr = $this->getDBConnectionRef( $dbMode );
// @todo: Title::getSelectFields(), or Title::getQueryInfo(), or something like that
$row = $dbr->selectRow(
[ 'revision', 'page' ],
$content = null;
$blobData = null;
- $blobFlags = '';
+ $blobFlags = null;
if ( is_object( $row ) ) {
// archive row
if ( isset( $row->old_text ) ) {
// this happens when the text-table gets joined directly, in the pre-1.30 schema
$blobData = isset( $row->old_text ) ? strval( $row->old_text ) : null;
- $blobFlags = isset( $row->old_flags ) ? strval( $row->old_flags ) : '';
+ // Check against selects that might have not included old_flags
+ if ( !property_exists( $row, 'old_flags' ) ) {
+ throw new InvalidArgumentException( 'old_flags was not set in $row' );
+ }
+ $blobFlags = ( $row->old_flags === null ) ? '' : $row->old_flags;
}
$mainSlotRow->slot_revision = intval( $row->rev_id );
$mainSlotRow->format_name = isset( $row['content_format'] )
? strval( $row['content_format'] ) : null;
$blobData = isset( $row['text'] ) ? rtrim( strval( $row['text'] ) ) : null;
- $blobFlags = isset( $row['flags'] ) ? trim( strval( $row['flags'] ) ) : '';
+ // XXX: If the flags field is not set then $blobFlags should be null so that no
+ // decoding will happen. An empty string will result in default decodings.
+ $blobFlags = isset( $row['flags'] ) ? trim( strval( $row['flags'] ) ) : null;
// if we have a Content object, override mText and mContentModel
if ( !empty( $row['content'] ) ) {
*
* @param SlotRecord $slot The SlotRecord to load content for
* @param string|null $blobData The content blob, in the form indicated by $blobFlags
- * @param string $blobFlags Flags indicating how $blobData needs to be processed
+ * @param string|null $blobFlags Flags indicating how $blobData needs to be processed.
+ * Use null if no processing should happen. That is in constrast to the empty string,
+ * which causes the blob to be decoded according to the configured legacy encoding.
* @param string|null $blobFormat MIME type indicating how $dataBlob is encoded
* @param int $queryFlags
*
private function loadSlotContent(
SlotRecord $slot,
$blobData = null,
- $blobFlags = '',
+ $blobFlags = null,
$blobFormat = null,
$queryFlags = 0
) {
if ( $blobData !== null ) {
Assert::parameterType( 'string', $blobData, '$blobData' );
- Assert::parameterType( 'string', $blobFlags, '$blobFlags' );
+ Assert::parameterType( 'string|null', $blobFlags, '$blobFlags' );
$cacheKey = $slot->hasAddress() ? $slot->getAddress() : null;
- $data = $this->blobStore->expandBlob( $blobData, $blobFlags, $cacheKey );
-
- if ( $data === false ) {
- throw new RevisionAccessException(
- "Failed to expand blob data using flags $blobFlags (key: $cacheKey)"
- );
+ if ( $blobFlags === null ) {
+ // No blob flags, so use the blob verbatim.
+ $data = $blobData;
+ } else {
+ $data = $this->blobStore->expandBlob( $blobData, $blobFlags, $cacheKey );
+ if ( $data === false ) {
+ throw new RevisionAccessException(
+ "Failed to expand blob data using flags $blobFlags (key: $cacheKey)"
+ );
+ }
}
+
} else {
$address = $slot->getAddress();
try {
* MCR migration note: this replaces Revision::getPrevious
*
* @param RevisionRecord $rev
+ * @param Title $title if known (optional)
*
* @return RevisionRecord|null
*/
- public function getPreviousRevision( RevisionRecord $rev ) {
- $title = $this->getTitle( $rev->getPageId(), $rev->getId() );
+ public function getPreviousRevision( RevisionRecord $rev, Title $title = null ) {
+ if ( $title === null ) {
+ $title = $this->getTitle( $rev->getPageId(), $rev->getId() );
+ }
$prev = $title->getPreviousRevisionID( $rev->getId() );
if ( $prev ) {
return $this->getRevisionByTitle( $title, $prev );
* MCR migration note: this replaces Revision::getNext
*
* @param RevisionRecord $rev
+ * @param Title $title if known (optional)
*
* @return RevisionRecord|null
*/
- public function getNextRevision( RevisionRecord $rev ) {
- $title = $this->getTitle( $rev->getPageId(), $rev->getId() );
+ public function getNextRevision( RevisionRecord $rev, Title $title = null ) {
+ if ( $title === null ) {
+ $title = $this->getTitle( $rev->getPageId(), $rev->getId() );
+ }
$next = $title->getNextRevisionID( $rev->getId() );
if ( $next ) {
return $this->getRevisionByTitle( $title, $next );