Source for file Ethna_Controller.php
Documentation is available at Ethna_Controller.php
// vim: foldmethod=marker  
 *  @author     Masaki Fujimoto <fujimoto@php.net>  
 *  @license    http://www.opensource.org/licenses/bsd-license.php The BSD License  
 *  @version    $Id: Ethna_Controller.php 516 2008-04-30 16:30:05Z mumumu-org $  
 *  @todo       gatewayでswitchしてるところがダサダサ  
 *  @author     Masaki Fujimoto <fujimoto@php.net>  
    /** @var    string      アプリケーションID */  
    /** @var    string      アプリケーションベースディレクトリ */  
    /** @var    string      アプリケーションベースURL */  
    /** @var    string      アプリケーションDSN(Data Source Name) */  
    /** @var    array       アプリケーションディレクトリ */  
    var $directory = 
array();  
    /** @var    array       アプリケーションディレクトリ(デフォルト) */  
    var $directory_default = 
array(  
        'action'        => 
'app/action',  
        'action_cli'    => 
'app/action_cli',  
        'action_xmlrpc' => 
'app/action_xmlrpc',  
        'plugin'        => 
'app/plugin',  
        'filter'        => 
'app/filter',  
        'template'      => 
'template',  
    /** @var    array       DBアクセス定義 */  
    /** @var    array       クラス設定(デフォルト) */  
    var $class_default = 
array(  
        'class'         => 
'Ethna_ClassFactory',  
        'backend'       => 
'Ethna_Backend',  
        'config'        => 
'Ethna_Config',  
        'error'         => 
'Ethna_ActionError',  
        'form'          => 
'Ethna_ActionForm',  
        'logger'        => 
'Ethna_Logger',  
        'plugin'        => 
'Ethna_Plugin',  
        'renderer'      => 
'Ethna_Renderer_Smarty',  
        'session'       => 
'Ethna_Session',  
        'view'          => 
'Ethna_ViewClass',  
        'url_handler'   => 
'Ethna_UrlHandler',  
    /** @var    array       検索対象となるプラグインのアプリケーションIDのリスト */  
    var $plugin_search_appids;  
    /** @var    string      使用言語設定 */  
    /** @var    string      システム側エンコーディング */  
    /** @var    string      クライアント側エンコーディング */  
    /** @var    string  現在実行中のアクション名 */  
    /** @var    string  現在実行中のXMLRPCメソッド名 */  
    /** @var    array   forward定義 */  
    /** @var    array   action定義 */  
    /** @var    array   action(CLI)定義 */  
    var $action_cli = 
array();  
    /** @var    array   action(XMLRPC)定義 */  
    var $action_xmlrpc = 
array();  
    /** @var    array   アプリケーションマネージャ定義 */  
    /** @var    array   smarty modifier定義 */  
    var $smarty_modifier_plugin = 
array();  
    /** @var    array   smarty function定義 */  
    var $smarty_function_plugin = 
array();  
    /** @var    array   smarty block定義 */  
    var $smarty_block_plugin = 
array();  
    /** @var    array   smarty prefilter定義 */  
    var $smarty_prefilter_plugin = 
array();  
    /** @var    array   smarty postfilter定義 */  
    var $smarty_postfilter_plugin = 
array();  
    /** @var    array   smarty outputfilter定義 */  
    var $smarty_outputfilter_plugin = 
array();  
    /** @var    array   フィルターチェイン(Ethna_Filterオブジェクトの配列) */  
    var $filter_chain = 
array();  
    /** @var    object  Ethna_ClassFactory  クラスファクトリオブジェクト */  
    var $class_factory = 
null;  
    /** @var    object  Ethna_ActionForm    フォームオブジェクト */  
    /** @var    object  Ethna_View          ビューオブジェクト */  
    /** @var    object  Ethna_Config        設定オブジェクト */  
    /** @var    object  Ethna_Logger        ログオブジェクト */  
    /** @var    object  Ethna_Plugin        プラグインオブジェクト */  
    /** @var    string  リクエストのゲートウェイ(www/cli/rest/xmlrpc/soap...) */  
    var $gateway = 
GATEWAY_WWW;  
     *  Ethna_Controllerクラスのコンストラクタ  
        $GLOBALS['_Ethna_controller'] =
& $this;  
        if ($this->base === 
"") {  
            // EthnaコマンドなどでBASEが定義されていない場合がある  
        $this->gateway = 
$gateway;  
        foreach ($this->class_default as $key => 
$val) {  
            if (isset
($this->class[$key]) == 
false) {  
                $this->class[$key] = 
$val;  
        foreach ($this->directory_default as $key => 
$val) {  
            if (isset
($this->directory[$key]) == 
false) {  
                $this->directory[$key] = 
$val;  
        $class_factory = 
$this->class['class'];  
        $this->class_factory =
& new $class_factory($this, $this->class);  
        // ディレクトリ名の設定(相対パス->絶対パス)  
        foreach ($this->directory as $key => 
$value) {  
                // Smartyプラグインディレクトリは配列で指定する  
                        $tmp[] = 
$this->base . 
(empty($this->base) ? 
'' : 
'/') . 
$elt;  
                $this->directory[$key] = 
$tmp;  
                    $this->directory[$key] = 
$this->base . 
(empty($this->base) ? 
'' : 
'/') . 
$value;  
        list
($this->language, $this->system_encoding, $this->client_encoding) = 
$this->_getDefaultLanguage(); 
        $this->url = 
$this->config->get('url');  
        //// assert (experimental)  
        //if ($this->config->get('debug') === false) {  
        //    ini_set('assert.active', 0);  
     *  (現在アクティブな)コントローラのインスタンスを返す  
     *  @return object  Ethna_Controller    コントローラのインスタンス  
        if (isset
($GLOBALS['_Ethna_controller'])) {  
            return $GLOBALS['_Ethna_controller'];  
     *  @return string  アプリケーションID  
     *  @param  string  $id     アプリケーションID  
     *  @return mixed   true:OK Ethna_Error:NG  
                "Only Numeric(0-9) and Alphabetical(A-Z) is allowed for Application Id\n"  
     *  @param  string  $action_name    アクション名  
     *  @return mixed   true:OK Ethna_Error:NG  
        if (preg_match('/^[a-zA-Z\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/',  
     *  @param  string  $view_name    ビュー名  
     *  @return mixed   true:OK Ethna_Error:NG  
        if (preg_match('/^[a-zA-Z\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/',  
     *  @param  string  $db_key DBキー  
        if (isset
($this->dsn[$db_key]) == 
false) {  
        return $this->dsn[$db_key];  
     *  @param  string  $db_key DBキー  
     *  @return bool    true:persistent false:non-persistent(あるいは設定無し)  
        $key = 
sprintf("dsn%s_persistent", $db_key == 
"" ? 
"" : 
"_$db_key");  
        $dsn_persistent = 
$this->config->get($key);  
     *  @param  string  $db_key DBキー("", "r", "rw", "default", "blog_r"...)  
     *  @return string  $db_keyに対応するDB種別定義(設定が無い場合はnull)  
        if (isset
($this->db[$db_key]) == 
false) {  
        return $this->db[$db_key];  
     *  @return string  アプリケーションベースURL  
     *  @return string  アプリケーションベースディレクトリ  
     *  クライアントタイプ/言語からテンプレートディレクトリ名を決定する  
     *  @return string  テンプレートディレクトリ  
            $template .= 
'/' . 
$this->language;  
     *  @return string  アクションディレクトリ  
        return (empty($this->directory[$key]) ? 
($this->base . 
(empty($this->base) ? 
'' : 
'/')) : 
($this->directory[$key] . 
"/"));  
     *  @return string  ビューディレクトリ  
        return (empty($this->directory['view']) ? 
($this->base . 
(empty($this->base) ? 
'' : 
'/')) : 
($this->directory['view'] . 
"/"));  
     *  (action,view以外の)テストケースを置くディレクトリ名を決定する  
     *  @return string  テストケースを置くディレクトリ  
        return (empty($this->directory['test']) ? 
($this->base . 
(empty($this->base) ? 
'' : 
'/')) : 
($this->directory['test'] . 
"/"));  
     *  @param  string  $key    ディレクトリタイプ("tmp", "template"...)  
     *  @return string  $keyに対応したアプリケーションディレクトリ(設定が無い場合はnull)  
        if ($key == 
'app' && isset
($this->directory[$key]) == 
false) {  
        if (isset
($this->directory[$key]) == 
false) {  
        return $this->directory[$key];  
     *  @param  string  $key    拡張子タイプ("php", "tpl"...)  
     *  @return string  $keyに対応した拡張子(設定が無い場合はnull)  
        if (isset
($this->ext[$key]) == 
false) {  
     *  @return object  Ethna_ClassFactory  クラスファクトリオブジェクト  
        return $this->class_factory;  
     *  @return object  Ethna_ActionError   アクションエラーオブジェクト  
        return $this->class_factory->getObject('error');  
     *  @return object  Ethna_ActionForm    アクションフォームオブジェクト  
        return $this->action_form;  
     *  @return object  Ethna_View          ビューオブジェクト  
     *  @return object  Ethna_Backend   backendオブジェクト  
        return $this->class_factory->getObject('backend');  
     *  @return object  Ethna_Config    設定オブジェクト  
        return $this->class_factory->getObject('config');  
     *  @return object  Ethna_I18N  i18nオブジェクト  
        return $this->class_factory->getObject('i18n');  
     *  @return object  Ethna_Logger        ログオブジェクト  
        return $this->class_factory->getObject('logger');  
     *  @return object  Ethna_Session       セッションオブジェクト  
        return $this->class_factory->getObject('session');  
     *  @return object  Ethna_AppSQL    SQLオブジェクト  
        return $this->class_factory->getObject('sql');  
     *  @return object  Ethna_Plugin    プラグインオブジェクト  
        return $this->class_factory->getObject('plugin');  
     *  @return object  Ethna_UrlHandler    URLハンドラオブジェクト  
        return $this->class_factory->getObject('url_handler');  
     *  @return string  実行中のアクション名  
        return $this->action_name;  
     *  @return string  実行中のXMLRPCメソッド名  
        return $this->xmlrpc_method_name;  
     *  @return array   使用言語,システムエンコーディング名,クライアントエンコーディング名  
        return array($this->language, $this->system_encoding, $this->client_encoding);  
        $this->gateway = 
$gateway;  
     *  @param  string  $class_name     アプリケーションコントローラのクラス名  
     *  @param  mixed   $action_name    指定のアクション名(省略可)  
     *  @param  mixed   $fallback_action_name   アクションが決定できなかった場合に実行されるアクション名(省略可)  
    function main($class_name, $action_name = 
"", $fallback_action_name = 
"")  
        $c->trigger($action_name, $fallback_action_name);  
     *  @param  string  $class_name     アプリケーションコントローラのクラス名  
     *  @param  string  $action_name    実行するアクション名  
     *  @param  bool    $enable_filter  フィルタチェインを有効にするかどうか  
    function main_CLI($class_name, $action_name, $enable_filter = 
true)  
        $c->action_cli[$action_name] = 
array();  
        $c->trigger($action_name, "", $enable_filter);  
     *  XMLRPCアプリケーションのエントリポイント  
            die("xmlrpc extension is required to enable this gateway");  
        $c->trigger("", "", false);  
     *  @param  string  $class_name     アプリケーションコントローラのクラス名  
     *  @param  mixed   $action_name    指定のアクション名(省略可)  
     *  @param  mixed   $fallback_action_name   アクションが決定できなかった場合に実行されるアクション名(省略可)  
    function main_SOAP($class_name, $action_name = 
"", $fallback_action_name = 
"")  
        $c->trigger($action_name, $fallback_action_name);  
     *  @param  mixed   $default_action_name    指定のアクション名  
     *  @param  mixed   $fallback_action_name   アクション名が決定できなかった場合に実行されるアクション名  
     *  @param  bool    $enable_filter  フィルタチェインを有効にするかどうか  
     *  @return mixed   0:正常終了 Ethna_Error:エラー  
    function trigger($default_action_name = 
"", $fallback_action_name = 
"", $enable_filter = 
true)  
            $this->_createFilterChain();  
        for ($i = 
0; $i < 
count($this->filter_chain); $i++
) {  
            $r = 
$this->filter_chain[$i]->preFilter();  
            if (Ethna::isError($r)) {  
            $this->_trigger_WWW($default_action_name, $fallback_action_name);  
            $this->_trigger_CLI($default_action_name);  
            $this->_trigger_XMLRPC();  
        for ($i = 
count($this->filter_chain) - 
1; $i >= 
0; $i--
) {  
            $r = 
$this->filter_chain[$i]->postFilter();  
            if (Ethna::isError($r)) {  
     *  引数$default_action_nameに配列が指定された場合、その配列で指定された  
     *  アクション以外は受け付けない(指定されていないアクションが指定された  
     *  場合、配列の先頭で指定されたアクションが実行される)  
     *  @param  mixed   $default_action_name    指定のアクション名  
     *  @param  mixed   $fallback_action_name   アクション名が決定できなかった場合に実行されるアクション名  
     *  @return mixed   0:正常終了 Ethna_Error:エラー  
    function _trigger_WWW($default_action_name = 
"", $fallback_action_name = 
"")  
        $action_name = 
$this->_getActionName($default_action_name, $fallback_action_name);  
        $this->_ethnaManagerEnabledCheck($action_name);  
        $action_obj =
& $this->_getAction($action_name);  
            if ($fallback_action_name != 
"") {  
                $this->logger->log(LOG_DEBUG, 'undefined action [%s] -> try fallback action [%s]', $action_name, $fallback_action_name);  
                $action_obj =
& $this->_getAction($fallback_action_name);  
                $action_name = 
$fallback_action_name;  
        for ($i = 
0; $i < 
count($this->filter_chain); $i++
) {  
            $r = 
$this->filter_chain[$i]->preActionFilter($action_name);  
                $this->logger->log(LOG_DEBUG, 'action [%s] -> [%s] by %s', $action_name, $r, get_class($this->filter_chain[$i]));  
        $this->action_name = 
$action_name;  
        $this->_setLanguage($this->language, $this->system_encoding, $this->client_encoding);  
        $this->action_form =
& new $form_name($this);  
        $backend->setActionForm($this->action_form);  
        $forward_name = 
$backend->perform($action_name);  
        for ($i = 
count($this->filter_chain) - 
1; $i >= 
0; $i--
) {  
            $r = 
$this->filter_chain[$i]->postActionFilter($action_name, $forward_name);  
                $this->logger->log(LOG_DEBUG, 'forward [%s] -> [%s] by %s', $forward_name, $r, get_class($this->filter_chain[$i]));  
        // コントローラで遷移先を決定する(オプション)  
        $forward_name = 
$this->_sortForward($action_name, $forward_name);  
        if ($forward_name != 
null) {  
            $this->view =
& new $view_class_name($backend, $forward_name, $this->_getForwardPath($forward_name));  
            $this->view->preforward();  
     *  @param  mixed   $default_action_name    指定のアクション名  
     *  @return mixed   0:正常終了 Ethna_Error:エラー  
    function _trigger_CLI($default_action_name = 
"")  
        return $this->_trigger_WWW($default_action_name);  
     *  フレームワークの処理を実行する(XMLRPC)  
     *  @param  mixed   $action_name    指定のアクション名  
     *  @return mixed   0:正常終了 Ethna_Error:エラー  
    function _trigger_XMLRPC($action_name = 
"")  
        $xmlrpc_gateway_method_name = 
"_Ethna_XmlrpcGateway";  
        $xmlrpc_server = 
xmlrpc_server_create();  
        $this->xmlrpc_method_name = 
$method;  
        $request = 
xmlrpc_encode_request(  
            $xmlrpc_gateway_method_name,  
                'escaping'      => 
array('markup'),  
        xmlrpc_server_register_method(  
            $xmlrpc_gateway_method_name,  
            $xmlrpc_gateway_method_name  
        $r = 
xmlrpc_server_call_method(  
                'escaping'      => 
array('markup'),  
        header('Content-Type: text/xml; charset=UTF-8');  
     *  _trigger_XMLRPCのコールバックメソッド  
        $action_obj =
& $this->_getAction($method);  
        $this->action_form =
& new $form_name($this);  
        $def = 
$this->action_form->getDef();  
        foreach ($def as $key => 
$value) {  
            if (isset
($param[$n]) == 
false) {  
                $this->action_form->set($key, null);  
                $this->action_form->set($key, $param[$n]);  
        $backend->setActionForm($this->action_form);  
        $r = 
$backend->perform($method);  
        $script = 
$gg->generate();  
        $server =
& new SoapServer(null, array('uri' => 
$this->config->get('url')));  
        $server->setClass($gg->getClassName());  
     *  エラー発生時の追加処理を行いたい場合はこのメソッドをオーバーライドする  
     *  (アラートメール送信等−デフォルトではログ出力時にアラートメール  
     *  が送信されるが、エラー発生時に別にアラートメールをここで送信  
     *  @param  object  Ethna_Error     エラーオブジェクト  
        $message = 
$error->getMessage();  
        $this->logger->log($log_level, sprintf("%s [ERROR CODE(%d)]", $message, $error->getCode()));  
     *  @param  int     $code       エラーコード  
     *  @return string  エラーメッセージ  
        $message_list =
& $GLOBALS['_Ethna_error_message_list'];  
        for ($i = 
count($message_list)-
1; $i >= 
0; $i--
) {  
                return $message_list[$i][$code];  
     *  @param  mixed   $default_action_name    指定のアクション名  
     *  @return string  実行するアクション名  
    function _getActionName($default_action_name, $fallback_action_name)  
        // フォームから要求されたアクション名を取得する  
        $form_action_name = 
preg_replace('/[^a-z0-9\-_]+/i', '', $form_action_name);  
        $this->logger->log(LOG_DEBUG, 'form_action_name[%s]', $form_action_name);  
        // Ethnaマネージャへのフォームからのリクエストは拒否  
        if ($form_action_name == 
"__ethna_info__" ||
  
            $form_action_name == 
"__ethna_unittest__") {  
        // フォームからの指定が無い場合はエントリポイントに指定されたデフォルト値を利用する  
        if ($form_action_name == 
"" && 
count($default_action_name) > 
0) {  
            $tmp = 
is_array($default_action_name) ? 
$default_action_name[0] : 
$default_action_name;  
            if ($tmp{strlen($tmp)-
1} == 
'*') {  
            $this->logger->log(LOG_DEBUG, '-> default_action_name[%s]', $tmp);  
            $action_name = 
$form_action_name;  
        // エントリポイントに配列が指定されている場合は指定以外のアクション名は拒否する  
            if ($this->_isAcceptableActionName($action_name, $default_action_name) == 
false) {  
                // 指定以外のアクション名で合った場合は$fallback_action_name(or デフォルト)  
                $tmp = 
$fallback_action_name != 
"" ? 
$fallback_action_name : 
$default_action_name[0];  
                if ($tmp{strlen($tmp)-
1} == 
'*') {  
                $this->logger->log(LOG_DEBUG, '-> fallback_action_name[%s]', $tmp);  
        $this->logger->log(LOG_DEBUG, '<<< action_name[%s] >>>', $action_name);  
     *  アプリケーションの性質に応じてこのメソッドをオーバーライドして下さい。  
     *  デフォルトでは"action_"で始まるフォーム値の"action_"の部分を除いたもの  
     *  ("action_sample"なら"sample")がアクション名として扱われます  
     *  @return string  フォームにより要求されたアクション名  
        if (isset
($_SERVER['REQUEST_METHOD']) == 
false) {  
        if ($_SERVER['REQUEST_METHOD'] == 
"GET") {  
        } else if ($_SERVER['REQUEST_METHOD'] == 
"POST") {  
        if (empty($_SERVER['URL_HANDLER']) == 
false) {  
            $tmp_vars['__url_handler__'] = 
$_SERVER['URL_HANDLER'];  
            $tmp_vars['__url_info__'] = isset
($_SERVER['PATH_INFO']) ? 
$_SERVER['PATH_INFO'] : 
null;  
            $tmp_vars = 
$url_handler->requestToAction($tmp_vars);  
            if ($_SERVER['REQUEST_METHOD'] == 
"GET") {  
            } else if ($_SERVER['REQUEST_METHOD'] == 
"POST") {  
        if (strcasecmp($_SERVER['REQUEST_METHOD'], 'post') == 
0) {  
        // フォーム値からリクエストされたアクション名を取得する  
        $action_name = 
$sub_action_name = 
null;  
        foreach ($http_vars as $name => 
$value) {  
            if ($value == 
"" || 
strncmp($name, 'action_', 7) != 
0) {  
            // value="dummy"となっているものは優先度を下げる  
        if ($action_name == 
null) {  
            $action_name = 
$sub_action_name;  
     *  アクション名を指定するクエリ/HTMLを生成する  
     *  @param  string  $action action to request  
     *  @param  string  $type   hidden, url...  
        } else if ($type == 
"url") {  
     *  フォームにより要求されたアクション名に対応する定義を返す  
     *  @param  string  $action_name    アクション名  
    function &_getAction($action_name, $gateway = 
null)  
            $action =
& $this->action;  
            $action =
& $this->action_cli;  
            $action =
& $this->action_xmlrpc;  
        if (isset
($action[$action_name])) {  
            $action_obj = 
$action[$action_name];  
            if (isset
($action_obj['inspect']) && 
$action_obj['inspect']) {  
            $this->logger->log(LOG_DEBUG, "action [%s] is not defined -> try default", $action_name);  
        $this->_includeActionScript($action_obj, $action_name);  
        if (isset
($action_obj['class_name']) == 
false) {  
        if (isset
($action_obj['form_name']) == 
false) {  
        } else if (class_exists($action_obj['form_name']) == 
false) {  
            // 明示指定されたフォームクラスが定義されていない場合は警告  
            $this->logger->log(LOG_WARNING, 'stated form class is not defined [%s]', $action_obj['form_name']);  
            $this->logger->log(LOG_NOTICE, 'action class is not defined [%s]', $action_obj['class_name']);  
            $this->logger->log(LOG_DEBUG, 'form class is not defined [%s] -> falling back to default [%s]', $action_obj['form_name'], $class_name);  
            $action_obj['form_name'] = 
$class_name;  
        $action_obj['inspect'] = 
true;  
        $action[$action_name] = 
$action_obj;  
        return $action[$action_name];  
     *  アクション名とアクションクラスからの戻り値に基づいて遷移先を決定する  
     *  @param  string  $action_name    アクション名  
     *  @param  string  $retval         アクションクラスからの戻り値  
    function _createFilterChain()  
        $this->filter_chain = 
array();  
        foreach ($this->filter as $filter) {  
                    $this->filter_chain[] =
& new $filter($this);  
                $filter_plugin =
& $this->plugin->getPlugin('Filter', $filter);  
                if (Ethna::isError($filter_plugin)) {  
                $this->filter_chain[] =
& $filter_plugin;  
     *  アクション名が実行許可されているものかどうかを返す  
     *  @param  string  $action_name            リクエストされたアクション名  
     *  @param  array   $default_action_name    許可されているアクション名  
     *  @return bool    true:許可 false:不許可  
    function _isAcceptableActionName($action_name, $default_action_name)  
        foreach (to_array($default_action_name) as $name) {  
            if ($action_name == 
$name) {  
            } else if ($name{strlen($name)-
1} == 
'*') {  
     *  指定されたアクションのフォームクラス名を返す(オブジェクトの生成は行わない)  
     *  @param  string  $action_name    アクション名  
     *  @return string  アクションのフォームクラス名  
        $action_obj =
& $this->_getAction($action_name);  
        return $action_obj['form_name'];  
     *  アクションに対応するフォームクラス名が省略された場合のデフォルトクラス名を返す  
     *  デフォルトでは[プロジェクトID]_Form_[アクション名]となるので好み応じてオーバライドする  
     *  @param  string  $action_name    アクション名  
     *  @return string  アクションフォーム名  
        $r = 
sprintf("%s_%sForm_%s", $this->getAppId(), $gateway_prefix ? 
$gateway_prefix . 
"_" : 
"", $postfix);  
        $this->logger->log(LOG_DEBUG, "default action class [%s]", $r);  
     *  getDefaultFormClass()で取得したクラス名からアクション名を取得する  
     *  getDefaultFormClass()をオーバーライドした場合、こちらも合わせてオーバーライド  
     *  @param  string  $class_name     フォームクラス名  
        if (preg_match("/$prefix(.*)/", $class_name, $match) == 
0) {  
     *  アクションに対応するフォームパス名が省略された場合のデフォルトパス名を返す  
     *  デフォルトでは_getDefaultActionPath()と同じ結果を返す(1ファイルに  
     *  アクションクラスとフォームクラスが記述される)ので、好みに応じて  
     *  @param  string  $action_name    アクション名  
     *  @return string  form classが定義されるスクリプトのパス名  
     *  指定されたアクションのクラス名を返す(オブジェクトの生成は行わない)  
     *  @param  string  $action_name    アクションの名称  
     *  @return string  アクションのクラス名  
        $action_obj =
& $this->_getAction($action_name);  
        if ($action_obj == 
null) {  
        return $action_obj['class_name'];  
     *  アクションに対応するアクションクラス名が省略された場合のデフォルトクラス名を返す  
     *  デフォルトでは[プロジェクトID]_Action_[アクション名]となるので好み応じてオーバライドする  
     *  @param  string  $action_name    アクション名  
     *  @return string  アクションクラス名  
        $r = 
sprintf("%s_%sAction_%s", $this->getAppId(), $gateway_prefix ? 
$gateway_prefix . 
"_" : 
"", $postfix);  
        $this->logger->log(LOG_DEBUG, "default action class [%s]", $r);  
     *  getDefaultActionClass()で取得したクラス名からアクション名を取得する  
     *  getDefaultActionClass()をオーバーライドした場合、こちらも合わせてオーバーライド  
     *  @param  string  $class_name     アクションクラス名  
        if (preg_match("/$prefix(.*)/", $class_name, $match) == 
0) {  
     *  アクションに対応するアクションパス名が省略された場合のデフォルトパス名を返す  
     *  デフォルトでは"foo_bar" -> "/Foo/Bar.php"となるので好み応じてオーバーライドする  
     *  @param  string  $action_name    アクション名  
     *  @return string  アクションクラスが定義されるスクリプトのパス名  
        $this->logger->log(LOG_DEBUG, "default action path [%s]", $r);  
     *  指定された遷移名に対応するビュークラス名を返す(オブジェクトの生成は行わない)  
     *  @param  string  $forward_name   遷移先の名称  
     *  @return string  view classのクラス名  
        if ($forward_name == 
null) {  
        if (isset
($this->forward[$forward_name])) {  
            $forward_obj = 
$this->forward[$forward_name];  
        if (isset
($forward_obj['view_name'])) {  
            $class_name = 
$forward_obj['view_name'];  
        $this->_includeViewScript($forward_obj, $forward_name);  
        } else if (is_null($class_name) == 
false) {  
            $this->logger->log(LOG_WARNING, 'stated view class is not defined [%s] -> try default', $class_name);  
            $this->logger->log(LOG_DEBUG, 'view class is not defined for [%s] -> use default [%s]', $forward_name, $class_name);  
     *  遷移名に対応するビュークラス名が省略された場合のデフォルトクラス名を返す  
     *  デフォルトでは[プロジェクトID]_View_[遷移名]となるので好み応じてオーバライドする  
     *  @param  string  $forward_name   forward名  
     *  @return string  view classクラス名  
        $r = 
sprintf("%s_%sView_%s", $this->getAppId(), $gateway_prefix ? 
$gateway_prefix . 
"_" : 
"", $postfix);  
        $this->logger->log(LOG_DEBUG, "default view class [%s]", $r);  
     *  遷移名に対応するビューパス名が省略された場合のデフォルトパス名を返す  
     *  デフォルトでは"foo_bar" -> "/Foo/Bar.php"となるので好み応じてオーバーライドする  
     *  @param  string  $forward_name   forward名  
     *  @return string  view classが定義されるスクリプトのパス名  
        $this->logger->log(LOG_DEBUG, "default view path [%s]", $r);  
     *  遷移名に対応するテンプレートパス名が省略された場合のデフォルトパス名を返す  
     *  デフォルトでは"foo_bar"というforward名が"foo/bar" + テンプレート拡張子となる  
     *  @param  string  $forward_name   forward名  
     *  @return string  forwardパス名  
        return str_replace('_', '/', $forward_name) . 
'.' . 
$this->ext['tpl'];  
     *  getDefaultForwardPath()をオーバーライドした場合、こちらも合わせてオーバーライド  
     *  @param  string  $forward_path   テンプレートパス名  
     *  遷移名からテンプレートファイルのパス名を取得する  
     *  @param  string  $forward_name   forward名  
     *  @return string  テンプレートファイルのパス名  
    function _getForwardPath($forward_name)  
        if (isset
($this->forward[$forward_name]) == 
false) {  
            $this->forward[$forward_name] = 
array();  
        $forward_obj =
& $this->forward[$forward_name];  
        if (isset
($forward_obj['forward_path']) == 
false) {  
        return $forward_obj['forward_path'];  
     *  レンダラを取得する(getTemplateEngine()はそのうち廃止されgetRenderer()に統合される予定)  
     *  @return object  Ethna_Renderer  レンダラオブジェクト  
     *  @return object  Ethna_Renderer  レンダラオブジェクト  
        $this->renderer =
& $this->class_factory->getObject('renderer');  
            // user defined modifiers  
            foreach ($this->smarty_modifier_plugin as $modifier) {  
                $name = 
str_replace('smarty_modifier_', '', $modifier);  
                $this->renderer->setPlugin($name,'modifier', $modifier);  
            // user defined functions  
            foreach ($this->smarty_function_plugin as $function) {  
                    $name = 
str_replace('smarty_function_', '', $function);  
                    $this->renderer->setPlugin($name, 'function', $function);  
                    $this->renderer->setPlugin($function[1], 'function', $function);  
            foreach ($this->smarty_block_plugin as $block) {  
                    $this->renderer->setPlugin($name,'block', $block);  
                    $this->renderer->setPlugin($block[1],'block', $block);  
            // user defined prefilters  
            foreach ($this->smarty_prefilter_plugin as $prefilter) {  
                    $name = 
str_replace('smarty_prefilter_', '', $prefilter);  
                    $this->renderer->setPlugin($name,'prefilter', $prefilter);  
                    $this->renderer->setPlugin($prefilter[1],'prefilter', $prefilter);  
            // user defined postfilters  
            foreach ($this->smarty_postfilter_plugin as $postfilter) {  
                    $name = 
str_replace('smarty_postfilter_', '', $postfilter);  
                    $this->renderer->setPlugin($name,'postfilter', $postfilter);  
                    $this->renderer->setPlugin($postfilter[1],'postfilter', $postfilter);  
            // user defined outputfilters  
            foreach ($this->smarty_outputfilter_plugin as $outputfilter) {  
                    $name = 
str_replace('smarty_outputfilter_', '', $outputfilter);  
                    $this->renderer->setPlugin($name,'outputfilter', $outputfilter);  
                    $this->renderer->setPlugin($outputfilter[1],'outputfilter', $outputfilter);  
     *  テンプレートエンジンのデフォルト状態を設定する  
     *  @param  object  Ethna_Renderer  レンダラオブジェクト  
     *  将来への拡張のためのみに存在しています。現在は特にオーバーライドの必要はありません。  
     *  @param  string  $language           言語定義(LANG_JA, LANG_EN...)  
     *  @param  string  $system_encoding    システムエンコーディング名  
     *  @param  string  $client_encoding    クライアントエンコーディング  
    function _setLanguage($language, $system_encoding = 
null, $client_encoding = 
null)  
        $this->language = 
$language;  
        $this->system_encoding = 
$system_encoding;  
        $this->client_encoding = 
$client_encoding;  
        $i18n->setLanguage($language, $system_encoding, $client_encoding);  
     *  @return array   使用言語,システムエンコーディング名,クライアントエンコーディング名  
     *  @return int     ゲートウェイ定義(GATEWAY_WWW, GATEWAY_CLI...)  
        if (is_null($GLOBALS['_Ethna_gateway']) == 
false) {  
            return $GLOBALS['_Ethna_gateway'];  
     *  ゲートウェイに対応したクラス名のプレフィクスを取得する  
     *  @param  string  $gateway    ゲートウェイ  
     *  @return string  ゲートウェイクラスプレフィクス  
     *  @param  string  $name   マネージャキー  
     *  @return string  マネージャクラス名  
     *  アプリケーションオブジェクトクラス名を取得する  
     *  @param  string  $name   アプリケーションオブジェクトキー  
     *  @return string  マネージャクラス名  
     *  ただし、インクルードしたファイルにクラスが正しく定義されているかどうかは保証しない  
     *  @param  array   $action_obj     アクション定義  
     *  @param  string  $action_name    アクション名  
    function _includeActionScript($action_obj, $action_name)  
        $class_path = 
$form_path = 
null;  
        if (isset
($action_obj['class_path'])) {  
            $tmp_path = 
$action_obj['class_path'];  
                $tmp_path = 
$action_dir . 
$tmp_path;  
                $this->logger->log(LOG_WARNING, 'class_path file not found [%s] -> try default', $tmp_path);  
                include_once $action_dir . 
$class_path;  
                $this->logger->log(LOG_DEBUG, 'default action file not found [%s] -> try all files', $class_path);  
        if (isset
($action_obj['form_path'])) {  
            $tmp_path = 
$action_obj['form_path'];  
                $tmp_path = 
$action_dir . 
$tmp_path;  
            if ($tmp_path == 
$class_path) {  
                $this->logger->log(LOG_WARNING, 'form_path file not found [%s] -> try default', $tmp_path);  
            if ($form_path == 
$class_path) {  
                include_once $action_dir . 
$form_path;  
                $this->logger->log(LOG_DEBUG, 'default form file not found [%s] -> maybe falling back to default form class', $form_path);  
     *  ただし、インクルードしたファイルにクラスが正しく定義されているかどうかは保証しない  
     *  @param  array   $forward_obj    遷移定義  
     *  @param  string  $forward_name   遷移名  
    function _includeViewScript($forward_obj, $forward_name)  
        if (isset
($forward_obj['view_path'])) {  
            $tmp_path = 
$forward_obj['view_path'];  
                $tmp_path = 
$view_dir . 
$tmp_path;  
                $this->logger->log(LOG_WARNING, 'view_path file not found [%s] -> try default', $tmp_path);  
            include_once $view_dir . 
$view_path;  
            $this->logger->log(LOG_DEBUG, 'default view file not found [%s]', $view_path);  
     *  ディレクトリ以下の全てのスクリプトをインクルードする  
    function _includeDirectory($dir)  
        $ext = 
"." . 
$this->ext['php'];  
            while (($file = 
readdir($dh)) !== 
false) {  
                if ($file != 
'.' && 
$file != 
'..' && 
is_dir("$dir/$file")) {  
                    $this->_includeDirectory("$dir/$file");  
                if (substr($file, -
$ext_len, $ext_len) != 
$ext) {  
                include_once $dir . 
'/' . 
$file;  
     *  設定ファイルのDSN定義から使用するデータを再構築する(スレーブアクセス分岐等)  
     *  DSNの定義方法(デフォルト:設定ファイル)を変えたい場合はここをオーバーライドする  
     *  @return array   DSN定義(array('DBキー1' => 'dsn1', 'DBキー2' => 'dsn2', ...))  
        foreach ($this->db as $key => 
$value) {  
            $dsn = 
$this->config->get($config_key);  
                // 種別1つにつき複数DSNが定義されている場合はアクセス分岐  
     *  スレーブサーバへの振分け処理(デフォルト:ランダム)を変更したい場合はこのメソッドをオーバーライドする  
     *  @param  string  $type       DB種別  
     *  @param  array   $dsn_list   DSN一覧  
     *  @return string  選択されたDSN  
        mt_srand($sec + 
((float) 
$usec * 
100000));  
     *  不要な場合は空のメソッドとしてオーバーライドしてもよい  
        if ($this->config->get('debug') == 
false) {  
        require_once ETHNA_BASE . 
'/class/Ethna_InfoManager.php';  
        // see if we have simpletest  
            require_once ETHNA_BASE . 
'/class/Ethna_UnitTestManager.php';  
        $this->action['__ethna_info__'] = 
array(  
            'form_name' =>  
'Ethna_Form_Info',  
            'class_name' => 
'Ethna_Action_Info',  
        $this->forward['__ethna_info__'] = 
array(  
            'view_name'     => 
'Ethna_View_Info',  
        $this->action['__ethna_unittest__'] = 
array(  
            'form_name' =>  
'Ethna_Form_UnitTest',  
            'class_name' => 
'Ethna_Action_UnitTest',  
        $this->forward['__ethna_unittest__'] = 
array(  
            'view_name'     => 
'Ethna_View_UnitTest',  
     *  Ethnaマネージャが実行可能かをチェックする  
     *  Ethnaマネージャを実行するよう指示されているにも関わらず、  
     *  debug が trueでない場合は実行を停止する。  
    function _ethnaManagerEnabledCheck($action_name)  
        if ($this->config->get('debug') == 
false  
         && 
($action_name == 
'__ethna_info__' || 
$action_name == 
'__ethna_unittest__')) { 
     *  Ethnaマネージャが実行不能な場合のエラーメッセージを  
     *  表示する。運用上の都合でこのメッセージを出力したくない  
         $run_action = 
($action_name == 
'__ethna_info__')  
                     ? 
' show Application Info List ' 
         echo 
"Ethna cannot {$run_action} under your application setting.<br>"; 
         echo 
"HINT: You must set {$appid}/etc/{$appid}-ini.php debug setting 'true'.<br>"; 
         echo 
"In {$appid}-ini.php, please set as follows :<br><br>"; 
         echo 
"\$config = array ( 'debug' => true, );"; 
    if (Ethna::isError($r)) {  
            'faultCode' => 
$r->getCode(),  
            'faultString' => 
$r->getMessage(),  
 
 
	
		Documentation generated on Thu, 08 May 2008 00:14:44 +0900 by phpDocumentor 1.4.2