Сегодня была написана и введена на сайте система емейл-уведомлений о новых комментариях в топиках. Уведомления четырех типов: Если это ответ на чужой комментарий, то отправляется уведомление автору родительского комментария. Затем отправляется уведомление автору топика, если он не был автором родительского комментария. Затем всем участникам дискуссии в этом топике. И напоследок администрации. Сам собой один пользователь получит только одно письмо по приоритету события. Правда предстоит еще написать личные настройки пользователей, где каждый мог бы указать какие уведомления он хочет получать, а какие нет. Постараемся написать это как можно быстрее. Когда это реализуем, введем и механизм уведомлений на новые топики (сейчас он не запущен, так как это слишком глобальный спам-охват). Вот примерная логическая схема: 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();
}