sfPageFlowプラグインを本家wikiに投稿しました。sfPageFlowプラグインはYAMLで定義した有限オートマトンによってページ遷移を制御するプラグインです。これにより複雑なフォーム遷移の実装が簡単になります。
実装にあたってはPiece Frameworkを参考にさせていただきました。
本日はざっと概要だけ説明させていただきます。
インストール
sfPageFlowプラグインから、sfPageFlowPlugin-0.0.1.tgzをダウンロードし、プロジェクトのpluginsディレクトリに展開してください。
tar xvzf sfPageFlowPlugin-0.0.1.tgzそのあと、キャッシュをクリアします。
symfony cc使い方
sfPageFlowプラグインは、sfPageFlowおよび、sfActionsの継承クラスである、sfPageFlowActionsの2つのクラスを実装しています。
例として、以下のような状態遷移を持つフォームを実装してみます。良くある、入力→確認→完了のフローになります。

まず、このフローを実装するためのモジュールをsampleという名前で作成します。
symfony module myapps sample
状態遷移を定義するためのYAMLを、pageflow.ymlという名前で、sampleモジュールのconfigディレクトリ以下に作成します。
#
firstState: ProcessInitialize
lastState: DisplayResult
state:
DisplayForm:
transition:
doInput: ProcessValidate
DisplayConfirm:
transition:
doConfirm: ProcessSubmit
doCancel: ProcessSetup
DisplayResult:
ProcessInitialize:
transition:
onSuccess: ProcessSetup
ProcessSetup:
transition:
onSuccess: DisplayForm
ProcessValidate:
entry:
- acceptRequests:
params: [name, title, body]
transition:
onSuccess: DisplayConfirm
onError: DisplayForm
ProcessSubmit:
transition:
onSuccess: DisplayResult次に、sampleモジュールのアクションの継承元をsfActionsからsfPageFlowActionsに変更します。
<?php class sampleActions extends sfPageFlowActions {
routing.ymlを修正して、以下のようにします。
sample:
url: /sample/*
param: { module: sample, action: flow }アクションステートのロジックをアクションとして実装します。Proccess??????ステートに対応するアクションのメソッドはexecute??????()になります。pageflow.ymlに定義したアクションステートを下記のようにアクションで実装します。
<?php
class sampleActions extends sfPageFlowActions
{
// Action States
// handle ProcessInitialize
public function executeInitialize(){
$this->flow->clearData();
$this->flow->transitOnSuccess();
return $this->flow->execute();
}
// handle ProcessSetup
public function executeSetup(){
$this->flow->transitOnSuccess();
return $this->flow->execute();
}
public function executeValidate(){
$this->flow->transitOnSuccess();
return $this->flow->execute();
}
public function executeSubmit(){
// process data
$this->flow->transitOnSuccess();
return $this->flow->execute();
}
}次に、ビューステートで使われるテンプレートを実装します。DisplayForm、DisplayConfirm、DisplayResultのそれぞれのステートに対応するテンプレートはdisplayForm.php、displayConfirm.php、displayResult.phpになります。これらをそれぞれtemplatesディレクトリにおきます。
テンプレートの中では、$flowという変数を利用して、フローのデータを取得することができます。
<?php echo input_tag('name',$flow->getData('name')) ?>
イベントにより遷移するときには下記のようにします。
<?php echo input_hidden_tag('pageflow_event','doInput') ?>
or
<?php echo link_to('back',"@sample?pageflow_event=doCancel")?>複雑な状態遷移を持つフォームの実装はいつも頭痛の種でしたが、sfPageFlowが少しでも役に立てば幸いです。
内部実装はbetaも良い所ですので不具合等ありましたらご連絡おねがいします。


現状だと一つのフローを実現するのにモジュールが一つ必要になってしまうかと 思うのですが、pageflow.ymlでstateの1つ上の階層にstoryなどを入れてあげて、複数のフローをもてるようになると嬉しいです。
story: name: firstStory firstState: FirstProcessInitialize lastState: FirstDisplayResult state: FirstDisplayForm: .... snip ....codeブロックが崩れてしまいましたorz。
面白いアイデアですが、良く考えるとstory は stateの一つとみなせないでしょうか?
現実的な例ではないかもしれませんが、アンケートシステムなどではアンケートを作るフローとアンケートに答えるフローが存在します。この二つのフローに対してモジュールを二つ作るのは時によっては大掛かりになるかなと思ったのですがいかがでしょうか? モジュールはある程度機能単位でまとめられている方がすっきりするかなと思った次第です。
i have searched in symfony website, but i can't find the plugin. does anyone where can i find it?
thanks a lot
to noone sfPageFlow is now at SVN repository: http://svn.tracfort.jp/svn/dino-symfony/plugins/sfPageFlowPlugin/'