8 require_once( 'Database.php' );
9 require_once( 'Article.php' );
17 * Load a page revision from a given revision ID number.
18 * Returns null if no such revision can be found.
24 function &newFromId( $id ) {
25 return Revision
::newFromConds(
26 array( 'page_id=rev_page',
27 'rev_id' => IntVal( $id ),
32 * Load either the current, or a specified, revision
33 * that's attached to a given title. If not attached
34 * to that title, will return null.
41 function &newFromTitle( &$title, $id = 0 ) {
43 $matchId = IntVal( $id );
45 $matchId = 'page_latest';
47 return Revision
::newFromConds(
48 array( "rev_id=$matchId",
50 'page_namespace' => $title->getNamespace(),
51 'page_title' => $title->getDbkey(),
56 * Given a set of conditions, fetch a revision.
58 * @param array $conditions
63 function &newFromConds( $conditions ) {
64 $res =& Revision
::fetchFromConds( $conditions );
66 $row = $res->fetchObject();
69 return new Revision( $row );
76 * Return a wrapper for a series of database rows to
77 * fetch all of a given page's revisions in turn.
78 * Each row can be fed to the constructor to get objects.
81 * @return ResultWrapper
85 function &fetchAllRevisions( &$title ) {
86 return Revision
::fetchFromConds(
87 array( 'page_namespace' => $title->getNamespace(),
88 'page_title' => $title->getDbkey(),
94 * Return a wrapper for a series of database rows to
95 * fetch all of a given page's revisions in turn.
96 * Each row can be fed to the constructor to get objects.
99 * @return ResultWrapper
103 function &fetchRevision( &$title ) {
104 return Revision
::fetchFromConds(
105 array( 'rev_id=page_latest',
106 'page_namespace' => $title->getNamespace(),
107 'page_title' => $title->getDbkey(),
112 * Given a set of conditions, return a ResultWrapper
113 * which will return matching database rows with the
114 * fields necessary to build Revision objects.
116 * @param array $conditions
117 * @return ResultWrapper
121 function &fetchFromConds( $conditions ) {
122 $dbr =& wfGetDB( DB_SLAVE
);
124 array( 'page', 'revision', 'text' ),
125 array( 'page_namespace',
138 'Revision::fetchRow' );
139 return $dbr->resultObject( $res );
146 function Revision( $row ) {
147 if( is_object( $row ) ) {
148 $this->mId
= IntVal( $row->rev_id
);
149 $this->mPage
= IntVal( $row->rev_page
);
150 $this->mComment
= $row->rev_comment
;
151 $this->mUserText
= $row->rev_user_text
;
152 $this->mUser
= IntVal( $row->rev_user
);
153 $this->mMinorEdit
= IntVal( $row->rev_minor_edit
);
154 $this->mTimestamp
= $row->rev_timestamp
;
156 $this->mCurrent
= ( $row->rev_id
== $row->page_latest
);
157 $this->mTitle
= Title
::makeTitle( $row->page_namespace
,
159 $this->mText
= $this->getRevisionText( $row );
160 } elseif( is_array( $row ) ) {
161 // Build a new revision to be saved...
164 $this->mId
= isset( $row['id'] ) ?
IntVal( $row['id'] ) : null;
165 $this->mPage
= isset( $row['page'] ) ?
IntVal( $row['page'] ) : null;
166 $this->mComment
= isset( $row['comment'] ) ?
StrVal( $row['comment'] ) : null;
167 $this->mUserText
= isset( $row['user_text'] ) ?
StrVal( $row['user_text'] ) : $wgUser->getName();
168 $this->mUser
= isset( $row['user'] ) ?
IntVal( $row['user'] ) : $wgUser->getId();
169 $this->mMinorEdit
= isset( $row['minor_edit'] ) ?
IntVal( $row['minor_edit'] ) : 0;
170 $this->mTimestamp
= isset( $row['timestamp'] ) ?
StrVal( $row['timestamp'] ) : wfTimestamp( TS_MW
);
171 $this->mText
= isset( $row['text'] ) ?
StrVal( $row['text'] ) : '';
173 $this->mTitle
= null; # Load on demand if needed
174 $this->mCurrent
= false;
176 wfDebugDieBacktrace( 'Revision constructor passed invalid row format.' );
192 * Returns the title of the page associated with this entry.
195 function &getTitle() {
196 if( isset( $this->mTitle
) ) {
197 return $this->mTitle
;
199 $dbr =& wfGetDB( DB_SLAVE
);
200 $row = $dbr->selectRow(
201 array( 'page', 'revision' ),
202 array( 'page_namespace', 'page_title' ),
203 array( 'page_id=rev_page',
204 'rev_id' => $this->mId
),
205 'Revision::getTItle' );
207 $this->mTitle
=& Title
::makeTitle( $row->page_namespace
,
210 return $this->mTitle
;
230 function getUserText() {
231 return $this->mUserText
;
237 function getComment() {
238 return $this->mComment
;
245 return (bool)$this->mMinorEdit
;
258 function getTimestamp() {
259 return $this->mTimestamp
;
265 function isCurrent() {
266 return $this->mCurrent
;
272 function &getPrevious() {
273 $prev = $this->mTitle
->getPreviousRevisionID( $this->mId
);
274 return Revision
::newFromTitle( $this->mTitle
, $prev );
280 function &getNext() {
281 $next = $this->mTitle
->getNextRevisionID( $this->mId
);
282 return Revision
::newFromTitle( $this->mTitle
, $next );
287 * Get revision text associated with an old or archive row
288 * $row is usually an object from wfFetchRow(), both the flags and the text
289 * field must be included
291 * @param integer $row Id of a row
292 * @param string $prefix table prefix (default 'old_')
293 * @return string $text|false the text requested
295 function getRevisionText( $row, $prefix = 'old_' ) {
296 $fname = 'Revision::getRevisionText';
297 wfProfileIn( $fname );
300 $textField = $prefix . 'text';
301 $flagsField = $prefix . 'flags';
303 if( isset( $row->$flagsField ) ) {
304 $flags = explode( ',', $row->$flagsField );
309 if( isset( $row->$textField ) ) {
310 $text = $row->$textField;
312 wfProfileOut( $fname );
316 if( in_array( 'gzip', $flags ) ) {
317 # Deal with optional compression of archived pages.
318 # This can be done periodically via maintenance/compressOld.php, and
319 # as pages are saved if $wgCompressRevisions is set.
320 $text = gzinflate( $text );
323 if( in_array( 'object', $flags ) ) {
324 # Generic compressed storage
325 $obj = unserialize( $text );
327 # Bugger, corrupted my test database by double-serializing
328 if ( !is_object( $obj ) ) {
329 $obj = unserialize( $obj );
332 $text = $obj->getText();
335 global $wgLegacyEncoding;
336 if( $wgLegacyEncoding && !in_array( 'utf-8', $flags ) ) {
337 # Old revisions kept around in a legacy encoding?
338 # Upconvert on demand.
339 global $wgInputEncoding, $wgContLang;
340 $text = $wgContLang->iconv( $wgLegacyEncoding, $wgInputEncoding, $text );
342 wfProfileOut( $fname );
347 * If $wgCompressRevisions is enabled, we will compress data.
348 * The input string is modified in place.
349 * Return value is the flags field: contains 'gzip' if the
350 * data is compressed, and 'utf-8' if we're saving in UTF-8
354 * @param mixed $text reference to a text
357 function compressRevisionText( &$text ) {
358 global $wgCompressRevisions, $wgUseLatin1;
360 if( !$wgUseLatin1 ) {
361 # Revisions not marked this way will be converted
362 # on load if $wgLegacyCharset is set in the future.
365 if( $wgCompressRevisions ) {
366 if( function_exists( 'gzdeflate' ) ) {
367 $text = gzdeflate( $text );
370 wfDebug( "Revision::compressRevisionText() -- no zlib support, not compressing\n" );
373 return implode( ',', $flags );
377 * Insert a new revision into the database, returning the new revision ID
378 * number on success and dies horribly on failure.
380 * @param Database $dbw
383 function insertOn( &$dbw ) {
384 $fname = 'Revision::insertOn';
385 wfProfileIn( $fname );
387 $mungedText = $this->mText
;
388 $flags = Revision
::compressRevisionText( $mungedText );
390 # Record the text to the text table
391 $old_id = isset( $this->mId
)
393 : $dbw->nextSequenceValue( 'text_old_id_val' );
394 $dbw->insert( 'text',
397 'old_text' => $mungedText,
398 'old_flags' => $flags,
401 $revisionId = $dbw->insertId();
403 # Record the edit in revisions
404 $dbw->insert( 'revision',
406 'rev_id' => $revisionId,
407 'rev_page' => $this->mPage
,
408 'rev_comment' => $this->mComment
,
409 'rev_minor_edit' => $this->mMinorEdit ?
1 : 0,
410 'rev_user' => $this->mUser
,
411 'rev_user_text' => $this->mUserText
,
412 'rev_timestamp' => $dbw->timestamp( $this->mTimestamp
),
416 $this->mId
= $revisionId;
418 wfProfileOut( $fname );