smarty3,pear…HTML_QuickForm2の情報が、ほとんどない!
smarty2,HTML_QuickFormから、いろいろと結構変わっていて、試行錯誤したメモです。
sample_input.php
<?php require_once("config.php"); require_once("HTML/QuickForm2.php"); require_once("HTML/QuickForm2/Renderer.php"); require_once("EXSmarty.php"); $smarty = new ExSmarty(); //以前のフォームデータがセッションにあれば取得する if (isset($_SESSION["data"])) { $data = $_SESSION["data"]; } else { $data = null; } $form = & new HTML_QuickForm2('inputform'); //テキスト $in_o_name = $form->addElement('text', 'o_name', array('id' => 'o_name', 'maxlength'=>50, 'autocomplete'=>"o_name", 'placeholder'=>"山田花子")); $in_o_kana = $form->addElement('text', 'o_kana', array('id' => 'o_kana', 'maxlength'=>50, 'autocomplete'=>"o_kana", 'placeholder'=>"やまだはなこ")); $in_d_name = $form->addElement('text', 'd_name', array('id' => 'd_name', 'maxlength'=>50, 'autocomplete'=>"d_name", 'placeholder'=>"山田太郎")); //セレクト $options = array('01'=>'北海道', '47'=>'沖縄県'); $form->addElement( 'select', 'o_pref_cd', array('id'=>"o_pref_cd", 'autocomplete'=>"o_pref_cd", 'class'=>"label_pref"), array('options' => $options)); //電話番号(オリジナルtype) $in_o_tel = $form->addElement('tel', 'o_tel', array('id' => 'tel', 'autocomplete'=>"tel", 'placeholder'=>"000-0000-0000")); //email(オリジナルtype) $in_o_email = $form->addElement('email', 'o_email', array('id' => 'email', 'autocomplete'=>"email", 'placeholder'=>"hoge@hoge.com", 'maxlength'=>"100")); //ラジオボタン $in_gp_dest = $form->addGroup('dest'); $in_gp_dest->addElement('radio', 'sel', array('value'=> 9, 'id'=>'dest_0')); //注文者へ送る $in_gp_dest->addElement('radio', 'sel', array('value'=> 1, 'id'=>'dest_1')); //注文者以外へ送る $in_gp_pay = $form->addGroup('pay'); $pay_list = array('1'=>'クレジットカード', '3'=>'銀行振り込み', '5'=>'代引き'); if (count($pay_list) > 0) { foreach ($pay_list as $cd=>$val) { $in_gp_pay->addElement('radio', 'sel', array('value'=>$cd, 'id' => 'pay_' . $cd)); } } //テキストエリア $in_message = $form->addElement('textarea', 'msg', array('rows' => 5), array('id' => 'msg') ); //チェックボックス $in_agree = $form->addElement('checkbox', 'agree', array('id' => 'agree', 'value' => 1)); //submitボタン $form->addSubmit('submit', array('value' => ' OK ', 'id' => 'submit')); //================= Filter $form->addRecursiveFilter('trim'); $in_o_kana->addFilter('_filter_mb_convert_kana_cH'); //================= Rule //callbackのパラメタとして渡すために、フォームデータを取得する //※filter適用後の値となる $form_data = $form->getValue(); //print_r($form_data); //必須 $in_o_name->addRule('required', 'ご注文者 お名前:入力して下さい'); $in_o_kana->addRule('required', 'ご注文者 ふりがな:入力して下さい'); $in_o_email->addRule('required', 'ご注文者 メールアドレス:入力して下さい'); //マルチバイト・文字数チェック $in_o_name->addRule('mbmaxlength', 'ご注文者 お名前:100文字までです',100); $in_message->addRule('mbmaxlength', 'メッセージ:1000文字までです',1000); //ひらがな/spaceのみチェック $in_o_kana->addRule('callback', 'お名前(かな)は、ひらがなのみで入力してください', array('callback' => 'check_zen_kana_space')); //別のフィールドとの関連チェック $in_d_name->addRule('callback', '別のお届先:お名前を入力してください', //array('callback' => 'check_dest_field','arguments' => array(array('dest' => $form_data['dest'])))); array('callback' => 'check_dest_field','arguments' => array(array('dest' => $form_data['dest']['sel'])))); //必須 $in_gp_dest->addRule('required', 'お届け先を選んで下さい'); //必須 $in_gp_pay->addRule('required', 'お支払い方法を選択してください'); //チェックボックス:必ずチェックさせたい時 $in_agree->addRule('required', '内容確認をお願いします'); $msg = ''; $errors = array(); $defaults = array(); if ($form->isSubmitted()) { if ($form->validate()) { //チェックOK //次のPGへ渡す場合、値をセッションへ格納しておく $_SESSION["data"] = $form->getValue(); echo "OK!"; print_r($form->getValue()); exit; } else { //validate()後のErrorを取得する foreach (new RecursiveIteratorIterator($form->getIterator(), RecursiveIteratorIterator::SELF_FIRST) as $item) { if (strlen($item->getError()) > 0) { $errors[$item->getName()] = $item->getError(); } } } } else { //初期表示:デフォルト値をセットする if (is_array($data) and isset($data)) { $defaults = $data; } else { $defaults = array("o_pref_cd" => 47, "dest" => array('sel'=> 9), "agree" => 0 ); } } //print_r($defaults); //Smarty $form->addDataSource(new HTML_QuickForm2_DataSource_Array($defaults)); HTML_QuickForm2_Renderer::register('smarty','HTML_QuickForm2_Renderer_Smarty'); $renderer = HTML_QuickForm2_Renderer::factory('smarty'); $FormData = $form->render($renderer)->toArray(); $smarty->assign('form', $FormData); //print_r($FormData); $smarty->assign('pay_list', $pay_list); //エラー情報 $smarty->assign('errors', $errors); $smarty->display("test/sample_input.tpl.html"); function check_dest_field($owner_field, $fields){ if ($fields["dest"] == 1) { //注文者以外の新住所へ送る時 if (strlen(trim($owner_field)) <= 0) { return False; } } return True; } //全角かな+空白のみか? チェック function check_zen_kana_space($p_field) { return preg_match("/^[ ぁ-ん ]+$/u", $p_field); } // c : 「全角カタカナ」を「全角ひらがな」 // H : 「半角カタカナ」を「全角ひらがな」 function _filter_mb_convert_kana_cH($p_word) { return mb_convert_kana($p_word, "cH"); } ?>
ExSmarty.php
<?php //require_once("config.php"); //独自のconfigファイル require_once("Smarty.class.php"); class ExSmarty extends Smarty { public function __construct() { parent::__construct(); //各パスを設定する // 複数の場合はarray()指定可能 $this->setTemplateDir( array("/hoge/templates/", "/hogehoge/templates/")); $this->setCompileDir(/hoge/templates_c/); $this->setCacheDir(/hoge/cache/); //効かなかった… //$this->setPluginsDir( // array(/hoge/plugins/, /hogehoge/plugins/)); //output filter $this->registerFilter("output", "change_src_path"); //plugin $this->registerPlugin("function", "bc_show_login_name", "smarty_bc_show_login_name"); } } //output filter // <img> src="..."の前に、所定のサイトURLを付加する function change_src_path($tpl_output, $smarty) { $add = "http://hoge.com/"; $tpl_output = preg_replace('/(<img[\s]+[^>]*?src=\"\/["\']?)/i', "$1$add", $tpl_output) ; $tpl_output = str_replace(array(' src="/http://',' src="/https://'), array(' src="http://',' src="https://'), $tpl_output); return $tpl_output; } //pluginと //セッションに保存した名前があれば出力する //なければ「ゲスト」を出力する function smarty_bc_show_login_name($param, &$smarty) { $smarty->cache_lifetime = 0; $_name = $_SESSION["name"]; if (strlen($_name) <= 0) { $_name = "ゲスト"; } echo $_name; } ?>
sample_input.tpl.html
<html> <head> <title>注文情報入力</title> <style type="text/css"> .error { font-size: 91%; color:red; } </style> </head> <body> <h1>注文情報入力</h1> <form {$form.attributes}> {if ($form.hidden)} {foreach from=$form.hidden item=item} {$item} {/foreach} {/if} {if count($errors) > 0} {foreach from=$errors key=key item=error} <div class="error">{*$key}:*}{$error}</div> {/foreach} {/if} <h2>注文者情報</h2> <p><label for="o_name">お名前</label> {$form.o_name.html}</p> {if isset($errors['o_name'])}<p class="error">{$errors['o_name']}</p>{/if} <p><label for="o_kana"> (ふりがな) </label> {$form.o_kana.html}</p> {if isset($errors['o_kana'])}<p class="error">{$errors['o_kana']}</p>{/if} <p><label for="o_pref"> 都道府県 </label> {$form.o_pref_cd.html}</p> <p><label for="tel"> 電話番号</label> {$form.o_tel.html}</p> {if isset($errors['o_tel'])}<p class="error">{$errors['o_tel']}</p>{/if} <p><label for="email"> メールアドレス</label> {$form.o_email.html}</p> {if isset($errors['o_email'])}<p class="error">{$errors['o_email']}</p>{/if} <h2>お届け先</h2> <p><label> {$form.dest.sel.elements[9].html} 注文者情報と同じ </label> <label> {$form.dest.sel.elements[1].html} 別のお届け先 </label></p> {if isset($errors['dest'])}<p class="error">{$errors['dest']}</p>{/if} <p><label for="d_name">お名前</label> {$form.d_name.html}</p> {if isset($errors['d_name'])}<p class="error">{$errors['d_name']}</p>{/if} <h2>お支払い方法</h2> <p><label> {$form.pay.sel.elements[1].html} {$pay_list[1]} <small>VISA,MASTER,AMEX</small> </label></p> <p><label> {$form.pay.sel.elements[3].html} {$pay_list[3]} <small>XX銀行 XX支店</small></label></p> <p><label> {$form.pay.sel.elements[5].html} {$pay_list[5]} </label></p> {if isset($errors['pay'])}<p class="error">{$errors['pay']}</p>{/if} <h2>ご注文について</h2> <p><label> {$form.agree.html} 確認しました</label></p> {if isset($errors['agree'])}<p class="error">{$errors['agree']}</p>{/if} <p>{$form.submit.html}</p> </form> </body> </html>
※input tel,email、はオリジナルのelementとして作成。
mbmaxlength(マルチバイト文字数チェック)は、オリジナルのルールとして作成。
いずれも、後日、UP予定。
生成htmlソース
<html> <head> <title>注文情報入力</title> <style type="text/css"> .error { font-size: 91%; color:red; } </style> </head> <body> <h1>注文情報入力</h1> <form method="post" id="inputform" action="/ap/p/test/sample_input.php"> <input type="hidden" id="qf:inputform" name="_qf__inputform" /> <h2>注文者様情報</h2> <p><label for="o_name">お名前</label> <input type="text" id="o_name" maxlength="50" autocomplete="o_name" placeholder="山田花子" name="o_name" /></p> <p><label for="o_kana"> (ふりがな) </label> <input type="text" id="o_kana" maxlength="50" autocomplete="o_kana" placeholder="やまだはなこ" name="o_kana" /></p> <p><label for="o_pref"> 都道府県 </label> <select id="o_pref_cd" autocomplete="o_pref_cd" class="label_pref" name="o_pref_cd"> <option value="01">北海道</option> <option value="47" selected="selected">沖縄県</option> </select></p> <p><label for="tel"> 電話番号</label> <input type="tel" id="tel" autocomplete="tel" placeholder="000-0000-0000" name="o_tel" /></p> <p><label for="email"> メールアドレス</label> <input type="email" id="email" autocomplete="email" placeholder="hoge@hoge.com" maxlength="100" name="o_email" /></p> <h2>お届け先</h2> <p><label> <input type="radio" value="9" id="dest_0" name="dest[sel]" checked="checked" /> 注文者情報と同じ </label> <label> <input type="radio" value="1" id="dest_1" name="dest[sel]" /> 別のお届け先 </label></p> <p><label for="d_name">お名前</label> <input type="text" id="d_name" maxlength="50" autocomplete="d_name" placeholder="山田太郎" name="d_name" /></p> <h2>お支払い方法</h2> <p><label> <input type="radio" value="1" id="pay_1" name="pay[sel]" /> クレジットカード <small>VISA,MASTER,AMEX</small> </label></p> <p><label> <input type="radio" value="3" id="pay_3" name="pay[sel]" /> 銀行振り込み <small>XX銀行 XX支店</small></label></p> <p><label> <input type="radio" value="5" id="pay_5" name="pay[sel]" /> 代引き </label></p> <h2>ご注文について</h2> <p><label> <input type="checkbox" id="agree" value="1" name="agree" /> 確認しました</label></p> <p><input type="submit" id="submit" value=" OK " name="submit" /></p> </form> </body> </html>