* If the given revision is newer than the currently set page_latest,
* update the page record. Otherwise, do nothing.
*
+ * @deprecated since 1.24, use updateRevisionOn instead
+ *
* @param DatabaseBase $dbw
* @param Revision $revision
* @return bool
* @throws MWException
* @return string New complete article text, or null if error.
*
- * @deprecated since 1.21, use replaceSectionContent() instead
+ * @deprecated since 1.21, use replaceSectionAtRev() instead
*/
public function replaceSection( $section, $text, $sectionTitle = '',
$edittime = null
* @return Content New complete article content, or null if error.
*
* @since 1.21
+ * @deprecated since 1.24, use replaceSectionAtRev instead
*/
public function replaceSectionContent( $section, Content $sectionContent, $sectionTitle = '',
$edittime = null ) {
wfProfileIn( __METHOD__ );
+ $baseRevId = null;
+ if ( $edittime && $section !== 'new' ) {
+ $dbw = wfGetDB( DB_MASTER );
+ $rev = Revision::loadFromTimestamp( $dbw, $this->mTitle, $edittime );
+ if ( $rev ) {
+ $baseRevId = $rev->getId();
+ }
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $this->replaceSectionAtRev( $section, $sectionContent, $sectionTitle, $baseRevId );
+ }
+
+ /**
+ * @param string|null|bool $section Null/false, a section number (0, 1, 2, T1, T2, ...) or "new".
+ * @param Content $sectionContent New content of the section.
+ * @param string $sectionTitle New section's subject, only if $section is "new".
+ * @param string $baseRevId integer|null
+ *
+ * @throws MWException
+ * @return Content New complete article content, or null if error.
+ *
+ * @since 1.24
+ */
+ public function replaceSectionAtRev( $section, Content $sectionContent,
+ $sectionTitle = '', $baseRevId = null
+ ) {
+ wfProfileIn( __METHOD__ );
+
if ( strval( $section ) == '' ) {
// Whole-page edit; let the whole text through
$newContent = $sectionContent;
}
// Bug 30711: always use current version when adding a new section
- if ( is_null( $edittime ) || $section == 'new' ) {
+ if ( is_null( $baseRevId ) || $section == 'new' ) {
$oldContent = $this->getContent();
} else {
+ // TODO: try DB_SLAVE first
$dbw = wfGetDB( DB_MASTER );
- $rev = Revision::loadFromTimestamp( $dbw, $this->mTitle, $edittime );
+ $rev = Revision::loadFromId( $dbw, $baseRevId );
if ( !$rev ) {
- wfDebug( "WikiPage::replaceSection asked for bogus section (page: " .
- $this->getId() . "; section: $section; edittime: $edittime)\n" );
+ wfDebug( __METHOD__ . " asked for bogus section (page: " .
+ $this->getId() . "; section: $section)\n" );
wfProfileOut( __METHOD__ );
return null;
}
return null;
}
- // FIXME: $oldContent might be null?
$newContent = $oldContent->replaceSection( $section, $sectionContent, $sectionTitle );
}
// Update page
//
- // Note that we use $this->mLatest instead of fetching a value from the master DB
- // during the course of this function. This makes sure that EditPage can detect
- // edit conflicts reliably, either by $ok here, or by $article->getTimestamp()
- // before this function is called. A previous function used a separate query, this
- // creates a window where concurrent edits can cause an ignored edit conflict.
+ // We check for conflicts by comparing $oldid with the current latest revision ID.
$ok = $this->updateRevisionOn( $dbw, $revision, $oldid, $oldIsRedirect );
if ( !$ok ) {
return $status;
}
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->begin( __METHOD__ );
+
if ( $id == 0 ) {
$this->loadPageData( 'forupdate' );
$id = $this->getID();
if ( $id == 0 ) {
+ $dbw->rollback( __METHOD__ );
$status->error( 'cannotdelete', wfEscapeWikiText( $this->getTitle()->getPrefixedText() ) );
return $status;
}
}
+ // we need to remember the old content so we can use it to generate all deletion updates.
+ $content = $this->getContent( Revision::RAW );
+
// Bitfields to further suppress the content
if ( $suppress ) {
$bitfield = 0;
$bitfield = 'rev_deleted';
}
- // we need to remember the old content so we can use it to generate all deletion updates.
- $content = $this->getContent( Revision::RAW );
-
- $dbw = wfGetDB( DB_MASTER );
- $dbw->begin( __METHOD__ );
// For now, shunt the revision data into the archive table.
// Text is *not* removed from the text table; bulk storage
// is left intact to avoid breaking block-compression or
$dbw->delete( 'revision', array( 'rev_page' => $id ), __METHOD__ );
}
+ // Clone the title, so we have the information we need when we log
+ $logTitle = clone $this->mTitle;
+
$this->doDeleteUpdates( $id, $content );
// Log the deletion, if the page was suppressed, log it at Oversight instead
$logEntry = new ManualLogEntry( $logtype, 'delete' );
$logEntry->setPerformer( $user );
- $logEntry->setTarget( $this->mTitle );
+ $logEntry->setTarget( $logTitle );
$logEntry->setComment( $reason );
$logid = $logEntry->insert();
- $logEntry->publish( $logid );
+
+ $dbw->onTransactionPreCommitOrIdle( function() use ( $dbw, $logEntry, $logid ) {
+ // Bug 56776: avoid deadlocks (especially from FileDeleteForm)
+ $logEntry->publish( $logid );
+ } );
if ( $commit ) {
$dbw->commit( __METHOD__ );