diff --git a/wire/modules/Fieldtype/FieldtypeComments/Comment.php b/wire/modules/Fieldtype/FieldtypeComments/Comment.php index ddb556a5..438ccf61 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/Comment.php +++ b/wire/modules/Fieldtype/FieldtypeComments/Comment.php @@ -28,6 +28,8 @@ * @property int $upvotes * @property int $downvotes * @property int $stars + * @property null|bool $isNew Was this comment added in this request? (since 3.0.169) + * @property null|string $approvalNote Runtime approval note for newly added comment, internal use (since 3.0.169) * @property-read Comment|null $parent Parent comment when depth is enabled or null if no parent (since 3.0.149) * @property-read CommentArray $parents All parent comments (since 3.0.149) * @property-read CommentArray $children Immediate child comments (since 3.0.149) @@ -149,10 +151,20 @@ class Comment extends WireData { protected $pageComments = null; /** + * Cache of comment text for getformattedCommentText method + * * @var string|null * */ - protected $textFormatted = null; + protected $formattedCommentText = null; + + /** + * Cache of options for getformattedCommentText method + * + * @var array|null + * + */ + protected $formattedCommentOptions = null; /** * @var int|null @@ -194,44 +206,44 @@ class Comment extends WireData { */ public function get($key) { - if($key == 'user' || $key == 'createdUser') { + if($key === 'user' || $key === 'createdUser') { if(!$this->created_users_id) return $this->users->get($this->config->guestUserPageID); return $this->users->get($this->created_users_id); - } else if($key == 'gravatar') { + } else if($key === 'gravatar') { return $this->gravatar(); - } else if($key == 'page') { + } else if($key === 'page') { return $this->getPage(); - } else if($key == 'field') { + } else if($key === 'field') { return $this->getField(); - } else if($key == 'parent') { + } else if($key === 'parent') { return $this->parent(); - } else if($key == 'parents') { + } else if($key === 'parents') { return $this->parents(); - } else if($key == 'children') { + } else if($key === 'children') { return $this->children(); - } else if($key == 'url') { + } else if($key === 'url') { return $this->url(); - } else if($key == 'httpUrl' || $key == 'httpURL') { + } else if($key === 'httpUrl' || $key == 'httpURL') { return $this->httpUrl(); - } else if($key == 'editUrl' || $key == 'editURL') { + } else if($key === 'editUrl' || $key == 'editURL') { return $this->editUrl(); - } else if($key == 'prevStatus') { + } else if($key === 'prevStatus') { return $this->prevStatus; - } else if($key == 'textFormatted') { - return $this->textFormatted; + } else if($key === 'textFormatted') { + return $this->getFormattedCommentText(); - } else if($key == 'depth') { + } else if($key === 'depth') { return $this->depth(); } else if($key === 'loaded') { @@ -249,39 +261,93 @@ class Comment extends WireData { * * Note that we won't apply this to get() when $page->outputFormatting is active * in order for backwards compatibility with older installations. - * - * @param $key + * + * @param string $key One of: text, cite, email, user_agent, website + * @param array $options * @return mixed|null|Page|string * */ - public function getFormatted($key) { - $value = $this->get($key); + public function getFormatted($key, array $options = array()) { + $value = trim($this->get($key)); + $sanitizer = $this->wire()->sanitizer; - if($key == 'text') { - if($this->textFormatted !== null) return $this->textFormatted; - - $textformatters = null; - // $textformatters = $this->field ? $this->field->textformatters : null; // @todo - if(is_array($textformatters) && count($textformatters)) { - // output formatting with specified textformatters - foreach($textformatters as $name) { - if(!$textformatter = $this->wire('modules')->get($name)) continue; - $textformatter->formatValue($this->page, $this->field, $value); - } - } else { - // default output formatting - $value = $this->wire('sanitizer')->entities(trim($value)); - $value = str_replace("\n\n", "

", $value); - $value = str_replace("\n", "
", $value); - } - + if($key === 'text') { + $value = $this->getFormattedCommentText($options); } else if(in_array($key, array('cite', 'email', 'user_agent', 'website'))) { - $value = $this->wire('sanitizer')->entities(trim($value)); + $value = $sanitizer->entities($value); + } else if(is_string($value)) { + $value = $sanitizer->entities1($value); } return $value; } + /** + * Get comment text as formatted string + * + * Note that the default options behavior is to return comment text with paragraphs split by `

` + * but without the first `

` and last `

` since it is assumed these will be the markup you wrap + * the comment in. If you want it to include the wrapping `

` tags then specify true for the + * `wrapParagraph` option in the `$options` argument. + * + * @param array $options + * - `useParagraphs` (bool): Convert newlines to paragraphs? (default=true) + * - `wrapParagraph` (bool): Use wrapping

tags around return value? (default=false) + * - `useLinebreaks` (bool): Convert single newlines to
tags? (default=true) + * @return string + * @since 3.0.169 + * + */ + public function getFormattedCommentText(array $options = array()) { + + $defaults = array( + 'useParagraphs' => true, + 'wrapParagraph' => false, + 'useLinebreaks' => true, + ); + + $options = array_merge($defaults, $options); + + if($this->formattedCommentText !== null) { + if($this->formattedCommentOptions === null || $options == $this->formattedCommentOptions) { + return $this->formattedCommentText; + } + } + + $sanitizer = $this->wire()->sanitizer; + $value = trim($this->get('text')); + $textformatters = null; + + // $textformatters = $this->field ? $this->field->textformatters : null; // @todo + + if(is_array($textformatters) && count($textformatters)) { + // output formatting with specified textformatters (@todo) + // NOT CURRENTLY ACTIVE + $value = strip_tags($value); + foreach($textformatters as $name) { + if(!$textformatter = $this->wire('modules')->get($name)) continue; + $textformatter->formatValue($this->page, $this->field, $value); + } + } else { + // default output formatting + $value = $sanitizer->entities($value); + while(strpos($value, "\n\n\n") !== false) $value = str_replace("\n\n\n", "\n\n", $value); + if($options['useParagraphs']) { + $value = str_replace("\n\n", "

", $value); + } + if($options['wrapParagraph']) { + $value = "

$value

"; + } + $linebreak = $options['useLinebreaks'] ? "
" : " "; + $value = str_replace("\n", $linebreak, $value); + } + + $this->formattedCommentText = $value; + $this->formattedCommentOptions = $options; + + return $value; + } + /** * Set property * @@ -296,7 +362,12 @@ class Comment extends WireData { $value = (int) $value; } else if($key === 'text') { $value = $this->cleanCommentString($value); - $this->textFormatted = null; + $this->formattedCommentText = null; + $this->formattedCommentOptions = null; + } else if($key === 'textFormatted') { + $this->formattedCommentText = $value; + $this->formattedCommentOptions = null; + return $this; } else if($key === 'cite') { $value = str_replace(array("\r", "\n", "\t"), ' ', substr(strip_tags($value), 0, 128)); } else if($key === 'email') { @@ -309,9 +380,6 @@ class Comment extends WireData { $value = $this->wire('sanitizer')->url($value, array('allowRelative' => false, 'allowQuerystring' => false)); } else if($key === 'upvotes' || $key === 'downvotes') { $value = (int) $value; - } else if($key === 'textFormatted') { - $this->textFormatted = $value; - return $this; } else if($key === 'numChildren') { $this->numChildren = (int) $value; return $this; diff --git a/wire/modules/Fieldtype/FieldtypeComments/CommentField.php b/wire/modules/Fieldtype/FieldtypeComments/CommentField.php index 96e2d06b..0a589128 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/CommentField.php +++ b/wire/modules/Fieldtype/FieldtypeComments/CommentField.php @@ -15,6 +15,7 @@ * @property string $fromEmail * @property int $notifySpam * @property int $useNotify See Comment::flagNotify* constants + * @property bool|int $useNotifyText Include comment text in notification emails? * @property int|bool $useAkismet * @property int $deleteSpamDays * @property int $depth diff --git a/wire/modules/Fieldtype/FieldtypeComments/CommentForm.php b/wire/modules/Fieldtype/FieldtypeComments/CommentForm.php index 083ca5c9..c25c2925 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/CommentForm.php +++ b/wire/modules/Fieldtype/FieldtypeComments/CommentForm.php @@ -169,6 +169,9 @@ class CommentForm extends Wire implements CommentFormInterface { // When a comment is saved to a page, avoid updating the modified time/user 'quietSave' => false, + // default value for the notify option (when used) + 'notifyDefault' => 0, + // interial use: have options been initialized and are ready to use? '_ready' => false, @@ -786,6 +789,7 @@ class CommentForm extends Wire implements CommentFormInterface { if(!$this->commentsField->useNotify) return ''; $out = ''; $tag = $this->options['inputWrapTag']; + $notifyDefault = (int) $this->options['notifyDefault']; $options = array(); @@ -808,16 +812,25 @@ class CommentForm extends Wire implements CommentFormInterface { foreach($classes as $key => $value) { $classes[$key] = $value ? " class='" . trim($value) . "'" : ""; } + + $checked = "checked='checked' "; + $checkedNotify = array( + 0 => ($notifyDefault === 0 ? $checked : ''), + Comment::flagNotifyAll => ($notifyDefault === Comment::flagNotifyAll ? $checked : ''), + Comment::flagNotifyReply => ($notifyDefault === Comment::flagNotifyReply ? $checked : ''), + ); if(count($options)) { + $checked = $checkedNotify[0]; $out = "\n\t<$tag$classes[notify]>" . "\n\t\t" . $this->labels('notify') . " " . - "\n\t\t " . $this->labels('notifyOff') . " "; + "\n\t\t " . $this->labels('notifyOff') . " "; foreach($options as $value => $label) { + $checked = $checkedNotify[(int)$value]; $label = str_replace(' ', ' ', $label); - $out .= "\n\t\t $label "; + $out .= "\n\t\t $label "; } $out .= "\n\t"; } diff --git a/wire/modules/Fieldtype/FieldtypeComments/CommentFormCustom.php b/wire/modules/Fieldtype/FieldtypeComments/CommentFormCustom.php index 70ce8646..1567e219 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/CommentFormCustom.php +++ b/wire/modules/Fieldtype/FieldtypeComments/CommentFormCustom.php @@ -109,20 +109,20 @@ class CommentFormCustom extends CommentForm { {notify.label} {if.notify.replies} {endif.notify.replies} {if.notify.all} {endif.notify.all} @@ -272,10 +272,13 @@ class CommentFormCustom extends CommentForm { '{notify.input.name}' => 'notify', '{notify.input.off.value}' => '0', '{notify.input.off.label}' => $labels['notifyOff'], + '{notify.input.off.checked}' => ($this->options['notifyDefault'] == 0 ? 'checked ' : ''), '{notify.input.replies.value}' => '2', '{notify.input.replies.label}' => $labels['notifyReplies'], + '{notify.input.replies.checked}' => ($this->options['notifyDefault'] == 2 ? 'checked ' : ''), '{notify.input.all.value}' => '4', '{notify.input.all.label}' => $labels['notifyAll'], + '{notify.input.all.checked}' => ($this->options['notifyDefault'] == 4 ? 'checked ' : ''), ); $ifs = array( diff --git a/wire/modules/Fieldtype/FieldtypeComments/CommentNotifications.php b/wire/modules/Fieldtype/FieldtypeComments/CommentNotifications.php index f69e221e..0d523840 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/CommentNotifications.php +++ b/wire/modules/Fieldtype/FieldtypeComments/CommentNotifications.php @@ -9,7 +9,7 @@ class CommentNotifications extends Wire { protected $page; /** - * @var Field + * @var CommentField * */ protected $field; @@ -429,25 +429,52 @@ class CommentNotifications extends Wire { */ public function ___sendNotificationEmail(Comment $comment, $email, $subcode) { + $showText = (bool) $this->field->useNotifyText; + $sanitizer = $this->wire()->sanitizer; $page = $comment->getPage(); - $title = $page->get('title|name'); + $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"; + $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 - $body = $this->_('Posted at: %s') . "\n"; - $body .= sprintf($this->_('Posted by: %s'), $this->wire('sanitizer')->name($comment->cite)) . "\n"; - $bodyHTML = "

" . nl2br(sprintf($body, "$page->title")) . "

"; - $body = sprintf($body, $page->title) . "\n" . sprintf($this->_('URL: %s'), $url); - $footer = $this->_('Disable Notifications'); - $body .= "\n\n$footer: $unsubURL"; - $bodyHTML .= "

$footer

"; + $postedAtLabel = $this->_('Posted at: %s'); + $postedByLabel = $this->_('Posted by: %s'); + $unsubLabel = $this->_('Unsubscribe from these notifications'); + $viewLabel = $this->_('View or reply'); + $body = + sprintf($postedAtLabel, $title) . "\n" . + sprintf($postedByLabel, $cite) . "\n\n" . + ($showText ? "$text\n\n" : "") . + "$viewLabel: $url\n\n" . + "$unsubLabel: $unsubUrl\n\n"; + + $url = $sanitizer->entities($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

" . + "\n

 

" . + "\n
" . + "\n

$unsubLabel

" . + ""; + $mail = $this->wire('mail')->new(); $mail->to($email)->subject($subject)->body($body)->bodyHTML($bodyHTML); $fromEmail = $this->getFromEmail(); if($fromEmail) $mail->from($fromEmail); $result = $mail->send(); + if($result) { $this->wire('log')->message("Sent comment notification email to $email"); } else { diff --git a/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module b/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module index b1c49d2e..1cd9d7bc 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module +++ b/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module @@ -9,7 +9,7 @@ * /wire/core/Fieldtype.php * /wire/core/FieldtypeMulti.php * - * ProcessWire 3.x, Copyright 2016 by Ryan Cramer + * ProcessWire 3.x, Copyright 2020 by Ryan Cramer * https://processwire.com * */ @@ -74,10 +74,10 @@ class FieldtypeComments extends FieldtypeMulti { public static function getModuleInfo() { return array( 'title' => __('Comments', __FILE__), - 'version' => 108, + 'version' => 109, 'summary' => __('Field that stores user posted comments for a single Page', __FILE__), 'installs' => array('InputfieldCommentsAdmin'), - ); + ); } public function wired() { @@ -119,7 +119,7 @@ class FieldtypeComments extends FieldtypeMulti { /** * Update a query to match the text with a fulltext index * - * @param DatabaseQuerySelect $query + * @param PageFinderDatabaseQuerySelect $query * @param string $table * @param string $subfield * @param string $operator @@ -297,17 +297,15 @@ class FieldtypeComments extends FieldtypeMulti { protected function checkCommentCodes(Comment $comment) { // assign code and subcode if(!$comment->code || !$comment->subcode) { - $pass = $this->wire(new Password()); + $rand = new WireRandom(); if(!strlen($comment->code)) { // code: visible to admin only - $code = $pass->randomBase64String(128, true); - $code = substr($this->wire('sanitizer')->fieldName($code), 0, 128); + $code = $rand->alphanumeric(128); $comment->code = $code; } if(!strlen($comment->subcode)) { // subcode: may be visible to commenter - $subcode = $pass->randomBase64String(40, true); - $subcode = substr($this->wire('sanitizer')->fieldName($subcode), 0, 40); + $subcode = $rand->alphanumeric(40); $comment->subcode = $subcode; } } @@ -324,7 +322,9 @@ class FieldtypeComments extends FieldtypeMulti { */ protected function checkNewComment(Page $page, Field $field, Comment $comment) { + if($page) {} // ignore if($comment->id || $comment->quiet()) return; + $comment->isNew = true; $this->checkCommentCodes($comment); @@ -340,7 +340,7 @@ class FieldtypeComments extends FieldtypeMulti { if($comment->status != Comment::statusSpam) { if($field->get('moderate') == self::moderateNone) { $comment->status = Comment::statusApproved; - $this->commentApproved($page, $field, $comment, 'New comment approved / moderation is off'); + $comment->approvalNote = 'New comment approved / moderation is off'; } else if($field->get('moderate') == self::moderateNew && $comment->email) { $database = $this->wire('database'); @@ -352,17 +352,12 @@ class FieldtypeComments extends FieldtypeMulti { $numApproved = (int) $query->fetchColumn(); if($numApproved > 0) { + $cite = $this->wire('sanitizer')->text($comment->cite); $comment->status = Comment::statusApproved; - $cite = $this->wire('sanitizer')->name($comment->cite); - $this->commentApproved($page, $field, $comment, "New comment auto-approved because user '$cite' has other approved comments"); + $comment->approvalNote = "New comment auto-approved because user '$cite' has other approved comments"; } } } - - require_once(dirname(__FILE__) . '/CommentNotifications.php'); - $no = $this->wire(new CommentNotifications($page, $field)); - $no->sendAdminNotificationEmail($comment); - $this->commentMaintenance($field); } /** @@ -794,6 +789,18 @@ class FieldtypeComments extends FieldtypeMulti { $f->addOption(Comment::flagNotifyReply, $this->_('Users can receive email notifications of replies to their comment only')); $f->addOption(Comment::flagNotifyAll, $this->_('Users can receive email notifications for all new comments on the page')); $f->attr('value', (int) $field->get('useNotify')); + $f->columnWidth = 50; + $fieldset->append($f); + + $name = 'useNotifyText'; + $f = $this->wire('modules')->get('InputfieldCheckbox'); + $f->attr('name', $name); + $f->attr('value', 1); + if($field->$name) $f->attr('checked', 'checked'); + $f->label = $this->_('Allow comment text in notifications?'); + $f->description = $this->_('When checked, the entire comment text will also appear in the notification emails, rather than just a link to it.'); + $f->columnWidth = 50; + $f->showIf = 'useNotify>0'; $fieldset->append($f); // --------------------------------------- @@ -1065,6 +1072,7 @@ class FieldtypeComments extends FieldtypeMulti { $intColumns = array( 'id', 'status', + 'flags', 'created', 'pages_id', 'parent_id', @@ -1148,6 +1156,23 @@ class FieldtypeComments extends FieldtypeMulti { } else if($operator === '!=') { $wheres[] = "($table.$f!=0 OR $table.$f IS NOT NULL)"; } + + } else if($f === 'flags') { + if(!is_array($value)) $value = array($value); + $whereFlags = array(); + if(!in_array($operator, array('=', '!=', '&'))) { + throw new WireException("Operator $operator not supported for comment flags"); + } + foreach($value as $flag) { + $intFlag = (int) $flag; + if($operator === '!=') { + $whereFlags[] = "(NOT $table.flags & $intFlag)"; + } else { + $whereFlags[] = "($table.flags & $intFlag)"; + } + } + $andOr = $operator === '!=' ? ' AND ' : ' OR '; + $wheres[] = '(' . implode($andOr, $whereFlags) . ')'; } else if(in_array($f, $intColumns)) { if(!$database->isOperator($operator)) $operator = '='; @@ -1798,42 +1823,20 @@ class FieldtypeComments extends FieldtypeMulti { $this->wire('log')->message("Approved comment $comment->id - $notes"); - if($field->get('useNotify')) { - - $emails = array(); - foreach($page->get($field->name) as $c) { - - if($c->status < Comment::statusApproved) continue; - if($c->id == $comment->id) continue; - if(strtolower($c->email) == strtolower($comment->email)) continue; - - /* - * @todo this should be ready to use, but needs more testing before enabling it - * - if($c->flags & Comment::flagNotifyConfirmed) { - // notifications have been confirmed by double opt-in - } else { - continue; - } - */ - if($c->flags & Comment::flagNotifyAll) { - if($c->subcode) $emails[strtolower($c->email)] = $c->subcode; - } else if(($c->flags & Comment::flagNotifyReply) && $comment->parent_id == $c->id) { - if($c->subcode) $emails[strtolower($c->email)] = $c->subcode; - } - } - - // 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 => $subcode) { - $no->sendNotificationEmail($comment, $email, $subcode); - } + if(!$field->get('useNotify')) return; + $emails = $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); } } } - + /** * Hook called when a comment goes from approved to pending or spam @@ -1860,6 +1863,11 @@ class FieldtypeComments extends FieldtypeMulti { * */ public function ___commentAddReady(Page $page, Field $field, Comment $comment) { + if($page && $field) {} // ignore + $text = $comment->text; + if(strtolower($this->wire()->config->dbEngine) !== 'utf8mb4') { + $comment->text = $this->wire()->sanitizer->removeMB4($text, array('replaceWith' => ' ')); + } } /** @@ -1873,6 +1881,89 @@ 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->sendAdminNotificationEmail($comment); + $this->commentMaintenance($field); + + if($comment->status == Comment::statusApproved || $comment->status == Comment::statusFeatured) { + $this->commentApproved($page, $field, $comment, $comment->approvalNote); + } + } + + /** + * 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 + * @return array + * @throws WireException + * @since 3.0.169 + * + */ + public function getNotifyEmails(Page $page, Field $field, Comment $comment = null) { + + if(!$field->get('useNotify')) return array(); + + $emails = array(); + $database = $this->wire()->database; + $table = $database->escapeTable($field->table); + + $sql = + "SELECT id, cite, flags, email, subcode " . + "FROM `$table` " . + "WHERE pages_id=:pages_id " . + "AND status>0 " . + "AND ((flags & 2) OR (flags & 4) OR (flags & 8)) " . // 2=replies, 4=all, 8=confirmed + "AND id!=:id " . + "AND email!=:email " . + "ORDER BY created DESC"; + + $query = $database->prepare($sql); + $query->bindValue(':pages_id', $page->id, \PDO::PARAM_INT); + $query->bindValue(':id', ($comment ? $comment->id : 0), \PDO::PARAM_INT); + $query->bindValue(':email', ($comment ? strtolower($comment->email) : ''), \PDO::PARAM_STR); + $query->execute(); + + while($row = $query->fetch(\PDO::FETCH_ASSOC)) { + $id = (int) $row['id']; + $flags = (int) $row['flags']; + $subcode = $row['subcode']; + $email = strtolower($row['email']); + + if(empty($subcode)) continue; + + /* + * @todo this should be ready to use, but needs more testing before enabling it + * + if($flags & Comment::flagNotifyConfirmed) { + // notifications have been confirmed by double opt-in + } else { + continue; + } + */ + + if($flags & Comment::flagNotifyAll) { + // OK + } else if(($flags & Comment::flagNotifyReply) && $comment && $comment->parent_id == $id) { + // OK + } else { + continue; // SKIP + } + + $emails[$email] = array( + 'id' => $id, + 'email' => $email, + 'cite' => $row['cite'], + 'subcode' => $subcode, + 'flags' => $flags, + ); + } + + $query->closeCursor(); + + return $emails; } /** diff --git a/wire/modules/Process/ProcessCommentsManager/ProcessCommentsManager.module b/wire/modules/Process/ProcessCommentsManager/ProcessCommentsManager.module index baf02ff7..c1249459 100644 --- a/wire/modules/Process/ProcessCommentsManager/ProcessCommentsManager.module +++ b/wire/modules/Process/ProcessCommentsManager/ProcessCommentsManager.module @@ -611,10 +611,14 @@ class ProcessCommentsManager extends Process { "  "; } - if($page->editable()) $text = - "
" . - "

$text $icons[edit] $labels[edit]

" . - "
"; + if($page->editable()) { + $text = + "
" . + "

$text $icons[edit] $labels[edit]

" . + "
"; + } else { + $text = "

$text

"; + } if($allowPageChange) $outs['page'] = "Page # " .