$changed = !$content->equals( $oldContent );
+ $dbw = wfGetDB( DB_MASTER );
+
if ( $changed ) {
$prepStatus = $content->prepareSave( $this, $flags, $oldid, $user );
$status->merge( $prepStatus );
return $status;
}
- $dbw = wfGetDB( DB_MASTER );
- $dbw->begin( __METHOD__ );
+ $dbw->startAtomic( __METHOD__ );
// Get the latest page_latest value while locking it.
// Do a CAS style check to see if it's the same as when this method
// started. If it changed then bail out before touching the DB.
$latestNow = $this->lockAndGetLatest();
if ( $latestNow != $oldid ) {
- $dbw->commit( __METHOD__ );
+ $dbw->endAtomic( __METHOD__ );
// Page updated or deleted in the mean time
$status->fatal( 'edit-conflict' );
$user->incEditCount();
- $dbw->commit( __METHOD__ );
+ $dbw->endAtomic( __METHOD__ );
$this->mTimestamp = $now;
} else {
// Bug 32948: revision ID must be set to page {{REVISIONID}} and
$revision->setId( $this->getLatest() );
}
- // Update links tables, site stats, etc.
- $this->doEditUpdates(
- $revision,
- $user,
- array(
- 'changed' => $changed,
- 'oldcountable' => $meta['oldCountable'],
- 'oldrevision' => $meta['oldRevision']
- )
- );
-
if ( $changed ) {
// Return the new revision to the caller
$status->value['revision'] = $revision;
$this->mTitle->invalidateCache( $now );
}
- // Trigger post-save hook
- $hook_args = array( &$this, &$user, $content, $summary,
- $flags & EDIT_MINOR, null, null, &$flags, $revision, &$status, $meta['baseRevId'] );
- ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $hook_args );
- Hooks::run( 'PageContentSaveComplete', $hook_args );
+ // Do secondary updates once the main changes have been committed...
+ $that = $this;
+ $dbw->onTransactionIdle(
+ function () use (
+ $dbw, &$that, $revision, &$user, $content, $summary, &$flags,
+ $changed, $meta, &$status
+ ) {
+ // Do per-page updates in a transaction
+ $dbw->setFlag( DBO_TRX );
+ // Update links tables, site stats, etc.
+ $that->doEditUpdates(
+ $revision,
+ $user,
+ array(
+ 'changed' => $changed,
+ 'oldcountable' => $meta['oldCountable'],
+ 'oldrevision' => $meta['oldRevision']
+ )
+ );
+ // Trigger post-save hook
+ $params = array( &$that, &$user, $content, $summary, $flags & EDIT_MINOR,
+ null, null, &$flags, $revision, &$status, $meta['baseRevId'] );
+ ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $params );
+ Hooks::run( 'PageContentSaveComplete', $params );
+ }
+ );
return $status;
}
}
public function testUpdatePage() {
+ $checkIds = array();
+
+ $this->setMwGlobals( 'wgHooks', array(
+ 'PageContentInsertComplete' => array( function (
+ WikiPage &$page, User &$user, Content $content,
+ $summary, $minor, $u1, $u2, &$flags, Revision $revision
+ ) {
+ // types/refs checked
+ } ),
+ 'PageContentSaveComplete' => array( function (
+ WikiPage &$page, User &$user, Content $content,
+ $summary, $minor, $u1, $u2, &$flags, Revision $revision,
+ Status &$status, $baseRevId
+ ) use ( &$checkIds ) {
+ $checkIds[] = $status->value['revision']->getId();
+ // types/refs checked
+ } ),
+ ) );
+
$text = "one";
$edit = array(
'wpTextbox1' => $text,
$page = $this->assertEdit( 'EditPageTest_testUpdatePage', "zero", null, $edit,
EditPage::AS_SUCCESS_UPDATE, $text,
"expected successfull update with given text" );
+ $this->assertGreaterThan( 0, $checkIds[0], "First event rev ID set" );
$this->forceRevisionDate( $page, '20120101000000' );
$this->assertEdit( 'EditPageTest_testUpdatePage', null, null, $edit,
EditPage::AS_SUCCESS_UPDATE, $text,
"expected successfull update with given text" );
+ $this->assertGreaterThan( 0, $checkIds[1], "Second edit hook rev ID set" );
+ $this->assertGreaterThan( $checkIds[0], $checkIds[1], "Second event rev ID is higher" );
+ }
+
+ public function testUpdatePageTrx() {
+ $text = "one";
+ $edit = array(
+ 'wpTextbox1' => $text,
+ 'wpSummary' => 'first update',
+ );
+
+ $page = $this->assertEdit( 'EditPageTest_testTrxUpdatePage', "zero", null, $edit,
+ EditPage::AS_SUCCESS_UPDATE, $text,
+ "expected successfull update with given text" );
+
+ $this->forceRevisionDate( $page, '20120101000000' );
+
+ $checkIds = array();
+ $this->setMwGlobals( 'wgHooks', array(
+ 'PageContentSaveComplete' => array( function (
+ WikiPage &$page, User &$user, Content $content,
+ $summary, $minor, $u1, $u2, &$flags, Revision $revision,
+ Status &$status, $baseRevId
+ ) use ( &$checkIds ) {
+ $checkIds[] = $status->value['revision']->getId();
+ // types/refs checked
+ } ),
+ ) );
+
+ wfGetDB( DB_MASTER )->begin( __METHOD__ );
+
+ $text = "two";
+ $edit = array(
+ 'wpTextbox1' => $text,
+ 'wpSummary' => 'second update',
+ );
+
+ $this->assertEdit( 'EditPageTest_testTrxUpdatePage', null, null, $edit,
+ EditPage::AS_SUCCESS_UPDATE, $text,
+ "expected successfull update with given text" );
+
+ $text = "three";
+ $edit = array(
+ 'wpTextbox1' => $text,
+ 'wpSummary' => 'third update',
+ );
+
+ $this->assertEdit( 'EditPageTest_testTrxUpdatePage', null, null, $edit,
+ EditPage::AS_SUCCESS_UPDATE, $text,
+ "expected successfull update with given text" );
+
+ wfGetDB( DB_MASTER )->commit( __METHOD__ );
+
+ $this->assertGreaterThan( 0, $checkIds[0], "First event rev ID set" );
+ $this->assertGreaterThan( 0, $checkIds[1], "Second edit hook rev ID set" );
+ $this->assertGreaterThan( $checkIds[0], $checkIds[1], "Second event rev ID is higher" );
}
public static function provideSectionEdit() {