前回は、ブログアプリケーションの画面遷移設計を行いました。今回は、設計した画面遷移をフロー定義ファイルに落とし込み、実際にPiece_Unityで動作するアプリケーションを作成します。
Piece_Unity 1.0.0から1.1.0へのアップグレード
先日Piece_Unity 1.1.0がリリースされました。作業を始める前にアップグレードを行いましょう。
アップグレード完了後、キャッシュディレクトリ(/path/to/pieceblog/web/webapp/cache)以下にあるすべてのキャッシュファイル(cache_XXX)を削除してください。
フロー定義ファイルの作成-エントリー一覧フロー
エントリポイントに着目し画面遷移設計を行った結果、アプリケーション全体のフローは新規エントリー入力フロー、エントリー一覧フロー、エントリー編集フローの3つのフローで構成されることになりました。まずはこれら3つのフローのうち、画面がひとつしか存在しない最もシンプルなフローであるエントリー一覧フローをフロー定義ファイルに落とし込んでみましょう。
上記のステートチャート図は、下記のように表現することができます。
フロー定義ファイルは任意の場所に配置することができますが、今回はサンプルアプリケーションで使われているディレクトリ/path/to/pieceblog/web/webapp/config/flows以下にEntryディレクトリを作成し、そこにList.yamlとして配置することにします。
フロー定義ファイルのフォーマットにはYAML[1]が採用されています。YAMLでは配列とハッシュ、スカラー(文字列、数値、真偽値など)を組み合わせることでデータが表現されます。firstState: DisplayListはハッシュのキーと値を表します。firstStateがキーでDisplayListが値です。
firstState要素は、フローが実行された際にイニシャルステートから遷移する先のステート、ファーストステートを表します。基本的に、ファーストステートにはフローの最初の画面を表すステートが指定されることになります。エントリー一覧フローの場合、最初の画面であるエントリー一覧画面を表すDisplayListステートがファーストステートとなっています。
viewState要素は、HTMLテンプレートやリダイレクション先のURLなどのビューを表すステートをひとつ以上持つ配列です。YAMLの配列要素は-(ハイフン)で表されます。エントリー一覧フローの場合、最初の画面であるエントリー一覧画面を表すDisplayListステートが、唯一の配列の要素となっています。viewState配列の要素はハッシュとなっており、name要素にはステートの名称、view要素にはHTMLテンプレートのファイル名やリダイレクション先のURLを記述します。Piece_Unityではビューは抽象化されており、ビューがHTMLテンプレートの場合、そのテンプレートのファイル名から拡張子を取り除いたものを指定します。また、ファイル名のパスを含める必要はありません。
なお、本連載中のステートやイベント、イベントハンドラの名称はPiece_IDEで使われている命名規約に従っています。この命名規約では、ビューステートの名称には必ずDisplayという接頭辞が含まれます。
エントリポイントの作成-エントリー一覧フロー
では、エントリー一覧画面が表示されるかどうか試してみましょう。Apacheを起動しブラウザからhttp://pieceblog/list.phpにアクセスしてみてください。
おっと、404 Not Foundの画面が表示されてしまいました。とはいっても、まだlist.phpを作成していないのでこの結果は当然です。
では、下記のようなスクリプトをlist.phpとして作成してみましょう。
上記のコードを解説します。
ブロック1では、require_onceによって必要なファイルのインクルードを行っています。
ブロック2では、簡易的なエラーハンドラとしてvar_dump()を使ったものを設定しています。独自のエラーハンドラを設定することで、Piece Framework内のエラーを例外に変換することもできます。
ブロック3では、Webアプリケーションのベースディレクトリを変数化しています。アプリケーションの配置先によって動作しなくなることがないように工夫を施しています。
ブロック4では、session.cookie_path設定を上書きし、セッションデータの保存ディレクトリを変更しています。ブロック3と同様に、アプリケーションの配置先によって動作しなくなることがないように工夫を施しています。
ブロック5では、Piece_Unity設定ファイルの配置先ディレクトリ及びそのキャッシュの配置先ディレクトリを引数にPiece_Unityクラスをインスタンス化しています。
ブロック6では、Piece_Unity::setConfiguration()をコールすることによってエントリポイント固有の設定を行っています。プラグインが持つ各設定のデフォルト値やPiece_Unity設定ファイルの設定はこのように上書きすることができます。このような動的な設定はダイナミックコンフィグレーションと呼ばれています。
ブロック7では、Piece_Unity::dispatch()をコールすることによってPiece_Unityの実行環境を稼働させています。
では、もう一度エントリー一覧画面が表示されるかどうか試してみましょう。ブラウザからhttp://pieceblog/list.phpにアクセスしてみてください。
アクセスは成功しましたが、エラーメッセージらしきものが表示されています。エラーメッセージの内容は、フロー定義にEntryListというフロー名が見つからない、というものです。フロー定義はPiece_Unity設定ファイルに記述されていますので、早速Piece_Unity設定ファイルを編集してみましょう。
Piece_Unity設定ファイルへのフロー定義の追加-エントリー一覧フロー
Piece_Unityの設定ファイルは、piece-unity-config.yamlというYAMLファイルです。Piece_Unityの機能はプラグイン[2]を通して設定を行うことができるようになっており、Piece_Unityの設定はプラグインの設定ということになります。フロー定義の設定はDispatcher_Continuationプラグインの設定ポイント[3]flowDefinitionsによって行うことができます。下記はフロー定義の追加を行った設定ファイルです。強調された行が追加分となっています。
では、もう一度エントリー一覧画面が表示されるかどうか試してみましょう。ブラウザからhttp://pieceblog/list.phpにアクセスしてみてください。
フロー定義の設定を行ったにもかかわらず、先程と同じエラーメッセージが表示されてしまいました。これは、Piece_Unity設定ファイルに記述されたフロー定義の情報がセッションに保存されていることに起因しています。この状態から先に進むためには、ブラウザからセッション用のクッキーを削除するか、サーバのセッションデータを削除するしかありません。ブラウザのセッション用のクッキーを削除する最も原始的な方法はブラウザの再起動です[4]。
では、ブラウザを再起動しhttp://pieceblog/list.phpにアクセスしてみてください。
ようやくまともなページが表示されました。しかし、ビューとして設定したList.htmlが存在しないため、表示されているのはレイアウト部分のみとなっています。下記のようにList.htmlを作成し、もう一度ブラウザからhttp://pieceblog/list.phpにアクセスしてみてください。
きちんと指定されたビューであるListのHTMLテンプレートが表示されたことがわかります。これでエントリー一覧フローはひとまず完成です。
新規エントリー入力フロー
続いて、新規エントリー入力フローに取りかかりましょう。
このフローは、エントリー一覧フローと異なり複数のビューステートが存在するため、それら複数のビューステートを接続する要素であるtransition要素が使われています。
transition要素は、ステート間の遷移を表現する要素です。この要素の値は、イベント名及びイベント発生時の遷移先のステート名の組をひとつ以上持つ配列です。この配列の要素はハッシュとなっており、event要素にはイベント名、nextState要素には遷移先のステート名を記述します。
lastState要素は、ラストステートとなるビューステートです。この要素の値はハッシュとなっており、name要素にはステートの名称、view要素にはHTMLテンプレートやリダイレクション先のURLを記述します。
このフローは新規エントリー入力完了時にエントリー一覧画面に遷移する仕様のため、lastState要素にはエントリー一覧フローのエントリポイントのURLをビューとして指定しています。なお、URLのドメイン部分は実行環境に応じて自動的に置換されるため、必ずしも実際のドメイン名を入力する必要はありません。
HTMLテンプレートには遷移に対応したリンクを記述しています。フロー定義に基づいた動作を行うエントリポイント[5]に対しては、実行中のフローを特定するための情報であるフロー実行チケットとイベントを与える必要があります。{}は今回使用するテンプレートエンジン、HTML_Template_Flexyのテンプレート変数を表します。__で始まる文字列は、Piece_Unityが提供するテンプレート変数を表します。では、エントリー一覧フローの場合と同様に、新規エントリポイントの作成とフロー定義の追加を行ってください。
上記の準備が完了したら、ブラウザを再起動し、エントリポイントにアクセスしてみましょう。
今度は最初から問題なく動作します。新規エントリー入力確認画面からCreateリンクをクリックすると先程作成したエントリー一覧画面が表示されます。これは、ステートチャート図の作成時に追加された新規エントリー入力完了画面、すなわちDisplayNewFinishステートのビューがエントリー一覧フローへのリダイレクションを指示しているからです。
エントリー編集フロー
続いて、最後となるエントリー編集フローに取りかかりましょう。
上記の準備が完了したら、ブラウザを再起動し、エントリポイントにアクセスしてみましょう。
今度も最初から問題なく動作します。画面遷移図ではひとつだったエントリー削除確認画面をふたつの異なるステートにしたのは、参照画面を経由したか編集画面を経由したかによって戻り先のステートが異なること、経由したステート以外のステートに戻れることがあってはならないこと、この2点を満たすためです。実際にリンクをコピーし、それぞれの削除確認画面を表示させたあと、そのリンクをブラウザから入力してしてみてください。Piece_UnityのWebフローコントロール機能により、不正なイベントが無効化され単に現在のステートのビューが表示されることがわかるでしょう。
フローの実行の復元にフローの実行毎に発行されるチケットが必要なこと、不正なイベントは無効化され定義された遷移しか行えないこと、これらはPiece_Unityを使用したアプリケーションが、不正リクエストやCSRFといった問題から自動的に保護されることを意味します。
おわりに
これで画面遷移設計とフロー定義は完了です。これまでの作業で、画面遷移のみではありますが、ブログアプリケーションを実行環境で稼働させることができました。
次回は、各画面の詳細な設計を行います。