/** */
require_once( 'Database.php' );
-require_once( 'Article.php' );
/**
* @package MediaWiki
* @todo document
*/
class Revision {
+ const DELETED_TEXT = 1;
+ const DELETED_COMMENT = 2;
+ const DELETED_USER = 4;
+ const DELETED_RESTRICTED = 8;
+
/**
* Load a page revision from a given revision ID number.
* Returns null if no such revision can be found.
$this->mTimestamp = $row->rev_timestamp;
$this->mDeleted = intval( $row->rev_deleted );
- $this->mCurrent = ( $row->rev_id == $row->page_latest );
- $this->mTitle = Title::makeTitle( $row->page_namespace,
- $row->page_title );
+ if( isset( $row->page_latest ) ) {
+ $this->mCurrent = ( $row->rev_id == $row->page_latest );
+ $this->mTitle = Title::makeTitle( $row->page_namespace,
+ $row->page_title );
+ } else {
+ $this->mCurrent = false;
+ $this->mTitle = null;
+ }
if( isset( $row->old_text ) ) {
$this->mText = $this->getRevisionText( $row );
$this->mTitle = null; # Load on demand if needed
$this->mCurrent = false;
} else {
- wfDebugDieBacktrace( 'Revision constructor passed invalid row format.' );
+ throw new MWException( 'Revision constructor passed invalid row format.' );
}
}
array( 'page_namespace', 'page_title' ),
array( 'page_id=rev_page',
'rev_id' => $this->mId ),
- 'Revision::getTItle' );
+ 'Revision::getTitle' );
if( $row ) {
$this->mTitle = Title::makeTitle( $row->page_namespace,
$row->page_title );
return $this->mTitle;
}
+ /**
+ * Set the title of the revision
+ * @param Title $title
+ */
+ function setTitle( $title ) {
+ $this->mTitle = $title;
+ }
+
/**
* @return int
*/
}
/**
+ * Fetch revision's user id if it's available to all users
* @return int
*/
function getUser() {
+ if( $this->isDeleted( self::DELETED_USER ) ) {
+ return 0;
+ } else {
+ return $this->mUser;
+ }
+ }
+
+ /**
+ * Fetch revision's user id without regard for the current user's permissions
+ * @return string
+ */
+ function getRawUser() {
return $this->mUser;
}
/**
+ * Fetch revision's username if it's available to all users
* @return string
*/
function getUserText() {
- return $this->mUserText;
+ if( $this->isDeleted( self::DELETED_USER ) ) {
+ return "";
+ } else {
+ return $this->mUserText;
+ }
}
/**
+ * Fetch revision's username without regard for view restrictions
+ * @return string
+ */
+ function getRawUserText() {
+ return $this->mUserText;
+ }
+
+ /**
+ * Fetch revision comment if it's available to all users
* @return string
*/
function getComment() {
+ if( $this->isDeleted( self::DELETED_COMMENT ) ) {
+ return "";
+ } else {
+ return $this->mComment;
+ }
+ }
+
+ /**
+ * Fetch revision comment without regard for the current user's permissions
+ * @return string
+ */
+ function getRawComment() {
return $this->mComment;
}
}
/**
+ * int $field one of DELETED_* bitfield constants
* @return bool
*/
- function isDeleted() {
- return (bool)$this->mDeleted;
+ function isDeleted( $field ) {
+ return ($this->mDeleted & $field) == $field;
}
/**
+ * Fetch revision text if it's available to all users
* @return string
*/
function getText() {
+ if( $this->isDeleted( self::DELETED_TEXT ) ) {
+ return "";
+ } else {
+ return $this->getRawText();
+ }
+ }
+
+ /**
+ * Fetch revision text without regard for view restrictions
+ * @return string
+ */
+ function getRawText() {
if( is_null( $this->mText ) ) {
// Revision text is immutable. Load on demand:
$this->mText = $this->loadText();
if( in_array( 'object', $flags ) ) {
# Generic compressed storage
$obj = unserialize( $text );
+ if ( !is_object( $obj ) ) {
+ // Invalid object
+ wfProfileOut( $fname );
+ return false;
+ }
$text = $obj->getText();
}
# Write to external storage if required
if ( $wgDefaultExternalStore ) {
+ if ( is_array( $wgDefaultExternalStore ) ) {
+ // Distribute storage across multiple clusters
+ $store = $wgDefaultExternalStore[mt_rand(0, count( $wgDefaultExternalStore ) - 1)];
+ } else {
+ $store = $wgDefaultExternalStore;
+ }
require_once('ExternalStore.php');
// Store and get the URL
- $data = ExternalStore::insert( $wgDefaultExternalStore, $data );
+ $data = ExternalStore::insert( $store, $data );
if ( !$data ) {
# This should only happen in the case of a configuration error, where the external store is not valid
- wfDebugDieBacktrace( "Unable to store text to external storage $wgDefaultExternalStore" );
+ throw new MWException( "Unable to store text to external storage $store" );
}
if ( $flags ) {
$flags .= ',';
);
$this->mId = !is_null($rev_id) ? $rev_id : $dbw->insertId();
-
wfProfileOut( $fname );
return $this->mId;
}
wfProfileOut( $fname );
return $revision;
}
+
+ /**
+ * Determine if the current user is allowed to view a particular
+ * field of this revision, if it's marked as deleted.
+ * @param int $field one of self::DELETED_TEXT,
+ * self::DELETED_COMMENT,
+ * self::DELETED_USER
+ * @return bool
+ */
+ function userCan( $field ) {
+ if( ( $this->mDeleted & $field ) == $field ) {
+ global $wgUser;
+ $permission = ( $this->mDeleted & self::DELETED_RESTRICTED ) == self::DELETED_RESTRICTED
+ ? 'hiderevision'
+ : 'deleterevision';
+ wfDebug( "Checking for $permission due to $field match on $this->mDeleted\n" );
+ return $wgUser->isAllowed( $permission );
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Get rev_timestamp from rev_id, without loading the rest of the row
+ * @param integer $id
+ */
+ static function getTimestampFromID( $id ) {
+ $timestamp = $dbr->selectField( 'revision', 'rev_timestamp',
+ array( 'rev_id' => $id ), __METHOD__ );
+ if ( $timestamp === false ) {
+ # Not in slave, try master
+ $dbw =& wfGetDB( DB_MASTER );
+ $timestamp = $dbw->selectField( 'revision', 'rev_timestamp',
+ array( 'rev_id' => $id ), __METHOD__ );
+ }
+ return $timestamp;
+ }
}
+
+/**
+ * Aliases for backwards compatibility with 1.6
+ */
+define( 'MW_REV_DELETED_TEXT', Revision::DELETED_TEXT );
+define( 'MW_REV_DELETED_COMMENT', Revision::DELETED_COMMENT );
+define( 'MW_REV_DELETED_USER', Revision::DELETED_USER );
+define( 'MW_REV_DELETED_RESTRICTED', Revision::DELETED_RESTRICTED );
+
+
?>