Николай Ланец
22 авг. 2014 г., 2:35

Емейл-уведомления о новых комментариях в топиках

Сегодня была написана и введена на сайте система емейл-уведомлений о новых комментариях в топиках.
Уведомления четырех типов:
  1. Если это ответ на чужой комментарий, то отправляется уведомление автору родительского комментария.
  2. Затем отправляется уведомление автору топика, если он не был автором родительского комментария.
  3. Затем всем участникам дискуссии в этом топике.
  4. И напоследок администрации.
Сам собой один пользователь получит только одно письмо по приоритету события. Правда предстоит еще написать личные настройки пользователей, где каждый мог бы указать какие уведомления он хочет получать, а какие нет. Постараемся написать это как можно быстрее. Когда это реализуем, введем и механизм уведомлений на новые топики (сейчас он не запущен, так как это слишком глобальный спам-охват).
Вот примерная логическая схема: https://www.lucidchart.com/documents/view/4f91f952-779b-4c62-beeb-ee6210a22ad6
А вот часть кода в процессоре создания комментария, которая как раз и отвечает за этот механизм. Если у опытных 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(); }

Добавить комментарий