MaxSem has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/405371 )

Change subject: WIP: Ping users mentioned in edit summaries
......................................................................

WIP: Ping users mentioned in edit summaries

Bug: T32750
Change-Id: I8012b82b6e27cc2612fb2302d0c9feb3f3623d62
---
M extension.json
M includes/DiscussionParser.php
M tests/phpunit/DiscussionParserTest.php
3 files changed, 103 insertions(+), 9 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Echo 
refs/changes/71/405371/1

diff --git a/extension.json b/extension.json
index 3928781..c2057a2 100644
--- a/extension.json
+++ b/extension.json
@@ -899,6 +899,10 @@
                "AllowArticleReminderNotification": {
                        "value": false,
                        "description": "This is a feature flag to the Article 
Reminder notification"
+               },
+               "EchoNotifyOnMentionsInEditSummary": {
+                       "value": false,
+                       "description": "Whether users whose user or talk pages 
are linked to should be notified"
                }
        },
        "manifest_version": 2,
diff --git a/includes/DiscussionParser.php b/includes/DiscussionParser.php
index 7786175..cf7283f 100644
--- a/includes/DiscussionParser.php
+++ b/includes/DiscussionParser.php
@@ -23,7 +23,7 @@
                // use slave database if there is a previous revision
                if ( $revision->getPrevious() ) {
                        $title = Title::newFromID( $revision->getPage() );
-               // use master database for new page
+                       // use master database for new page
                } else {
                        $title = Title::newFromID( $revision->getPage(), 
Title::GAID_FOR_UPDATE );
                }
@@ -44,26 +44,29 @@
                                $fullSection = $action['full-section'];
                                $header = self::extractHeader( $fullSection );
                                $userLinks = self::getUserLinks( 
$action['content'], $title );
-                               self::generateMentionEvents( $header, 
$userLinks, $action['content'], $revision, $user );
+                               self::generateMentionEvents( $header, 
$userLinks, $action['content'], $revision,
+                                       $user );
                        } elseif ( $action['type'] == 
'new-section-with-comment' ) {
                                $content = $action['content'];
                                $header = self::extractHeader( $content );
                                $userLinks = self::getUserLinks( $content, 
$title );
                                self::generateMentionEvents( $header, 
$userLinks, $content, $revision, $user );
-                       } elseif ( $action['type'] == 'add-section-multiple' && 
$wgEchoMentionsOnMultipleSectionEdits ) {
+                       } elseif ( $action['type'] == 'add-section-multiple' &&
+                                          
$wgEchoMentionsOnMultipleSectionEdits ) {
                                $content = self::stripHeader( 
$action['content'] );
                                $content = self::stripSignature( $content );
                                $userLinks = self::getUserLinks( $content, 
$title );
-                               self::generateMentionEvents( $action['header'], 
$userLinks, $content, $revision, $user );
+                               self::generateMentionEvents( $action['header'], 
$userLinks, $content, $revision,
+                                       $user );
                        } elseif ( $action['type'] === 'unknown-signed-change' 
) {
-                               $userLinks = array_diff_key(
-                                       self::getUserLinks( 
$action['new_content'], $title ) ?: [],
-                                       self::getUserLinks( 
$action['old_content'], $title ) ?: []
-                               );
+                               $userLinks =
+                                       array_diff_key( self::getUserLinks( 
$action['new_content'], $title ) ?: [],
+                                               self::getUserLinks( 
$action['old_content'], $title ) ?: [] );
                                $header = self::extractHeader( 
$action['full-section'] );
 
                                if ( $wgEchoMentionOnChanges ) {
-                                       self::generateMentionEvents( $header, 
$userLinks, $action['new_content'], $revision, $user );
+                                       self::generateMentionEvents( $header, 
$userLinks, $action['new_content'],
+                                               $revision, $user );
                                }
                        }
                }
@@ -94,6 +97,20 @@
                                        ] );
                                }
                        }
+               }
+
+               // Notify users mentioned in edit summary
+               $summaryUsers = self::getMentionsFromEditSummary( 
$revision->getComment() );
+
+               // Don't allow pinging yourself
+               unset( $summaryUsers[$userName] );
+
+               foreach ( $summaryUsers as $summaryUser ) {
+                       if ( $summaryUser->getTalkPage()->equals( $title ) ) {
+                               // Users already get a ping when their talk 
page is edited
+                               continue;
+                       }
+                       // EchoEvent::create( ... );
                }
        }
 
@@ -1190,4 +1207,35 @@
                $section = self::detectSectionTitleAndText( $interpretation );
                return $lang->truncate( $section['section-title'] . ' ' . 
$section['section-text'], $length );
        }
+
+       /**
+        * Returns a list of registered users linked in an edit summary
+        *
+        * @param string $summary
+        * @return User[]
+        */
+       public static function getMentionsFromEditSummary( $summary ) {
+               // Remove section autocomments. Replace with characters that 
can't be in titles,
+               // to prevent fun stuff like "[[foo /* section */ bar]]".
+               $summary = preg_replace( '#/\*.*?\*/#', ' [] ', $summary );
+
+               $users = [];
+               $regex = '/\[\[([' . Title::legalChars() . ']*?)\]\]/';
+               if ( preg_match_all( $regex, $summary, $matches ) ) {
+                       foreach ( $matches[1] as $match ) {
+                               $title = Title::newFromText( $match );
+                               if ( $title
+                                       && $title->isLocal()
+                                       && ( $title->getNamespace() == NS_USER 
|| $title->getNamespace() == NS_USER_TALK )
+                               ) {
+                                       $user = User::newFromName( 
$title->getText() );
+                                       if ( $user && $user->isLoggedIn() && 
$user->isLoggedIn() ) {
+                                               $users[$user->getName()] = 
$user;
+                                       }
+                               }
+                       }
+               }
+
+               return $users;
+       }
 }
diff --git a/tests/phpunit/DiscussionParserTest.php 
b/tests/phpunit/DiscussionParserTest.php
index 24de8bf..84a7357 100644
--- a/tests/phpunit/DiscussionParserTest.php
+++ b/tests/phpunit/DiscussionParserTest.php
@@ -1813,4 +1813,46 @@
                        )
                );
        }
+
+       /**
+        * @covers EchoDiscussionParser::getMentionsFromEditSummary
+        * @dataProvider provideMentionsFromEditSummary
+        *
+        * @param string $summary
+        * @param string[] $expectedUsers
+        */
+       public function testMentionsFromEditSummary( $summary, array 
$expectedUsers ) {
+               foreach ( $expectedUsers as $user ) {
+                       $this->setupTestUser( $user );
+               }
+
+               $users = EchoDiscussionParser::getMentionsFromEditSummary( 
$summary );
+               foreach ( $users as $name => $user ) {
+                       $this->assertType( User::class, $user );
+                       $this->assertEquals( $name, $user->getName() );
+               }
+
+               $users = array_keys( $users );
+
+               $this->assertArrayEquals( $expectedUsers, $users );
+       }
+
+       public function provideMentionsFromEditSummary() {
+               return [
+                       [ '', [] ],
+                       [  " \t\r\n   ", [] ],
+                       [ 'foo bar', [] ],
+                       [ 'Werdna', [] ],
+                       [ 'User:Werdna', [] ],
+                       [ '[User:Werdna]', [] ],
+                       [ '[[User:Nonexistent]]', [] ],
+                       [ '/* [[User:Werdna */', [] ],
+                       [ '[[User:Werdna]]', [ 'Werdna' ] ],
+                       [ '[[User:Werdna]][[User:Werdna]][[User:Werdna]]', [ 
'Werdna' ] ],
+                       [ '/**/[[User:Werdna]][[user:jorm]]', [ 'Werdna', 
'Jorm' ] ],
+                       [ '/* [[User:Werdna]] */ [[ user : jim_ Carter_]]', [ 
'Jim Carter' ] ],
+                       [ '[[User:/* Jorm */]][[User:/* remove me */Werdna]]', 
[] ],
+                       [ ]
+               ];
+       }
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/405371
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I8012b82b6e27cc2612fb2302d0c9feb3f3623d62
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Echo
Gerrit-Branch: master
Gerrit-Owner: MaxSem <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to