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

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

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

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

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

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

…основная часть отображения post…
 
<div id="comments">
    <?php if($model->commentCount>=1): ?>
        <h3>
            <?php echo $model->commentCount . 'comment(s)'; ?>
        </h3>
 
        <?php $this->renderPartial('_comments',array(
            'post'=>$model,
            'comments'=>$model->comments,
        )); ?>
    <?php endif; ?>
</div>

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

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

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

Чтобы обработать создание комментария, мы сначала изменяем метод 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">
            <?php echo Yii::app()->user->getFlash('commentSubmitted'); ?>
        </div>
    <?php else: ?>
        <?php $this->renderPartial('/comment/_form',array(
            'model'=>$comment,
        )); ?>
    <?php endif; ?>
 
</div><!-- comments -->

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

3. 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,
)); ?>
…
<?php $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;
}

Be the first person to leave a comment

Please to leave your comment.