diff --git a/wire/modules/Fieldtype/FieldtypeComments/Comment.php b/wire/modules/Fieldtype/FieldtypeComments/Comment.php index 438ccf61..18180984 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/Comment.php +++ b/wire/modules/Fieldtype/FieldtypeComments/Comment.php @@ -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 diff --git a/wire/modules/Fieldtype/FieldtypeComments/CommentForm.php b/wire/modules/Fieldtype/FieldtypeComments/CommentForm.php index c25c2925..d9e267d8 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/CommentForm.php +++ b/wire/modules/Fieldtype/FieldtypeComments/CommentForm.php @@ -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; diff --git a/wire/modules/Fieldtype/FieldtypeComments/CommentNotifications.php b/wire/modules/Fieldtype/FieldtypeComments/CommentNotifications.php index 0d523840..d9dc9f20 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/CommentNotifications.php +++ b/wire/modules/Fieldtype/FieldtypeComments/CommentNotifications.php @@ -1,5 +1,11 @@ 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 = "$title"; - $div = "
"; $bodyHTML = "$title" . "

" . sprintf($this->_('Posted at %s by %s'), $titleLink, $cite) . "

" . - ($showText ? "\n$div

$textHTML

" : '') . - "\n

$viewLabel

" . + ($showText ? "\n

$options[textHTML]

" : '') . + "\n

$options[viewLabel]

" . "\n

 

" . "\n
" . - "\n

$unsubLabel

" . + "\n

" . + (strlen($unsubUrl) ? "$options[unsubLabel]" : "$options[unsubLabel]") . + "

" . ""; - - $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 .= "

$footer

"; - $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); diff --git a/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module b/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module index 4d2c52df..9bde3abf 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module +++ b/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module @@ -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; + } }