mirror of
https://github.com/processwire/processwire.git
synced 2025-08-12 01:34:31 +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:
@@ -88,7 +88,13 @@ class Comment extends WireData {
|
||||
* Flag to indicate author of this comment wants notifications and request confirmed by double opt in
|
||||
*
|
||||
*/
|
||||
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
|
||||
|
@@ -861,7 +861,7 @@ class CommentForm extends Wire implements CommentFormInterface {
|
||||
|
||||
/** @var Comment $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->created_users_id = $this->user->id;
|
||||
//$comment->sort = count($this->comments)+1;
|
||||
@@ -872,7 +872,13 @@ class CommentForm extends Wire implements CommentFormInterface {
|
||||
if($parent) {
|
||||
// validate that depth is in allowed limit
|
||||
$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 {
|
||||
// parent does not exist on this page
|
||||
$comment->parent_id = 0;
|
||||
|
@@ -1,5 +1,11 @@
|
||||
<?php namespace ProcessWire;
|
||||
|
||||
/**
|
||||
*
|
||||
* @method int sendAdminNotificationEmail(Comment $comment)
|
||||
* @method int sendNotificationEmail(Comment $comment, $email, $subcode, array $options = array())
|
||||
*
|
||||
*/
|
||||
class CommentNotifications extends Wire {
|
||||
|
||||
/**
|
||||
@@ -14,6 +20,14 @@ class CommentNotifications extends Wire {
|
||||
*/
|
||||
protected $field;
|
||||
|
||||
/**
|
||||
* WireMail mailer module name to use
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
*/
|
||||
protected $mailer = '';
|
||||
|
||||
/*
|
||||
* FYI
|
||||
*
|
||||
@@ -34,6 +48,25 @@ class CommentNotifications extends Wire {
|
||||
$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
|
||||
@@ -144,7 +177,7 @@ class CommentNotifications extends Wire {
|
||||
|
||||
$emails = $this->parseEmails($field->get('notificationEmail'));
|
||||
if(count($emails)) {
|
||||
$mail = $this->wire('mail')->new();
|
||||
$mail = $this->newMail();
|
||||
foreach($emails as $email) $mail->to($email);
|
||||
$mail->subject($subject)->body($body)->bodyHTML($bodyHTML);
|
||||
$fromEmail = $this->getFromEmail();
|
||||
@@ -422,63 +455,100 @@ class CommentNotifications extends Wire {
|
||||
* Send a user (not admin) notification email
|
||||
*
|
||||
* @param Comment $comment
|
||||
* @param string $email
|
||||
* @param string $subcode
|
||||
* @param string|array $email
|
||||
* @param string $subcode Subscribe/unsubscribe code or blank string if not in use
|
||||
* @param array $options
|
||||
* @return int
|
||||
*
|
||||
*/
|
||||
public function ___sendNotificationEmail(Comment $comment, $email, $subcode) {
|
||||
|
||||
$showText = (bool) $this->field->useNotifyText;
|
||||
$sanitizer = $this->wire()->sanitizer;
|
||||
public function ___sendNotificationEmail(Comment $comment, $email, $subcode, array $options = array()) {
|
||||
|
||||
$page = $comment->getPage();
|
||||
$title = $sanitizer->text($page->getUnformatted('title|path'));
|
||||
$cite = $sanitizer->text($comment->cite);
|
||||
$url = $page->httpUrl . "#Comment$comment->id";
|
||||
$unsubUrl = $page->httpUrl . "?comment_success=unsub&subcode=$subcode";
|
||||
$text = $showText ? $sanitizer->textarea($comment->text) : '';
|
||||
$textHTML = $showText ? $comment->getFormattedCommentText() : '';
|
||||
$subject = $this->_('New comment posted:') . " $title"; // Email subject
|
||||
$postedAtLabel = $this->_('Posted at: %s');
|
||||
$postedByLabel = $this->_('Posted by: %s');
|
||||
$unsubLabel = $this->_('Unsubscribe from these notifications');
|
||||
$viewLabel = $this->_('View or reply');
|
||||
$sanitizer = $this->wire()->sanitizer;
|
||||
$title = $sanitizer->text($page->getUnformatted('title|path'));
|
||||
$cite = $sanitizer->text($comment->cite);
|
||||
$showText = isset($options['showText']) ? (bool) $options['showText'] : (bool) $this->field->useNotifyText;
|
||||
$emails = is_array($email) ? $email : array($email);
|
||||
|
||||
$defaults = array(
|
||||
'postedAtLabel' => sprintf($this->_('Posted at: %s'), $title),
|
||||
'postedByLabel' => sprintf($this->_('Posted by: %s'), $cite),
|
||||
'postedAtByLabel' => $this->_('Posted at %s by %s'),
|
||||
'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 =
|
||||
sprintf($postedAtLabel, $title) . "\n" .
|
||||
sprintf($postedByLabel, $cite) . "\n\n" .
|
||||
($showText ? "$text\n\n" : "") .
|
||||
"$viewLabel: $url\n\n" .
|
||||
"$unsubLabel: $unsubUrl\n\n";
|
||||
$options['postedAtLabel'] . "\n" .
|
||||
$options['postedByLabel'] . "\n" .
|
||||
($showText ? "$options[text]\n\n" : "") .
|
||||
"$options[viewLabel]: $options[url]\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);
|
||||
$title = $sanitizer->entities($title);
|
||||
$unsubUrl = $sanitizer->entities($unsubUrl);
|
||||
$titleLink = "<a href='$url'>$title</a>";
|
||||
$div = "<div style='padding:10px 20px;border:1px solid #eee'>";
|
||||
|
||||
$bodyHTML =
|
||||
"<html><head><title>$title</title><head><body>" .
|
||||
"<p><em>" . sprintf($this->_('Posted at %s by %s'), $titleLink, $cite) . "</em></p>" .
|
||||
($showText ? "\n$div<p>$textHTML</p></div>" : '') .
|
||||
"\n<p><a href='$url'>$viewLabel</a></p>" .
|
||||
($showText ? "\n<div style='$options[divStyle]'><p>$options[textHTML]</p></div>" : '') .
|
||||
"\n<p><a href='$url'>$options[viewLabel]</a></p>" .
|
||||
"\n<p> </p>" .
|
||||
"\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>";
|
||||
|
||||
$mail = $this->wire('mail')->new();
|
||||
$mail->to($email)->subject($subject)->body($body)->bodyHTML($bodyHTML);
|
||||
$fromEmail = $this->getFromEmail();
|
||||
if($fromEmail) $mail->from($fromEmail);
|
||||
|
||||
/** @var WireMail $mail */
|
||||
$mail = $this->newMail();
|
||||
$mail->to($emails)
|
||||
->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();
|
||||
|
||||
if($result) {
|
||||
$this->wire('log')->message("Sent comment notification email to $email");
|
||||
$this->wire()->log->message("Sent comment notification email to " . implode(', ', $emails));
|
||||
} else {
|
||||
$this->wire('log')->error("Failed sending comment notification to $email");
|
||||
$this->wire()->log->error("Failed sending comment notification to " . implode(', ', $emails));
|
||||
}
|
||||
|
||||
return $result;
|
||||
@@ -508,7 +578,7 @@ class CommentNotifications extends Wire {
|
||||
$body .= "\n\n$footer: $confirmURL";
|
||||
$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);
|
||||
$fromEmail = $this->getFromEmail();
|
||||
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 commentAddReady(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");
|
||||
|
||||
if(!$field->get('useNotify')) return;
|
||||
$emails = $this->getNotifyEmails($page, $field, $comment);
|
||||
if(!$field->get('useNotify')) return; // notifications not in use
|
||||
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
|
||||
if(count($emails)) {
|
||||
require_once(dirname(__FILE__) . '/CommentNotifications.php');
|
||||
$no = $this->wire(new CommentNotifications($page, $field));
|
||||
foreach($emails as $email => $data) {
|
||||
$subcode = $data['subcode'];
|
||||
$no->sendNotificationEmail($comment, $email, $subcode);
|
||||
if(count($emailsData)) {
|
||||
$qty = $this->sendNotifyEmails($page, $field, $comment, $emailsData);
|
||||
if($qty > 0) {
|
||||
// emails sent
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1922,8 +1923,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
||||
*
|
||||
*/
|
||||
public function ___commentAdded(Page $page, Field $field, Comment $comment) {
|
||||
require_once(dirname(__FILE__) . '/CommentNotifications.php');
|
||||
$no = $this->wire(new CommentNotifications($page, $field));
|
||||
$no = $this->commentNotifications($page, $field);
|
||||
$no->sendAdminNotificationEmail($comment);
|
||||
$this->commentMaintenance($field);
|
||||
|
||||
@@ -2006,6 +2006,31 @@ class FieldtypeComments extends FieldtypeMulti {
|
||||
|
||||
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
|
||||
@@ -2371,6 +2396,24 @@ class FieldtypeComments extends FieldtypeMulti {
|
||||
$options['test'] = true;
|
||||
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