jenkins-bot has submitted this change and it was merged.

Change subject: Log edits in multiple sections that could trigger mentions.
......................................................................


Log edits in multiple sections that could trigger mentions.

This patch logs multiple section edits that could trigger mentions.

Since we only want to send mentions when userlinks and signature are present
in the same section a new method was added extracting sections and the related
content from an addition. The results are checked whether a section content
contains a signature and might be relevant for mentions.

Bug: T141863
Change-Id: Ib06cd855b2c7fbd51d8ab6602882cb38aadf8350
---
M includes/DiscussionParser.php
M tests/phpunit/DiscussionParserTest.php
2 files changed, 256 insertions(+), 8 deletions(-)

Approvals:
  Catrope: Looks good to me, approved
  Jakob: Checked; Looks good to me, but someone else must approve
  jenkins-bot: Verified



diff --git a/includes/DiscussionParser.php b/includes/DiscussionParser.php
index 1aaac67..43901cd 100644
--- a/includes/DiscussionParser.php
+++ b/includes/DiscussionParser.php
@@ -1,6 +1,7 @@
 <?php
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Logger\LoggerFactory;
 
 abstract class EchoDiscussionParser {
        const HEADER_REGEX = '^(==+)\s*([^=].*)\s*\1$';
@@ -45,6 +46,24 @@
                                $content = $action['content'];
                                $header = self::extractHeader( $content );
                                self::generateMentionEvents( $header, $content, 
$revision, $user );
+                       } elseif ( $action['type'] == 'add-section-multiple' ) {
+                               $content = self::stripHeader( 
$action['content'] );
+                               $content = self::stripSignature( $content );
+                               $userLinks = self::getUserLinks( $content, 
$title );
+                               if ( $userLinks ) {
+                                       $diffUrl = $title->getFullURL( array(
+                                               'oldid' => 'prev',
+                                               'diff' => $revision->getId()
+                                       ) );
+                                       LoggerFactory::getInstance( 'Echo' 
)->debug(
+                                               'Triggered add-section-multiple 
action with user links by {user} on {diff}',
+                                               array(
+                                                       'user' => 
$user->getName(),
+                                                       'diff' => $diffUrl,
+                                                       'user-links' => 
$userLinks,
+                                               )
+                                       );
+                               }
                        }
                }
 
@@ -417,9 +436,8 @@
         *    existing section.
         * - new-section-with-comment: A new section is added, containing
         *    a single comment signed by the user in question.
-        * - unknown-signed-addition: Some signed content is added, but it
-        *    includes section headers, is signed by another user or
-        *    otherwise confuses the interpretation engine.
+        * - add-section-multiple: A new section or additions to a section
+        *    while editing multiple sections at once.
         * - unknown-multi-signed-addition: Some signed content is added,
         *    but it contains multiple signatures.
         * - unknown-unsigned-addition: Some content is added, but it is
@@ -470,10 +488,26 @@
                                                        'content' => $content,
                                                );
                                        } else {
-                                               $actions[] = array(
-                                                       'type' => 
'unknown-signed-addition',
-                                                       'content' => $content,
-                                               );
+                                               $sectionData = 
self::extractSections( $content );
+                                               foreach ( $sectionData as 
$section ) {
+                                                       $sectionSignedUsers = 
self::extractSignatures( $section['content'], $title );
+                                                       if ( !empty( 
$sectionSignedUsers ) ) {
+                                                               if ( 
!$section['header'] ) {
+                                                                       
$fullSection = self::getFullSection( $changes['_info']['rhs'], 
$change['right-pos'] );
+                                                                       
$section['header'] = self::extractHeader( $fullSection );
+                                                               }
+                                                               $actions[] = 
array(
+                                                                       'type' 
=> 'add-section-multiple',
+                                                                       
'content' => $section['content'],
+                                                                       
'header' => $section['header'],
+                                                               );
+                                                       } else {
+                                                               $actions[] = 
array(
+                                                                       'type' 
=> 'unknown-unsigned-addition',
+                                                                       
'content' => $section['content'],
+                                                               );
+                                                       }
+                                               }
                                        }
                                } elseif ( count( $signedUsers ) >= 1 ) {
                                        $actions[] = array(
@@ -580,6 +614,49 @@
        }
 
        /**
+        * Extracts sections and their contents from text.
+        *
+        * @param string $text The text to parse.
+        * @return array[]
+        * Array of arrays containing sections with header and content.
+        * - [header]: The full header string of the section or false if there 
is preceding text without header.
+        * - [content]: The content of the section including the header string.
+        */
+       private static function extractSections( $text ) {
+               $matches = array();
+
+               if ( !preg_match_all( '/' . self::HEADER_REGEX . '/um', $text, 
$matches, PREG_OFFSET_CAPTURE ) ) {
+                       return array( array(
+                               'header' => false,
+                               'content' => $text
+                       ) );
+               }
+
+               $sectionNum = count( $matches[0] );
+               $sections = array();
+
+               if ( $matches[0][0][1] > 1 ) { // is there text before the 
first headline?
+                       $sections[] = array(
+                               'header' => false,
+                               'content' =>  substr( $text, 0, 
$matches[0][0][1] - 1 )
+                       );
+               }
+               for ( $i = 0; $i < $sectionNum; $i++ ) {
+                       if ( $i + 1 < $sectionNum ) {
+                               $content = substr( $text, $matches[0][$i][1], 
$matches[0][$i + 1][1] - $matches[0][$i][1] );
+                       } else {
+                               $content = substr( $text, $matches[0][$i][1] );
+                       }
+                       $sections[] = array(
+                               'header' => $matches[0][$i][0],
+                               'content' =>  trim( $content )
+                       );
+               }
+
+               return $sections;
+       }
+
+       /**
         * Strips out a signature if possible.
         *
         * @param string $text The wikitext to strip
diff --git a/tests/phpunit/DiscussionParserTest.php 
b/tests/phpunit/DiscussionParserTest.php
index 4f35aed..e93463b 100644
--- a/tests/phpunit/DiscussionParserTest.php
+++ b/tests/phpunit/DiscussionParserTest.php
@@ -377,12 +377,14 @@
                                                'agent' => 'Admin',
                                                'section-title' => 'Hello 
Users',
                                                'notifyAgent' => true,
+                                               'subject-name' => 'Ping',
                                        ),
                                        array(
                                                'type' => 'mention-failure',
                                                'agent' => 'Admin',
                                                'section-title' => 'Hello 
Users',
                                                'notifyAgent' => true,
+                                               'subject-name' => 'Po?ng',
                                        ),
                                ),
                        ),
@@ -399,12 +401,14 @@
                                                'agent' => 'Admin',
                                                'section-title' => 'Hello 
Users',
                                                'notifyAgent' => null,
+                                               'subject-name' => null,
                                        ),
                                        array(
                                                'type' => 'mention-success',
                                                'agent' => 'Admin',
                                                'section-title' => 'Hello 
Users',
                                                'notifyAgent' => true,
+                                               'subject-name' => 'Test11',
                                        ),
                                ),
                        ),
@@ -421,6 +425,7 @@
                                                'agent' => 'Admin',
                                                'section-title' => 'Section 2',
                                                'notifyAgent' => true,
+                                               'subject-name' => 'NoUser',
                                        ),
                                ),
                        ),
@@ -437,6 +442,7 @@
                                                'agent' => 'Admin',
                                                'section-title' => 'Section 2',
                                                'notifyAgent' => true,
+                                               'subject-name' => 'NoUser',
                                        ),
                                ),
                        ),
@@ -468,7 +474,8 @@
                                        'type' => $event->getType(),
                                        'agent' => 
$event->getAgent()->getName(),
                                        'section-title' => 
$event->getExtraParam( 'section-title' ),
-                                       'notifyAgent' => $event->getExtraParam( 
'notifyAgent' )
+                                       'notifyAgent' => $event->getExtraParam( 
'notifyAgent' ),
+                                       'subject-name' => 
$event->getExtraParam( 'subject-name' ),
                                );
                                return false;
                        }
@@ -482,6 +489,170 @@
                $this->assertEquals( $expected, $events );
        }
 
+       public function provider_extractSections() {
+               return array(
+                       array(
+                               'content' => 'Just Text.',
+                               'result' => array(
+                                       array(
+                                               'header' => false,
+                                               'content' => 'Just Text.',
+                                       ),
+                               ),
+                       ),
+                       array(
+                               'content' =>
+<<<TEXT
+Text and a
+== Headline ==
+with text
+TEXT
+                               ,
+                               'result' => array(
+                                       array(
+                                               'header' => false,
+                                               'content' =>
+<<<TEXT
+Text and a
+TEXT
+                                               ,
+                                       ),
+                                       array(
+                                               'header' => '== Headline ==',
+                                               'content' =>
+<<<TEXT
+== Headline ==
+with text
+TEXT
+                                               ,
+                                       ),
+                               ),
+                       ),
+                       array(
+                               'content' =>
+<<<TEXT
+== Headline ==
+Text and a [[User:Test]]
+TEXT
+                       ,
+                               'result' => array(
+                                       array(
+                                               'header' => '== Headline ==',
+                                               'content' =>
+<<<TEXT
+== Headline ==
+Text and a [[User:Test]]
+TEXT
+                                       ,
+                                       ),
+                               ),
+                       ),
+                       array(
+                               'content' =>
+<<<TEXT
+Content 0
+== Headline 1 ==
+Content 1
+=== Headline 2 ===
+Content 2
+TEXT
+                       ,
+                               'result' => array(
+                                       array(
+                                               'header' => false,
+                                               'content' => 'Content 0',
+                                       ),
+                                       array(
+                                               'header' => '== Headline 1 ==',
+                                               'content' =>
+<<<TEXT
+== Headline 1 ==
+Content 1
+TEXT
+                                       ,
+                                       ),
+                                       array(
+                                               'header' => '=== Headline 2 
===',
+                                               'content' =>
+<<<TEXT
+=== Headline 2 ===
+Content 2
+TEXT
+                                       ,
+                                       ),
+                               ),
+                       ),
+                       array(
+                               'content' =>
+<<<TEXT
+== Headline 1 ==
+مرحبا كيف حالك 
+=== Headline 2 ===
+انا بخير شكرا
+TEXT
+                       ,
+                               'result' => array(
+                                       array(
+                                               'header' => '== Headline 1 ==',
+                                               'content' =>
+<<<TEXT
+== Headline 1 ==
+مرحبا كيف حالك
+TEXT
+                                       ,
+                                       ),
+                                       array(
+                                               'header' => '=== Headline 2 
===',
+                                               'content' =>
+<<<TEXT
+=== Headline 2 ===
+انا بخير شكرا
+TEXT
+                                       ,
+                                       ),
+                               ),
+                       ),
+                       array(
+                               'content' =>
+<<<TEXT
+مرحبا كيف حالك
+=== Headline 1 ===
+انا بخير شكرا
+TEXT
+                       ,
+                               'result' => array(
+                                       array(
+                                               'header' => false,
+                                               'content' =>
+<<<TEXT
+مرحبا كيف حالك
+TEXT
+                                       ,
+                                       ),
+                                       array(
+                                               'header' => '=== Headline 1 
===',
+                                               'content' =>
+<<<TEXT
+=== Headline 1 ===
+انا بخير شكرا
+TEXT
+                                       ,
+                                       ),
+                               ),
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider provider_extractSections
+        */
+       public function testExtractSections( $content, $result ) {
+               $discussionParser = TestingAccessWrapper::newFromClass( 
'EchoDiscussionParser' );
+               $sections = $discussionParser->extractSections( $content );
+
+               $this->assertEquals( $result, $sections );
+       }
+
        public function testGenerateEventsForRevision_tooManyMentionsFailure() {
                $expected = array(
                        array(

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib06cd855b2c7fbd51d8ab6602882cb38aadf8350
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/extensions/Echo
Gerrit-Branch: master
Gerrit-Owner: WMDE-Fisch <christoph.fisc...@wikimedia.de>
Gerrit-Reviewer: Addshore <addshorew...@gmail.com>
Gerrit-Reviewer: Catrope <roan.katt...@gmail.com>
Gerrit-Reviewer: Gabriel Birke <gabriel.bi...@wikimedia.de>
Gerrit-Reviewer: Jakob <jakob.warkot...@wikimedia.de>
Gerrit-Reviewer: Kai Nissen (WMDE) <kai.nis...@wikimedia.de>
Gerrit-Reviewer: Tobias Gritschacher <tobias.gritschac...@wikimedia.de>
Gerrit-Reviewer: WMDE-Fisch <christoph.fisc...@wikimedia.de>
Gerrit-Reviewer: WMDE-leszek <leszek.mani...@wikimedia.de>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to