*
* @internal documentation reviewed 15 Mar 2010
*/
-class WikiPage extends Page {
+class WikiPage extends Page implements IDBAccessObject {
// Constants for $mDataLoadedFrom and related
- /**
- * Data has not been loaded yet (or the object was cleared)
- */
- const DATA_NOT_LOADED = 0;
-
- /**
- * Data has been loaded from a slave database
- */
- const DATA_FROM_SLAVE = 1;
-
- /**
- * Data has been loaded from the master database
- */
- const DATA_FROM_MASTER = 2;
-
- /**
- * Data has been loaded from the master database using FOR UPDATE
- */
- const DATA_FOR_UPDATE = 3;
-
/**
* @var Title
*/
/**@}}*/
/**
- * @var int; one of the DATA_* constants
+ * @var int; one of the READ_* constants
*/
- protected $mDataLoadedFrom = self::DATA_NOT_LOADED;
+ protected $mDataLoadedFrom = self::READ_NONE;
/**
* @var Title
* Create a WikiPage object of the appropriate class for the given title.
*
* @param $title Title
+ * @throws MWException
* @return WikiPage object of the appropriate type
*/
public static function factory( Title $title ) {
*
* @param $id Int article ID to load
* @param $from string|int one of the following values:
- * - "fromdb" or self::DATA_FROM_SLAVE to select from a slave database
- * - "fromdbmaster" or self::DATA_FROM_MASTER to select from the master database
+ * - "fromdb" or WikiPage::READ_NORMAL to select from a slave database
+ * - "fromdbmaster" or WikiPage::READ_LATEST to select from the master database
*
* @return WikiPage|null
*/
public static function newFromID( $id, $from = 'fromdb' ) {
$from = self::convertSelectType( $from );
- $db = wfGetDB( $from === self::DATA_FROM_MASTER ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( $from === self::READ_LATEST ? DB_MASTER : DB_SLAVE );
$row = $db->selectRow( 'page', self::selectFields(), array( 'page_id' => $id ), __METHOD__ );
if ( !$row ) {
return null;
* @param $row object: database row containing at least fields returned
* by selectFields().
* @param $from string|int: source of $data:
- * - "fromdb" or self::DATA_FROM_SLAVE: from a slave DB
- * - "fromdbmaster" or self::DATA_FROM_MASTER: from the master DB
- * - "forupdate" or self::DATA_FOR_UPDATE: from the master DB using SELECT FOR UPDATE
+ * - "fromdb" or WikiPage::READ_NORMAL: from a slave DB
+ * - "fromdbmaster" or WikiPage::READ_LATEST: from the master DB
+ * - "forupdate" or WikiPage::READ_LOCKING: from the master DB using SELECT FOR UPDATE
* @return WikiPage
*/
public static function newFromRow( $row, $from = 'fromdb' ) {
}
/**
- * Convert 'fromdb', 'fromdbmaster' and 'forupdate' to DATA_* constants.
+ * Convert 'fromdb', 'fromdbmaster' and 'forupdate' to READ_* constants.
*
* @param $type object|string|int
* @return mixed
private static function convertSelectType( $type ) {
switch ( $type ) {
case 'fromdb':
- return self::DATA_FROM_SLAVE;
+ return self::READ_NORMAL;
case 'fromdbmaster':
- return self::DATA_FROM_MASTER;
+ return self::READ_LATEST;
case 'forupdate':
- return self::DATA_FOR_UPDATE;
+ return self::READ_LOCKING;
default:
// It may already be an integer or whatever else
return $type;
*/
public function clear() {
$this->mDataLoaded = false;
- $this->mDataLoadedFrom = self::DATA_NOT_LOADED;
+ $this->mDataLoadedFrom = self::READ_NONE;
$this->clearCacheFields();
}
*
* @param $from object|string|int One of the following:
* - A DB query result object
- * - "fromdb" or self::DATA_FROM_SLAVE to get from a slave DB
- * - "fromdbmaster" or self::DATA_FROM_MASTER to get from the master DB
- * - "forupdate" or self::DATA_FOR_UPDATE to get from the master DB using SELECT FOR UPDATE
+ * - "fromdb" or WikiPage::READ_NORMAL to get from a slave DB
+ * - "fromdbmaster" or WikiPage::READ_LATEST to get from the master DB
+ * - "forupdate" or WikiPage::READ_LOCKING to get from the master DB using SELECT FOR UPDATE
*
* @return void
*/
return;
}
- if ( $from === self::DATA_FOR_UPDATE ) {
+ if ( $from === self::READ_LOCKING ) {
$data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle, array( 'FOR UPDATE' ) );
- } elseif ( $from === self::DATA_FROM_MASTER ) {
+ } elseif ( $from === self::READ_LATEST ) {
$data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
- } elseif ( $from === self::DATA_FROM_SLAVE ) {
+ } elseif ( $from === self::READ_NORMAL ) {
$data = $this->pageDataFromTitle( wfGetDB( DB_SLAVE ), $this->mTitle );
# Use a "last rev inserted" timestamp key to dimish the issue of slave lag.
# Note that DB also stores the master position in the session and checks it.
$touched = $this->getCachedLastEditTime();
if ( $touched ) { // key set
if ( !$data || $touched > wfTimestamp( TS_MW, $data->page_touched ) ) {
- $from = self::DATA_FROM_MASTER;
+ $from = self::READ_LATEST;
$data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
}
}
} else {
// No idea from where the caller got this data, assume slave database.
$data = $from;
- $from = self::DATA_FROM_SLAVE;
+ $from = self::READ_NORMAL;
}
$this->loadFromRow( $data, $from );
* @param $data object: database row containing at least fields returned
* by selectFields()
* @param $from string|int One of the following:
- * - "fromdb" or self::DATA_FROM_SLAVE if the data comes from a slave DB
- * - "fromdbmaster" or self::DATA_FROM_MASTER if the data comes from the master DB
- * - "forupdate" or self::DATA_FOR_UPDATE if the data comes from from
+ * - "fromdb" or WikiPage::READ_NORMAL if the data comes from a slave DB
+ * - "fromdbmaster" or WikiPage::READ_LATEST if the data comes from the master DB
+ * - "forupdate" or WikiPage::READ_LOCKING if the data comes from from
* the master DB using SELECT FOR UPDATE
*/
public function loadFromRow( $data, $from ) {
// also gets the revision row FOR UPDATE; otherwise, it may not find it since a page row
// UPDATE and revision row INSERT by S2 may have happened after the first S1 SELECT.
// http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read.
- $flags = ( $this->mDataLoadedFrom == self::DATA_FOR_UPDATE ) ? Revision::LOCKING_READ : 0;
+ $flags = ( $this->mDataLoadedFrom == self::READ_LOCKING ) ? Revision::READ_LOCKING : 0;
$revision = Revision::newFromPageId( $this->getId(), $latest, $flags );
if ( $revision ) { // sanity
$this->setLastEdit( $revision );
* Determine whether a page would be suitable for being counted as an
* article in the site_stats table based on the title & its content
*
- * @param $editInfo Object or false: object returned by prepareTextForEdit(),
+ * @param $editInfo Object|bool (false): object returned by prepareTextForEdit(),
* if false, the current database state will be used
* @return Boolean
*/
$tables = array( 'revision', 'user' );
$fields = array(
- 'rev_user as user_id',
- 'rev_user_text AS user_name',
+ 'user_id' => 'rev_user',
+ 'user_name' => 'rev_user_text',
$realNameField,
- 'MAX(rev_timestamp) AS timestamp',
+ 'timestamp' => 'MAX(rev_timestamp)',
);
$conds = array( 'rev_page' => $this->getId() );
if ( $section == 'new' ) {
# Inserting a new section
- $subject = $sectionTitle ? wfMsgForContent( 'newsectionheaderdefaultlevel', $sectionTitle ) . "\n\n" : '';
+ $subject = $sectionTitle ? wfMessage( 'newsectionheaderdefaultlevel' )
+ ->rawParams( $sectionTitle )->inContentLanguage()->text() . "\n\n" : '';
if ( wfRunHooks( 'PlaceNewSection', array( $this, $oldtext, $subject, &$text ) ) ) {
$text = strlen( trim( $oldtext ) ) > 0
? "{$oldtext}\n\n{$subject}{$text}"
* edit-already-exists error will be returned. These two conditions are also possible with
* auto-detection due to MediaWiki's performance-optimised locking strategy.
*
- * @param $baseRevId int the revision ID this edit was based off, if any
+ * @param bool|int $baseRevId int the revision ID this edit was based off, if any
* @param $user User the user doing the edit
*
+ * @throws MWException
* @return Status object. Possible errors:
* edit-hook-aborted: The ArticleSave hook aborted the edit but didn't set the fatal flag of $status
* edit-gone-missing: In update mode, but the article didn't exist
* Compatibility note: this function previously returned a boolean value indicating success/failure
*/
public function doEdit( $text, $summary, $flags = 0, $baseRevId = false, $user = null ) {
- global $wgUser, $wgUseAutomaticEditSummaries;
+ global $wgUser, $wgUseAutomaticEditSummaries, $wgUseRCPatrol, $wgUseNPPatrol;
# Low-level sanity check
if ( $this->mTitle->getText() === '' ) {
$ok = $this->updateRevisionOn( $dbw, $revision, $oldid, $oldIsRedirect );
if ( !$ok ) {
- /* Belated edit conflict! Run away!! */
+ # Belated edit conflict! Run away!!
$status->fatal( 'edit-conflict' );
- $revisionId = 0;
$dbw->rollback( __METHOD__ );
- } else {
- global $wgUseRCPatrol;
- wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, $baseRevId, $user ) );
- # Update recentchanges
- if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
- # Mark as patrolled if the user can do so
- $patrolled = $wgUseRCPatrol && !count(
- $this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
- # Add RC row to the DB
- $rc = RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $user, $summary,
- $oldid, $this->getTimestamp(), $bot, '', $oldsize, $newsize,
- $revisionId, $patrolled
- );
-
- # Log auto-patrolled edits
- if ( $patrolled ) {
- PatrolLog::record( $rc, true, $user );
- }
+
+ wfProfileOut( __METHOD__ );
+ return $status;
+ }
+
+ wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, $baseRevId, $user ) );
+ # Update recentchanges
+ if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
+ # Mark as patrolled if the user can do so
+ $patrolled = $wgUseRCPatrol && !count(
+ $this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
+ # Add RC row to the DB
+ $rc = RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $user, $summary,
+ $oldid, $this->getTimestamp(), $bot, '', $oldsize, $newsize,
+ $revisionId, $patrolled
+ );
+
+ # Log auto-patrolled edits
+ if ( $patrolled ) {
+ PatrolLog::record( $rc, true, $user );
}
- $user->incEditCount();
- $dbw->commit( __METHOD__ );
}
+ $user->incEditCount();
+ $dbw->commit( __METHOD__ );
} else {
// Bug 32948: revision ID must be set to page {{REVISIONID}} and
// related variables correctly
$revision->setId( $this->getLatest() );
}
- // Now that ignore_user_abort is restored, we can respond to fatal errors
- if ( !$status->isOK() ) {
- wfProfileOut( __METHOD__ );
- return $status;
- }
-
# Update links tables, site stats, etc.
$this->doEditUpdates( $revision, $user, array( 'changed' => $changed,
'oldcountable' => $oldcountable ) );
# Update recentchanges
if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
- global $wgUseRCPatrol, $wgUseNPPatrol;
-
# Mark as patrolled if the user can do so
$patrolled = ( $wgUseRCPatrol || $wgUseNPPatrol ) && !count(
$this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
wfDebug( __METHOD__ . ": invalid username\n" );
} elseif ( User::isIP( $shortTitle ) ) {
// An anonymous user
- $other->setNewtalk( true );
+ $other->setNewtalk( true, $revision );
} elseif ( $other->isLoggedIn() ) {
- $other->setNewtalk( true );
+ $other->setNewtalk( true, $revision );
} else {
wfDebug( __METHOD__ . ": don't need to notify a nonexistent user\n" );
}
if ( $restrictions != '' ) {
$protectDescription .= $wgContLang->getDirMark() . "[$action=$restrictions] (";
if ( $encodedExpiry[$action] != 'infinity' ) {
- $protectDescription .= wfMsgForContent( 'protect-expiring',
+ $protectDescription .= wfMessage(
+ 'protect-expiring',
$wgContLang->timeanddate( $expiry[$action], false, false ) ,
$wgContLang->date( $expiry[$action], false, false ) ,
- $wgContLang->time( $expiry[$action], false, false ) );
+ $wgContLang->time( $expiry[$action], false, false )
+ )->inContentLanguage()->text();
} else {
- $protectDescription .= wfMsgForContent( 'protect-expiry-indefinite' );
+ $protectDescription .= wfMessage( 'protect-expiry-indefinite' )
+ ->inContentLanguage()->text();
}
$protectDescription .= ') ';
}
# Prepare a null revision to be added to the history
- $editComment = $wgContLang->ucfirst( wfMsgForContent( $revCommentMsg, $this->mTitle->getPrefixedText() ) );
+ $editComment = $wgContLang->ucfirst(
+ wfMessage(
+ $revCommentMsg,
+ $this->mTitle->getPrefixedText()
+ )->inContentLanguage()->text()
+ );
if ( $reason ) {
$editComment .= ": $reason";
}
$editComment .= " ($protectDescription)";
}
if ( $cascade ) {
- $editComment .= ' [' . wfMsgForContent( 'protect-summary-cascade' ) . ']';
+ // FIXME: Should use 'brackets' message.
+ $editComment .= ' [' . wfMessage( 'protect-summary-cascade' )
+ ->inContentLanguage()->text() . ']';
}
# Insert a null revision
* Take an array of page restrictions and flatten it to a string
* suitable for insertion into the page_restrictions field.
* @param $limit Array
+ * @throws MWException
* @return String
*/
protected static function flattenRestrictions( $limit ) {
* Deletes the article with database consistency, writes logs, purges caches
*
* @param $reason string delete reason for deletion log
- * @param $suppress int bitfield
- * Revision::DELETED_TEXT
- * Revision::DELETED_COMMENT
- * Revision::DELETED_USER
- * Revision::DELETED_RESTRICTED
+ * @param $suppress boolean suppress all revisions and log the deletion in
+ * the suppression log instead of the deletion log
* @param $id int article ID
* @param $commit boolean defaults to true, triggers transaction end
* @param &$error Array of errors to append to
* Back-end article deletion
* Deletes the article with database consistency, writes logs, purges caches
*
+ * @since 1.19
+ *
* @param $reason string delete reason for deletion log
- * @param $suppress int bitfield
- * Revision::DELETED_TEXT
- * Revision::DELETED_COMMENT
- * Revision::DELETED_USER
- * Revision::DELETED_RESTRICTED
- * @param $id int article ID
+ * @param $suppress boolean suppress all revisions and log the deletion in
+ * the suppression log instead of the deletion log
* @param $commit boolean defaults to true, triggers transaction end
* @param &$error Array of errors to append to
* @param $user User The deleting user
array( /* WHERE */
'rc_cur_id' => $current->getPage(),
'rc_user_text' => $current->getUserText(),
- "rc_timestamp > '{$s->rev_timestamp}'",
+ 'rc_timestamp > ' . $dbw->addQuotes( $s->rev_timestamp ),
), __METHOD__
);
}
$target = Revision::newFromId( $s->rev_id );
if ( empty( $summary ) ) {
if ( $from == '' ) { // no public user name
- $summary = wfMsgForContent( 'revertpage-nouser' );
+ $summary = wfMessage( 'revertpage-nouser' )->inContentLanguage()->text();
} else {
- $summary = wfMsgForContent( 'revertpage' );
+ $summary = wfMessage( 'revertpage' )->inContentLanguage()->text();
}
}
);
$summary = wfMsgReplaceArgs( $summary, $args );
+ # Truncate for whole multibyte characters.
+ $summary = $wgContLang->truncate( $summary, 255 );
+
# Save
$flags = EDIT_UPDATE;
$truncatedtext = $wgContLang->truncate(
str_replace( "\n", ' ', $newtext ),
max( 0, 255
- - strlen( wfMsgForContent( 'autoredircomment' ) )
+ - strlen( wfMessage( 'autoredircomment' )->inContentLanguage()->text() )
- strlen( $rt->getFullText() )
) );
- return wfMsgForContent( 'autoredircomment', $rt->getFullText(), $truncatedtext );
+ return wfMessage( 'autoredircomment', $rt->getFullText() )
+ ->rawParams( $truncatedtext )->inContentLanguage()->text();
}
# New page autosummaries
$truncatedtext = $wgContLang->truncate(
str_replace( "\n", ' ', $newtext ),
- max( 0, 200 - strlen( wfMsgForContent( 'autosumm-new' ) ) ) );
+ max( 0, 200 - strlen( wfMessage( 'autosumm-new' )->inContentLanguage()->text() ) ) );
- return wfMsgForContent( 'autosumm-new', $truncatedtext );
+ return wfMessage( 'autosumm-new' )->rawParams( $truncatedtext )
+ ->inContentLanguage()->text();
}
# Blanking autosummaries
if ( $oldtext != '' && $newtext == '' ) {
- return wfMsgForContent( 'autosumm-blank' );
+ return wfMessage( 'autosumm-blank' )->inContentLanguage()->text();
} elseif ( strlen( $oldtext ) > 10 * strlen( $newtext ) && strlen( $newtext ) < 500 ) {
# Removing more than 90% of the article
$truncatedtext = $wgContLang->truncate(
$newtext,
- max( 0, 200 - strlen( wfMsgForContent( 'autosumm-replace' ) ) ) );
+ max( 0, 200 - strlen( wfMessage( 'autosumm-replace' )->inContentLanguage()->text() ) ) );
- return wfMsgForContent( 'autosumm-replace', $truncatedtext );
+ return wfMessage( 'autosumm-replace' )->rawParams( $truncatedtext )
+ ->inContentLanguage()->text();
}
# If we reach this point, there's no applicable autosummary for our case, so our
if ( $blank ) {
// The current revision is blank and the one before is also
// blank. It's just not our lucky day
- $reason = wfMsgForContent( 'exbeforeblank', '$1' );
+ $reason = wfMessage( 'exbeforeblank', '$1' )->inContentLanguage()->text();
} else {
if ( $onlyAuthor ) {
- $reason = wfMsgForContent( 'excontentauthor', '$1', $onlyAuthor );
+ $reason = wfMessage(
+ 'excontentauthor',
+ '$1',
+ $onlyAuthor
+ )->inContentLanguage()->text();
} else {
- $reason = wfMsgForContent( 'excontent', '$1' );
+ $reason = wfMessage( 'excontent', '$1' )->inContentLanguage()->text();
}
}
/**
* @deprecated since 1.18
+ * @param $oldid int
* @return bool
*/
public function useParserCache( $oldid ) {