Tobias Gritschacher has submitted this change and it was merged.
Change subject: (bug 41573) Add entities to watchlist.
......................................................................
(bug 41573) Add entities to watchlist.
When editing an entity, it should get added to the user's watchlist
according to the user's preferences.
Bug: 41573
Change-Id: I36c6a3a285f21cc0f4a1298752b34823140cb736
---
M repo/includes/EditEntity.php
M repo/tests/phpunit/includes/EditEntityTest.php
2 files changed, 255 insertions(+), 10 deletions(-)
Approvals:
Tobias Gritschacher: Verified; Looks good to me, approved
jenkins-bot: Verified
diff --git a/repo/includes/EditEntity.php b/repo/includes/EditEntity.php
index 552f254..eae909e 100644
--- a/repo/includes/EditEntity.php
+++ b/repo/includes/EditEntity.php
@@ -265,11 +265,11 @@
* Returns the Title of the page to be edited.
* Shorthand for $this->getPage()->getTitle().
*
- * @return Title
+ * @return Title|bool
*/
public function getTitle() {
if ( $this->isNew() ) {
- return null;
+ return false;
}
return $this->newContent->getTitle();
@@ -611,17 +611,23 @@
* @param int $flags The edit flags (see
WikiPage::toEditContent)
* @param String|bool $token Edit token to check, or false to
disable the token check.
* Null will fail the token text, as
will the empty string.
+ * @param bool|null $watch Whether the user wants to watch the
entity.
+ * Set to null to apply default
according to getWatchDefault().
*
* @throws \ReadOnlyError
* @return Status Indicates success and provides detailed warnings or
error messages. See
* getStatus() for more details.
* @see WikiPage::doEditContent
*/
- public function attemptSave( $summary, $flags, $token ) {
+ public function attemptSave( $summary, $flags, $token, $watch = null ) {
wfProfileIn( __METHOD__ );
if ( wfReadOnly() ) {
throw new \ReadOnlyError();
+ }
+
+ if ( $watch === null ) {
+ $watch = $this->getWatchDefault();
}
$this->status = Status::newGood();
@@ -715,7 +721,9 @@
$this->status->setResult( $editStatus->isOK(),
$editStatus->getValue() );
$this->status->merge( $editStatus );
- if ( !$this->status->isOK() ) {
+ if ( $this->status->isOK() ) {
+ $this->updateWatchlist( $watch );
+ } else {
$value = $this->status->getValue();
$value['errorFlags'] = $this->errorType;
$this->status->setResult( false, $value );
@@ -932,4 +940,68 @@
wfProfileOut( __METHOD__ );
return true;
}
+
+ /**
+ * Returns whether the present edit would, per default,
+ * lead to the user watching the page.
+ *
+ * This uses the user's watchdefault and watchcreations settings
+ * and considers whether the entity is already watched by the user.
+ *
+ * @return bool
+ *
+ * @note: keep in sync with logic in EditPage
+ */
+ public function getWatchDefault() {
+ $user = $this->getUser();
+ $title = $this->getTitle();
+
+ if ( $title && !$title->exists() ) {
+ $title = false;
+ }
+
+ if ( $user->getOption( 'watchdefault' ) ) {
+ // Watch all edits
+ return true;
+ } elseif ( $user->getOption( 'watchcreations' ) && !$title ) {
+ // Watch creations
+ return true;
+ }
+
+ // keep current state
+ return $title !== false && $user->isWatched( $title );
+ }
+
+ /**
+ * Watches or unwatches the entity.
+ *
+ * @param bool $watch whether to watch or unwatch the page.
+ *
+ * @throws \MWException
+ * @return void : keep in sync with logic in EditPage
+ */
+ public function updateWatchlist( $watch ) {
+ $user = $this->getUser();
+ $title = $this->getTitle();
+
+ if ( !$title ) {
+ throw new \MWException( "Title not yet known!" );
+ }
+
+ if ( $user->isLoggedIn() && $watch != $user->isWatched( $title
) ) {
+ $fname = __METHOD__;
+
+ // Do this in its own transaction to reduce
contention...
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->onTransactionIdle( function() use ( $dbw, $title,
$watch, $user, $fname ) {
+ $dbw->begin( $fname );
+ if ( $watch ) {
+ \WatchAction::doWatch( $title, $user );
+ } else {
+ \WatchAction::doUnwatch( $title, $user
);
+ }
+ $dbw->commit( $fname );
+ } );
+ }
+ }
}
diff --git a/repo/tests/phpunit/includes/EditEntityTest.php
b/repo/tests/phpunit/includes/EditEntityTest.php
index 3651788..b706de5 100644
--- a/repo/tests/phpunit/includes/EditEntityTest.php
+++ b/repo/tests/phpunit/includes/EditEntityTest.php
@@ -4,8 +4,8 @@
use \Wikibase\EntityContent;
use \Wikibase\EditEntity;
-use Wikibase\Item;
use \Wikibase\ItemContent;
+use \Wikibase\Item;
use \Status;
use Wikibase\Test\Api\ModifyItemBase;
@@ -54,15 +54,21 @@
private static $testRevisions = null;
+ protected static function getUser( $name ) {
+ $user = \User::newFromName( $name );
+
+ if ( $user->getId() === 0 ) {
+ $user = \User::createNew( $user->getName() );
+ }
+
+ return $user;
+ }
+
protected static function getTestRevisions() {
global $wgUser;
if ( self::$testRevisions === null ) {
- $otherUser = \User::newFromName( "EditEntityTestUser2"
);
-
- if ( $otherUser->getId() === 0 ) {
- $otherUser = \User::createNew(
$otherUser->getName() );
- }
+ $otherUser = self::getUser( "EditEntityTestUser2" );
$itemContent = ItemContent::newEmpty();
$itemContent->getEntity()->setLabel('en', "foo");
@@ -702,4 +708,171 @@
$this->assertNotEquals( $shouldWork, $edit->hasError(
EditEntity::TOKEN_ERROR ) );
$this->assertNotEquals( $shouldWork, $edit->showErrorPage() );
}
+
+ public static function provideGetWatchDefault() {
+ // $watchdefault, $watchcreations, $new, $watched, $expected
+
+ return array(
+ array( false, false, false, false, false ),
+ array( false, false, false, true, true ),
+ array( false, false, true, false, false ),
+ //array( false, false, true, true, true ), // can't
happen, a new pages is never watched
+
+ array( false, true, false, false, false ),
+ array( false, true, false, true, true ),
+ array( false, true, true, false, true ),
+ //array( false, true, true, true, true ), // can't
happen, a new pages is never watched
+
+ array( true, false, false, false, true ),
+ array( true, false, false, true, true ),
+ array( true, false, true, false, true ),
+ //array( true, false, true, true, true ), // can't
happen, a new pages is never watched
+
+ array( true, true, false, false, true ),
+ array( true, true, false, true, true ),
+ array( true, true, true, false, true ),
+ //array( true, true, true, true, true ), // can't
happen, a new pages is never watched
+ );
+ }
+
+ /**
+ * @dataProvider provideGetWatchDefault
+ */
+ public function testGetWatchDefault( $watchdefault, $watchcreations,
$new, $watched, $expected ) {
+ $user = self::getUser( "EditEntityTestUser2" );
+
+ $user->setOption( 'watchdefault', $watchdefault );
+ $user->setOption( 'watchcreations', $watchcreations );
+
+ $item = Item::newEmpty();
+ $item->setLabel( "en", "Test" );
+
+ if ( $new ) {
+ $item->setId( 33224477 );
+ $content = ItemContent::newFromItem( $item );
+ } else {
+ $content = ItemContent::newFromItem( $item );
+ $stats = $content->save( "testing", null, EDIT_NEW );
+ $this->assertTrue( $stats->isOK(), "failed to save" );
// sanity
+ }
+
+ $title = $content->getTitle();
+ $this->assertType( 'object', $title ); // sanity
+
+ if ( $watched ) {
+ \WatchAction::doWatch( $title, $user );
+ } else {
+ \WatchAction::doUnwatch( $title, $user );
+ }
+
+ $edit = new EditEntity( $content, $user );
+ $watch = $edit->getWatchDefault();
+ $this->assertEquals( $expected, $watch, "getWatchDefault" );
+
+ if ( $title && $title->exists() ) {
+ // clean up
+ $page = \WikiPage::factory( $title );
+ $page->doDeleteArticle( "testing" );
+ }
+ }
+
+ public static function provideUpdateWatchlist() {
+ // $wasWatched, $watch, $expected
+
+ return array(
+ array( false, false, false ),
+ array( false, true, true ),
+ array( true, false, false ),
+ array( true, true, true ),
+ );
+ }
+
+ /**
+ * @dataProvider provideUpdateWatchlist
+ */
+ public function testUpdateWatchlist( $wasWatched, $watch, $expected ) {
+ $user = self::getUser( "EditEntityTestUser2" );
+
+ $content = ItemContent::newEmpty();
+ $content->getEntity()->setLabel( "en", "Test" );
+ $content->getEntity()->setId( 33224477 );
+
+ $title = $content->getTitle();
+
+ if ( $wasWatched ) {
+ \WatchAction::doWatch( $title, $user );
+ } else {
+ \WatchAction::doUnwatch( $title, $user );
+ }
+
+ $edit = new EditEntity( $content, $user );
+ $edit->updateWatchlist( $watch );
+
+ $this->assertEquals( $expected, $user->isWatched( $title ) );
+ }
+
+
+ public static function provideAttemptSaveWatch() {
+ // $watchdefault, $watchcreations, $new, $watched, $watch,
$expected
+
+ return array(
+ array( true, true, true, false, null, true ), // watch
new
+ array( true, true, true, false, false, false ), //
override watch new
+
+ array( true, true, false, false, null, true ), // watch
edit
+ array( true, true, false, false, false, false ), //
override watch edit
+
+ array( false, false, false, false, null, false ), //
don't watch edit
+ array( false, false, false, false, true, true ), //
override don't watch edit
+
+ array( false, false, false, true, null, true ), //
watch watched
+ array( false, false, false, true, false, false ), //
override don't watch edit
+ );
+ }
+
+ /**
+ * @dataProvider provideAttemptSaveWatch
+ */
+ public function testAttemptSaveWatch( $watchdefault, $watchcreations,
$new, $watched, $watch, $expected ) {
+ $user = self::getUser( "EditEntityTestUser2" );
+
+ $user->setOption( 'watchdefault', $watchdefault );
+ $user->setOption( 'watchcreations', $watchcreations );
+
+ $item = Item::newEmpty();
+ $item->setLabel( "en", "Test" );
+
+ if ( $new ) {
+ $content = ItemContent::newFromItem( $item );
+ } else {
+ $content = ItemContent::newFromItem( $item );
+ $stats = $content->save( "testing", null, EDIT_NEW );
+ $this->assertTrue( $stats->isOK(), "failed to save" );
// sanity
+ }
+
+ if ( !$new ) {
+ $title = $content->getTitle();
+ $this->assertType( 'object', $title ); // sanity
+
+ if ( $watched ) {
+ \WatchAction::doWatch( $title, $user );
+ } else {
+ \WatchAction::doUnwatch( $title, $user );
+ }
+ }
+
+ $edit = new EditEntity( $content, $user );
+ $status = $edit->attemptSave( "testing", $new ? EDIT_NEW :
EDIT_UPDATE, false, $watch );
+
+ $this->assertTrue( $status->isOK(), "edit failed: " .
$status->getWikiText() ); // sanity
+
+ $title = $content->getTitle();
+ $this->assertEquals( $expected, $user->isWatched( $title ),
"watched" );
+
+ if ( $title && $title->exists() ) {
+ // clean up
+ $page = \WikiPage::factory( $title );
+ $page->doDeleteArticle( "testing" );
+ }
+ }
}
--
To view, visit https://gerrit.wikimedia.org/r/54704
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I36c6a3a285f21cc0f4a1298752b34823140cb736
Gerrit-PatchSet: 6
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Daniel Werner <[email protected]>
Gerrit-Reviewer: Jeroen De Dauw <[email protected]>
Gerrit-Reviewer: John Erling Blad <[email protected]>
Gerrit-Reviewer: Tobias Gritschacher <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits