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

記事の作成と修正

“Post”モデルの実装後、”PostController”のためのアクションとビューを手直しする。
先ずは、CRUD操作のアクセス制御をカスタマイズして、次に『create』と『update』の
操作を実装しているコードを修正する。

アクセス制御のカスタマイズ

【Gii】で生成したコードは要求にあっていないためコントローラーファイルを修正する。

  public function accessRules()
  {
    return array(
      // 全てのユーザに'index'と'view'のアクションを許可
      array(
        'allow',
        'actions'=>array('index', 'view'),
        'users'=>array('*'),
      ),
      // 認証されたユーザに全てのアクションを許可
      array(
        'allow',
        'users'=>array('@'),
      ),
      // 全てのユーザのアクセスを拒否
      array(
        'deny',
        'users'=>array('*'),
      ),
    );
  }

■上記のルールについて

全てのユーザが"index"(一覧)と"view"(詳細)アクションにアクセスが可能。
認証済みユーザは"admin"アクションを含めた全てのアクションにアクセスが可能。
それ以外のシナリオはアクセスが拒否される。

これらのルールは書き並べた順番で評価されるため、その時の状況に最初に一致したルールによって
アクセスの可否が決まる。例えば、ユーザがシステムオーナで記事作成ページを訪れようとした場合
2番めのルールが一致して、ユーザにアクセス権が与えられる。

管理者画面
yii030

create操作とupdate操作のカスタマイズ

■記事ステータスを選択させるドロップダウンリストを生成する

  <div class="row">
    <?php echo $form->labelEx($model,'status'); ?>
    <?php echo $form->dropDownList($model,'status',Lookup::items('PostStatus')); ?>
    <?php echo $form->error($model,'status'); ?>
  </div>
記事ステータスのドロップダウンリストのデータを取得する『Lookup::items('PostStatus')』を呼ぶ。

yii031

■”Post”モデルを修正
データベースに保存される前に幾つかの属性(create_timeやauthor_id)が自動的にセットされるようにbeforeSave()メソッドをオーバーライドする。

  /**
   * 
   * 自動設定処理
   * 登録日:crate_time
   * 投稿者ID:author_id
   * 
   **/
  protected function beforeSave()
  {
    if(parent::beforeSave())
    {
      if($this->isNewRecord)
      {
        // 新規登録:登録時間と投稿者IDを登録
        $this->create_time = $this->update_time = time();
        $this->author_id = Yii::app()->user->id;
      }
      else
      {
        // 更新処理:更新時間を更新
        $this->update_time = time();
      }
      
      return true;
    }
    else
    {
      return false;
    }
  }
  
  private $_oldTags;
  
  /**
   * 
   * タグ更新
   * 
   **/
  protected function afterSave()
  {
    parent::afterSave();
    // 更新タグと更新前のタグを比較して更新させる
    Tag::model()->updateFrequency($this->_oldTags, $this->tags);
  }
  
  /**
   * 
   * タグ更新判定
   * 
   **/
  protected function afterFind()
  {
    parent::afterFind();
    // 更新前のタグ情報を格納
    $this->_oldTags = $this->tags;
  }
記事を保存するとき、タグの出現頻度の変化を反映するために"tbl_tag"テーブルを更新する必要がある。
この処理は"afterSave()"メソッドに書くことで実現できる。"afterSave()"メソッドはデータベースへの
記事の保存が成功した後に【Yii】から自動的に呼ばれる。

タグが変更されたかどうかの判定に"afterFind()"メソッドを用いて、"_oldTags"変数に更新前のタグを保持する。
この"afterFind()"メソッドは、アクティブレコードにデータベースから取得したデータが投入された時に、【Yii】から自動的に呼ばれる。

■”Tag”モデルでupdateFrequencyを実装
タグ更新のロジックを実装する

  /**
   * 
   * タグ更新処理
   * 
   **/
  public function updateFrequency($oldTags, $newTags)
  {
    $oldTags = self::string2array($oldTags);
    $newTags = self::string2array($newTags);
    
    // タグを追加
    $this->addTags(array_values(array_diff($newTags, $oldTags)));
    // タグを削除
    $this->removeTags(array_values(array_diff($oldTags, $newTags)));
  }
  
  /**
   * 
   * タグ追加
   * 
   **/
  public function addTags($tags)
  {
    $criteria = new CDbCriteria;
    $criteria->addInCondition('name', $tags);
    $this->updateCounters(array('frequency'=>1), $criteria);
    
    foreach($tags as $name)
    {
      if(!$this->exists('name=:name', array(':name'=>$name)))
      {
        $tag = new Tag;
        $tag->name = $name;
        $tag->frequency = 1;
        $tag->save();
      }
    }
  }
  
  /**
   * 
   * タグ削除
   * 
   **/
  public function removeTags($tags)
  {
    if(empty($tags))
    {
      return;
    }
    
    $criteria = new CDbCriteria;
    $criteria->addInCondition('name', $tags);
    
    $this->updateCounters(array('frequency'=>-1), $criteria);
    $this->deleteAll('frequency<=0');
  }

記事入力画面
yii032

記事投稿画面
yii033

記事更新画面
yii034

記事投稿画面
yii035

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

Next Post

Comments are closed.