CakePHPでは、モデルオブジェクトでアクセスコントロールを行う場合にAclビヘイビアを使用します。
ただし、標準のAclビヘイビアは若干クセがあり、設定しづらいものとなっています。
今回はAclBehaviorを拡張し、ACLの機能をモデルへ手早く組み込むことが出来るようにする、AclPlusBehaviorを紹介します。
CakePHPに同梱されているAclビヘイビアを使う場合、以下のようにモデルを定義します。
参考: The Cookbook − リクエスタとして振舞う :: ACL を制御するシンプルなアプリケーション
class Group extends AppModel { var $name = 'Group'; var $hasMany = array('User'); var $actsAs = array('Acl' => array( 'type' => 'requester' )); function parentNode() { return null; } } class User extends AppModel { var $name = 'User'; var $belongsTo = array('Group'); var $actsAs = array('Acl' => array( 'type' => 'requester' )); function parentNode() { if (!$this->id && empty($this->data)) { return null; } $data = $this->data; if (empty($this->data)) { $data = $this->read(); } if (!$data['User']['group_id']) { return null; } else { return array('Group' => array('id' => $data['User']['group_id'])); } } }
ビヘイビアの’type’パラメータは、モデルがAROの場合には’reguester’、ACOの場合には’controlled’と指定するようになっており、ちょっと分かりにくいです。
また上位オブジェクトの取得のためにparentNodeメソッドを定義する必要があります。
このあたりの面倒くささを解決するのがAclPlusビヘイビアになります。
AclPlusビヘイビアのポイント
- typeパラメータへ’requester’または’controlled’の代わりに、’aro‘または’aco‘と書いて型を指定できるようになります。
- parentNodeメソッドを提供します。ビヘイビアのパラメータにモデル名、外部キーを指定するだけで親データを取得できます。指定しない場合はbelongsToから取得を試みます。
- aliasFieldパラメータを追加します。aliasFieldに指定されたフィールド名のデータがACLのエイリアスとして使用されます。
上記の例であれば、下記のように書き換えることができます。
class Group extends AppModel { var $name = 'Group'; var $hasMany = array('User' => array( 'className' => 'User', 'foreginKey' => 'group_id', )); var $actsAs = array('AclPlus' => array( 'type' => 'aro', // requesterの代わりにaroを使用できる 'parentNodeType' => 'root' // 上位モデルが無い場合は、parentNodeTypeにrootを指定。 )); } class User extends AppModel { var $name = 'User'; var $belongsTo = array('Group' => array( 'className' => 'Group', 'foreginKey' => 'group_id', )); var $actsAs = array('AclPlus' => array( 'type' => 'aro', // requesterの代わりにaroを使用できる 'aliasFields' => 'username' // usernameフィールドの値をAROのエイリアスとして指定する )); }
これだけで、モデルにACLの機能を組み込むことが出来るようになります。
他の例として、ArticleモデルとCommentモデルの場合は操作対象オブジェクトとなるので
class Article extends AppModel { var $name = 'Article'; var $hasMany = array('Comment'); var $actsAs = array('AclPlus' => 'aco'); // controlledの代わりにacoを使用できる } class Comment extends AppModel { var $name = 'Comment'; var $belongsTo = array('Article'); var $actsAs = array('AclPlus' => 'aco'); }
といったように、指定します。
ダウンロード
AclPlusBehaviorは、こちらから入手してください。
gist: 434135 – Extend Acl Behavior- GitHub
ダウンロードしたコードを
acl_plus.phpとして APP/models/behaviors/ 配下へ設置すれば利用可能になります。
本ビヘイビアはCakePHP 1.3.2のコードをベースにしています。1.2系での動作は確認していません。
質問・要望等について
質問、要望等は、@nojimage宛にささやいていただくか、この記事のコメント欄にお寄せください。
CakePHP 1.3.8のコードをベースに書き直しています。 https://gist.github.com/434135