Создание и отображение комментариев

В данном разделе мы реализуем функции отображения и создания комментариев.

Для большей интерактивности будем проводить валидацию на стороне клиента. При помощи Yii сделать это довольно легко. Отметим, что для этого потребуется Yii версии 1.1.1 или новее.

Отображение комментариев #

Вместо использования отдельных страниц для отображения и создания комментариев, мы используем страницу записи (генерируемую действием view контроллера PostController). Под текстом записи мы отображаем список комментариев, принадлежащих ей и форму создания комментария.

Чтобы отобразить комментарии на странице записи, мы изменяем отображение /wwwroot/blog/protected/views/post/view.php следующим образом:

…основная часть отображения post…

<div id="comments">
    <?
php if($model->commentCount>=1): ?>
        <h3>
             echo $model->commentCount 'comment(s)'?>
        </h3>

         $this->renderPartial('_comments',array(
            
'post'=>$model,
            
'comments'=>$model->comments,
        )); 
?>
     endif; ?>
</div>

Выше мы вызываем renderPartial() для вывода отображения _comments, показывающего список комментариев к текущей записи. Заметим, что в отображении, для получения комментариев к записи, мы используем выражение $model->comments. Это возможно так как мы объявили связь comments в классе Post. Выполнение этого выражения вызывает дополнительный JOIN-запрос к БД, чтобы возвратить нужные комментарии. Эта возможность известна как ленивая загрузка.

Отображение _comments не очень интересно. В нём производится обход всех комментариев и их вывод. Заинтересованные читатели могут посмотреть файл /wwwroot/yii/demos/blog/protected/views/post/_comments.php.

Создание комментариев #

Чтобы обработать создание комментария, мы сначала изменяем метод actionView() контроллера PostController следующим образом:

public function actionView()
{
    
$post=$this->loadModel();
    
$comment=$this->newComment($post);

    
$this->render('view',array(
        
'model'=>$post,
        
'comment'=>$comment,
    ));
}

protected function 
newComment($post)
{
    
$comment=new Comment;
    if(isset(
$_POST['Comment']))
    {
        
$comment->attributes=$_POST['Comment'];
        if(
$post->addComment($comment))
        {
            if(
$comment->status==Comment::STATUS_PENDING)
                
Yii::app()->user->setFlash('commentSubmitted','Thank you for your comment.
                Your comment will be posted once it is approved.'
);
            
$this->refresh();
        }
    }
    return 
$comment;
}

Далее мы добавляем метод addComment() в модель Post:

public function addComment($comment)
{
    if(
Yii::app()->params['commentNeedApproval'])
        
$comment->status=Comment::STATUS_PENDING;
    else
        
$comment->status=Comment::STATUS_APPROVED;
    
$comment->post_id=$this->id;
    return 
$comment->save();
}

Выше мы вызываем метод newComment() перед показом представления view. В методе newComment() мы создаем экземпляр класса Comment и проверяем, отправлена ли форма комментария. Если отправлена — пробуем добавить комментарий к записи, вызывая $post->addComment($comment). Если получилось — обновляем страницу записи, на которой будет показан только что созданный комментарий в том случае, если он не требует одобрения. В противном случае показываем моментальное сообщение о том, что комментарий будет показан как только он будет одобрен. Моментальное сообщение обычно выводится для подтверждения какого-то действия. Если пользователь обновляет страницу, такое сообщение исчезает.

Продолжаем изменять /wwwroot/blog/protected/views/post/view.php:


<div id="comments">
    

    
<h3>Оставить комментарий</h3>

    <?
php if(Yii::app()->user->hasFlash('commentSubmitted')): ?>
        <div class="flash-success">
             echo Yii::app()->user->getFlash('commentSubmitted'); ?>
        </div>
     else: ?>
         $this->renderPartial('/comment/_form',array(
            
'model'=>$comment,
        )); 
?>
     endif; ?>

</div><!-- comments -->

В приведённом выше коде мы показываем моментальное сообщение, если оно есть. В обратном случае — показываем форму ввода комментария из файла /wwwroot/blog/protected/views/comment/_form.php.

AJAX валидация #

Для того, чтобы улучшить удобство формы, можно использовать AJAX валидацию полей формы. В этом случае пользователь получает информацию об ошибках по мере заполнения формы. Для использования данной возможности в форме комментариев необходимо сделать несколько изменений в отображении /wwwroot/blog/protected/views/comment/_form.php и методе newComment().

В файле _form.php нам необходимо установить свойство CActiveForm::enableAjaxValidation для виджета CActiveForm в true:

<div class="form">

<?
php $form=$this->beginWidget('CActiveForm', array(
    
'id'=>'comment-form',
    
'enableAjaxValidation'=>true,
)); 
?>

 $this->endWidget(); ?>

</div><!-- form -->

В метод newComment() мы добавляем код, отвечающий на запросы AJAX валидации. Код проверяет, есть ли параметр POST с именем ajax. Если есть — отдаёт результат валидации, используя CActiveForm::validate.

protected function newComment($post)
{
    
$comment=new Comment;

    if(isset(
$_POST['ajax']) && $_POST['ajax']==='comment-form')
    {
        echo 
CActiveForm::validate($comment);
        
Yii::app()->end();
    }

    if(isset(
$_POST['Comment']))
    {
        
$comment->attributes=$_POST['Comment'];
        if(
$post->addComment($comment))
        {
            if(
$comment->status==Comment::STATUS_PENDING)
                
Yii::app()->user->setFlash('commentSubmitted','Thank you for your comment. Your comment will be posted once it is approved.');
            
$this->refresh();
        }
    }
    return 
$comment;
}

Зачем реклама?