Form
Each related function of Web Forms using Aura.Input and Aura.Filter is aggregated to a single class so that it is easy to test and change. We can use a corresponding class for the use of Web Forms and validation.
Install
Install ray/web-form-module
via composer to add form using Aura.Input
composer require ray/web-form-module
Install AuraInputModule
in our application module src/Module/AppModule.php
use BEAR\Package\AbstractAppModule;
use Ray\WebFormModule\WebFormModule;
class AppModule extends AbstractAppModule
{
protected function configure()
{
// ...
$this->install(new AuraInputModule);
}
}
Web Form
Create a form class that defines the registration and the rules of form elements, then bind it to a method using @FormValidation
annotation.
The method runs only when the sent data is validated.
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.');
}
}
We can register the input elements in the init()
method of the form class and apply the rules of validation and sanitation.
Please refer to Rules To Validate Fields of Aura.Filter with respect to validation rules, and Rules To Sanitize Fields with respect to sanitize rules.
We validate an associative array of the argument of the method.
If we want to change the input, we can set the values by implementing submit()
method of SubmitInterface
interface.
@FormValidation Annotation
Annotate the method that we want to validate with the @FormValidation
, so that the validation is done in the form object specified by the form
property before execution.
When validation fails, the method with the ValidationFailed
suffix is called.
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
* // or
* @FormValidation(form="form", onFailure="onPostValidationFailed")
*/
public function onPost($name, $age)
{
// validation success
}
public function onPostValidationFailed($name, $age)
{
// validation failed
}
}
We can explicitly specify the name and the method by changing the form
property of @FormValidation
annotation or the onValidationFailed
property.
The submit parameters will be passed to the onPostValidationFailed
method.
View
Specify the element name to get the input
elements and error messages
$form->input('name'); // <input id="name" type="text" name="name" size="20" maxlength="20" />
$form->error('name'); // "Please enter a double-byte characters or letters in the name." or blank
The same applies to Twig template
{{ form.input('name') }}
{{ form.error('name') }}
CSRF Protections
We can add a CSRF(Cross site request forgeries) object to the form to apply CSRF protections.
use Ray\WebFormModule\SetAntiCsrfTrait;
class MyForm extends AbstractAuraForm
{
use SetAntiCsrfTrait;
In order to increase the security level, add a custom CSRF class that contains the user authentication to the form class. Please refer to the Applying CSRF Protections of Aura.Input for more information.
@InputValidation annotation
If we annotate the method with @InputValidation
instead of @FormValidation
, the exception Ray\WebFormModule\Exception\ValidationException
is thrown when validation fails.
For convenience, HTML representation is not used in this case.
When we echo
the error
property of the caught exception, we can see the representation of the media type application/vnd.error+json.
http_response_code(400);
echo $e->error;
// {
// "message": "Validation failed",
// "path": "/path/to/error",
// "validation_messages": {
// "name": [
// "Please enter a double-byte characters or letters in the name."
// ]
// }
// }
We can add the necessary information to vnd.error+json
using @VndError
annotation.
/**
* @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()
FormVndErrorModule
If we install Ray\WebFormModule\FormVndErrorModule
, the method annotated with @FormValidation
will throw an exception in the same way as the method annotated with @InputValidation
.
We can use the page resources as API.
class FooModule extends AbstractModule
{
protected function configure()
{
$this->install(new AuraInputModule);
$this->override(new FormVndErrorModule);
}
}
Demo
Try the demo app MyVendor.ContactForm to get an idea on how forms such as a confirmation form and multiple forms in a single page work.