EBernhardson (WMF) has uploaded a new change for review.
https://gerrit.wikimedia.org/r/63789
Change subject: Link directly to the edited section from edit-user-talk events
......................................................................
Link directly to the edited section from edit-user-talk events
Adjusted the edit-user-talk event creation to detect and record which section
of the talk page was edited. Flyout, special page, and email messages have
been adjusted to use this section title as a URL fragment when available.
Bug: 46937
Change-Id: I161e2ffda2f2540f64de90cc621fb3b69479d0db
---
M Echo.i18n.php
M Echo.php
M formatters/BasicFormatter.php
M formatters/CommentFormatter.php
M formatters/EditFormatter.php
M includes/DiscussionParser.php
A tests/NotificationFormatterTest.php
A tests/TalkPageFunctionalTest.php
8 files changed, 192 insertions(+), 17 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Echo
refs/changes/89/63789/1
diff --git a/Echo.i18n.php b/Echo.i18n.php
index 0aa22e7..fc4aef3 100644
--- a/Echo.i18n.php
+++ b/Echo.i18n.php
@@ -63,8 +63,8 @@
// Notification
'echo-quotation-marks' => '"$1"',
- 'notification-edit-talk-page2' => '[[User:$1|$1]] {{GENDER:$1|posted}}
on your [[User talk:$2|talk page]].',
- 'notification-edit-talk-page-flyout2' => '<b>$1</b>
{{GENDER:$1|posted}} on your [[User talk:$2|talk page]].',
+ 'notification-edit-talk-page2' => '[[User:$1|$1]] {{GENDER:$1|posted}}
on your [[User talk:$2#$3|talk page]].',
+ 'notification-edit-talk-page-flyout2' => '<b>$1</b>
{{GENDER:$1|posted}} on your [[User talk:$2#$3|talk page]].',
'notification-page-linked' => '[[:$2]] was {{GENDER:$1|linked}} from
[[:$3]]: [[Special:WhatLinksHere/$2|See all links to this page]]',
'notification-page-linked-flyout' => '<b>$2</b> was
{{GENDER:$1|linked}} from <b>$3</b>: [[Special:WhatLinksHere/$2|See all links
to this page]]',
'notification-add-comment2' => '[[User:$1|$1]] {{GENDER:$1|commented}}
on "[[$3|$2]]" on the "$4" talk page',
@@ -280,12 +280,14 @@
'notification-edit-talk-page2' => "Format for displaying notifications
of a user talk page being edited
* $1 is the username of the person who edited, plain text. Can be used for
GENDER.
* $2 is the current user's name, used in the link to their talk page.
+* $3 is the section title of the edited section, used in the link to their
talk page
See also:
* {{msg-mw|Notification-edit-talk-page-flyout2}}
* {{msg-mw|Notification-add-talkpage-topic2}}",
'notification-edit-talk-page-flyout2' => "Flyout-specific format for
displaying notifications of a user talk page being edited
* $1 is the username of the person who edited, plain text. Can be used for
GENDER.
* $2 is the current user's name, used in the link to their talk page.
+* $3 is the section title of the edited section, used in the link to their
talk page
See also:
* {{msg-mw|Notification-edit-talk-page2}}
* {{msg-mw|Notification-add-talkpage-topic2}}",
diff --git a/Echo.php b/Echo.php
index a2baef3..44a01f3 100644
--- a/Echo.php
+++ b/Echo.php
@@ -377,12 +377,12 @@
'bundle' => array( 'web' => true, 'email' => false ),
'formatter-class' => 'EchoEditFormatter',
'title-message' => 'notification-edit-talk-page2',
- 'title-params' => array( 'agent', 'user' ),
+ 'title-params' => array( 'agent', 'user', 'subject-anchor' ),
'bundle-message' => 'notification-edit-talk-page-bundle',
'bundle-params' => array( 'agent', 'user',
'agent-other-display', 'agent-other-count' ),
'payload' => array( 'summary' ),
'flyout-message' => 'notification-edit-talk-page-flyout2',
- 'flyout-params' => array( 'agent', 'user' ),
+ 'flyout-params' => array( 'agent', 'user', 'subject-anchor' ),
'email-subject-message' =>
'notification-edit-talk-page-email-subject2',
'email-body-message' =>
'notification-edit-talk-page-email-body2',
'email-body-params' => array( 'email-intro', 'titlelink',
'summary', 'email-footer' ),
diff --git a/formatters/BasicFormatter.php b/formatters/BasicFormatter.php
index b294f55..c904873 100644
--- a/formatters/BasicFormatter.php
+++ b/formatters/BasicFormatter.php
@@ -334,6 +334,25 @@
}
/**
+ * Extract the subject anchor (linkable portion of the edited page) from
+ * the event.
+ *
+ * @param $event EchoEvent The event to format the subject anchor of
+ * @return string The anchor on page, or an empty string
+ */
+ protected function formatSubjectAnchor( EchoEvent $event ) {
+ global $wgParser;
+
+ $extra = $event->getExtra();
+ if ( empty( $extra['section-title'] ) ) {
+ return '';
+ }
+
+ // Strip out #, keeping # in the i18n message makes it look
more clear
+ return substr( $wgParser->guessLegacySectionNameFromWikiText(
$extra['section-title'] ), 1 );
+ }
+
+ /**
* Generate links based on output format and passed properties
* $event EchoEvent
* $message Message
@@ -354,6 +373,11 @@
if ( isset( $props['fragment'] ) ) {
$title->setFragment( '#' . $props['fragment'] );
+ } else {
+ $fragment = $this->formatSubjectAnchor( $event );
+ if ( $fragment ) {
+ $title->setFragment( "#$fragment" );
+ }
}
if ( $this->outputFormat === 'html' || $this->outputFormat ===
'flyout' ) {
diff --git a/formatters/CommentFormatter.php b/formatters/CommentFormatter.php
index 2fd7c28..58fc5b1 100644
--- a/formatters/CommentFormatter.php
+++ b/formatters/CommentFormatter.php
@@ -48,17 +48,7 @@
*/
protected function processParam( $event, $param, $message, $user ) {
$extra = $event->getExtra();
- if ( $param === 'subject-anchor' ) {
- global $wgParser;
- if ( !empty( $extra['section-title'] ) ) {
- $message->params(
- // Strip out #, keeping # in the i18n
message makes it look more clear
- substr(
$wgParser->guessLegacySectionNameFromWikiText( $extra['section-title'] ), 1 )
- );
- } else {
- $message->params( '' );
- }
- } elseif ( $param === 'content-page' ) {
+ if ( $param === 'content-page' ) {
if ( $event->getTitle() ) {
$message->params(
$event->getTitle()->getSubjectPage()->getPrefixedText() );
} else {
diff --git a/formatters/EditFormatter.php b/formatters/EditFormatter.php
index 3b9cc06..41ac126 100644
--- a/formatters/EditFormatter.php
+++ b/formatters/EditFormatter.php
@@ -9,7 +9,9 @@
* @param $user User
*/
protected function processParam( $event, $param, $message, $user ) {
- if ( $param === 'difflink' ) {
+ if ( $param === 'subject-anchor' ) {
+ $message->params( $this->formatSubjectAnchor( $event )
);
+ } elseif ( $param === 'difflink' ) {
$eventData = $event->getExtra();
if ( !isset( $eventData['revid'] ) ) {
$message->params( '' );
diff --git a/includes/DiscussionParser.php b/includes/DiscussionParser.php
index 60cf30c..11aaee6 100644
--- a/includes/DiscussionParser.php
+++ b/includes/DiscussionParser.php
@@ -84,7 +84,11 @@
EchoEvent::create( array(
'type' => 'edit-user-talk',
'title' => $title,
- 'extra' => array( 'revid' =>
$revision->getID(), 'minoredit' => $revision->isMinor() ),
+ 'extra' => array(
+ 'revid' =>
$revision->getID(),
+ 'minoredit' =>
$revision->isMinor(),
+ 'section-title' =>
self::detectSectionTitle( $interpretation ),
+ ),
'agent' => $user,
) );
}
@@ -92,6 +96,25 @@
}
}
+ public static function detectSectionTitle( array $interpretation ) {
+ $header = null;
+ foreach ( $interpretation as $action ) {
+ switch( $action['type'] ) {
+ case 'add-comment':
+ $header = self::extractHeader(
$action['full-section'] );
+ break;
+
+ case 'new-section-with-comment':
+ $header = self::extractHeader(
$action['content'] );
+ break;
+ }
+ if ( $header ) {
+ return $header;
+ }
+ }
+ return null;
+ }
+
/**
* For an action taken on a talk page, notify users whose user pages
* are linked.
diff --git a/tests/NotificationFormatterTest.php
b/tests/NotificationFormatterTest.php
new file mode 100644
index 0000000..2c89930
--- /dev/null
+++ b/tests/NotificationFormatterTest.php
@@ -0,0 +1,46 @@
+<?php
+
+class EchoNotificationFormatterTest extends MediaWikiTestCase {
+
+ public function testUserTalkEmailContainsSectionLinkFragment() {
+ $event = $this->mockEvent( 'edit-user-talk', array(
+ 'revid' => 1,
+ 'minoredit' => false,
+ 'section-title' => 'Section 8',
+ ) );
+ $event->expects( $this->any() )
+ ->method( 'getTitle' )
+ ->will( $this->returnValue( Title::newMainPage() ) );
+
+ $formatted = $this->format( $event, 'email' );
+ $this->assertContains( '#Section_8', $formatted['body'] );
+ }
+
+ protected function format( EchoEvent $event, $format, array $params =
array() ) {
+ global $wgEchoNotifications;
+
+ $params += $wgEchoNotifications[ $event->getType() ];
+ $formatter = EchoNotificationFormatter::factory( $params );
+ $formatter->setOutputFormat( $format );
+
+ return $formatter->format($event, new User, '');
+ }
+
+ protected function mockEvent( $type, array $extra = array(), Revision
$rev = null ) {
+ $event = $this->getMockBuilder('EchoEvent')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $event->expects( $this->any() )
+ ->method( 'getType' )
+ ->will( $this->returnValue( $type ) );
+ $event->expects( $this->any() )
+ ->method( 'getExtra' )
+ ->will( $this->returnValue( $extra ) );
+ if ( $rev !== null ) {
+ $event->expects( $this->any() )
+ ->method( 'getRevision' )
+ ->will( $this->returnValue( $rev ) );
+ }
+ return $event;
+ }
+}
diff --git a/tests/TalkPageFunctionalTest.php b/tests/TalkPageFunctionalTest.php
new file mode 100644
index 0000000..e5af785
--- /dev/null
+++ b/tests/TalkPageFunctionalTest.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * @group DataBase
+ * @group medium
+ */
+class EchoTalkPageFunctionalTest extends ApiTestCase {
+
+ protected $dbr;
+
+ public function setUp() {
+ parent::setUp();
+ $this->dbr = MWEchoDbFactory::getDB( DB_SLAVE );
+ }
+
+ /**
+ * Creates and updates a user talk page a few times to ensure proper
events are
+ * created. The user performing the edits is self::$users['sysop'].
+ */
+ public function testAddCommentsToTalkPage() {
+ $editor = self::$users['sysop']->user->getName();
+ $talkPage = self::$users['uploader']->user->getName();
+ // A set of messages which will be inserted
+ $messages = array(
+ 'Moar Cowbell',
+ "I can haz test\n\nplz?", // checks that the parser
allows multi-line comments
+ 'blah blah',
+ );
+
+ $messageCount = 0;
+ $this->assertCount($messageCount, $this->fetchAllEvents() );
+
+ // Start a talkpage
+ $content = "== Section 8 ==\n\n" . $this->signedMessage(
$editor, $messages[$messageCount] );
+ $this->editPage( $talkPage, $content, '', NS_USER_TALK );
+
+ // Ensure the proper event was created
+ $events = $this->fetchAllEvents();
+ $this->assertCount(1 + $messageCount, $events, 'After initial
edit a single event must exist.'); // +1 is due to 0 index
+ $row = end( $events );
+ $this->assertEquals( 'edit-user-talk', $row->event_type );
+ $this->assertEventSectionTitle( 'Section 8', $row );
+
+ // Add another message to the talk page
+ $messageCount++;
+ $content .= $this->signedMessage( $editor,
$messages[$messageCount] );
+ $this->editPage( $talkPage, $content, '', NS_USER_TALK );
+
+ // Ensure another event was created
+ $events = $this->fetchAllEvents();
+ $this->assertCount(1 + $messageCount, $events);
+ $row = end( $events );
+ $this->assertEquals( 'edit-user-talk', $row->event_type );
+ $this->assertEventSectionTitle( 'Section 8', $row );
+
+ // Add a new section and a message within it
+ $messageCount++;
+ $content .= "\n\n== EE ==\n\n" . $this->signedMessage( $editor,
$messages[$messageCount] );
+ $this->editPage( $talkPage, $content, '', NS_USER_TALK );
+
+ // Ensure this event has the new section title
+ $events = $this->fetchAllEvents();
+ $this->assertCount(1 + $messageCount, $events);
+ $row = end( $events );
+ $this->assertEquals( 'edit-user-talk', $row->event_type );
+ $this->assertEventSectionTitle( 'EE', $row );
+ }
+
+ protected function assertEventSectionTitle( $sectionTitle, $row ) {
+ $this->assertNotNull( $row->event_extra, 'Event must contain
extra data.' );
+ $extra = unserialize( $row->event_extra );
+ $this->assertArrayHasKey( 'section-title', $extra, 'Extra data
must include a section-title key.' );
+ $this->assertEquals( $sectionTitle, $extra['section-title'],
'Detected section title must match' );
+ }
+
+ /**
+ * @return array All events in db sorted from oldest to newest
+ */
+ protected function fetchAllEvents() {
+ $res = $this->dbr->select( 'echo_event', array( '*' ), array(),
__METHOD__, array( 'ORDER BY' => 'event_id ASC' ) );
+
+ return iterator_to_array( $res );
+ }
+
+ protected function signedMessage( $name, $content = 'Moar cowbell',
$depth = 1 ) {
+ return str_repeat(':', $depth)." $content [[User:$name|$name]]
([[User talk:$name|$name]]) 00:17, 7 May 2013 (UTC)\n";
+ }
+
+}
--
To view, visit https://gerrit.wikimedia.org/r/63789
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I161e2ffda2f2540f64de90cc621fb3b69479d0db
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Echo
Gerrit-Branch: master
Gerrit-Owner: EBernhardson (WMF) <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits