Validation
Ice\Validation is an independent validation component that allows to validate any array data eg. $_POST, $_GET, $_FILES, etc.
Let's try to validate $data
with some email rules:
use Ice\Validation;
use Ice\Validation\Validator\Email;
use Ice\Validation\Validator\Required;
use Ice\Validation\Validator\Same;
$data = [
'emailAddress' => '',
'repeatEmailAddress' => 'user@example.com',
];
$validation = new Validation();
$validation->rule('emailAddress', new Required());
$validation->rule('emailAddress', new Email());
$validation->rule('repeatEmailAddress', new Same(['other' => 'emailAddress']));
$validation->validate($data);
if (!$validation->valid()) {
$messages = $validation->getMessages();
}
In the messages
variable you should have:
var_dump($messages->all());
array(2) {
["emailAddress"]=>
array(1) {
[0]=>
string(30) "Field emailAddress is required"
}
["repeatEmailAddress"]=>
array(1) {
[0]=>
string(52) "Field repeatEmailAddress and emailAddress must match"
}
}
Add multiple rules
You can add multiple rules at once:
$validation->rules([
'emailAddress' => [
new Required(),
new Email()
],
'repeatEmailAddress' => new Same(['other' => 'emailAddress'])
]);
Array way
You can add multiple rules at once in the array way:
$validation->rules([
'emailAddress' => [
'required',
'email'
],
'repeatEmailAddress' => [
'same' => [
'other' => 'emailAddress'
]
]
]);
Short syntax
The same in the short syntax:
$validation->rules([
'emailAddress' => 'required|email',
'repeatEmailAddress' => 'same:emailAddress'
]);
Set the human labels in the messages
$validation->setHumanLabels(true);
var_dump($messages->all());
array(2) {
["emailAddress"]=>
array(1) {
[0]=>
string(31) "Field Email address is required"
}
["repeatEmailAddress"]=>
array(1) {
[0]=>
string(55) "Field Repeat email address and Email address must match"
}
}
Set the custom messages and custom labels
// ...
'repeatEmailAddress' => [
'same' => [
'other' => 'emailAddress',
'message' => ':field must be the same as :other',
'label' => 'Repeat E-mail',
'labelOther' => 'E-mail'
]
]
// ...
["repeatEmailAddress"]=>
array(1) {
[0]=>
string(40) "Repeat E-mail must be the same as E-mail"
}
}
Also you can overwrite default messages and labels by setDefaultMessages()
and setLabels()
methods.
Translation
The messages and labels are translated by default, so if you have in the pl.php
lang file (Polish language):
return [
'Field :field is required' => 'Pole <em>:field</em> jest wymagane',
'Field :field and :other must match' => 'Pole <em>:field</em> i <em>:other</em> muszą się zgadzać',
'emailAddress' => 'Adres email'
'repeatEmailAddress' => 'Powtórz email'
];
Messages:
array(2) {
["emailAddress"]=>
array(1) {
[0]=>
string(41) "Pole <em>Adres email</em> jest wymagane"
}
["repeatEmailAddress"]=>
array(1) {
[0]=>
string(80) "Pole <em>Powtórz email</em> i <em>Adres email</em> muszą się zgadzać"
}
}
The Ice\I18n componet must be set to the
i18n
service in the di.
Filters
You can add some filter to be sure to retreive valid value after validation:
$data = [
'username' => 'ice-123_framework'
];
$validation = new Validation();
$validation->setFilters([
'username' => 'alpha'
]);
$validation->validate($data);
var_dump($validation->getValue('username'));
string(12) "iceframework"
In this way you can simply escape string, remove repeats, or cast values to int
, float
, etc.
The Ice\Filter componet must be set to the
filter
service in the di.
Validating Models
In the models there is implemented the autovalidation, so you can simply validate some Ice\Mvc\Model fields during creating. Just specify rules
property:
namespace App\Models;
use Ice\Mvc\Model;
class Users extends Model
{
protected $rules = [
'username' => 'required|length:4,24|regex:/[a-z][a-z0-9_-]{3,}/i|notIn:admin,index,user,root|unique:users',
'password' => 'required|length:5,32',
'email' => 'required|email|unique:users',
];
}
And fetch messages if fields are not valid:
$user = new Users();
if ($user->create($data) !== true) {
$messages = $user->getMessages();
}
Extra validation
Add extra validation for fields that won't be save but must pass:
$extra = new Validation($data);
$extra->rules([
'repeatPassword' => 'same:password',
'repeatEmail' => 'same:email',
]);
if ($this->create($data, $extra) !== true) {
$messages = $user->getMessages();
}
During updating the validation is not being used by default. Before
update()
you should run:$user->setValidation($validation);
Valid fields
You can specify valid fields and only them will be saved:
$user = new Users();
$user->username = 'ice';
$user->password = 'secret';
$user->email = 'user@example.com';
if ($user->create(['username', 'password']) !== true) {
$messages = $user->getMessages();
}
The email
field won't be saved.
Or globally in the fields
property:
class Users extends Model
{
protected $fields = [
'email',
'username',
'password'
];
}
if ($user->create($_POST) !== true) {
$messages = $user->getMessages();
}
Then only email
, username
, and password
will be taken from the $_POST.
Model hooks
You can add hooks to run some code before or after model's validation:
class Users extends Model
{
public function create($fields = [], Validation $extra = null)
{
$this->di->hook('model.after.validate', function ($this) {
$this->set('password', md5($this->get('password')));
});
return parent::create($fields, $extra);
}
}