Создание и отображение комментариев =================================== В данном разделе мы реализуем функции отображения и создания комментариев. Для большей интерактивности будем проводить валидацию на стороне клиента. При помощи Yii сделать это довольно легко. Отметим, что для этого потребуется Yii версии 1.1.1 или новее. Отображение комментариев ------------------------ Вместо использования отдельных страниц для отображения и создания комментариев, мы используем страницу записи (генерируемую действием `view` контроллера `PostController`). Под текстом записи мы отображаем список комментариев, принадлежащих ей и форму создания комментария. Чтобы отобразить комментарии на странице записи, мы изменяем отображение `/wwwroot/blog/protected/views/post/view.php` следующим образом: ~~~ [php] …основная часть отображения post…
commentCount>=1): ?>

commentCount . 'comment(s)'; ?>

renderPartial('_comments',array( 'post'=>$model, 'comments'=>$model->comments, )); ?>
~~~ Выше мы вызываем `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] …

Оставить комментарий

user->hasFlash('commentSubmitted')): ?>
user->getFlash('commentSubmitted'); ?>
renderPartial('/comment/_form',array( 'model'=>$comment, )); ?>
~~~ В приведённом выше коде мы показываем моментальное сообщение, если оно есть. В обратном случае — показываем форму ввода комментария из файла `/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; } ~~~