Fi1osof 22 августа 2014 0 0
Сегодня была написана и введена на сайте система емейл-уведомлений о новых комментариях в топиках.

Уведомления четырех типов:
  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();
    }
0 комментариев
Авторизуйтесь или зарегистрируйтесь (можно через соцсети ), чтобы оставлять комментарии.