ページ:アクションのマッピングという、従来のフレームワークの概念の延長線上でステートフルをサポートする、というXhwlayの当初目的。
・・・いろいろ考えてみたんだけど、どうも、意味が半減するような気がしてきた。
というのは、現時点でのXhwlayは実際にModelを動かすのはやはりページにマッピングされたアクション。&br;
で、その後 手動で Bookmarkのページを次に動かす必要がある。
これは・・・勿体ない、というか、 危ない。 Bookmark・・・正確にはアクションに引数で渡されてきた&$bookmarkに対して、
$bookmark->setPageName("次のページ名");
をプログラマが意識して呼ばないと、・・・逆にこれを呼び忘れると、CSRFが効いてしまう。
では逆に、これを呼んでいることを保証できるUnitTestツールなどを用意できるか、と言われれば、そこまでするリソースは持ち合わせていない。
つまり、せっかくのステートフルな仕組みが中途半端になってしまう。羊頭狗肉じゃないか。
こりゃまずい・・・というわけでいろいろあれこれ考えてみた結果、やっぱり、
Page -> (Event) -> Transit -> Page -> (Event) -> Transit -> Page -> ...
という、Piece-Flowも採用している、一般的なステートマシンの動き方を採用することになりました。
うわっConfig関連も全部UTしなおし。
で、じゃあ現状採用しているBarrierはどうするか・・・Guardとするか・・・なんだけど。
う~~ん・・・まあ・・・しても・・・いいか・・・?POST値とかGET値の入力チェック処理だけを綺麗にモジュール化したい、っていうのであれば、分けた方が良いんだよね。う~~ん・・・まぁ・・・HTML_QuickForm使う場合であれば、Formのビルダを別クラスにしておいて、validateだけするっていうのもありだし・・・。
うん、ちょっと面倒くさくなりそうだけど、将来的なわかりやすさから言えば、実装するに値する。
というか、Guardが無い場合、Event側で前頁に戻す処理を可能にしなければならない。・・・面倒なんだよな・・・。
あ、あと、transitすれども次のPageはInvokeせず。というパターンも考慮しておかないと。HTTP304でLocationさせるルート。
これは・・・Runnerに、escape()を用意すれば良いかな・・・。いや、EventHandlerがnullを返せば良い。
Configは最終的にはこんな感じになるだろう。
"page.aci" => array( "event" => array( "event1", "event2", "event3", ), ), "event" => array( "event1" => array( "guard" => array( "component" => "EventGuard_guard1.class.php", ), "component" => "EventAction_event1.class.php", "transit" => array( "error" => "page_error1", "success" => "page2", "invalid" => "page1", ), ), ), );
Transitが返すのはあくまでも文字列。で、Config側で文字列とページ名をマッピングする。aciは保持。
なんだかPieceっぽくなってきちゃったけど・・・まあ、いっか。一応この辺りまで分離することで、雛形の自動生成への道も開ける。
うん、これですっきりする。で、もしもLocationせずに、普通に遷移先のpageをinvokeして続行するとした場合、URLに"&_event=..."ってのこっちゃうので、二重POSTまたはDouble-Requestが走るけど、内部的にはすでにpage2に遷移しているので、page2のほうでの"event"にそのevent名が定義されていなければ当然何も起こらない、というだけの話。
これで、DataのCUD(Create/Update/Delete)に対するActionと、単なるR(Refer)とをきれいに分割し、また、FWレベルでもきれいに分離できるようになった・・・。また大分改造が入るけど、まあしょうがないな。
ただこれやると、単純なpage遷移が使えなくなる。あと、局所的なBookmark-OFFも使えなくなる。
まあ・・・その辺は、併用でも良いかもしれない。BookmarkがOFFになると、event志向ではページを動かせなくなるから。
今どのページで、というのは、BookmarkがOFFの時に限り、ユーザーランドで調整できても良いかもしれない。
あるいは"event"属性が未定義の場合。"next"で遷移させる、という手もある。
つまり"event"と"next"が指定可能で、"next"にはBookmark-OFFのページのみへ遷移可能、とか。いや、Bookmark-ONでも平気か。
$_eventが指定された場合は"event"に従い遷移し、"_page"が指定されたときは"next"に従い遷移する。
両方していされた場合は・・・どうしようかね。無効なパラメータ指定だから、No-Event, No-Actionで支障ないでしょう。
上手く組み合わせれば、局所的なBookmark-OFFも実現できるかもしれない・・・。
うん。大体まとまったな。単純なpage遷移のフォローも、"next"属性存続で路が残された。こんな感じで、良いんじゃない?
Guardも、Page遷移で利用できるようにしたいから・・・Configをまとめ直すと、こんな感じかな?
"page.aci" => array( "bookmark" => "off", "next" => array( "pageA" => "guard1", "pageB" => null, ), "event" => array( "event1" => "guard2", "event2" => "guard3", "event3" => "guard4", ), ), "guard" => array( "guard1" => array( "component" => "PageGuard_guard1.class.php" ), "guard2" => array( "component" => "EventGuard_guard2.class.php" ), ... ), "event" => array( "event1" => array( "component" => "EventAction_event1.class.php", "transit" => array( "error" => "page_error1", "success" => "page2", "invalid" => "page1", ), ), ), );
こんな感じか。