記事の作成と修正
“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





