Laravel 5.6 validate required_without multiple - laravel

I use laravel 5.6 and I try to use validate to check my input.
But I have an issue with required_without.
I have 4 input : heure_bureau / heure_supp_bureau / heure_terrain / heure_supp_terrain
I must fill one input at least. So if I fill heure_bureau, the others aren't necessary.
So I use this code :
$validator = \Validator::make($request->all(), [
'heures_bureau' => 'nullable|date_format:"H\hi"|required_without:heures_supp_bureau,heures_terrain,heures_supp_terrain|before:07h45',
'heures_supp_bureau' => 'nullable|date_format:"H\hi"|required_without:heures_bureau,heures_terrain,heures_supp_terrain|before:13h15',
'heures_terrain' => 'nullable|date_format:"H\hi"|required_without:heures_bureau,heures_supp_bureau,heures_supp_terrain|before:07h45',
'heures_supp_terrain' => 'nullable|date_format:"H\hi"|required_without:heures_bureau,heures_supp_bureau,heures_terrain|before:13h15'
], $messages);
But it doesn't work. I have an error for each other input when I fill one.
If I use requried_without with only one input, it work well but not when I use it with multiple inputs.
Where am I wrong ?
Thank for your help !

try this:
$validator = \Validator::make($request->all(), [
'heures_bureau' => 'nullable|date_format:"H\hi"|required_without_all:heures_supp_bureau,heures_terrain,heures_supp_terrain|before:07h45',
'heures_supp_bureau' => 'nullable|date_format:"H\hi"|required_without_all:heures_bureau,heures_terrain,heures_supp_terrain|before:13h15',
'heures_terrain' => 'nullable|date_format:"H\hi"|required_without_all:heures_bureau,heures_supp_bureau,heures_supp_terrain|before:07h45',
'heures_supp_terrain' => 'nullable|date_format:"H\hi"|required_without_all:heures_bureau,heures_supp_bureau,heures_terrain|before:13h15'
], $messages);

Related

Laravel 5.6. How to test JSON/JSONb columns

$this->assertDatabaseHas() not working with JSON/JSONb columns.
So how can I tests these types of columns in Laravel?
Currently, I have a store action. How can I perform an assertion, that a specific column with pre-defined values was saved.
Something like
['options->language', 'en']
is NOT an option, cause I have an extensive JSON with meta stuff.
How can I check the JSON in DB at once?
UPD
Now can be done like that.
I have solved it with this one-liner (adjust it to your models/fields)
$this->assertEquals($store->settings, Store::find($store->id)->settings);
Laravel 7+
Not sure how far back this solution works.
I found out the solution. Ignore some of the data label, Everything is accessible, i was just play around with my tests to figure it out.
/**
* #test
*/
public function canUpdate()
{
$authUser = UserFactory::createDefault();
$this->actingAs($authUser);
$generator = GeneratorFactory::createDefault();
$request = [
'json_field_one' => [
'array-data',
['more-data' => 'cool'],
'data' => 'some-data',
'collection' => [
['key' => 'value'],
'data' => 'some-more-data'
],
],
'json_field_two' => [],
];
$response = $this->putJson("/api/generators/{$generator->id}", $request);
$response->assertOk();
$this->assertDatabaseHas('generators', [
'id' => $generator->id,
'generator_set_id' => $generator->generatorSet->id,
// Testing for json requires arrows for accessing the data
// For Collection data, you should use numbers to access the indexes
// Note: Mysql dose not guarantee array order if i recall. Dont quote me on that but i'm pretty sure i read that somewhere. But for testing this works
'json_field_one->0' => 'array-data',
'json_field_one->1->more-data' => 'cool',
// to access properties just arrow over to the property name
'json_field_one->data' => 'some-data',
'json_field_one->collection->data' => 'some-more-data',
// Nested Collection
'json_field_one->collection->0->key' => 'value',
// Janky way to test for empty array
// Not really testing for empty
// only that the 0 index is not set
'json_field_two->0' => null,
]);
}
Note: The below solution is tested on Laravel Version: 9.x and Postgres version: 12.x
and the solution might not work on lower version of laravel
There would be two condition to assert json column into database.
1. Object
Consider Object is in json column in database as shown below:
"properties" => "{"attributes":{"id":1}}"
It can assert as
$this->assertDatabaseHas("table_name",[
"properties->attributes->id"=>1
]);
2. Array
Consider array is in json column as shown below:
"properties" => "[{"id":1},{"id":2}]"
It can assert as
$this->assertDatabaseHas("table_name",[
"properties->0->id"=>1,
"properties->1->id"=>2,
]);
Using json_encode on the value worked for me:
$this->assertDatabaseHas('users', [
'name' => 'Gaurav',
'attributes' => json_encode([
'gender' => 'Male',
'nationality' => 'Indian',
]),
]);

Laravel:file extension validation

I am using laravel 5.2 ,i use image rule to validate images uploaded by user,which requires php_fileinfo extension to be installed ,but is there a way to validate images only for there extensions like .png,.jpg etc?
Use mimes
'photo' => 'mimes:jpeg,bmp,png'
You can add the mime type to your validation like you would add any other rule:
$rules = [
'image' => 'required|image|mimes:gif,png'
];
Source: https://laravel.com/docs/5.5/validation#rule-mimes
yes you can by using mimes validation rule
Try this.
$validator = Validator::make(
[
'file' => $request->file,
'extension' => strtolower($request->file>getClientOriginalExtension()),
],
[
'file' => 'required',
'extension' =>'required|in:txt',
]
);

Laravel input file validation

I'm trying to make my validator working but for some reason it only accepts the pdf files. I want to make the validator works for all of them.
$filePathTemp = Input::file('cv');
$file = array('cv' => $filePathTemp);
$rules = array('cv' => 'mimes:doc,pdf,docx');
$validator = Validator::make($file, $rules);
Any idea why this solution isn't working?
put this code
$validator = Validator::make($request->all(), [
'file' => 'required|max:10000|mimes:doc,docx,pdf'
]);
and in config/mimes.php add the below mime types:
'doc' => array('application/msword', 'application/vnd.ms-office'),
'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip'),
Hope this may help you!
I think you can try this:
$validator = Validator::make($request->all(), [
'cv' => 'mimes:doc,pdf,docx'
]);
Hope this work for you!!!
it worked adding the txt type to the other mimes

Laravel Validation custom messages using nested attributes

I would like to ask for some advices about Laravel Validation...
Let's say I've got an input named invoiceAddress[name] and in a controller I've got a rule
$rule = ['invoiceAddress.name' => 'required',];
or just a
$validator = \Validator::make($request->all(), [
'invoiceAddress.name' => 'required',
]);
now, inside custom validation language file validation.php, am I able to nest attributes somehow? like:
'required' => ':attribute is mandatory',
'attributes' => [
'invoiceAddress' => [
'name' => 'blahblah'
],
],
If I try to nest the attribute the way above, i get
ErrorException
mb_strtoupper() expects parameter 1 to be string, array given
because I am using a field (as above)
['name' => 'blahblah']
I am trying to get custom messages using the file and the :attribute directive (as mentioned in the code above).
I am basically trying to do this How to set custom attribute labels for nested inputs in Laravel but i get the mentioned error...
Thank you in advance...
A Note On Nested Attributes
If your HTTP request contains "nested" parameters, you may specify them in your validation rules using "dot" syntax:
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'author.name' => 'required',
'author.description' => 'required',
]);
Reference: https://laravel.com/docs/5.3/validation#quick-writing-the-validation-logic (A Note On Nested Attributes Section)

Validating Matching Strings

When I use the Validation feature in Laravel, how can I add a pre-defined strings that are allowed in an Input?
For example, let's say I want the Input to contain only one of the following: foo,bar,baz, how can I do that?
$validator = Validator::make($credentials, [
'profile' => 'required|max:255', // Here I want Predefined allowed values for it
]);
Best to use the 'in' validation rule like this:
$validator = Validator::make($credentials, [
'profile' => ["required" , "max:255", "in:foo,bar,baz"]
]);
It is recommended in Laravel docs to put the validation rules in an array when they get bigger and I thought 3 rules were sufficient. I think it makes it for a more readable content but you do not have to. I added the regex portion below and I have it works. I am not that great with regexing stuff. Let me know.
$validator = Validator::make($credentials, [
'profile' => ["required" , "max:255", "regex:(foo|bar|baz)"]
]);
Works for me in Laravel 9:
use Illuminate\Validation\Rule;
 
Validator::make($data, [
'toppings' => [
'required',
Rule::notIn(['sprinkles', 'cherries']),
],
]);
Docs: https://laravel.com/docs/9.x/validation#rule-not-in
For the opposite you could use Rule::in(['foo', 'bar', 'baz'])

Resources