В данном разделе мы реализуем функции отображения и создания комментариев.
Для большей интерактивности будем проводить валидацию на стороне клиента. При помощи Yii сделать это довольно легко. Отметим, что для этого потребуется Yii версии 1.1.1 или новее.
Вместо использования отдельных страниц для отображения и создания
комментариев, мы используем страницу записи (генерируемую действием view
контроллера PostController
). Под текстом записи мы отображаем список
комментариев, принадлежащих ей и форму создания комментария.
Чтобы отобразить комментарии на странице записи, мы изменяем отображение
/wwwroot/blog/protected/views/post/view.php
следующим образом:
…основная часть отображения post… <div id="comments"> 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> 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 валидацию полей формы. В этом случае пользователь
получает информацию об ошибках по мере заполнения формы. Для использования данной возможности в форме комментариев
необходимо сделать несколько изменений в отображении /wwwroot/blog/protected/views/comment/_form.php
и методе newComment()
.
В файле _form.php
нам необходимо установить свойство CActiveForm::enableAjaxValidation
для виджета CActiveForm в true
:
<div class="form"> $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;
}
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.