mirror of
https://github.com/processwire/processwire.git
synced 2025-08-13 18:24:57 +02:00
Improvements to FieldtypeComments notifications to improve hookability and allow greater runtime/hook customization for how notification emails are sent.
This commit is contained in:
@@ -90,6 +90,12 @@ class Comment extends WireData {
|
|||||||
*/
|
*/
|
||||||
const flagNotifyConfirmed = 8;
|
const flagNotifyConfirmed = 8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to indicate comment is queued for notifications to be sent later by 3rd party implementation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const flagNotifyQueue = 16;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Max bytes that a Comment may use
|
* Max bytes that a Comment may use
|
||||||
*
|
*
|
||||||
|
@@ -861,7 +861,7 @@ class CommentForm extends Wire implements CommentFormInterface {
|
|||||||
|
|
||||||
/** @var Comment $comment */
|
/** @var Comment $comment */
|
||||||
$comment = $this->wire(new Comment());
|
$comment = $this->wire(new Comment());
|
||||||
$comment->user_agent = $_SERVER['HTTP_USER_AGENT'];
|
$comment->user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
|
||||||
$comment->ip = $this->wire('session')->getIP();
|
$comment->ip = $this->wire('session')->getIP();
|
||||||
$comment->created_users_id = $this->user->id;
|
$comment->created_users_id = $this->user->id;
|
||||||
//$comment->sort = count($this->comments)+1;
|
//$comment->sort = count($this->comments)+1;
|
||||||
@@ -872,7 +872,13 @@ class CommentForm extends Wire implements CommentFormInterface {
|
|||||||
if($parent) {
|
if($parent) {
|
||||||
// validate that depth is in allowed limit
|
// validate that depth is in allowed limit
|
||||||
$parents = $this->commentsField->getCommentParents($this->page, $comment);
|
$parents = $this->commentsField->getCommentParents($this->page, $comment);
|
||||||
if($parents->count() >= $maxDepth) $comment->parent_id = 0;
|
if($parents->count() >= $maxDepth) {
|
||||||
|
if($parent->parent_id) {
|
||||||
|
$comment->parent_id = $parent->parent_id;
|
||||||
|
} else {
|
||||||
|
$comment->parent_id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// parent does not exist on this page
|
// parent does not exist on this page
|
||||||
$comment->parent_id = 0;
|
$comment->parent_id = 0;
|
||||||
|
@@ -1,5 +1,11 @@
|
|||||||
<?php namespace ProcessWire;
|
<?php namespace ProcessWire;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @method int sendAdminNotificationEmail(Comment $comment)
|
||||||
|
* @method int sendNotificationEmail(Comment $comment, $email, $subcode, array $options = array())
|
||||||
|
*
|
||||||
|
*/
|
||||||
class CommentNotifications extends Wire {
|
class CommentNotifications extends Wire {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,6 +20,14 @@ class CommentNotifications extends Wire {
|
|||||||
*/
|
*/
|
||||||
protected $field;
|
protected $field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WireMail mailer module name to use
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $mailer = '';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FYI
|
* FYI
|
||||||
*
|
*
|
||||||
@@ -34,6 +48,25 @@ class CommentNotifications extends Wire {
|
|||||||
$this->field = $field;
|
$this->field = $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set name of WireMail module to use for sending notifications
|
||||||
|
*
|
||||||
|
* @param string $mailer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function setMailer($mailer) {
|
||||||
|
$this->mailer = $mailer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return WireMail
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function newMail() {
|
||||||
|
$options = array();
|
||||||
|
if($this->mailer) $options['module'] = $this->mailer;
|
||||||
|
return $this->wire()->mail->new($options);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send notification email to specified admin to review the comment
|
* Send notification email to specified admin to review the comment
|
||||||
@@ -144,7 +177,7 @@ class CommentNotifications extends Wire {
|
|||||||
|
|
||||||
$emails = $this->parseEmails($field->get('notificationEmail'));
|
$emails = $this->parseEmails($field->get('notificationEmail'));
|
||||||
if(count($emails)) {
|
if(count($emails)) {
|
||||||
$mail = $this->wire('mail')->new();
|
$mail = $this->newMail();
|
||||||
foreach($emails as $email) $mail->to($email);
|
foreach($emails as $email) $mail->to($email);
|
||||||
$mail->subject($subject)->body($body)->bodyHTML($bodyHTML);
|
$mail->subject($subject)->body($body)->bodyHTML($bodyHTML);
|
||||||
$fromEmail = $this->getFromEmail();
|
$fromEmail = $this->getFromEmail();
|
||||||
@@ -422,63 +455,100 @@ class CommentNotifications extends Wire {
|
|||||||
* Send a user (not admin) notification email
|
* Send a user (not admin) notification email
|
||||||
*
|
*
|
||||||
* @param Comment $comment
|
* @param Comment $comment
|
||||||
* @param string $email
|
* @param string|array $email
|
||||||
* @param string $subcode
|
* @param string $subcode Subscribe/unsubscribe code or blank string if not in use
|
||||||
|
* @param array $options
|
||||||
* @return int
|
* @return int
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function ___sendNotificationEmail(Comment $comment, $email, $subcode) {
|
public function ___sendNotificationEmail(Comment $comment, $email, $subcode, array $options = array()) {
|
||||||
|
|
||||||
$showText = (bool) $this->field->useNotifyText;
|
|
||||||
$sanitizer = $this->wire()->sanitizer;
|
|
||||||
$page = $comment->getPage();
|
$page = $comment->getPage();
|
||||||
|
$sanitizer = $this->wire()->sanitizer;
|
||||||
$title = $sanitizer->text($page->getUnformatted('title|path'));
|
$title = $sanitizer->text($page->getUnformatted('title|path'));
|
||||||
$cite = $sanitizer->text($comment->cite);
|
$cite = $sanitizer->text($comment->cite);
|
||||||
$url = $page->httpUrl . "#Comment$comment->id";
|
$showText = isset($options['showText']) ? (bool) $options['showText'] : (bool) $this->field->useNotifyText;
|
||||||
$unsubUrl = $page->httpUrl . "?comment_success=unsub&subcode=$subcode";
|
$emails = is_array($email) ? $email : array($email);
|
||||||
$text = $showText ? $sanitizer->textarea($comment->text) : '';
|
|
||||||
$textHTML = $showText ? $comment->getFormattedCommentText() : '';
|
$defaults = array(
|
||||||
$subject = $this->_('New comment posted:') . " $title"; // Email subject
|
'postedAtLabel' => sprintf($this->_('Posted at: %s'), $title),
|
||||||
$postedAtLabel = $this->_('Posted at: %s');
|
'postedByLabel' => sprintf($this->_('Posted by: %s'), $cite),
|
||||||
$postedByLabel = $this->_('Posted by: %s');
|
'postedAtByLabel' => $this->_('Posted at %s by %s'),
|
||||||
$unsubLabel = $this->_('Unsubscribe from these notifications');
|
'viewLabel' => $this->_('View or reply'),
|
||||||
$viewLabel = $this->_('View or reply');
|
'showText' => $showText,
|
||||||
|
'url' => $page->httpUrl . "#Comment$comment->id",
|
||||||
|
'unsubLabel' => $this->_('Unsubscribe from these notifications'),
|
||||||
|
'unsubUrl' => (strlen($subcode) ? $page->httpUrl . "?comment_success=unsub&subcode=$subcode" : ''),
|
||||||
|
'subject' => $this->_('New comment posted:') . " $title", // Email subject
|
||||||
|
'text' => $showText ? $sanitizer->textarea($comment->text) : '',
|
||||||
|
'textHTML' => $showText ? $comment->getFormattedCommentText() : '',
|
||||||
|
'divStyle' => "padding:10px 20px;border:1px solid #eee",
|
||||||
|
'ccEmails' => array(),
|
||||||
|
'bccEmails' => array(),
|
||||||
|
'fromEmail' => $this->getFromEmail(),
|
||||||
|
'replyToEmail' => '',
|
||||||
|
);
|
||||||
|
|
||||||
|
$options = array_merge($defaults, $options);
|
||||||
|
$unsubUrl = $options['unsubUrl'];
|
||||||
|
|
||||||
$body =
|
$body =
|
||||||
sprintf($postedAtLabel, $title) . "\n" .
|
$options['postedAtLabel'] . "\n" .
|
||||||
sprintf($postedByLabel, $cite) . "\n\n" .
|
$options['postedByLabel'] . "\n" .
|
||||||
($showText ? "$text\n\n" : "") .
|
($showText ? "$options[text]\n\n" : "") .
|
||||||
"$viewLabel: $url\n\n" .
|
"$options[viewLabel]: $options[url]\n\n" .
|
||||||
"$unsubLabel: $unsubUrl\n\n";
|
"---\n" .
|
||||||
|
(strlen($unsubUrl) ? "$options[unsubLabel]: $options[unsubUrl]\n\n" : "$options[unsubLabel]\n\n");
|
||||||
|
|
||||||
$url = $sanitizer->entities($url);
|
$url = $sanitizer->entities($options['url']);
|
||||||
$cite = $sanitizer->entities($cite);
|
$cite = $sanitizer->entities($cite);
|
||||||
$title = $sanitizer->entities($title);
|
$title = $sanitizer->entities($title);
|
||||||
$unsubUrl = $sanitizer->entities($unsubUrl);
|
$unsubUrl = $sanitizer->entities($unsubUrl);
|
||||||
$titleLink = "<a href='$url'>$title</a>";
|
$titleLink = "<a href='$url'>$title</a>";
|
||||||
$div = "<div style='padding:10px 20px;border:1px solid #eee'>";
|
|
||||||
|
|
||||||
$bodyHTML =
|
$bodyHTML =
|
||||||
"<html><head><title>$title</title><head><body>" .
|
"<html><head><title>$title</title><head><body>" .
|
||||||
"<p><em>" . sprintf($this->_('Posted at %s by %s'), $titleLink, $cite) . "</em></p>" .
|
"<p><em>" . sprintf($this->_('Posted at %s by %s'), $titleLink, $cite) . "</em></p>" .
|
||||||
($showText ? "\n$div<p>$textHTML</p></div>" : '') .
|
($showText ? "\n<div style='$options[divStyle]'><p>$options[textHTML]</p></div>" : '') .
|
||||||
"\n<p><a href='$url'>$viewLabel</a></p>" .
|
"\n<p><a href='$url'>$options[viewLabel]</a></p>" .
|
||||||
"\n<p> </p>" .
|
"\n<p> </p>" .
|
||||||
"\n<hr />" .
|
"\n<hr />" .
|
||||||
"\n<p><small><a href='$unsubUrl'>$unsubLabel</a></small></p>" .
|
"\n<p><small>" .
|
||||||
|
(strlen($unsubUrl) ? "<a href='$unsubUrl'>$options[unsubLabel]</a>" : "$options[unsubLabel]") .
|
||||||
|
"</small></p>" .
|
||||||
"</body></html>";
|
"</body></html>";
|
||||||
|
|
||||||
$mail = $this->wire('mail')->new();
|
/** @var WireMail $mail */
|
||||||
$mail->to($email)->subject($subject)->body($body)->bodyHTML($bodyHTML);
|
$mail = $this->newMail();
|
||||||
$fromEmail = $this->getFromEmail();
|
$mail->to($emails)
|
||||||
if($fromEmail) $mail->from($fromEmail);
|
->subject($options['subject'])
|
||||||
|
->body($body)
|
||||||
|
->bodyHTML($bodyHTML);
|
||||||
|
|
||||||
|
if($options['fromEmail']) {
|
||||||
|
$mail->from($options['fromEmail']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($options['replyToEmail']) {
|
||||||
|
$mail->replyTo($options['replyToEmail']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($options['ccEmails'] && is_array($options['ccEmails'])) {
|
||||||
|
$mail->header('cc', implode(',', $options['ccEmails']));
|
||||||
|
$emails = array_merge($emails, $options['ccEmails']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($options['bccEmails'] && is_array($options['bccEmails'])) {
|
||||||
|
$mail->header('bcc', implode(',', $options['bccEmails']));
|
||||||
|
$emails = array_merge($emails, $options['ccEmails']);
|
||||||
|
}
|
||||||
|
|
||||||
$result = $mail->send();
|
$result = $mail->send();
|
||||||
|
|
||||||
if($result) {
|
if($result) {
|
||||||
$this->wire('log')->message("Sent comment notification email to $email");
|
$this->wire()->log->message("Sent comment notification email to " . implode(', ', $emails));
|
||||||
} else {
|
} else {
|
||||||
$this->wire('log')->error("Failed sending comment notification to $email");
|
$this->wire()->log->error("Failed sending comment notification to " . implode(', ', $emails));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
@@ -508,7 +578,7 @@ class CommentNotifications extends Wire {
|
|||||||
$body .= "\n\n$footer: $confirmURL";
|
$body .= "\n\n$footer: $confirmURL";
|
||||||
$bodyHTML .= "<p><strong><a href='$confirmURL'>$footer</a></strong></p>";
|
$bodyHTML .= "<p><strong><a href='$confirmURL'>$footer</a></strong></p>";
|
||||||
|
|
||||||
$mail = $this->wire('mail')->new();
|
$mail = $this->newMail();
|
||||||
$mail->to($email)->subject($subject)->body($body)->bodyHTML($bodyHTML);
|
$mail->to($email)->subject($subject)->body($body)->bodyHTML($bodyHTML);
|
||||||
$fromEmail = $this->getFromEmail();
|
$fromEmail = $this->getFromEmail();
|
||||||
if($fromEmail) $mail->from($fromEmail);
|
if($fromEmail) $mail->from($fromEmail);
|
||||||
|
@@ -34,6 +34,7 @@ require_once($dirname . "/CommentField.php");
|
|||||||
* @method void commentUnapproved(Page $page, Field $field, Comment $comment, $notes = '') #pw-hooker
|
* @method void commentUnapproved(Page $page, Field $field, Comment $comment, $notes = '') #pw-hooker
|
||||||
* @method void commentAddReady(Page $page, Field $field, Comment $comment) #pw-hooker
|
* @method void commentAddReady(Page $page, Field $field, Comment $comment) #pw-hooker
|
||||||
* @method void commentAdded(Page $page, Field $field, Comment $comment) #pw-hooker
|
* @method void commentAdded(Page $page, Field $field, Comment $comment) #pw-hooker
|
||||||
|
* @method int sendNotifyEmails(Page $page, Field $field, Comment $comment, array $emailsData)
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -1864,16 +1865,16 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
|
|
||||||
$this->wire('log')->message("Approved comment $comment->id - $notes");
|
$this->wire('log')->message("Approved comment $comment->id - $notes");
|
||||||
|
|
||||||
if(!$field->get('useNotify')) return;
|
if(!$field->get('useNotify')) return; // notifications not in use
|
||||||
$emails = $this->getNotifyEmails($page, $field, $comment);
|
if($comment->flags & Comment::flagNotifyQueue) return; // comment queued for 3rd party notifications
|
||||||
|
|
||||||
|
$emailsData = $this->getNotifyEmails($page, $field, $comment);
|
||||||
|
|
||||||
// emails array contains email address => subcode to send notifications to
|
// emails array contains email address => subcode to send notifications to
|
||||||
if(count($emails)) {
|
if(count($emailsData)) {
|
||||||
require_once(dirname(__FILE__) . '/CommentNotifications.php');
|
$qty = $this->sendNotifyEmails($page, $field, $comment, $emailsData);
|
||||||
$no = $this->wire(new CommentNotifications($page, $field));
|
if($qty > 0) {
|
||||||
foreach($emails as $email => $data) {
|
// emails sent
|
||||||
$subcode = $data['subcode'];
|
|
||||||
$no->sendNotificationEmail($comment, $email, $subcode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1922,8 +1923,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function ___commentAdded(Page $page, Field $field, Comment $comment) {
|
public function ___commentAdded(Page $page, Field $field, Comment $comment) {
|
||||||
require_once(dirname(__FILE__) . '/CommentNotifications.php');
|
$no = $this->commentNotifications($page, $field);
|
||||||
$no = $this->wire(new CommentNotifications($page, $field));
|
|
||||||
$no->sendAdminNotificationEmail($comment);
|
$no->sendAdminNotificationEmail($comment);
|
||||||
$this->commentMaintenance($field);
|
$this->commentMaintenance($field);
|
||||||
|
|
||||||
@@ -2007,6 +2007,31 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
return $emails;
|
return $emails;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get emails (and other data) of people that should be notified for a given Page’s comments
|
||||||
|
*
|
||||||
|
* @param Page $page
|
||||||
|
* @param Field $field
|
||||||
|
* @param Comment|null $comment
|
||||||
|
* @param array $emailsData
|
||||||
|
* @return int
|
||||||
|
* @since 3.0.175
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function ___sendNotifyEmails(Page $page, Field $field, Comment $comment, array $emailsData) {
|
||||||
|
|
||||||
|
$no = $this->commentNotifications($page, $field);
|
||||||
|
$cnt = 0;
|
||||||
|
|
||||||
|
foreach($emailsData as $data) {
|
||||||
|
$subcode = $data['subcode'];
|
||||||
|
$email = $data['email'];
|
||||||
|
$cnt += $no->sendNotificationEmail($comment, $email, $subcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $cnt;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a vote to the current comment from the current user/IP
|
* Add a vote to the current comment from the current user/IP
|
||||||
*
|
*
|
||||||
@@ -2372,5 +2397,23 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
return $options;
|
return $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get instance of CommentNotifications class
|
||||||
|
*
|
||||||
|
* #pw-internal
|
||||||
|
*
|
||||||
|
* @param Page $page
|
||||||
|
* @param Field $field
|
||||||
|
* @return CommentNotifications
|
||||||
|
* @since 3.0.175
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function commentNotifications(Page $page, Field $field) {
|
||||||
|
require_once(dirname(__FILE__) . '/CommentNotifications.php');
|
||||||
|
$no = new CommentNotifications($page, $field);
|
||||||
|
$this->wire($no);
|
||||||
|
return $no;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user