2004-12-19 12:21:29 +00:00
|
|
|
<?php
|
2005-01-27 19:51:47 +00:00
|
|
|
/**
|
|
|
|
|
* @todo document
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @file
|
2005-01-27 19:51:47 +00:00
|
|
|
*/
|
2004-12-19 12:21:29 +00:00
|
|
|
|
2005-01-27 19:51:47 +00:00
|
|
|
/**
|
|
|
|
|
* @todo document
|
|
|
|
|
*/
|
2004-12-19 12:21:29 +00:00
|
|
|
class Revision {
|
2007-02-05 23:26:26 +00:00
|
|
|
const DELETED_TEXT = 1;
|
|
|
|
|
const DELETED_COMMENT = 2;
|
|
|
|
|
const DELETED_USER = 4;
|
2007-04-21 14:44:56 +00:00
|
|
|
const DELETED_RESTRICTED = 8;
|
|
|
|
|
|
2008-09-24 09:44:45 +00:00
|
|
|
// Audience options for Revision::getText()
|
|
|
|
|
const FOR_PUBLIC = 1;
|
|
|
|
|
const FOR_THIS_USER = 2;
|
|
|
|
|
const RAW = 3;
|
|
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
|
|
|
|
* Load a page revision from a given revision ID number.
|
|
|
|
|
* Returns null if no such revision can be found.
|
|
|
|
|
*
|
|
|
|
|
* @param int $id
|
|
|
|
|
* @access public
|
2006-10-02 15:03:39 +00:00
|
|
|
* @static
|
2004-12-19 12:21:29 +00:00
|
|
|
*/
|
2006-10-02 16:17:57 +00:00
|
|
|
public static function newFromId( $id ) {
|
|
|
|
|
return Revision::newFromConds(
|
|
|
|
|
array( 'page_id=rev_page',
|
|
|
|
|
'rev_id' => intval( $id ) ) );
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
|
|
|
|
* Load either the current, or a specified, revision
|
|
|
|
|
* that's attached to a given title. If not attached
|
|
|
|
|
* to that title, will return null.
|
|
|
|
|
*
|
|
|
|
|
* @param Title $title
|
|
|
|
|
* @param int $id
|
|
|
|
|
* @return Revision
|
|
|
|
|
*/
|
2008-05-23 07:20:52 +00:00
|
|
|
public static function newFromTitle( $title, $id = 0 ) {
|
2008-09-26 02:42:30 +00:00
|
|
|
$conds = array(
|
|
|
|
|
'page_namespace' => $title->getNamespace(),
|
|
|
|
|
'page_title' => $title->getDBkey()
|
|
|
|
|
);
|
|
|
|
|
if ( $id ) {
|
|
|
|
|
// Use the specified ID
|
|
|
|
|
$conds['rev_id'] = $id;
|
|
|
|
|
} elseif ( wfGetLB()->getServerCount() > 1 ) {
|
|
|
|
|
// Get the latest revision ID from the master
|
|
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
|
|
|
|
$latest = $dbw->selectField( 'page', 'page_latest', $conds, __METHOD__ );
|
2009-02-17 14:02:12 +00:00
|
|
|
if ( $latest === false ) {
|
|
|
|
|
// Page does not exist
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2008-09-26 02:42:30 +00:00
|
|
|
$conds['rev_id'] = $latest;
|
2004-12-19 12:21:29 +00:00
|
|
|
} else {
|
2008-09-26 02:42:30 +00:00
|
|
|
// Use a join to get the latest revision
|
|
|
|
|
$conds[] = 'rev_id=page_latest';
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2008-09-26 02:42:30 +00:00
|
|
|
$conds[] = 'page_id=rev_page';
|
|
|
|
|
return Revision::newFromConds( $conds );
|
2005-03-18 04:32:55 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-10-02 16:17:57 +00:00
|
|
|
/**
|
|
|
|
|
* Load a page revision from a given revision ID number.
|
|
|
|
|
* Returns null if no such revision can be found.
|
|
|
|
|
*
|
|
|
|
|
* @param Database $db
|
|
|
|
|
* @param int $id
|
|
|
|
|
* @access public
|
|
|
|
|
* @static
|
|
|
|
|
*/
|
2008-05-23 07:33:35 +00:00
|
|
|
public static function loadFromId( $db, $id ) {
|
2006-10-02 16:17:57 +00:00
|
|
|
return Revision::loadFromConds( $db,
|
|
|
|
|
array( 'page_id=rev_page',
|
|
|
|
|
'rev_id' => intval( $id ) ) );
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-18 04:32:55 +00:00
|
|
|
/**
|
|
|
|
|
* Load either the current, or a specified, revision
|
|
|
|
|
* that's attached to a given page. If not attached
|
|
|
|
|
* to that page, will return null.
|
|
|
|
|
*
|
|
|
|
|
* @param Database $db
|
|
|
|
|
* @param int $pageid
|
|
|
|
|
* @param int $id
|
|
|
|
|
* @return Revision
|
|
|
|
|
* @access public
|
2006-10-02 15:03:39 +00:00
|
|
|
* @static
|
2005-03-18 04:32:55 +00:00
|
|
|
*/
|
2007-01-22 23:50:42 +00:00
|
|
|
public static function loadFromPageId( $db, $pageid, $id = 0 ) {
|
2006-01-25 20:50:39 +00:00
|
|
|
$conds=array('page_id=rev_page','rev_page'=>intval( $pageid ), 'page_id'=>intval( $pageid ));
|
2005-03-18 04:32:55 +00:00
|
|
|
if( $id ) {
|
2006-01-25 20:50:39 +00:00
|
|
|
$conds['rev_id']=intval($id);
|
2005-03-18 04:32:55 +00:00
|
|
|
} else {
|
2006-01-25 20:50:39 +00:00
|
|
|
$conds[]='rev_id=page_latest';
|
2005-03-18 04:32:55 +00:00
|
|
|
}
|
2006-01-25 20:50:39 +00:00
|
|
|
return Revision::loadFromConds( $db, $conds );
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-06-28 23:19:56 +00:00
|
|
|
/**
|
|
|
|
|
* Load either the current, or a specified, revision
|
|
|
|
|
* that's attached to a given page. If not attached
|
|
|
|
|
* to that page, will return null.
|
|
|
|
|
*
|
|
|
|
|
* @param Database $db
|
|
|
|
|
* @param Title $title
|
|
|
|
|
* @param int $id
|
|
|
|
|
* @return Revision
|
|
|
|
|
* @access public
|
2006-10-02 15:03:39 +00:00
|
|
|
* @static
|
2005-06-28 23:19:56 +00:00
|
|
|
*/
|
2008-05-23 07:33:35 +00:00
|
|
|
public static function loadFromTitle( $db, $title, $id = 0 ) {
|
2005-06-28 23:19:56 +00:00
|
|
|
if( $id ) {
|
2005-08-16 23:36:16 +00:00
|
|
|
$matchId = intval( $id );
|
2005-06-28 23:19:56 +00:00
|
|
|
} else {
|
|
|
|
|
$matchId = 'page_latest';
|
|
|
|
|
}
|
|
|
|
|
return Revision::loadFromConds(
|
|
|
|
|
$db,
|
|
|
|
|
array( "rev_id=$matchId",
|
|
|
|
|
'page_id=rev_page',
|
|
|
|
|
'page_namespace' => $title->getNamespace(),
|
2008-01-14 09:13:04 +00:00
|
|
|
'page_title' => $title->getDBkey() ) );
|
2005-06-28 23:19:56 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-04-26 09:52:11 +00:00
|
|
|
/**
|
|
|
|
|
* Load the revision for the given title with the given timestamp.
|
|
|
|
|
* WARNING: Timestamps may in some circumstances not be unique,
|
|
|
|
|
* so this isn't the best key to use.
|
|
|
|
|
*
|
|
|
|
|
* @param Database $db
|
|
|
|
|
* @param Title $title
|
|
|
|
|
* @param string $timestamp
|
|
|
|
|
* @return Revision
|
|
|
|
|
* @access public
|
|
|
|
|
* @static
|
|
|
|
|
*/
|
2008-05-23 07:33:35 +00:00
|
|
|
public static function loadFromTimestamp( $db, $title, $timestamp ) {
|
2005-04-26 09:52:11 +00:00
|
|
|
return Revision::loadFromConds(
|
|
|
|
|
$db,
|
|
|
|
|
array( 'rev_timestamp' => $db->timestamp( $timestamp ),
|
|
|
|
|
'page_id=rev_page',
|
|
|
|
|
'page_namespace' => $title->getNamespace(),
|
2008-01-14 09:13:04 +00:00
|
|
|
'page_title' => $title->getDBkey() ) );
|
2005-04-26 09:52:11 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
|
|
|
|
* Given a set of conditions, fetch a revision.
|
|
|
|
|
*
|
|
|
|
|
* @param array $conditions
|
|
|
|
|
* @return Revision
|
|
|
|
|
* @access private
|
2006-10-02 15:03:39 +00:00
|
|
|
* @static
|
2004-12-19 12:21:29 +00:00
|
|
|
*/
|
2006-07-10 15:41:30 +00:00
|
|
|
private static function newFromConds( $conditions ) {
|
2007-01-22 23:50:42 +00:00
|
|
|
$db = wfGetDB( DB_SLAVE );
|
2005-06-26 18:47:09 +00:00
|
|
|
$row = Revision::loadFromConds( $db, $conditions );
|
2008-09-26 02:42:30 +00:00
|
|
|
if( is_null( $row ) && wfGetLB()->getServerCount() > 1 ) {
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-06-26 18:47:09 +00:00
|
|
|
$row = Revision::loadFromConds( $dbw, $conditions );
|
|
|
|
|
}
|
|
|
|
|
return $row;
|
2005-03-18 04:32:55 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-18 04:32:55 +00:00
|
|
|
/**
|
|
|
|
|
* Given a set of conditions, fetch a revision from
|
|
|
|
|
* the given database connection.
|
|
|
|
|
*
|
|
|
|
|
* @param Database $db
|
|
|
|
|
* @param array $conditions
|
|
|
|
|
* @return Revision
|
|
|
|
|
* @access private
|
2006-10-02 15:03:39 +00:00
|
|
|
* @static
|
2005-03-18 04:32:55 +00:00
|
|
|
*/
|
2007-01-22 23:50:42 +00:00
|
|
|
private static function loadFromConds( $db, $conditions ) {
|
2005-07-22 11:29:15 +00:00
|
|
|
$res = Revision::fetchFromConds( $db, $conditions );
|
2004-12-19 12:21:29 +00:00
|
|
|
if( $res ) {
|
|
|
|
|
$row = $res->fetchObject();
|
|
|
|
|
$res->free();
|
|
|
|
|
if( $row ) {
|
2005-08-02 13:35:19 +00:00
|
|
|
$ret = new Revision( $row );
|
|
|
|
|
return $ret;
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
$ret = null;
|
|
|
|
|
return $ret;
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
|
|
|
|
* 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 Title $title
|
|
|
|
|
* @return ResultWrapper
|
|
|
|
|
* @access public
|
2006-10-02 15:03:39 +00:00
|
|
|
* @static
|
2004-12-19 12:21:29 +00:00
|
|
|
*/
|
2008-05-23 07:33:35 +00:00
|
|
|
public static function fetchAllRevisions( $title ) {
|
2004-12-19 12:21:29 +00:00
|
|
|
return Revision::fetchFromConds(
|
2005-03-18 04:32:55 +00:00
|
|
|
wfGetDB( DB_SLAVE ),
|
2004-12-19 12:21:29 +00:00
|
|
|
array( 'page_namespace' => $title->getNamespace(),
|
2008-01-14 09:13:04 +00:00
|
|
|
'page_title' => $title->getDBkey(),
|
2005-08-02 13:35:19 +00:00
|
|
|
'page_id=rev_page' ) );
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
|
|
|
|
* 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 Title $title
|
|
|
|
|
* @return ResultWrapper
|
|
|
|
|
* @access public
|
2006-10-02 15:03:39 +00:00
|
|
|
* @static
|
2004-12-19 12:21:29 +00:00
|
|
|
*/
|
2008-05-23 07:33:35 +00:00
|
|
|
public static function fetchRevision( $title ) {
|
2004-12-19 12:21:29 +00:00
|
|
|
return Revision::fetchFromConds(
|
2005-03-18 04:32:55 +00:00
|
|
|
wfGetDB( DB_SLAVE ),
|
2004-12-19 12:21:29 +00:00
|
|
|
array( 'rev_id=page_latest',
|
|
|
|
|
'page_namespace' => $title->getNamespace(),
|
2008-01-14 09:13:04 +00:00
|
|
|
'page_title' => $title->getDBkey(),
|
2005-08-02 13:35:19 +00:00
|
|
|
'page_id=rev_page' ) );
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-18 04:32:55 +00:00
|
|
|
/**
|
2004-12-19 12:21:29 +00:00
|
|
|
* Given a set of conditions, return a ResultWrapper
|
|
|
|
|
* which will return matching database rows with the
|
|
|
|
|
* fields necessary to build Revision objects.
|
|
|
|
|
*
|
2005-03-18 04:32:55 +00:00
|
|
|
* @param Database $db
|
2004-12-19 12:21:29 +00:00
|
|
|
* @param array $conditions
|
|
|
|
|
* @return ResultWrapper
|
|
|
|
|
* @access private
|
2006-10-02 15:03:39 +00:00
|
|
|
* @static
|
2004-12-19 12:21:29 +00:00
|
|
|
*/
|
2007-01-22 23:50:42 +00:00
|
|
|
private static function fetchFromConds( $db, $conditions ) {
|
2008-04-07 23:53:57 +00:00
|
|
|
$fields = self::selectFields();
|
|
|
|
|
$fields[] = 'page_namespace';
|
|
|
|
|
$fields[] = 'page_title';
|
|
|
|
|
$fields[] = 'page_latest';
|
2005-03-18 04:32:55 +00:00
|
|
|
$res = $db->select(
|
|
|
|
|
array( 'page', 'revision' ),
|
2008-04-07 23:53:57 +00:00
|
|
|
$fields,
|
2004-12-19 12:21:29 +00:00
|
|
|
$conditions,
|
2008-09-26 02:42:30 +00:00
|
|
|
__METHOD__,
|
2005-05-28 07:01:14 +00:00
|
|
|
array( 'LIMIT' => 1 ) );
|
2005-08-02 13:35:19 +00:00
|
|
|
$ret = $db->resultObject( $res );
|
|
|
|
|
return $ret;
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2007-03-09 15:29:18 +00:00
|
|
|
/**
|
2008-04-14 07:45:50 +00:00
|
|
|
* Return the list of revision fields that should be selected to create
|
2007-03-09 15:29:18 +00:00
|
|
|
* a new revision.
|
|
|
|
|
*/
|
|
|
|
|
static function selectFields() {
|
2008-04-14 07:45:50 +00:00
|
|
|
return array(
|
2007-03-09 15:29:18 +00:00
|
|
|
'rev_id',
|
|
|
|
|
'rev_page',
|
|
|
|
|
'rev_text_id',
|
|
|
|
|
'rev_timestamp',
|
|
|
|
|
'rev_comment',
|
|
|
|
|
'rev_user_text,'.
|
2008-04-07 23:53:57 +00:00
|
|
|
'rev_user',
|
|
|
|
|
'rev_minor_edit',
|
2007-03-09 15:29:18 +00:00
|
|
|
'rev_deleted',
|
2008-04-07 23:53:57 +00:00
|
|
|
'rev_len',
|
|
|
|
|
'rev_parent_id'
|
2007-03-09 15:29:18 +00:00
|
|
|
);
|
|
|
|
|
}
|
2008-05-13 10:42:32 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return the list of text fields that should be selected to read the
|
|
|
|
|
* revision text
|
|
|
|
|
*/
|
|
|
|
|
static function selectTextFields() {
|
|
|
|
|
return array(
|
|
|
|
|
'old_text',
|
|
|
|
|
'old_flags'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Return the list of page fields that should be selected from page table
|
|
|
|
|
*/
|
|
|
|
|
static function selectPageFields() {
|
|
|
|
|
return array(
|
|
|
|
|
'page_namespace',
|
|
|
|
|
'page_title',
|
|
|
|
|
'page_latest'
|
|
|
|
|
);
|
|
|
|
|
}
|
2007-03-09 15:29:18 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
|
|
|
|
* @param object $row
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
function Revision( $row ) {
|
2005-03-11 06:00:05 +00:00
|
|
|
if( is_object( $row ) ) {
|
2005-08-16 23:36:16 +00:00
|
|
|
$this->mId = intval( $row->rev_id );
|
|
|
|
|
$this->mPage = intval( $row->rev_page );
|
|
|
|
|
$this->mTextId = intval( $row->rev_text_id );
|
2005-03-11 06:00:05 +00:00
|
|
|
$this->mComment = $row->rev_comment;
|
|
|
|
|
$this->mUserText = $row->rev_user_text;
|
2005-08-16 23:36:16 +00:00
|
|
|
$this->mUser = intval( $row->rev_user );
|
|
|
|
|
$this->mMinorEdit = intval( $row->rev_minor_edit );
|
2005-03-11 06:00:05 +00:00
|
|
|
$this->mTimestamp = $row->rev_timestamp;
|
2005-08-16 23:36:16 +00:00
|
|
|
$this->mDeleted = intval( $row->rev_deleted );
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-04-08 05:50:42 +00:00
|
|
|
if( !isset( $row->rev_parent_id ) )
|
2008-04-08 21:38:39 +00:00
|
|
|
$this->mParentId = is_null($row->rev_parent_id) ? null : 0;
|
2008-04-08 05:50:42 +00:00
|
|
|
else
|
|
|
|
|
$this->mParentId = intval( $row->rev_parent_id );
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-04-20 15:33:51 +00:00
|
|
|
if( !isset( $row->rev_len ) || is_null( $row->rev_len ) )
|
2007-03-08 03:07:58 +00:00
|
|
|
$this->mSize = null;
|
|
|
|
|
else
|
2008-04-14 07:45:50 +00:00
|
|
|
$this->mSize = intval( $row->rev_len );
|
2007-03-08 03:07:58 +00:00
|
|
|
|
2006-03-16 19:04:25 +00:00
|
|
|
if( isset( $row->page_latest ) ) {
|
2008-12-11 01:28:37 +00:00
|
|
|
$this->mCurrent = ( $row->rev_id == $row->page_latest );
|
|
|
|
|
$this->mTitle = Title::makeTitle( $row->page_namespace, $row->page_title );
|
|
|
|
|
$this->mTitle->resetArticleID( $this->mPage );
|
2006-03-16 19:04:25 +00:00
|
|
|
} else {
|
|
|
|
|
$this->mCurrent = false;
|
|
|
|
|
$this->mTitle = null;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-09-18 17:52:44 +00:00
|
|
|
// Lazy extraction...
|
|
|
|
|
$this->mText = null;
|
2005-03-18 04:32:55 +00:00
|
|
|
if( isset( $row->old_text ) ) {
|
2006-09-18 17:52:44 +00:00
|
|
|
$this->mTextRow = $row;
|
2005-03-18 04:32:55 +00:00
|
|
|
} else {
|
2006-09-18 17:52:44 +00:00
|
|
|
// 'text' table row entry will be lazy-loaded
|
|
|
|
|
$this->mTextRow = null;
|
2005-03-18 04:32:55 +00:00
|
|
|
}
|
2005-03-11 06:00:05 +00:00
|
|
|
} elseif( is_array( $row ) ) {
|
|
|
|
|
// Build a new revision to be saved...
|
|
|
|
|
global $wgUser;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-08-16 23:36:16 +00:00
|
|
|
$this->mId = isset( $row['id'] ) ? intval( $row['id'] ) : null;
|
|
|
|
|
$this->mPage = isset( $row['page'] ) ? intval( $row['page'] ) : null;
|
|
|
|
|
$this->mTextId = isset( $row['text_id'] ) ? intval( $row['text_id'] ) : null;
|
|
|
|
|
$this->mUserText = isset( $row['user_text'] ) ? strval( $row['user_text'] ) : $wgUser->getName();
|
2008-05-22 16:39:43 +00:00
|
|
|
$this->mUser = isset( $row['user'] ) ? intval( $row['user'] ) : $wgUser->getId();
|
2005-08-16 23:36:16 +00:00
|
|
|
$this->mMinorEdit = isset( $row['minor_edit'] ) ? intval( $row['minor_edit'] ) : 0;
|
|
|
|
|
$this->mTimestamp = isset( $row['timestamp'] ) ? strval( $row['timestamp'] ) : wfTimestamp( TS_MW );
|
|
|
|
|
$this->mDeleted = isset( $row['deleted'] ) ? intval( $row['deleted'] ) : 0;
|
2007-03-15 00:48:38 +00:00
|
|
|
$this->mSize = isset( $row['len'] ) ? intval( $row['len'] ) : null;
|
2008-04-08 21:38:39 +00:00
|
|
|
$this->mParentId = isset( $row['parent_id'] ) ? intval( $row['parent_id'] ) : null;
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2005-06-01 08:18:34 +00:00
|
|
|
// Enforce spacing trimming on supplied text
|
2005-08-16 23:36:16 +00:00
|
|
|
$this->mComment = isset( $row['comment'] ) ? trim( strval( $row['comment'] ) ) : null;
|
|
|
|
|
$this->mText = isset( $row['text'] ) ? rtrim( strval( $row['text'] ) ) : null;
|
2006-10-26 16:47:30 +00:00
|
|
|
$this->mTextRow = null;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-11 06:00:05 +00:00
|
|
|
$this->mTitle = null; # Load on demand if needed
|
|
|
|
|
$this->mCurrent = false;
|
2007-03-13 23:28:34 +00:00
|
|
|
# If we still have no len_size, see it we have the text to figure it out
|
|
|
|
|
if ( !$this->mSize )
|
|
|
|
|
$this->mSize = is_null($this->mText) ? null : strlen($this->mText);
|
2005-03-11 06:00:05 +00:00
|
|
|
} else {
|
2006-06-07 06:40:24 +00:00
|
|
|
throw new MWException( 'Revision constructor passed invalid row format.' );
|
2005-03-11 06:00:05 +00:00
|
|
|
}
|
2009-01-15 17:53:19 +00:00
|
|
|
$this->mUnpatrolled = NULL;
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-01-27 19:51:47 +00:00
|
|
|
/**#@+
|
2004-12-19 12:21:29 +00:00
|
|
|
* @access public
|
|
|
|
|
*/
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
2008-04-07 23:53:57 +00:00
|
|
|
* Get revision ID
|
2004-12-19 12:21:29 +00:00
|
|
|
* @return int
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getId() {
|
2004-12-19 12:21:29 +00:00
|
|
|
return $this->mId;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-28 10:47:12 +00:00
|
|
|
/**
|
2008-04-07 23:53:57 +00:00
|
|
|
* Get text row ID
|
2005-03-28 10:47:12 +00:00
|
|
|
* @return int
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getTextId() {
|
2005-03-28 10:47:12 +00:00
|
|
|
return $this->mTextId;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-04-07 23:53:57 +00:00
|
|
|
/**
|
|
|
|
|
* Get parent revision ID (the original previous page revision)
|
|
|
|
|
* @return int
|
|
|
|
|
*/
|
|
|
|
|
public function getParentId() {
|
|
|
|
|
return $this->mParentId;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2007-03-08 03:07:58 +00:00
|
|
|
/**
|
|
|
|
|
* Returns the length of the text in this revision, or null if unknown.
|
2008-04-07 23:53:57 +00:00
|
|
|
* @return int
|
2007-03-08 03:07:58 +00:00
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getSize() {
|
2007-03-08 03:07:58 +00:00
|
|
|
return $this->mSize;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
|
|
|
|
* Returns the title of the page associated with this entry.
|
|
|
|
|
* @return Title
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getTitle() {
|
2004-12-19 12:21:29 +00:00
|
|
|
if( isset( $this->mTitle ) ) {
|
|
|
|
|
return $this->mTitle;
|
|
|
|
|
}
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2004-12-19 12:21:29 +00:00
|
|
|
$row = $dbr->selectRow(
|
|
|
|
|
array( 'page', 'revision' ),
|
|
|
|
|
array( 'page_namespace', 'page_title' ),
|
|
|
|
|
array( 'page_id=rev_page',
|
|
|
|
|
'rev_id' => $this->mId ),
|
2006-06-11 04:48:27 +00:00
|
|
|
'Revision::getTitle' );
|
2004-12-19 12:21:29 +00:00
|
|
|
if( $row ) {
|
2008-05-22 16:47:12 +00:00
|
|
|
$this->mTitle = Title::makeTitle( $row->page_namespace,
|
|
|
|
|
$row->page_title );
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
|
|
|
|
return $this->mTitle;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-06-11 04:48:27 +00:00
|
|
|
/**
|
|
|
|
|
* Set the title of the revision
|
|
|
|
|
* @param Title $title
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function setTitle( $title ) {
|
2006-06-11 04:48:27 +00:00
|
|
|
$this->mTitle = $title;
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-12 12:50:43 +00:00
|
|
|
/**
|
2008-04-07 23:53:57 +00:00
|
|
|
* Get the page ID
|
2005-03-12 12:50:43 +00:00
|
|
|
* @return int
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getPage() {
|
2005-03-12 12:50:43 +00:00
|
|
|
return $this->mPage;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
2008-09-24 09:44:45 +00:00
|
|
|
* Fetch revision's user id if it's available to the specified audience.
|
|
|
|
|
* If the specified audience does not have access to it, zero will be
|
|
|
|
|
* returned.
|
|
|
|
|
*
|
|
|
|
|
* @param integer $audience One of:
|
|
|
|
|
* Revision::FOR_PUBLIC to be displayed to all users
|
|
|
|
|
* Revision::FOR_THIS_USER to be displayed to $wgUser
|
|
|
|
|
* Revision::RAW get the ID regardless of permissions
|
|
|
|
|
*
|
|
|
|
|
*
|
2004-12-19 12:21:29 +00:00
|
|
|
* @return int
|
|
|
|
|
*/
|
2008-09-24 09:44:45 +00:00
|
|
|
public function getUser( $audience = self::FOR_PUBLIC ) {
|
|
|
|
|
if( $audience == self::FOR_PUBLIC && $this->isDeleted( self::DELETED_USER ) ) {
|
2008-09-22 14:37:05 +00:00
|
|
|
return 0;
|
2008-09-24 09:44:45 +00:00
|
|
|
} elseif( $audience == self::FOR_THIS_USER && !$this->userCan( self::DELETED_USER ) ) {
|
2006-03-16 19:04:25 +00:00
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return $this->mUser;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Fetch revision's user id without regard for the current user's permissions
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getRawUser() {
|
2004-12-19 12:21:29 +00:00
|
|
|
return $this->mUser;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
2008-09-24 09:44:45 +00:00
|
|
|
* Fetch revision's username if it's available to the specified audience.
|
|
|
|
|
* If the specified audience does not have access to the username, an
|
|
|
|
|
* empty string will be returned.
|
|
|
|
|
*
|
|
|
|
|
* @param integer $audience One of:
|
|
|
|
|
* Revision::FOR_PUBLIC to be displayed to all users
|
|
|
|
|
* Revision::FOR_THIS_USER to be displayed to $wgUser
|
|
|
|
|
* Revision::RAW get the text regardless of permissions
|
|
|
|
|
*
|
2004-12-19 12:21:29 +00:00
|
|
|
* @return string
|
|
|
|
|
*/
|
2008-09-24 09:44:45 +00:00
|
|
|
public function getUserText( $audience = self::FOR_PUBLIC ) {
|
|
|
|
|
if( $audience == self::FOR_PUBLIC && $this->isDeleted( self::DELETED_USER ) ) {
|
2008-09-22 14:37:05 +00:00
|
|
|
return "";
|
2008-09-24 09:44:45 +00:00
|
|
|
} elseif( $audience == self::FOR_THIS_USER && !$this->userCan( self::DELETED_USER ) ) {
|
2008-03-18 23:07:19 +00:00
|
|
|
return "";
|
2006-03-16 19:04:25 +00:00
|
|
|
} else {
|
|
|
|
|
return $this->mUserText;
|
|
|
|
|
}
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
2006-03-16 19:04:25 +00:00
|
|
|
* Fetch revision's username without regard for view restrictions
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getRawUserText() {
|
2006-03-16 19:04:25 +00:00
|
|
|
return $this->mUserText;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-03-16 19:04:25 +00:00
|
|
|
/**
|
2008-09-24 09:44:45 +00:00
|
|
|
* 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 integer $audience One of:
|
|
|
|
|
* Revision::FOR_PUBLIC to be displayed to all users
|
|
|
|
|
* Revision::FOR_THIS_USER to be displayed to $wgUser
|
|
|
|
|
* Revision::RAW get the text regardless of permissions
|
|
|
|
|
*
|
2004-12-19 12:21:29 +00:00
|
|
|
* @return string
|
|
|
|
|
*/
|
2008-09-24 09:44:45 +00:00
|
|
|
function getComment( $audience = self::FOR_PUBLIC ) {
|
|
|
|
|
if( $audience == self::FOR_PUBLIC && $this->isDeleted( self::DELETED_COMMENT ) ) {
|
2008-09-22 14:37:05 +00:00
|
|
|
return "";
|
2008-09-24 09:44:45 +00:00
|
|
|
} elseif( $audience == self::FOR_THIS_USER && !$this->userCan( self::DELETED_COMMENT ) ) {
|
2008-03-18 23:07:19 +00:00
|
|
|
return "";
|
2006-03-16 19:04:25 +00:00
|
|
|
} else {
|
|
|
|
|
return $this->mComment;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Fetch revision comment without regard for the current user's permissions
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getRawComment() {
|
2004-12-19 12:21:29 +00:00
|
|
|
return $this->mComment;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function isMinor() {
|
2004-12-19 12:21:29 +00:00
|
|
|
return (bool)$this->mMinorEdit;
|
|
|
|
|
}
|
2009-01-15 17:53:19 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return int rcid of the unpatrolled row, zero if there isn't one
|
|
|
|
|
*/
|
|
|
|
|
public function isUnpatrolled() {
|
|
|
|
|
if( $this->mUnpatrolled !== NULL ) {
|
|
|
|
|
return $this->mUnpatrolled;
|
|
|
|
|
}
|
|
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
|
$this->mUnpatrolled = $dbr->selectField( 'recentchanges',
|
|
|
|
|
'rc_id',
|
|
|
|
|
array( // Add redundant user,timestamp condition so we can use the existing index
|
|
|
|
|
'rc_user_text' => $this->getRawUserText(),
|
|
|
|
|
'rc_timestamp' => $dbr->timestamp( $this->getTimestamp() ),
|
|
|
|
|
'rc_this_oldid' => $this->getId(),
|
|
|
|
|
'rc_patrolled' => 0
|
|
|
|
|
),
|
|
|
|
|
__METHOD__
|
|
|
|
|
);
|
|
|
|
|
return (int)$this->mUnpatrolled;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-31 11:40:05 +00:00
|
|
|
/**
|
2006-06-23 06:31:46 +00:00
|
|
|
* int $field one of DELETED_* bitfield constants
|
2005-03-31 11:40:05 +00:00
|
|
|
* @return bool
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function isDeleted( $field ) {
|
2006-03-16 19:04:25 +00:00
|
|
|
return ($this->mDeleted & $field) == $field;
|
2005-03-31 11:40:05 +00:00
|
|
|
}
|
2008-10-19 05:47:23 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the deletion bitfield of the revision
|
|
|
|
|
*/
|
|
|
|
|
public function getVisibility() {
|
|
|
|
|
return (int)$this->mDeleted;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
2008-09-24 09:44:45 +00:00
|
|
|
* Fetch revision text if it's available to the specified audience.
|
|
|
|
|
* If the specified audience does not have the ability to view this
|
|
|
|
|
* revision, an empty string will be returned.
|
|
|
|
|
*
|
|
|
|
|
* @param integer $audience One of:
|
|
|
|
|
* Revision::FOR_PUBLIC to be displayed to all users
|
|
|
|
|
* Revision::FOR_THIS_USER to be displayed to $wgUser
|
|
|
|
|
* Revision::RAW get the text regardless of permissions
|
|
|
|
|
*
|
|
|
|
|
*
|
2004-12-19 12:21:29 +00:00
|
|
|
* @return string
|
|
|
|
|
*/
|
2008-09-24 09:44:45 +00:00
|
|
|
public function getText( $audience = self::FOR_PUBLIC ) {
|
|
|
|
|
if( $audience == self::FOR_PUBLIC && $this->isDeleted( self::DELETED_TEXT ) ) {
|
2008-09-22 14:24:18 +00:00
|
|
|
return "";
|
2008-09-24 09:44:45 +00:00
|
|
|
} elseif( $audience == self::FOR_THIS_USER && !$this->userCan( self::DELETED_TEXT ) ) {
|
2008-03-18 23:07:19 +00:00
|
|
|
return "";
|
2006-03-16 19:04:25 +00:00
|
|
|
} else {
|
|
|
|
|
return $this->getRawText();
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-09-24 09:44:45 +00:00
|
|
|
/**
|
|
|
|
|
* Alias for getText(Revision::FOR_THIS_USER)
|
|
|
|
|
*/
|
|
|
|
|
public function revText() {
|
|
|
|
|
return $this->getText( self::FOR_THIS_USER );
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-16 19:04:25 +00:00
|
|
|
/**
|
|
|
|
|
* Fetch revision text without regard for view restrictions
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getRawText() {
|
2005-03-18 04:32:55 +00:00
|
|
|
if( is_null( $this->mText ) ) {
|
|
|
|
|
// Revision text is immutable. Load on demand:
|
|
|
|
|
$this->mText = $this->loadText();
|
|
|
|
|
}
|
2004-12-19 12:21:29 +00:00
|
|
|
return $this->mText;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getTimestamp() {
|
2005-08-02 13:35:19 +00:00
|
|
|
return wfTimestamp(TS_MW, $this->mTimestamp);
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function isCurrent() {
|
2004-12-19 12:21:29 +00:00
|
|
|
return $this->mCurrent;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
/**
|
2008-04-07 23:53:57 +00:00
|
|
|
* Get previous revision for this title
|
2004-12-19 12:21:29 +00:00
|
|
|
* @return Revision
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getPrevious() {
|
2008-05-22 16:47:12 +00:00
|
|
|
if( $this->getTitle() ) {
|
|
|
|
|
$prev = $this->getTitle()->getPreviousRevisionID( $this->getId() );
|
|
|
|
|
if( $prev ) {
|
|
|
|
|
return Revision::newFromTitle( $this->getTitle(), $prev );
|
|
|
|
|
}
|
2006-01-19 17:12:37 +00:00
|
|
|
}
|
2008-05-22 16:47:12 +00:00
|
|
|
return null;
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return Revision
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function getNext() {
|
2008-05-22 16:47:12 +00:00
|
|
|
if( $this->getTitle() ) {
|
|
|
|
|
$next = $this->getTitle()->getNextRevisionID( $this->getId() );
|
|
|
|
|
if ( $next ) {
|
|
|
|
|
return Revision::newFromTitle( $this->getTitle(), $next );
|
|
|
|
|
}
|
2006-01-19 17:12:37 +00:00
|
|
|
}
|
2008-05-22 16:47:12 +00:00
|
|
|
return null;
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-04-07 23:53:57 +00:00
|
|
|
/**
|
|
|
|
|
* Get previous revision Id for this page_id
|
|
|
|
|
* This is used to populate rev_parent_id on save
|
|
|
|
|
* @param Database $db
|
|
|
|
|
* @return int
|
|
|
|
|
*/
|
|
|
|
|
private function getPreviousRevisionId( $db ) {
|
|
|
|
|
if( is_null($this->mPage) ) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
# Use page_latest if ID is not given
|
|
|
|
|
if( !$this->mId ) {
|
2008-04-08 07:41:01 +00:00
|
|
|
$prevId = $db->selectField( 'page', 'page_latest',
|
2008-04-07 23:53:57 +00:00
|
|
|
array( 'page_id' => $this->mPage ),
|
|
|
|
|
__METHOD__ );
|
|
|
|
|
} else {
|
2008-04-08 00:13:46 +00:00
|
|
|
$prevId = $db->selectField( 'revision', 'rev_id',
|
|
|
|
|
array( 'rev_page' => $this->mPage, 'rev_id < ' . $this->mId ),
|
|
|
|
|
__METHOD__,
|
|
|
|
|
array( 'ORDER BY' => 'rev_id DESC' ) );
|
2008-04-07 23:53:57 +00:00
|
|
|
}
|
|
|
|
|
return intval($prevId);
|
|
|
|
|
}
|
2004-12-19 12:21:29 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get revision text associated with an old or archive row
|
|
|
|
|
* $row is usually an object from wfFetchRow(), both the flags and the text
|
|
|
|
|
* field must be included
|
2008-04-01 15:13:44 +00:00
|
|
|
*
|
2008-10-28 14:55:42 +00:00
|
|
|
* @param object $row The text data
|
2004-12-19 12:21:29 +00:00
|
|
|
* @param string $prefix table prefix (default 'old_')
|
|
|
|
|
* @return string $text|false the text requested
|
|
|
|
|
*/
|
2007-01-07 18:52:45 +00:00
|
|
|
public static function getRevisionText( $row, $prefix = 'old_' ) {
|
2008-04-01 15:13:44 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
# Get data
|
|
|
|
|
$textField = $prefix . 'text';
|
|
|
|
|
$flagsField = $prefix . 'flags';
|
|
|
|
|
|
|
|
|
|
if( isset( $row->$flagsField ) ) {
|
|
|
|
|
$flags = explode( ',', $row->$flagsField );
|
|
|
|
|
} else {
|
|
|
|
|
$flags = array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( isset( $row->$textField ) ) {
|
|
|
|
|
$text = $row->$textField;
|
|
|
|
|
} else {
|
2008-04-01 15:13:44 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2004-12-19 12:21:29 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-18 17:21:27 +00:00
|
|
|
# Use external methods for external objects, text in table is URL-only then
|
|
|
|
|
if ( in_array( 'external', $flags ) ) {
|
|
|
|
|
$url=$text;
|
2006-11-29 11:43:58 +00:00
|
|
|
@list(/* $proto */,$path)=explode('://',$url,2);
|
2005-04-18 17:21:27 +00:00
|
|
|
if ($path=="") {
|
2008-04-01 15:13:44 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-04-18 17:21:27 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
$text=ExternalStore::fetchFromURL($url);
|
|
|
|
|
}
|
|
|
|
|
|
2006-01-19 03:59:20 +00:00
|
|
|
// If the text was fetched without an error, convert it
|
|
|
|
|
if ( $text !== false ) {
|
|
|
|
|
if( in_array( 'gzip', $flags ) ) {
|
|
|
|
|
# Deal with optional compression of archived pages.
|
|
|
|
|
# This can be done periodically via maintenance/compressOld.php, and
|
|
|
|
|
# as pages are saved if $wgCompressRevisions is set.
|
|
|
|
|
$text = gzinflate( $text );
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
|
|
|
|
|
2006-01-19 03:59:20 +00:00
|
|
|
if( in_array( 'object', $flags ) ) {
|
|
|
|
|
# Generic compressed storage
|
|
|
|
|
$obj = unserialize( $text );
|
2006-04-24 03:29:27 +00:00
|
|
|
if ( !is_object( $obj ) ) {
|
|
|
|
|
// Invalid object
|
2008-04-01 15:13:44 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2006-04-24 03:29:27 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2006-01-19 03:59:20 +00:00
|
|
|
$text = $obj->getText();
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-01-19 03:59:20 +00:00
|
|
|
global $wgLegacyEncoding;
|
2008-12-30 21:43:54 +00:00
|
|
|
if( $wgLegacyEncoding && !in_array( 'utf-8', $flags ) && !in_array( 'utf8', $flags ) ) {
|
2006-01-19 03:59:20 +00:00
|
|
|
# Old revisions kept around in a legacy encoding?
|
|
|
|
|
# Upconvert on demand.
|
2008-12-30 21:43:54 +00:00
|
|
|
# ("utf8" checked for compatibility with some broken
|
|
|
|
|
# conversion scripts 2008-12-30)
|
2006-01-19 03:59:20 +00:00
|
|
|
global $wgInputEncoding, $wgContLang;
|
2007-03-16 13:04:57 +00:00
|
|
|
$text = $wgContLang->iconv( $wgLegacyEncoding, $wgInputEncoding, $text );
|
2006-01-19 03:59:20 +00:00
|
|
|
}
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2008-04-01 15:13:44 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2004-12-19 12:21:29 +00:00
|
|
|
return $text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* If $wgCompressRevisions is enabled, we will compress data.
|
|
|
|
|
* The input string is modified in place.
|
|
|
|
|
* Return value is the flags field: contains 'gzip' if the
|
|
|
|
|
* data is compressed, and 'utf-8' if we're saving in UTF-8
|
|
|
|
|
* mode.
|
|
|
|
|
*
|
|
|
|
|
* @param mixed $text reference to a text
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public static function compressRevisionText( &$text ) {
|
2005-03-26 22:23:48 +00:00
|
|
|
global $wgCompressRevisions;
|
2004-12-19 12:21:29 +00:00
|
|
|
$flags = array();
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-26 22:23:48 +00:00
|
|
|
# Revisions not marked this way will be converted
|
|
|
|
|
# on load if $wgLegacyCharset is set in the future.
|
|
|
|
|
$flags[] = 'utf-8';
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2004-12-19 12:21:29 +00:00
|
|
|
if( $wgCompressRevisions ) {
|
|
|
|
|
if( function_exists( 'gzdeflate' ) ) {
|
|
|
|
|
$text = gzdeflate( $text );
|
|
|
|
|
$flags[] = 'gzip';
|
|
|
|
|
} else {
|
|
|
|
|
wfDebug( "Revision::compressRevisionText() -- no zlib support, not compressing\n" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return implode( ',', $flags );
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-11 06:00:05 +00:00
|
|
|
/**
|
|
|
|
|
* Insert a new revision into the database, returning the new revision ID
|
|
|
|
|
* number on success and dies horribly on failure.
|
|
|
|
|
*
|
|
|
|
|
* @param Database $dbw
|
|
|
|
|
* @return int
|
|
|
|
|
*/
|
2008-05-23 07:33:35 +00:00
|
|
|
public function insertOn( $dbw ) {
|
2006-01-09 03:16:56 +00:00
|
|
|
global $wgDefaultExternalStore;
|
2008-04-01 15:13:44 +00:00
|
|
|
|
|
|
|
|
wfProfileIn( __METHOD__ );
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-01-09 03:16:56 +00:00
|
|
|
$data = $this->mText;
|
|
|
|
|
$flags = Revision::compressRevisionText( $data );
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-01-09 03:16:56 +00:00
|
|
|
# Write to external storage if required
|
2008-09-28 01:42:55 +00:00
|
|
|
if( $wgDefaultExternalStore ) {
|
2006-01-09 03:16:56 +00:00
|
|
|
// Store and get the URL
|
2008-09-24 20:30:10 +00:00
|
|
|
$data = ExternalStore::insertToDefault( $data );
|
2008-09-28 01:42:55 +00:00
|
|
|
if( !$data ) {
|
|
|
|
|
throw new MWException( "Unable to store text to external storage" );
|
|
|
|
|
}
|
|
|
|
|
if( $flags ) {
|
2006-01-09 03:16:56 +00:00
|
|
|
$flags .= ',';
|
|
|
|
|
}
|
|
|
|
|
$flags .= 'external';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Record the text (or external storage URL) to the text table
|
2005-03-28 10:47:12 +00:00
|
|
|
if( !isset( $this->mTextId ) ) {
|
|
|
|
|
$old_id = $dbw->nextSequenceValue( 'text_old_id_val' );
|
|
|
|
|
$dbw->insert( 'text',
|
|
|
|
|
array(
|
|
|
|
|
'old_id' => $old_id,
|
2006-01-09 03:16:56 +00:00
|
|
|
'old_text' => $data,
|
2005-03-28 10:47:12 +00:00
|
|
|
'old_flags' => $flags,
|
2008-04-01 15:13:44 +00:00
|
|
|
), __METHOD__
|
2005-03-28 10:47:12 +00:00
|
|
|
);
|
|
|
|
|
$this->mTextId = $dbw->insertId();
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-11 06:00:05 +00:00
|
|
|
# Record the edit in revisions
|
2005-03-28 10:47:12 +00:00
|
|
|
$rev_id = isset( $this->mId )
|
|
|
|
|
? $this->mId
|
|
|
|
|
: $dbw->nextSequenceValue( 'rev_rev_id_val' );
|
2005-03-11 06:00:05 +00:00
|
|
|
$dbw->insert( 'revision',
|
|
|
|
|
array(
|
2005-03-28 10:47:12 +00:00
|
|
|
'rev_id' => $rev_id,
|
2005-03-11 06:00:05 +00:00
|
|
|
'rev_page' => $this->mPage,
|
2005-03-28 10:47:12 +00:00
|
|
|
'rev_text_id' => $this->mTextId,
|
2005-03-11 06:00:05 +00:00
|
|
|
'rev_comment' => $this->mComment,
|
|
|
|
|
'rev_minor_edit' => $this->mMinorEdit ? 1 : 0,
|
|
|
|
|
'rev_user' => $this->mUser,
|
|
|
|
|
'rev_user_text' => $this->mUserText,
|
|
|
|
|
'rev_timestamp' => $dbw->timestamp( $this->mTimestamp ),
|
2005-03-31 11:40:05 +00:00
|
|
|
'rev_deleted' => $this->mDeleted,
|
2007-03-15 00:48:38 +00:00
|
|
|
'rev_len' => $this->mSize,
|
2009-01-15 17:48:14 +00:00
|
|
|
'rev_parent_id' => is_null($this->mParentId) ?
|
|
|
|
|
$this->getPreviousRevisionId( $dbw ) : $this->mParentId
|
2008-04-01 15:13:44 +00:00
|
|
|
), __METHOD__
|
2005-03-11 06:00:05 +00:00
|
|
|
);
|
2005-08-02 13:35:19 +00:00
|
|
|
|
|
|
|
|
$this->mId = !is_null($rev_id) ? $rev_id : $dbw->insertId();
|
2008-04-15 15:38:08 +00:00
|
|
|
|
2008-07-10 18:04:32 +00:00
|
|
|
wfRunHooks( 'RevisionInsertComplete', array( &$this, $data, $flags ) );
|
2008-04-15 15:38:08 +00:00
|
|
|
|
2008-04-01 15:13:44 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-03-28 10:47:12 +00:00
|
|
|
return $this->mId;
|
2005-03-11 06:00:05 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-18 04:32:55 +00:00
|
|
|
/**
|
|
|
|
|
* Lazy-load the revision's text.
|
|
|
|
|
* Currently hardcoded to the 'text' table storage engine.
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
private function loadText() {
|
2008-04-01 15:13:44 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-09-18 18:10:20 +00:00
|
|
|
// Caching may be beneficial for massive use of external storage
|
2006-10-04 09:06:18 +00:00
|
|
|
global $wgRevisionCacheExpiry, $wgMemc;
|
|
|
|
|
$key = wfMemcKey( 'revisiontext', 'textid', $this->getTextId() );
|
2006-09-18 18:10:20 +00:00
|
|
|
if( $wgRevisionCacheExpiry ) {
|
|
|
|
|
$text = $wgMemc->get( $key );
|
|
|
|
|
if( is_string( $text ) ) {
|
2008-04-01 15:13:44 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2006-09-18 18:10:20 +00:00
|
|
|
return $text;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-09-18 17:52:44 +00:00
|
|
|
// If we kept data for lazy extraction, use it now...
|
2006-10-03 13:00:52 +00:00
|
|
|
if ( isset( $this->mTextRow ) ) {
|
|
|
|
|
$row = $this->mTextRow;
|
|
|
|
|
$this->mTextRow = null;
|
|
|
|
|
} else {
|
|
|
|
|
$row = null;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-09-18 17:52:44 +00:00
|
|
|
if( !$row ) {
|
|
|
|
|
// Text data is immutable; check slaves first.
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2006-09-18 17:52:44 +00:00
|
|
|
$row = $dbr->selectRow( 'text',
|
|
|
|
|
array( 'old_text', 'old_flags' ),
|
|
|
|
|
array( 'old_id' => $this->getTextId() ),
|
2008-04-01 15:13:44 +00:00
|
|
|
__METHOD__ );
|
2006-09-18 17:52:44 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-09-26 02:42:30 +00:00
|
|
|
if( !$row && wfGetLB()->getServerCount() > 1 ) {
|
2006-09-18 17:52:44 +00:00
|
|
|
// Possible slave lag!
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-06-27 03:48:05 +00:00
|
|
|
$row = $dbw->selectRow( 'text',
|
|
|
|
|
array( 'old_text', 'old_flags' ),
|
|
|
|
|
array( 'old_id' => $this->getTextId() ),
|
2008-04-01 15:13:44 +00:00
|
|
|
__METHOD__ );
|
2005-06-27 03:48:05 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-04-01 15:13:44 +00:00
|
|
|
$text = self::getRevisionText( $row );
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-07-28 10:16:12 +00:00
|
|
|
# No negative caching -- negative hits on text rows may be due to corrupted slave servers
|
|
|
|
|
if( $wgRevisionCacheExpiry && $text !== false ) {
|
2006-09-18 18:10:20 +00:00
|
|
|
$wgMemc->set( $key, $text, $wgRevisionCacheExpiry );
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-04-01 15:13:44 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-18 04:32:55 +00:00
|
|
|
return $text;
|
|
|
|
|
}
|
2005-03-28 10:47:12 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create a new null-revision for insertion into a page's
|
|
|
|
|
* history. This will not re-save the text, but simply refer
|
|
|
|
|
* to the text from the previous version.
|
|
|
|
|
*
|
|
|
|
|
* Such revisions can for instance identify page rename
|
|
|
|
|
* operations and other such meta-modifications.
|
|
|
|
|
*
|
|
|
|
|
* @param Database $dbw
|
|
|
|
|
* @param int $pageId ID number of the page to read from
|
|
|
|
|
* @param string $summary
|
|
|
|
|
* @param bool $minor
|
|
|
|
|
* @return Revision
|
|
|
|
|
*/
|
2008-05-23 07:33:35 +00:00
|
|
|
public static function newNullRevision( $dbw, $pageId, $summary, $minor ) {
|
2007-11-10 13:38:37 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-28 10:47:12 +00:00
|
|
|
$current = $dbw->selectRow(
|
|
|
|
|
array( 'page', 'revision' ),
|
2008-12-21 22:35:52 +00:00
|
|
|
array( 'page_latest', 'rev_text_id', 'rev_len' ),
|
2005-03-28 10:47:12 +00:00
|
|
|
array(
|
|
|
|
|
'page_id' => $pageId,
|
|
|
|
|
'page_latest=rev_id',
|
|
|
|
|
),
|
2007-11-10 13:38:37 +00:00
|
|
|
__METHOD__ );
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-03-28 10:47:12 +00:00
|
|
|
if( $current ) {
|
|
|
|
|
$revision = new Revision( array(
|
|
|
|
|
'page' => $pageId,
|
|
|
|
|
'comment' => $summary,
|
|
|
|
|
'minor_edit' => $minor,
|
|
|
|
|
'text_id' => $current->rev_text_id,
|
2008-12-21 22:35:52 +00:00
|
|
|
'parent_id' => $current->page_latest,
|
|
|
|
|
'len' => $current->rev_len
|
2005-03-28 10:47:12 +00:00
|
|
|
) );
|
|
|
|
|
} else {
|
|
|
|
|
$revision = null;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2007-11-10 13:38:37 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-03-28 10:47:12 +00:00
|
|
|
return $revision;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-03-16 19:04:25 +00:00
|
|
|
/**
|
|
|
|
|
* Determine if the current user is allowed to view a particular
|
|
|
|
|
* field of this revision, if it's marked as deleted.
|
2006-06-23 06:31:46 +00:00
|
|
|
* @param int $field one of self::DELETED_TEXT,
|
|
|
|
|
* self::DELETED_COMMENT,
|
|
|
|
|
* self::DELETED_USER
|
2006-03-16 19:04:25 +00:00
|
|
|
* @return bool
|
|
|
|
|
*/
|
2008-04-07 23:53:57 +00:00
|
|
|
public function userCan( $field ) {
|
2006-03-16 19:04:25 +00:00
|
|
|
if( ( $this->mDeleted & $field ) == $field ) {
|
|
|
|
|
global $wgUser;
|
2006-06-23 06:31:46 +00:00
|
|
|
$permission = ( $this->mDeleted & self::DELETED_RESTRICTED ) == self::DELETED_RESTRICTED
|
2008-05-25 00:31:28 +00:00
|
|
|
? 'suppressrevision'
|
2006-03-16 19:04:25 +00:00
|
|
|
: 'deleterevision';
|
|
|
|
|
wfDebug( "Checking for $permission due to $field match on $this->mDeleted\n" );
|
|
|
|
|
return $wgUser->isAllowed( $permission );
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-06-23 06:31:46 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get rev_timestamp from rev_id, without loading the rest of the row
|
2008-10-30 10:04:30 +00:00
|
|
|
* @param Title $title
|
2006-06-23 06:31:46 +00:00
|
|
|
* @param integer $id
|
|
|
|
|
*/
|
2008-10-30 10:04:30 +00:00
|
|
|
static function getTimestampFromId( $title, $id ) {
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2009-01-14 22:20:15 +00:00
|
|
|
// Casting fix for DB2
|
|
|
|
|
if ($id == '') {
|
|
|
|
|
$id = 0;
|
|
|
|
|
}
|
2008-05-22 15:15:00 +00:00
|
|
|
$conds = array( 'rev_id' => $id );
|
2008-10-30 10:04:30 +00:00
|
|
|
$conds['rev_page'] = $title->getArticleId();
|
2008-05-22 15:15:00 +00:00
|
|
|
$timestamp = $dbr->selectField( 'revision', 'rev_timestamp', $conds, __METHOD__ );
|
2008-09-26 02:42:30 +00:00
|
|
|
if ( $timestamp === false && wfGetLB()->getServerCount() > 1 ) {
|
2006-06-23 06:31:46 +00:00
|
|
|
# Not in slave, try master
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2008-05-22 15:15:00 +00:00
|
|
|
$timestamp = $dbw->selectField( 'revision', 'rev_timestamp', $conds, __METHOD__ );
|
2006-06-23 06:31:46 +00:00
|
|
|
}
|
2008-07-09 17:41:02 +00:00
|
|
|
return wfTimestamp( TS_MW, $timestamp );
|
2006-06-23 06:31:46 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-04-07 23:53:57 +00:00
|
|
|
/**
|
|
|
|
|
* Get count of revisions per page...not very efficient
|
|
|
|
|
* @param Database $db
|
|
|
|
|
* @param int $id, page id
|
|
|
|
|
*/
|
2006-06-27 21:48:43 +00:00
|
|
|
static function countByPageId( $db, $id ) {
|
|
|
|
|
$row = $db->selectRow( 'revision', 'COUNT(*) AS revCount',
|
|
|
|
|
array( 'rev_page' => $id ), __METHOD__ );
|
|
|
|
|
if( $row ) {
|
|
|
|
|
return $row->revCount;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-04-07 23:53:57 +00:00
|
|
|
/**
|
|
|
|
|
* Get count of revisions per page...not very efficient
|
|
|
|
|
* @param Database $db
|
|
|
|
|
* @param Title $title
|
|
|
|
|
*/
|
2006-06-27 21:48:43 +00:00
|
|
|
static function countByTitle( $db, $title ) {
|
|
|
|
|
$id = $title->getArticleId();
|
|
|
|
|
if( $id ) {
|
|
|
|
|
return Revision::countByPageId( $db, $id );
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2004-12-19 12:21:29 +00:00
|
|
|
}
|
2006-03-16 19:04:25 +00:00
|
|
|
|
2006-06-23 06:31:46 +00:00
|
|
|
/**
|
|
|
|
|
* 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 );
|