フォーム
Aura.InputとAura.Filterを使ったWebフォーム機能は 関連する機能が単体のクラスに集約され、テストや変更が容易です。1つのクラスでWebフォームとバリデーションのみの両方の用途に使えます。
インストール
Aura.Inputを使ったフォーム処理を追加するのにcomposerでray/web-form-module
をインストールします。
composer require ray/web-form-module
アプリケーションモジュールsrc/Module/AppModule.php
でAuraInputModule
をインストールします。
use BEAR\Package\AbstractAppModule;
use Ray\WebFormModule\WebFormModule;
class AppModule extends AbstractAppModule
{
protected function configure()
{
// ...
$this->install(new AuraInputModule);
}
}
Webフォーム
フォーム要素の登録やルールを定めたフォームクラスを作成して、@FormValidation
アノテーションを使って特定のメソッドと束縛します。
メソッドは送信されたデータがバリデーションOKのときのみ実行されます。
use Ray\WebFormModule\AbstractForm;
use Ray\WebFormModule\SetAntiCsrfTrait;
class MyForm extends AbstractForm
{
/**
* {@inheritdoc}
*/
public function init()
{
// set input fields
$this->setField('name', 'text')
->setAttribs([
'id' => 'name'
]);
// set rules and user defined error message
$this->filter->validate('name')->is('alnum');
$this->filter->useFieldMessage('name', 'Name must be alphabetic only.');
}
}
フォームクラスのinit()
メソッドでフォームのinput要素を登録し、バリデーションのフィルターやサニタイズのルールを適用します。バリデーションルールに関してはAura.FilterのRules To Validate Fields、サニタイズに関してはRules To Sanitize Fieldsをご覧ください。
メソッドの引数を連想配列にしたもをバリデーションします。入力を変更したいときは
SubmitInterface
インターフェイスのsubmit()メソッド
を実装して入力にする値を返します。
@FormValidationアノテーション
フォームのバリデーションを行うメソッドを@FormValidation
でアノテートすると、実行前にform
プロパティのフォームオブジェクトでバリデーションが行われます。
バリデーションに失敗するとメソッド名にValidationFailed
サフィックスをつけたメソッドが呼ばれます。
use Ray\Di\Di\Inject;
use Ray\Di\Di\Named;
use Ray\WebFormModule\Annotation\FormValidation;
use Ray\WebFormModule\FormInterface;
class MyController
{
/**
* @var FormInterface
*/
protected $form;
/**
* @Inject
* @Named("contact_form")
*/
public function setForm(FormInterface $form)
{
$this->form = $form;
}
/**
* @FormValidation
* // または
* @FormValidation(form="form", onFailure="onPostValidationFailed")
*/
public function onPost($name, $age)
{
// validation success
}
public function onPostValidationFailed($name, $age)
{
// validation failed
}
}
@FormValidation
アノテーションのform
,onValidationFailed
プロパティを変更してform
プロパティの名前やメソッドの名前を明示的に指定こともできます。
onPostValidationFailed
にはサブミットされた値が渡されます。
ビュー
フォームのinput
要素やエラーメッセージを取得するには要素名を指定します。
$form->input('name'); // <input id="name" type="text" name="name" size="20" maxlength="20" />
$form->error('name'); // 文字列「名前には全角文字またはアルファベットを入力して下さい。」またはブランク
テンプレートにTwigを使った場合でも同様です。
{{ form.input('name') }}
{{ form.error('name') }}
CSRF
CSRF(クロスサイトリクエストフォージェリ)対策を行うためにはフォームにCSRFオブジェクトをセットします。
use Ray\WebFormModule\SetAntiCsrfTrait;
class MyForm extends AbstractAuraForm
{
use SetAntiCsrfTrait;
セキュリティレベルを高めるためには、ユーザーの認証を含んだカスタムCsrfクラスを作成してフォームクラスにセットします。 詳しくはAura.InputのApplying CSRF Protectionsをご覧ください。
@InputValidation
@FormValidation
の代わりに@InputValidation
とアノテートするとバリデーションが失敗したときにRay\WebFormModule\Exception\ValidationException
が投げられるようになります。
この場合はHTML表現は使われません。Web APIに便利です。
キャッチした例外のerror
プロパティをecho
するとapplication/vnd.error+jsonメディアタイプの表現が出力されます。
http_response_code(400);
echo $e->error;
// {
// "message": "Validation failed",
// "path": "/path/to/error",
// "validation_messages": {
// "name": [
// "名前には全角文字またはアルファベットを入力して下さい。"
// ]
// }
// }
@VndError
アノテーションでvnd.error+json
に必要な情報を加えることができます。
/**
* @FormValidation(form="contactForm")
* @VndError(
* message="foo validation failed",
* logref="a1000", path="/path/to/error",
* href={"_self"="/path/to/error", "help"="/path/to/help"}
* )
*/
public function onPost()
Vnd Error
Ray\WebFormModule\FormVndErrorModule
をインストールすると@FormValidation
フォームとアノートしたメソッドも@InputValidation
とアノテートしたメソッドと同じように例外を投げるようになります。
作成したPageリソースをAPIとして使うことが出来ます。
use BEAR\Package\AbstractAppModule;
use Ray\WebFormModule\FormVndErrorModule;
class FooModule extends AbstractModule
{
protected function configure()
{
$this->install(new AuraInputModule);
$this->override(new FormVndErrorModule);
}
}
デモ
MyVendor.ContactFormアプリケーションでフォームのデモを実行して試すことができます。 確認付きのフォームページや、複数のフォームを1ページに設置したときの例などが用意されています。