Создание и отображение комментариев
===================================
В данном разделе мы реализуем функции отображения и создания комментариев.
Для большей интерактивности будем проводить валидацию на стороне клиента.
При помощи Yii сделать это довольно легко. Отметим, что для этого потребуется
Yii версии 1.1.1 или новее.
Отображение комментариев
------------------------
Вместо использования отдельных страниц для отображения и создания
комментариев, мы используем страницу записи (генерируемую действием `view`
контроллера `PostController`). Под текстом записи мы отображаем список
комментариев, принадлежащих ей и форму создания комментария.
Чтобы отобразить комментарии на странице записи, мы изменяем отображение
`/wwwroot/blog/protected/views/post/view.php` следующим образом:
~~~
[php]
…основная часть отображения post…
~~~
Выше мы вызываем `renderPartial()` для вывода отображения `_comments`, показывающего
список комментариев к текущей записи. Заметим, что в отображении, для получения
комментариев к записи, мы используем выражение `$model->comments`. Это возможно
так как мы объявили связь `comments` в классе `Post`. Выполнение этого
выражения вызывает дополнительный JOIN-запрос к БД, чтобы возвратить
нужные комментарии. Эта возможность известна как [ленивая загрузка](/doc/guide/ru/database.arr).
Отображение `_comments` не очень интересно. В нём производится обход всех комментариев
и их вывод. Заинтересованные читатели могут посмотреть файл
`/wwwroot/yii/demos/blog/protected/views/post/_comments.php`.
Создание комментариев
---------------------
Чтобы обработать создание комментария, мы сначала изменяем метод `actionView()`
контроллера `PostController` следующим образом:
~~~
[php]
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`:
~~~
[php]
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`:
~~~
[php]
…
~~~
В приведённом выше коде мы показываем моментальное сообщение, если оно есть.
В обратном случае — показываем форму ввода комментария из файла
`/wwwroot/blog/protected/views/comment/_form.php`.
AJAX валидация
--------------
Для того, чтобы улучшить удобство формы, можно использовать AJAX валидацию полей формы. В этом случае пользователь
получает информацию об ошибках по мере заполнения формы. Для использования данной возможности в форме комментариев
необходимо сделать несколько изменений в отображении `/wwwroot/blog/protected/views/comment/_form.php` и методе `newComment()`.
В файле `_form.php` нам необходимо установить свойство [CActiveForm::enableAjaxValidation]
для виджета [CActiveForm] в `true`:
~~~
[php]
beginWidget('CActiveForm', array(
'id'=>'comment-form',
'enableAjaxValidation'=>true,
)); ?>
…
endWidget(); ?>
~~~
В метод `newComment()` мы добавляем код, отвечающий на запросы AJAX валидации.
Код проверяет, есть ли параметр `POST` с именем `ajax`. Если есть — отдаёт
результат валидации, используя [CActiveForm::validate].
~~~
[php]
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;
}
~~~
commentCount . 'comment(s)'; ?>
renderPartial('_comments',array( 'post'=>$model, 'comments'=>$model->comments, )); ?>