Dec 4

逆引きrhaco60: フィルタをかける

逆引きじゃない気がしますが、フィルタ関連でまとめてみようと思ったので、メモ。

rhacoのフィルタはRequestを継承、使用しているクラス(RequestLogin, Flow, Views)、Urls、およびTagParserを継承、使用しているクラス(TemplateParser, HtmlParser, Flow, Views)で使用できます。

Request系のフィルタはリクエストをセットする前(reset)後(validate)で処理を追加することが出来ます。

TagParser系のフィルタはrhacoタグをhtmlに変換していく過程(init, before, after, publish)で処理を追加できます。
各段階は

  • init:テンプレートの変換開始時

  • before:テンプレートファイルからのソース読み込み、rt:include,rt:extend,rt:block,rt:replace,rt:commentタグの変換後

  • after:その他タグのphpコードへの変換後、{$hoge}などの変数割り当て前

  • publish:テンプレートの変換終了時

  • を意味します。


フィルタの指定方法は以下の様になります。フィルタ名はリクエスト用をAFilter、テンプレート用をBFilterとします。実際はリクエスト用のメソッドとテンプレート用のメソッドを同じフィルタ内に書くことが出来ます。
  • Urls

  • Urlsでリクエスト系フィルタを適用する時は全てのケースに適用されます(ハマリポイント)

Rhaco::import("generic.Urls");
Rhaco::import("database.DbUtil");
Rhaco::import("model.Product");

$parser = Urls::parser(array(
  '^$'=>array("method"=>"read","args"=>array(new Product())),
  '^create$'=>array("method"=>"create","args"=>array(new Product(),Rhaco::url('index.php')))
),new DbUtil(Product::connection()),"AFilter,BFilter");
$parser->write();

Rhaco::import("generic.Urls");
Rhaco::import("database.DbUtil");
Rhaco::import("model.Product");

$parser = Urls::parser(array(
  '^$'=>array("method"=>"read","args"=>array(new Product())),
  '^create$'=>array("method"=>"create","args"=>array(new Product(),Rhaco::url('index.php'),"BFilter"))
),new DbUtil(Product::connection()),"AFilter");
$parser->write();

  • Views

  • Viewsにフィルタを適用する時はデフォルトで定義されているgeneric.filter.ViewsFilterを明示的に指定する必要があります(ハマリポイント)

Viewsのメソッドで指定するフィルタはTagParser系のメソッドのみ行われます(ハマリポイント)
Rhaco::import("generic.Views");
Rhaco::import("database.DbUtil");
Rhaco::import("model.Product");
$views = new Views(new DbUtil(Product::connection()),"generic.filter.ViewsFilter,AFilter,BFilter");
$parser = $views->create(new Product(),Rhaco::url("index.php"));
$parser->write();

Rhaco::import("generic.Views");
Rhaco::import("database.DbUtil");
Rhaco::import("model.Product");
$views = new Views(new DbUtil(Product::connection()),"generic.filter.ViewsFilter,AFilter");
$parser = $views->create(new Product(), Rhaco::url("index.php"), "BFilter");
$parser->write();

  • Flow

  • Rhaco::import("generic.Flow");
    $flow = new Flow("AFilter,BFilter");
    //適当に処理を書く
    $flow->write("ATemplate.html");
    


フィルタは次のように書きます。
library/AFilter.php
class AFilter {
  /**
  * リクエスト用フィルタ
  * @param $request リクエストオブジェクト
  */
  function reset(&$request){
    $request->setVariable("status",1);
  }
  /**
  * テンプレート用フィルタ
  * @param $src テンプレートのソース
  * @param $parser TagParserオブジェクト
  * @return $src テンプレートのソース
  */
  function init($src,&$parser){
    //これ間違いでした><(2008/12/17)$parser->setVariable("status",1);
    //return $src;
    return str_replace('{$status}',1,$src);
  }
}

Request, TemplateParser, TagParserを直接使うケースはほとんど無いと思いますので、省略します。

Urlsで各呼び出しメソッドで異なるリクエストフィルタを適用したい場合は自前でクラスを作成してフィルタをセットする必要があります。FlowやViewsを拡張すると便利です。以下はフィルタをセットするだけの作業です。

  • Viewsを拡張した場合

  • class Hoge extends Views {
      function __init__($args){
        $this->setFilter("AFilter");
        parent::__init__($args);
      }
    }
    

  • Flowを拡張した場合

  • class Hoge extends Flow {
      function __init__($args){
        $this->setFilter("AFilter");
        parent::__init__($args);
      }
    }
    

| comment(0)