Source for file ActionForm.php

Documentation is available at ActionForm.php

  1. <?php
  2. // vim: foldmethod=marker
  3. /**
  4.  *  ActionForm.php
  5.  *
  6.  *  @author     Masaki Fujimoto <fujimoto@php.net>
  7.  *  @license    http://www.opensource.org/licenses/bsd-license.php The BSD License
  8.  *  @package    Ethna
  9.  *  @version    $Id: 74849ca9e466fbe64f785a0e77ec5ec43c7ea0bd $
  10.  */
  11.  
  12. /** 定型フィルタ: 半角入力 */
  13. define('FILTER_HW''numeric_zentohan,alphabet_zentohan,ltrim,rtrim,ntrim');
  14.  
  15. /** 定型フィルタ: 全角入力 */
  16. define('FILTER_FW''kana_hantozen,ntrim');
  17.  
  18.  
  19. // {{{ Ethna_ActionForm
  20. /**
  21.  *  アクションフォームクラス
  22.  *
  23.  *  @author     Masaki Fujimoto <fujimoto@php.net>
  24.  *  @access     public
  25.  *  @package    Ethna
  26.  */
  27. {
  28.     /**#@+
  29.      *  @access protected
  30.      */
  31.  
  32.     /** @var    array   フォーム値定義(デフォルト) */
  33.     protected $form_template = array();
  34.  
  35.     /** @var    array   フォーム値定義 */
  36.     protected $form = array();
  37.  
  38.     /** @FIXME @protected    array   フォーム値 */
  39.     public $form_vars = array();
  40.  
  41.     /** @protected    array   アプリケーション設定値 */
  42.     protected $app_vars = array();
  43.  
  44.     /** @protected    array   アプリケーション設定値(自動エスケープなし) */
  45.     protected $app_ne_vars = array();
  46.  
  47.     /** @protected    object  Ethna_Backend       バックエンドオブジェクト */
  48.     protected $backend;
  49.  
  50.     /** @protected    object  Ethna_ActionError   アクションエラーオブジェクト */
  51.     protected $action_error;
  52.  
  53.     /** @protected    object  Ethna_ActionError   アクションエラーオブジェクト(省略形) */
  54.     protected $ae;
  55.  
  56.     /** @protected    object  Ethna_I18N  i18nオブジェクト */
  57.     protected $i18n;
  58.  
  59.     /** @protected    object  Ethna_Logger    ログオブジェクト */
  60.     protected $logger;
  61.  
  62.     /** @protected    object  Ethna_Plugin    プラグインオブジェクト */
  63.     protected $plugin;
  64.  
  65.     /** @var    array   フォーム定義要素 */
  66.     protected $def = array('name''required''max''min''regexp''mbregexp',
  67.                      'custom''filter''form_type''type');
  68.  
  69.     /** @protected    array   フォーム定義のうち非プラグイン要素とみなすprefix */
  70.     protected $def_noplugin = array('type''form''name''plugin''filter',
  71.                               'option''default');
  72.  
  73.     /** @protected    bool    追加検証強制フラグ */
  74.     protected $force_validate_plus = false;
  75.  
  76.     /** @protected    array   アプリケーションオブジェクト(helper) */
  77.     protected $helper_app_object = array();
  78.  
  79.     /** @protected    array   アプリケーションオブジェクト(helper)で利用しないフォーム名 */
  80.     protected $helper_skip_form = array();
  81.  
  82.     /** @protected    int   フォーム配列で使用可能な深さの上限 */
  83.     protected $max_form_deps = 10;
  84.  
  85.     /**#@-*/
  86.  
  87.     /**
  88.      *  Ethna_ActionFormクラスのコンストラクタ
  89.      *
  90.      *  @access public
  91.      *  @param  object  Ethna_Controller    $controller    controllerオブジェクト
  92.      */
  93.     public function __construct($controller)
  94.     {
  95.         $this->backend = $controller->getBackend();
  96.         $this->action_error = $controller->getActionError();
  97.         $this->ae = $this->action_error;
  98.         $this->i18n = $controller->getI18N();
  99.         $this->logger = $controller->getLogger();
  100.         $this->plugin = $controller->getPlugin();
  101.  
  102.         if (isset($_SERVER['REQUEST_METHOD']== false{
  103.             return;
  104.         }
  105.  
  106.         // フォーム値テンプレートの更新
  107.         $this->form_template = $this->_setFormTemplate($this->form_template);
  108.  
  109.         // アプリケーションオブジェクト(helper)の生成
  110.         foreach ($this->helper_app_object as $key => $value{
  111.             if (is_object($value)) {
  112.                 continue;
  113.             }
  114.             $this->helper_app_object[$key$this->_getHelperAppObject($key);
  115.         }
  116.  
  117.         // フォーム値定義の設定
  118.         $this->_setFormDef_HelperObj();
  119.         $this->_setFormDef();
  120.  
  121.         // 省略値補正
  122.         foreach ($this->form as $name => $value{
  123.             foreach ($this->def as $k{
  124.                 if (isset($value[$k]== false{
  125.                     $this->form[$name][$knull;
  126.                 }
  127.             }
  128.         }
  129.     }
  130.  
  131.     /**
  132.      *  フォーム値のアクセサ(R)
  133.      *
  134.      *  @access public
  135.      *  @param  string  $name   フォーム値の名称
  136.      *  @return mixed   フォーム値
  137.      */
  138.     public function get($name)
  139.     {
  140.         return $this->_getVarsByFormName($this->form_vars$name);
  141.     }
  142.  
  143.     /**
  144.      *  フォーム値定義を取得する
  145.      *
  146.      *  @access public
  147.      *  @param  string  $name   取得するフォーム名(nullなら全ての定義を取得)
  148.      *  @return array   フォーム値定義
  149.      */
  150.     public function getDef($name null)
  151.     {
  152.         if (is_null($name)) {
  153.             return $this->form;
  154.         }
  155.  
  156.         if (array_key_exists($name$this->form== false{
  157.             return null;
  158.         else {
  159.             return $this->form[$name];
  160.         }
  161.     }
  162.  
  163.     /**
  164.      *  フォーム項目表示名を取得する
  165.      *
  166.      *  @access public
  167.      *  @param  string  $name   フォーム値の名称
  168.      *  @return mixed   フォーム値の表示名
  169.      */
  170.     public function getName($name)
  171.     {
  172.         if (isset($this->form[$name]== false{
  173.             return null;
  174.         }
  175.         if (isset($this->form[$name]['name'])
  176.             && $this->form[$name]['name'!= null{
  177.             return $this->form[$name]['name'];
  178.         }
  179.  
  180.         // try message catalog
  181.         return $this->i18n->get($name);
  182.     }
  183.  
  184.     /**
  185.      *  フォーム名に対応するキーの配列を返す
  186.      *
  187.      *  @access private
  188.      *  @param  string  $name   フォーム名
  189.      *  @return array   キーの配列
  190.      */
  191.     private function _getFormNameArray($name)
  192.     {
  193.         // 多次元配列を指定した場合
  194.         if (preg_match('/^.*\[[^\]]+\]$/'$name)) 
  195.             $buff preg_replace('/\]\[/''['$name)// hoge[foo][bar] => hoge[foo[bar]
  196.             $buff preg_replace('/\]/'""$buff);    // hoge][foo[bar] => hoge[foo[bar
  197.             $ret explode('['$buff);                 // hoge[foo[bar   => array('hoge', 'foo', 'var')
  198.         else {
  199.             // 多次元配列を指定していない場合
  200.             $ret array($name);
  201.         }
  202.         return $ret;
  203.     }
  204.  
  205.     /**
  206.      *  配列の中からキーで指定された要素を取り出す
  207.      *
  208.      *  @access private
  209.      *  @param  array   &$target    対象とする配列
  210.      *  @param  string  $nane       キー
  211.      *  @return string  指定された要素
  212.      */
  213.     private function _getVarsByFormName(&$target$name)
  214.     {
  215.         $keys $this->_getFormNameArray($name);
  216.         return $this->_getVarsByKeys($target$keys);
  217.     }
  218.  
  219.     /**
  220.      *  配列の中にキーで指定された要素を登録する
  221.      *  フォーム定義にキーがあるかどうかは無関係に登録します
  222.      *
  223.      *  @access private
  224.      *  @param  array   &$target    対象とする配列
  225.      *  @param  string  $nane       キー
  226.      *  @param  mixde   $value      登録する値
  227.      */
  228.     private function _setVarsByFormName(&$target$name$vars)
  229.     {
  230.         $keys $this->_getFormNameArray($name);
  231.         $this->_setVarsByKeys($target$keys$vars);
  232.     }
  233.  
  234.     /**
  235.      *  配列の中からキーで指定された要素を取り出す
  236.      *
  237.      *  @access private
  238.      *  @param  array   &$target    対象とする配列
  239.      *  @param  array   $keys       キーの配列
  240.      *  @return string  指定された要素
  241.      */
  242.     private function _getVarsByKeys(&$target$keys)
  243.     {
  244.         $count count($keys);
  245.         if ($count == 0// 探索完了
  246.             return $target;
  247.         elseif ($this->max_form_deps + <= $count// 深すぎる配列を制限する
  248.             return null;
  249.         }
  250.  
  251.         // まだ探索するキーが残っている
  252.         $curval array_shift($keys);
  253.         if (is_array($target&& array_key_exists($curval$target)) {
  254.             return $this->_getVarsByKeys($target[$curval]$keys);
  255.         }
  256.         return null;
  257.     }
  258.  
  259.     private function _setVarsByKeys(&$target$keys&$var)
  260.     {
  261.         $count count($keys);
  262.         if ($count == 0// 探索完了
  263.             $target $var;
  264.             return;
  265.         elseif ($this->max_form_deps + <= $count// 深すぎる配列を制限する
  266.             return;
  267.         }
  268.  
  269.         // まだ探索するキーが残っている
  270.         $curval array_shift($keys);
  271.         if (is_array($target)) {
  272.             if (array_key_exists($curval$target)) {
  273.                 $target[$curvalnull;
  274.             }
  275.         else {
  276.             $target array($curval => null);
  277.         }
  278.  
  279.         $this->_setVarsByKeys($target[$curval]$keys$var);
  280.     }
  281.  
  282.     /**
  283.      *  $_FILESの中からキーで指定された要素を取り出す
  284.      *
  285.      *  @access private
  286.      *  @param  array   &$target    対象とする配列
  287.      *  @param  string  $nane       キー
  288.      *  @param  string  $key        $_FILESに含まれる項目(tmp_name等)
  289.      *  @return string  指定された要素
  290.      */
  291.     private function _getFilesInfoByFormName(&$target$name$key)
  292.     {
  293.         $form_keys $this->_getFormNameArray($name);
  294.         array_splice($form_keys10$key);
  295.         return $this->_getVarsByKeys($target$form_keys);
  296.     }
  297.  
  298.     /**
  299.      *  ユーザから送信されたフォーム値をフォーム値定義に従ってインポートする
  300.      *
  301.      *  @access public
  302.      */
  303.     public function setFormVars()
  304.     {
  305.         if (isset($_SERVER['REQUEST_METHOD']== false{
  306.             return;
  307.         else if (strcasecmp($_SERVER['REQUEST_METHOD']'post'== 0{
  308.             $http_vars $_POST;
  309.         else {
  310.             $http_vars $_GET;
  311.         }
  312.  
  313.         //
  314.         //  ethna_fid というフォーム値は、フォーム定義に関わらず受け入れる
  315.         //  これは、submitされたフォームを識別するために使われる
  316.         //  null の場合は、以下の場合である
  317.         //
  318.         //  1. フォームヘルパが使われていない
  319.         //  2. 画面の初期表示などで、submitされなかった
  320.         //  3. {form name=...} が未設定である
  321.         //
  322.         $this->form_vars['ethna_fid'(isset($http_vars['ethna_fid']== false
  323.                                       || is_null($http_vars['ethna_fid']))
  324.                                       ? null
  325.                                       : $http_vars['ethna_fid'];
  326.  
  327.         foreach ($this->form as $name => $def{
  328.             $type is_array($def['type']$def['type'][0$def['type'];
  329.             if ($type == VAR_TYPE_FILE{
  330.                 // ファイルの場合
  331.  
  332.                 // 値の有無の検査
  333.                 if (is_null($this->_getFilesInfoByFormName($_FILES$name'tmp_name'))) {
  334.                     $this->set($namenull);
  335.                     continue;
  336.                 }
  337.  
  338.                 // 配列構造の検査
  339.                 if (is_array($def['type'])) {
  340.                     if (is_array($this->_getFilesInfoByFormName($_FILES$name'tmp_name')) == false{
  341.                         $this->handleError($nameE_FORM_WRONGTYPE_ARRAY);
  342.                         $this->set($namenull);
  343.                         continue;
  344.                     }
  345.                 else {
  346.                     if (is_array($this->_getFilesInfoByFormName($_FILES$name'tmp_name'))) {
  347.                         $this->handleError($nameE_FORM_WRONGTYPE_SCALAR);
  348.                         $this->set($namenull);
  349.                         continue;
  350.                     }
  351.                 }
  352.  
  353.                 $files null;
  354.                 if (is_array($def['type'])) {
  355.                     $files array();
  356.                     // ファイルデータを再構成
  357.                     foreach (array_keys($this->_getFilesInfoByFormName($_FILES$name'name')) as $key{
  358.                         $files[$keyarray();
  359.                         $files[$key]['name'$this->_getFilesInfoByFormName($_FILES$name."[".$key."]"'name');
  360.                         $files[$key]['type'$this->_getFilesInfoByFormName($_FILES$name."[".$key."]"'type');
  361.                         $files[$key]['size'$this->_getFilesInfoByFormName($_FILES$name."[".$key."]"'size');
  362.                         $files[$key]['tmp_name'$this->_getFilesInfoByFormName($_FILES$name."[".$key."]"'tmp_name');
  363.                         if ($this->_getFilesInfoByFormName($_FILES$name."[".$key."]"'error'== null{
  364.                             // PHP 4.2.0 以前
  365.                             $files[$key]['error'0;
  366.                         else {
  367.                             $files[$key]['error'$this->_getFilesInfoByFormName($_FILES$name."[".$key."]"'error');
  368.                         }
  369.                     }
  370.                 else {
  371.                     $files['name'$this->_getFilesInfoByFormName($_FILES$name'name');
  372.                     $files['type'$this->_getFilesInfoByFormName($_FILES$name'type');
  373.                     $files['size'$this->_getFilesInfoByFormName($_FILES$name'size');
  374.                     $files['tmp_name'$this->_getFilesInfoByFormName($_FILES$name'tmp_name');
  375.                     if ($this->_getFilesInfoByFormName($_FILES$name'error'== null{
  376.                         // PHP 4.2.0 以前
  377.                         $files['error'0;
  378.                     else {
  379.                         $files['error'$this->_getFilesInfoByFormName($_FILES$name'error');
  380.                     }
  381.                 }
  382.  
  383.                 // 値のインポート
  384.                 $this->set($name$files);
  385.  
  386.             else {
  387.                 // ファイル以外の場合
  388.  
  389.                 $target_var $this->_getVarsByFormName($http_vars$name);
  390.  
  391.                 // 値の有無の検査
  392.                 if (isset($target_var== false
  393.                     || is_null($target_var)) {
  394.                     $this->set($namenull);
  395.                     if (isset($http_vars["{$name}_x"])
  396.                      && isset($http_vars["{$name}_y"])) {
  397.                         // 以前の仕様に合わせる
  398.                         $this->set($name$http_vars["{$name}_x"]);
  399.                     }
  400.                     continue;
  401.                 }
  402.  
  403.                 // 配列構造の検査
  404.                 if (is_array($def['type'])) {
  405.                     if (is_array($target_var== false{
  406.                         // 厳密には、この配列の各要素はスカラーであるべき
  407.                         $this->handleError($nameE_FORM_WRONGTYPE_ARRAY);
  408.                         $this->set($namenull);
  409.                         continue;
  410.                     }
  411.                 else {
  412.                     if (is_array($target_var)) {
  413.                         $this->handleError($nameE_FORM_WRONGTYPE_SCALAR);
  414.                         $this->set($namenull);
  415.                         continue;
  416.                     }
  417.                 }
  418.  
  419.                 // 値のインポート
  420.                 $this->set($name$target_var);
  421.             }
  422.         }
  423.     }
  424.  
  425.     /**
  426.      *  ユーザから送信されたフォーム値をクリアする
  427.      *
  428.      *  @access public
  429.      */
  430.     public function clearFormVars()
  431.     {
  432.         $this->form_vars = array();
  433.     }
  434.  
  435.     /**
  436.      *  フォーム値へのアクセサ(W)
  437.      *
  438.      *  @access public
  439.      *  @param  string  $name   フォーム値の名称
  440.      *  @param  string  $value  設定する値
  441.      */
  442.     public function set($name$value)
  443.     {
  444.         $this->_setVarsByFormName($this->form_vars$name$value);
  445.     }
  446.  
  447.     /**
  448.      *  フォーム値定義を設定する
  449.      *
  450.      *  @access public
  451.      *  @param  string  $name   設定するフォーム名(nullなら全ての定義を設定)
  452.      *  @param  array   $value  設定するフォーム値定義
  453.      *  @return array   フォーム値定義
  454.      */
  455.     public function setDef($name$value)
  456.     {
  457.         if (is_null($name)) {
  458.             $this->form = $value;
  459.         }
  460.         else {
  461.             $this->form[$name$value;
  462.         }
  463.     }
  464.  
  465.     /**
  466.      *  フォーム値を配列にして返す
  467.      *
  468.      *  @access public
  469.      *  @param  bool    $escape HTMLエスケープフラグ(true:エスケープする)
  470.      *  @return array   フォーム値を格納した配列
  471.      */
  472.     public function getArray($escape true)
  473.     {
  474.         $retval array();
  475.  
  476.         $this->_getArray($this->form_vars$retval$escape);
  477.  
  478.         return $retval;
  479.     }
  480.  
  481.     /**
  482.      *  アプリケーション設定値のアクセサ(R)
  483.      *
  484.      *  @access public
  485.      *  @param  string  $name   キー
  486.      *  @return mixed   アプリケーション設定値
  487.      */
  488.     public function getApp($name)
  489.     {
  490.         if (isset($this->app_vars[$name]== false{
  491.             return null;
  492.         }
  493.         return $this->app_vars[$name];
  494.     }
  495.  
  496.     /**
  497.      *  アプリケーション設定値のアクセサ(W)
  498.      *
  499.      *  @access public
  500.      *  @param  string  $name   キー
  501.      *  @param  mixed   $value  値
  502.      */
  503.     public function setApp($name$value)
  504.     {
  505.         $this->app_vars[$name$value;
  506.     }
  507.  
  508.     /**
  509.      *  アプリケーション設定値を配列にして返す
  510.      *
  511.      *  @access public
  512.      *  @param  boolean $escape HTMLエスケープフラグ(true:エスケープする)
  513.      *  @return array   フォーム値を格納した配列
  514.      */
  515.     public function getAppArray($escape true)
  516.     {
  517.         $retval array();
  518.  
  519.         $this->_getArray($this->app_vars$retval$escape);
  520.  
  521.         return $retval;
  522.     }
  523.  
  524.     /**
  525.      *  アプリケーション設定値(自動エスケープなし)のアクセサ(R)
  526.      *
  527.      *  @access public
  528.      *  @param  string  $name   キー
  529.      *  @return mixed   アプリケーション設定値
  530.      */
  531.     public function getAppNE($name)
  532.     {
  533.         if (isset($this->app_ne_vars[$name]== false{
  534.             return null;
  535.         }
  536.         return $this->app_ne_vars[$name];
  537.     }
  538.  
  539.     /**
  540.      *  アプリケーション設定値(自動エスケープなし)のアクセサ(W)
  541.      *
  542.      *  @access public
  543.      *  @param  string  $name   キー
  544.      *  @param  mixed   $value  値
  545.      */
  546.     public function setAppNE($name$value)
  547.     {
  548.         $this->app_ne_vars[$name$value;
  549.     }
  550.  
  551.     /**
  552.      *  アプリケーション設定値(自動エスケープなし)を配列にして返す
  553.      *
  554.      *  @access public
  555.      *  @param  boolean $escape HTMLエスケープフラグ(true:エスケープする)
  556.      *  @return array   フォーム値を格納した配列
  557.      */
  558.     public function getAppNEArray($escape false)
  559.     {
  560.         $retval array();
  561.  
  562.         $this->_getArray($this->app_ne_vars$retval$escape);
  563.  
  564.         return $retval;
  565.     }
  566.  
  567.     /**
  568.      *  フォームを配列にして返す(内部処理)
  569.      *
  570.      *  @access private
  571.      *  @param  array   &$vars      フォーム(等)の配列
  572.      *  @param  array   &$retval    配列への変換結果
  573.      *  @param  bool    $escape     HTMLエスケープフラグ(true:エスケープする)
  574.      */
  575.     public function _getArray(&$vars&$retval$escape)
  576.     {
  577.         foreach (array_keys($varsas $name{
  578.             if (is_array($vars[$name])) {
  579.                 $retval[$namearray();
  580.                 $this->_getArray($vars[$name]$retval[$name]$escape);
  581.             else {
  582.                 $retval[$name$escape
  583.                     ? htmlspecialchars($vars[$name]ENT_QUOTES$vars[$name];
  584.             }
  585.         }
  586.     }
  587.  
  588.     /**
  589.      *  追加検証強制フラグを取得する
  590.      *  (通常検証でエラーが発生した場合でも_validatePlus()が呼び出される)
  591.      *  @access public
  592.      *  @return bool    true:追加検証強制 false:追加検証非強制
  593.      */
  594.     public function isForceValidatePlus()
  595.     {
  596.         return $this->force_validate_plus;
  597.     }
  598.  
  599.     /**
  600.      *  追加検証強制フラグを設定する
  601.      *
  602.      *  @access public
  603.      *  @param  $force_validate_plus    追加検証強制フラグ
  604.      */
  605.     public function setForceValidatePlus($force_validate_plus)
  606.     {
  607.         $this->force_validate_plus = $force_validate_plus;
  608.     }
  609.  
  610.     /**
  611.      *  フォーム値検証メソッド
  612.      *
  613.      *  @access public
  614.      *  @return int     発生したエラーの数
  615.      */
  616.     public function validate()
  617.     {
  618.         foreach ($this->form as $name => $def{
  619.             $this->_validateWithPlugin($name);
  620.         }
  621.  
  622.         if ($this->ae->count(== || $this->isForceValidatePlus()) {
  623.             // 追加検証メソッド
  624.             $this->_validatePlus();
  625.         }
  626.  
  627.         return $this->ae->count();
  628.     }
  629.  
  630.     /**
  631.      *  プラグインを使ったフォーム値検証メソッド
  632.      *
  633.      *  @access private
  634.      *  @param  string  $form_name  フォームの名前
  635.      *  @todo   ae 側に $key を与えられるようにする
  636.      */
  637.     private function _validateWithPlugin($form_name)
  638.     {
  639.         // (pre) filter
  640.         if ($this->form[$form_name]['type'!= VAR_TYPE_FILE{
  641.  
  642.             //    入力値とフィルタ定義を取り出す
  643.             $form_var $this->get($form_name);
  644.             $filter (isset($this->form[$form_name]['filter']))
  645.                     ? $this->form[$form_name]['filter']
  646.                     : null;
  647.  
  648.             //    フィルタを適用
  649.             if (is_array($this->form[$form_name]['type']== false{
  650.                 $this->set($form_name$this->_filter($form_var$filter));
  651.             else if ($form_var != null{  //  配列の場合
  652.                 foreach (array_keys($form_varas $key{
  653.                     $this->set($form_name."[".$key."]"$this->_filter($form_var[$key]$filter));
  654.                 }
  655.             else {  //  配列で値が空の場合
  656.                 $this->set($form_name$this->_filter($form_var$filter));
  657.             }
  658.         }
  659.  
  660.         $form_vars $this->get($form_name);
  661.         $plugin $this->_getPluginDef($form_name);
  662.  
  663.         // type のチェックを処理の最初に追加
  664.         $plugin array_merge(array('type' => array())$plugin);
  665.         if (is_array($this->form[$form_name]['type'])) {
  666.             $plugin['type']['type'$this->form[$form_name]['type'][0];
  667.         else {
  668.             $plugin['type']['type'$this->form[$form_name]['type'];
  669.         }
  670.         if (isset($this->form[$form_name]['type_error'])) {
  671.             $plugin['type']['error'$this->form[$form_name]['type_error'];
  672.         }
  673.  
  674.         // スカラーの場合
  675.         if (is_array($this->form[$form_name]['type']== false{
  676.             foreach (array_keys($pluginas $name{
  677.                 // break: 明示されていなければ,エラーが起きたらvalidateを継続しない
  678.                 $break = isset($plugin[$name]['break']== false
  679.                                || $plugin[$name]['break'];
  680.  
  681.                 // プラグイン取得
  682.                 unset($v);
  683.                 $v $this->plugin->getPlugin('Validator',
  684.                                                ucfirst(strtolower($name)));
  685.                 if (Ethna::isError($v)) {
  686.                     continue;
  687.                 }
  688.  
  689.                 // バリデーション実行
  690.                 unset($r);
  691.                 $r $v->validate($form_name$form_vars$plugin[$name]);
  692.  
  693.                 // エラー処理
  694.                 if ($r !== true{
  695.                     if (Ethna::isError($r)) {
  696.                         $this->ae->addObject($form_name$r);
  697.                     }
  698.                     if ($break{
  699.                         break;
  700.                     }
  701.                 }
  702.             }
  703.             return;
  704.         }
  705.  
  706.         // 配列の場合
  707.  
  708.         // break 指示用の key list
  709.         $valid_keys is_array($form_varsarray_keys($form_varsarray();
  710.  
  711.         foreach (array_keys($pluginas $name{
  712.             // break: 明示されていなければ,エラーが起きたらvalidateを継続しない
  713.             $break = isset($plugin[$name]['break']== false
  714.                            || $plugin[$name]['break'];
  715.  
  716.             // プラグイン取得
  717.             unset($v);
  718.             $v $this->plugin->getPlugin('Validator'ucfirst(strtolower($name)));
  719.             if (Ethna::isError($v)) {
  720.                 continue;
  721.             }
  722.  
  723.             // 配列全体を受け取るプラグインの場合
  724.             if (isset($v->accept_array&& $v->accept_array == true{
  725.                 // バリデーション実行
  726.                 unset($r);
  727.                 $r $v->validate($form_name$form_vars$plugin[$name]);
  728.  
  729.                 // エラー処理
  730.                 if (Ethna::isError($r)) {
  731.                     $this->ae->addObject($form_name$r);
  732.                     if ($break{
  733.                         break;
  734.                     }
  735.                 }
  736.                 continue;
  737.             }
  738.  
  739.             // 配列の各要素に対して実行
  740.             foreach ($valid_keys as $key{
  741.                 // バリデーション実行
  742.                 unset($r);
  743.                 $r $v->validate($form_name$form_vars[$key]$plugin[$name]);
  744.  
  745.                 // エラー処理
  746.                 if (Ethna::isError($r)) {
  747.                     $this->ae->addObject($form_name$r);
  748.                     if ($break{
  749.                         unset($valid_keys[$key]);
  750.                     }
  751.                 }
  752.             }
  753.         }
  754.     }
  755.  
  756.     /**
  757.      *  チェックメソッド(基底クラス)
  758.      *
  759.      *  @access public
  760.      *  @param  string  $name   フォーム項目名
  761.      *  @return array   チェック対象のフォーム値(エラーが無い場合はnull)
  762.      */
  763.     public function check($name)
  764.     {
  765.         if (is_null($this->get($name)) || $this->get($name=== ""{
  766.             return null;
  767.         }
  768.  
  769.         // Ethna_Backendの設定
  770.         $c Ethna_Controller::getInstance();
  771.         $this->backend = $c->getBackend();
  772.  
  773.         return to_array($this->get($name));
  774.     }
  775.  
  776.     /**
  777.      *  チェックメソッド: 機種依存文字
  778.      *
  779.      *  @access public
  780.      *  @param  string  $name   フォーム項目名
  781.      *  @return object  Ethna_Error エラーオブジェクト(エラーが無い場合はnull)
  782.      */
  783.     public function checkVendorChar($name)
  784.     {
  785.         $null null;
  786.         $string $this->get($name);
  787.  
  788.         for ($i 0$i strlen($string)$i++{
  789.             /* JIS13区のみチェック */
  790.             $c ord($string{$i});
  791.             if ($c 0x80{
  792.                 /* ASCII */
  793.             else if ($c == 0x8e{
  794.                 /* 半角カナ */
  795.                 $i++;
  796.             else if ($c == 0x8f{
  797.                 /* JIS X 0212 */
  798.                 $i += 2;
  799.             else if ($c == 0xad || ($c >= 0xf9 && $c <= 0xfc)) {
  800.                 /* IBM拡張文字 / NEC選定IBM拡張文字 */
  801.                 return $this->ae->add($name,
  802.                     _et('{form} contains machine dependent code.')E_FORM_INVALIDCHAR);
  803.             else {
  804.                 $i++;
  805.             }
  806.         }
  807.  
  808.         return $null;
  809.     }
  810.  
  811.     /**
  812.      *  チェックメソッド: bool値
  813.      *
  814.      *  @access public
  815.      *  @param  string  $name   フォーム項目名
  816.      *  @return object  Ethna_Error エラーオブジェクト(エラーが無い場合はnull)
  817.      */
  818.     public function checkBoolean($name)
  819.     {
  820.         $null null;
  821.         $form_vars $this->check($name);
  822.  
  823.         if ($form_vars == null{
  824.             return $null;
  825.         }
  826.  
  827.         foreach ($form_vars as $v{
  828.             if ($v === ""{
  829.                 continue;
  830.             }
  831.             if ($v != "0" && $v != "1"{
  832.                 return $this->ae->add($name,
  833.                     _et('Please input {form} properly.')E_FORM_INVALIDCHAR);
  834.             }
  835.         }
  836.  
  837.         return $null;
  838.     }
  839.  
  840.     /**
  841.      *  チェックメソッド: メールアドレス
  842.      *
  843.      *  @access public
  844.      *  @param  string  $name   フォーム項目名
  845.      *  @return object  Ethna_Error エラーオブジェクト(エラーが無い場合はnull)
  846.      */
  847.     public function checkMailaddress($name)
  848.     {
  849.         $null null;
  850.         $form_vars $this->check($name);
  851.  
  852.         if ($form_vars == null{
  853.             return $null;
  854.         }
  855.  
  856.         foreach ($form_vars as $v{
  857.             if ($v === ""{
  858.                 continue;
  859.             }
  860.             if (Ethna_Util::checkMailaddress($v== false{
  861.                 return $this->ae->add($name,
  862.                     _et('Please input {form} properly.')E_FORM_INVALIDCHAR);
  863.             }
  864.         }
  865.  
  866.         return $null;
  867.     }
  868.  
  869.     /**
  870.      *  チェックメソッド: URL
  871.      *
  872.      *  @access public
  873.      *  @param  string  $name   フォーム項目名
  874.      *  @return object  Ethna_Error エラーオブジェクト(エラーが無い場合はnull)
  875.      */
  876.     public function checkURL($name)
  877.     {
  878.         $null null;
  879.         $form_vars $this->check($name);
  880.  
  881.         if ($form_vars == null{
  882.             return $null;
  883.         }
  884.  
  885.         foreach ($form_vars as $v{
  886.             if ($v === ""{
  887.                 continue;
  888.             }
  889.             if (preg_match('/^(http:\/\/|https:\/\/|ftp:\/\/)/'$v== 0{
  890.                 return $this->ae->add($name,
  891.                     _et('Please input {form} properly.')E_FORM_INVALIDCHAR);
  892.             }
  893.         }
  894.  
  895.         return $null;
  896.     }
  897.  
  898.     /**
  899.      *  フォーム値をhiddenタグとして返す
  900.      *
  901.      *  @access public
  902.      *  @param  array   $include_list   配列が指定された場合、その配列に含まれるフォーム項目のみが対象となる
  903.      *  @param  array   $exclude_list   配列が指定された場合、その配列に含まれないフォーム項目のみが対象となる
  904.      *  @return string  hiddenタグとして記述されたHTML
  905.      */
  906.     public function getHiddenVars($include_list null$exclude_list null)
  907.     {
  908.         $hidden_vars "";
  909.         foreach ($this->form as $key => $value{
  910.             if (is_array($include_list== true
  911.                 && in_array($key$include_list== false{
  912.                 continue;
  913.             }
  914.             if (is_array($exclude_list== true
  915.                 && in_array($key$exclude_list== true{
  916.                 continue;
  917.             }
  918.  
  919.             $type is_array($value['type']$value['type'][0$value['type'];
  920.             if ($type == VAR_TYPE_FILE{
  921.                 continue;
  922.             }
  923.  
  924.             $form_value $this->get($key);
  925.             if (is_array($value['type'])) {
  926.                 $form_array true;
  927.                 //  フォーム定義が配列なのにスカラーが
  928.                 //  渡ってきた場合は値を配列扱いとし、
  929.                 //  フォーム定義を尊重する
  930.                 if (is_array($form_value== false{
  931.                     $form_value array($form_value);
  932.                 }
  933.             else {
  934.                 //  フォーム定義がスカラーなのに配列が渡ってきた
  935.                 //  場合は救いようがないのでNOTICE扱いとし、タグも出力しない
  936.                 if (is_array($form_value)) {
  937.                     $this->handleError($keyE_FORM_WRONGTYPE_ARRAY);
  938.                     continue;
  939.                 }
  940.                 $form_value array($form_value);
  941.                 $form_array false;
  942.             }
  943.  
  944.             if (is_null($this->get($key))) {
  945.                 // フォーム値が送られていない場合はそもそもhiddenタグを出力しない
  946.                 continue;
  947.             }
  948.  
  949.             foreach ($form_value as $k => $v{
  950.                 if ($form_array{
  951.                     $form_name "$key"[$k]";
  952.                 else {
  953.                     $form_name $key;
  954.                 }
  955.                 $hidden_vars .=
  956.                     sprintf("<input type=\"hidden\" name=\"%s\" value=\"%s\" />\n",
  957.                             htmlspecialchars($form_nameENT_QUOTES),
  958.                             htmlspecialchars($vENT_QUOTES)
  959.                     );
  960.             }
  961.         }
  962.         return $hidden_vars;
  963.     }
  964.  
  965.     /**
  966.      *  フォーム値検証のエラー処理を行う
  967.      *
  968.      *  @access public
  969.      *  @param  string      $name   フォーム項目名
  970.      *  @param  int         $code   エラーコード
  971.      */
  972.     public function handleError($name$code)
  973.     {
  974.         $def $this->getDef($name);
  975.  
  976.         // ユーザ定義エラーメッセージ
  977.         $code_map array(
  978.             E_FORM_REQUIRED     => 'required_error',
  979.             E_FORM_WRONGTYPE_SCALAR => 'type_error',
  980.             E_FORM_WRONGTYPE_ARRAY  => 'type_error',
  981.             E_FORM_WRONGTYPE_INT    => 'type_error',
  982.             E_FORM_WRONGTYPE_FLOAT  => 'type_error',
  983.             E_FORM_WRONGTYPE_DATETIME   => 'type_error',
  984.             E_FORM_WRONGTYPE_BOOLEAN    => 'type_error',
  985.             E_FORM_MIN_INT      => 'min_error',
  986.             E_FORM_MIN_FLOAT    => 'min_error',
  987.             E_FORM_MIN_DATETIME => 'min_error',
  988.             E_FORM_MIN_FILE     => 'min_error',
  989.             E_FORM_MIN_STRING   => 'min_error',
  990.             E_FORM_MAX_INT      => 'max_error',
  991.             E_FORM_MAX_FLOAT    => 'max_error',
  992.             E_FORM_MAX_DATETIME => 'max_error',
  993.             E_FORM_MAX_FILE     => 'max_error',
  994.             E_FORM_MAX_STRING   => 'max_error',
  995.             E_FORM_REGEXP       => 'regexp_error',
  996.         );
  997.         //   フォーム定義にエラーメッセージが定義されていれば
  998.         //   それを使う
  999.         if (array_key_exists($code_map[$code]$def)) {
  1000.             $this->ae->add($name$def[$code_map[$code]]$code);
  1001.             return;
  1002.         }
  1003.  
  1004.         //   定義されていない場合は、内部のメッセージを使う
  1005.         if ($code == E_FORM_REQUIRED{
  1006.             switch ($def['form_type']{
  1007.             case FORM_TYPE_TEXT:
  1008.             case FORM_TYPE_PASSWORD:
  1009.             case FORM_TYPE_TEXTAREA:
  1010.             case FORM_TYPE_SUBMIT:
  1011.                 $message _et('Please input {form}.');
  1012.                 break;
  1013.             case FORM_TYPE_SELECT:
  1014.             case FORM_TYPE_RADIO:
  1015.             case FORM_TYPE_CHECKBOX:
  1016.             case FORM_TYPE_FILE:
  1017.                 $message _et('Please select {form}.');
  1018.                 break;
  1019.             default:
  1020.                 $message _et('Please input {form}.');
  1021.                 break;
  1022.             }
  1023.         else if ($code == E_FORM_WRONGTYPE_SCALAR{
  1024.             $message _et('Please input scalar value to {form}.');
  1025.         else if ($code == E_FORM_WRONGTYPE_ARRAY{
  1026.             $message _et('Please input array value to {form}.');
  1027.         else if ($code == E_FORM_WRONGTYPE_INT{
  1028.             $message _et('Please input integer value to {form}.');
  1029.         else if ($code == E_FORM_WRONGTYPE_FLOAT{
  1030.             $message _et('Please input float value to {form}.');
  1031.         else if ($code == E_FORM_WRONGTYPE_DATETIME{
  1032.             $message _et('Please input valid datetime to {form}.');
  1033.         else if ($code == E_FORM_WRONGTYPE_BOOLEAN{
  1034.             $message _et('You can input 0 or 1 to {form}.');
  1035.         else if ($code == E_FORM_MIN_INT{
  1036.             $this->ae->add($name,
  1037.                 _et('Please input more than %d(int) to {form}.'),
  1038.                 $code$def['min']);
  1039.             return;
  1040.         else if ($code == E_FORM_MIN_FLOAT{
  1041.             $this->ae->add($name,
  1042.                 _et('Please input more than %f(float) to {form}.'),
  1043.                 $code$def['min']);
  1044.             return;
  1045.         else if ($code == E_FORM_MIN_DATETIME{
  1046.             $this->ae->add($name,
  1047.                 _et('Please input datetime value %s or later to {form}.'),
  1048.                 $code$def['min']);
  1049.             return;
  1050.         else if ($code == E_FORM_MIN_FILE{
  1051.             $this->ae->add($name,
  1052.                 _et('Please specify file whose size is more than %d KB.')
  1053.                 $code$def['min']);
  1054.             return;
  1055.         else if ($code == E_FORM_MIN_STRING{
  1056.             $this->ae->add($name,
  1057.                 _et('Please input more than %d full-size (%d half-size) characters to {form}.'),
  1058.                 $codeintval($def['min']/2)$def['min']);
  1059.             return;
  1060.         else if ($code == E_FORM_MAX_INT{
  1061.             $this->ae->add($name,
  1062.                 _et('Please input less than %d(int) to {form}.'),
  1063.                 $code$def['max']);
  1064.             return;
  1065.         else if ($code == E_FORM_MAX_FLOAT{
  1066.             $this->ae->add($name,
  1067.                 _et('Please input less than %f(float) to {form}.'),
  1068.                 $code$def['max']);
  1069.             return;
  1070.         else if ($code == E_FORM_MAX_DATETIME{
  1071.             $this->ae->add($name,
  1072.                 _et('Please input datetime value before %s to {form}.'),
  1073.                 $code$def['max']);
  1074.             return;
  1075.         else if ($code == E_FORM_MAX_FILE{
  1076.             $this->ae->add($name,
  1077.                 _et('Please specify file whose size is less than %d KB to {form}.')
  1078.                 $code$def['max']);
  1079.             return;
  1080.         else if ($code == E_FORM_MAX_STRING{
  1081.             $this->ae->add($name,
  1082.                 _et('Please input less than %d full-size (%d half-size) characters to {form}.'),
  1083.                 $codeintval($def['max']/2)$def['max']);
  1084.             return;
  1085.         else if ($code == E_FORM_REGEXP{
  1086.             $message _et('Please input {form} properly.');
  1087.         }
  1088.  
  1089.         $this->ae->add($name$message$code);
  1090.     }
  1091.  
  1092.     /**
  1093.      *  ユーザ定義検証メソッド(フォーム値間の連携チェック等)
  1094.      *
  1095.      *  @access protected
  1096.      */
  1097.     protected function _validatePlus()
  1098.     {
  1099.     }
  1100.  
  1101.     /**
  1102.      *  カスタムチェックメソッドを実行する
  1103.      *
  1104.      *  @access protected
  1105.      *  @param  string  $method_list    カスタムメソッド名(カンマ区切り)
  1106.      *  @param  string  $name           フォーム項目名
  1107.      */
  1108.     protected function _validateCustom($method_list$name)
  1109.     {
  1110.         $method_list preg_split('/\s*,\s*/'$method_list,
  1111.                                   -1PREG_SPLIT_NO_EMPTY);
  1112.         if (is_array($method_list== false{
  1113.             return;
  1114.         }
  1115.         foreach ($method_list as $method{
  1116.             $this->$method($name);
  1117.         }
  1118.     }
  1119.  
  1120.     /**
  1121.      *  フォーム値に変換フィルタを適用する
  1122.      *
  1123.      *  @access protected
  1124.      *  @param  mixed   $value  フォーム値
  1125.      *  @param  int     $filter フィルタ定義
  1126.      *  @return mixed   変換結果
  1127.      */
  1128.     protected function _filter($value$filter)
  1129.     {
  1130.         if (is_null($filter)) {
  1131.             return $value;
  1132.         }
  1133.  
  1134.         foreach (preg_split('/\s*,\s*/'$filteras $f{
  1135.             $method sprintf('_filter_%s'$f);
  1136.             if (method_exists($this$method== false{
  1137.                 $this->logger->log(LOG_WARNING,
  1138.                     'filter method is not defined [%s]'$method);
  1139.                 continue;
  1140.             }
  1141.             $value $this->$method($value);
  1142.         }
  1143.  
  1144.         return $value;
  1145.     }
  1146.  
  1147.     /**
  1148.      *  フォーム値変換フィルタ: 全角英数字->半角英数字
  1149.      *
  1150.      *  @access protected
  1151.      *  @param  mixed   $value  フォーム値
  1152.      *  @return mixed   変換結果
  1153.      */
  1154.     protected function _filter_alnum_zentohan($value)
  1155.     {
  1156.         return mb_convert_kana($value"a");
  1157.     }
  1158.  
  1159.     /**
  1160.      *  フォーム値変換フィルタ: 全角数字->半角数字
  1161.      *
  1162.      *  @access protected
  1163.      *  @param  mixed   $value  フォーム値
  1164.      *  @return mixed   変換結果
  1165.      */
  1166.     protected function _filter_numeric_zentohan($value)
  1167.     {
  1168.         return mb_convert_kana($value"n");
  1169.     }
  1170.  
  1171.     /**
  1172.      *  フォーム値変換フィルタ: 全角英字->半角英字
  1173.      *
  1174.      *  @access protected
  1175.      *  @param  mixed   $value  フォーム値
  1176.      *  @return mixed   変換結果
  1177.      */
  1178.     protected function _filter_alphabet_zentohan($value)
  1179.     {
  1180.         return mb_convert_kana($value"r");
  1181.     }
  1182.  
  1183.     /**
  1184.      *  フォーム値変換フィルタ: 左空白削除
  1185.      *
  1186.      *  @access protected
  1187.      *  @param  mixed   $value  フォーム値
  1188.      *  @return mixed   変換結果
  1189.      */
  1190.     protected function _filter_ltrim($value)
  1191.     {
  1192.         return ltrim($value);
  1193.     }
  1194.  
  1195.     /**
  1196.      *  フォーム値変換フィルタ: 右空白削除
  1197.      *
  1198.      *  @access protected
  1199.      *  @param  mixed   $value  フォーム値
  1200.      *  @return mixed   変換結果
  1201.      */
  1202.     protected function _filter_rtrim($value)
  1203.     {
  1204.         return rtrim($value);
  1205.     }
  1206.  
  1207.     /**
  1208.      *  フォーム値変換フィルタ: NULL(0x00)削除
  1209.      *
  1210.      *  @access protected
  1211.      *  @param  mixed   $value  フォーム値
  1212.      *  @return mixed   変換結果
  1213.      */
  1214.     protected function _filter_ntrim($value)
  1215.     {
  1216.         return str_replace("\x00"""$value);
  1217.     }
  1218.  
  1219.     /**
  1220.      *  フォーム値変換フィルタ: 半角カナ->全角カナ
  1221.      *
  1222.      *  @access protected
  1223.      *  @param  mixed   $value  フォーム値
  1224.      *  @return mixed   変換結果
  1225.      */
  1226.     protected function _filter_kana_hantozen($value)
  1227.     {
  1228.         return mb_convert_kana($value"K");
  1229.     }
  1230.  
  1231.     /**
  1232.      *  フォーム値定義テンプレートを設定する
  1233.      *
  1234.      *  @access protected
  1235.      *  @param  array   $form_template  フォーム値テンプレート
  1236.      *  @return array   フォーム値テンプレート
  1237.      */
  1238.     protected function _setFormTemplate($form_template)
  1239.     {
  1240.         return $form_template;
  1241.     }
  1242.  
  1243.     /**
  1244.      *  フォーム定義変更用、ユーザ定義ヘルパメソッド
  1245.      *
  1246.      *  Ethna_ActionForm#prepare() が実行される前に
  1247.      *  ユーザが動的にフォーム定義を変更したい場合に
  1248.      *  このメソッドをオーバーライドします。
  1249.      *
  1250.      *  $this->backend も初期化済みのため、DBやセッション
  1251.      *  の値に基づいてフォーム定義を変更することができます。
  1252.      *
  1253.      *  @access public
  1254.      */
  1255.     public function setFormDef_PreHelper()
  1256.     {
  1257.         //  TODO: override this method. 
  1258.     }
  1259.  
  1260.     /**
  1261.      *  フォーム定義変更用、ユーザ定義ヘルパメソッド
  1262.      *
  1263.      *  フォームヘルパを使うときに、フォーム定義を動的に
  1264.      *  変更したい場合に、このメソッドをオーバーライドします。
  1265.      *
  1266.      *  以下の定義をテンプレートで行った場合に呼び出されます。
  1267.      *  
  1268.      *  {form ethna_action=...} (ethna_action がない場合は呼び出されません)
  1269.      *  {form_input action=...} (action がない場合は呼び出されません)
  1270.      *
  1271.      *  @access public
  1272.      */
  1273.     public function setFormDef_ViewHelper()
  1274.     {
  1275.         //   TODO: デフォルト実装は Ethna_ActionClass#prepare 前に
  1276.         //   呼び出されるものと同じ。異なる場合にオーバライドする
  1277.         $this->setFormDef_PreHelper()
  1278.     }
  1279.  
  1280.     /**
  1281.      *  ヘルパオブジェクト(アプリケーションオブジェクト)
  1282.      *  経由でのフォーム値定義を設定する
  1283.      *
  1284.      *  @access protected
  1285.      */
  1286.     protected function _setFormDef_HelperObj()
  1287.     {
  1288.         foreach (array_keys($this->helper_app_objectas $key{
  1289.             $object $this->helper_app_object[$key];
  1290.             $prop_def $object->getDef();
  1291.  
  1292.             foreach ($prop_def as $key => $value{
  1293.                 // 1. override form_template
  1294.                 $form_key = isset($value['form_name']$value['form_name'$key;
  1295.  
  1296.                 if (isset($this->form_template[$form_key]== false{
  1297.                     $this->form_template[$form_keyarray();
  1298.                 }
  1299.  
  1300.                 $this->form_template[$form_key]['type'$value['type'];
  1301.                 if (isset($value['required'])) {
  1302.                     $this->form_template[$form_key]['required'$value['required'];
  1303.                 }
  1304.  
  1305.                 if ($value['type'== VAR_TYPE_STRING && isset($value['length'])) {
  1306.                     $this->form_template[$form_key]['max'$value['length'];
  1307.                 }
  1308.  
  1309.                 // 2. then activate form
  1310.                 if (in_array($key$this->helper_skip_form== false{
  1311.                     if (isset($this->form[$key]== false{
  1312.                         $this->form[$keyarray();
  1313.                     }
  1314.                 }
  1315.             }
  1316.         }
  1317.     }
  1318.  
  1319.     /**
  1320.      *  フォーム値定義を設定する
  1321.      *
  1322.      *  @access protected
  1323.      */
  1324.     protected function _setFormDef()
  1325.     {
  1326.         foreach ($this->form as $key => $value{
  1327.             if (is_numeric($key)) {
  1328.                 $this->form[$valuearray();
  1329.                 unset($this->form[$key]);
  1330.             }
  1331.         }
  1332.  
  1333.         foreach ($this->form as $key => $value{
  1334.             if (array_key_exists($key$this->form_template)
  1335.                 && is_array($this->form_template)) {
  1336.                 foreach ($this->form_template[$keyas $def_key => $def_value{
  1337.                     if (array_key_exists($def_key$value== false{
  1338.                         $this->form[$key][$def_key$def_value;
  1339.                     }
  1340.                 }
  1341.             }
  1342.         }
  1343.     }
  1344.  
  1345.     /**
  1346.      *  フォーム値定義からプラグインの定義リストを分離する
  1347.      *
  1348.      *  @access protected
  1349.      *  @param  string  $form_name   プラグインの定義リストを取得するフォームの名前
  1350.      */
  1351.     protected function _getPluginDef($form_name)
  1352.     {
  1353.         //  $def = array(
  1354.         //               'name'         => 'number',
  1355.         //               'max'          => 10,
  1356.         //               'max_error'    => 'too large!',
  1357.         //               'min'          => 5,
  1358.         //               'min_error'    => 'too small!',
  1359.         //              );
  1360.         //
  1361.         // as plugin parameters:
  1362.         //
  1363.         //  $plugin_def = array(
  1364.         //                      'max' => array('max' => 10, 'error' => 'too large!'),
  1365.         //                      'min' => array('min' => 5, 'error' => 'too small!'),
  1366.         //                     );
  1367.  
  1368.         $def $this->getDef($form_name);
  1369.         $plugin array();
  1370.         foreach (array_keys($defas $key{
  1371.             // 未定義要素をスキップ
  1372.             if ($def[$key=== null{
  1373.                 continue;
  1374.             }
  1375.  
  1376.             // プラグイン名とパラメータ名に分割
  1377.             $snippet explode('_'$key2);
  1378.             $name $snippet[0];
  1379.  
  1380.             // 非プラグイン要素をスキップ
  1381.             if (in_array($name$this->def_noplugin)) {
  1382.                 continue;
  1383.             }
  1384.  
  1385.             if (count($snippet== 1{
  1386.                 // プラグイン名だけだった場合
  1387.                 if (is_array($def[$key])) {
  1388.                     // プラグインパラメータがあらかじめ配列で指定されている(とみなす)
  1389.                     $tmp $def[$key];
  1390.                 else {
  1391.                     $tmp array($name => $def[$key]);
  1392.                 }
  1393.             else {
  1394.                 // plugin_param の場合
  1395.                 $tmp array($snippet[1=> $def[$key]);
  1396.             }
  1397.  
  1398.             // merge
  1399.             if (isset($plugin[$name]== false{
  1400.                 $plugin[$namearray();
  1401.             }
  1402.             $plugin[$namearray_merge($plugin[$name]$tmp);
  1403.         }
  1404.  
  1405.         return $plugin;
  1406.     }
  1407.  
  1408.     /**
  1409.      *  アプリケーションオブジェクト(helper)を生成する
  1410.      *
  1411.      *  @access protected
  1412.      */
  1413.     protected function _getHelperAppObject($key)
  1414.     {
  1415.         $app_object $this->backend->getObject($key);
  1416.         return $app_object;
  1417.     }
  1418. }
  1419. // }}}

Documentation generated on Fri, 11 Nov 2011 03:57:24 +0900 by phpDocumentor 1.4.3