Bsitu has uploaded a new change for review.
https://gerrit.wikimedia.org/r/70112
Change subject: Add HTML email support to Echo notification
......................................................................
Add HTML email support to Echo notification
-2ed as this needs testing and some code update
Change-Id: Ia4b98b14e135742b84f1b0e04589b0efdd24e954
---
M Echo.i18n.php
M Echo.php
M Notifier.php
M formatters/BasicFormatter.php
M formatters/CommentFormatter.php
M formatters/EditFormatter.php
M formatters/NotificationFormatter.php
A includes/EmailFormatter.php
8 files changed, 546 insertions(+), 201 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Echo
refs/changes/12/70112/1
diff --git a/Echo.i18n.php b/Echo.i18n.php
index b8de66e..01e6c84 100644
--- a/Echo.i18n.php
+++ b/Echo.i18n.php
@@ -91,56 +91,15 @@
'notification-new-user' => "Welcome to {{SITENAME}}, $1! We're glad
you're here.",
'notification-reverted2' => 'Your {{PLURAL:$4|edit on [[:$2]] has|edits
on [[:$2]] have}} been {{GENDER:$1|reverted}} by [[User:$1|$1]] $3',
'notification-reverted-flyout2' => 'Your {{PLURAL:$4|edit on $2
has|edits on $2 have}} been {{GENDER:$1|reverted}} by $1 $3',
- 'notification-edit-talk-page-email-subject2' => 'You have a new
talkpage message on {{SITENAME}}',
- 'notification-edit-talk-page-email-body2' => '$1
-
-$3
-
-View more:
-
-<$2>
-
-$4',
- 'notification-edit-talk-page-email-batch-body2' => '$1
{{GENDER:$1|posted}} on your talk page',
+ 'notification-edit-talk-page-email-subject2' => '$1 {{GENDER:$1|left}}
you a message on {{SITENAME}}',
+ 'notification-edit-talk-page-email-batch-body2' => '$1
{{GENDER:$1|left}} a message on your talk page',
'notification-page-linked-email-subject' => 'A page you started was
linked on {{SITENAME}}',
- 'notification-page-linked-email-body' => '$1
-
-See all links to this page:
-
-{{canonicalurl:{{#special:WhatLinksHere/$2}}}}
-
-$3',
'notification-page-linked-email-batch-body' => '$2 was
{{GENDER:$1|linked}} from $3',
'notification-reverted-email-subject2' => 'Your {{PLURAL:$3|edit on $2
was|edits on $2 were}} {{GENDER:$1|reverted}} by $1 on {{SITENAME}}',
- 'notification-reverted-email-body2' => 'Your {{PLURAL:$7|edit on $2 has
been|edits on $2 have been}} {{GENDER:$1|reverted}} by $1.
-
-$5
-
-View more:
-
-<$3>
-
-$6',
'notification-reverted-email-batch-body2' => 'Your {{PLURAL:$3|edit on
$2 was|edits on $2 were}} {{GENDER:$1|reverted}} by $1',
'notification-mention-email-subject' => '$1 {{GENDER:$1|mentioned}} you
on {{SITENAME}}',
- 'notification-mention-email-body' => '{{SITENAME}} user $1
{{GENDER:$1|mentioned}} you on $2.
-
-$3
-
-View more:
-
-<$4>
-
-$5',
'notification-mention-email-batch-body' => '$1 {{GENDER:$1|mentioned}}
you on $2',
'notification-user-rights-email-subject' => 'Your user rights have
changed on {{SITENAME}}',
- 'notification-user-rights-email-body' => 'Your user rights were
{{GENDER:$1|changed}} by $1. $2
-
-View more:
-
-{{canonicalurl:{{#special:ListGroupRights}}}}
-
-$3',
'notification-user-rights-email-batch-body' => 'Your user rights were
{{GENDER:$1|changed}} by $1. $2',
'echo-notification-count' => '$1+',
// Email notification
@@ -154,6 +113,8 @@
To control which emails we send you, check your preferences:
{{canonicalurl:{{#special:Preferences}}#mw-prefsection-echo}}
+$1',
+ 'echo-email-footer-default-html' => 'To control which emails we send
you, <a href="$2" style="text-decoration:none;">check your preferences</a><br />
$1',
// Notifications overlay
'echo-overlay-link' => 'All notifications',
@@ -318,8 +279,7 @@
See also:
* {{msg-mw|Notification-page-linked-flyout}}
* {{msg-mw|Notification-page-linked-email-batch-body}}
-* {{msg-mw|Notification-page-linked-email-subject}}
-* {{msg-mw|Notification-page-linked-email-body}}',
+* {{msg-mw|Notification-page-linked-email-subject}}',
'notification-page-linked-flyout' => 'Flyout-specific format for
displaying notifications of articles being linked
* $1 is the username of the person who linked the page, plain text. Can be
used for GENDER.
* $2 is the page being linked
@@ -327,8 +287,7 @@
See also:
* {{msg-mw|Notification-page-linked}}
* {{msg-mw|Notification-page-linked-email-batch-body}}
-* {{msg-mw|Notification-page-linked-email-subject}}
-* {{msg-mw|Notification-page-linked-email-body}}',
+* {{msg-mw|Notification-page-linked-email-subject}}',
'notification-add-comment2' => 'Format for displaying notifications of
a comment being added to an existing discussion. Parameters:
* $1 is the username of the person who edited, plain text. Can be used for
GENDER.
* $2 is the section title of the discussion,
@@ -391,11 +350,6 @@
* $4 is the number of edits that were reverted. NOTE: This will only be set to
1 or 2, with 2 actually meaning 'an unknown number greater than 0'.
{{Related|Notification-reverted}}",
'notification-edit-talk-page-email-subject2' => 'E-mail subject.',
- 'notification-edit-talk-page-email-body2' => 'E-mail notification.
Parameters:
-* $1 - the email intro, could be
{{msg-mw|notification-edit-talk-page-email-batch-body2}} or
{{msg-mw|notification-edit-user-talk-email-batch-bundle-body}}
-* <$2> - a link to a change
-* $3 - the edit summary
-* $4 - the e-mail footer, {{msg-mw|echo-email-footer-default}}',
'notification-edit-talk-page-email-batch-body2' => 'E-mail notification
for talk page edit
* $1 is a username
@@ -407,17 +361,7 @@
See also:
* {{msg-mw|Notification-page-linked}}
* {{msg-mw|Notification-page-linked-flyout}}
-* {{msg-mw|Notification-page-linked-email-batch-body}}
-* {{msg-mw|Notification-page-linked-email-body}}',
- 'notification-page-linked-email-body' => 'E-mail notification.
Parameters:
-* $1 is the email intro, could be
{{msg-mw|notification-page-linked-email-batch-body}} or
{{msg-mw|notification-page-linked-email-batch-bundle-body}}
-* $2 is the page being linked.
-* $3 is the e-mail footer, {{msg-mw|echo-email-footer-default}}.
-See also:
-* {{msg-mw|Notification-page-linked}}
-* {{msg-mw|Notification-page-linked-flyout}}
-* {{msg-mw|Notification-page-linked-email-batch-body}}
-* {{msg-mw|Notification-page-linked-email-subject}}',
+* {{msg-mw|Notification-page-linked-email-batch-body}}',
'notification-page-linked-email-batch-body' => 'E-mail notification for
page being linked. Parameters:
* $1 is the username of the person who linked the page, plain text. Can be
used for GENDER.
* $2 is the page being linked.
@@ -425,22 +369,12 @@
See also:
* {{msg-mw|Notification-page-linked}}
* {{msg-mw|Notification-page-linked-flyout}}
-* {{msg-mw|Notification-page-linked-email-subject}}
-* {{msg-mw|Notification-page-linked-email-body}}',
+* {{msg-mw|Notification-page-linked-email-subject}}',
'notification-reverted-email-subject2' => 'E-mail subject. Parameters:
* $1 is a username
* $2 is a page title
* $3 is the number of revert
{{Related|Notification-reverted}}',
- 'notification-reverted-email-body2' => "E-mail notification. Parameters:
-* $1 is the username
-* $2 is the page title
-* <$3> is the link to the change
-* $4 is the e-mail recipient's username
-* $5 is the edit summary
-* $6 is the email footer, {{msg-mw|echo-email-footer-default}}
-* $7 is the number of revert
-{{Related|Notification-reverted}}",
'notification-reverted-email-batch-body2' => 'E-mail notification for
page revert. Parameters:
* $1 is a username
* $2 is a page title
@@ -452,20 +386,7 @@
See also:
* {{msg-mw|Notification-mention}}
* {{msg-mw|Notification-mention-flyout}}
-* {{msg-mw|Notification-mention-email-batch-body}}
-* {{msg-mw|Notification-mention-email-body}}',
- 'notification-mention-email-body' => 'E-mail notification. Parameters:
-* $1 is a username, plaintext. Can be used for gender support
-* $2 is talk page title
-* $3 is the edit summary
-* <$4> is the link to the talk page section title
-* $5 is the email footer
-
-See also:
-* {{msg-mw|Notification-mention}}
-* {{msg-mw|Notification-mention-flyout}}
-* {{msg-mw|Notification-mention-email-batch-body}}
-* {{msg-mw|Notification-mention-email-subject}}',
+* {{msg-mw|Notification-mention-email-batch-body}}',
'notification-mention-email-batch-body' => 'E-mail notification batch
body. Parameters:
* $1 is a username, plaintext. Can be used for gender support
* $2 is talk page title
@@ -473,25 +394,13 @@
See also:
* {{msg-mw|Notification-mention}}
* {{msg-mw|Notification-mention-flyout}}
-* {{msg-mw|Notification-mention-email-body}}
* {{msg-mw|Notification-mention-email-subject}}',
'notification-user-rights-email-subject' => 'E-mail subject for user
rights notification
See also:
* {{msg-mw|Notification-user-rights}}
* {{msg-mw|Notification-user-rights-flyout}}
-* {{msg-mw|Notification-user-rights-email-batch-body}}
-* {{msg-mw|Notification-user-rights-email-body}}',
- 'notification-user-rights-email-body' => 'E-mail notification.
Parameters:
-* $1 - a user name, plaintext. Can be used for gender support
-* $2 - a semicolon separated list of {{msg-mw|notification-user-rights-add}},
{{msg-mw|notification-user-rights-remove}}
-* $3 - the email footer
-
-See also:
-* {{msg-mw|Notification-user-rights}}
-* {{msg-mw|Notification-user-rights-flyout}}
-* {{msg-mw|Notification-user-rights-email-batch-body}}
-* {{msg-mw|Notification-user-rights-email-subject}}',
+* {{msg-mw|Notification-user-rights-email-batch-body}}',
'notification-user-rights-email-batch-body' => 'Email notification
batch body. Parameters:
* $1 is a user name, plaintext. Can be used for gender support
* $2 is a semicolon separated list of {{msg-mw|notification-user-rights-add}},
{{msg-mw|notification-user-rights-remove}}',
@@ -502,9 +411,12 @@
'echo-email-body-default' => 'Default message content for Echo e-mail
notifications.
* $1 is a plain text description of the notification.',
'echo-email-batch-body-default' => 'Default message for Echo e-mail
digest notifications',
- 'echo-email-footer-default' => 'Default footer content for Echo e-mail
notifications. Parameters:
+ 'echo-email-footer-default' => 'Default footer content for Echo text
e-mail notifications. Parameters:
* $1 is the address of the organization that sent the e-mail
* $2 is "-------..." ({{msg-mw|echo-email-batch-separator}})',
+ 'echo-email-footer-default-html' => 'Default footer content for Echo
html e-mail notifications. Parameters:
+* $1 is the address of the organization that sent the e-mail
+* $2 is the url to the notification preference page',
'echo-overlay-link' => 'Link to "all notifications" at the bottom of
the overlay.
{{Identical|All notifications}}',
'echo-overlay-title' => 'Title at the top of the notifications overlay.
Should include bold tags.',
@@ -526,8 +438,7 @@
See also:
* {{msg-mw|Notification-edit-talk-page2}}
* {{msg-mw|Notification-edit-talk-page-email-batch-body2}}
-* {{msg-mw|Notification-edit-talk-page-email-subject2}}
-* {{msg-mw|Notification-edit-talk-page-email-body2}}',
+* {{msg-mw|Notification-edit-talk-page-email-subject2}}',
'notification-page-linked-bundle' => 'Bundled message for page-linked
notification. Parameters:
* $1 - the username who performs the action, which can be used for gender
support
* $2 - the page title
@@ -549,8 +460,7 @@
* {{msg-mw|Notification-edit-talk-page2}}
* {{msg-mw|Notification-edit-talk-page-flyout2}}
* {{msg-mw|Notification-edit-talk-page-email-batch-body2}}
-* {{msg-mw|Notification-edit-talk-page-email-subject2}}
-* {{msg-mw|Notification-edit-talk-page-email-body2}}',
+* {{msg-mw|Notification-edit-talk-page-email-subject2}}',
'notification-page-linked-email-batch-bundle-body' => 'Bundled message
for page-linked email digest notification. Parameters:
* $1 - the username who performs the action, which can be used for gender
support
* $2 - the link-to page title
@@ -562,8 +472,7 @@
* {{msg-mw|Notification-page-linked}}
* {{msg-mw|Notification-page-linked-flyout}}
* {{msg-mw|Notification-page-linked-email-batch-body}}
-* {{msg-mw|Notification-page-linked-email-subject}}
-* {{msg-mw|Notification-page-linked-email-body}}',
+* {{msg-mw|Notification-page-linked-email-subject}}',
'echo-email-batch-separator' => '{{optional}}
Email batch content separator',
'echo-email-batch-bullet' => '{{optional}}',
diff --git a/Echo.php b/Echo.php
index 1843b2b..de18e60 100755
--- a/Echo.php
+++ b/Echo.php
@@ -61,6 +61,14 @@
$wgAutoloadClasses['EchoUserRightsFormatter'] = $dir .
'formatters/UserRightsFormatter.php';
$wgAutoloadClasses['EchoPageLinkFormatter'] = $dir .
'formatters/PageLinkFormatter.php';
+// Email formatters
+$wgAutoloadClasses['EchoEmailFormatter'] = $dir .
'includes/EmailFormatter.php';
+$wgAutoloadClasses['EchoTextEmailFormatter'] = $dir .
'includes/EmailFormatter.php';
+$wgAutoloadClasses['EchoHTMLEmailFormatter'] = $dir .
'includes/EmailFormatter.php';
+$wgAutoloadClasses['EchoEmailMode'] = $dir . 'includes/EmailFormatter.php';
+$wgAutoloadClasses['EchoEmailSingle'] = $dir . 'includes/EmailFormatter.php';
+$wgAutoloadClasses['EchoEmailDigest'] = $dir . 'includes/EmailFormatter.php';
+
// Internal stuff
$wgAutoloadClasses['EchoNotifier'] = $dir . 'Notifier.php';
$wgAutoloadClasses['EchoNotificationController'] = $dir .
'controller/NotificationController.php';
@@ -432,8 +440,7 @@
'flyout-message' => 'notification-edit-talk-page-flyout2',
'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' ),
+ 'email-subject-params' => array( 'agent' ),
'email-body-batch-message' =>
'notification-edit-talk-page-email-batch-body2',
'email-body-batch-params' => array( 'agent' ),
'email-body-batch-bundle-message' =>
'notification-edit-user-talk-email-batch-bundle-body',
@@ -452,8 +459,6 @@
'flyout-params' => array( 'agent', 'title', 'difflink',
'number' ),
'email-subject-message' =>
'notification-reverted-email-subject2',
'email-subject-params' => array( 'agent', 'title', 'number' ),
- 'email-body-message' => 'notification-reverted-email-body2',
- 'email-body-params' => array( 'agent', 'title', 'difflink',
'user', 'summary', 'email-footer', 'number' ),
'email-body-batch-message' =>
'notification-reverted-email-batch-body2',
'email-body-batch-params' => array( 'agent', 'title', 'number'
),
'icon' => 'revert',
@@ -473,8 +478,6 @@
'flyout-params' => array( 'agent', 'title', 'link-from-page' ),
'email-subject-message' =>
'notification-page-linked-email-subject',
'email-subject-params' => array(),
- 'email-body-message' => 'notification-page-linked-email-body',
- 'email-body-params' => array( 'email-intro', 'title',
'email-footer', 'link-from-page' ),
'email-body-batch-message' =>
'notification-page-linked-email-batch-body',
'email-body-batch-params' => array( 'agent', 'title',
'link-from-page' ),
'email-body-batch-bundle-message' =>
'notification-page-linked-email-batch-bundle-body',
@@ -494,8 +497,6 @@
'flyout-params' => array( 'agent', 'subject-anchor', 'title' ),
'email-subject-message' => 'notification-mention-email-subject',
'email-subject-params' => array( 'agent' ),
- 'email-body-message' => 'notification-mention-email-body',
- 'email-body-params' => array( 'agent', 'title', 'summary',
'subject-link', 'email-footer' ),
'email-body-batch-message' =>
'notification-mention-email-batch-body',
'email-body-batch-params' => array( 'agent', 'title' ),
'icon' => 'chat',
@@ -512,8 +513,6 @@
'flyout-params' => array( 'agent', 'user-rights-list' ),
'email-subject-message' =>
'notification-user-rights-email-subject',
'email-subject-params' => array(),
- 'email-body-message' => 'notification-user-rights-email-body',
- 'email-body-params' => array( 'agent', 'user-rights-list',
'email-footer' ),
'email-body-batch-message' =>
'notification-user-rights-email-batch-body',
'email-body-batch-params' => array( 'agent', 'user-rights-list'
),
'icon' => 'site',
diff --git a/Notifier.php b/Notifier.php
index 2e4f03f..884382c 100644
--- a/Notifier.php
+++ b/Notifier.php
@@ -95,6 +95,8 @@
$subject = $email['subject'];
$body = $email['body'];
+ $body = array( 'text' => $body, 'html' =>
$email['body-html'] );
+
UserMailer::send( $toAddress, $fromAddress,
$subject, $body, $replyAddress );
MWEchoEventLogging::logSchemaEchoMail( $user,
'single' );
}
diff --git a/formatters/BasicFormatter.php b/formatters/BasicFormatter.php
index 7354e38..da2bd4b 100644
--- a/formatters/BasicFormatter.php
+++ b/formatters/BasicFormatter.php
@@ -8,15 +8,6 @@
class EchoBasicFormatter extends EchoNotificationFormatter {
/**
- * Required parameters
- * @param array
- */
- protected $requiredParameters = array(
- 'title-message',
- 'title-params'
- );
-
- /**
* Notification title data for archive page
* @param array
*/
@@ -34,11 +25,6 @@
protected $bundleTitle;
/**
- * @Todo Check if this varaible can be removed
- */
- protected $content;
-
- /**
* Notification email data
* @param array
*/
@@ -49,6 +35,15 @@
* @param string
*/
protected $icon;
+
+ /**
+ * Required parameters
+ * @param array
+ */
+ protected $requiredParameters = array (
+ 'title-message',
+ 'title-params'
+ );
/**
* Data for constructing bundle message, data in this array
@@ -92,10 +87,6 @@
'message' => $params['email-subject-message'],
'params' => $params['email-subject-params']
),
- 'body' => array(
- 'message' => $params['email-body-message'],
- 'params' => $params['email-body-params']
- ),
'batch-body' => array(
'message' =>
$params['email-body-batch-message'],
'params' => $params['email-body-batch-params']
@@ -124,8 +115,6 @@
'payload' => array(),
'email-subject-message' => 'echo-email-subject-default',
'email-subject-params' => array(),
- 'email-body-message' => 'echo-email-body-default',
- 'email-body-params' => array( 'text-notification' ),
'email-body-batch-message' =>
'echo-email-batch-body-default',
'email-body-batch-params' => array(),
'email-body-batch-bundle-message' => '',
@@ -261,25 +250,37 @@
}
/**
+ * Create text version and/or html version for email notification
+ *
* @param $event EchoEvent
* @param $user User
- * @param $type
+ * @param $type string
* @return array
*/
protected function formatEmail( $event, $user, $type ) {
- $subject = $this->formatFragment( $this->email['subject'],
$event, $user )->text();
-
- $body = preg_replace( "/\n{3,}/", "\n\n",
$this->formatFragment( $this->email['body'], $event, $user )->text() );
+ global $wgEchoNotifications;
if ( $this->bundleData['use-bundle'] &&
$this->email['batch-bundle-body'] ) {
- $bodyKey = $this->email['batch-bundle-body'];
+ $key = $this->email['batch-bundle-body'];
} else {
- $bodyKey = $this->email['batch-body'];
+ $key = $this->email['batch-body'];
}
- $batchBody = preg_replace( "/\n{3,}/", "\n\n",
$this->formatFragment( $bodyKey, $event, $user )->text() );
+ // Echo single email
+ $emailSingle = new EchoEmailSingle( $this, $event, $user );
- return array( 'subject' => $subject, 'body' => $body,
'batch-body' => $batchBody );
+ $content = array(
+ // Single email subject
+ 'subject' => $this->formatFragment(
$this->email['subject'], $event, $user )->escaped(),
+ // Single email text body
+ 'body' => EchoTextEmailFormatter::newFromEmailMode(
$emailSingle )->formatEmail(),
+ // Single email html body
+ 'body-html' =>
EchoHTMLEmailFormatter::newFromEmailMode( $emailSingle )->formatEmail(),
+ // Email digest text body
+ 'batch-body' => $this->formatFragment( $key, $event,
$user )->text()
+ );
+
+ return $content;
}
/**
@@ -290,7 +291,7 @@
* @param $user User to format the notification for.
* @return string
*/
- protected function formatFragment( $details, $event, $user ) {
+ public function formatFragment( $details, $event, $user ) {
$message = wfMessage( $details['message'] )
->inLanguage( $user->getOption( 'language' ) );
@@ -387,7 +388,6 @@
return Xml::tags( 'div', array( 'class' =>
'mw-echo-notification-footer' ), $footer ) . "\n";
}
-
/**
* Generate links based on output format and passed properties
* $event EchoEvent
@@ -414,10 +414,10 @@
}
$title->setFragment( "#$fragment" );
- if ( $this->outputFormat === 'html' || $this->outputFormat ===
'flyout' ) {
- $class = array();
- if ( isset( $props['class'] ) ) {
- $class['class'] = $props['class'];
+ if ( in_array( $this->outputFormat, array( 'html', 'flyout',
'htmlemail' ) ) ) {
+ $attribs = array();
+ if ( isset( $props['attribs'] ) ) {
+ $attribs = (array)$props['attribs'];
}
if ( isset( $props['linkText'] ) ) {
@@ -426,25 +426,38 @@
$linkText = htmlspecialchars(
$title->getPrefixedText() );
}
- $message->rawParams( Linker::link( $title, $linkText,
$class, $param ) );
- } elseif ( $this->outputFormat === 'email' ) {
- // plain text email in some mail client is messing with
- // ending punctuation in links, it is better to encode
them
- $url = $title->getCanonicalURL( $param );
- // $url should contain all ascii characters now, it's
safe to use substr()
- $lastChar = substr( $url, -1 );
- if ( $lastChar && !ctype_alnum( $lastChar ) ) {
- $lastChar = str_replace(
- array( '.', '-', '(', ';', '!', ':',
',' ),
- array( '%2E', '%2D', '%28', '%3B',
'%21', '%3A', '%2C' ),
- $lastChar
- );
- $url = substr( $url, 0, -1 ) . $lastChar;
+ $options = array();
+ if ( $this->outputFormat === 'htmlemail' ) {
+ $options = array( 'http' );
}
- $message->params( $url );
+
+ $message->rawParams( Linker::link( $title, $linkText,
$attribs, $param, $options ) );
+ } elseif ( $this->outputFormat === 'email' ) {
+ $url = $title->getCanonicalURL( $param );
+ $message->params( $this->sanitizeEmailLink( $url ) );
} else {
$message->params( $title->getFullURL( $param ) );
}
+ }
+
+ /**
+ * Plain text email in some mail client is misinterpreting the ending
+ * punctuation, this function would encode the last character
+ * @param $url string
+ * @param string
+ */
+ public function sanitizeEmailLink( $url ) {
+ // $url should contain all ascii characters now, it's safe to
use substr()
+ $lastChar = substr( $url, -1 );
+ if ( $lastChar && !ctype_alnum( $lastChar ) ) {
+ $lastChar = str_replace(
+ array( '.', '-', '(', ';', '!', ':', ',' ),
+ array( '%2E', '%2D', '%28', '%3B', '%21',
'%3A', '%2C' ),
+ $lastChar
+ );
+ $url = substr( $url, 0, -1 ) . $lastChar;
+ }
+ return $url;
}
/**
@@ -551,11 +564,12 @@
* 'border: 1px solid green; text-decoration: none;' (optional)
* @return String URL for link, or HTML for anchor tag, or empty string
*/
- protected function getLink( $event, $user, $rank = 'primary', $local =
true, $urlOnly = false, $style = '' ) {
+ public function getLink( $event, $user, $rank = 'primary', $local =
true, $urlOnly = false, $style = '' ) {
$destination = $event->getLinkDestination( $rank );
if ( !$destination ) {
return '';
}
+
// Get link parameters based on the destination
list( $target, $query ) = $this->getLinkParams( $event, $user,
$destination );
if ( !$target ) {
@@ -625,24 +639,37 @@
}
return array( $target, $query );
}
-
+
/**
* Helper function for processParams()
*
* @param $event EchoEvent
- * @param $param
+ * @param $param string
* @param $message Message
* @param $user User
* @throws MWException
*/
protected function processParam( $event, $param, $message, $user ) {
if ( $param === 'agent' ) {
- if ( !$event->getAgent() ) {
+ $agent = $event->getAgent();
+ if ( !$agent ) {
$message->params( wfMessage( 'echo-no-agent'
)->text() );
} elseif ( !$event->userCan( Revision::DELETED_USER,
$user ) ) {
$message->params( wfMessage( 'rev-deleted-user'
)->text() );
} else {
- $message->params( $event->getAgent()->getName()
);
+ if ( $this->outputFormat === 'htmlemail' ) {
+ $message->rawParams(
+ Linker::link(
+ $agent->getUserPage(),
+ $agent->getName(),
+ array( 'style' =>
'text-decoration: none;' ),
+ array(),
+ array( 'http' )
+ )
+ );
+ } else {
+ $message->params( $agent->getName() );
+ }
}
// example: {7} others, {99+} others
} elseif ( $param === 'agent-other-display') {
@@ -667,7 +694,14 @@
if ( !$event->getTitle() ) {
$message->params( wfMessage( 'echo-no-title'
)->text() );
} else {
- $message->params( $this->formatTitle(
$event->getTitle() ) );
+ if ( $this->outputFormat === 'htmlemail' ) {
+ $props = array (
+ 'attribs' => array( 'style' =>
'text-decoration: none;' )
+ );
+ $this->setTitleLink( $event, $message,
$props );
+ } else {
+ $message->params( $this->formatTitle(
$event->getTitle() ) );
+ }
}
} elseif ( $param === 'titlelink' ) {
$this->setTitleLink( $event, $message );
@@ -679,29 +713,20 @@
$this->setOutputFormat( $oldOutputFormat );
$message->params( $textNotification );
- } elseif ( $param === 'email-intro' ) {
- if ( $this->bundleData['use-bundle'] && isset(
$this->email['batch-bundle-body']['message'] ) ) {
- $detail = array(
- 'message' =>
$this->email['batch-bundle-body']['message'],
- 'params' =>
$this->email['batch-bundle-body']['params']
- );
- } else {
- $detail = array(
- 'message' =>
$this->email['batch-body']['message'],
- 'params' =>
$this->email['batch-body']['params']
- );
- }
- $message->params( $this->formatFragment( $detail,
$event, $user )->text() );
- } elseif ( $param === 'email-footer' ) {
- global $wgEchoEmailFooterAddress;
- $message->params(
- wfMessage( 'echo-email-footer-default' )
- ->inLanguage( $user->getOption( 'language' ) )
- ->params( $wgEchoEmailFooterAddress, wfMessage(
'echo-email-batch-separator' )->text() )
- ->text()
- );
} else {
throw new MWException( "Unrecognised parameter $param"
);
}
+ }
+
+ /**
+ * Getter method
+ * @param $key string
+ * @return mixed
+ */
+ public function getValue( $key ) {
+ if ( !property_exists( $this, $key ) ) {
+ throw new MWException( "Call to non-existing property
$key in " . get_class( $this ) );
+ }
+ return $this->$key;
}
}
diff --git a/formatters/CommentFormatter.php b/formatters/CommentFormatter.php
index 8e7f333..25a781e 100644
--- a/formatters/CommentFormatter.php
+++ b/formatters/CommentFormatter.php
@@ -8,10 +8,6 @@
$this->title['message-yours'] =
$params['title-message-yours'];
}
- if ( isset( $params['content-message-yours'] ) ) {
- $this->content['message-yours'] =
$params['content-message-yours'];
- }
-
if ( isset( $params['email-subject-message-yours'] ) ) {
$this->email['subject']['message-yours'] =
$params['email-subject-message-yours'];
}
diff --git a/formatters/EditFormatter.php b/formatters/EditFormatter.php
index 31dda39..5c02f65 100644
--- a/formatters/EditFormatter.php
+++ b/formatters/EditFormatter.php
@@ -18,7 +18,7 @@
return;
}
$props = array(
- 'class' => 'mw-echo-diff',
+ 'attribs' => array( 'class' => 'mw-echo-diff' ),
'linkText' => wfMessage( 'parentheses',
wfMessage( 'showdiff' )->text() )->escaped(),
'param' => array(
'oldid' => $revid,
diff --git a/formatters/NotificationFormatter.php
b/formatters/NotificationFormatter.php
index 775eb49..7f0b87e 100644
--- a/formatters/NotificationFormatter.php
+++ b/formatters/NotificationFormatter.php
@@ -12,7 +12,7 @@
* List of valid output format
* @var array
*/
- protected $validOutputFormats = array( 'text', 'flyout', 'html',
'email' );
+ protected $validOutputFormats = array( 'text', 'flyout', 'html',
'email', 'htmlemail' );
/**
* Current output format, default is 'text'
@@ -121,7 +121,7 @@
* @param User $user The user to format the notification for.
* @return String The revision comment (or empty string)
*/
- protected function formatRevisionComment( $event, $user ) {
+ public function formatRevisionComment( $event, $user ) {
$revision = $event->getRevision();
if ( $revision === null ) {
return '';
@@ -143,6 +143,11 @@
$comment = Xml::tags( 'div', array(
'class' => 'mw-echo-edit-summary' ), $comment );
}
}
+
+ if ( in_array( $this->outputFormat, array( 'htmlemail',
'email' ) ) && $comment ) {
+ $comment = wfMessage( 'echo-quotation-marks',
$comment )->inContentLanguage()->plain();
+ }
+
return $comment;
}
}
diff --git a/includes/EmailFormatter.php b/includes/EmailFormatter.php
new file mode 100644
index 0000000..93adcdb
--- /dev/null
+++ b/includes/EmailFormatter.php
@@ -0,0 +1,409 @@
+<?php
+
+/**
+ * Abstract class for formatting email notifications
+ */
+abstract class EchoEmailFormatter {
+
+ /**
+ * @var EchoEmailMode
+ */
+ public $emailMode;
+
+ /**
+ * @var EchoBasicFormatter
+ */
+ public $notifFormatter;
+
+ /**
+ * @param $emailMode EchoEmailMode
+ */
+ public function __construct( EchoEmailMode $emailMode ) {
+ $this->emailMode = $emailMode;
+ $this->notifFormatter = $emailMode->notifFormatter;
+ }
+
+ /**
+ * Factory method for creating EchoEmailFormatter
+ * @param $mode EchoEmailMode
+ * @return EchoEmailFormatter
+ */
+ public static function newFromEmailMode( EchoEmailMode $mode ) {
+ return new static( $mode );
+ }
+
+ /**
+ * Abstract method for formatting email
+ * @return string
+ */
+ abstract public function formatEmail();
+}
+
+/**
+ * Formatter class for formatting text email notification
+ */
+class EchoTextEmailFormatter extends EchoEmailFormatter {
+
+ /**
+ * @param $emailMode EchoEmailMode
+ */
+ public function __construct( EchoEmailMode $emailMode ) {
+ parent::__construct( $emailMode );
+ }
+
+ /**
+ * Formatting text email notification
+ * @return string
+ */
+ public function formatEmail() {
+
+ $template = $this->emailMode->getTextTemplate();
+
+ foreach ( $this->emailMode->component as $val ) {
+ $func = 'get' . ucfirst( $val );
+ $template = str_replace( "%%$val%%",
$this->emailMode->$func( 'text' ), $template );
+ }
+
+ // Remove redundant newline characters
+ return $this->removeExtraNewLine( $template );
+ }
+
+ /**
+ * Remove extra newline from a text content
+ * @param $text string
+ * @return string
+ */
+ protected function removeExtraNewLine( $text ) {
+ return preg_replace( "/\n{3,}/", "\n\n", $text );
+ }
+
+}
+
+/**
+ * Formatter class for formatting HTML email notification
+ */
+class EchoHTMLEmailFormatter extends EchoEmailFormatter {
+
+ /**
+ * @param $emailMode EchoEmailMode
+ */
+ public function __construct( EchoEmailMode $emailMode ) {
+ parent::__construct( $emailMode );
+ }
+
+ /**
+ * Formatting HTML email notification
+ * @return string
+ */
+ public function formatEmail() {
+ $outputFormat = $this->notifFormatter->getValue( 'outputFormat'
);
+ $this->notifFormatter->setOutputFormat( 'htmlemail' );
+
+ $template = $this->emailMode->getHTMLTemplate();
+
+ foreach ( $this->emailMode->component as $val ) {
+ $func = 'get' . ucfirst( $val );
+ $template = str_replace( "%%$val%%",
$this->emailMode->$func( 'html' ), $template );
+ }
+
+ $this->notifFormatter->setOutputFormat( $outputFormat );
+
+ return $template;
+ }
+}
+
+/**
+ * Abstract entity that represents an email delivery mode
+ */
+abstract class EchoEmailMode {
+
+ /**
+ * @var EchoBasicFormatter
+ */
+ public $notifFormatter;
+
+ /**
+ * Email components
+ * @var array
+ */
+ public $component;
+
+ /**
+ * @var EchoEvent
+ */
+ public $event;
+
+ /**
+ * @var User
+ */
+ public $user;
+
+ /**
+ * @param $notifFormatter EchoBasicFormatter
+ * @param $event EchoEvent
+ * @param $user User
+ */
+ public function __construct( EchoBasicFormatter $notifFormatter,
EchoEvent $event, User $user ) {
+ $this->notifFormatter = $notifFormatter;
+ $this->event = $event;
+ $this->user = $user;
+ // All email delivery mode share the same footer
+ $this->component = array( 'footer' );
+ }
+
+ /**
+ * Get text email template
+ * @return string
+ */
+ abstract public function getTextTemplate();
+
+ /**
+ * Get html email template
+ * @return string
+ */
+ abstract public function getHTMLTemplate();
+
+ /**
+ * Get the footer component
+ * @return string
+ */
+ public function getFooter( $format ) {
+ global $wgEchoEmailFooterAddress;
+
+ if ( $format === 'text' ) {
+ return wfMessage( 'echo-email-footer-default' )
+ ->params( $wgEchoEmailFooterAddress, wfMessage(
'echo-email-batch-separator' )->text() )
+ ->text();
+ } else {
+ $title = Title::makeTitle( NS_SPECIAL, 'Preferences' );
+ $title->setFragment( "#mw-prefsection-echo" );
+ return wfMessage( 'echo-email-footer-default-html' )
+ ->params( $wgEchoEmailFooterAddress )
+ ->rawParams( $title->getCanonicalURL() )
+ ->text();
+ }
+ }
+
+ /**
+ * The style for primary link
+ */
+ protected function getPrimaryLinkCSS() {
+ return 'cursor:pointer; text-align:center;
text-decoration:none; padding:.5em 1.2em .55em; color:#d9eef7;
background:#0095cd;';
+ }
+
+ /**
+ * The style for secondary link
+ */
+ protected function getSecondaryLinkCSS() {
+ return 'text-decoration: none;font-size: 13px;';
+ }
+}
+
+/**
+ * Entity that represents a single email delivery mode
+ */
+class EchoEmailSingle extends EchoEmailMode {
+
+ /**
+ * @param $notifFormatter EchoBasicFormatter
+ * @param $event EchoEvent
+ * @param $user User
+ */
+ public function __construct( EchoBasicFormatter $notifFormatter,
EchoEvent $event, User $user ) {
+ parent::__construct( $notifFormatter, $event, $user );
+ $this->component = array_merge( $this->component, array (
'emailIcon', 'intro', 'summary', 'action' ) );
+ }
+
+ /**
+ * Get the intro component
+ * @return string
+ */
+ public function getIntro() {
+ $bundle = $this->notifFormatter->getValue( 'bundleData' );
+ $email = $this->notifFormatter->getValue( 'email' );
+
+ if ( $bundle['use-bundle'] &&
$email['batch-bundle-body']['message'] ) {
+ $detail = $email['batch-bundle-body'];
+ } else {
+ $detail = $email['batch-body'];
+ }
+
+ return $this->notifFormatter->formatFragment( $detail,
$this->event, $this->user );
+ }
+
+ /**
+ * Get the summary component
+ * @return string
+ */
+ public function getSummary() {
+ return $this->notifFormatter->formatRevisionComment(
$this->event, $this->user );
+ }
+
+ /**
+ * Get the action component
+ * @return string
+ */
+ public function getAction( $format ) {
+ $link = array();
+ $ranks = array( 'primary', 'secondary' );
+
+ foreach ( $ranks as $rank ) {
+ $message = $this->event->getLinkMessage( $rank );
+
+ // Valid call to action should have link text
+ if ( !$message ) {
+ continue;
+ }
+
+ // Plain text email
+ if ( $format === 'text' ) {
+ $url = $this->notifFormatter->getLink(
$this->event, $this->user, $rank, false, true );
+
+ $link[] = wfMessage( $message )->text()
+ . wfMessage( 'colon-separator' )->text()
+ . '<'
+ .
$this->notifFormatter->sanitizeEmailLink( $url )
+ . '>';
+ // HTML email
+ } else {
+ if ( $rank === 'primary' ) {
+ $style = $this->getPrimaryLinkCSS();
+ } else {
+ $style = $this->getSecondaryLinkCSS();
+ }
+
+ $link[] = $this->notifFormatter->getLink(
$this->event, $this->user, $rank, false, false, $style );
+ }
+ }
+
+ // Add some spacing between the two action links
+ if ( $format === 'text' ) {
+ $link = implode( "\n\n", $link );
+ } else {
+ $link = implode( "<br /><br />", $link );
+ }
+
+ return $link;
+ }
+
+ /**
+ * Get the email icon component
+ * @return string
+ */
+ public function getEmailIcon() {
+ global $wgEchoNotificationIcons, $wgExtensionAssetsPath;
+
+ $iconInfo =
$wgEchoNotificationIcons[$this->notifFormatter->getValue( 'icon' ) ];
+ if ( isset( $iconInfo['url'] ) && $iconInfo['url'] ) {
+ $iconUrl = $iconInfo['url'];
+ } else {
+ if ( !isset( $iconInfo['path'] ) || !$iconInfo['path']
) {
+ $iconInfo =
$wgEchoNotificationIcons['placeholder'];
+ }
+ $iconUrl = "$wgExtensionAssetsPath/{$iconInfo['path']}";
+ }
+
+ return wfExpandUrl( $iconUrl );
+ }
+
+ /**
+ * Get template for text email
+ * @return string
+ */
+ public function getTextTemplate() {
+ return <<< EOF
+%%intro%%
+
+%%summary%%
+
+%%action%%
+
+%%footer%%
+EOF;
+ }
+
+ /**
+ * Get template for html email
+ * @return string
+ */
+ public function getHTMLTemplate() {
+ return <<< EOF
+<html><head></head><body>
+<table cellspacing="0" cellpadding="0" border="0" width="100%" align="center">
+<tr>
+ <td bgcolor="#E6E7E8"><center>
+ <br /><br />
+ <table cellspacing="0" cellpadding="0" border="0" width="600">
+ <tr>
+ <td bgcolor="#FFFFFF" width = "35"> </td>
+ <td bgcolor="#FFFFFF" width = "61"> </td>
+ <td bgcolor="#FFFFFF" width = "469" style =
"line-height:50px;"> </td>
+ <td bgcolor="#FFFFFF" width = "35"> </td>
+ </tr><tr>
+ <td bgcolor="#FFFFFF" width = "35"
rowspan="2"> </td>
+ <td bgcolor="#FFFFFF" width = "61" align =
"center" valign="top" rowspan="2"><img src="%%emailIcon%%" alt = "" height =
"30" width = "30"></td>
+ <td bgcolor="#FFFFFF" width = "369" style =
"font-family:sans-serif; font-size:15px; line-height:19px;
color:#C9C9C9;">%%intro%%</td>
+ <td bgcolor="#FFFFFF" width = "35" rowspan =
"2"> </td>
+ </tr><tr>
+ <td bgcolor="#FFFFFF" width = "61" style =
"font-family: sans-serif; font-size:16px; line-height: 20px; font-weight: 600;">
+ <table cellspacing="0" cellpadding="0"
border="0" style="margin-top: 12px;">
+ <tr>
+ <td bgcolor="#FFFFFF"
style="font-family: sans-serif; font-size:16px; font-weight: 600;">
+ %%summary%%
+ </td>
+ </tr>
+ </table>
+ <table cellspacing="0" cellpadding="0"
border="0" style="margin-top: 25px;">
+ <tr>
+ <td bgcolor="#FFFFFF"
style="font-family: sans-serif; font-size:14px;">
+ %%action%%
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr><tr>
+ <td bgcolor="#FFFFFF" width = "35"> </td>
+ <td bgcolor="#FFFFFF" width = "61"> </td>
+ <td bgcolor="#FFFFFF" width = "369" style =
"line-height:30px;"> </td>
+ <td bgcolor="#FFFFFF" width = "35"> </td>
+ </tr><tr>
+ <td bgcolor="#F8F8F8" width = "35"> </td>
+ <td bgcolor="#F8F8F8" width = "61"> </td>
+ <td bgcolor="#F8F8F8" width = "369" style =
"font-family:sans-serif; font-size:12px; line-height:15px; color:#C9C9C9"><br />
+ %%footer%%
+<br /><br />
+ </td>
+ <td bgcolor="#F8F8F8" width = "35"> </td>
+ </tr>
+ </table>
+ <br><br></center>
+ </td>
+</tr>
+</table>
+</body></html>
+EOF;
+ }
+
+}
+
+/**
+ * Class that represents email digest delivery mode
+ * @Todo - To be completed for email digest
+ */
+class EchoEmailDigest extends EchoEmailMode {
+
+ public function __construct( EchoBasicFormatter $notifFormatter,
$event, $user ) {
+ parent::__construct( $notifFormatter, $event, $user );
+ $this->component = array_merge( $this->component, array(
'header', 'intro', 'digestList' ) );
+ }
+
+ public function getHeader() {}
+ public function getIntro() {}
+ public function getDigestList() {}
+ public function getFooter() {}
+
+ public function getTextTemplate() {}
+
+ public function getHTMLTemplate() {}
+
+}
--
To view, visit https://gerrit.wikimedia.org/r/70112
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia4b98b14e135742b84f1b0e04589b0efdd24e954
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Echo
Gerrit-Branch: master
Gerrit-Owner: Bsitu <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits