Yii ブログシステム作成(11)

コメントの作成と表示

コメントの表示と作成の機能を実装する。
コメント作成の際は入力欄への入力が確定するたびにチェックして
エラーを表示し再入力を促すようにする。

コメントの表示

個別記事(view)ページからコメントの表示及び作成を行う。
記事に関するコメントをリスト表示し、その下にコメントの投稿フォームを表示する。

<div id="comments">
  <?php if($model->commentCount >= 1): ?>
    <h3>
      <?php echo $model->commentCount.'個のコメント'; ?>
    </h3>
    <?php
      $this->renderPartial(
        '_comments',
        array(
          'post'=>$model,
          'comments'=>$model->comments,
        )
      );
    ?>
  <?php endif; ?>
</div>

“Post”ビューに”_comments.php”ファイルを追加

<?php foreach($comments as $comment): ?>
<div class="comment" id="c<?php echo $comment->id; ?>">
  <?php
    echo CHtml::link(
      "#{$comment->id}",
      $comment->getUrl($post),
      array(
        'class'=>'cid',
        'title'=>'Permalink to this comment',
      )
    );
  ?>
  
  <div class="author">
    <?php echo $comment->authorLink; ?>:
  </div>
  
  <div class="time">
    <?php echo date('F j, Y \a\t h:i a', $comment->create_time); ?>
  </div>
  
  <div class="content">
    <?php echo nl2br(CHtml::encode($comment->content)); ?>
  </div>
</div>
<?php endforeach; ?>

“Comment”モデルにメソッドを追加する

	/**
	 * 
	 * URL取得
	 * 
	 **/
	public function getUrl($post=null)
	{
		if($post === null)
		{
			$post = $this->post;
		}
		
		return $post->url.'#c'.$this->id;
	}
	
	/**
	 * 
	 * 記事リンク取得
	 * 
	 **/
	public function getAuthorLink()
	{
		if(!empty($this->url))
		{
			return CHtml::link(CHtml::encode($this->author), $this->url);
		}
		else
		{
			return CHtml::encode($this->author);
		}
	}
上の例では、現在の記事に属するコメント一覧を表示するために_commentsという部分的ビューを指定して
renderPartial()を呼んでいる。事前に"Comment.php"ファイルを追加する必要があり
ビューで『$model->comments』という式を使って記事に属するコメントを取得できるのは"Post"クラスで
"relation()"にて宣言しているため。
この式が評価されると、暗黙的にデータベースのJOINクエリが発行され、適切なコメントが返される。
この機能は遅延リレーショナルクエリと呼ばれる。

コメントの作成

コメントの作成を行うために、”PostController”の”actionView()”メソッドを修正及び”newComment()”メソッドを追加

  /**
   * 
   * ビューアクション
   * 
   **/
  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;
    
    // AJAXモードチェック
    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))
      {
        // コメント承認のチェック 参照:params.php
        if($comment->status == Comment::STATUS_PENDING)
        {
          // 承認が必要な場合はメッセージを表示
          Yii::app()->user->setFlash('commentSubmitted', 'コメントは承認後に表示されます。');
        }
        
        // 詳細ページをリフレッシュ
        $this->refresh();
      }
    }
    
    return $comment;
  }

“Post”モデルに”addComment()”メソッドを追加する

  /**
   * 
   * コメント追加
   * 
   **/
  public function addComment($comment)
  {
    // コメントの承認が必要かどうか:参照params.php
    if(Yii::app()->params['commentNeedApproval'])
    {
      // 承認必要
      $comment->status = Comment::STATUS_PENDING;
    }
    else
    {
      // 承認不必要
      $comment->status = Comment::STATUS_APPROVED;
    }
    
    // コメントID設定
    $comment->post_id = $this->id;
    
    return $comment->save();
  }
上記コードではviewを表示する前に"newComment()"メソッドを呼んでいる。
"newComment()"メソッドでは、"Comment"インスタンスを生成し、コメントフォームが送信されたかをチェックする。
送信されている場合、"$post->addComment($comment)"を呼んで記事にコメントを追加する。
問題なく処理が進むと記事の詳細ページをリフレッシュする。再表示されたページは、コメント承認制でなければ、
新しく投稿されたコメントが表示される。
コメントの承認が必要な場合は、フラッシュメッセージを使って、承認が必要であることをユーザに示す。(※1)

※1:コメントの承認ついて

【Yii】のデモにあるブログシステムではデフォルトでコメント承認が『未承認』の状態になっている。
且つチュートリアル通りに進めると設定ファイルについての記述がなかった多分。

コメント承認の設定は下記の手順をふむ必要がある。
“config”フォルダに”params.php”ファイルを追加して『commentNeedApproval』をtrueにする。
“main.php”ファイルの最下部を

‘params’=>require(dirname(__FILE__).’/params.php’),

に書き換える。

各ビューファイルを編集する

<div id="comments">
  <?php if($model->commentCount >= 1): ?>
    <h3>
      <?php echo $model->commentCount.'個のコメント'; ?>
    </h3>
    <?php
      $this->renderPartial(
        '_comments',
        array(
          'post'=>$model,
          'comments'=>$model->comments,
        )
      );
    ?>
  <?php endif; ?>
  <h3>コメントする</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>
<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'post-form',
	'enableAjaxValidation'=>true,
)); ?>
<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'comment-form',
	'enableAjaxValidation'=>true,
)); ?>

	<p class="note">Fields with <span class="required">*</span> are required.</p>

	<div class="row">
		<?php echo $form->labelEx($model,'author'); ?>
		<?php echo $form->textField($model,'author',array('size'=>60,'maxlength'=>128)); ?>
		<?php echo $form->error($model,'author'); ?>
	</div>

	<div class="row">
		<?php echo $form->labelEx($model,'email'); ?>
		<?php echo $form->textField($model,'email',array('size'=>60,'maxlength'=>128)); ?>
		<?php echo $form->error($model,'email'); ?>
	</div>

	<div class="row">
		<?php echo $form->labelEx($model,'url'); ?>
		<?php echo $form->textField($model,'url',array('size'=>60,'maxlength'=>128)); ?>
		<?php echo $form->error($model,'url'); ?>
	</div>

	<div class="row">
		<?php echo $form->labelEx($model,'content'); ?>
		<?php echo $form->textArea($model,'content',array('rows'=>6, 'cols'=>50)); ?>
		<?php echo $form->error($model,'content'); ?>
	</div>
	<div class="row buttons">
		<?php echo CHtml::submitButton($model->isNewRecord ? 'Submit' : 'Save'); ?>
	</div>

<?php $this->endWidget(); ?>

</div><!-- form -->

コメント入力画面
yii042

コメント送信(コメント認証あり)
yii043

入力エラー(動的チェック)
yii044

コメント送信(コメント認証無し:params.phpの”commentNeedApproval”をfalseにする)
yii045

参考サイト:
http://www.yiiframework.com/doc/blog/1.1/ja/comment.create

Comments are closed.