$this->isConflict = false;
wfDebug( __METHOD__ . ": conflict suppressed; new section\n" );
}
- } elseif ( $this->section == '' && $this->userWasLastToEdit( $wgUser->getId(), $this->edittime ) ) {
+ } elseif ( $this->section == '' && Revision::userWasLastToEdit( DB_MASTER, $this->mTitle->getArticleID(), $wgUser->getId(), $this->edittime ) ) {
# Suppress edit conflict with self, except for section edits where merging is required.
wfDebug( __METHOD__ . ": Suppressing edit conflict, same user.\n" );
$this->isConflict = false;
}
}
- /**
- * Check if no edits were made by other users since
- * the time a user started editing the page. Limit to
- * 50 revisions for the sake of performance.
- *
- * @param $id int
- * @param $edittime string
- *
- * @return bool
- */
- protected function userWasLastToEdit( $id, $edittime ) {
- if ( !$id ) return false;
- $dbw = wfGetDB( DB_MASTER );
- $res = $dbw->select( 'revision',
- 'rev_user',
- array(
- 'rev_page' => $this->mTitle->getArticleID(),
- 'rev_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $edittime ) )
- ),
- __METHOD__,
- array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 50 ) );
- foreach ( $res as $row ) {
- if ( $row->rev_user != $id ) {
- return false;
- }
- }
- return true;
- }
-
/**
* @private
* @todo document
}
return 0;
}
-}
+
+ /**
+ * Check if no edits were made by other users since
+ * the time a user started editing the page. Limit to
+ * 50 revisions for the sake of performance.
+ *
+ * @since 1.20
+ *
+ * @param DatabaseBase|int $db the Database to perform the check on. May be given as a Database object or
+ * a database identifier usable with wfGetDB.
+ * @param int $pageId the ID of the page in question
+ * @param int $userId the ID of the user in question
+ * @param string $since look at edits since this time
+ *
+ * @return bool True if the given user was the only one to edit since the given timestamp
+ */
+ public static function userWasLastToEdit( $db, $pageId, $userId, $since ) {
+ if ( !$userId ) return false;
+
+ if ( is_int( $db ) ) {
+ $db = wfGetDB( $db );
+ }
+
+ $res = $db->select( 'revision',
+ 'rev_user',
+ array(
+ 'rev_page' => $pageId,
+ 'rev_timestamp > ' . $db->addQuotes( $db->timestamp( $since ) )
+ ),
+ __METHOD__,
+ array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 50 ) );
+ foreach ( $res as $row ) {
+ if ( $row->rev_user != $userId ) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
\ No newline at end of file
*
* @group Database
* ^--- important, causes temporary tables to be used instead of the real database
+ *
+ * @group medium
+ * ^--- important, causes tests not to fail with timeout
*/
class RevisionStorageTest extends MediaWikiTestCase {
$this->assertEquals( $orig->getTextId(), $rev->getTextId(), 'new null revision shold have the same text id as the original revision' );
$this->assertEquals( 'some testing text', $rev->getText() );
}
+
+ public function dataUserWasLastToEdit() {
+ return array(
+ array( #0
+ 3, true, # actually the last edit
+ ),
+ array( #1
+ 2, true, # not the current edit, but still by this user
+ ),
+ array( #2
+ 1, false, # edit by another user
+ ),
+ array( #3
+ 0, false, # first edit, by this user, but another user edited in the mean time
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider dataUserWasLastToEdit
+ */
+ public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) {
+ $userA = \User::newFromName( "RevisionStorageTest_userA" );
+ $userB = \User::newFromName( "RevisionStorageTest_userB" );
+
+ if ( $userA->getId() === 0 ) {
+ $userA = \User::createNew( $userA->getName() );
+ }
+
+ if ( $userB->getId() === 0 ) {
+ $userB = \User::createNew( $userB->getName() );
+ }
+
+ $dbw = wfGetDB( DB_MASTER );
+ $revisions = array();
+
+ // create revisions -----------------------------
+ $page = WikiPage::factory( Title::newFromText( 'RevisionStorageTest_testUserWasLastToEdit' ) );
+
+ # zero
+ $revisions[0] = new Revision( array(
+ 'page' => $page->getId(),
+ 'timestamp' => '20120101000000',
+ 'user' => $userA->getId(),
+ 'text' => 'zero',
+ 'summary' => 'edit zero'
+ ) );
+ $revisions[0]->insertOn( $dbw );
+
+ # one
+ $revisions[1] = new Revision( array(
+ 'page' => $page->getId(),
+ 'timestamp' => '20120101000100',
+ 'user' => $userA->getId(),
+ 'text' => 'one',
+ 'summary' => 'edit one'
+ ) );
+ $revisions[1]->insertOn( $dbw );
+
+ # two
+ $revisions[2] = new Revision( array(
+ 'page' => $page->getId(),
+ 'timestamp' => '20120101000200',
+ 'user' => $userB->getId(),
+ 'text' => 'two',
+ 'summary' => 'edit two'
+ ) );
+ $revisions[2]->insertOn( $dbw );
+
+ # three
+ $revisions[3] = new Revision( array(
+ 'page' => $page->getId(),
+ 'timestamp' => '20120101000300',
+ 'user' => $userA->getId(),
+ 'text' => 'three',
+ 'summary' => 'edit three'
+ ) );
+ $revisions[3]->insertOn( $dbw );
+
+ # four
+ $revisions[4] = new Revision( array(
+ 'page' => $page->getId(),
+ 'timestamp' => '20120101000200',
+ 'user' => $userA->getId(),
+ 'text' => 'zero',
+ 'summary' => 'edit four'
+ ) );
+ $revisions[4]->insertOn( $dbw );
+
+ // test it ---------------------------------
+ $since = $revisions[ $sinceIdx ]->getTimestamp();
+
+ $wasLast = Revision::userWasLastToEdit( $dbw, $page->getId(), $userA->getId(), $since );
+
+ $this->assertEquals( $expectedLast, $wasLast );
+ }
}