この節では、コメントの表示と作成の機能を実装します。
ユーザーのインタラクティブ性を向上するために、入力欄への入力が確定するたびにエラー表示をします。いわゆるクライアントサイドの入力検証(client-side input validation)です。これをYiiで行う方法を説明します。シームレスそして極めて簡単にできます。
コメントの表示・作成に個別のページを使う代わりに、記事の詳細ページ(PostControllerのviewアクションで生成される)を使います。以下の記事内容の表示では、記事に属するコメント一覧を最初に表示し、それからコメントの投稿フォームを表示します。
記事の詳細ページにコメントを表示するため、ビュースクリプト/wwwroot/blog/protected/views/post/view.phpを以下のように修正します。
...post view here... <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>
上の例では、現在の記事に属するコメント一覧を表示するために、_commentsという部分的ビューを指定してrenderPartial()を呼んでいます。ビューでは、$model->commentsという式で、記事のコメントを取得できます。この式が使える理由は、Postクラスでcommentsリレーションを宣言しているからです。この式が評価されると、暗黙的にデータベースのJOINクエリーが発行され、適切なコメントが返されます。この機能はlazy relational queryとして知られています。
部分的ビュー(partial view)の_commentsはあまり興味深いものではありません。コメントを一つ一つ取り扱い、コメントの詳細を表示します。興味のある方は/wwwroot/yii/demos/blog/protected/views/post/_comments.phpを参照してください。
コメントの作成を扱うために、PostControllerのactionView()メソッドを以下のように修正します。
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; }
それからPostモデルクラスを修正して、addComment()メソッドを以下のように追加します。
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(); }
上記コードでは、viewを表示する前にnewComment()メソッドを呼んでいます。newComment()メソッドでは、Commentインスタンスを生成し、コメントフォームが送信されたかどうかをチェックします。もし送信されていた場合、$post->addComment($comment)を呼んで記事にコメントを追加しようとします。問題なく進んだら記事の詳細ページをリフレッシュします。再表示されたページには、コメント承認制でなければ、新しく投稿されたコメントが表示されます。表示前にコメントの承認が必要な場合は、フラッシュ・メッセージを使って、承認が必要であることをユーザーに示します。フラッシュ・メッセージは大抵、エンドユーザーに確認メッセージを見せるものです。ユーザーがブラウザの再読み込みボタンをクリックしたら、メッセージは消えます。
さらに/wwwroot/blog/protected/views/post/view.phpを修正します。
...... <div id="comments"> ...... <h3>Leave a Comment</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を使ってコメント入力フォームを表示します。
コメントフォームのクライアントサイド・バリデーションをサポートするため、コメントフォームのビュー/wwwroot/blog/protected/views/comment/_form.phpと、newComment()メソッドの両方に小さな変更を加える必要があります。
_form.phpでは、CActiveFormウィジェットを作成するときに、CActiveForm::enableAjaxValidationをtrueに設定します。
<div class="form"> <?php $form=$this->beginWidget('CActiveForm', array( 'id'=>'comment-form', 'enableAjaxValidation'=>true, )); ...... <?php $this->endWidget(); </div><!-- form -->
newComment()メソッドでは、AJAXバリデーションのリクエストに応答するためのコードを追加します。このコードはajaxという名前のPOST変数があるかどうかチェックします。もしあれば、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 login to leave your comment.