s/Revision::MW_REV_DELETED/Revision::DELETED/, and introduced aliases for compatibili...
[lhc/web/wiklou.git] / includes / Revision.php
index 7908d56..3139f24 100644 (file)
@@ -6,13 +6,17 @@
 
 /** */
 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.
@@ -246,9 +250,14 @@ class Revision {
                        $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 );
@@ -275,7 +284,7 @@ class Revision {
                        $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.' );
                }
        }
 
@@ -311,7 +320,7 @@ class Revision {
                        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 );
@@ -319,6 +328,14 @@ class Revision {
                return $this->mTitle;
        }
 
+       /**
+        * Set the title of the revision
+        * @param Title $title
+        */
+       function setTitle( $title ) {
+               $this->mTitle = $title;
+       }
+
        /**
         * @return int
         */
@@ -327,23 +344,62 @@ class Revision {
        }
 
        /**
+        * 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;
        }
 
@@ -355,16 +411,30 @@ class Revision {
        }
 
        /**
+        * 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();
@@ -465,6 +535,11 @@ class Revision {
                        if( in_array( 'object', $flags ) ) {
                                # Generic compressed storage
                                $obj = unserialize( $text );
+                               if ( !is_object( $obj ) ) {
+                                       // Invalid object
+                                       wfProfileOut( $fname );
+                                       return false;
+                               }
                                $text = $obj->getText();
                        }
 
@@ -528,12 +603,18 @@ class Revision {
 
                # 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 .= ',';
@@ -573,7 +654,6 @@ class Revision {
                );
 
                $this->mId = !is_null($rev_id) ? $rev_id : $dbw->insertId();
-
                wfProfileOut( $fname );
                return $this->mId;
        }
@@ -650,6 +730,53 @@ class Revision {
                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 );
+
+
 ?>