Ray.WebFormModuleはアスペクト指向でフォームのバリデーションを行うモジュールです。 フォームライブラリにはAura.Inputを使い、 特定のアプリケーションフレームワークの依存なしで利用できます。
$ composer require ray/web-form-module
use Ray\Di\AbstractModule;
use Ray\WebFormModule\AuraInputModule;
class AppModule extends AbstractModule
{
protected function configure()
{
$this->install(new AuraInputModule);
}
}
init()
メソッドでフォームのinput
要素を登録とルールの設定を行います。
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 input filters
$this->filter->validate('name')->is('alnum');
$this->filter->useFieldMessage('name', 'Name must be alphabetic only.');
}
}
メソッドの引数を名前付き引数にしたものがフォームオブジェクトに渡されバリデーションされます。
// このメソッドの場合['id' => $id, 'name' => $name]配列が渡されます
public function createAction($id, $name, $body)
{
Ray\WebFormModule\WebFormModule\SubmitInterface
を実装するとsubmit()
メソッドで返された値がフォームオブジェクトに渡されます。
/**
* {@inheritdoc}
*/
public function submit()
{
return $_POST;
}
}
init()
メソッドでで利用できるメソッドについて詳しく`はAura.Inputをご覧ください
コントローラークラスにフォームをインジェクトします。フォームのバリデーションを行うメソッドを@FormValidation
で
アノテートします。この時フォームのプロパティ名をform
で、バリデーションが失敗したときのメソッドをonFailure
で指定します。
use Ray\Di\Di\Inject;
use Ray\Di\Di\Named;
use Ray\WebFormModule\Annotation\FormValidation;
use Ray\WebFormModule\FormInterface;
class MyController
{
/**
* @var FormInterface
*/
protected $contactForm;
/**
* @Inject
* @Named("contact_form")
*/
public function setForm(FormInterface $form)
{
$this->contactForm = $form;
}
/**
* @FormValidation(form="contactForm", onFailure="badRequestAction")
*/
public function createAction()
{
// validation success
}
public function badRequestAction()
{
// validation faild
}
}
フォームのinput
要素やエラーメッセージを取得するには要素名を指定します。
echo $form->input('name'); // <input id="name" type="text" name="name" size="20" maxlength="20" />
echo $form->error('name'); // "Name must be alphabetic only." or blank.
CSRF対策を行うためにはフォームにCSRFオブジェクトをセットします。
use Ray\WebFormModule\SetAntiCsrfTrait;
class MyForm extends AbstractAuraForm
{
use SetAntiCsrfTrait;
セキュリティレベルを高めるためにはユーザーの認証を含んだカスタムCsrfクラスを作成してフォームクラスにセットします。 詳しくはAura.InputのApplying CSRF Protectionsをご覧ください。
@FormValidation
の代わりに@InputValidation
とアノテートするとバリデーションが失敗したときにRay\WebFormModule\Exception\ValidationException
が投げられるよになります。この場合はHTML表現は使われません。Web APIアプリケーションなどに便利です。
use Ray\WebFormModule\Annotation\InputValidation;
class Foo
{
/**
* @InputValidation(form="form1")
*/
public function createAction($name)
{
// ...
}
以下のように Ray\WebFormModule\FormVndErrorModule
をインストールするとフォームのバリデーションが失敗したときにRay\WebFormModule\Exception\ValidationException
例外が投げられるよになります。
use Ray\Di\AbstractModule;
class FakeVndErrorModule extends AbstractModule
{
protected function configure()
{
$this->install(new AuraInputModule);
$this->override(new FormVndErrorModule);
}
キャッチした例外のerror
プロパティをecho
するとapplication/vnd.error+jsonメディアタイプの表現が出力されます。
http_response_code(400);
echo $e->error;
//{
// "message": "Validation failed",
// "path": "/path/to/error",
// "validation_messages": {
// "name": [
// "Name must be alphabetic only."
// ]
// }
//}
@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"}
* )
*/
このオプションのモジュールはAPIアプリケーションの時に有用です。
$ php -S docs/demo/1.csrf/web.php