Ethnaでロケーションさせる方法

いろいろな方法があると思いますが、うちで使用している方法です。


まず、本家での説明は以下のようになっています。
http://ethna.jp/ethna-document-faq-dev_guide_faq.html#content_1_6

locationさせるメソッドはないの?

今のところ、locationをさせるメソッドはありません。 Ethna_ActionClass::performあたりで

header('location: http://exsample.com/');
exit;

とでもしましょう。そのうち、どこかにメソッドとして実装されかなぁ・・?

この方法でも確かに実現できますが、unittestを作った場合、そこで挙動が止まってしまいます。


ActionやUtilにロケーション用のメソッドを作成し、それを呼ぶという方法もあると思います。
うちでも以前は、この方法を使用していましたが、テスト時と実行時で挙動を分ける記述をメソッド内に書く必要が出てきてしまいます。


なので、_sortForwardを拡張し、actionの戻り値でロケーションさせるようにしています。

使用方法

actionの、prepareやperformで以下のように戻り値を返します。

/**
 *  アクションの前処理
 *
 *  @access public
 *  @return string      遷移名(正常終了ならnull, 処理終了ならfalse)
 */
function prepare()
{
    return 'Location: http://example.com/....';
}
/**
 *  アクションの実装
 *
 *  @access public
 *  @return string  遷移名
 */
function perform()
{
    return 'Location: http://example.com/....';
}

修正箇所

実際にハックする箇所は、app/[appid]_Controller.php 内にメソッドを追加します。

/**
 *  アクション名とアクションクラスからの戻り値に基づいて遷移先を決定する
 *
 *  @access protected
 *  @param  string  $action_name    アクション名
 *  @param  string  $retval         アクションクラスからの戻り値
 *  @return string  遷移先
 */
function _sortForward($action_name, $retval)
{
    $forward_name = $retval;
    if (preg_match('/^Location: (.*)$/i', $forward_name)) {
        $this->logger->log(LOG_INFO, 'forward_location[%s]', $forward_name);
        header($forward_name);
        exit;
    }

    $forward_path = $this->_getForwardPath($forward_name);
    $this->logger->log(LOG_INFO, 'forward_name[%s]', $forward_name);
    return $forward_name;
}


いま、これ以外に、戻り値にフルパスで書かずに、action名や http<->https を、ドメインを意識しないで出来る方法を模索中です。
いい方法あったら教えてください。

追記(2009-01-23)

はてぶを付けてくださった人が居て久々に自分のエントリを見返しました。
最近はこれとは違った方法を使っています。


TODO:あとで、別エントリに書く。