From b52fd0ea6fc59ae9bed517d11144595b4ba76b82 Mon Sep 17 00:00:00 2001 From: Stephane Bisson Date: Thu, 16 Jun 2016 12:12:38 -0400 Subject: [PATCH] Make thanks notifications expandable bundles * edit-thank * flow-thank Bug: T120152 Depends-On: I1507cae360f45cc87f2d60e966b4d047abfa202d Depends-On: I91abb2dded9ab7f124aaa798dd07c52576ee791b Change-Id: I21e36d1874967495d9541f621481cfccf54b7f19 --- ApiFlowThank.php | 14 ++++++-- ApiRevThank.php | 1 + FlowThanksPresentationModel.php | 36 +++++++++++++++---- Thanks.hooks.php | 35 ++++++++++++++++++ ThanksPresentationModel.php | 64 ++++++++++++++++++++++++++++++--- extension.json | 3 ++ i18n/en.json | 8 +++-- i18n/qqq.json | 4 +++ 8 files changed, 150 insertions(+), 15 deletions(-) diff --git a/ApiFlowThank.php b/ApiFlowThank.php index ab5b422f..b8c5a289 100644 --- a/ApiFlowThank.php +++ b/ApiFlowThank.php @@ -50,13 +50,19 @@ class ApiFlowThank extends ApiThank { $topicTitleText = $this->getLanguage()->truncate( $rawTopicTitleText, 200 ); $pageTitle = $this->getPageTitleFromRootPost( $rootPost ); + /** @var PostRevision $post */ + $post = $data['post']; + $postText = Utils::htmlToPlaintext( $post->getContent() ); + $postText = $this->getLanguage()->truncate( $postText, 200 ); + $this->sendThanks( $user, $recipient, $postId, $workflowId, $topicTitleText, - $pageTitle + $pageTitle, + $postText ); } @@ -111,9 +117,12 @@ class ApiFlowThank extends ApiThank { * @param UUID $workflowId * @param string $topicTitleText * @param Title $pageTitle + * @param string $postTextExcerpt + * @throws FlowException + * @throws MWException */ private function sendThanks( User $user, User $recipient, UUID $postId, UUID $workflowId, - $topicTitleText, Title $pageTitle ) { + $topicTitleText, Title $pageTitle, $postTextExcerpt ) { $uniqueId = "flow-{$postId->getAlphadecimal()}"; // Do one last check to make sure we haven't sent Thanks before @@ -132,6 +141,7 @@ class ApiFlowThank extends ApiThank { 'workflow' => $workflowId->getAlphadecimal(), 'thanked-user-id' => $recipient->getId(), 'topic-title' => $topicTitleText, + 'excerpt' => $postTextExcerpt, ], 'agent' => $user, ] ); diff --git a/ApiRevThank.php b/ApiRevThank.php index 63670f31..febe3562 100644 --- a/ApiRevThank.php +++ b/ApiRevThank.php @@ -90,6 +90,7 @@ class ApiRevThank extends ApiThank { 'revid' => $revision->getId(), 'thanked-user-id' => $recipient->getId(), 'source' => $source, + 'excerpt' => EchoDiscussionParser::getEditExcerpt( $revision, $this->getLanguage() ), ], 'agent' => $user, ] ); diff --git a/FlowThanksPresentationModel.php b/FlowThanksPresentationModel.php index 89ef8153..543f46f4 100644 --- a/FlowThanksPresentationModel.php +++ b/FlowThanksPresentationModel.php @@ -10,16 +10,36 @@ class EchoFlowThanksPresentationModel extends Flow\FlowPresentationModel { } public function getHeaderMessage() { - $msg = parent::getHeaderMessage(); - - $truncatedTopicTitle = $this->getTopicTitle(); - $msg->plaintextParams( $truncatedTopicTitle ); - $msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) ); + if ( $this->isBundled() ) { + $msg = $this->msg( 'notification-bundle-header-flow-thank' ); + $msg->params( $this->getBundleCount() ); + $msg->plaintextParams( $this->getTopicTitle() ); + $msg->params( $this->getViewingUserForGender() ); + return $msg; + } else { + $msg = parent::getHeaderMessage(); + $msg->plaintextParams( $this->getTopicTitle() ); + $msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) ); + $msg->params( $this->getViewingUserForGender() ); + return $msg; + } + } + public function getCompactHeaderMessage() { + $msg = parent::getCompactHeaderMessage(); $msg->params( $this->getViewingUserForGender() ); return $msg; } + public function getBodyMessage() { + $excerpt = $this->event->getExtraParam( 'excerpt' ); + if ( $excerpt ) { + $msg = new RawMessage( '$1' ); + $msg->plaintextParams( $excerpt ); + return $msg; + } + } + public function getPrimaryLink() { $title = $this->event->getTitle(); // Make a link to #flow-post-{postid} @@ -38,6 +58,10 @@ class EchoFlowThanksPresentationModel extends Flow\FlowPresentationModel { } public function getSecondaryLinks() { - return [ $this->getAgentLink(), $this->getBoardLink() ]; + if ( $this->isBundled() ) { + return [ $this->getBoardLink() ]; + } else { + return [ $this->getAgentLink(), $this->getBoardLink() ]; + } } } diff --git a/Thanks.hooks.php b/Thanks.hooks.php index 45d87552..3f2b28d9 100644 --- a/Thanks.hooks.php +++ b/Thanks.hooks.php @@ -1,4 +1,6 @@ 'notification-thanks-email-batch-body', 'email-body-batch-params' => [ 'agent', 'title' ], 'icon' => 'thanks', + 'bundle' => [ + 'web' => true, + 'expandable' => true, + ], ]; $notifications['flow-thank'] = [ @@ -203,6 +209,10 @@ class ThanksHooks { 'email-body-batch-message' => 'notification-flow-thanks-email-batch-body', 'email-body-batch-params' => [ 'agent', 'topictitle', 'title', 'user' ], 'icon' => 'thanks', + 'bundle' => [ + 'web' => true, + 'expandable' => true, + ], ]; $icons['thanks'] = [ @@ -339,4 +349,29 @@ class ThanksHooks { } return true; } + + /** + * Handler for EchoGetBundleRule hook, which defines the bundle rules for each notification + * + * @param $event EchoEvent + * @param $bundleString string Determines how the notification should be bundled + * @return boolean True for success + */ + public static function onEchoGetBundleRules( $event, &$bundleString ) { + switch ( $event->getType() ) { + case 'edit-thank': + $revId = $event->getExtraParam( 'revid' ); + if ( $revId ) { + $bundleString = $event->getExtraParam( 'revid' ); + } + break; + case 'flow-thank': + $postId = $event->getExtraParam( 'post-id' ); + if ( $postId ) { + $bundleString = $postId; + } + break; + } + return true; + } } diff --git a/ThanksPresentationModel.php b/ThanksPresentationModel.php index af6fb4aa..ee6b2d0b 100644 --- a/ThanksPresentationModel.php +++ b/ThanksPresentationModel.php @@ -9,10 +9,59 @@ class EchoThanksPresentationModel extends EchoEventPresentationModel { } public function getHeaderMessage() { - $msg = parent::getHeaderMessage(); - $msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) ); - $msg->params( $this->getViewingUserForGender() ); - return $msg; + if ( $this->isBundled() ) { + $msg = $this->msg( 'notification-bundle-header-edit-thank' ); + $msg->params( $this->getBundleCount() ); + $msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) ); + $msg->params( $this->getViewingUserForGender() ); + return $msg; + } else { + $msg = $this->getMessageWithAgent( 'notification-header-edit-thank' ); + $msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) ); + $msg->params( $this->getViewingUserForGender() ); + return $msg; + } + } + + public function getBodyMessage() { + $comment = $this->getEditComment(); + if ( $comment ) { + $msg = new RawMessage( '$1' ); + $msg->plaintextParams( $comment ); + return $msg; + } + } + + private function getRevisionEditSummary() { + if ( !$this->userCan( Revision::DELETED_COMMENT ) ) { + return false; + } + + $revId = $this->event->getExtraParam( 'revid', false ); + if ( !$revId ) { + return false; + } + + $revision = Revision::newFromId( $revId ); + if ( !$revision ) { + return false; + } + + $summary = $revision->getComment( Revision::RAW ); + return $summary ?: false; + } + + private function getEditComment() { + // try to get edit summary + $summary = $this->getRevisionEditSummary(); + if ( $summary ) { + return $summary; + } + + // fallback on edit excerpt + if ( $this->userCan( Revision::DELETED_TEXT ) ) { + return $this->event->getExtraParam( 'excerpt', false ); + } } public function getPrimaryLink() { @@ -26,6 +75,11 @@ class EchoThanksPresentationModel extends EchoEventPresentationModel { } public function getSecondaryLinks() { - return [ $this->getAgentLink() ]; + $pageLink = $this->getPageLink( $this->event->getTitle(), null, true ); + if ( $this->isBundled() ) { + return [ $pageLink ]; + } else { + return [ $this->getAgentLink(), $pageLink ]; + } } } diff --git a/extension.json b/extension.json index aac9a61f..b27fb303 100644 --- a/extension.json +++ b/extension.json @@ -171,6 +171,9 @@ ], "ApiMain::moduleManager": [ "ThanksHooks::onApiMainModuleManager" + ], + "EchoGetBundleRules": [ + "ThanksHooks::onEchoGetBundleRules" ] }, "config": { diff --git a/i18n/en.json b/i18n/en.json index b5d4cb33..ed64880f 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -25,7 +25,9 @@ "echo-category-title-edit-thank": "Thanks", "notification-thanks-diff-link": "your edit", "notification-thanks": "[[User:$1|$1]] {{GENDER:$1|thanked}} you for $2 on [[:$3]].", - "notification-header-edit-thank": "$1 {{GENDER:$2|thanked}} {{GENDER:$4|you}} for your edit on '''$3'''.", + "notification-header-edit-thank": "$1 {{GENDER:$2|thanked}} {{GENDER:$4|you}} for your edit on $3.", + "notification-compact-header-edit-thank": "$1 {{GENDER:$2|thanked}} {{GENDER:$4|you}}.", + "notification-bundle-header-edit-thank": "{{PLURAL:$1|One person|$1 people|100=99+ people}} thanked {{GENDER:$3|you}} for your edit on $2.", "notification-thanks-email-subject": "$1 {{GENDER:$1|thanked}} you for your edit on {{SITENAME}}", "notification-thanks-email-batch-body": "$1 {{GENDER:$1|thanked}} you for your edit on $2.", "log-name-thanks": "Thanks log", @@ -40,7 +42,9 @@ "flow-thanks-thanked-notice": "$1 received your thanks for {{GENDER:$2|his|her|their}} comment.", "notification-flow-thanks": "[[User:$1|$1]] {{GENDER:$1|thanked}} {{GENDER:$5|you}} for $2 in \"$3\" on [[:$4]].", "notification-flow-thanks-post-link": "your comment", - "notification-header-flow-thank": "$1 {{GENDER:$2|thanked}} {{GENDER:$5|you}} for your comment in '''$3''' on '''$4'''.", + "notification-header-flow-thank": "$1 {{GENDER:$2|thanked}} {{GENDER:$5|you}} for your comment in \"$3\".", + "notification-compact-header-flow-thank": "$1 {{GENDER:$2|thanked}} {{GENDER:$3|you}}.", + "notification-bundle-header-flow-thank": "{{PLURAL:$1|One person|$1 people|100=99+ people}} thanked {{GENDER:$3|you}} for your comment in \"$2\".", "notification-flow-thanks-email-subject": "$1 {{GENDER:$1|thanked}} {{GENDER:$2|you}} for your comment on {{SITENAME}}", "notification-flow-thanks-email-batch-body": "$1 {{GENDER:$1|thanked}} {{GENDER:$4|you}} for your comment in \"$2\" on $3.", "apihelp-flowthank-description": "Send a public thank-you notification for a Flow comment.", diff --git a/i18n/qqq.json b/i18n/qqq.json index 8f8b8b21..5c4fd548 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -36,6 +36,8 @@ "notification-thanks-diff-link": "The text of a link to the user's edit.\n\nUsed for $2 in {{msg-mw|Notification-thanks}}. Should have capitalization appropriate for the middle of a sentence.\n\nThis is an object in a sentence so it should be in object case in languages where there is a special object form for words.", "notification-thanks": "Format for displaying notifications when a user is thanked for their edit. Parameters:\n* $1 is the username of the person sending the thanks, as plain text. Can be used for GENDER.\n* $2 is a link to the user's edit. The text of the link is {{msg-mw|Notification-thanks-diff-link}}.\n* $3 is the title of the page the user edited.", "notification-header-edit-thank": "Header text for a notification when a user is thanked for their edit. Parameters:\n* $1 is the username of the user sending the thanks (not suitable for GENDER).\n* $2 is the thanking user's name for use in GENDER.\n* $3 is the title of the page the thanked user edited.\n* $4 is the username of the user being thanked, for use in GENDER.", + "notification-compact-header-edit-thank": "Compact header text for a notification when a user is thanked for their edit. Parameters:\n* $1 is the username of the user sending the thanks (not suitable for GENDER).\n* $2 is the thanking user's name for use in GENDER.\n* $3 is the username of the user being thanked, for use in GENDER.", + "notification-bundle-header-edit-thank": "Bundle header text for a notification when a user is thanked for their edit. Parameters:\n* $1 is the number of users who sent thanks for the same edit. When used with PLURAL, the value 100 represents more than 99.\n* $2 is the title of the page the thanked user edited.\n* $3 is the username of the user being thanked, for use in GENDER.", "notification-thanks-email-subject": "E-mail subject. Parameters:\n* $1 is the username of the person sending the thanks, as plain text. Can be used for GENDER.", "notification-thanks-email-batch-body": "E-mail notification. Parameters:\n* $1 is the username of the person sending the thanks, as plain text. Can be used for GENDER.\n* $2 the title of the page the user edited.", "log-name-thanks": "Name of log that appears on [[Special:Log]].", @@ -51,6 +53,8 @@ "notification-flow-thanks": "Format for displaying notifications when a user is thanked for their comment on a Flow board.\n\nParameters:\n* $1 - the username of the person sending the thanks, as plain text. Can be used for GENDER.\n* $2 - a link to the comment. The text of the link is {{msg-mw|Notification-flow-thanks-post-link}}.\n* $3 - the title of the topic the comment belongs to\n* $4 - the title of the page where the comment is located\n* $5 - the username (of the thanked person ?). Can be used for GENDER.", "notification-flow-thanks-post-link": "The text of a link to the comment made by the user.\n\nUsed for $2 in {{msg-mw|notification-flow-thanks}}. Should have capitalization appropriate for the middle of a sentence.\n\nThis is an object in a sentence so it should be in object case in languages where there is a special object form for words.", "notification-header-flow-thank": "Header text for a notification when a user is thanked for their comment on a Flow board. Parameters:\n* $1 is the username of the user sending the thanks (not suitable for GENDER).\n* $2 is either unused by the translation, or is the thanking user's name for use in GENDER.\n* $3 is the title of the topic the comment belongs to\n* $4 is the title of the page where the comment is located\n* $5 is either unused by the translation, or is the username of the user being thanked, for use in GENDER.\n{{related|Notification-header-flow}}", + "notification-bundle-header-flow-thank": "Bundle header text for a notification when a user is thanked for their comment on a Flow board. Parameters:\n* $1 is the number of users who sent thanks for the same post. When used with PLURAL, the value 100 represents more than 99.\n* $2 is the title of the topic the comment belongs to\n* $3 is either unused by the translation, or is the username of the user being thanked, for use in GENDER.\n{{related|Notification-header-flow}}", + "notification-compact-header-flow-thank": "Compact header text for a notification when a user is thanked for their comment on a Flow board. Parameters:\n* $1 is the username of the user sending the thanks (not suitable for GENDER).\n* $2 is either unused by the translation, or is the thanking user's name for use in GENDER.\n* $3 is either unused by the translation, or is the username of the user being thanked, for use in GENDER.\n{{related|Notification-header-flow-thank}}", "notification-flow-thanks-email-subject": "Email subject when a user is thanked for a comment on a Flow board. Parameters:\n* $1 - the username of the person sending the thanks, as plain text. Can be used for GENDER.\n* $2 - the username. Can be used for GENDER.", "notification-flow-thanks-email-batch-body": "Email notification. Parameters:\n* $1 - the username of the person sending the thanks, as plain text. Can be used for GENDER.\n* $2 - the title of the topic the comment belongs to\n* $3 - the title of the page where the comment is located\n* $4 - the username. Can be used for GENDER.", "apihelp-flowthank-description": "{{doc-apihelp-description|flowthank}}",