diff --git a/_prepend.php b/_prepend.php deleted file mode 100644 index b2427a8..0000000 --- a/_prepend.php +++ /dev/null @@ -1,17 +0,0 @@ -autoload(['emailNotificationBehaviors' => __DIR__ . '/inc/class.emailnotification.behaviors.php']); diff --git a/src/Backend.php b/src/Backend.php index e1a8fb5..01c9001 100644 --- a/src/Backend.php +++ b/src/Backend.php @@ -10,11 +10,35 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_CONTEXT_ADMIN')) { - return null; -} +declare(strict_types=1); -dcCore::app()->addBehavior('adminPreferencesFormV2', ['emailNotificationBehaviors', 'adminUserForm']); -dcCore::app()->addBehavior('adminUserForm', ['emailNotificationBehaviors', 'adminUserForm']); -dcCore::app()->addBehavior('adminBeforeUserUpdate', ['emailNotificationBehaviors', 'adminBeforeUserUpdate']); -dcCore::app()->addBehavior('adminBeforeUserOptionsUpdate', ['emailNotificationBehaviors', 'adminBeforeUserUpdate']); +namespace Dotclear\Plugin\emailNotification; + +use dcCore; +use dcNsProcess; + +class Backend extends dcNsProcess +{ + public static function init(): bool + { + static::$init = defined('DC_CONTEXT_ADMIN'); + + return static::$init; + } + + public static function process(): bool + { + if (!static::$init) { + return false; + } + + dcCore::app()->addBehaviors([ + 'adminPreferencesFormV2' => [BackendBehaviors::class, 'adminUserForm'], + 'adminUserForm' => [BackendBehaviors::class, 'adminUserForm'], + 'adminBeforeUserUpdate' => [BackendBehaviors::class, 'adminBeforeUserUpdate'], + 'adminBeforeUserOptionsUpdate' => [BackendBehaviors::class, 'adminBeforeUserUpdate'], + ]); + + return true; + } +} diff --git a/src/BackendBehaviors.php b/src/BackendBehaviors.php index 03c4c2f..e4a2185 100644 --- a/src/BackendBehaviors.php +++ b/src/BackendBehaviors.php @@ -10,137 +10,39 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_RC_PATH')) { - return; -} +declare(strict_types=1); -class emailNotificationBehaviors +namespace Dotclear\Plugin\emailNotification; + +use cursor; +use dcCore; +use Dotclear\Helper\Html\Form\{ + Label, + Para, + Select +}; + +class BackendBehaviors { - public static function adminUserForm() + public static function adminUserForm(): void { $options = dcCore::app()->auth->getOptions(); echo '
' . __('Email notification') . '
' . - '

' . - form::combo( - 'notify_comments', - [ + (new Para())->items([ + (new Label(__('Notify new comments by email:')))->for('notify_comments'), + (new Select('notify_comments'))->default($options['notify_comments'] ?? '0')->items([ __('Never') => '0', __('My entries') => 'mine', __('All entries') => 'all', - ], - $options['notify_comments'] ?? '0' - ) . - '

' . + ]), + ])->render() . '
'; } - public static function adminBeforeUserUpdate($cur, $user_id = '') + public static function adminBeforeUserUpdate(cursor $cur, string $user_id = ''): void { $cur->user_options['notify_comments'] = $_POST['notify_comments']; } - - public static function publicAfterCommentCreate($cur, $comment_id) - { - # We don't want notification for spam - if ($cur->comment_status == -2) { - return; - } - - # Information on comment author and post author - $rs = dcCore::app()->auth->sudo([dcCore::app()->blog, 'getComments'], ['comment_id' => $comment_id]); - - if ($rs->isEmpty()) { - return; - } - - # Information on blog users - $strReq = 'SELECT U.user_id, user_email, user_options ' . - 'FROM ' . dcCore::app()->blog->prefix . dcAuth::USER_TABLE_NAME . ' U ' . - 'JOIN ' . dcCore::app()->blog->prefix . dcAuth::PERMISSIONS_TABLE_NAME . ' P ON U.user_id = P.user_id ' . - "WHERE blog_id = '" . dcCore::app()->con->escape(dcCore::app()->blog->id) . "' " . - 'UNION ' . - 'SELECT user_id, user_email, user_options ' . - 'FROM ' . dcCore::app()->blog->prefix . dcAuth::USER_TABLE_NAME . ' ' . - 'WHERE user_super = 1 '; - - $users = dcCore::app()->con->select($strReq); - - # Create notify list - $ulist = []; - while ($users->fetch()) { - if (!$users->user_email) { - continue; - } - - $notification_pref = self::notificationPref(rsExtUser::options(new dcRecord($users))); - - if ($notification_pref == 'all' - || ($notification_pref == 'mine' && $users->user_id == $rs->user_id)) { - $ulist[$users->user_id] = $users->user_email; - } - } - - if (count($ulist) > 0) { - # Author of the post wants to be notified by mail - $headers = [ - 'Reply-To: ' . $rs->comment_email, - 'Content-Type: text/plain; charset=UTF-8;', - 'X-Mailer: Dotclear', - 'X-Blog-Id: ' . mail::B64Header(dcCore::app()->blog->id), - 'X-Blog-Name: ' . mail::B64Header(dcCore::app()->blog->name), - 'X-Blog-Url: ' . mail::B64Header(dcCore::app()->blog->url), - ]; - - $subject = '[' . dcCore::app()->blog->name . '] ' . sprintf(__('"%s" - New comment'), $rs->post_title); - $subject = mail::B64Header($subject); - - $msg = preg_replace('%

\s*

%msu', "\n\n", $rs->comment_content); - $msg = html::clean($msg); - $msg = html_entity_decode($msg); - - if ($cur->comment_status == 1) { - $status = __('published'); - } elseif ($cur->comment_status == 0) { - $status = __('unpublished'); - } elseif ($cur->comment_status == -1) { - $status = __('pending'); - } else { - # unknown status - $status = $cur->comment_status; - } - - $msg .= "\n\n-- \n" . - sprintf(__('Blog: %s'), dcCore::app()->blog->name) . "\n" . - sprintf(__('Entry: %s <%s>'), $rs->post_title, $rs->getPostURL()) . "\n" . - sprintf(__('Comment by: %s <%s>'), $rs->comment_author, $rs->comment_email) . "\n" . - sprintf(__('Website: %s'), $rs->getAuthorURL()) . "\n" . - sprintf(__('Comment status: %s'), $status) . "\n" . - sprintf(__('Edit this comment: <%s>'), DC_ADMIN_URL . - ((substr(DC_ADMIN_URL, -1) != '/') ? '/' : '') . - 'comment.php?id=' . $cur->comment_id . - '&switchblog=' . dcCore::app()->blog->id) . "\n" . - __('You must log in on the backend before clicking on this link to go directly to the comment.'); - - $msg = __('You received a new comment on your blog:') . "\n\n" . $msg; - - # --BEHAVIOR-- emailNotificationAppendToEmail - $msg .= dcCore::app()->callBehavior('emailNotificationAppendToEmail', $cur); - - foreach ($ulist as $email) { - $h = array_merge(['From: ' . $email], $headers); - mail::sendMail($email, $subject, $msg, $h); - } - } - } - - protected static function notificationPref($o) - { - if (is_array($o) && isset($o['notify_comments'])) { - return $o['notify_comments']; - } - - return null; - } } diff --git a/src/Frontend.php b/src/Frontend.php index 8739244..f241450 100644 --- a/src/Frontend.php +++ b/src/Frontend.php @@ -10,8 +10,129 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_RC_PATH')) { - return null; -} +declare(strict_types=1); -dcCore::app()->addBehavior('publicAfterCommentCreate', ['emailNotificationBehaviors', 'publicAfterCommentCreate']); +namespace Dotclear\Plugin\emailNotification; + +use cursor; +use dcAuth; +use dcCore; +use dcNsProcess; +use dcRecord; +use Dotclear\Helper\Html\Html; +use Dotclear\Helper\Network\Mail\Mail; +use rsExtUser; + +class Frontend extends dcNsProcess +{ + public static function init(): bool + { + static::$init = defined('DC_RC_PATH'); + + return static::$init; + } + + public static function process(): bool + { + if (!static::$init) { + return false; + } + + dcCore::app()->addBehavior('publicAfterCommentCreate', function (cursor $cur, ?int $comment_id): void { + # We don't want notification for spam + if ($cur->comment_status == -2) { + return; + } + + # Information on comment author and post author + $rs = dcCore::app()->auth->sudo([dcCore::app()->blog, 'getComments'], ['comment_id' => $comment_id]); + + if ($rs->isEmpty()) { + return; + } + + # Information on blog users + $strReq = 'SELECT U.user_id, user_email, user_options ' . + 'FROM ' . dcCore::app()->blog->prefix . dcAuth::USER_TABLE_NAME . ' U ' . + 'JOIN ' . dcCore::app()->blog->prefix . dcAuth::PERMISSIONS_TABLE_NAME . ' P ON U.user_id = P.user_id ' . + "WHERE blog_id = '" . dcCore::app()->con->escapeStr(dcCore::app()->blog->id) . "' " . + 'UNION ' . + 'SELECT user_id, user_email, user_options ' . + 'FROM ' . dcCore::app()->blog->prefix . dcAuth::USER_TABLE_NAME . ' ' . + 'WHERE user_super = 1 '; + + $users = dcCore::app()->con->select($strReq); + + # Create notify list + $ulist = []; + while ($users->fetch()) { + if (!$users->user_email) { + continue; + } + + $o = rsExtUser::options(new dcRecord($users)); + $notification_pref = is_array($o) && isset($o['notify_comments']) ? $o['notify_comments'] : null; + unset($o); + + if ($notification_pref == 'all' + || ($notification_pref == 'mine' && $users->user_id == $rs->user_id)) { + $ulist[$users->user_id] = $users->user_email; + } + } + + if (count($ulist) > 0) { + # Author of the post wants to be notified by mail + $headers = [ + 'Reply-To: ' . $rs->comment_email, + 'Content-Type: text/plain; charset=UTF-8;', + 'X-Mailer: Dotclear', + 'X-Blog-Id: ' . Mail::B64Header(dcCore::app()->blog->id), + 'X-Blog-Name: ' . Mail::B64Header(dcCore::app()->blog->name), + 'X-Blog-Url: ' . Mail::B64Header(dcCore::app()->blog->url), + ]; + + $subject = '[' . dcCore::app()->blog->name . '] ' . sprintf(__('"%s" - New comment'), $rs->post_title); + $subject = Mail::B64Header($subject); + + $msg = preg_replace('%

\s*

%msu', "\n\n", $rs->comment_content); + $msg = Html::clean($msg); + $msg = html_entity_decode($msg); + + if ($cur->comment_status == 1) { + $status = __('published'); + } elseif ($cur->comment_status == 0) { + $status = __('unpublished'); + } elseif ($cur->comment_status == -1) { + $status = __('pending'); + } else { + # unknown status + $status = $cur->comment_status; + } + + $msg .= "\n\n-- \n" . + sprintf(__('Blog: %s'), dcCore::app()->blog->name) . "\n" . + sprintf(__('Entry: %s <%s>'), $rs->post_title, $rs->getPostURL()) . "\n" . + sprintf(__('Comment by: %s <%s>'), $rs->comment_author, $rs->comment_email) . "\n" . + sprintf(__('Website: %s'), $rs->getAuthorURL()) . "\n" . + sprintf(__('Comment status: %s'), $status) . "\n" . + sprintf(__('Edit this comment: <%s>'), DC_ADMIN_URL . + ((substr(DC_ADMIN_URL, -1) != '/') ? '/' : '') . + 'comment.php?id=' . $cur->comment_id . + '&switchblog=' . dcCore::app()->blog->id) . "\n" . + __('You must log in on the backend before clicking on this link to go directly to the comment.'); + + $msg = __('You received a new comment on your blog:') . "\n\n" . $msg; + + # --BEHAVIOR-- emailNotificationAppendToEmail + $msg .= dcCore::app()->callBehavior('emailNotificationAppendToEmail', $cur); + + foreach ($ulist as $email) { + $h = array_merge(['From: ' . $email], $headers); + Mail::sendMail($email, $subject, $msg, $h); + } + } + }); + + return true; + } +}