0 follower

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

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

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

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

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

public function actionShow()
{
    $post=$this->loadPost();
    $this->render('show',array(
        'post'=>$post,
        'comments'=>$post->comments,
    ));
}

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

Мы также изменяем представление show, добавляя отображение комментария в конце отображения записи, которое мы не будем уточнять.

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

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

public function actionShow()
{
    $post=$this->loadPost();
    $comment=$this->newComment($post);
    $this->render('show',array(
        'post'=>$post,
        'comments'=>$post->comments,
        'newComment'=>$comment,
    ));
}
 
protected function newComment($post)
{
    $comment=new Comment;
    if(isset($_POST['Comment']))
    {
        $comment->attributes=$_POST['Comment'];
        $comment->postId=$post->id;
        $comment->status=Comment::STATUS_PENDING;
 
        if(isset($_POST['previewComment']))
            $comment->validate('insert');
        else if(isset($_POST['submitComment']) && $comment->save())
        {
            Yii::app()->user->setFlash('commentSubmitted','Спасибо...');
            $this->refresh();
        }
    }
    return $comment;
}

Выше мы вызываем метод newComment() перед рендерингом представления show. В методе newComment() мы создаем экземпляр класса Comment и проверяем, отправлена ли форма комментария. Форма может быть отправлена щелчком мыши либо по кнопке отправки либо по кнопке предпросмотра. Если первое, то пытаемся сохранить комментарий и отобразить flash-сообщение. Flash-сообщение отображается только один раз, а значит, при следующем обновлении страницы оно исчезнет.

Мы также модифицируем представление show добавлением формы создания комментария:

......
<?php $this->renderPartial('/comment/_form',array(
    'comment'=>$newComment,
    'update'=>false,
)); ?>

Здесь мы включаем форму создания комментария рендерингом частичного представления /wwwroot/blog/protected/views/comment/_form.php. Переменная $newComment передается методом actionShow. Её назначение - хранение введенного пользовательского комментария. Переменная update установлена в значение false, которое указывает, что форма комментария используется для создания нового комментария.

Для поддержки предварительного просмотра комментария мы добавляем кнопку предварительного просмотра к форме создания комментария. Когда нажимается кнопка предварительного просмотра, предварительный вид комментария отображается внизу страницы. Ниже обновленный код формы комментария:

... форма комментария с кнопкой предварительного просмотра...
 
<?php if(isset($_POST['previewComment']) && !$comment->hasErrors()): ?>
<h3>Предварительный просмотр</h3>
<div class="comment">
  <div class="author"><?php echo $comment->authorLink; ?> сказал:</div>
  <div class="time"><?php echo date('F j, Y \a\t h:i a',$comment->createTime); ?></div>
  <div class="content"><?php echo $comment->contentDisplay; ?></div>
</div><!-- post preview -->
<?php endif; ?>