ぐらめぬ・ぜぷつぇんのはてダ(2007 to 2011)

2007年~2011年ごろまで はてなダイアリー に書いてた記事を引っ越してきました。

あるcontrollerのHelperを他のcontrollerのリクエスト処理中でも使えるよう共有したい場合


後述しますが、Controllerクラスの $helpers や $app_helpers を弄っていないデフォルトのControllerの場合、Akelos自体が提供している全ヘルパー+app/helpers/(コントローラ名)_helper.php のみそのcontrollerが処理するリクエストで使用可能です。
逆に言うと、controller-Aが処理しているリクエスト中では、controller-BのHelperを呼び出すことは(そのままでは)できません。
よくあるパターン(というか自分が嵌ったパターン)としては、共通的なpartialやHelper, デフォルトページ用のcontrollerとかを "common" コントローラとしてまとめて、そのヘルパを他のcontrollerのview中から呼ぶ・・・などがあります。

$common_helper->hogehgoe();
→
Fatal error: Call to a member function on a non-object in ... app/views/other_controller/compiled/hoge.tpl.php

みたいな。

対処法としては、こうしたcommonなcontrollerのhelperを他のcontrollerで遍く使いたい場合は、ApplicationControllerで $app_helpers に共用したいcontroller名を指定します。
app/application_controller.php

<?php
class ApplicationController extends AkActionController
{
    var $app_helpers = "common"; // 面倒くさがり屋は "all" を指定。
...

面倒くさいときは"all"を指定することで、もう全部のcontrollerのhelperを、全部のcontroller中で見境無く使えるようになります。

AkActionControllerでHelperに関連するメンバ変数とロード対象ディレクト

以下のメンバ変数がHelperのロードに影響してきます。

変数名 ロード対象ディレクト デフォルト値 デフォルトでロードされるHelper群
$helpers AK_LIB_DIR*1/AkActionView/helpers/ 以下 'default' ロード対象ディレクトリ以下の全Helper
$app_helpers AK_HELPERS_DIR*2 指定無し(null) 無し
$plugin_helpers AK_PLUGINS_DIR以下? 'all' ??

すみません、$plugin_helpersについてはよく分からなかったんでスルーさせてください。

各メンバ変数は、ApplicationController(app/application_controller.php)または各controllerで次のようにカンマ区切り*3でカスタマイズ可能です。

var $helpers = "asset_tag, capture, date, file_upload, url";
var $app_helpers = "foo, bar";
など

ソースコードの追跡

バージョンが上がるとまた変わってしまうとは思いますが・・・とりあえず、AkActionControllerになります。

<?php
class AkActionController extends AkObject
{
    // ...
    // デフォルト値の設定
    var $helpers = 'default';
    var $app_helpers;
    var $plugin_helpers = 'all';

    function process(&$Request, &$Response)
    {
        // ...
            if(!empty($this->helpers)){
                // Helpers群をロード&インスタンス化
                $this->instantiateHelpers();
            }
        // ...
    }

    function instantiateHelpers()
    {
        // var $helpers でロードするヘルパファイルを取得
        $helpers = $this->getDefaultHelpers();
        // var $app_helpers でロードするヘルパファイルを取得・マージ
        $helpers = array_merge($helpers, $this->getApplicationHelpers());
        // var $plugin_helpers でロードするヘルパファイルを取得・マージ
        $helpers = array_merge($helpers, $this->getPluginHelpers());

        // ...

        // 現在のcontrollerのhelperファイルを取得
        $current_controller_helper = $this->getControllerName();
        $current_controller_helper_file_name = AK_HELPERS_DIR.DS.$this->_module_path.AkInflector::underscore($current_controller_helper).'_helper.php';
        if(file_exists($current_controller_helper_file_name)){
            $helpers[$current_controller_helper_file_name] = $current_controller_helper;
        }

        // 以下、ファイルのロードとインスタンス化
    }

    // ↑のinstantiateHelpers()から呼ばれている、ヘルパファイル取得メソッド。
    // 実装の詳細は http://www.akelos.org/xref/nav.html?index.html で。
    function getDefaultHelpers() { ... }
    function getApplicationHelpers() { ... }
    function getPluginHelpers() { ... }

こんな流れになってます。

*1:app/config/boot.php 中で"Akelos自体のディレクトリ/lib" になるよう調整されています

*2:akelos/lib/constants.php 中で"AK_APP_DIR/helpers"になるよう調整されています

*3:Ak::stringToArray()をかましているので、カンマ, 縦棒, ハイフン, セミコロンでも区切れます。