はじめての機能拡張

Contaoのフォームジェネレーターを使うとWebのフォームを簡単に作成でき、フォームの入力内容をメールで受け取るくらいであればすぐに可能で、本サイトののページでも使用しています。(しばらく前に、少しスタイルシートを調整して、多少形を整えました。)

これを職場のサイトでも連絡先に留まらずに使ってみよう、と実際に試してみると思わぬことがわかってきます。試しに設置したフォームに対して出てきた問題点はこんなものがありました。

  1. 入力内容を確認してから申し込む流れが欲しい。
  2. 必須の入力を抜かしたときの警告メッセージが ! で終わっていると強圧的な印象を与えそう。
  3. メールアドレスの欄に全角文字で入力すると、警告された画面でドメインの部分が変わってしまう。
  4. 「セキュリティ質問」って、何それ?

最初の1.の問題は、Session Formという機能拡張で無事に解決、2.の問題は私家版の日本語言語ファイルの方で直して、そちらを使用するようにして解決。問題は3.で、フォームのテキスト入力で入力された内容が電子メールアドレスかどうか検証するようにして発生しているのは確かなものの、何が起きているのかが最初はわかりませんでした。同じ問題は入力がURLかどうかの検証でも、同じ理由で発生します。

これはContaoが国際化ドメイン(IDN, Internationalized Domain Name)をサポートしていて、メールアドレスのドメイン部部分の検証を行う際に、入力された日本語の全角文字(UTF-8)を国際化ドメインとしてACE(ASCII Compatible Encoding)にしてから検証していることが原因の1つでした。このようにACEにしてから検証すること自体は間違いではなく、IDNをサポートする場合の正しい処理なのです。

しかし、エラーとしたフォームの再入力を促す画面でACEにエンコードされたままのドメイン名で表示されているのは問題です。おそらく、IDN自体があまり使用されていない上に、ヨーロッパ圏で使用する文字コード(特にISO-8859-1の範囲で収まってる場合)では気がつきにくいかもしれない気もします。

そもそもIDN抜きで検証する手段があっても良いのではないかと思ってチケットも書きましたが、「フック関数を使えば簡単に独自の検証方法を拡張できるから』とチケットがあっさりクローズされる前に、そのことには気づいてゴソゴソ始めた成果の1つが今回の話題です。(前置きだけで殆ど終わりそう。)

フック関数を使用するためには、新しくPHPのクラスを作成することが必要で機能拡張の形に(まとめなくてもできなくはないですが)するのが常道となります。というわけで、下の画像のような入力の検証「非国際化電子メールアドレス」と「非国際化URL」が出来上がりました。

実質的なファイルは3つ、言語ファイルが各言語毎に2つずつで、この手の拡張はやりやすいと言えます。さらに、少々別の機能も加えたものがありますが、どちらも機能拡張リポジトリに登録するかもしれません。

追記

図のプルダウンメニューの項目が3つ間違った内容となっています。「数字の変換」、「英字の変換」、「英数記号の変換」は本来それぞれ「数字」、「英字」、「英数字」であるべきところです。「少々別の機能」の部分で追加した言語ファイルのキーが被ってしまっています。Tongue out

2011年1月17日に直しました。

フォームの入力検証の拡張