Laravel form-data image and text fields validation - laravel

//TestRequest.php
public function rules()
{
return [
'name' => 'string|required|min:5',
'tip' => 'string|required|min:5',
'answer' => 'string|required',
'image' => 'file|required|mimes:png,jpg,jpeg'
];
}
//TestController.php
public function put(TestRequest $request)
{
$validated = $request->validated();
}
I'm doing some rest API. I need a form with some text fields and one image upload field but I have a problem with validating it.
When I'm sending the request as 'form-data' in the Postman, Laravel doesn't see in the validation any fields (why?).
When I'm sending the request as application/x-www-form-urlencoded Laravel sees my text fields, but I can't, of course, upload the image.
API will be used by the android APP. How I can solve this? How I can have both validation on text and file inputs?

Using application/x-www-form-urlencoded is the correct way to upload images. According to your second screenshot, you are not sending the file field in Postman, but you are sending it in the first screenshot.

see this
'name' => 'string|required|min:5',
minimum is 5 character but you send test or 4 chars. Laravel validation rule, if it failed it will stop or next validation will not checked.

I think I've found a solution.
Changing method from PUT to POST seems to fix this issue.

Related

Laravel validate request filter field with dot (period) in field name

Here is to validate form request in laravel, request contains filter and field name in the filter has period(dot) present.
Sample Request url
...?filter[entity.abc][]='value'
Here entity.abc is actually a string, but laravel considers it to be array of object, when rule is given for 'filter.entity.abc'
filter:[
[entity]: [ {abc:'value'}]
]
which is actually
filter:[
[entity.abc]:['value']
]
So we need to make regex for second dot, which equivalents to:
public function rules()
{
return [
'filter.entity\.abc' => ['bail', 'sometimes', 'array'],
'filter.entity\.abc' => ['uuid']
];
}
Above always retuns true,even when invalid uuid is present
why not modify your request like this?
...?filter[entity][abc][]='value'
Edit:
You can use custom validation in laravel where you can deconstruct the parameters and check the values manually
Laravel Custom Validation
https://laravel.com/docs/8.x/validation

Conditionally loaded data in API resource: How to "pass" a condition?

I got a little issue to solve. In my app I am handling with a lot of Models and each model does have something like:
ModelResource
ModelResourceCollection
ModelResourceOverview
ModelResourceOverviewCollection
The reason is: Sometimes I don't need all the information that are visible if I am using the ModelResource - in this case I am calling the ModelResourceOverview.
Example
PostResource
- title
- tags
- content
- author
Example
PostOverviewResource
- title
- author
As I have a lot of Models I have a huge number of ApiResource-Classes and I want to get rid of that.
I thought about using $this->when in the Resource and pass something like "full" or "overview" to the request in the Controller.
Example
$data
= new PostResource($this->post);
So my question is: Is it the best way to add this to the request or is there a handier/nicer way to handle this?
Laravel has a way to hide fields on the fly: Hiding attributes from json
e.g.
return $post->makeHidden('content')->toArray();
If your logic about "visible or not" is bound to the current request, then you should use when or mergeWhen as you mentioned (everything here https://laravel.com/docs/7.x/eloquent-resources#conditional-attributes ), therefore you'll only have 2 resources instead of 4
public function toArray($request)
{
return [
'title' => $this->title,
'author' => $this->author,
$this->mergeWhen($this->needsFullData($request), [
'tags' => $this->tags,
'content' => $this->content,
]),
];
}
protected function needsFullData($request)
{
//Your logic
}

Laravel - form validation to pass only if certain field is empty

So I'm building a form and I need specific fields to be empty.
They return an empty string and from other similar questions, I looked for
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class
in Kernel.php which is commented out by default, I believe.
I don't want to change its behavior since it's a global middleware.
I have tried making them nullable, string|sometimes, present|max:0 yet none of these give me the desired result. I want the validation to pass only if the fields are empty.
Any help will be deeply appreciated.
So as I understood, you want for specific field to be required, if the other field in form is empty? To achieve that, you can use required_without property in Request validation like this:
public function rules()
{
return [
'filed_name' => 'required_without:other_field_name',
];
}
public function messages()
{
return [
'filed_name.required_without' => 'filed_name is required.',
];
}
More on validation on official documentation.

Customized validation rule on laravel form request validation

I do have a registration form in my laravel 5.4 application and laravel form request validation is used for server side validation. Some fields in this form are populated dynamically using calculations in javascript which need to be validated against user inputs.
The user input fields in the form are 'quantity', 'rate' and 'discount'.
The populated fields are 'total' and 'bill_amount'.
What i need to validate are :
Check 'total' equal to 'quantity' * 'rate'.
Check 'bill_amount' equal to 'total' - 'rate'
I would prefer laravel form request validation methods for this validation. I have tried to use methods like After Hooks and conditionally adding rule etc. and failed.
In simple words the requirement is : check if a field is equal to product of other two fields, and invalidate if not equal and validate if equal.(using form request validation.)
Thanks in advance!
After a long time I was able to find this solution.
Form request After Hooks can be used to achieve the result:
[I was unable to find this logic before]
public function withValidator($validator)
{
$quanty = $this->request->get("quantity");
$rate = $this->request->get("rate");
$billAmount = $this->request->get("bill_amount");
$validator->after(function ($validator) {
if(($quanty * $rate) != $billAmount) {
$validator->errors()->add('bill_amount', 'Something went wrong with this field!');
}
});
}

Form input values not remain after flash error message

How to solve above issue? I want to keep test even after a validation failure in the submission. But after session error message is passed all the entered data will be gone.
To re-fill the form with the input data again, check the input validation then if validation fails, redirect the user back along with his input data and validation errors.
$validator = Validator::make($request->all(), [
// your validation rules.
'name' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
// Continue your app logic.
You'll find more information in Laravel validation docs
You should send back the input also to the view.
Like Sameh Salama already mentioned, use the following code:
function () {
return redirect()->back()->withErrors($validator)->withInput();
}
Notice the withInput() function, it returns the old input.
Use it in the View as
<input type="something" value="{{$input->first_something}}" />

Resources