自作フィルターの作成
詳しくは本家のサイトを参照してもらいたいのですが、
今まではSessionフィルターとかDIContainerフィルターとかを散々使って実装していたわけですが、
既存のフィルターだけではカバーしきれない箇所(ユーザー認証とか)を
毎回クラスので呼び出していたらきりがないので、
「action」が実行される前に「必ず動くフィルター」を今回実装する方法を教えてもらったので覚書
まずはフィルタークラスを作成します。
$ samurai add-filter kakeibo
今回は覚えるように家計簿を使ってるので、名前はkakeibo実際何でもOKっす。
そしたら、ドキュメントルートのsamurai.ymlファイルに以下のように作ったフィルターを追加します。
kakeibo :
これで下位層のすべてのactionに反映されるようになります。
そしたらさっき作ったフィルターを作成に入ります。
パスは/kakeibo/component/filter/ここにできているはず。
<?php /** * [[機能説明]] * * @package Package * @subpackage Filter * @copyright Foo Project * @author Foo Bar <foo@bar.jp> */ class Filter_Kakeibo extends Samurai_Filter { /** * コンストラクタ * * @access public */ public function __construct() { } /** * @override */ protected function _prefilter() { parent::_prefilter(); /*これがaction実行前に動くフィルター*/ } /** * @override */ protected function _postfilter() { parent::_postfilter(); /*これがaction実行後に動くフィルター*/ } }
こんな感じで作成されているはず。コメントはちょっと追加してみました。
ここのaction実行前に動くフィルターに今回authフィルターを実装します。
はい、できました。
以下はちょっと例ですけど
仕様としては認証はログイン時には名前とパスワードを入力して、
ユーザーテーブルに存在しているかを確認。
そしたらユーザーテーブルのIDをセッションに持たせる。
これがログイン認証。
その続きに、URLを直接打たれても表示できないように
セッションにIDがあるかを確認し、ない場合は認証失敗。
<?php /** * [[機能説明]] * * @package Package * @subpackage Filter * @copyright Foo Project * @author Foo Bar <foo@bar.jp> */ class Filter_Kakeibo extends Samurai_Filter { /* *セッションとアクションチェインは後で使うのでここで定義 */ public $Session; public $ActionChain; /*ユーザーマネージャー(自分で作成してください)*/ public $UserManager; /* *ユーザーidとuser(obj)はpublicで一応持っておく */ public $userid; public $user; /** * コンストラクタ * * @access public */ public function __construct() { } /** * @override */ protected function _prefilter() { parent::_prefilter(); /*すべてのアクションの実行前に行いたい処理を書く*/ //もしもauthがtrueならユーザー認証を行う(デフォルト値はtrue) if($this->getAttribute('auth',true)){ //ユーザー認証 $this->_auth(); } } /* *ユーザー認証を行うメソッド */ private function _auth(){ //セッション取得(セッションにuseridが入る予定) $this->userid =$this->Session->get('userid'); $this->_errorView($this->userid); //テーブルから取得 $this->user = $this->UserManager->get($this->userid); $this->_errorView($this->user); } /* * エラーハンドリング */ private function _errorView($user){ //取得できなかった場合 if(!$user){ /*ここでエラーリストを作成して、authErrorという名前でset*/ $errorList = $this->ActionChain->getCurrentErrorList(); $errorList->setType('authError'); } } /** * @override */ protected function _postfilter() { parent::_postfilter(); /*すべてのアクションの実行後に行いたい処理を書く*/ } }
これでフィルターの作成は終わりましたが、
今のままではすべてのactionで認証が起きてログイン画面でも認証が動いて
無限ループにはまってしまいます。
なので、ログイン画面では認証を動かさないようにしたいので、login.ymlに以下のように
記述します。
# # login.yml # Kakeibo : auth : false
これでフィルターに作成した値が初期値ではなくfalseを返すようになり、
認証が動かないようになります。
要点としては
フィルターを作成>ymlファイルにフィルターを定義>実装
という感じです。