このセクションでは、コメントの表示と作成機能を実装します。
ユーザーインタラクティビティを向上させるため、ユーザーが1つのフィールドに入力するたびに発生する可能性のあるエラーをプロンプト表示します。これは、クライアントサイド入力検証と呼ばれます。Yiiでこれをどのようにシームレスかつ非常に簡単に実行できるかを示します。Yiiバージョン1.1.1以降が必要です。
個々のページにコメントを表示および作成する代わりに、投稿詳細ページ( `PostController` の `view` アクションによって生成される)を使用します。投稿コンテンツの表示の下に、最初にその投稿に属するコメントのリストを表示し、次にコメント作成フォームを表示します。
投稿詳細ページにコメントを表示するために、ビュースクリプト `/wwwroot/blog/protected/views/post/view.php` を次のように変更します。
...post view here... <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` 式を使用して投稿のコメントを取得していることに注意してください。 `Post` クラスで `comments` リレーションを宣言しているため、これは有効です。この式を評価すると、暗黙的なJOINデータベースクエリがトリガーされ、適切なコメントが返されます。この機能は、遅延リレーショナルクエリと呼ばれます。
部分ビュー `_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;
}
次に、 `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();
}
上記では、 `view` をレンダリングする前に `newComment()` メソッドを呼び出します。 `newComment()` メソッドでは、 `Comment` インスタンスを生成し、コメントフォームが送信されたかどうかを確認します。送信された場合は、 `$post->addComment($comment)` を呼び出して投稿にコメントを追加しようとします。それが成功した場合、投稿詳細ページを更新し、承認が必要ない限り、新しく作成されたコメントが表示されます。コメントが表示される前に承認が必要な場合、コメントが承認されると表示されることをユーザーに示すフラッシュメッセージを表示します。フラッシュメッセージは通常、エンドユーザーに表示される確認メッセージです。ユーザーがブラウザの更新ボタンをクリックすると、メッセージは消えます。
また、 `/wwwroot/blog/protected/views/post/view.php` をさらに変更する必要があります。
...... <div id="comments"> ...... <h3>Leave a Comment</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ベースのフォームフィールド検証を使用できます。これにより、ユーザーはフォーム全体をサーバーに送信する前に、フォームに入力するときに検証フィードバックを受け取ることができます。コメントフォームでAjaxベースの検証をサポートするには、コメントフォームビュー `/wwwroot/blog/protected/views/comment/_form.php` と `newComment()` メソッドの両方に小さな変更を加える必要があります。
`_form.php` ファイルでは、CActiveForm ウィジェットを作成するときに、主に CActiveForm::enableAjaxValidation をtrueに設定する必要があります。
<div class="form"> $form=$this->beginWidget('CActiveForm', array( 'id'=>'comment-form', 'enableAjaxValidation'=>true, )); ...... $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;
}
タイプミスを見つけた、またはこのページの改善が必要だと思いますか?
githubで編集してください !
フォローアップ...
間違えて送信をクリックしました...(ちなみに、コメントを編集するにはどうすればよいですか?)
だから
$url=$this->getController()->createUrl($this->captchaAction); CHtml::image($url,$alt,$this->imageOptions);
重要な行です。最初の行は、現在の コントローラーのアクションを作成します。これは次のようになります(**get** パラメーターを使用したデフォルトのURL):**index.php?r=post/captcha**
このURLは、gdライブラリの助けを借りて実際に画像をレンダリングする**captcha アクション** CCaptchaAction を指すために使用されます(CCaptchaActionクラスのrenderImageメソッドを参照)。
しかし、これらすべてが機能するためには、**このURLが正しいアクションを指している**必要があり、これは**PostControllerのアクション配列**で行われます(ガイドのコントローラーページのアクションセクションを参照)
/** * Declares class-based actions. */ public function actions() { return array( // captcha action renders the CAPTCHA image // this is used by the contact page 'captcha'=>array( 'class'=>'CCaptchaAction', 'backColor'=>0xF5F5F5, ), ); }
これが、私と同じように完成したデモコードを見ずにチュートリアルに従おうとしていた人に役立つことを願っています。
コメントモデルのverifyCode変数
こんにちは、
15分かけてアプリケーションが
プロパティ "Comment.verifyCode" が定義されていません。
新しいコメントフォームを設定しようとしたときに
このモデルには、この同じモデルで設定された各検証ルールに対応する変数が必要だと思います。つまり、dbフィールドではないフィールドの検証ルール用です。
例
このルールがエラーを返さずに存在するには
array('verifyCode', 'captcha', 'on' => 'insert', 'allowEmpty'=>!Yii::app()->user->isGuest)
コメントモデルに次の行を追加する必要があります
public $verifyCode;
どこかで説明されていたのかもしれませんが、もしそうなら情報を見逃していました :)
誰かの役に立てば幸いです
ありがとう
はルールです
addComment
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(); }
'commentNeedApproval' の動作
'commentNeedApproval' を参照する行で何が起こっているのかを理解するのに時間がかかったので、答えを共有することにしました。
設定ファイルmain.phpにアプリパラメータを追加する必要があります
return array( ... // application-level parameters that can be accessed // using Yii::app()->params['paramName'] 'params'=>array( ... 'commentNeedApproval'=>true, ),
うまく動作します!
コメントするには、サインアップ または ログイン してください。