How do I validate if array is empty? - php

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

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()];
}

Validate a field: required_if the url contains parameter in Laravel

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);

Laravel custom validation rule

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 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 to validate multiple email in laravel validation?

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

Categories