「WYSIWYG Editor搭載」
なんて売り文句を見る度に眉をひそめてきた私ですが、いろいろとテストした限り、HTMLPurifierを信用して良さそうなので、最新の d3forum-0.77 でfckxoopsを利用できるようにしてみました。
それもあえてこのサイトで運用してます。(自信の顕れ? 無謀な挑戦? )
HTML allowed FORUM
http://xoops.peak.ne.jp/md/d3forum/index.php?forum_id=12
このフォーラムでのみ、WYSIWYGエディタが有効になっており、HTML許可の投稿が出来ます。そして、HTML許可の場合は、無条件で、HTMLPurifierを通過します。
(当たり前ですが、d3forumでは、フォーラム毎に、それらの設定を細かくコントロールできます。フォーラムオプションでの指定法は記事の最後を参照のこと)
プレビューとかでいろいろ試してみるのも良いかもしれません。
試しに投稿しちゃっても良いですよ。但し、残しておく保証はありません。(fckxoopsの画像も同じ)
"HTMLでValidateするフォームメール" という記事を何回か連続で書いてきましたが、この意味がなかなか判りづらいかもしれません。「POSTデータ処理を行うための基準を、HTMLフォームそのものに求める」と書いても、判らない人には判らないでしょう。
というわけで、もう少し判りやすい実例で行きましょう。
その1
「商品説明コンテンツに、共通の問い合わせフォームを埋め込む」
picoを使ってカテゴリーごとに商品ページを作ったとしましょう。それらの一つ一つに、問い合わせフォームを埋め込んでいくなんて、それこそナンセンスです。
こんな用途では、formmailプラグインとpicoプラグインの組み合わせでバッチリです。
商品説明ページはこんな感じで作ります。(SmartyフィルターをONにすること)
(商品説明部分)
<{capture}>
<{pico id="(フォームを記述したコンテンツ番号)"}>
<{/capture}>
<{formmail4fleamarket mail_body_pre="以下の商品について問い合わせがありました。\nいずれかの連絡先までご連絡ください。\n\n" from_name="商品問い合わせ担当" cc_field_name="youremail" cc_mail_subject="確認メール" cc_mail_body_pre="お問い合わせありがとうございました。\n以下が確認内容です。\n"}>
<form>
お名前: <input type="text" name="お名前" class="required" /><br />
email: <input type="text" name="youremail" class="email" />
<input type="submit" />
</form>
WYSIWYGエディタを有効にするなら、基本的にHTML表示許可でデータを受け取るしかないのですが、そうするとScriptInsertionが避けられません。
HTMLを再構築してくれるライブラリさえあればなあ、と思っていたら、kentaulsさんが教えてくれました。
HTMLPurifier
http://htmlpurifier.org/
この手のライブラリってあまり信用していなかったのですが、アーカイブ内にあるsmoketestのXSSがあまりにも圧巻で、これはいけるかも! と期待してます。
ただこのライブラリ、手元で一通り試した限りでは、PHP5専用ですね。サイトにはPHP4でも動くと書いてありますし、一応、エラーを吐かずに通過はしますが、惨憺たる変換状況です。
逆に、PHP5だとおかしな動作が見つかりません。EUC-JPを通しても、ちゃんとiconvで内部的にUTF-8に変換してから処理してくれます。もちろん、返り値もEUC-JPとなります。
INSTALLにも書いてありますが、キャッシュの置き場所と、エンコーディング指定だけはちゃんとやった方が良いでしょう。
require_once dirname(__FILE__).'/library/HTMLPurifier.auto.php' ;
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache', 'SerializerPath',dirname(__FILE__).'/cache');
$config->set('Core', 'Encoding', 'EUC-JP');
$purifier = new HTMLPurifier($config);
pico-1.52になって、HTMLを書くだけ、というフォームメールシステムの仕様もほぼ確定したので、しばらくは実例でいきましょう。
繰り返しになりますが、基本構造はこれです。
<{capture}>
<form>
(フォーム記述部分)
</form>
<{/capture}>
<{formmail}>
<{capture}>
<form>
<input type="checkbox" name="好きなフルーツ" value="みかん" />みかん
<input type="checkbox" name="好きなフルーツ" value="りんご" />りんご
<input type="checkbox" name="好きなフルーツ" value="梨" />梨
<input type="submit" value="内容確認" />
</form>
<{/capture}>
<{formmail}>
<{capture}>
<form>
<fieldset>
<legend>好きなフルーツ</legend>
<input type="checkbox" name="favorite_fruits" id="favorite_fruits_orange" value="みかん" /><label for="favorite_fruits_orange">みかん</label>
<input type="checkbox" name="favorite_fruits" id="favorite_fruits_apple" value="りんご" /><label for="favorite_fruits_apple">りんご</label>
<input type="checkbox" name="favorite_fruits" id="favorite_fruits_pear" value="梨" /><label for="favorite_fruits_pear">梨</label>
</fieldset>
<input type="submit" value="内容確認" />
</form>
<{/capture}>
<{formmail}>
pico-1.51では、HTMLでValidateするルールが大きく変わりました。(ついでに、formmailプラグインそのものも大きく変貌しています)
(1)〜(3)も一部書き直しているので、古いのを読んでいた方はぜひ読み直してください。
今後、このHTML Validated Formシステムはいろいろな局面で流用すると思うので、デザイナーさんのためのルールを可能な限り詳しく記述します。
●項目名
name属性です。一通りのキャラクターが利用できます。日本語でも構いません。
配列も指定できますが、明示的に使う必要はほとんどありません。
●項目タイトル
<input><select><textarea>に対応する<label>がある場合、それを最優先に取得します。
checkboxやradioの場合は、<label>ではなく、所属する<fieldset>ブロック内の<legend>が最優先となります。
(<label>や<legend>ブロック内のテキストについているHTMLタグは除去されます)
<label>や<legend>が無い場合は、タグのtitle属性から項目タイトルを取得します。
上記のいずれからも項目タイトルが取得できなかった時には、項目名(name属性)が、項目タイトルとして扱われます。
●必須
class属性で指定します。
<input ... class="required" />
入力されていない、選択されていない時にエラーとなります
●型指定
class属性で指定します。以下のうち、いずれか一つだけが指定可能です。複数の型指定があった場合は、最初のものだけが利用されます。
- int
-- 整数型へ変換されます
- double
-- 浮動小数点型に変換されます
- singlebytes
-- 全角->半角変換の自動変換を行います
- email
-- 全角->半角変換の後、RFC2822によるチェックを行います。形式が合わなければエラーとなります。
- telephone
-- 全角->半角変換の後、電話番号を構成しなさそうなキャラクターが排除されます