記事の作成と修正
“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番めのルールが一致して、ユーザにアクセス権が与えられる。
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')』を呼ぶ。
■”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'); }
参考サイト:
http://www.yiiframework.com/doc/blog/1.1/ja/post.create