Image validation doesn't work in Laravel Voyager - php

I have used validation for image in Laravel Voyager BREAD. But it doesn't work. It takes all dimension of images.
Here is my code
{
"validation": {
"rule": "dimensions:width=100,height=100",
"messages": {
"dimensions": "This :attribute field is a must."
}
}
}
Image for more clarification:

You can try a creating a rule since this requires several arguments
use Illuminate\Validation\Rule;
Validator::make($data, [
'image' => [
'required',
Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
],
]);

From the docs you need to add mimes rule, and use dimensions rule like:
'rule' => 'mimes:jpeg,bmp,png|dimensions:width=340,height=960'

Related

Dimensions validation in Laravel 5.8 is not working

I am using the following code to validate the dimensions of the image in Laravel 5.8 (link to following code):
'profile_image' => 'required|dimensions:width=300,height=500'
but I am getting the error eventhough I attached exact 300x500 image, look at the following code:
list($width, $height) = getimagesize($request->profile_image);
$messages = [
'profile_image.dimensions' => "Profile image must be 300x500 resolution (current is {$width}x{$height})."
];
$request->validate([
'profile_image' => 'required|dimensions:width=300,height=500',
], $messages);
I am getting this "Profile image must be 300x500 resolution (current is 300x500)".
I also tried min_width=300,min_height=500 and max_width=300,max_height=500 but not working.
Image is in base64 format (I think it doesn't matter)
Any suggestions?
This works for me:
'profile_image' => [
'required',
Rule::dimensions()->width(300)->height(500)
]

Laravel 5.5 "The file must be an image" on image array

I am working on a Laravel 5.5 project which is giving me some issues... One of them is that when I upload some image it returns me an error: "The file must be an image" with the following code in the controller.`
public function update(\App\Property $property, Request $request)
{
$rules = [
'images.*' => 'mimes:image|max:2048',
'zone' => 'required'
];
$messages = [
'images.mimes' => 'The file must be an image', // in my file that is a translated of the original message
'images.max' => 'The images sizes must be under 2MB',
];
$validator = Validator::make($request->all(), $rules, $messages);
if($validator->fails()) {
parent::message(
$validator->errors(),
'¡Error!',
'error'
);
return back()->withInput();
}
Just in case:
I was reading some people who had the same issue but in my case I have the usual <form method="POST action="..." enctype="multipart/form-data">
I made a dd($request->files) on the request but the all the images I upload seems to be images.
Also I've tried to use the iteration method as following:
if($request->hasFile('images')) {
foreach ($images as $image)
{
$validator = Validator::make(
[ 'image' => $image ],
[ 'image' => 'mimes:jpeg,png,jpg,gif,svg|max:2048' ],
[
'image.mimes' => 'Images must have format (JPEG, PNG, JPG, GIF or SVG)',
'image.max' => 'Each image must be under 2MB'
]);
if($validator->fails()) {
parent::message(
$validator->errors(),
'¡Error!',
'error'
);
return back()->withInput();
}
}
}
But when the images are too bigger than 2MB the request is not even passing through if($request->hasFile() function.
And I want a generic error for all the images and not validate every image, is that possible? By the way in the Laravel Documentation it hasn't the previous iterating method.
I was trying to figure this out as well and it seems symfony has been updated since Laravel 5.5. On Laravel 8 I can tell you that the following combination of settings fixed the error I had yielding the same error type you had:
In your form:
make sure your form has
<form method="POST action="..." enctype="multipart/form-data">
In your validator:
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
In the event that you are using Laravel Collectives for your form, then you can implement the enctype as show below :
{!! Form::open([‘action’ =>’ProfilesController#update’,
‘method’ => ‘POST’, ‘enctype’ => ‘multipart/form-data’]) !!}

Laravel validating required at least one element in array

I am trying to post the following data to an endpoint built up on Laravel.
{
"category": "2",
"title": "my text goes here",
"difficulty": 1,
"correct": {
"id": "NULL",
"text": "Correct"
},
"wrong": [
{
"id": "NULL",
"text": ""
},
{
"id": "NULL",
"text": ""
},
{
"id": "NULL",
"text": ""
}
]
}
and I have the following validation rules.
return [
'correct' => 'required|array',
'correct.text' => 'required',
'wrong' => 'required|array|between:1,3'
];
What I am trying to accomplish is the wrong should be and array and it should contain at least one element and should not exceed 3. Now these rules are satisfying, but there is one more case I need to take care and that is the validation of the text in wrong . With the current rules, if I post the above data, it will accept as there is no rule in place for the text in the wrong section. Which rule I need to add to validate that the wrong section at least contains one entry with a not empty text.
tl;dr
If you have very specific needs for a validator rule, you can always create your own.
Create a Custom Validator
The scheme will be: properties_filled:propertyName:minimumOccurence. This rule will check if the field under validation:
Is an array.
Its elements have at least minimumOccurence amounts of non empty (!== '') values among element properties called propertyName.
In your app/Providers/AppServiceProvider.php file's boot method, you can add the custom rule implementation:
public function boot()
{
Validator::extend('properties_filled', function ($attribute, $value, $parameters, $validator) {
$validatedProperty = $parameters[0];
$minimumOccurrence = $parameters[1];
if (is_array($value)) {
$validElementCount = 0;
$valueCount = count($value);
for ($i = 0; $i < $valueCount; ++$i) {
if ($value[$i][$validatedProperty] !== '') {
++$validElementCount;
}
}
} else {
return false;
}
return $validElementCount >= $minimumOccurrence;
});
}
Then you can use it in your validation like this:
return [
'correct' => 'required|array',
'correct.text' => 'required',
'wrong' => 'required|between:1,3|properties_filled:text,1'
];
Testing
Note: I assumed that you parse your JSON data with json_decode's $assoc parameter set to true. If you use an object then change the $value[$i][$validatedProperty] !== '' in the condition to: $value[$i]->{$validatedProperty} !== ''.
Here is my example test:
$data = json_decode('{"category":"2","title":"mytextgoeshere","difficulty":1,"correct":{"id":"NULL","text":"Correct"},"wrong":[{"id":"NULL","text":""},{"id":"NULL","text":""},{"id":"NULL","text":""}]}', true);
$validator = Validator::make($data, [
'correct' => 'required|array',
'correct.text' => 'required',
'wrong' => 'required|between:1,3|properties_filled:text,1'
]);
$validator->fails();
Take advantage of the validation rule in
EDIT: I assume that wrong will have a specific value, therefore pass that value in this way
return [
'correct' => 'required|array',
'correct.text' => 'required',
'wrong' => 'required|array|between:1,3',
'wrong.text' => 'sometimes|min:1|in:somevalue,someothervalue',
];
The sometimes validation makes sure that field is checked only if exists. To check that there will be at least
I'm not sure, but does min suffice to your request? Otherwise you have to write a custom validation rule as someone else suggested
I got the same issue while trying to validate an array on the API side. I made a solution. try this
$validator = Validator::make($request->all(), [
'target_user_ids' => 'required',
'target_user_ids.*' => 'present|exists:users,uuid|distinct',
]);
if ($validator->fails()) {
return response()->json([
'status' => false,
'error' => $validator->errors()->first(),
], 400);
}
If you want to validate input fields in array, you can define your rules like this:
return [
'correct' => 'required|array',
'correct.text' => 'required',
'wrong' => 'required|array|between:1,3',
'wrong.*.text' => 'required|string|min:1',
];

Custom error messages in package for Laravel 5.x

I am creating a package for Laravel 5.4 and have a few custom regexes with error messages. Normally you put these messages in de validation.php file (which works). But when installing a package I want the user to not have to copy paste those in.
Is there way for a package to have an extra validation language file that will automatically be called when the rule is not found in the regular validation language file?
OK Figured it out.
If you're using Validator::make() call. You can do this
$fields = [
"fieldA" => "Testing",
"fieldB" => "TextB",
];
$rules = [
"fieldA" => [
"alpha",
],
"fieldB" => [
"regex:/TextC/",
],
];
$messages = [
"fieldA.alpha" => "Sorry champ, but fieldA must be only characters",
"fieldB.regex" => "The regex failed here",
];
$validator = Validator::make($fields, $rules, $messages);
if ($validator->fails()) return $validator->messages()->all();
I haven't tested this code - mine is a little different, but this should work.
Reference here: https://laravel.com/docs/5.4/validation#custom-error-messages

In Laravel 4, How are the merging rulesets implemented?

I'm using the dwightwatson/validating package to create validation rules in the model.
I particularly like the custom rulesets you can create for different routes.
Model
protected $rulesets = [
'set_up_all' => [
'headline' => 'required|max:100',
'description' => 'required'
],
'set_up_property' => [
'pets' => 'required'
],
'set_up_room' => [
'residents_gender' => 'required',
'residents_smoker' => 'required'
],
'set_up_roommate' => [
'personal_gender' => 'required',
'personal_smoker' => 'required'
]
];
Controller
$post = new Post(Input::all());
if($post->isValid('set_up_all', false)) {
return 'It passed validation';
} else {
return 'It failed validation';
}
In the above example, it works well in validating against the set_up_all ruleset. Now I would like to combine several rulesets and validate against all of them together.
According to the documentation, the package offers a way to merge rulesets. I just can't figure out how to integrate the example provided into my current flow.
According to the docs, I need to implement this line:
$mergedRules = $post->mergeRulesets('set_up_all', 'set_up_property_room', 'set_up_property');
This was my attempt, but it didn't work:
if($mergedRules->isValid()) { ...
I get the following error:
Call to a member function isValid() on array
I also tried this, but that didn't work either:
if($post->isValid($mergedRules)) { ...
I get the following error:
array_key_exists(): The first argument should be either a string or an integer
Any suggestions on how I would implement the merging rulesets?
From what I can see - mergeRulesets() returns an array of rules.
So if you do this - it might work:
$post = new Post(Input::all());
$post->setRules($post->mergeRulesets('set_up_all', 'set_up_property_room', 'set_up_property'));
if($post->isValid()) {
///
}
I've released an update version of the package for Laravel 4.2 (0.10.7) which now allows you to pass your rules to the isValid() method to validate against them.
$post->isValid($mergedRules);
The other answers will work, but this syntax is nicer (and won't override the existing rules on the model).

Categories