diff options
-rw-r--r-- | includes/changes/RecentChange.php | 39 | ||||
-rw-r--r-- | includes/rcfeed/Hook/IRCLineURLHook.php | 2 | ||||
-rw-r--r-- | includes/rcfeed/IRCColourfulRCFeedFormatter.php | 24 | ||||
-rw-r--r-- | includes/rcfeed/MachineReadableRCFeedFormatter.php | 2 | ||||
-rw-r--r-- | tests/phpunit/includes/changes/RecentChangeTest.php | 91 | ||||
-rw-r--r-- | tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php | 8 |
6 files changed, 140 insertions, 26 deletions
diff --git a/includes/changes/RecentChange.php b/includes/changes/RecentChange.php index e2b8fac32438..8ea5b5e9ceb5 100644 --- a/includes/changes/RecentChange.php +++ b/includes/changes/RecentChange.php @@ -1319,6 +1319,45 @@ class RecentChange implements Taggable { } /** + * Get the extra URL that is given as part of the notification to RCFeed consumers. + * + * This is mainly to facilitate patrolling or other content review. + * + * @since 1.40 + * @return string|null URL + */ + public function getNotifyUrl() { + $services = MediaWikiServices::getInstance(); + $mainConfig = $services->getMainConfig(); + $useRCPatrol = $mainConfig->get( MainConfigNames::UseRCPatrol ); + $useNPPatrol = $mainConfig->get( MainConfigNames::UseNPPatrol ); + $localInterwikis = $mainConfig->get( MainConfigNames::LocalInterwikis ); + $canonicalServer = $mainConfig->get( MainConfigNames::CanonicalServer ); + $script = $mainConfig->get( MainConfigNames::Script ); + + $type = $this->getAttribute( 'rc_type' ); + if ( $type == RC_LOG ) { + $url = null; + } else { + $url = $canonicalServer . $script; + if ( $type == RC_NEW ) { + $query = '?oldid=' . $this->getAttribute( 'rc_this_oldid' ); + } else { + $query = '?diff=' . $this->getAttribute( 'rc_this_oldid' ) + . '&oldid=' . $this->getAttribute( 'rc_last_oldid' ); + } + if ( $useRCPatrol || ( $this->getAttribute( 'rc_type' ) == RC_NEW && $useNPPatrol ) ) { + $query .= '&rcid=' . $this->getAttribute( 'rc_id' ); + } + + ( new HookRunner( $services->getHookContainer() ) )->onIRCLineURL( $url, $query, $this ); + $url .= $query; + } + + return $url; + } + + /** * Parses and returns the rc_params attribute * * @since 1.26 diff --git a/includes/rcfeed/Hook/IRCLineURLHook.php b/includes/rcfeed/Hook/IRCLineURLHook.php index 5a84ccc55a77..6e7151f58400 100644 --- a/includes/rcfeed/Hook/IRCLineURLHook.php +++ b/includes/rcfeed/Hook/IRCLineURLHook.php @@ -13,7 +13,7 @@ use RecentChange; */ interface IRCLineURLHook { /** - * This hook is called when constructing the URL to use in an IRC notification. + * This hook is called when constructing the URL to use in an RCFeed notification. * Callee may modify $url and $query; URL will be constructed as $url . $query * * @since 1.35 diff --git a/includes/rcfeed/IRCColourfulRCFeedFormatter.php b/includes/rcfeed/IRCColourfulRCFeedFormatter.php index 03a1f107c399..7e07a86d8fb9 100644 --- a/includes/rcfeed/IRCColourfulRCFeedFormatter.php +++ b/includes/rcfeed/IRCColourfulRCFeedFormatter.php @@ -19,7 +19,6 @@ * @file */ -use MediaWiki\HookContainer\HookRunner; use MediaWiki\MainConfigNames; use MediaWiki\MediaWikiServices; use MediaWiki\Title\Title; @@ -48,11 +47,9 @@ class IRCColourfulRCFeedFormatter implements RCFeedFormatter { public function getLine( array $feed, RecentChange $rc, $actionComment ) { $services = MediaWikiServices::getInstance(); $mainConfig = $services->getMainConfig(); + $localInterwikis = $mainConfig->get( MainConfigNames::LocalInterwikis ); $useRCPatrol = $mainConfig->get( MainConfigNames::UseRCPatrol ); $useNPPatrol = $mainConfig->get( MainConfigNames::UseNPPatrol ); - $localInterwikis = $mainConfig->get( MainConfigNames::LocalInterwikis ); - $canonicalServer = $mainConfig->get( MainConfigNames::CanonicalServer ); - $script = $mainConfig->get( MainConfigNames::Script ); $attribs = $rc->getAttributes(); if ( $attribs['rc_type'] == RC_CATEGORIZE ) { // Don't send RC_CATEGORIZE events to IRC feed (T127360) @@ -69,22 +66,7 @@ class IRCColourfulRCFeedFormatter implements RCFeedFormatter { $title = $titleObj->getPrefixedText(); $title = self::cleanupForIRC( $title ); - if ( $attribs['rc_type'] == RC_LOG ) { - $url = ''; - } else { - $url = $canonicalServer . $script; - if ( $attribs['rc_type'] == RC_NEW ) { - $query = '?oldid=' . $attribs['rc_this_oldid']; - } else { - $query = '?diff=' . $attribs['rc_this_oldid'] . '&oldid=' . $attribs['rc_last_oldid']; - } - if ( $useRCPatrol || ( $attribs['rc_type'] == RC_NEW && $useNPPatrol ) ) { - $query .= '&rcid=' . $attribs['rc_id']; - } - - ( new HookRunner( $services->getHookContainer() ) )->onIRCLineURL( $url, $query, $rc ); - $url .= $query; - } + $notifyUrl = $rc->getNotifyUrl() ?? ''; if ( $attribs['rc_old_len'] !== null && $attribs['rc_new_len'] !== null ) { $szdiff = $attribs['rc_new_len'] - $attribs['rc_old_len']; @@ -139,7 +121,7 @@ class IRCColourfulRCFeedFormatter implements RCFeedFormatter { # see http://www.irssi.org/documentation/formats for some colour codes. prefix is \003, # no colour (\003) switches back to the term default $fullString = "$titleString\0034 $flag\00310 " . - "\00302$url\003 \0035*\003 \00303$user\003 \0035*\003 $szdiff \00310$comment\003\n"; + "\00302$notifyUrl\003 \0035*\003 \00303$user\003 \0035*\003 $szdiff \00310$comment\003\n"; return $fullString; } diff --git a/includes/rcfeed/MachineReadableRCFeedFormatter.php b/includes/rcfeed/MachineReadableRCFeedFormatter.php index 5652931a3bdb..698fe5b8a467 100644 --- a/includes/rcfeed/MachineReadableRCFeedFormatter.php +++ b/includes/rcfeed/MachineReadableRCFeedFormatter.php @@ -58,10 +58,12 @@ abstract class MachineReadableRCFeedFormatter implements RCFeedFormatter { 'type' => RecentChange::parseFromRCType( $rc->getAttribute( 'rc_type' ) ), 'namespace' => $rc->getTitle()->getNamespace(), 'title' => $rc->getTitle()->getPrefixedText(), + 'title_url' => $rc->getTitle()->getCanonicalURL(), 'comment' => $rc->getAttribute( 'rc_comment' ), 'timestamp' => (int)wfTimestamp( TS_UNIX, $rc->getAttribute( 'rc_timestamp' ) ), 'user' => $rc->getAttribute( 'rc_user_text' ), 'bot' => (bool)$rc->getAttribute( 'rc_bot' ), + 'notify_url' => $rc->getNotifyUrl(), ]; if ( isset( $feed['channel'] ) ) { diff --git a/tests/phpunit/includes/changes/RecentChangeTest.php b/tests/phpunit/includes/changes/RecentChangeTest.php index bdc0ee7f7b66..49354e2ab8b5 100644 --- a/tests/phpunit/includes/changes/RecentChangeTest.php +++ b/tests/phpunit/includes/changes/RecentChangeTest.php @@ -33,6 +33,17 @@ class RecentChangeTest extends MediaWikiIntegrationTestCase { $this->user = new UserIdentityValue( $user->getId(), $user->getName() ); $this->user_comment = '<User comment about action>'; + + $this->overrideConfigValues( [ + MainConfigNames::CanonicalServer => 'https://example.org', + MainConfigNames::ServerName => 'example.org', + MainConfigNames::ScriptPath => '/w', + MainConfigNames::Script => '/w/index.php', + MainConfigNames::UseRCPatrol => false, + MainConfigNames::UseNPPatrol => false, + MainConfigNames::RCFeeds => [], + MainConfigNames::RCEngines => [], + ] ); } public static function provideAttribs() { @@ -369,6 +380,84 @@ class RecentChangeTest extends MediaWikiIntegrationTestCase { } /** + * @covers RecentChange::getNotifyUrl + */ + public function testGetNotifyUrlForEdit() { + $rc = new RecentChange; + $rc->mAttribs = [ + 'rc_id' => 60, + 'rc_timestamp' => '20110401090000', + 'rc_namespace' => NS_MAIN, + 'rc_title' => 'Example', + 'rc_type' => RC_EDIT, + 'rc_cur_id' => 42, + 'rc_this_oldid' => 50, + 'rc_last_oldid' => 30, + 'rc_patrolled' => 0, + ]; + $this->assertSame( + 'https://example.org/w/index.php?diff=50&oldid=30', + $rc->getNotifyUrl(), 'Notify url' + ); + + $this->overrideConfigValue( MainConfigNames::UseRCPatrol, true ); + $this->assertSame( + 'https://example.org/w/index.php?diff=50&oldid=30&rcid=60', + $rc->getNotifyUrl(), 'Notify url (RC Patrol)' + ); + } + + /** + * @covers RecentChange::getNotifyUrl + */ + public function testGetNotifyUrlForCreate() { + $rc = new RecentChange; + $rc->mAttribs = [ + 'rc_id' => 60, + 'rc_timestamp' => '20110401090000', + 'rc_namespace' => NS_MAIN, + 'rc_title' => 'Example', + 'rc_type' => RC_NEW, + 'rc_cur_id' => 42, + 'rc_this_oldid' => 50, + 'rc_last_oldid' => 0, + 'rc_patrolled' => 0, + ]; + $this->assertSame( + 'https://example.org/w/index.php?oldid=50', + $rc->getNotifyUrl(), 'Notify url' + ); + + $this->overrideConfigValue( MainConfigNames::UseNPPatrol, true ); + $this->assertSame( + 'https://example.org/w/index.php?oldid=50&rcid=60', + $rc->getNotifyUrl(), 'Notify url (NP Patrol)' + ); + } + + /** + * @covers RecentChange::getNotifyUrl + */ + public function testGetNotifyUrlForLog() { + $rc = new RecentChange; + $rc->mAttribs = [ + 'rc_id' => 60, + 'rc_timestamp' => '20110401090000', + 'rc_namespace' => NS_MAIN, + 'rc_title' => 'Example', + 'rc_type' => RC_LOG, + 'rc_cur_id' => 42, + 'rc_this_oldid' => 50, + 'rc_last_oldid' => 0, + 'rc_patrolled' => 2, + 'rc_logid' => 160, + 'rc_log_type' => 'delete', + 'rc_log_action' => 'delete', + ]; + $this->assertSame( null, $rc->getNotifyUrl(), 'Notify url' ); + } + + /** * @return array */ public static function provideIsInRCLifespan() { @@ -519,7 +608,6 @@ class RecentChangeTest extends MediaWikiIntegrationTestCase { * @covers RecentChange::doMarkPatrolled */ public function testDoMarkPatrolledPermissions_NoRcPatrol() { - $this->overrideConfigValue( MainConfigNames::UseRCPatrol, false ); $rc = $this->getDummyEditRecentChange(); $errors = $rc->doMarkPatrolled( $this->mockRegisteredUltimateAuthority() ); $this->assertContains( [ 'rcpatroldisabled' ], $errors ); @@ -529,6 +617,7 @@ class RecentChangeTest extends MediaWikiIntegrationTestCase { * @covers RecentChange::doMarkPatrolled */ public function testDoMarkPatrolled() { + $this->overrideConfigValue( MainConfigNames::UseRCPatrol, true ); $rc = $this->getDummyEditRecentChange(); $errors = $rc->doMarkPatrolled( $this->mockUserAuthorityWithPermissions( $this->user, [ 'patrol', 'autopatrol' ] ) diff --git a/tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php b/tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php index 68fc651a93e7..46de786f7232 100644 --- a/tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php +++ b/tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php @@ -19,6 +19,8 @@ class RCFeedIntegrationTest extends MediaWikiIntegrationTestCase { MainConfigNames::CanonicalServer => 'https://example.org', MainConfigNames::ServerName => 'example.org', MainConfigNames::ScriptPath => '/w', + MainConfigNames::Script => '/w/index.php', + MainConfigNames::ArticlePath => '/wiki/$1', MainConfigNames::DBname => 'example', MainConfigNames::DBprefix => $this->dbPrefix(), MainConfigNames::RCFeeds => [], @@ -32,11 +34,9 @@ class RCFeedIntegrationTest extends MediaWikiIntegrationTestCase { ->onlyMethods( [ 'send' ] ) ->getMock(); - $feed->method( 'send' ) - ->willReturn( true ); - $feed->expects( $this->once() ) ->method( 'send' ) + ->willReturn( true ) ->with( $this->anything(), $this->callback( function ( $line ) { $this->assertJsonStringEqualsJsonString( json_encode( [ @@ -44,10 +44,12 @@ class RCFeedIntegrationTest extends MediaWikiIntegrationTestCase { 'type' => 'log', 'namespace' => 0, 'title' => 'Example', + 'title_url' => 'https://example.org/wiki/Example', 'comment' => '', 'timestamp' => 1301644800, 'user' => 'UTSysop', 'bot' => false, + 'notify_url' => null, 'log_id' => 0, 'log_type' => 'move', 'log_action' => 'move', |