Сегодня была написана и введена на сайте система емейл-уведомлений о новых комментариях в топиках.
Уведомления четырех типов:
Если это ответ на чужой комментарий, то отправляется уведомление автору родительского комментария.
Затем отправляется уведомление автору топика, если он не был автором родительского комментария.
Затем всем участникам дискуссии в этом топике.
И напоследок администрации.
Сам собой один пользователь получит только одно письмо по приоритету события. Правда предстоит еще написать личные настройки пользователей, где каждый мог бы указать какие уведомления он хочет получать, а какие нет. Постараемся написать это как можно быстрее. Когда это реализуем, введем и механизм уведомлений на новые топики (сейчас он не запущен, так как это слишком глобальный спам-охват).
А вот часть кода в процессоре создания комментария, которая как раз и отвечает за этот механизм. Если у опытных MODX-разработчиков не возникнет никаких вопросов по коду на предмет необычности, я этого не пойму;)
<?php
public function afterSave(){
$comment = $this->modx->getObject('SocietyComment',
$this->object->comment_id);
$topic = $this->modx->getObject($this->object->target_class,
$this->object->target_id);
if(empty($this->modx->smarty)){
$this->modx->invokeEvent('OnHandleRequest');
}
$this->modx->smarty->assign('topic',
$topic->toArray());
$this->modx->smarty->assign('comment',
$comment->toArray());
$this->modx->smarty->assign('topic_url',
$this->modx->makeUrl($topic->id, '', '', 'full'));
/*
Рассылаем емейл-уведомления.
Схема: https://www.lucidchart.com/documents/view/4f91f952-779b-4c62-beeb-ee6210a22ad6
*/
// Кому уже отправлялось, чтобы не отправлять повторно
// Сразу добавляем и того, кто пишет
$sended_to = array(
$this->modx->user->id,
);
// Не используем этот объект запроса, а только его клоны
$users_query = $this->modx->newQuery('modUser');
$users_query->innerJoin('modUserProfile', 'Profile');
$users_query->where(array(
"active" => 1,
"Profile.blocked" => 0,
));
$users_query->where(array(
"Profile.blockeduntil" => 0,
"OR:Profile.blockeduntil:<" => time(),
));
// Комментарий в ответ на другой комментарий?
if($parent = $comment->Parent){
// Автор комментария - автор родительского комментария?
if($parent->createdby != $this->modx->user->id){
// Если текущий пользователь не автор родительского комментария,
// то отслыаем уведомление об ответе на комментарий
if(
$ParentAuthor = $parent->Author
AND $ParentAuthor->active
AND !$ParentAuthor->Profile->blocked
){
$message = $this->modx->smarty->fetch('messages/society/new_comment/comment_reply.tpl');
$ParentAuthor->sendEmail($message, array(
"subject" => "Новый ответ на ваш комментарий",
));
$sended_to[] = $ParentAuthor->id;
$this->modx->mail->reset();
}
}
}
else{
}
// Отправляем уведомление автору топика о новом комментарии
$sended_to = array_unique($sended_to);
$q = clone($users_query);
$q->where(array(
"id" => $topic->createdby,
));
if($sended_to){
$q->where(array(
"id:not in" => $sended_to,
));
}
if($user = $this->modx->getObject('modUser', $q)){
$message = $this->modx->smarty->fetch('messages/society/new_comment/topic_author.tpl');
$user->sendEmail($message, array(
"subject" => "В вашем топике добавлен новый комментарий",
));
$sended_to[] = $user->id;
$this->modx->mail->reset();
}
// Отсылаем комментарии всем, кто в этом топике писал
// Получаем всех пользователей всех комментариев данной ветки
$sended_to = array_unique($sended_to);
$q = clone($users_query);
$q->innerJoin(
'SocietyComment',
"Comments",
"Comments.thread_id = {$comment->thread_id}
AND Comments.id != {$comment->id}
AND Comments.createdby = modUser.id"
);
if($sended_to){
$q->where(array(
"id:not in" => $sended_to,
));
}
if($users = $this->modx->getCollection('modUser', $q)){
foreach($users as $user){
$message = $this->modx->smarty->fetch('messages/society/new_comment/participants.tpl');
$user->sendEmail($message, array(
"subject" => "В топике добавлен новый комментарий",
));
$sended_to[] = $user->id;
$this->modx->mail->reset();
}
}
// Отсылаем уведомление администрации
$sended_to = array_unique($sended_to);
$q = clone($users_query);
$q->innerJoin('modUserGroupMember', 'UserGroupMembers');
$q->where(array(
"UserGroupMembers.user_group" => '1',
));
if($sended_to){
$q->where(array(
"id:not in" => $sended_to,
));
}
if($users = $this->modx->getCollection('modUser', $q)){
foreach($users as $user){
$message = $this->modx->smarty->fetch('messages/society/new_comment/administration.tpl');
$user->sendEmail($message, array(
"subject" => "В топике добавлен новый комментарий",
));
$sended_to[] = $user->id;
$this->modx->mail->reset();
}
}
return parent::afterSave();
}