/**
* Clear the object
+ * @return void
*/
public function clear() {
$this->mDataLoaded = false;
$this->mDataLoadedFrom = self::DATA_NOT_LOADED;
+ $this->clearCacheFields();
+ }
+
+ /**
+ * Clear the object cache fields
+ * @return void
+ */
+ protected function clearCacheFields() {
$this->mCounter = null;
$this->mRedirectTarget = null; # Title object if set
$this->mLastRevision = null; # Latest revision
$this->mTouched = wfTimestamp( TS_MW, $data->page_touched );
$this->mIsRedirect = intval( $data->page_is_redirect );
$this->mLatest = intval( $data->page_latest );
+ // Bug 37225: $latest may no longer match the cached latest Revision object.
+ // Double-check the ID of any cached latest Revision object for consistency.
+ if ( $this->mLastRevision && $this->mLastRevision->getId() != $this->mLatest ) {
+ $this->mLastRevision = null;
+ $this->mTimestamp = '';
+ }
} else {
$lc->addBadLinkObj( $this->mTitle );
$this->mTitle->loadFromRow( false );
+
+ $this->clearCacheFields();
}
$this->mDataLoaded = true;
}
wfProfileOut( __METHOD__ );
- if ( $row ) {
- return Revision::newFromRow( $row );
- } else {
- return null;
- }
+ return $row ? Revision::newFromRow( $row ) : null;
}
/**
if ( !$this->mTimestamp ) {
$this->loadLastEdit();
}
-
+
return wfTimestamp( TS_MW, $this->mTimestamp );
}
* 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, $wgDBtransactions, $wgUseAutomaticEditSummaries;
+ global $wgUser, $wgUseAutomaticEditSummaries;
# Low-level sanity check
if ( $this->mTitle->getText() === '' ) {
return $status;
}
- # Make sure the revision is either completely inserted or not inserted at all
- if ( !$wgDBtransactions ) {
- $userAbort = ignore_user_abort( true );
- }
-
$revision = new Revision( array(
'page' => $this->getId(),
'comment' => $summary,
'user_text' => $user->getName(),
'timestamp' => $now
) );
+ # Bug 37225: use accessor to get the text as Revision may trim it.
+ # After trimming, the text may be a duplicate of the current text.
+ $text = $revision->getText(); // sanity; EditPage should trim already
$changed = ( strcmp( $text, $oldtext ) != 0 );
/* Belated edit conflict! Run away!! */
$status->fatal( 'edit-conflict' );
- # Delete the invalid revision if the DB is not transactional
- if ( !$wgDBtransactions ) {
- $dbw->delete( 'revision', array( 'rev_id' => $revisionId ), __METHOD__ );
- }
-
$revisionId = 0;
$dbw->rollback( __METHOD__ );
} else {
$revision->setId( $this->getLatest() );
}
- if ( !$wgDBtransactions ) {
- ignore_user_abort( $userAbort );
- }
-
// Now that ignore_user_abort is restored, we can respond to fatal errors
if ( !$status->isOK() ) {
wfProfileOut( __METHOD__ );
) );
$revisionId = $revision->insertOn( $dbw );
+ # Bug 37225: use accessor to get the text as Revision may trim it
+ $text = $revision->getText(); // sanity; EditPage should trim already
+
# Update the page record with revision data
$this->updateRevisionOn( $dbw, $revision, 0 );
$parserCache->save( $editInfo->output, $this, $editInfo->popts );
}
- # Update the links tables
- $u = new LinksUpdate( $this->mTitle, $editInfo->output );
- $u->doUpdate();
+ # Update the links tables and other secondary data
+ $updates = $editInfo->output->getSecondaryDataUpdates( $this->mTitle );
+ DataUpdate::runUpdates( $updates );
wfRunHooks( 'ArticleEditUpdates', array( &$this, &$editInfo, $options['changed'] ) );
/**
* Do some database updates after deletion
*
- * @param $id Int: page_id value of the page being deleted
+ * @param $id Int: page_id value of the page being deleted (B/C, currently unused)
*/
public function doDeleteUpdates( $id ) {
+ # update site status
DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, - (int)$this->isCountable(), -1 ) );
- $dbw = wfGetDB( DB_MASTER );
-
- # Delete restrictions for it
- $dbw->delete( 'page_restrictions', array ( 'pr_page' => $id ), __METHOD__ );
-
- # Fix category table counts
- $cats = array();
- $res = $dbw->select( 'categorylinks', 'cl_to', array( 'cl_from' => $id ), __METHOD__ );
-
- foreach ( $res as $row ) {
- $cats [] = $row->cl_to;
- }
-
- $this->updateCategoryCounts( array(), $cats );
-
- # If using cascading deletes, we can skip some explicit deletes
- if ( !$dbw->cascadingDeletes() ) {
- $dbw->delete( 'revision', array( 'rev_page' => $id ), __METHOD__ );
-
- # Delete outgoing links
- $dbw->delete( 'pagelinks', array( 'pl_from' => $id ), __METHOD__ );
- $dbw->delete( 'imagelinks', array( 'il_from' => $id ), __METHOD__ );
- $dbw->delete( 'categorylinks', array( 'cl_from' => $id ), __METHOD__ );
- $dbw->delete( 'templatelinks', array( 'tl_from' => $id ), __METHOD__ );
- $dbw->delete( 'externallinks', array( 'el_from' => $id ), __METHOD__ );
- $dbw->delete( 'langlinks', array( 'll_from' => $id ), __METHOD__ );
- $dbw->delete( 'iwlinks', array( 'iwl_from' => $id ), __METHOD__ );
- $dbw->delete( 'redirect', array( 'rd_from' => $id ), __METHOD__ );
- $dbw->delete( 'page_props', array( 'pp_page' => $id ), __METHOD__ );
- }
-
- # If using cleanup triggers, we can skip some manual deletes
- if ( !$dbw->cleanupTriggers() ) {
- # Clean up recentchanges entries...
- $dbw->delete( 'recentchanges',
- array( 'rc_type != ' . RC_LOG,
- 'rc_namespace' => $this->mTitle->getNamespace(),
- 'rc_title' => $this->mTitle->getDBkey() ),
- __METHOD__ );
- $dbw->delete( 'recentchanges',
- array( 'rc_type != ' . RC_LOG, 'rc_cur_id' => $id ),
- __METHOD__ );
- }
+ # remove secondary indexes, etc
+ $updates = $this->getDeletionUpdates( );
+ DataUpdate::runUpdates( $updates );
# Clear caches
- self::onArticleDelete( $this->mTitle );
+ WikiPage::onArticleDelete( $this->mTitle );
# Reset this object
$this->clear();
$this->mTitle->resetArticleID( 0 );
}
+ public function getDeletionUpdates() {
+ $updates = array(
+ new LinksDeletionUpdate( $this ),
+ );
+
+ //@todo: make a hook to add update objects
+ //NOTE: deletion updates will be determined by the ContentHandler in the future
+ return $updates;
+ }
+
/**
* Roll back the most recent consecutive set of edits to a page
* from the same user; fails if there are no eligible edits to
* roll back to, e.g. user is the sole contributor. This function
* performs permissions checks on $user, then calls commitRollback()
* to do the dirty work
- *
+ *
* @todo: seperate the business/permission stuff out from backend code
*
* @param $fromP String: Name of the user whose edits to rollback.
if ( count( $templates_diff ) > 0 ) {
# Whee, link updates time.
+ # Note: we are only interested in links here. We don't need to get other DataUpdate items from the parser output.
$u = new LinksUpdate( $this->mTitle, $parserOutput, false );
$u->doUpdate();
}
public function quickEdit( $text, $comment = '', $minor = 0 ) {
wfDeprecated( __METHOD__, '1.18' );
global $wgUser;
- return $this->doQuickEdit( $text, $wgUser, $comment, $minor );
+ $this->doQuickEdit( $text, $wgUser, $comment, $minor );
}
/**