OSDN Git Service

Add Ethna_Plugin_Abstract for all plugins abstract
[ethna/ethna.git] / class / Ethna_Controller.php
index bb96cf0..f844092 100644 (file)
@@ -93,9 +93,6 @@ class Ethna_Controller
         'url_handler'   => 'Ethna_UrlHandler',
     );
 
-    /** @var    array       検索対象となるプラグインのアプリケーションIDのリスト */
-    var $plugin_search_appids;
-
     /** @var    array       フィルタ設定 */
     var $filter = array(
     );
@@ -119,6 +116,15 @@ class Ethna_Controller
     /** @var    array   forward定義 */
     var $forward = array();
 
+    /** @var    array   デフォルトのforward定義 */
+    var $forward_default = array(
+        '403' => array( 'view_name' => 'Ethna_View_403',),
+        '404' => array( 'view_name' => 'Ethna_View_404',),
+        '500' => array( 'view_name' => 'Ethna_View_500',), 
+        'json' => array( 'view_name' => 'Ethna_View_Json',),
+        'redirect' => array( 'view_name' => 'Ethna_View_Redirect',),
+    );
+
     /** @var    array   action定義 */
     var $action = array();
 
@@ -134,25 +140,6 @@ class Ethna_Controller
     /** @var    object  レンダラー */
     var $renderer = null;
 
-    /** @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();
 
@@ -236,6 +223,10 @@ class Ethna_Controller
             }
         }
 
+        // 遷移先設定をマージ
+        // 但し、キーは完全に維持する
+        $this->forward = $this->forward + $this->forward_default;
+
         // 初期設定
         // フレームワークとしての内部エンコーディングはクライアント
         // エンコーディング(=ブラウザからのエンコーディング)
@@ -263,11 +254,25 @@ class Ethna_Controller
         $this->plugin->setLogger($this->logger);
         $this->logger->begin();
 
+        // include Ethna_Plugin_Abstract for all plugins
+        $this->plugin->includePlugin('Abstract');
+
         // Ethnaマネージャ設定
         $this->_activateEthnaManager();
     }
 
     /**
+     *  アプリケーション実行後の後始末を行います。
+     *
+     *  @access protected
+     */
+    function end()
+    {
+        //  必要に応じてオーバライドして下さい。
+        $this->logger->end();
+    }
+
+    /**
      *  (現在アクティブな)コントローラのインスタンスを返す
      *
      *  @access public
@@ -448,7 +453,9 @@ class Ethna_Controller
         $template = $this->getDirectory('template');
 
         // 言語別ディレクトリ
-        if (file_exists($template . '/' . $this->locale)) {
+        // _getDerfaultLanguageメソッドでロケールが指定されていた場合は、
+        // テンプレートディレクトリにも自動的にそれを付加する。
+        if (!empty($this->locale)) {
             $template .= '/' . $this->locale;
         }
 
@@ -708,7 +715,7 @@ class Ethna_Controller
      *                  システムエンコーディング名,
      *                  クライアントエンコーディング名 の配列
      *                  (ロケール名は、ll_cc の形式。ll = 言語コード cc = 国コード)
-     *  @see http://www.gnu.org/software/gettext/manual/html_node/Locale-Names.html 
+     *  @see http://www.gnu.org/software/gettext/manual/html_node/Locale-Names.html
      */
     function getLanguage()
     {
@@ -798,6 +805,7 @@ class Ethna_Controller
     {
         $c =& new $class_name;
         $c->trigger($action_name, $fallback_action_name);
+        $c->end();
     }
 
     /**
@@ -814,6 +822,7 @@ class Ethna_Controller
         $c =& new $class_name(GATEWAY_CLI);
         $c->action_cli[$action_name] = array();
         $c->trigger($action_name, "", $enable_filter);
+        $c->end();
     }
 
     /**
@@ -830,6 +839,7 @@ class Ethna_Controller
 
         $c =& new $class_name(GATEWAY_XMLRPC);
         $c->trigger("", "", false);
+        $c->end();
     }
 
     /**
@@ -845,6 +855,7 @@ class Ethna_Controller
     {
         $c =& new $class_name(GATEWAY_SOAP);
         $c->trigger($action_name, $fallback_action_name);
+        $c->end();
     }
 
     /**
@@ -940,21 +951,23 @@ class Ethna_Controller
         }
         $this->action_name = $action_name;
 
-        // ロケール/言語設定
-        $this->_setLanguage($this->locale, $this->system_encoding, $this->client_encoding);
-
         // オブジェクト生成
         $backend =& $this->getBackend();
+        $session =& $this->getSession();
+        $session->restore();
 
+        // 言語切り替えフックを呼ぶ
+        $this->_setLanguage($this->locale, $this->system_encoding, $this->client_encoding);
+
+        // アクションフォーム初期化
+        // フォーム定義、フォーム値設定
         $form_name = $this->getActionFormName($action_name);
         $this->action_form =& new $form_name($this);
+        $this->action_form->setFormDef_PreHelper();
         $this->action_form->setFormVars();
-
-        // バックエンド処理実行
         $backend->setActionForm($this->action_form);
 
-        $session =& $this->getSession();
-        $session->restore();
+        // バックエンド処理実行
         $forward_name = $backend->perform($action_name);
 
         // アクション実行後フィルタ
@@ -967,12 +980,22 @@ class Ethna_Controller
         }
 
         // コントローラで遷移先を決定する(オプション)
-        $forward_name = $this->_sortForward($action_name, $forward_name);
+        $forward_name_params = $this->_sortForward($action_name, $forward_name);
+
+        // Viewへの引数があれば取り出す
+        $preforward_params = array();
+        if (is_array($forward_name_params)) {
+            $forward_name = array_shift($forward_name_params);
+            $preforward_params = $forward_name_params;
+        }
+        else {
+            $forward_name = $forward_name_params;
+        }
 
         if ($forward_name != null) {
             $view_class_name = $this->getViewClassName($forward_name);
             $this->view =& new $view_class_name($backend, $forward_name, $this->_getForwardPath($forward_name));
-            $this->view->preforward();
+            call_user_func_array(array($this->view, 'preforward'), $preforward_params);
             $this->view->forward();
         }
 
@@ -1018,7 +1041,7 @@ class Ethna_Controller
                 'version'       => 'xmlrpc',
                 'encoding'      => 'utf-8'
             )
-        ); 
+        );
 
         xmlrpc_server_register_method(
             $xmlrpc_server,
@@ -1269,9 +1292,9 @@ class Ethna_Controller
      */
     function getActionRequest($action, $type = "hidden")
     {
-        $s = null; 
+        $s = null;
         if ($type == "hidden") {
-            $s = sprintf('<input type="hidden" name="action_%s" value="true">', htmlspecialchars($action, ENT_QUOTES));
+            $s = sprintf('<input type="hidden" name="action_%s" value="true" />', htmlspecialchars($action, ENT_QUOTES));
         } else if ($type == "url") {
             $s = sprintf('action_%s=true', urlencode($action));
         }
@@ -1366,21 +1389,12 @@ class Ethna_Controller
     {
         $this->filter_chain = array();
         foreach ($this->filter as $filter) {
-            //バージョン0.2.0以前のフィルタ群から探す
-            $file = sprintf("%s/%s.%s", $this->getDirectory('filter'), $filter,$this->getExt('php'));
-            if (file_exists($file)) {
-                include_once $file;
-                if (class_exists($filter)) {
-                    $this->filter_chain[] =& new $filter($this);
-                }
-            } else {  //プラグインから探す.
-                $filter_plugin =& $this->plugin->getPlugin('Filter', $filter);
-                if (Ethna::isError($filter_plugin)) {
-                    continue;
-                }
-
-                $this->filter_chain[] =& $filter_plugin;
+            $filter_plugin =& $this->plugin->getPlugin('Filter', $filter);
+            if (Ethna::isError($filter_plugin)) {
+                continue;
             }
+
+            $this->filter_chain[] =& $filter_plugin;
         }
     }
 
@@ -1659,7 +1673,7 @@ class Ethna_Controller
     {
         return str_replace('_', '/', $forward_name) . '.' . $this->ext['tpl'];
     }
-    
+
     /**
      *  テンプレートパス名から遷移名を取得する
      *
@@ -1726,71 +1740,8 @@ class Ethna_Controller
         if (is_object($this->renderer)) {
             return $this->renderer;
         }
-        
-        $this->renderer =& $this->class_factory->getObject('renderer');
-       
-        // {{{ for B.C.
-        if (strtolower(get_class($this->renderer)) == "ethna_renderer_smarty") {
-            // user defined modifiers
-            foreach ($this->smarty_modifier_plugin as $modifier) {
-                if (!is_array($modifier)) {
-                    $name = str_replace('smarty_modifier_', '', $modifier);
-                    $this->renderer->setPlugin($name,'modifier', $modifier);
-                } else {
-                    $this->renderer->setPlugin($modifier[1], 'modifier', $modifier);
-                }
-            }
-
-            // user defined functions
-            foreach ($this->smarty_function_plugin as $function) {
-                if (!is_array($function)) {
-                    $name = str_replace('smarty_function_', '', $function);
-                    $this->renderer->setPlugin($name, 'function', $function);
-                } else {
-                    $this->renderer->setPlugin($function[1], 'function', $function);
-                }
-            }
-
-            // user defined blocks
-            foreach ($this->smarty_block_plugin as $block) {
-                if (!is_array($block)) {
-                    $name = str_replace('smarty_block_', '', $block);
-                    $this->renderer->setPlugin($name,'block', $block);
-                } else {
-                    $this->renderer->setPlugin($block[1],'block', $block);
-                }
-            }
-
-            // user defined prefilters
-            foreach ($this->smarty_prefilter_plugin as $prefilter) {
-                if (!is_array($prefilter)) {
-                    $name = str_replace('smarty_prefilter_', '', $prefilter);
-                    $this->renderer->setPlugin($name,'prefilter', $prefilter);
-                } else {
-                    $this->renderer->setPlugin($prefilter[1],'prefilter', $prefilter);
-                }
-            }
 
-            // user defined postfilters
-            foreach ($this->smarty_postfilter_plugin as $postfilter) {
-                if (!is_array($postfilter)) {
-                    $name = str_replace('smarty_postfilter_', '', $postfilter);
-                    $this->renderer->setPlugin($name,'postfilter', $postfilter);
-                } else {
-                    $this->renderer->setPlugin($postfilter[1],'postfilter', $postfilter);
-                }
-            }
-
-            // user defined outputfilters
-            foreach ($this->smarty_outputfilter_plugin as $outputfilter) {
-                if (!is_array($outputfilter)) {
-                    $name = str_replace('smarty_outputfilter_', '', $outputfilter);
-                    $this->renderer->setPlugin($name,'outputfilter', $outputfilter);
-                } else {
-                    $this->renderer->setPlugin($outputfilter[1],'outputfilter', $outputfilter);
-                }
-            }
-        }
+        $this->renderer =& $this->class_factory->getObject('renderer');
 
         //テンプレートエンジンのデフォルトの設定
         $this->_setDefaultTemplateEngine($this->renderer);
@@ -1820,7 +1771,7 @@ class Ethna_Controller
      *                                      (ll_cc の形式。ll = 言語コード cc = 国コード)
      *  @param  string  $system_encoding    システムエンコーディング名
      *  @param  string  $client_encoding    クライアントエンコーディング(テンプレートのエンコーディングと考えれば良い)
-     *  @see    http://www.gnu.org/software/gettext/manual/html_node/Locale-Names.html 
+     *  @see    http://www.gnu.org/software/gettext/manual/html_node/Locale-Names.html
      *  @see    Ethna_Controller#_getDefaultLanguage
      */
     function _setLanguage($locale, $system_encoding = null, $client_encoding = null)
@@ -1829,6 +1780,9 @@ class Ethna_Controller
         $this->system_encoding = $system_encoding;
         $this->client_encoding = $client_encoding;
 
+        //   $this->locale, $this->client_encoding を書き換えた場合は
+        //   必ず Ethna_I18N クラスの setLanguageメソッドも呼ぶこと!
+        //   さもないとカタログその他が再ロードされない!
         $i18n =& $this->getI18N();
         $i18n->setLanguage($locale, $system_encoding, $client_encoding);
     }
@@ -1906,8 +1860,9 @@ class Ethna_Controller
     function getManagerClassName($name)
     {
         //   アプリケーションIDと、渡された名前のはじめを大文字にして、
-        //   組み合わせたものが返される 
-        return sprintf('%s_%sManager', $this->getAppId(), ucfirst($name));
+        //   組み合わせたものが返される
+        $manager_id = preg_replace('/_(.)/e', "strtoupper('\$1')", ucfirst($name));
+        return sprintf('%s_%sManager', $this->getAppId(), ucfirst($manager_id));
     }
 
     /**
@@ -1922,7 +1877,7 @@ class Ethna_Controller
         //  引数のはじめの一文字目と、アンダーバー直後の
         //  1文字を必ず大文字にする。アンダーバーは削除される。
         $name = preg_replace('/_(.)/e', "strtoupper('\$1')", ucfirst($name));
-        
+
         //  $name に foo_bar を渡し、AppID が Hogeの場合
         //  [Appid]_FooBar が返される
         return sprintf('%s_%s', $this->getAppId(), $name);
@@ -1966,15 +1921,9 @@ class Ethna_Controller
                 include_once $action_dir . $class_path;
             } else {
                 $this->logger->log(LOG_DEBUG, 'default action file not found [%s] -> try all files', $class_path);
-                $class_path = null;
+                return;
             }
         }
-        
-        // 全ファイルインクルード
-        if (is_null($class_path)) {
-            $this->_includeDirectory($this->getActiondir());
-            return;
-        }
 
         // form_path属性チェック
         if (isset($action_obj['form_path'])) {
@@ -2107,7 +2056,7 @@ class Ethna_Controller
 
     /**
      *  DSNのアクセス分岐を行う
-     *  
+     *
      *  スレーブサーバへの振分け処理(デフォルト:ランダム)を変更したい場合はこのメソッドをオーバーライドする
      *
      *  @access protected
@@ -2125,7 +2074,7 @@ class Ethna_Controller
         list($usec, $sec) = explode(' ', microtime());
         mt_srand($sec + ((float) $usec * 100000));
         $n = mt_rand(0, count($dsn_list)-1);
-        
+
         return $dsn_list[$n];
     }
 
@@ -2143,7 +2092,7 @@ class Ethna_Controller
         }
 
         require_once ETHNA_BASE . '/class/Ethna_InfoManager.php';
-        
+
         // see if we have simpletest
         if (file_exists_ex('simpletest/unit_tester.php', true)) {
             require_once ETHNA_BASE . '/class/Ethna_UnitTestManager.php';
@@ -2163,8 +2112,8 @@ class Ethna_Controller
             'view_name'     => 'Ethna_View_Info',
             'view_path'     => sprintf('%s/class/View/Ethna_View_Info.php', ETHNA_BASE),
         );
-        
-        
+
+
         // action設定
         $this->action['__ethna_unittest__'] = array(
             'form_name' =>  'Ethna_Form_UnitTest',
@@ -2217,7 +2166,7 @@ class Ethna_Controller
          echo "<br>";
          echo "In {$appid}-ini.php, please set as follows :<br><br>";
          echo "\$config = array ( 'debug' => true, );";
-     } 
+     }
 
     /**
      *  CLI実行中フラグを取得する