How to validate multiple email in laravel validation? - php

I have done all the things for the validation for the variable in laravel but for emails I got one simple problem.
From doc of Laravel,
'email' => 'required|email'
I got to know this is for only one email address but for like,
email=abc#xyz.com,xyz#abc.com, def#ghi,com
When I send array of the email i still get email is not a valid email.
I have done more like,
'email' => 'required|email|array'
But I still got error. can any body help.
Thanks,

You need to write custom Validator, which will take the array and validate each ofthe emails in array manually. In Laravel 5 Request you can do something like that
public function __construct() {
Validator::extend("emails", function($attribute, $value, $parameters) {
$rules = [
'email' => 'required|email',
];
foreach ($value as $email) {
$data = [
'email' => $email
];
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
return false;
}
}
return true;
});
}
public function rules() {
return [
'email' => 'required|emails'
];
}

In 5.6 or above you can define your validator rule as follows:
'email.*' => 'required|email'
This will expect the email key to be an array of valid email addresses.

We can achieve this without custom validation,We can overridden a method prepareForValidation
protected function prepareForValidation()
{
//Here email we are reciving as comma seperated so we make it array
$this->merge(['email' => explode(',', rtrim($this->email, ','))]);
}
Then above function will call automatically and convert email-ids to array, after that use array validation rule
public function rules()
{
return [
'email.*' => 'required|email'
];
}

Laravel 5.2 introduced array validation and you can easily validate array of emails :)
All you need is exploding the string to array.
https://laravel.com/docs/5.2/validation#validating-arrays

I did it like this. Working good for me.
if email or emails (email1#gmail.com, email2#yahoo.com, email3#gmail.com) are coming from a Form like this following custom validator works. This need to be added to - AppServiceProvider.php - file. And new rule is - 'emails'.
/**
* emails
* Note: this validates multiple emails in coma separated string.
*/
Validator::extend('emails', function ($attribute, $value, $parameters, $validator) {
$emails = explode(",", $value);
foreach ($emails as $k => $v) {
if (isset($v) && $v !== "") {
$temp_email = trim($v);
if (!filter_var($temp_email, FILTER_VALIDATE_EMAIL)) {
return false;
}
}
}
return true;
}, 'Error message - email is not in right format');
And in your controller, it can be used like this:
$this->validate($request, [
'email_txt_area' => 'emails',
]);

If you don't want to override prepareForValidation just because of one rule here's another approach using closures:
$rules = [
'name' => 'required|string|max:255',
'email' => [
'required',
function ($attribute, $value, $fail) {
$emails = array_map('trim', explode(',', $value));
$validator = Validator::make(['emails' => $emails], ['emails.*' => 'required|email']);
if ($validator->fails()) {
$fail('All email addresses must be valid.');
}
},
],
];
Tested with Laravel 9.x

Related

Is there a way to display which element in an array failed validation?

I'm using a Class extends Laravel's FormRequest class. I have arrays incoming, so I have rules like:
public function rules()
{
return [
'name' => 'required',
'name.*.value' => 'required',
'email' => 'required',
'email.*.value' => 'required|email',
];
}
Basicly when I do my Ajax call it returns 422 with message for eg:
The name.0.value field is required.
I want it to be something like : The {index}th name is required.
public function messages()
{
return [
'email.*.value.required' => 'Recipient email field is required',
'email.*.value.email' => 'Wrong e-mail format',
];
}
Is there an option to include the * somehow in the message? Or am I supposed to process it with JQuery?
Thanks in advance.
Try to use loop like this:
public function messages() {
$messages = [];
foreach ($this->get('email') as $key => $val) {
$messages["email.$key.value.required"] = "email $key is required";
$messages["email.$key.value.email"] = "email $key is wrong e-mail format";
}
return $messages;
}
I have refactored the code a little bit, to suit my style. It's working like this as well, if someone like this style more. Of course TsaiKoga's answer is flawless, and good to go with it!
public function messages(){
$messages=[];
foreach ($this->get('email') as $key => $val) {
$messages = [
"email.$key.value.required" => "$key th e-mail is required",
"email.$key.value.email" => "$key th e-mail is wrong e-mail format",
"name.$key.value.required" => "$key th name is required"];
}
return $messages;
}
$rules = [
'name' => 'required',
'password' => 'required',
'email' => 'required|email'
];
$validator = Validator::make($request->only('name','password','email'), $rules);
if ($validator->fails()) {
$messages = $validator->errors()->messages();
return response()->json(['status' => 'error', 'messages' => $messages]);}

validate on array parameter igoners my rules and update

I have a function that updates the data. It receives the data as an array parameter.
I tried use validator make, and also validate helper method but it didn't work because it's only work for requests, and i tried also in validator make as the code below and also 'params.name' but it didn't work.
public function updateCompany(array $params): bool
{
if( Validator::make($params,[
'name'=> 'required|min:3|unique:company',
'email'=> 'required|min:4|unique:company|email'
])) {
return $this->update($params);
}
}
After trying this it didn't give me any error put it ignores my validation rules and update anyway.
Just use
public function updateCompany(Request $request)
then you could do something like this:
$rules = array('name' => 'required',
'email' => 'email|required|unique:users',
'name' => 'required|min:6|max:20');
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return ['status' => 422, 'errors' => $validator->errors()];
}

How to validate an Input Array field in Laravel 5.1?

How can I write rule for input field like below:
{!! Form::number("amount[]",null,['min' => 0, 'class' => 'form-control col-xs-2 ']) !!}
I tried following which gave error: htmlentities() expects parameter 1 to be string, array given
$rules = array(
'amount[]' => 'required'
);
$this->validate($request, $rules);
Update:
I tried this as suggested by a user, it's not redirecting it on page again. Below is controller method:
public function postEstimate(Request $request) {
$rules = array(
'amount' => 'required|array'
);
$this->validate($request, $rules);
}
I guess you got issues with what I explained so this is what I meant -
$rules = [];
$count_amounts = count($request->input('amount'));
foreach (range(0, $count_amounts) as $number) {
$rules['amount.' . $number] = 'required|integer|min:0';
}
This should check that each amount input you have is an integer and is bigger than 0 (like you defined in the html validation)
Instead try this:
private $rules = array(
'amount' => 'required|array',
);
public function postEstimate(Request $request) {
$this->validate($request, $this->rules);
}
or, try a validation with a 'amount' => 'required
im not sure about this 'amount' => 'required|array
For custom rules implementation of integer type value check of an array
firstly open the following file
/resources/lang/en/validation.php
Then add the custom message
'numericarray' => 'The :attribute must be numeric array value.',
'requiredarray' => 'The :attribute must required all element.',
Again open the another file
/app/Providers/AppServiceProvider.php
Now add custom validation code in the boot function.
public function boot()
{
$this->app['validator']->extend('numericarray', function ($attribute, $value, $parameters)
{
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
});
$this->app['validator']->extend('requiredarray', function ($attribute, $value, $parameters)
{
foreach ($value as $v) {
if(empty($v)){
return false;
}
}
return true;
});
}
Now you can use the requiredarray for all element required of array. And also use the numericarray for integer type value check of array
$this->validate($request, [
'field_name1' => 'requiredarray',
'field_name2' => 'numericarray'
]);
if you expect amount as an array the rules should be
$rules = array(
'amount' => 'required|array'
);
check the doc
If your not redirecting or getting a validation error means there is no validation error
just dd($request->input('amount')) in the controller and check its a array or not if it's a array then validations will pass.

How do I validate if array is empty?

I have a form with 5 multiple-choice dropdown lists. When submitted, I am trying to run some validation to check that at least one item has been checked.
The code in my controller;
$input = Request::except('postcode_id'); //all user input from the form
$validator = \Validator::make(
[
$input => 'required'
]
);
if ($validator->fails())
{
print "failed";
}else{
print "passed";
}
The error I get is; Illegal offset type. I think I might need to do a custom validator but would like to check first in case there is an easier way.
The first argument of Validator::make() is the data, and the second is an array of validation rules, which are indexed by the input names. You can use required_without_all to validate that at least one must be present, but it is a little verbose:
$validator = \Validator::make($input, [
'dropdown_1' => 'required_without_all:dropdown_2,dropdown_3,dropdown_4,dropdown_5'
'dropdown_2' => 'required_without_all:dropdown_1,dropdown_3,dropdown_4,dropdown_5'
'dropdown_3' => 'required_without_all:dropdown_1,dropdown_2,dropdown_4,dropdown_5'
'dropdown_4' => 'required_without_all:dropdown_1,dropdown_2,dropdown_4,dropdown_5'
'dropdown_5' => 'required_without_all:dropdown_1,dropdown_2,dropdown_3,dropdown_4'
]);
Or write some code to generate the $rules array:
$fields = ['dropdown_1', 'dropdown_2', 'dropdown_3', 'dropdown_4', 'dropdown_5'];
$rules = [];
foreach ($fields as $i => $field) {
$rules[$field] = 'required_without_all:' . implode(',', array_except($fields, $i));
}
$validator = \Validator::make($input, $rules);
You need to use strings in your validator, not variables. Try this instead.
$validator = \Validator::make(
[
'input' => 'required'
]
);
Custom validator itself is not too difficult. I am using it all the time for array input validation. In Laravel 5 Request I will do something like that
public function __construct() {
Validator::extend("pcc", function($attribute, $value, $parameters) {
$rules = [
'container_id' => 'exists:containers,id'
];
foreach ($value as $containerId) {
$data = [
'container_id' => $containerId
];
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
return false;
}
}
return true;
});
}
public function rules() {
return [
'containers' => 'required|pcc',
];
}

How do I validate an array of integers in Laravel

I have an array of integer like this $someVar = array(1,2,3,4,5). I need to validate $someVar to make sure every element is numeric.How can I do that?
I know that for the case of a single valued variable, the validation rule would be something like this $rules = array('someVar'=>'required|numeric'). How can I apply the same rule to every element of the array $someVar?
Thanks a lot for helping.
Now laravel has option to set condition on array elements. No need to write your own validator for simple things like validation int array. Use this (if using in controller)-
$validator = \Validator::make(compact('someVar'), [
'someVar' => 'required|array',
'someVar.*' => 'integer'
]);
$this->validateWith($validator);
or
$this->validate($request, [
'someVar' => 'array',
'someVar.*' => 'int'
]);
Validator::extend('numericarray', function($attribute, $value, $parameters)
{
foreach($value as $v) {
if(!is_int($v)) return false;
}
return true;
});
Use it
$rules = array('someVar'=>'required|array|numericarray')
Edit:
Up to date version of this validation would not require the definition of numericarray method.
$rules = [
'someVar' => 'required|array',
'someVar.*' => 'integer',
];
In Laravel 5 you can check the elements in an array by using .*. For you this would mean:
$rules = array('someVar' => 'required|array',
'someVar.*' => 'integer')
Start with adding a new validation attribute
Validator::extend('numeric_array', function($attribute, $values, $parameters)
{
if(! is_array($values)) {
return false;
}
foreach($values as $v) {
if(! is_numeric($v)) {
return false;
}
}
return true;
});
The function will return false if attribute is not an array or if one value is not a numeric value. Then add message to `app/lang/en/validation.php'
"numeric_array" => "The :attribute field should be an array of numeric values",
You can add custom rules for integer type value check of array
Just open file
/resources/lang/en/validation.php
Add the custom message before "accepted" message in the file.
'numericarray' => 'The :attribute must be numeric array value.',
"accepted" => "The :attribute must be accepted.",
Now Open the file
/app/Providers/AppServiceProvider.php
and then add the custom validation in boot function.
public function boot()
{
$this->app['validator']->extend('numericarray', function ($attribute, $value, $parameters)
{
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
});
}
Now you can use the numericarray for integer type value check of array
$this->validate($request, [
'field_name1' => 'required',
'field_name2' => 'numericarray'
]);
There is only the 'array' validation which ensures that the value is an array, but for your specific case you will have to create a custom filter:
Laravel 3: http://three.laravel.com/docs/validation#custom-validation-rules
Laravel 4: http://laravel.com/docs/validation#custom-validation-rules
AppServiceProvider.php
Validator::extend('integer_array', function($attribute, $value, $parameters)
{
return Assert::isIntegerArray($value);
});
Assert.php
/**
* Checks wheter value is integer array or not
* #param $value
* #return bool
*/
public static function isIntegerArray($value){
if(!is_array($value)){
return false;
}
foreach($value as $element){
if(!is_int($element)){
return false;
}
}
return true;
}

Categories