OSDN Git Service

- __ethna_info__アクションを追加
authorfujimoto <fujimoto@2ef88817-412d-0410-a32c-8029a115e976>
Thu, 23 Dec 2004 06:03:12 +0000 (06:03 +0000)
committerfujimoto <fujimoto@2ef88817-412d-0410-a32c-8029a115e976>
Thu, 23 Dec 2004 06:03:12 +0000 (06:03 +0000)
CHANGES
Ethna.php
class/Action/Ethna_Action_Info.php
class/Ethna_Backend.php
class/Ethna_Controller.php
class/Ethna_InfoManager.php
class/Ethna_Util.php
class/Form/Ethna_Form_Info.php [deleted file]
class/View/Ethna_View_Info.php [new file with mode: 0644]
skel/www.info.php
tpl/info.tpl

diff --git a/CHANGES b/CHANGES
index b781470..b803020 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,7 @@
 
 *** features
 
+- __ethna_info__¥¢¥¯¥·¥ç¥ó¤òÄɲÃ
 - class_path, form_path, view_path°À­¤Î¥Õ¥ë¥Ñ¥¹»ØÄꥵ¥Ý¡¼¥È¤òÄɲÃ
 - ¥¹¥¯¥ê¥×¥È¤ò1¥Õ¥¡¥¤¥ë¤Ë¤Þ¤È¤á¤ë¥Ä¡¼¥ë(bin/unify_script.php)¤òÄɲÃ
 
index 1fba7a2..21725d8 100644 (file)
--- a/Ethna.php
+++ b/Ethna.php
@@ -38,7 +38,6 @@ include_once(ETHNA_BASE . '/class/Ethna_Controller.php');
 include_once(ETHNA_BASE . '/class/Ethna_DB.php');
 include_once(ETHNA_BASE . '/class/Ethna_Filter.php');
 include_once(ETHNA_BASE . '/class/Ethna_I18N.php');
-include_once(ETHNA_BASE . '/class/Ethna_InfoManager.php');
 include_once(ETHNA_BASE . '/class/Ethna_LogWriter.php');
 include_once(ETHNA_BASE . '/class/Ethna_LogWriter_File.php');
 include_once(ETHNA_BASE . '/class/Ethna_LogWriter_Syslog.php');
@@ -50,9 +49,7 @@ include_once(ETHNA_BASE . '/class/Ethna_SmartyPlugin.php');
 include_once(ETHNA_BASE . '/class/Ethna_Util.php');
 include_once(ETHNA_BASE . '/class/Ethna_ViewClass.php');
 include_once(ETHNA_BASE . '/class/AMF/Ethna_AMF_ActionClass.php');
-include_once(ETHNA_BASE . '/class/Action/Ethna_Action_Info.php');
 include_once(ETHNA_BASE . '/class/CLI/Ethna_CLI_ActionClass.php');
-include_once(ETHNA_BASE . '/class/Form/Ethna_Form_Info.php');
 include_once(ETHNA_BASE . '/class/View/Ethna_View_List.php');
 
 if (extension_loaded('soap')) {
index c8e77d9..1c099a8 100644 (file)
@@ -9,6 +9,25 @@
  *     @version        $Id$
  */
 
+// {{{ Ethna_Form_Info
+/**
+ *     __ethna_info__¥Õ¥©¡¼¥à¤Î¼ÂÁõ
+ *
+ *     @author         Masaki Fujimoto <fujimoto@php.net>
+ *     @access         public
+ *     @package        Ethna
+ */
+class Ethna_Form_Info extends Ethna_ActionForm
+{
+       /**
+        *      @access private
+        *      @var    array   ¥Õ¥©¡¼¥àÃÍÄêµÁ
+        */
+       var     $form = array(
+       );
+}
+// }}}
+
 // {{{ Ethna_Action_Info
 /**
  *     __ethna_info__¥¢¥¯¥·¥ç¥ó¤Î¼ÂÁõ
@@ -40,18 +59,6 @@ class Ethna_Action_Info extends Ethna_ActionClass
        {
                return '__ethna_info__';
        }
-
-       /**
-        *      Á«°ÜÁ°½èÍý
-        *
-        *      @access public
-        */
-       function preforward()
-       {
-               $em =& new Ethna_InfoManager($this->backend);
-
-               $this->af->setApp('ethna_version', ETHNA_VERSION);
-       }
 }
 // }}}
 ?>
index 9400955..496aa65 100644 (file)
@@ -113,7 +113,7 @@ class Ethna_Backend
                // ¥Þ¥Í¡¼¥¸¥ã¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®
                $manager_list = $controller->getManagerList();
                foreach ($manager_list as $key => $value) {
-                       $class_name = $controller->getAppId() . "_" . ucfirst(strtolower($value)) . 'Manager';
+                       $class_name = $this->controller->getManagerClassName($value);
                        $this->manager[$value] =& new $class_name($this);
                }
 
index 3b00d3a..ddeda25 100644 (file)
@@ -227,17 +227,18 @@ class Ethna_Controller
                                // Smarty¥×¥é¥°¥¤¥ó¥Ç¥£¥ì¥¯¥È¥ê¤ÏÇÛÎó¤Ç»ØÄꤹ¤ë
                                $tmp = array(SMARTY_DIR . 'plugins');
                                foreach (to_array($value) as $elt) {
-                                       if ($elt{0} != '/') {
+                                       if (Ethna_Util::isAbsolute($elt) == false) {
                                                $tmp[] = $this->base . (empty($this->base) ? '' : '/') . $elt;
                                        }
                                }
                                $this->directory[$key] = $tmp;
                        } else {
-                               if ($value{0} != '/') {
+                               if (Ethna_Util::isAbsolute($value) == false) {
                                        $this->directory[$key] = $this->base . (empty($this->base) ? '' : '/') . $value;
                                }
                        }
                }
+
                $this->i18n =& new Ethna_I18N($this->getDirectory('locale'), $this->getAppId());
                list($this->language, $this->system_encoding, $this->client_encoding) = $this->_getDefaultLanguage();
                $this->client_type = $this->_getDefaultClientType();
@@ -591,74 +592,6 @@ class Ethna_Controller
        }
 
        /**
-        *      ¥Æ¥ó¥×¥ì¡¼¥È¥¨¥ó¥¸¥ó¼èÆÀ¤¹¤ë(¸½ºß¤Ïsmarty¤Î¤ßÂбþ)
-        *
-        *      @access public
-        *      @return object  Smarty  ¥Æ¥ó¥×¥ì¡¼¥È¥¨¥ó¥¸¥ó¥ª¥Ö¥¸¥§¥¯¥È
-        *      @todo   ¥Ö¥í¥Ã¥¯´Ø¿ô¥×¥é¥°¥¤¥ó(etc)Âбþ
-        */
-       function &getTemplateEngine()
-       {
-               $smarty =& new Smarty();
-               $smarty->template_dir = $this->getTemplatedir();
-               $smarty->compile_dir = $this->getDirectory('template_c') . '/tpl_' . md5($smarty->template_dir);
-               if (@is_dir($smarty->compile_dir) == false) {
-                       mkdir($smarty->compile_dir, 0755);
-               }
-               $smarty->plugins_dir = $this->getDirectory('plugins');
-
-               // default modifiers
-               $smarty->register_modifier('number_format', 'smarty_modifier_number_format');
-               $smarty->register_modifier('strftime', 'smarty_modifier_strftime');
-               $smarty->register_modifier('count', 'smarty_modifier_count');
-               $smarty->register_modifier('join', 'smarty_modifier_join');
-               $smarty->register_modifier('filter', 'smarty_modifier_filter');
-               $smarty->register_modifier('unique', 'smarty_modifier_unique');
-               $smarty->register_modifier('wordwrap_i18n', 'smarty_modifier_wordwrap_i18n');
-               $smarty->register_modifier('i18n', 'smarty_modifier_i18n');
-               $smarty->register_modifier('checkbox', 'smarty_modifier_checkbox');
-               $smarty->register_modifier('select', 'smarty_modifier_select');
-               $smarty->register_modifier('form_value', 'smarty_modifier_form_value');
-
-               // user defined modifiers
-               foreach ($this->smarty_modifier_plugin as $modifier) {
-                       $name = str_replace('smarty_modifier_', '', $modifier);
-                       $smarty->register_modifier($name, $modifier);
-               }
-
-               // default functions
-               $smarty->register_function('message', 'smarty_function_message');
-               $smarty->register_function('uniqid', 'smarty_function_uniqid');
-               $smarty->register_function('select', 'smarty_function_select');
-               $smarty->register_function('checkbox_list', 'smarty_function_checkbox_list');
-
-               // user defined functions
-               foreach ($this->smarty_function_plugin as $function) {
-                       $name = str_replace('smarty_function_', '', $function);
-                       $smarty->register_function($name, $function);
-               }
-
-               // user defined prefilters
-               foreach ($this->smarty_prefilter_plugin as $prefilter) {
-                       $smarty->register_prefilter($prefilter);
-               }
-
-               // user defined postfilters
-               foreach ($this->smarty_postfilter_plugin as $postfilter) {
-                       $smarty->register_postfilter($postfilter);
-               }
-
-               // user defined outputfilters
-               foreach ($this->smarty_outputfilter_plugin as $outputfilter) {
-                       $smarty->register_outputfilter($outputfilter);
-               }
-
-               $this->_setDefaultTemplateEngine($smarty);
-
-               return $smarty;
-       }
-
-       /**
         *      ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥¨¥ó¥È¥ê¥Ý¥¤¥ó¥È
         *
         *      @access public
@@ -905,416 +838,543 @@ class Ethna_Controller
        }
 
        /**
-        *      »ØÄꤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó¤Î¥Õ¥©¡¼¥à¥¯¥é¥¹Ì¾¤òÊÖ¤¹(¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®¤Ï¹Ô¤ï¤Ê¤¤)
+        *      ¼Â¹Ô¤¹¤ë¥¢¥¯¥·¥ç¥ó̾¤òÊÖ¤¹
         *
-        *      @access public
-        *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó̾
-        *      @return string  ¥¢¥¯¥·¥ç¥ó¤Î¥Õ¥©¡¼¥à¥¯¥é¥¹̾
+        *      @access private
+        *      @param  mixed   $default_action_name    »ØÄê¤Î¥¢¥¯¥·¥ç¥ó̾
+        *      @return string  ¼Â¹Ô¤¹¤ë¥¢¥¯¥·¥ç¥ó̾
         */
-       function getActionFormName($action_name)
+       function _getActionName($default_action_name, $fallback_action_name)
        {
-               $action_obj =& $this->_getAction($action_name);
-               if (is_null($action_obj)) {
-                       return null;
+               // ¥Õ¥©¡¼¥à¤«¤éÍ׵ᤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó̾¤ò¼èÆÀ¤¹¤ë
+               $form_action_name = $this->_getActionName_Form();
+               $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 = "";
                }
 
-               return $action_obj['form_name'];
-       }
+               // ¥Õ¥©¡¼¥à¤«¤é¤Î»ØÄ̵꤬¤¤¾ì¹ç¤Ï¥¨¥ó¥È¥ê¥Ý¥¤¥ó¥È¤Ë»ØÄꤵ¤ì¤¿¥Ç¥Õ¥©¥ë¥ÈÃͤòÍøÍѤ¹¤ë
+               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} == '*') {
+                               $tmp = substr($tmp, 0, -1);
+                       }
+                       $this->logger->log(LOG_DEBUG, '-> default_action_name[%s]', $tmp);
+                       $action_name = $tmp;
+               } else {
+                       $action_name = $form_action_name;
+               }
 
-       /**
-        *      »ØÄꤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó¤Î¥¯¥é¥¹Ì¾¤òÊÖ¤¹(¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®¤Ï¹Ô¤ï¤Ê¤¤)
-        *
-        *      @access public
-        *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó¤Î̾¾Î
-        *      @return string  ¥¢¥¯¥·¥ç¥ó¤Î¥¯¥é¥¹Ì¾
-        */
-       function getActionClassName($action_name)
-       {
-               $action_obj =& $this->_getAction($action_name);
-               if ($action_obj == null) {
-                       return null;
+               // ¥¨¥ó¥È¥ê¥Ý¥¤¥ó¥È¤ËÇÛÎ󤬻ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï»ØÄê°Ê³°¤Î¥¢¥¯¥·¥ç¥ó̾¤ÏµñÈݤ¹¤ë
+               if (is_array($default_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} == '*') {
+                                       $tmp = substr($tmp, 0, -1);
+                               }
+                               $this->logger->log(LOG_DEBUG, '-> fallback_action_name[%s]', $tmp);
+                               $action_name = $tmp;
+                       }
                }
 
-               return $action_obj['class_name'];
+               $this->logger->log(LOG_DEBUG, '<<< action_name[%s] >>>', $action_name);
+
+               return $action_name;
        }
 
        /**
-        *      »ØÄꤵ¤ì¤¿Á«°Ü̾¤ËÂбþ¤¹¤ë¥Ó¥å¡¼¥¯¥é¥¹Ì¾¤òÊÖ¤¹(¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®¤Ï¹Ô¤ï¤Ê¤¤)
+        *      ¥Õ¥©¡¼¥à¤Ë¤è¤êÍ׵ᤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó̾¤òÊÖ¤¹
         *
-        *      @access public
-        *      @param  string  $forward_name   Á«°ÜÀè¤Î̾¾Î
-        *      @return string  view class¤Î¥¯¥é¥¹Ì¾
+        *      ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎÀ­¼Á¤Ë±þ¤¸¤Æ¤³¤Î¥á¥½¥Ã¥É¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Æ²¼¤µ¤¤¡£
+        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï"action_"¤Ç»Ï¤Þ¤ë¥Õ¥©¡¼¥àÃͤÎ"action_"¤ÎÉôʬ¤ò½ü¤¤¤¿¤â¤Î
+        *      ("action_sample"¤Ê¤é"sample")¤¬¥¢¥¯¥·¥ç¥ó̾¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹
+        *
+        *      @access protected
+        *      @return string  ¥Õ¥©¡¼¥à¤Ë¤è¤êÍ׵ᤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó̾
         */
-       function getViewClassName($forward_name)
+       function _getActionName_Form()
        {
-               if ($forward_name == null) {
+               if (isset($_SERVER['REQUEST_METHOD']) == false) {
                        return null;
                }
 
-               if (isset($this->forward[$forward_name])) {
-                       $forward_obj = $this->forward[$forward_name];
+               if (strcasecmp($_SERVER['REQUEST_METHOD'], 'post') == 0) {
+                       $http_vars =& $_POST;
                } else {
-                       $forward_obj = array();
+                       $http_vars =& $_GET;
                }
 
-               if (isset($forward_obj['view_name'])) {
-                       $class_name = $forward_obj['view_name'];
-                       if (class_exists($class_name)) {
-                               return $class_name;
+               // ¥Õ¥©¡¼¥àÃͤ«¤é¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥¢¥¯¥·¥ç¥ó̾¤ò¼èÆÀ¤¹¤ë
+               $action_name = $sub_action_name = null;
+               foreach ($http_vars as $name => $value) {
+                       if ($value == "" || strncmp($name, 'action_', 7) != 0) {
+                               continue;
                        }
-               } else {
-                       $class_name = null;
-               }
 
-               // view¤Î¥¤¥ó¥¯¥ë¡¼¥É
-               $this->_includeViewScript($forward_obj, $forward_name);
+                       $tmp = substr($name, 7);
 
-               if (is_null($class_name) == false && class_exists($class_name)) {
-                       return $class_name;
-               } else if (is_null($class_name) == false) {
-                       $this->logger->log(LOG_WARNING, 'stated view class is not defined [%s] -> try default', $class_name);
-               }
+                       // type="image"Âбþ
+                       if (preg_match('/_x$/', $name) || preg_match('/_y$/', $name)) {
+                               $tmp = substr($tmp, 0, strlen($tmp)-2);
+                       }
 
-               $class_name = $this->getDefaultViewClass($forward_name);
-               if (class_exists($class_name)) {
-                       return $class_name;
-               } else {
-                       $this->logger->log(LOG_DEBUG, 'view class is not defined for [%s] -> use default [%s]', $forward_name, 'Ethna_ViewClass');
-                       return 'Ethna_ViewClass';
+                       // value="dummy"¤È¤Ê¤Ã¤Æ¤¤¤ë¤â¤Î¤ÏÍ¥ÀèÅÙ¤ò²¼¤²¤ë
+                       if ($value == "dummy") {
+                               $sub_action_name = $tmp;
+                       } else {
+                               $action_name = $tmp;
+                       }
                }
+               if ($action_name == null) {
+                       $action_name = $sub_action_name;
+               }
+
+               return $action_name;
        }
 
        /**
-        *      ¥¢¥¯¥·¥ç¥ó¤ËÂбþ¤¹¤ë¥Õ¥©¡¼¥à¥¯¥é¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥¯¥é¥¹Ì¾¤òÊÖ¤¹
-        *
-        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï[¥×¥í¥¸¥§¥¯¥ÈID]_Form_[¥¢¥¯¥·¥ç¥ó̾]¤È¤Ê¤ë¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¥é¥¤¥É¤¹¤ë
+        *      ¥Õ¥©¡¼¥à¤Ë¤è¤êÍ׵ᤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó̾¤ËÂбþ¤¹¤ëÄêµÁ¤òÊÖ¤¹
         *
-        *      @access public
+        *      @access private
         *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó̾
-        *      @param  bool    $fallback               ¥¯¥é¥¤¥¢¥ó¥È¼ïÊ̤ˤè¤ëfallback on/off
-        *      @return string  ¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à̾
+        *      @return array   ¥¢¥¯¥·¥ç¥óÄêµÁ
         */
-       function getDefaultFormClass($action_name, $fallback = true)
+       function &_getAction($action_name)
        {
-               $postfix = preg_replace('/_(.)/e', "strtoupper('\$1')", ucfirst($action_name));
+               if ($this->client_type == CLIENT_TYPE_SOAP) {
+                       $action =& $this->soap_action;
+               } else {
+                       $action =& $this->action;
+               }
 
-               $r = null;
-               if ($this->getClientType() == CLIENT_TYPE_SOAP) {
-                       $r = sprintf("%s_SOAPForm_%s", $this->getAppId(), $postfix);
-               } else if ($this->getClientType() == CLIENT_TYPE_MOBILE_AU) {
-                       $tmp = sprintf("%s_MobileAUForm_%s", $this->getAppId(), $postfix);
-                       if ($fallback == false || class_exists($tmp)) {
-                               $r = $tmp;
+               $action_obj = array();
+               if (isset($action[$action_name])) {
+                       $action_obj = $action[$action_name];
+                       if (isset($action_obj['inspect']) && $action_obj['inspect']) {
+                               return $action_obj;
                        }
+               } else {
+                       $this->logger->log(LOG_DEBUG, "action [%s] is not defined -> try default", $action_name);
                }
 
-               if ($r == null) {
-                       $r = sprintf("%s_Form_%s", $this->getAppId(), $postfix);
+               // ¥¢¥¯¥·¥ç¥ó¥¹¥¯¥ê¥×¥È¤Î¥¤¥ó¥¯¥ë¡¼¥É
+               $this->_includeActionScript($action_obj, $action_name);
+
+               // ¾ÊάÃͤÎÊäÀµ
+               if (isset($action_obj['class_name']) == false) {
+                       $action_obj['class_name'] = $this->getDefaultActionClass($action_name);
                }
-               $this->logger->log(LOG_DEBUG, "default action class [%s]", $r);
-               return $r;
+
+               if (isset($action_obj['form_name']) == false) {
+                       $action_obj['form_name'] = $this->getDefaultFormClass($action_name);
+               } 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']);
+               }
+
+               // É¬Í×¾ò·ï¤Î³Îǧ
+               if (class_exists($action_obj['class_name']) == false) {
+                       $this->logger->log(LOG_WARNING, 'action class is not defined [%s]', $action_obj['class_name']);
+                       return null;
+               }
+               if (class_exists($action_obj['form_name']) == false) {
+                       // ¥Õ¥©¡¼¥à¥¯¥é¥¹¤Ï̤ÄêµÁ¤Ç¤âÎɤ¤
+                       $this->logger->log(LOG_DEBUG, 'form class is not defined [%s] -> falling back to default [%s]', $action_obj['form_name'], 'Ethna_ActionForm');
+                       $action_obj['form_name'] = 'Ethna_ActionForm';
+               }
+
+               $action_obj['inspect'] = true;
+               $action[$action_name] = $action_obj;
+               return $action[$action_name];
        }
 
        /**
-        *      ¥¢¥¯¥·¥ç¥ó¤ËÂбþ¤¹¤ë¥Õ¥©¡¼¥à¥Ñ¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥Ñ¥¹Ì¾¤òÊÖ¤¹
+        *      ¥¢¥¯¥·¥ç¥ó̾¤È¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¤«¤é¤ÎÌá¤êÃͤ˴ð¤Å¤¤¤ÆÁ«°ÜÀè¤ò·èÄꤹ¤ë
         *
-        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï_getDefaultActionPath()¤ÈƱ¤¸·ë²Ì¤òÊÖ¤¹(1¥Õ¥¡¥¤¥ë¤Ë
-        *      ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¤È¥Õ¥©¡¼¥à¥¯¥é¥¹¤¬µ­½Ò¤µ¤ì¤ë)¤Î¤Ç¡¢¹¥¤ß¤Ë±þ¤¸¤Æ
-        *      ¥ª¡¼¥Ð¡¼¥é¥¤¥É¤¹¤ë
+        *      @access protected
+        *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó̾
+        *      @param  string  $retval                 ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¤«¤é¤ÎÌá¤êÃÍ
+        *      @return string  Á«°ÜÀè
+        */
+       function _sortForward($action_name, $retval)
+       {
+               return $retval;
+       }
+
+       /**
+        *      ¥Õ¥£¥ë¥¿¡¼¥Á¥§¥¤¥ó¤òÀ¸À®¤¹¤ë
+        *
+        *      @access private
+        */
+       function _createFilterChain()
+       {
+               $this->filter_chain = array();
+               foreach ($this->filter as $filter) {
+                       $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);
+                       }
+               }
+       }
+
+       /**
+        *      ¥¢¥¯¥·¥ç¥ó̾¤¬¼Â¹Ôµö²Ä¤µ¤ì¤Æ¤¤¤ë¤â¤Î¤«¤É¤¦¤«¤òÊÖ¤¹
+        *
+        *      @access private
+        *      @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) {
+                               return true;
+                       } else if ($name{strlen($name)-1} == '*') {
+                               if (strncmp($action_name, substr($name, 0, -1), strlen($name)-1) == 0) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       /**
+        *      »ØÄꤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó¤Î¥Õ¥©¡¼¥à¥¯¥é¥¹Ì¾¤òÊÖ¤¹(¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®¤Ï¹Ô¤ï¤Ê¤¤)
         *
         *      @access public
         *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó̾
-        *      @param  bool    $fallback               ¥¯¥é¥¤¥¢¥ó¥È¼ïÊ̤ˤè¤ëfallback on/off
-        *      @return string  form class¤¬ÄêµÁ¤µ¤ì¤ë¥¹¥¯¥ê¥×¥È¤Î¥Ñ¥¹Ì¾
+        *      @return string  ¥¢¥¯¥·¥ç¥ó¤Î¥Õ¥©¡¼¥à¥¯¥é¥¹Ì¾
         */
-       function getDefaultFormPath($action_name, $fallback = true)
+       function getActionFormName($action_name)
        {
-               return $this->getDefaultActionPath($action_name, $fallback);
+               $action_obj =& $this->_getAction($action_name);
+               if (is_null($action_obj)) {
+                       return null;
+               }
+
+               return $action_obj['form_name'];
        }
 
        /**
-        *      ¥¢¥¯¥·¥ç¥ó¤ËÂбþ¤¹¤ë¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥¯¥é¥¹Ì¾¤òÊÖ¤¹
+        *      ¥¢¥¯¥·¥ç¥ó¤ËÂбþ¤¹¤ë¥Õ¥©¡¼¥à¥¯¥é¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥¯¥é¥¹Ì¾¤òÊÖ¤¹
         *
-        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï[¥×¥í¥¸¥§¥¯¥ÈID]_Action_[¥¢¥¯¥·¥ç¥ó̾]¤È¤Ê¤ë¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¥é¥¤¥É¤¹¤ë
+        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï[¥×¥í¥¸¥§¥¯¥ÈID]_Form_[¥¢¥¯¥·¥ç¥ó̾]¤È¤Ê¤ë¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¥é¥¤¥É¤¹¤ë
         *
         *      @access public
         *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó̾
         *      @param  bool    $fallback               ¥¯¥é¥¤¥¢¥ó¥È¼ïÊ̤ˤè¤ëfallback on/off
-        *      @return string  ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹̾
+        *      @return string  ¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à̾
         */
-       function getDefaultActionClass($action_name, $fallback = true)
+       function getDefaultFormClass($action_name, $fallback = true)
        {
                $postfix = preg_replace('/_(.)/e', "strtoupper('\$1')", ucfirst($action_name));
 
                $r = null;
                if ($this->getClientType() == CLIENT_TYPE_SOAP) {
-                       $r = sprintf("%s_SOAPAction_%s", $this->getAppId(), $postfix);
+                       $r = sprintf("%s_SOAPForm_%s", $this->getAppId(), $postfix);
                } else if ($this->getClientType() == CLIENT_TYPE_MOBILE_AU) {
-                       $tmp = sprintf("%s_MobileAUAction_%s", $this->getAppId(), $postfix);
+                       $tmp = sprintf("%s_MobileAUForm_%s", $this->getAppId(), $postfix);
                        if ($fallback == false || class_exists($tmp)) {
                                $r = $tmp;
                        }
                }
 
                if ($r == null) {
-                       $r = sprintf("%s_Action_%s", $this->getAppId(), $postfix);
+                       $r = sprintf("%s_Form_%s", $this->getAppId(), $postfix);
                }
                $this->logger->log(LOG_DEBUG, "default action class [%s]", $r);
                return $r;
        }
 
        /**
-        *      ¥¢¥¯¥·¥ç¥ó¤ËÂбþ¤¹¤ë¥¢¥¯¥·¥ç¥ó¥Ñ¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥Ñ¥¹Ì¾¤òÊÖ¤¹
+        *      getDefaultFormClass()¤Ç¼èÆÀ¤·¤¿¥¯¥é¥¹Ì¾¤«¤é¥¢¥¯¥·¥ç¥ó̾¤ò¼èÆÀ¤¹¤ë
         *
-        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï"foo_bar" -> "/Foo/Bar.php"¤È¤Ê¤ë¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¡¼¥é¥¤¥É¤¹¤ë
+        *      getDefaultFormClass()¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤¿¾ì¹ç¡¢¤³¤Á¤é¤â¹ç¤ï¤»¤Æ¥ª¡¼¥Ð¡¼¥é¥¤¥É
+        *      ¤¹¤ë¤³¤È¤ò¿ä¾©(ɬ¿Ü¤Ç¤Ï¤Ê¤¤)
+        *
+        *      @access public
+        *      @param  string  $class_name             ¥Õ¥©¡¼¥à¥¯¥é¥¹Ì¾
+        *      @return string  ¥¢¥¯¥·¥ç¥ó̾
+        */
+       function actionFormToName($class_name)
+       {
+               $prefix = sprintf("%s_Form_", $this->getAppId());
+               if (preg_match("/$prefix(.*)/", $class_name, $match) == 0) {
+                       // ÉÔÌÀ¤Ê¥¯¥é¥¹Ì¾
+                       return null;
+               }
+               $target = $match[1];
+
+               $action_name = substr(preg_replace('/([A-Z])/e', "'_' . strtolower('\$1')", $target), 1);
+
+               return $action_name;
+       }
+
+       /**
+        *      ¥¢¥¯¥·¥ç¥ó¤ËÂбþ¤¹¤ë¥Õ¥©¡¼¥à¥Ñ¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥Ñ¥¹Ì¾¤òÊÖ¤¹
+        *
+        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï_getDefaultActionPath()¤ÈƱ¤¸·ë²Ì¤òÊÖ¤¹(1¥Õ¥¡¥¤¥ë¤Ë
+        *      ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¤È¥Õ¥©¡¼¥à¥¯¥é¥¹¤¬µ­½Ò¤µ¤ì¤ë)¤Î¤Ç¡¢¹¥¤ß¤Ë±þ¤¸¤Æ
+        *      ¥ª¡¼¥Ð¡¼¥é¥¤¥É¤¹¤ë
         *
         *      @access public
         *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó̾
         *      @param  bool    $fallback               ¥¯¥é¥¤¥¢¥ó¥È¼ïÊ̤ˤè¤ëfallback on/off
-        *      @return string  ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¤¬ÄêµÁ¤µ¤ì¤ë¥¹¥¯¥ê¥×¥È¤Î¥Ñ¥¹Ì¾
+        *      @return string  form class¤¬ÄêµÁ¤µ¤ì¤ë¥¹¥¯¥ê¥×¥È¤Î¥Ñ¥¹Ì¾
         */
-       function getDefaultActionPath($action_name, $fallback = true)
+       function getDefaultFormPath($action_name, $fallback = true)
        {
-               $default_path = preg_replace('/_(.)/e', "'/' . strtoupper('\$1')", ucfirst($action_name)) . '.' . $this->getExt('php');
-               $action_dir = $this->getActiondir();
-
-               if ($this->getClientType() == CLIENT_TYPE_SOAP) {
-                       $r = 'SOAP/' . $default_path;
-               } else if ($this->getClientType() == CLIENT_TYPE_MOBILE_AU) {
-                       $r = 'MobileAU/' . $default_path;
-               } else {
-                       $r = $default_path;
-               }
+               return $this->getDefaultActionPath($action_name, $fallback);
+       }
 
-               if ($fallback && file_exists($action_dir . $r) == false && $r != $default_path) {
-                       $this->logger->log(LOG_DEBUG, 'client_type specific file not found [%s] -> try defualt', $r);
-                       $r = $default_path;
+       /**
+        *      »ØÄꤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó¤Î¥¯¥é¥¹Ì¾¤òÊÖ¤¹(¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®¤Ï¹Ô¤ï¤Ê¤¤)
+        *
+        *      @access public
+        *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó¤Î̾¾Î
+        *      @return string  ¥¢¥¯¥·¥ç¥ó¤Î¥¯¥é¥¹Ì¾
+        */
+       function getActionClassName($action_name)
+       {
+               $action_obj =& $this->_getAction($action_name);
+               if ($action_obj == null) {
+                       return null;
                }
 
-               $this->logger->log(LOG_DEBUG, "default action path [%s]", $r);
-               return $r;
+               return $action_obj['class_name'];
        }
 
        /**
-        *      Á«°Ü̾¤ËÂбþ¤¹¤ë¥Ó¥å¡¼¥¯¥é¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥¯¥é¥¹Ì¾¤òÊÖ¤¹
+        *      ¥¢¥¯¥·¥ç¥ó¤ËÂбþ¤¹¤ë¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥¯¥é¥¹Ì¾¤òÊÖ¤¹
         *
-        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï[¥×¥í¥¸¥§¥¯¥ÈID]_View_[Á«°Ü̾]¤È¤Ê¤ë¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¥é¥¤¥É¤¹¤ë
+        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï[¥×¥í¥¸¥§¥¯¥ÈID]_Action_[¥¢¥¯¥·¥ç¥ó̾]¤È¤Ê¤ë¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¥é¥¤¥É¤¹¤ë
         *
         *      @access public
-        *      @param  string  $forward_name   forward̾
+        *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó̾
         *      @param  bool    $fallback               ¥¯¥é¥¤¥¢¥ó¥È¼ïÊ̤ˤè¤ëfallback on/off
-        *      @return string  view class¥¯¥é¥¹Ì¾
+        *      @return string  ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹Ì¾
         */
-       function getDefaultViewClass($forward_name, $fallback = true)
+       function getDefaultActionClass($action_name, $fallback = true)
        {
-               $postfix = preg_replace('/_(.)/e', "strtoupper('\$1')", ucfirst($forward_name));
+               $postfix = preg_replace('/_(.)/e', "strtoupper('\$1')", ucfirst($action_name));
 
                $r = null;
-               if ($this->getClientType() == CLIENT_TYPE_MOBILE_AU) {
-                       $tmp = sprintf("%s_MobileAUView_%s", $this->getAppId(), $postfix);
+               if ($this->getClientType() == CLIENT_TYPE_SOAP) {
+                       $r = sprintf("%s_SOAPAction_%s", $this->getAppId(), $postfix);
+               } else if ($this->getClientType() == CLIENT_TYPE_MOBILE_AU) {
+                       $tmp = sprintf("%s_MobileAUAction_%s", $this->getAppId(), $postfix);
                        if ($fallback == false || class_exists($tmp)) {
                                $r = $tmp;
                        }
                }
 
                if ($r == null) {
-                       $r = sprintf("%s_View_%s", $this->getAppId(), $postfix);
+                       $r = sprintf("%s_Action_%s", $this->getAppId(), $postfix);
                }
-               $this->logger->log(LOG_DEBUG, "default view class [%s]", $r);
+               $this->logger->log(LOG_DEBUG, "default action class [%s]", $r);
                return $r;
        }
 
        /**
-        *      Á«°Ü̾¤ËÂбþ¤¹¤ë¥Ó¥å¡¼¥Ñ¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥Ñ¥¹Ì¾¤òÊÖ¤¹
+        *      getDefaultActionClass()¤Ç¼èÆÀ¤·¤¿¥¯¥é¥¹Ì¾¤«¤é¥¢¥¯¥·¥ç¥ó̾¤ò¼èÆÀ¤¹¤ë
         *
-        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï"foo_bar" -> "/Foo/Bar.php"¤È¤Ê¤ë¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¡¼¥é¥¤¥É¤¹¤ë
+        *      getDefaultActionClass()¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤¿¾ì¹ç¡¢¤³¤Á¤é¤â¹ç¤ï¤»¤Æ¥ª¡¼¥Ð¡¼¥é¥¤¥É
+        *      ¤¹¤ë¤³¤È¤ò¿ä¾©(ɬ¿Ü¤Ç¤Ï¤Ê¤¤)
         *
         *      @access public
-        *      @param  string  $forward_name   forward̾
-        *      @param  bool    $fallback               ¥¯¥é¥¤¥¢¥ó¥È¼ïÊ̤ˤè¤ëfallback on/off
-        *      @return string  view class¤¬ÄêµÁ¤µ¤ì¤ë¥¹¥¯¥ê¥×¥È¤Î¥Ñ¥¹Ì¾
+        *      @param  string  $class_name             ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹Ì¾
+        *      @return string  ¥¢¥¯¥·¥ç¥ó̾
         */
-       function getDefaultViewPath($forward_name, $fallback = true)
+       function actionClassToName($class_name)
        {
-               $default_path = preg_replace('/_(.)/e', "'/' . strtoupper('\$1')", ucfirst($forward_name)) . '.' . $this->getExt('php');
-               $view_dir = $this->getViewdir();
-
-               if ($this->getClientType() == CLIENT_TYPE_MOBILE_AU) {
-                       $r = 'MobileAU/' . $r;
-               } else {
-                       $r = $default_path;
+               $prefix = sprintf("%s_Action_", $this->getAppId());
+               if (preg_match("/$prefix(.*)/", $class_name, $match) == 0) {
+                       // ÉÔÌÀ¤Ê¥¯¥é¥¹Ì¾
+                       return null;
                }
+               $target = $match[1];
 
-               if ($fallback && file_exists($view_dir . $r) == false && $r != $default_path) {
-                       $this->logger->log(LOG_DEBUG, 'client_type specific file not found [%s] -> try defualt', $r);
-                       $r = $default_path;
-               }
+               $action_name = substr(preg_replace('/([A-Z])/e', "'_' . strtolower('\$1')", $target), 1);
 
-               $this->logger->log(LOG_DEBUG, "default view path [%s]", $r);
-               return $r;
+               return $action_name;
        }
 
        /**
-        *      ¼Â¹Ô¤¹¤ë¥¢¥¯¥·¥ç¥ó̾¤òÊÖ¤¹
+        *      ¥¢¥¯¥·¥ç¥ó¤ËÂбþ¤¹¤ë¥¢¥¯¥·¥ç¥ó¥Ñ¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥Ñ¥¹Ì¾¤òÊÖ¤¹
         *
-        *      @access private
-        *      @param  mixed   $default_action_name    »ØÄê¤Î¥¢¥¯¥·¥ç¥ó̾
-        *      @return string  ¼Â¹Ô¤¹¤ë¥¢¥¯¥·¥ç¥ó̾
+        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï"foo_bar" -> "/Foo/Bar.php"¤È¤Ê¤ë¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¡¼¥é¥¤¥É¤¹¤ë
+        *
+        *      @access public
+        *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó̾
+        *      @param  bool    $fallback               ¥¯¥é¥¤¥¢¥ó¥È¼ïÊ̤ˤè¤ëfallback on/off
+        *      @return string  ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¤¬ÄêµÁ¤µ¤ì¤ë¥¹¥¯¥ê¥×¥È¤Î¥Ñ¥¹Ì¾
         */
-       function _getActionName($default_action_name, $fallback_action_name)
+       function getDefaultActionPath($action_name, $fallback = true)
        {
-               // ¥Õ¥©¡¼¥à¤«¤éÍ׵ᤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó̾¤ò¼èÆÀ¤¹¤ë
-               $form_action_name = $this->_getActionName_Form();
-               $form_action_name = preg_replace('/[^a-z0-9\-_]+/i', '', $form_action_name);
-               $this->logger->log(LOG_DEBUG, 'form_action_name[%s]', $form_action_name);
+               $default_path = preg_replace('/_(.)/e', "'/' . strtoupper('\$1')", ucfirst($action_name)) . '.' . $this->getExt('php');
+               $action_dir = $this->getActiondir();
 
-               // ¥Õ¥©¡¼¥à¤«¤é¤Î»ØÄ̵꤬¤¤¾ì¹ç¤Ï¥¨¥ó¥È¥ê¥Ý¥¤¥ó¥È¤Ë»ØÄꤵ¤ì¤¿¥Ç¥Õ¥©¥ë¥ÈÃͤòÍøÍѤ¹¤ë
-               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} == '*') {
-                               $tmp = substr($tmp, 0, -1);
-                       }
-                       $this->logger->log(LOG_DEBUG, '-> default_action_name[%s]', $tmp);
-                       $action_name = $tmp;
+               if ($this->getClientType() == CLIENT_TYPE_SOAP) {
+                       $r = 'SOAP/' . $default_path;
+               } else if ($this->getClientType() == CLIENT_TYPE_MOBILE_AU) {
+                       $r = 'MobileAU/' . $default_path;
                } else {
-                       $action_name = $form_action_name;
+                       $r = $default_path;
                }
 
-               // ¥¨¥ó¥È¥ê¥Ý¥¤¥ó¥È¤ËÇÛÎ󤬻ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï»ØÄê°Ê³°¤Î¥¢¥¯¥·¥ç¥ó̾¤ÏµñÈݤ¹¤ë
-               if (is_array($default_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} == '*') {
-                                       $tmp = substr($tmp, 0, -1);
-                               }
-                               $this->logger->log(LOG_DEBUG, '-> fallback_action_name[%s]', $tmp);
-                               $action_name = $tmp;
-                       }
+               if ($fallback && file_exists($action_dir . $r) == false && $r != $default_path) {
+                       $this->logger->log(LOG_DEBUG, 'client_type specific file not found [%s] -> try defualt', $r);
+                       $r = $default_path;
                }
 
-               $this->logger->log(LOG_DEBUG, '<<< action_name[%s] >>>', $action_name);
-
-               return $action_name;
+               $this->logger->log(LOG_DEBUG, "default action path [%s]", $r);
+               return $r;
        }
 
        /**
-        *      ¥Õ¥©¡¼¥à¤Ë¤è¤êÍ׵ᤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó̾¤òÊÖ¤¹
-        *
-        *      ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎÀ­¼Á¤Ë±þ¤¸¤Æ¤³¤Î¥á¥½¥Ã¥É¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Æ²¼¤µ¤¤¡£
-        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï"action_"¤Ç»Ï¤Þ¤ë¥Õ¥©¡¼¥àÃͤÎ"action_"¤ÎÉôʬ¤ò½ü¤¤¤¿¤â¤Î
-        *      ("action_sample"¤Ê¤é"sample")¤¬¥¢¥¯¥·¥ç¥ó̾¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹
+        *      »ØÄꤵ¤ì¤¿Á«°Ü̾¤ËÂбþ¤¹¤ë¥Ó¥å¡¼¥¯¥é¥¹Ì¾¤òÊÖ¤¹(¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®¤Ï¹Ô¤ï¤Ê¤¤)
         *
-        *      @access protected
-        *      @return string  ¥Õ¥©¡¼¥à¤Ë¤è¤êÍ׵ᤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó̾
+        *      @access public
+        *      @param  string  $forward_name   Á«°ÜÀè¤Î̾¾Î
+        *      @return string  view class¤Î¥¯¥é¥¹Ì¾
         */
-       function _getActionName_Form()
+       function getViewClassName($forward_name)
        {
-               if (isset($_SERVER['REQUEST_METHOD']) == false) {
+               if ($forward_name == null) {
                        return null;
                }
 
-               if (strcasecmp($_SERVER['REQUEST_METHOD'], 'post') == 0) {
-                       $http_vars =& $_POST;
+               if (isset($this->forward[$forward_name])) {
+                       $forward_obj = $this->forward[$forward_name];
                } else {
-                       $http_vars =& $_GET;
+                       $forward_obj = array();
                }
 
-               // ¥Õ¥©¡¼¥àÃͤ«¤é¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥¢¥¯¥·¥ç¥ó̾¤ò¼èÆÀ¤¹¤ë
-               $action_name = $sub_action_name = null;
-               foreach ($http_vars as $name => $value) {
-                       if ($value == "" || strncmp($name, 'action_', 7) != 0) {
-                               continue;
+               if (isset($forward_obj['view_name'])) {
+                       $class_name = $forward_obj['view_name'];
+                       if (class_exists($class_name)) {
+                               return $class_name;
                        }
+               } else {
+                       $class_name = null;
+               }
 
-                       $tmp = substr($name, 7);
-
-                       // type="image"Âбþ
-                       if (preg_match('/_x$/', $name) || preg_match('/_y$/', $name)) {
-                               $tmp = substr($tmp, 0, strlen($tmp)-2);
-                       }
+               // view¤Î¥¤¥ó¥¯¥ë¡¼¥É
+               $this->_includeViewScript($forward_obj, $forward_name);
 
-                       // value="dummy"¤È¤Ê¤Ã¤Æ¤¤¤ë¤â¤Î¤ÏÍ¥ÀèÅÙ¤ò²¼¤²¤ë
-                       if ($value == "dummy") {
-                               $sub_action_name = $tmp;
-                       } else {
-                               $action_name = $tmp;
-                       }
-               }
-               if ($action_name == null) {
-                       $action_name = $sub_action_name;
+               if (is_null($class_name) == false && class_exists($class_name)) {
+                       return $class_name;
+               } else if (is_null($class_name) == false) {
+                       $this->logger->log(LOG_WARNING, 'stated view class is not defined [%s] -> try default', $class_name);
                }
 
-               return $action_name;
+               $class_name = $this->getDefaultViewClass($forward_name);
+               if (class_exists($class_name)) {
+                       return $class_name;
+               } else {
+                       $this->logger->log(LOG_DEBUG, 'view class is not defined for [%s] -> use default [%s]', $forward_name, 'Ethna_ViewClass');
+                       return 'Ethna_ViewClass';
+               }
        }
 
        /**
-        *      ¥Õ¥©¡¼¥à¤Ë¤è¤êÍ׵ᤵ¤ì¤¿¥¢¥¯¥·¥ç¥ó̾¤ËÂбþ¤¹¤ëÄêµÁ¤òÊÖ¤¹
+        *      Á«°Ü̾¤ËÂбþ¤¹¤ë¥Ó¥å¡¼¥¯¥é¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥¯¥é¥¹Ì¾¤òÊÖ¤¹
         *
-        *      @access private
-        *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó̾
-        *      @return array   ¥¢¥¯¥·¥ç¥óÄêµÁ
+        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï[¥×¥í¥¸¥§¥¯¥ÈID]_View_[Á«°Ü̾]¤È¤Ê¤ë¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¥é¥¤¥É¤¹¤ë
+        *
+        *      @access public
+        *      @param  string  $forward_name   forward̾
+        *      @param  bool    $fallback               ¥¯¥é¥¤¥¢¥ó¥È¼ïÊ̤ˤè¤ëfallback on/off
+        *      @return string  view class¥¯¥é¥¹Ì¾
         */
-       function &_getAction($action_name)
+       function getDefaultViewClass($forward_name, $fallback = true)
        {
-               if ($this->client_type == CLIENT_TYPE_SOAP) {
-                       $action =& $this->soap_action;
-               } else {
-                       $action =& $this->action;
-               }
-
-               $action_obj = array();
-               if (isset($action[$action_name])) {
-                       $action_obj = $action[$action_name];
-                       if (isset($action_obj['inspect']) && $action_obj['inspect']) {
-                               return $action_obj;
-                       }
-               } else {
-                       $this->logger->log(LOG_DEBUG, "action [%s] is not defined -> try default", $action_name);
-               }
+               $postfix = preg_replace('/_(.)/e', "strtoupper('\$1')", ucfirst($forward_name));
 
-               // ¥¢¥¯¥·¥ç¥ó¥¹¥¯¥ê¥×¥È¤Î¥¤¥ó¥¯¥ë¡¼¥É
-               $this->_includeActionScript($action_obj, $action_name);
+               $r = null;
+               if ($this->getClientType() == CLIENT_TYPE_MOBILE_AU) {
+                       $tmp = sprintf("%s_MobileAUView_%s", $this->getAppId(), $postfix);
+                       if ($fallback == false || class_exists($tmp)) {
+                               $r = $tmp;
+                       }
+               }
 
-               // ¾ÊάÃͤÎÊäÀµ
-               if (isset($action_obj['class_name']) == false) {
-                       $action_obj['class_name'] = $this->getDefaultActionClass($action_name);
+               if ($r == null) {
+                       $r = sprintf("%s_View_%s", $this->getAppId(), $postfix);
                }
+               $this->logger->log(LOG_DEBUG, "default view class [%s]", $r);
+               return $r;
+       }
 
-               if (isset($action_obj['form_name']) == false) {
-                       $action_obj['form_name'] = $this->getDefaultFormClass($action_name);
+       /**
+        *      Á«°Ü̾¤ËÂбþ¤¹¤ë¥Ó¥å¡¼¥Ñ¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥Ñ¥¹Ì¾¤òÊÖ¤¹
+        *
+        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï"foo_bar" -> "/Foo/Bar.php"¤È¤Ê¤ë¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¡¼¥é¥¤¥É¤¹¤ë
+        *
+        *      @access public
+        *      @param  string  $forward_name   forward̾
+        *      @param  bool    $fallback               ¥¯¥é¥¤¥¢¥ó¥È¼ïÊ̤ˤè¤ëfallback on/off
+        *      @return string  view class¤¬ÄêµÁ¤µ¤ì¤ë¥¹¥¯¥ê¥×¥È¤Î¥Ñ¥¹Ì¾
+        */
+       function getDefaultViewPath($forward_name, $fallback = true)
+       {
+               $default_path = preg_replace('/_(.)/e', "'/' . strtoupper('\$1')", ucfirst($forward_name)) . '.' . $this->getExt('php');
+               $view_dir = $this->getViewdir();
+
+               if ($this->getClientType() == CLIENT_TYPE_MOBILE_AU) {
+                       $r = 'MobileAU/' . $r;
                } else {
-                       // ÌÀ¼¨»ØÄꤵ¤ì¤¿¥Õ¥©¡¼¥à¥¯¥é¥¹¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï·Ù¹ð
-                       $this->logger->log(LOG_WARNING, 'stated form class is not defined [%s]', $action_obj['form_name']);
+                       $r = $default_path;
                }
 
-               // É¬Í×¾ò·ï¤Î³Îǧ
-               if (class_exists($action_obj['class_name']) == false) {
-                       $this->logger->log(LOG_WARNING, 'action class is not defined [%s]', $action_obj['class_name']);
-                       return null;
-               }
-               if (class_exists($action_obj['form_name']) == false) {
-                       // ¥Õ¥©¡¼¥à¥¯¥é¥¹¤Ï̤ÄêµÁ¤Ç¤âÎɤ¤
-                       $this->logger->log(LOG_DEBUG, 'form class is not defined [%s] -> falling back to default [%s]', $action_obj['form_name'], 'Ethna_ActionForm');
-                       $action_obj['form_name'] = 'Ethna_ActionForm';
+               if ($fallback && file_exists($view_dir . $r) == false && $r != $default_path) {
+                       $this->logger->log(LOG_DEBUG, 'client_type specific file not found [%s] -> try defualt', $r);
+                       $r = $default_path;
                }
 
-               $action_obj['inspect'] = true;
-               $action[$action_name] = $action_obj;
-               return $action[$action_name];
+               $this->logger->log(LOG_DEBUG, "default view path [%s]", $r);
+               return $r;
        }
 
        /**
-        *      ¥¢¥¯¥·¥ç¥ó̾¤È¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¤«¤é¤ÎÌá¤êÃͤ˴ð¤Å¤¤¤ÆÁ«°ÜÀè¤ò·èÄꤹ¤ë
+        *      Á«°Ü̾¤ËÂбþ¤¹¤ë¥Æ¥ó¥×¥ì¡¼¥È¥Ñ¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥Ñ¥¹Ì¾¤òÊÖ¤¹
         *
-        *      @access protected
-        *      @param  string  $action_name    ¥¢¥¯¥·¥ç¥ó̾
-        *      @param  string  $retval                 ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¤«¤é¤ÎÌá¤êÃÍ
-        *      @return string  Á«°ÜÀè
+        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï"foo_bar"¤È¤¤¤¦forward̾¤¬"foo/bar" + ¥Æ¥ó¥×¥ì¡¼¥È³ÈÄ¥»Ò¤È¤Ê¤ë
+        *      ¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¥é¥¤¥É¤¹¤ë
+        *
+        *      @access public
+        *      @param  string  $forward_name   forward̾
+        *      @return string  forward¥Ñ¥¹Ì¾
         */
-       function _sortForward($action_name, $retval)
+       function getDefaultForwardPath($forward_name)
        {
-               return $retval;
+               return str_replace('_', '/', $forward_name) . '.' . $this->ext['tpl'];
+       }
+       
+       /**
+        *      ¥Æ¥ó¥×¥ì¡¼¥È¥Ñ¥¹Ì¾¤«¤éÁ«°Ü̾¤ò¼èÆÀ¤¹¤ë
+        *
+        *      getDefaultForwardPath()¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤¿¾ì¹ç¡¢¤³¤Á¤é¤â¹ç¤ï¤»¤Æ¥ª¡¼¥Ð¡¼¥é¥¤¥É
+        *      ¤¹¤ë¤³¤È¤ò¿ä¾©(ɬ¿Ü¤Ç¤Ï¤Ê¤¤)
+        *
+        *      @access public
+        *      @param  string  $forward_path   ¥Æ¥ó¥×¥ì¡¼¥È¥Ñ¥¹Ì¾
+        *      @return string  Á«°Ü̾
+        */
+       function forwardPathToName($forward_path)
+       {
+               $forward_path = preg_replace('/^\/+/', '', $forward_path);
+               $forward_path = preg_replace(sprintf('/\.%s$/', $this->getExt('tpl')), '', $forward_path);
+
+               return str_replace('/', '_', $forward_path);
        }
 
        /**
@@ -1335,13 +1395,91 @@ class Ethna_Controller
                $forward_obj =& $this->forward[$forward_name];
                if (isset($forward_obj['forward_path']) == false) {
                        // ¾ÊάÃÍÊäÀµ
-                       $forward_obj['forward_path'] = $this->_getDefaultForwardPath($forward_name);
+                       $forward_obj['forward_path'] = $this->getDefaultForwardPath($forward_name);
                }
 
                return $forward_obj['forward_path'];
        }
 
        /**
+        *      ¥Æ¥ó¥×¥ì¡¼¥È¥¨¥ó¥¸¥ó¼èÆÀ¤¹¤ë(¸½ºß¤Ïsmarty¤Î¤ßÂбþ)
+        *
+        *      @access public
+        *      @return object  Smarty  ¥Æ¥ó¥×¥ì¡¼¥È¥¨¥ó¥¸¥ó¥ª¥Ö¥¸¥§¥¯¥È
+        *      @todo   ¥Ö¥í¥Ã¥¯´Ø¿ô¥×¥é¥°¥¤¥ó(etc)Âбþ
+        */
+       function &getTemplateEngine()
+       {
+               $smarty =& new Smarty();
+               $smarty->template_dir = $this->getTemplatedir();
+               $smarty->compile_dir = $this->getDirectory('template_c') . '/tpl_' . md5($smarty->template_dir);
+               if (@is_dir($smarty->compile_dir) == false) {
+                       mkdir($smarty->compile_dir, 0755);
+               }
+               $smarty->plugins_dir = $this->getDirectory('plugins');
+
+               // default modifiers
+               $smarty->register_modifier('number_format', 'smarty_modifier_number_format');
+               $smarty->register_modifier('strftime', 'smarty_modifier_strftime');
+               $smarty->register_modifier('count', 'smarty_modifier_count');
+               $smarty->register_modifier('join', 'smarty_modifier_join');
+               $smarty->register_modifier('filter', 'smarty_modifier_filter');
+               $smarty->register_modifier('unique', 'smarty_modifier_unique');
+               $smarty->register_modifier('wordwrap_i18n', 'smarty_modifier_wordwrap_i18n');
+               $smarty->register_modifier('i18n', 'smarty_modifier_i18n');
+               $smarty->register_modifier('checkbox', 'smarty_modifier_checkbox');
+               $smarty->register_modifier('select', 'smarty_modifier_select');
+               $smarty->register_modifier('form_value', 'smarty_modifier_form_value');
+
+               // user defined modifiers
+               foreach ($this->smarty_modifier_plugin as $modifier) {
+                       $name = str_replace('smarty_modifier_', '', $modifier);
+                       $smarty->register_modifier($name, $modifier);
+               }
+
+               // default functions
+               $smarty->register_function('message', 'smarty_function_message');
+               $smarty->register_function('uniqid', 'smarty_function_uniqid');
+               $smarty->register_function('select', 'smarty_function_select');
+               $smarty->register_function('checkbox_list', 'smarty_function_checkbox_list');
+
+               // user defined functions
+               foreach ($this->smarty_function_plugin as $function) {
+                       $name = str_replace('smarty_function_', '', $function);
+                       $smarty->register_function($name, $function);
+               }
+
+               // user defined prefilters
+               foreach ($this->smarty_prefilter_plugin as $prefilter) {
+                       $smarty->register_prefilter($prefilter);
+               }
+
+               // user defined postfilters
+               foreach ($this->smarty_postfilter_plugin as $postfilter) {
+                       $smarty->register_postfilter($postfilter);
+               }
+
+               // user defined outputfilters
+               foreach ($this->smarty_outputfilter_plugin as $outputfilter) {
+                       $smarty->register_outputfilter($outputfilter);
+               }
+
+               $this->_setDefaultTemplateEngine($smarty);
+
+               return $smarty;
+       }
+
+       /**
+        *  ¥Æ¥ó¥×¥ì¡¼¥È¥¨¥ó¥¸¥ó¤Î¥Ç¥Õ¥©¥ë¥È¾õÂÖ¤òÀßÄꤹ¤ë
+        *
+        *  @access protected
+        *  @param  object  Smarty  $smarty ¥Æ¥ó¥×¥ì¡¼¥È¥¨¥ó¥¸¥ó¥ª¥Ö¥¸¥§¥¯¥È
+        */
+       function _setDefaultTemplateEngine(&$smarty)
+       {
+       }
+
+       /**
         *      »ÈÍѸÀ¸ì¤òÀßÄꤹ¤ë
         *
         *      ¾­Íè¤Ø¤Î³ÈÄ¥¤Î¤¿¤á¤Î¤ß¤Ë¸ºß¤·¤Æ¤¤¤Þ¤¹¡£¸½ºß¤ÏÆä˥ª¡¼¥Ð¡¼¥é¥¤¥É¤ÎɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
@@ -1386,6 +1524,18 @@ class Ethna_Controller
        }
 
        /**
+        *      ¥Þ¥Í¡¼¥¸¥ã¥¯¥é¥¹Ì¾¤ò¼èÆÀ¤¹¤ë
+        *
+        *      @access public
+        *      @param  string  $name   ¥Þ¥Í¡¼¥¸¥ã̾
+        *      @return string  ¥Þ¥Í¡¼¥¸¥ã¥¯¥é¥¹Ì¾
+        */
+       function getManagerClassName($name)
+       {
+               return sprintf('%s_%sManager', $this->getAppId(), ucfirst($name));
+       }
+
+       /**
         *      ¥¢¥¯¥·¥ç¥ó¥¹¥¯¥ê¥×¥È¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë
         *
         *      ¤¿¤À¤·¡¢¥¤¥ó¥¯¥ë¡¼¥É¤·¤¿¥Õ¥¡¥¤¥ë¤Ë¥¯¥é¥¹¤¬Àµ¤·¤¯ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤ÏÊݾڤ·¤Ê¤¤
@@ -1402,11 +1552,17 @@ class Ethna_Controller
 
                // class_path°À­¥Á¥§¥Ã¥¯
                if (isset($action_obj['class_path'])) {
-                       if (file_exists($action_dir . $action_obj['class_path']) == false) {
-                               $this->logger->log(LOG_WARNING, 'class_path file not found [%s] -> try default', $action_obj['class_path']);
+                       // ¥Õ¥ë¥Ñ¥¹»ØÄꥵ¥Ý¡¼¥È
+                       $tmp_path = $action_obj['class_path'];
+                       if (Ethna_Util::isAbsolute($tmp_path) == false) {
+                               $tmp_path = $action_dir . $tmp_path;
+                       }
+
+                       if (file_exists($tmp_path) == false) {
+                               $this->logger->log(LOG_WARNING, 'class_path file not found [%s] -> try default', $tmp_path);
                        } else {
-                               include_once($action_dir . $action_obj['class_path']);
-                               $class_path = $action_obj['class_path'];
+                               include_once($tmp_path);
+                               $class_path = $tmp_path;
                        }
                }
 
@@ -1429,14 +1585,20 @@ class Ethna_Controller
 
                // form_path°À­¥Á¥§¥Ã¥¯
                if (isset($action_obj['form_path'])) {
-                       if ($action_obj['form_path'] == $class_path) {
+                       // ¥Õ¥ë¥Ñ¥¹»ØÄꥵ¥Ý¡¼¥È
+                       $tmp_path = $action_obj['class_path'];
+                       if (Ethna_Util::isAbsolute($tmp_path) == false) {
+                               $tmp_path = $action_dir . $tmp_path;
+                       }
+
+                       if ($tmp_path == $class_path) {
                                return;
                        }
-                       if (file_exists($action_dir . $action_obj['form_path']) == false) {
-                               $this->logger->log(LOG_WARNING, 'form_path file not found [%s] -> try default', $action_obj['form_path']);
+                       if (file_exists($tmp_path) == false) {
+                               $this->logger->log(LOG_WARNING, 'form_path file not found [%s] -> try default', $tmp_path);
                        } else {
-                               include_once($action_dir . $action_obj['form_path']);
-                               $form_path = $action_obj['form_path'];
+                               include_once($tmp_path);
+                               $form_path = $tmp_path;
                        }
                }
 
@@ -1468,11 +1630,17 @@ class Ethna_Controller
                $view_dir = $this->getViewdir();
 
                // view_path°À­¥Á¥§¥Ã¥¯
-               if (isset($action_obj['view_path'])) {
-                       if (file_exists($view_dir . $forward_obj['view_path']) == false) {
-                               $this->logger->log(LOG_WARNING, 'view_path file not found [%s] -> try default', $forward_obj['view_path']);
+               if (isset($forward_obj['view_path'])) {
+                       // ¥Õ¥ë¥Ñ¥¹»ØÄꥵ¥Ý¡¼¥È
+                       $tmp_path = $forward_obj['view_path'];
+                       if (Ethna_Util::isAbsolute($tmp_path) == false) {
+                               $tmp_path = $view_dir . $tmp_path;
+                       }
+
+                       if (file_exists($tmp_path) == false) {
+                               $this->logger->log(LOG_WARNING, 'view_path file not found [%s] -> try default', $tmp_path);
                        } else {
-                               include_once($action_dir . $forward_obj['view_path']);
+                               include_once($tmp_path);
                                return;
                        }
                }
@@ -1518,62 +1686,6 @@ class Ethna_Controller
        }
 
        /**
-        *  ¥Æ¥ó¥×¥ì¡¼¥È¥¨¥ó¥¸¥ó¤Î¥Ç¥Õ¥©¥ë¥È¾õÂÖ¤òÀßÄꤹ¤ë
-        *
-        *  @access protected
-        *  @param  object  Smarty  $smarty ¥Æ¥ó¥×¥ì¡¼¥È¥¨¥ó¥¸¥ó¥ª¥Ö¥¸¥§¥¯¥È
-        */
-       function _setDefaultTemplateEngine(&$smarty)
-       {
-       }
-
-       /**
-        *      Ethna¥Þ¥Í¡¼¥¸¥ã¤òÀßÄꤹ¤ë(ÉÔÍפʾì¹ç¤Ï¶õ¤Î¥á¥½¥Ã¥É¤È¤·¤Æ¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Æ¤â¤è¤¤)
-        *
-        *      @access protected
-        */
-       function _activateEthnaManager()
-       {
-               $base = dirname(dirname(__FILE__));
-
-               if ($this->config->get('debug') == false) {
-                       return;
-               }
-
-               // actionÀßÄê
-               $this->action['__ethna_info__'] = array(
-                       'form_name' =>  'Ethna_Form_Info',
-                       'class_name' => 'Ethna_Action_Info',
-               );
-               $this->action['__ethna_info_do__'] = array(
-                       'form_name' =>  'Ethna_Form_InfoDo',
-                       'class_name' => 'Ethna_Action_InfoDo',
-               );
-
-               // forwardÀßÄê
-               $forward_obj = array();
-
-               $forward_obj['forward_path'] = sprintf("%s/tpl/info.tpl", $base);
-               $forward_obj['view_name'] = 'Ethna_Action_Info';
-               $this->forward['__ethna_info__'] = $forward_obj;
-       }
-
-       /**
-        *      Á«°Ü̾¤ËÂбþ¤¹¤ë¥Æ¥ó¥×¥ì¡¼¥È¥Ñ¥¹Ì¾¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¥Ñ¥¹Ì¾¤òÊÖ¤¹
-        *
-        *      ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï"foo_bar"¤È¤¤¤¦forward̾¤¬"foo/bar" + ¥Æ¥ó¥×¥ì¡¼¥È³ÈÄ¥»Ò¤È¤Ê¤ë
-        *      ¤Î¤Ç¹¥¤ß±þ¤¸¤Æ¥ª¡¼¥Ð¥é¥¤¥É¤¹¤ë
-        *
-        *      @access protected
-        *      @param  string  $forward_name   forward̾
-        *      @return string  forward¥Ñ¥¹Ì¾
-        */
-       function _getDefaultForwardPath($forward_name)
-       {
-               return str_replace('_', '/', $forward_name) . '.' . $this->ext['tpl'];
-       }
-
-       /**
         *      ÀßÄê¥Õ¥¡¥¤¥ë¤ÎDSNÄêµÁ¤«¤é»ÈÍѤ¹¤ë¥Ç¡¼¥¿¤òºÆ¹½ÃÛ¤¹¤ë(¥¹¥ì¡¼¥Ö¥¢¥¯¥»¥¹Ê¬´ôÅù)
         *
         *      DSN¤ÎÄêµÁÊýË¡(¥Ç¥Õ¥©¥ë¥È:ÀßÄê¥Õ¥¡¥¤¥ë)¤òÊѤ¨¤¿¤¤¾ì¹ç¤Ï¤³¤³¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤¹¤ë
@@ -1621,44 +1733,34 @@ class Ethna_Controller
        }
 
        /**
-        *      ¥¢¥¯¥·¥ç¥ó̾¤¬¼Â¹Ôµö²Ä¤µ¤ì¤Æ¤¤¤ë¤â¤Î¤«¤É¤¦¤«¤òÊÖ¤¹
+        *      Ethna¥Þ¥Í¡¼¥¸¥ã¤òÀßÄꤹ¤ë
         *
-        *      @access private
-        *      @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) {
-                               return true;
-                       } else if ($name{strlen($name)-1} == '*') {
-                               if (strncmp($action_name, substr($name, 0, -1), strlen($name)-1) == 0) {
-                                       return true;
-                               }
-                       }
-               }
-               return false;
-       }
-
-       /**
-        *      ¥Õ¥£¥ë¥¿¡¼¥Á¥§¥¤¥ó¤òÀ¸À®¤¹¤ë
+        *      ÉÔÍפʾì¹ç¤Ï¶õ¤Î¥á¥½¥Ã¥É¤È¤·¤Æ¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Æ¤â¤è¤¤
         *
-        *      @access private
+        *      @access protected
         */
-       function _createFilterChain()
+       function _activateEthnaManager()
        {
-               $this->filter_chain = array();
-               foreach ($this->filter as $filter) {
-                       $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);
-                       }
+               if ($this->config->get('debug') == false) {
+                       return;
                }
+
+               include_once(ETHNA_BASE . '/class/Ethna_InfoManager.php');
+
+               // actionÀßÄê
+               $this->action['__ethna_info__'] = array(
+                       'form_name' =>  'Ethna_Form_Info',
+                       'form_path' =>  sprintf('%s/class/Action/Ethna_Action_Info.php', ETHNA_BASE),
+                       'class_name' => 'Ethna_Action_Info',
+                       'class_path' => sprintf('%s/class/Action/Ethna_Action_Info.php', ETHNA_BASE),
+               );
+
+               // forwardÀßÄê
+               $this->forward['__ethna_info__'] = array(
+                       'forward_path'  => sprintf('%s/tpl/info.tpl', ETHNA_BASE),
+                       'view_name'             => 'Ethna_View_Info',
+                       'view_path'             => sprintf('%s/class/View/Ethna_View_Info.php', ETHNA_BASE),
+               );
        }
 }
 // }}}
index 0d2a1c5..2570aa6 100644 (file)
  */
 class Ethna_InfoManager extends Ethna_AppManager
 {
+       /**#@+
+        *      @access private
+        */
+       
+       /**
+        *      @var    object  Ethna_Controller        ¥³¥ó¥È¥í¡¼¥é¥ª¥Ö¥¸¥§¥¯¥È
+        */
+       var     $ctl;
+
+       /**
+        *      @var    array   ¥¢¥¯¥·¥ç¥ó¥¹¥¯¥ê¥×¥È²òÀÏ·ë²Ì¥­¥ã¥Ã¥·¥å¥Õ¥¡¥¤¥ë
+        */
+       var     $cache_class_list_file;
+
+       /**
+        *      @var    array   ¥¢¥¯¥·¥ç¥ó¥¹¥¯¥ê¥×¥È²òÀÏ·ë²Ì¥­¥ã¥Ã¥·¥å
+        */
+       var     $cache_class_list;
+
+       /**
+        *      @var    array   [°À­]DB¥¿¥¤¥×°ìÍ÷
+        */
+       var     $db_type_list = array(
+               DB_TYPE_RW              => array('name' => 'DB_TYPE_RW'),
+               DB_TYPE_RO              => array('name' => 'DB_TYPE_RO'),
+               DB_TYPE_MISC    => array('name' => 'DB_TYPE_MISC'),
+       );
+
+       /**
+        *      @var    array   [°À­]¥Õ¥©¡¼¥à·¿°ìÍ÷
+        */
+       var     $form_type_list = array(
+               FORM_TYPE_TEXT          => array('name' => '¥Æ¥­¥¹¥È¥Ü¥Ã¥¯¥¹'),
+               FORM_TYPE_PASSWORD      => array('name' => '¥Ñ¥¹¥ï¡¼¥É'),
+               FORM_TYPE_TEXTAREA      => array('name' => '¥Æ¥­¥¹¥È¥¨¥ê¥¢'),
+               FORM_TYPE_SELECT        => array('name' => '¥»¥ì¥¯¥È¥Ü¥Ã¥¯¥¹'),
+               FORM_TYPE_RADIO         => array('name' => '¥é¥¸¥ª¥Ü¥¿¥ó'),
+               FORM_TYPE_CHECKBOX      => array('name' => '¥Á¥§¥Ã¥¯¥Ü¥Ã¥¯¥¹'),
+               FORM_TYPE_SUBMIT        => array('name' => '¥Õ¥©¡¼¥àÁ÷¿®¥Ü¥¿¥ó'),
+               FORM_TYPE_FILE          => array('name' => '¥Õ¥¡¥¤¥ë'),
+       );
+
+       /**
+        *      @var    array   [°À­]ÊÑ¿ô·¿°ìÍ÷
+        */
+       var     $var_type_list = array(
+               VAR_TYPE_INT            => array('name' => 'À°¿ô'),
+               VAR_TYPE_FLOAT          => array('name' => 'ÉâÆ°¾®¿ôÅÀ¿ô'),
+               VAR_TYPE_STRING         => array('name' => 'ʸ»úÎó'),
+               VAR_TYPE_DATETIME       => array('name' => 'ÆüÉÕ'),
+               VAR_TYPE_BOOLEAN        => array('name' => '¿¿µ¶ÃÍ'),
+               VAR_TYPE_FILE           => array('name' => '¥Õ¥¡¥¤¥ë'),
+       );
+
+       /**#@-*/
+
+       /**
+        *      Ethna_InfoManager¤Î¥³¥ó¥¹¥È¥é¥¯¥¿
+        *
+        *      @access public
+        *      @param  object  Ethna_Backend   &$backend       Ethna_Backend¥ª¥Ö¥¸¥§¥¯¥È
+        */
+       function Ethna_InfoManager(&$backend)
+       {
+               parent::Ethna_AppManager($backend);
+               $this->ctl =& Ethna_Controller::getInstance();
+
+               // ¥¢¥¯¥·¥ç¥ó¥¹¥¯¥ê¥×¥È²òÀÏ·ë²Ì¥­¥ã¥Ã¥·¥å¼èÆÀ
+               $this->cache_class_list_file = sprintf('%s/ethna_info_class_list', $this->ctl->getDirectory('tmp'));
+               if (file_exists($this->cache_class_list_file) && filesize($this->cache_class_list_file) > 0) {
+                       $fp = fopen($this->cache_class_list_file, 'r');
+                       $s = fread($fp, filesize($this->cache_class_list_file));
+                       fclose($fp);
+                       $this->cache_class_list = unserialize($s);
+               }
+       }
+
+       /**
+        *      ÄêµÁºÑ¤ß¥¢¥¯¥·¥ç¥ó°ìÍ÷¤ò¼èÆÀ¤¹¤ë
+        *
+        *      @access public
+        *      @return array   ¥¢¥¯¥·¥ç¥ó°ìÍ÷
+        */
+       function getActionList()
+       {
+               $r = array();
+
+               // ¥¢¥¯¥·¥ç¥ó¥¹¥¯¥ê¥×¥È¤ò²òÀϤ¹¤ë
+               $class_list = $this->_analyzeActionList();
+
+               // ¥¢¥¯¥·¥ç¥óÄêµÁ¥¨¥ó¥È¥ê°ìÍ÷
+               list($manifest_action_list, $manifest_class_list) = $this->_getActionList_Manifest($class_list);
+
+               // ¥¢¥¯¥·¥ç¥óÄêµÁ¾Êά¥¨¥ó¥È¥ê°ìÍ÷
+               $implicit_action_list = $this->_getActionList_Implicit($class_list, $manifest_action_list, $manifest_class_list);
+
+               $r = array_merge($manifest_action_list, $implicit_action_list);
+               ksort($r);
+
+               // ¥¢¥¯¥·¥ç¥óÄêµÁ¾ðÊóÊä´°
+               $r = $this->_addActionList($r);
+
+               return $r;
+       }
+
+       /**
+        *      ÄêµÁºÑ¤ßÁ«°ÜÀè°ìÍ÷¤ò¼èÆÀ¤¹¤ë
+        *
+        *      @access public
+        *      @return array   Á«°ÜÀè°ìÍ÷
+        */
+       function getForwardList()
+       {
+               $r = array();
+
+               // ¥Æ¥ó¥×¥ì¡¼¥È/¥Ó¥å¡¼¥¹¥¯¥ê¥×¥È¤ò²òÀϤ¹¤ë
+               $forward_list = $this->_analyzeForwardList();
+
+               // ¥Ó¥å¡¼ÄêµÁ¥¨¥ó¥È¥ê°ìÍ÷
+               $manifest_forward_list = $this->_getForwardList_Manifest($forward_list);
+
+               // ¥Ó¥å¡¼ÄêµÁ¾Êά¥¨¥ó¥È¥ê°ìÍ÷
+               $implicit_forward_list = $this->_getForwardList_Implicit($forward_list, $manifest_forward_list);
+
+               $r = array_merge($manifest_forward_list, $implicit_forward_list);
+               ksort($r);
+
+               return $r;
+       }
+
+       /**
+        *      ¥Ç¥£¥ì¥¯¥È¥ê°Ê²¼¤Î¥¢¥¯¥·¥ç¥ó¥¹¥¯¥ê¥×¥È¤ò²òÀϤ¹¤ë
+        *
+        *      @access private
+        *      @param  string  $action_dir             ²òÀÏÂоݤΥǥ£¥ì¥¯¥È¥ê
+        *      @return array   ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹ÄêµÁ°ìÍ÷
+        */
+       function _analyzeActionList($action_dir = null)
+       {
+               $r = array();
+               $cache_update = false;
+
+               if (is_null($action_dir)) {
+                       $cache_update = true;
+                       $action_dir = $this->ctl->getActiondir();
+               }
+               $prefix_len = strlen($this->ctl->getActiondir());
+
+               $child_dir_list = array();
+
+               $dh = opendir($action_dir);
+               if ($dh == false) {
+                       return;
+               }
+
+               $ext = $this->ctl->getExt('php');
+               while (($file = readdir($dh)) !== false) {
+                       if ($file == "." || $file == "..") {
+                               continue;
+                       }
+                       $file = $action_dir . $file;
+
+                       if (is_dir($file)) {
+                               $child_dir_list[] = $file;
+                               continue;
+                       }
+
+                       if (preg_match("/\.$ext\$/", $file) == 0) {
+                               continue;
+                       }
+
+                       $key = substr($file, $prefix_len);
+                       
+                       // ¥­¥ã¥Ã¥·¥å¥Á¥§¥Ã¥¯
+                       include_once($file);
+                       if ($this->cache_class_list[$key]['.mtime'] >= filemtime($file)) {
+                               $class_list = $this->cache_class_list[$key];
+                       } else {
+                               $class_list = $this->_analyzeActionScript($file);
+                       }
+                       if (is_null($class_list) == false) {
+                               $r[$key] = $class_list;
+                       }
+               }
+
+               closedir($dh);
+
+               foreach ($child_dir_list as $child_dir) {
+                       $tmp = $this->_analyzeActionList($child_dir);
+                       $r = array_merge($r, $tmp);
+               }
+
+               if ($cache_update) {
+                       // ¥­¥ã¥Ã¥·¥å¥Õ¥¡¥¤¥ë¹¹¿·
+                       $fp = fopen($this->cache_class_list_file, 'w');
+                       fwrite($fp, serialize($r));
+                       fclose($fp);
+               }
+
+               return $r;
+       }
+
+       /**
+        *      ¥¢¥¯¥·¥ç¥ó¥¹¥¯¥ê¥×¥È¤ò²òÀϤ¹¤ë
+        *
+        *      @access private
+        *      @param  string  $script ¥Õ¥¡¥¤¥ë̾
+        *      @return array   ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹ÄêµÁ°ìÍ÷
+        */
+       function _analyzeActionScript($script)
+       {
+               $class_list = array();
+               $class_list['.mtime'] = filemtime($script);
+
+               $source = "";
+               $fp = fopen($script, 'r');
+               if ($fp == false) {
+                       return null;
+               }
+               while (feof($fp) == false) {
+                       $source .= fgets($fp, 8192);
+               }
+               fclose($fp);
+
+               // ¥È¡¼¥¯¥ó¤Ëʬ³ä¤·¤Æ¥¯¥é¥¹ÄêµÁ¾ðÊó¤ò¼èÆÀ
+               $token_list = token_get_all($source);
+               $state = 'T_OUT';
+               $nest = 0;
+               $current = null;
+               for ($i = 0; $i < count($token_list); $i++) {
+                       $token = $token_list[$i];
+
+                       if (is_string($token)) {
+                               if ($token == '{') {
+                                       $nest++;
+                               } else if ($token == '}') {
+                                       $nest--;
+                                       if ($state == 'T_PREPARE' || $state == 'T_PERFORM') {
+                                               if ($nest == $method_nest) {
+                                                       $state = 'T_ACTION_CLASS';
+                                               }
+                                       } else if ($nest == 0) {
+                                               $state = 'T_OUT';
+                                       }
+                               }
+                               continue;
+                       }
+
+                       if ($token[0] == T_CLASS) {
+                               // ¥¯¥é¥¹ÄêµÁ³«»Ï
+                               $i += 2;
+                               $class_name = $token_list[$i][1];               // should be T_STRING
+                               if ($this->_isSubclassOf($class_name, 'Ethna_ActionClass')) {
+                                       $state = 'T_ACTION_CLASS';
+                                       $current = $class_name;
+                                       $class_list[$current] = array('type' => 'action_class');
+                               } else if ($this->_isSubclassOf($class_name, 'Ethna_ActionForm')) {
+                                       $state = 'T_ACTION_FORM';
+                                       $current = $class_name;
+                                       $class_list[$current] = array('type' => 'action_form');
+                               }
+                               $nest = 0;      // for safe
+                       } else if ($token[0] == T_COMMENT && strncmp($token[1], "/**", 3) == 0 && is_array($token_list[$i+2]) && $token_list[$i+2][0] == T_CLASS) {
+                               // DocComment for class
+                       } else if ($state == 'T_ACTION_CLASS' && $token[0] == T_FUNCTION) {
+                               $i += 2;
+                               $method_name = $token_list[$i][1];
+                               if (strcasecmp($method_name, 'prepare') == 0) {
+                                       $state = 'T_PREPARE';
+                                       $method_nest = $nest;
+                               } else if (strcasecmp($method_name, 'perform') == 0) {
+                                       $state = 'T_PERFORM';
+                                       $method_nest = $nest;
+                               }
+                       } else if (($state == 'T_PREPARE' || $state == 'T_PERFORM') && $token[0] == T_RETURN) {
+                               $s = "";
+                               $n = 2;
+                               while ($token_list[$i+$n] !== ";") {
+                                       $s .= is_string($token_list[$i+$n]) ? $token_list[$i+$n] : $token_list[$i+$n][1];
+                                       $n++;
+                               }
+                               $key = $state == 'T_PREPARE' ? 'prepare' : 'perform';
+                               $class_list[$current]['return'][$key][] = $s;
+                       }
+               }
+
+               if (count($class_list) == 0) {
+                       return null;
+               }
+               return $class_list;
+       }
+
+       /**
+        *      »ØÄꤵ¤ì¤¿¥¯¥é¥¹Ì¾¤ò·Ñ¾µ¤·¤Æ¤¤¤ë¤«¤É¤¦¤«¤òÊÖ¤¹
+        *
+        *      @access private
+        *      @param  string  $class_name             ¥Á¥§¥Ã¥¯ÂоݤΥ¯¥é¥¹Ì¾
+        *      @param  string  $parent_name    ¿Æ¥¯¥é¥¹Ì¾
+        *      @return bool    true:·Ñ¾µ¤·¤Æ¤¤¤ë false:¤¤¤Ê¤¤
+        */
+       function _isSubclassOf($class_name, $parent_name)
+       {
+               while ($tmp = get_parent_class($class_name)) {
+                       if (strcasecmp($tmp, $parent_name) == 0) {
+                               return true;
+                       }
+                       $class_name = $tmp;
+               }
+               return false;
+       }
+
+       /**
+        *      ¥³¥ó¥È¥í¡¼¥é¤ËÌÀ¼¨Åª¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥¢¥¯¥·¥ç¥ó°ìÍ÷¤ò¼èÆÀ¤¹¤ë
+        *
+        *      @access private
+        *      @param  array   ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥¯¥é¥¹°ìÍ÷
+        *      @return array   array(¥¢¥¯¥·¥ç¥ó°ìÍ÷, ¥¯¥é¥¹°ìÍ÷)
+        */
+       function _getActionList_Manifest($class_list)
+       {
+               $manifest_action_list = array();
+               $manifest_class_list = array();
+               foreach ($this->ctl->action as $action_name => $action) {
+                       if ($action_name == '__ethna_info__') {
+                               continue;
+                       }
+                       $action = $this->ctl->_getAction($action_name);
+
+                       $elt = array();
+                       // _analyzeActionList()¤Ç¼èÆÀ¤·¤¿¥¯¥é¥¹ÄêµÁ¥Ç¡¼¥¿¤«¤éÂбþ´Ø·¸¤ò¼èÆÀ
+                       foreach ($class_list as $file => $elts) {
+                               foreach ($elts as $class_name => $def) {
+                                       if ($def['type'] == 'action_class' && strcasecmp($class_name, $action['class_name']) == 0) {
+                                               $elt['action_class'] = $class_name;
+                                               $elt['action_class_file'] = $file;
+                                               $elt['action_class_info'] = $def;
+                                       } else if ($def['type'] == 'action_form' && strcasecmp($class_name, $action['form_name']) == 0) {
+                                               $elt['action_form'] = $class_name;
+                                               $elt['action_form_file'] = $file;
+                                               $elt['action_form_info'] = $def;
+                                       }
+                               }
+                       }
+
+                       // Ì¤ÄêµÁ¥Á¥§¥Ã¥¯
+                       if (isset($elt['action_class']) == false) {
+                               $elt['action_class'] = $action['class_name'];
+                               if (class_exists($action['class_name']) == false) {
+                                       $elt['action_class_info'] = array('undef' => true);
+                               }
+                       }
+                       if (isset($elt['action_form']) == false && $action['form_name'] != 'Ethna_ActionForm') {
+                               $elt['action_form'] = $action['form_name'];
+                               if (class_exists($action['form_name']) == false) {
+                                       $elt['action_form_info'] = array('undef' => true);
+                               }
+                       }
+                       $manifest_action_list[$action_name] = $elt;
+                       $manifest_class_list[] = strtolower($elt['action_class']);
+               }
+
+               return array($manifest_action_list, $manifest_class_list);
+       }
+
+       /**
+        *      °ÅÌÛ¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥¢¥¯¥·¥ç¥ó°ìÍ÷¤ò¼èÆÀ¤¹¤ë
+        *
+        *      @access private
+        *      @param  array   $class_list                             ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥¯¥é¥¹°ìÍ÷
+        *      @param  array   $manifest_action_list   ÌÀ¼¨Åª¤ËÄêµÁºÑ¤ß¤Î¥¢¥¯¥·¥ç¥ó°ìÍ÷
+        *      @param  array   $manifest_class_list    ÌÀ¼¨Åª¤ËÄêµÁºÑ¤ß¤Î¥¯¥é¥¹°ìÍ÷
+        *      @return array   array:¥¢¥¯¥·¥ç¥ó°ìÍ÷
+        */
+       function _getActionList_Implicit($class_list, $manifest_action_list, $manifest_class_list)
+       {
+               $implicit_action_list = array();
+
+               foreach ($class_list as $file => $elts) {
+                       foreach ($elts as $class_name => $def) {
+                               if (in_array(strtolower($class_name), $manifest_class_list)) {
+                                       continue;
+                               }
+
+                               // ¥¯¥é¥¹Ì¾¤«¤é¥¢¥¯¥·¥ç¥ó̾¤ò¼èÆÀ
+                               if ($def['type'] == 'action_class') {
+                                       $action_name = $this->ctl->actionClassToName($class_name);
+                                       if (array_key_exists($action_name, $manifest_action_list)) {
+                                               continue;
+                                       }
+                                       $implicit_action_list[$action_name]['action_class'] = $class_name;
+                                       $implicit_action_list[$action_name]['action_class_file'] = $file;
+                                       $implicit_action_list[$action_name]['action_class_info'] = $def;
+                               } else if ($def['type'] == 'action_form') {
+                                       $action_name = $this->ctl->actionFormToName($class_name);
+                                       if (array_key_exists($action_name, $manifest_action_list)) {
+                                               continue;
+                                       }
+                                       $implicit_action_list[$action_name]['action_form'] = $class_name;
+                                       $implicit_action_list[$action_name]['action_form_file'] = $file;
+                                       $implicit_action_list[$action_name]['action_form_info'] = $def;
+                               } else {
+                                       continue;
+                               }
+                       }
+               }
+
+               return $implicit_action_list;
+       }
+       
+       /**
+        *      ¥¢¥¯¥·¥ç¥óÄêµÁ°ìÍ÷¤òÊä´°¤¹¤ë
+        *
+        *      @access private
+        *      @param  array   $action_list    ¼èÆÀ¤·¤¿¥¢¥¯¥·¥ç¥ó°ìÍ÷
+        *      @return array   ½¤Àµ¸å¤Î¥¢¥¯¥·¥ç¥ó°ìÍ÷
+        */
+       function _addActionList($action_list)
+       {
+               foreach ($action_list as $action_name => $action) {
+                       // ¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à¤Ë¥Õ¥©¡¼¥àÄêµÁ¾ðÊó¤òÄɲÃ
+                       $form_name = $action['action_form'];
+                       if (class_exists($form_name) == false) {
+                               continue;
+                       }
+                       $af =& new $form_name($this->ctl);
+
+                       $form = array();
+                       foreach ($af->getDef() as $name => $def) {
+                               $form[$name]['required'] = $def['required'] ? 'true' : 'false';
+                               foreach (array('name', 'max', 'min', 'regexp', 'custom') as $key) {
+                                       $form[$name][$key] = $def[$key];
+                               }
+                               $form[$name]['filter'] = str_replace(",", "\n", $def['filter']);
+                               $form[$name]['form_type'] = $this->getAttrName('form_type', $def['form_type']);
+                               $form[$name]['type_is_array'] = is_array($def['type']);
+                               $form[$name]['type'] = $this->getAttrName('var_type', is_array($def['type']) ? $def['type'][0] : $def['type']);
+                       }
+                       $action['action_form_info']['form'] = $form;
+                       $action_list[$action_name] = $action;
+               }
+
+               return $action_list;
+       }
+
+       /**
+        *      ¥Ç¥£¥ì¥¯¥È¥ê°Ê²¼¤Î¥Æ¥ó¥×¥ì¡¼¥È¤ò²òÀϤ¹¤ë
+        *
+        *      @access private
+        *      @param  string  $action_dir             ²òÀÏÂоݤΥǥ£¥ì¥¯¥È¥ê
+        *      @return array   Á«°ÜÄêµÁ°ìÍ÷
+        */
+       function _analyzeForwardList($template_dir = null)
+       {
+               $r = array();
+
+               if (is_null($template_dir)) {
+                       $template_dir = $this->ctl->getTemplatedir();
+               }
+               $prefix_len = strlen($this->ctl->getTemplatedir());
+
+               $child_dir_list = array();
+
+               $dh = opendir($template_dir);
+               if ($dh == false) {
+                       return;
+               }
+
+               $ext = $this->ctl->getExt('tpl');
+               while (($file = readdir($dh)) !== false) {
+                       if ($file == "." || $file == "..") {
+                               continue;
+                       }
+                       $file = $template_dir . '/' . $file;
+
+                       if (is_dir($file)) {
+                               $child_dir_list[] = $file;
+                               continue;
+                       }
+
+                       if (preg_match("/\.$ext\$/", $file) == 0) {
+                               continue;
+                       }
+
+                       $tpl = substr($file, $prefix_len);
+                       $r[] = $this->ctl->forwardPathToName($tpl);
+               }
+
+               closedir($dh);
+
+               foreach ($child_dir_list as $child_dir) {
+                       $tmp = $this->_analyzeForwardList($child_dir);
+                       $r = array_merge($r, $tmp);
+               }
+
+               return $r;
+       }
+
+       /**
+        *      ¥³¥ó¥È¥í¡¼¥é¤ËÌÀ¼¨Åª¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ëÁ«°ÜÀè°ìÍ÷¤ò¼èÆÀ¤¹¤ë
+        *
+        *      @access private
+        *      @return array   ¥Ó¥å¡¼°ìÍ÷
+        */
+       function _getForwardList_Manifest()
+       {
+               $manifest_forward_list = array();
+               foreach ($this->ctl->forward as $forward_name => $forward) {
+                       if ($forward_name == '__ethna_info__') {
+                               continue;
+                       }
+
+                       $elt = array();
+                       $elt['template_file'] = $this->ctl->_getForwardPath($forward_name);
+                       if (file_exists(sprintf("%s/%s", $this->ctl->getTemplatedir(), $elt['template_file'])) == false) {
+                               $elt['template_file_info'] = array('undef' => true);
+                       }
+
+                       $elt['view_class'] = $this->ctl->getViewClassName($forward_name);
+                       if ($elt['view_class'] == 'Ethna_ViewClass') {
+                               $elt['view_class'] = null;
+                       } else if (class_exists($elt['view_class']) == false) {
+                               $elt['view_class_info'] = array('undef' => true);
+                       }
+
+                       if (isset($forward['view_path']) && $forward['view_path']) {
+                               $elt['view_path'] = $forward['view_path'];
+                       } else if ($this->_isSubclassOf($elt['view_class'], 'Ethna_ViewClass')) {
+                               $elt['view_class_file'] = $this->ctl->getDefaultViewPath($forward_name);
+                       } else {
+                               foreach ($this->cache_class_list as $file => $elts) {
+                                       foreach ($elts as $name => $def) {
+                                               if (strcasecmp($elt['view_class'], $name) == 0) {
+                                                       $elt['view_class_file'] = $file;
+                                                       break 2;
+                                               }
+                                       }
+                               }
+                       }
+
+                       $manifest_forward_list[$forward_name] = $elt;
+               }
+
+               return $manifest_forward_list;
+       }
+
+       /**
+        *      °ÅÌÛ¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥Ó¥å¡¼°ìÍ÷¤ò¼èÆÀ¤¹¤ë
+        *
+        *      @access private
+        *      @param  array   $forward_list                   ÄêµÁ¤µ¤ì¤Æ¤¤¤ëÁ«°Ü̾°ìÍ÷
+        *      @param  array   $manifest_forward_list  ÌÀ¼¨Åª¤ËÄêµÁºÑ¤ß¤Î¥Ó¥å¡¼°ìÍ÷
+        *      @return array   array:¥Ó¥å¡¼°ìÍ÷
+        */
+       function _getForwardList_Implicit($forward_list, $manifest_forward_list)
+       {
+               $implicit_forward_list = array();
+               $manifest_forward_name_list = array_keys($manifest_forward_list);
+
+               foreach ($forward_list as $forward_name) {
+                       if (in_array($forward_name, $manifest_forward_name_list)) {
+                               continue;
+                       }
+
+                       $elt = array();
+                       $elt['template_file'] = $this->ctl->_getForwardPath($forward_name);
+                       $elt['view_class'] = $this->ctl->getViewClassName($forward_name);
+                       if ($elt['view_class'] == 'Ethna_ViewClass') {
+                               $elt['view_class'] = null;
+                       } else if (class_exists($elt['view_class']) == false) {
+                               $elt['view_class'] = null;
+                       } else {
+                               $elt['view_class_file'] = $this->ctl->getDefaultViewPath($forward_name);
+                       }
+
+                       $implicit_forward_list[$forward_name] = $elt;
+               }
+
+               return $implicit_forward_list;
+       }
+
+       /**
+        *      Ethna¤ÎÀßÄê°ìÍ÷¤ò¼èÆÀ¤¹¤ë
+        *
+        *      @access public
+        *      @return array   ÀßÄê°ìÍ÷¤ò³ÊǼ¤·¤¿ÇÛÎó
+        *      @todo   respect access controll
+        */
+       function getConfiguration()
+       {
+               $r = array();
+
+               // core
+               $elts = array();
+               $elts['¥¢¥×¥ê¥±¡¼¥·¥ç¥óID'] = $this->ctl->getAppId();
+               $elts['¥¢¥×¥ê¥±¡¼¥·¥ç¥óURL'] = $this->ctl->getURL();
+               $elts['Ethna¥Ð¡¼¥¸¥ç¥ó'] = ETHNA_VERSION;
+               $elts['Ethna¥Ù¡¼¥¹¥Ç¥£¥ì¥¯¥È¥ê'] = ETHNA_BASE;
+               $r['Core'] = $elts;
+
+               // class
+               $elts = array();
+               $elts['ÀßÄê'] = $this->ctl->getClass('config');
+               $elts['DB'] = $this->ctl->getClass('db');
+               $elts['¥í¥°'] = $this->ctl->getClass('logger');
+               $elts['SQL'] = $this->ctl->getClass('sql');
+               $r['¥¯¥é¥¹'] = $elts;
+
+               // DB
+               $elts = array();
+               $db_list = array();
+               foreach ($this->ctl->db as $key => $db) {
+                       if ($key == "") {
+                               $tmp = '$db';
+                       } else {
+                               $tmp = sprintf('$db_%s', $key);
+                       }
+                       $elts[$tmp] = $this->getAttrName('db_type', $db);
+                       $db_list[$key] = $tmp;
+               }
+               $r['DB¥¿¥¤¥×'] = $elts;
+
+               // DSN
+               $elts = array();
+               foreach ($db_list as $key => $name) {
+                       $config_key = "dsn";
+                       if ($key != "") {
+                               $config_key .= "_$key";
+                       }
+                       $dsn = $this->config->get($config_key);
+                       if ($dsn) {
+                               $elts[$name] = implode("\n", to_array($dsn));
+                       }
+               }
+               $r['DSN'] = $elts;
+
+               // directory
+               $elts = array();
+               $elts['¥¢¥×¥ê¥±¡¼¥·¥ç¥ó'] = $this->ctl->getBasedir();
+               $elts['¥¢¥¯¥·¥ç¥ó'] = $this->ctl->getActiondir();
+               $elts['¥Ó¥å¡¼'] = $this->ctl->getViewdir();
+               $elts['¥Õ¥£¥ë¥¿'] = $this->ctl->getDirectory('filter');
+               $elts['¥Æ¥ó¥×¥ì¡¼¥È'] = $this->ctl->getTemplatedir();
+               $elts['¥Æ¥ó¥×¥ì¡¼¥È¥­¥ã¥Ã¥·¥å'] = $this->ctl->getDirectory('template_c');
+               $elts['Smarty¥×¥é¥°¥¤¥ó'] = implode(',', $this->ctl->getDirectory('plugins'));
+               $elts['ÀßÄê¥Õ¥¡¥¤¥ë'] = $this->ctl->getDirectory('etc');
+               $elts['¥í¥±¡¼¥ë'] = $this->ctl->getDirectory('locale');
+               $elts['¥í¥°'] = $this->ctl->getDirectory('log');
+               $elts['°ì»þ¥Õ¥¡¥¤¥ë'] = $this->ctl->getDirectory('tmp');
+               $r['¥Ç¥£¥ì¥¯¥È¥ê'] = $elts;
+
+               // ext
+               $elts = array();
+               $elts['¥Æ¥ó¥×¥ì¡¼¥È'] = $this->ctl->getExt('tpl');
+               $elts['PHP¥¹¥¯¥ê¥×¥È'] = $this->ctl->getExt('php');
+               $r['³ÈÄ¥»Ò'] = $elts;
+
+               // filter
+               $elts = array();
+               $n = 1;
+               foreach ($this->ctl->filter as $filter) {
+                       $key = sprintf("¥Õ¥£¥ë¥¿(%d)", $n);
+                       if (class_exists($filter)) {
+                               $elts[$key] = $filter;
+                               $n++;
+                       }
+               }
+               $r['¥Õ¥£¥ë¥¿'] = $elts;
+
+               // manager
+               $elts = array();
+               foreach ($this->ctl->getManagerList() as $key => $manager) {
+                       $name = sprintf('$%s', $key);
+                       $elts[$name] = $this->ctl->getManagerClassName($manager);
+               }
+               $r['¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥Þ¥Í¡¼¥¸¥ã'] = $elts;
+
+               return $r;
+       }
 }
 // }}}
 ?>
index cb5c114..a63857c 100644 (file)
@@ -489,6 +489,30 @@ class Ethna_Util
        }
 
        /**
+        *      ¥Ñ¥¹Ì¾¤¬ÀäÂХѥ¹¤«¤É¤¦¤«¤òÊÖ¤¹
+        *
+        *      port from File in PEAR (for BC)
+        *
+        *      @access public
+        *      @param  string  $path
+        *      @return bool    true:ÀäÂХѥ¹ false:ÁêÂХѥ¹
+        */
+       function isAbsolute($path)
+       {
+        if (preg_match("/\.\./", $path)) {
+            return false;
+        }
+
+        if (DIRECTORY_SEPARATOR == '/' && (substr($path, 0, 1) == '/' OR substr($path, 0, 1) == '~')) {
+            return true;
+        } elseif (DIRECTORY_SEPARATOR == '\\' && preg_match('/^[a-z]:\\\/i', $path)) {
+            return true;
+        }
+
+        return false;
+       }
+
+       /**
         *      ¥Æ¥ó¥Ý¥é¥ê¥Ç¥£¥ì¥¯¥È¥ê¤Î¥Õ¥¡¥¤¥ë¤òºï½ü¤¹¤ë
         *
         *      @access public
diff --git a/class/Form/Ethna_Form_Info.php b/class/Form/Ethna_Form_Info.php
deleted file mode 100644 (file)
index c0830ab..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-// vim: foldmethod=marker
-/**
- *     app_info.php
- *
- *     @author         Masaki Fujimoto <fujimoto@php.net>
- *     @license        http://www.opensource.org/licenses/bsd-license.php The BSD License
- *     @package        Ethna
- *     @version        $Id$
- */
-
-// {{{ Ethna_Form_Info
-/**
- *     __ethna_info__¥Õ¥©¡¼¥à¤Î¼ÂÁõ
- *
- *     @author         Masaki Fujimoto <fujimoto@php.net>
- *     @access         public
- *     @package        Ethna
- */
-class Ethna_Form_Info extends Ethna_ActionForm
-{
-       /**
-        *      @access private
-        *      @var    array   ¥Õ¥©¡¼¥àÃÍÄêµÁ
-        */
-       var     $form = array(
-       );
-}
-// }}}
-?>
diff --git a/class/View/Ethna_View_Info.php b/class/View/Ethna_View_Info.php
new file mode 100644 (file)
index 0000000..f5b187e
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+// vim: foldmethod=marker
+/**
+ *     Ethna_View_Info.php
+ *
+ *     @author         Masaki Fujimoto <fujimoto@php.net>
+ *     @license        http://www.opensource.org/licenses/bsd-license.php The BSD License
+ *     @package        Ethna
+ *     @version        $Id$
+ */
+
+// {{{ Ethna_View_Info
+/**
+ *     __ethna_info__¥Ó¥å¡¼¤Î¼ÂÁõ
+ *
+ *     @author         Masaki Fujimoto <fujimoto@php.net>
+ *     @access         public
+ *     @package        Ethna
+ */
+class Ethna_View_Info extends Ethna_ViewClass
+{
+       /**#@+
+        *      @access private
+        */
+
+       /**#@-*/
+
+       /**
+        *      Á«°ÜÁ°½èÍý
+        *
+        *      @access public
+        */
+       function preforward()
+       {
+               $ctl =& Ethna_Controller::getInstance();
+               $em =& new Ethna_InfoManager($this->backend);
+
+               // cores
+               $this->af->setApp('app_id', $ctl->getAppId());
+               $this->af->setApp('ethna_version', ETHNA_VERSION);
+
+               // actions
+               $this->af->setApp('action_list', $em->getActionList());
+
+               // views 
+               $this->af->setApp('forward_list', $em->getForwardList());
+
+               // configuration
+               $this->af->setApp('configuration', $em->getConfiguration());
+       }
+}
+// }}}
+?>
index d08740d..ca7b502 100644 (file)
@@ -3,7 +3,6 @@ include_once('{$basedir}/app/{$project_id}_Controller.php');
 
 {$project_id}_Controller::main('{$project_id}_Controller', array(
        '__ethna_info__',
-       '__ethna_info_do__',
        )
 );
 ?>
index 95ecb5d..9e6e034 100644 (file)
                <style type="text/css">
                <!--
                {literal}
-                       body {background-color: #ffffff; color: #000000; font-family: Arial,Verdana,Helvetica,'MS UI Gothic',sans-serif; margin-left: 50px; margin-right: 50px;}
-                       div.block {margin-left: 1em; margin-bottom: 1em;}
-                       h1 {font-weight: bold; text-align: left; font-size:1.2em}
-                       h2 {border-top: 1px solid #cccccc; border-right: 1px solid #cccccc; border-bottom: 1px solid #cccccc; border-left: 10px solid #0055bb; padding:6px; font-size: 1.2em;}
+                       body {background-color: #ffffff; color: #000000;}
+                       body, td, th, h1, h2 {font-family: sans-serif;}
                        pre {margin: 0px; font-family: monospace;}
                        a:link {color: #000099; text-decoration: none; background-color: #ffffff;}
                        a:hover {text-decoration: underline;}
                        table {border-collapse: collapse;}
-                       td, th { border: 1px solid #000000; font-size: 75%; vertical-align: baseline;}
-                       hr {width: 600px; background-color: #cccccc; border: 0px; height: 1px; color: #000000;}
-
-                       .powered {font-size: 0.8em;}
-
+                       .center {text-align: center;}
+                       .center table { text-align: left;}
+                       .center th { text-align: center !important; }
+                       td, th { border: 1px solid #000000; font-size: 75%; vertical-align: top;}
+                       h1 {font-size: 150%;}
+                       h2 {font-size: 125%;}
+                       .p {text-align: left;}
                        .e {background-color: #ccccff; font-weight: bold; color: #000000;}
                        .h {background-color: #9999cc; font-weight: bold; color: #000000;}
                        .v {background-color: #cccccc; color: #000000;}
+                       i {color: #666666; background-color: #cccccc;}
+                       img {float: right; border: 0px;}
+                       hr {width: 600px; background-color: #cccccc; border: 0px; height: 1px; color: #000000;}
                {/literal}
                //-->
                </style>
-               <title>{$app.project_id}¥×¥í¥¸¥§¥¯¥È</title>
+               <title>{$app.app_id} - Ethna Info</title>
        </head>
        <body>
-               <h1>{$app.project_id}¥×¥í¥¸¥§¥¯¥È</h1>
-               <h2>Actions</h2>
-               <p>
-               </p>
-               <h2>Forwards</h2>
-               <p>
-               </p>
-               <h2>ÀßÄê¾ðÊó</h2>
-               <p>
-               </p>
+               <div class="center">
+                       <table border="0" cellpadding="3" width="600">
+                               <tr class="h">
+                                       <td>
+                                               <h1 class="p">{$app.app_id}</h1>
+                                       </td>
+                               </tr>
+                       </table>
+                       <br />
+                       <hr />
+                       Contents
+                       <hr />
+                       <table border="0" cellpadding="3" width="600">
+                               <tr>
+                                       <td style="border:0px">
+                                               <ul>
+                                                       <li><a href="#actions">Actions</a></li>
+                                                               <ol>
+                                                               {foreach from=$app.action_list key=action_name item=action}
+                                                                       <li><a href="#action_{$action_name}">{$action_name}</a></li>
+                                                               {/foreach}
+                                                               </ol>
+                                                       <li><a href="#forwards">Forwards</a></li>
+                                                               <ol>
+                                                               {foreach from=$app.forward_list key=forward_name item=forward}
+                                                                       <li><a href="#forward_{$forward_name}">{$forward_name}</a></li>
+                                                               {/foreach}
+                                                               </ol>
+                                                       <li><a href="#configuration">Configuration</a></li>
+                                               </ul>
+                                       </td>
+                               </tr>
+                       </table>
+                       <br />
+                       <a name="actions"></a>
+                       <h1>Actions</h1>
+
+                       <table border="0" cellpadding="3" width="600">
+                               {foreach from=$app.action_list key=action_name item=action}
+                               <tr class="h">
+                                       <a name="action_{$action_name}"></a>
+                                       <th colspan="3">{$action_name}</th>
+                               </tr>
+                               <tr>
+                                       <td class="e">¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹</td>
+                                       <td class="v" colspan="2">{$action.action_class}{if $action.action_class_info.undef}<i>(̤ÄêµÁ)</li>{/if}</td>
+                               </tr>
+                               <tr>
+                                       <td class="e">¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à</td>
+                                       <td class="v" colspan="2">{$action.action_form|default:"<i>(̤ÄêµÁ)</i>"}{if $action.action_form_info.undef}<i>(̤ÄêµÁ)</li>{/if}</td>
+                               </tr>
+                               <tr>
+                                       <td class="e" rowspan="{$action.action_form_info.form|@count}">¥Õ¥©¡¼¥àÃÍ</td>
+                                       {foreach name="form" from=$action.action_form_info.form key=form_name item=form}
+                                               {if !$smarty.foreach.form.first}<tr>{/if}
+                                               <td class="v">{$form_name}</td>
+                                               <td class="v">
+                                                       <table cellpadding="1">
+                                                               <tr>
+                                                                       <td style="border:0px; font-size:100%;">ɽ¼¨Ì¾</td>
+                                                                       <td style="border:0px; font-size:100%;">{$form.name|default:"<i>̤ÄêµÁ</i>"}</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td style="border:0px; font-size:100%;">ɬ¿Ü</td>
+                                                                       <td style="border:0px; font-size:100%;">{$form.required|default:"false"}</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td style="border:0px; font-size:100%;">ºÇÂçÃÍ</td>
+                                                                       <td style="border:0px; font-size:100%;">{$form.max|default:"<i>̤ÄêµÁ</i>"}</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td style="border:0px; font-size:100%;">ºÇ¾®ÃÍ</td>
+                                                                       <td style="border:0px; font-size:100%;">{$form.min|default:"<i>̤ÄêµÁ</i>"}</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td style="border:0px; font-size:100%;">Àµµ¬É½¸½</td>
+                                                                       <td style="border:0px; font-size:100%;">{$form.regexp|default:"<i>̤ÄêµÁ</i>"}</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td style="border:0px; font-size:100%;">¥Á¥§¥Ã¥¯¥á¥½¥Ã¥É</td>
+                                                                       <td style="border:0px; font-size:100%;">{$form.custom|default:"<i>̤ÄêµÁ</i>"}</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td style="border:0px; font-size:100%;">ÊÑ´¹¥Õ¥£¥ë¥¿</td>
+                                                                       <td style="border:0px; font-size:100%;">{$form.filter|default:"<i>̤ÄêµÁ</i>"|nl2br}</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td style="border:0px; font-size:100%;">¥Õ¥©¡¼¥à¥¿¥¤¥×</td>
+                                                                       <td style="border:0px; font-size:100%;">{$form.form_type|default:"<i>̤ÄêµÁ</i>"}</td>
+                                                               </tr>
+                                                               <tr>
+                                                                       <td style="border:0px; font-size:100%;">¥¿¥¤¥×</td>
+                                                                       <td style="border:0px; font-size:100%;">{$form.type|default:"<i>̤ÄêµÁ</i>"}</td>
+                                                               </tr>
+                                                       </table>
+                                               </td>
+                                               {if !$smarty.foreach.form.first}</tr>{/if}
+                                       {foreachelse}
+                                               <td class="v" colspan="2"></td>
+                                       {/foreach}
+                               </tr>
+                               <tr>
+                                       <td class="e" rowspan="{$action.action_class_info.return.prepare|@count}">Á«°ÜÀè(prepare)</td>
+                                       {foreach name="return_prepare" from=$action.action_class_info.return.prepare item=forward}
+                                               {if !$smarty.foreach.return_prepare.first}<tr>{/if}
+                                               <td class="v" colspan="2">{$forward}</td>
+                                               {if !$smarty.foreach.return_prepare.first}</tr>{/if}
+                                       {foreachelse}
+                                               <td class="v" colspan="2"></td>
+                                       {/foreach}
+                               </tr>
+                               <tr>
+                                       <td class="e" rowspan="{$action.action_class_info.return.perform|@count}">Á«°ÜÀè(perform)</td>
+                                       {foreach name="return_perform" from=$action.action_class_info.return.perform item=forward}
+                                               {if !$smarty.foreach.return_perform.first}<tr>{/if}
+                                               <td class="v" colspan="2">{$forward}</td>
+                                               {if !$smarty.foreach.return_perform.first}</tr>{/if}
+                                       {foreachelse}
+                                               <td class="v" colspan="2"></td>
+                                       {/foreach}
+                               </tr>
+                               {/foreach}
+                       </table>
+                       <br />
+
+                       <a name="forwards"></a>
+                       <h1>Forwards</h1>
+
+                       <table border="0" cellpadding="3" width="600">
+                               {foreach from=$app.forward_list key=forward_name item=forward}
+                               <tr class="h">
+                                       <a name="forward_{$forward_name}"></a>
+                                       <th colspan="2">{$forward_name}</th>
+                               </tr>
+                               <tr>
+                                       <td class="e">¥Ó¥å¡¼¥¯¥é¥¹</td>
+                                       <td class="v">{$forward.view_class|default:"<i>̤ÄêµÁ</i>"}</td>
+                               </tr>
+                               <tr>
+                                       <td class="e">¥Æ¥ó¥×¥ì¡¼¥È¥Õ¥¡¥¤¥ë</td>
+                                       <td class="v">{$forward.template_file}</td>
+                               </tr>
+                               {/foreach}
+                       </table>
+                       <br />
+
+                       <a name="configuration"></a>
+                       <h1>Configuration</h1>
+
+                       <table border="0" cellpadding="3" width="600">
+                       {foreach from=$app.configuration key=section_name item=section}
+                               {if $section_name}
+                                       <tr class="h">
+                                               <th class="h" colspan="2">{$section_name}</th>
+                                       </tr>
+                               {/if}
+                               {if count($section) == 0}
+                                       <tr>
+                                               <td class="v" colspan="2">N/A</td>
+                                       </tr>
+                               {else}
+                                       {foreach from=$section key=entry_name item=entry}
+                                       <tr>
+                                               <td class="e">{$entry_name}</td>
+                                               <td class="v">{$entry|nl2br}</td>
+                                       </tr>
+                                       {/foreach}
+                               {/if}
+                       {/foreach}
+                       </table>
+
+                       <br />
 
-               <p align="right">
-                       <i class="powered">powered by <a href="http://ethna.jp/">Ethna {$app.ethna_version}</a></i>
-               </p>
+                       <hr />
+                       powered by <a href="http://ethna.jp/">Ethna {$app.ethna_version}</a> (experimental)
+                       <hr />
+               </div>
        </body>
 </html>