Affamative Way

前向きにグダグダいいながらコード書く

ビュークラスで他のビューを呼び出したり、リダイレクトしてみた。

Ethnaのいやーんな部分にビューの中で他のビューへ移動できないのでちょろっといじくってみた。メモ書き


たとえば、あるパラメータを基に画面へ表示する情報がある画面にフォームがあった場合。

エラー処理もあるからビュークラスに情報の取得処理を書きたいわけだけど、取得処理で失敗した場合にどうしようもないわけで。。。

だからってアクションクラスに書くと、エラーが起きた場合にビューしか実行されないからエラーが起きた場合の取得処理が必要になってしまう。

同じこと2回も書きたくないので、こんな風にした。

<?php
  # Viewクラスに記載

    // エラーページのビューを実行して表示
    $this->forwardView( 'err');
    // エラーページへリダイレクト
    $this->redirectPage( 'err');

下準備

リダイレクト画面の準備

ブラウザがHTTPヘッダーによるリダイレクトを拒否している場合があるのでリダイレクト用のページを準備する。

ethna add-view redirect
ethna add-template redirect
[PROJECT_ID]/app/view/redirect.php の実装
<?php
    function preforward()
    {
        $redirect_url = $this->config->get('url') 
            ."?" .$this->af->getApp('redirect_page_id') ."=true";
        $this->af->setApp( 'redirect_url', $redirect_url );
        if (!headers_sent()) {
            @ob_end_clean();
            header('Location: ' .$redirect_url);
        }
    }

やってることはアクションフォームに設定されたredirect_page_idを取得して、HTTPヘッダー吐いてます。

[PROJECT_ID]/ja/redirect.tpl の記述
<html>
<head>
  <meta http-equiv="Refresh" content="60;url={$app.redirect_url}" />
</head>
<body onload="try {ldelim}self.location.href='{$app.redirect_url}'{rdelim} catch(e) {ldelim}{rdelim}">
ページを移動しようとしています。自動的に移動しない場合は
<a href="{$app.redirect_url}">ココ</a>をクリックしてください。
</body>
</html>

HTTPヘッダでダメだった場合に備えて、javascriptとmetaタグでトライしてかつリダイレクト先のリンクを提供してます。

下準備完了

実は、この辺のリダイレクトの実装はS2Ethnaを参考というかそのまんまです ^^;

基底ビュークラスの拡張

拡張と言ってもも関数二つ追加するだけ〜

@ [PROJECT_ID]_ViewClass

<?php
・・・・
    /**
     * ビュー側からビューへの遷移を提供する
     *
     * @param String $viewId
     */
    function forwardView( $viewId)
    {
        $c = $this->backend->controller;
        $view_class_name = $c->getViewClassName( $viewId);
        $c->view =& new $view_class_name(
            $this->backend, $viewId, $c->_getForwardPath( $viewId));
        $c->preforward();
        $c->forward();
        exit();
    }
    
    /**
     * 指定IDのページをリダイレクトする
     *
     * @param String $pageId
     */
    function redirectPage( $pageId)
    {
        $c = $this->backend->controller;
        $view_class_name = $c->getViewClassName( 'redirect');
        $c->view =& new $view_class_name(
            $this->backend, 'redirect', $c->_getForwardPath( 'redirect'));
        $c->view->af->setApp('redirect_page_id', $pageId);
        $c->view->preforward();
        $c->view->forward();
        exit();
    }


以上。簡単っ♪

リダイレクトの画面作るのなんてめんどーだよ。という場合には
下準備なしにして以下のように実装してやればおけ

<?php
    /**
     * 指定IDのページをリダイレクトする
     *
     * @param String $pageId
     */
    function redirectPage( $pageId)
    {
        header('Location: '.$this->config->get('url') ."?{$page_id}=true");
    }

たんじゅーん。