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>