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',
];
}
Related
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()];
}
Is there any way to validate required field when the requested url contains some parameter?
Assuming you are using Form requsts, you can simple use PHP condition.
public function rules()
{
$rules = []; // here you put some rules
// here you check condition and add some rule when it's true
if (str_contains($this->input('url'), 'something')) {
$rules['some_other_field'] = 'required';
}
return $rules;
}
You need to first check the route before validating....
$roles =[
'title' => 'required|unique:posts|max:255',
'author.name' => 'required',
'author.description' => 'required',
];
if(Route::getCurrentRoute()->getPath() == "xxxxx"){
$role['desc'] = 'required'
}
if(\Request::route()->getName() == "yyyy"){
$role['desc'] = 'required'
}
if($request->is('admin/*')){
$role['desc'] = 'required'
}
$this->validate($request, $role);
How can i make a custom validation rule to an input which value must be an integer and starting with 120?
I already read about making custom messages but didnt understand about rules.
I want to use a regex to validate the data. ^120\d{11}$ here is my regex.
I'm new in Laravel that's why cant now imagine how to do that.
A custom validation to use it in $this->validate($request, []);
Now i'm validating data like so:
$this->validate($request, [
'user_id' => 'integer|required',
'buy_date' => 'date',
'guarantee' => 'required|unique:client_devices|number',
'sn_imei' => 'required|unique:client_devices',
'type_id' => 'integer|required',
'brand_id' => 'integer|required',
'model' => 'required'
]);
The input that i want to add custom validation is guarantee
The quickest neatest way is an inline validator in your controller action:
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'number' => [
'regex' => '/^120\d{11}$/'
],
]);
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
return view('welcome');
}
Where number is the name of the field being submitted in the request.
If you have a lot of validation to do, you might want to consider using a Form Request instead, as a way of consolidating a lot of validation logic.
You can create custom validations in your controller as:
$name = Input::get('field-name')
$infoValidation = Validator::make(
array( // Input array
'name' => $name,
),
array( // rules array
'name' => array("regex:/^120\d{11}$"),
),
array( // Custom messages array
'name.regex' => 'Your message here',
)
); // End of validation
$error = array();
if ($infoValidation->fails())
{
$errors = $infoValidation->errors()->toArray();
if(count($errors) > 0)
{
if(isset($errors['name'])){
$response['errCode'] = 1;
$response['errMsg'] = $errors['name'][0];
}
}
return response()->json(['errMsg'=>$response['errMsg'],'errCode'=>$response['errCode']]);
}
Hope this helps.
Since Laravel 5.5, you can make the validation directly on the request object.
public function store(Request $request)
{
$request->validate([
'guarantee' => 'regex:/^120\d{11}$/'
]);
}
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.
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