Laravel 5.4 validator not seeing input field - php

So I'm trying to setup validation using the Validator facade. For some strange reason, the validator is not seeing one of the input fields though it's present in the request. Here's the validation code:
$rules = [
'name' => 'required',
'resource_type' => 'required',
'semester' => 'required',
'file' => 'required|max:8196'
];
$messages = [
'name.required' => 'The name field is required',
'semester.required' => 'The semester field is required',
'resource_type.required' => 'The resource_type field is required',
'file.required' => 'The file field is required',
'file.max' => 'The max file size is 8196 kilobytes',
];
$validator = Validator::make($request->input(), $rules, $messages);
if ($validator->fails()) {
return response()->json($validator->messages(), 422);
}
And here's the test I'm running:
$file = UploadedFile::fake()->create('file.pdf', 512);
$response = $this->json( "POST", 'api/v2/papers', [
"name" => $paper->name,
"semester" => $paper->semester,
"resource_type" => $paper->resource_type,
"file" => $file,
] )->assertSuccessful();
When I print the value of $response->content() I get
{"file":["The file field is required"]}
The file field is present so I'm not sure what is really going on?
Thanks in advance.

Don't use $request->input(), it does not include files.
Use $request->all()

Related

How to update a user only when value has not changed in the database and also avoid using other people's email

So, I have controller method which validates user and updates their information.
public function updateBasicInfo(Request $request)
{
$basic_info = Validator::make($request->all(), [
'fullname' => 'required|min:2|max:255',
'phone_number' => 'required|numeric|min:10',
'email' => 'required',
'country' => 'required',
'address' => 'required',
], [
'phone_number.min' => "The phone number must be at least 10 digits",
]);
if($basic_info->fails())
{
return response()->json([
'errors'=> $basic_info->errors()->all(),
]);
}
else
{
$basic_info = $basic_info->validated();
$user = request()->session()->get('id');
$currentUser = User::firstWhere('username', $user->username);
$currentUser->name = $basic_info['fullname'];
$currentUser->phone_number = $basic_info['phone_number'];
$currentUser->email = $basic_info['email'];
$currentUser->save();
UserDetail::firstWhere(['username' => $user->username])->update([
'address'=>$basic_info['address'],
'country' => $basic_info['country'],
]);
$current_user = $currentUser;
Mail::to($current_user->email)->send(new ProfileMail($user));
return response()->json(['success'=> 'Profile Updated Sucessfully']);
}
}
I want to update user but I don't want two users to have the same email and I also want the user email to change only if it's value has been changed in the database.
Check to make sure that only the user has that email in the whole table and update it to prevent double email records
Please, how do I do this?
I have tried calling the isDirty() method,nothing seems to work
You can use the unique validation rule for email with ignore to make sure that it doesn't receive an error if the new email is the same as the last email. (Unique validation only in comparison with other users). Check out this link.
$basic_info = Validator::make($request->all(), [
'fullname' => 'required|min:2|max:255',
'phone_number' => 'required|numeric|min:10',
'email' => 'required|unique:users,email,'.request()->session()->get('id'),
'country' => 'required',
'address' => 'required',
], [
'phone_number.min' => "The phone number must be at least 10 digits",
]);
The isDirty() method is to check if you set a value to any of the properties of instance. And it checks the change after it occured.isDirty()

What is wrong with this form validation

I'm working with Laravel 5.8 and I have made this Controller method for creating some records inside the DB.
public function doTheUpload(Request $request)
{
try{
$request->validate([
'video' => 'nullable|mimes:mp4',
'video_thumb' => 'required|mimes:jpg,png,jpeg',
'video_name' => 'required',
'video_desc' => 'nullable',
'available_download' => 'nullable',
],[
'video.mimes' => 'video file format is not valid',
'video_thumb.required' => 'uploading video thumbnail is required',
'video_name.required' => 'you must enter name of video',
'video_thumb.mimes' => 'image thumbnail file format is not valid',
]);
// Do the upload process
}catch(\Exception $e){
dd($e);
}
}
But this will not working and return this error:
The given data was invalid.
This is basically because of the form validation requests and when I remove those validations from the method, it will work absolutely fine.
So what is wrong with those form request validation that returns this error?
If you know, please let me know... I would really really appreciate any idea or suggestion from you guys.
Thanks.
When you use Laravel's validation, you should let Laravel handle the errors, because when a rule fails, Laravel automatically throws an exception.
So the first advise is no to use a try-catch block in your validation routine.
As Laravel docs states:
Displaying The Validation Errors
So, what if the incoming request parameters do not pass the given
validation rules? As mentioned previously, Laravel will automatically
redirect the user back to their previous location. In addition, all of
the validation errors will automatically be flashed to the session.
In addition, I suggest you not to use validation in the controllers because according to good practices, it is recommended to create separate formRequest for validation, so you should slightly modify you controller to include validator class:
<?php
namespace App\Http\Controllers;
...
use App\Http\Requests\UploadVideoRequest;
...
public function doTheUpload(UploadVideoRequest $request)
{
/*
* Here where are calling validation as UploadVideoRequest
*/
// logic for valid uploaded video
}
Now you have to create a form request, maybe using php artisan make:request UploadVideoRequest
This command will create a form request class under app/Http/Requests, and you should fill it as:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UploadVideoRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
/*
* here you should check if the user is authorized to upload video
* or let in true if anyone can do that
*/
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'video' => 'nullable|mimes:mp4',
'video_thumb' => 'required|mimes:jpg,png,jpeg',
'video_name' => 'required',
'video_desc' => 'nullable',
'available_download' => 'nullable',
];
}
/**
* Define messages to return if an error is detected.
*
* #return array
*/
public function messages()
{
return [
'video.mimes' => 'video file format is not valid',
'video_thumb.required' => 'uploading video thumbnail is required',
'video_name.required' => 'you must enter name of video',
'video_thumb.mimes' => 'image thumbnail file format is not valid',
];
}
}
By using this approach Laravel is validating user input and managing any error via Exceptions.
Regards.
You must specify exactly what you are validating:
$request->validate([
'request.video' => 'nullable|mimes:mp4',
'request.video_thumb' => 'required|mimes:jpg,png,jpeg',
'request.video_name' => 'required',
'request.video_desc' => 'nullable',
'request.available_download' => 'nullable',
], [
'request.video.mimes' => 'video file format is not valid',
'request.video_thumb.required' => 'uploading video thumbnail is required',
'request.video_name.required' => 'you must enter name of video',
'request.video_thumb.mimes' => 'image thumbnail file format is not valid',
]);
An example from my codes:
$requestData = $request->request_data;
// data
$company_name = $requestData['company_name'];
$company_type = $requestData['company_type'];
$company_address = $requestData['company_address'];
$latitude = $requestData['latitude'];
$longitude = $requestData['longitude'];
$company_branch_count = $requestData['company_branch_count'];
$yes_radio = strval($requestData['yes_radio']);
$no_radio = strval($requestData['no_radio']);
$company_contact_user_first_name = $requestData['company_contact_user_first_name'];
$company_contact_user_last_name = $requestData['company_contact_user_last_name'];
$company_contact_user_email = $requestData['company_contact_user_email'];
$company_contact_user_password = $requestData['company_contact_user_password'];
$company_contact_user_phone = $requestData['company_contact_user_phone'];
$company_kvkk_ok = strval($requestData['company_kvkk_ok']);
$shipping_method_yourself = $yes_radio === 'true' && $yes_radio != $no_radio ? 1 : 0;
if ($company_kvkk_ok == 'false') {
return json_encode([
'operation_status' => 'error',
'error_messages' => 'no',
]);
}
// Validate
$validator = Validator::make($request->all(), [
"request_data.company_name" => "required|string|min:5",
"request_data.company_type" => "required|in:0,1,2,3,4,5,6,7,8,9,10,11,12",
"request_data.company_address" => "required",
"request_data.latitude" => "required",
"request_data.longitude" => "required",
"request_data.company_branch_count" => "required|integer",
"request_data.yes_radio" => "required",
"request_data.no_radio" => "required",
"request_data.company_contact_user_first_name" => "required",
"request_data.company_contact_user_last_name" => "required",
"request_data.company_contact_user_email" => [
'required',
'email',
Rule::unique('users', 'email')->where(function ($query) use ($company_contact_user_email) {
return $query->where('email', $company_contact_user_email);
}),
Rule::unique('companies', 'company_contact_user_email')->where(function ($query) use ($company_contact_user_email) {
return $query->where('company_contact_user_email', $company_contact_user_email);
}),
],
"request_data.company_contact_user_password" => "required|min:6",
"request_data.company_contact_user_phone" => "required",
"request_data.company_kvkk_ok" => "required",
], [
'request_data.company_name.required' => __('company name required'),
'request_data.company_name.string' => __('company name must be string'),
'request_data.company_name.min' => __('company name must be at least 5 characters'),
'request_data.company_type.required' => __('company type required'),
'request_data.company_type.in' => __('company type invalid'),
'request_data.company_address.required' => __('company address required'),
'request_data.latitude.required' => __('latitude required'),
'request_data.longitude.required' => __('longitude required'),
'request_data.company_branch_count.required' => __('company branch count required'),
'request_data.company_branch_count.integer' => __('company branch count must be integer'),
'request_data.yes_radio.required' => __('yes radio required'),
'request_data.no_radio.required' => __('no radio required'),
'request_data.company_contact_user_first_name.required' => __('company contact user first name required'),
'request_data.company_contact_user_last_name.required' => __('company contact user last name required'),
'request_data.company_contact_user_email.required' => __('company contact user email required'),
'request_data.company_contact_user_email.email' => __('company contact user email invalid'),
'request_data.company_contact_user_email.unique' => __('email already taken'),
'request_data.company_contact_user_password.required' => __('company contact user password required'),
'request_data.company_contact_user_password.min' => __('company contact user password must be at least 6 characters'),
'request_data.company_contact_user_phone.required' => __('company contact user phone required'),
'request_data.company_kvkk_ok.required' => __('company kvkk ok required'),
]);
if ($validator->fails()) {
$messages = $validator->messages();
return json_encode([
'operation_status' => 'not_validated',
'request' => $requestData,
'messages' => $messages,
]);
}

laravel 8, how to get individual errors message in array based on the field names instead of this default array

I have a contact form, with some field and i want to get error message based on the form field, i.e the error message for name, email, phone, subject and message
Here is what I get here:
XHRPOSThttp://127.0.0.1:8000/save
[HTTP/1.1 200 OK 137ms]
success false
errors [ "The name field is required.", "The email field is required.", "The phone field is required.", "The subject field is required.", "The description field is required." ]
because of this line in controller
$validator->errors()->all()
but I want the error message to be like:
errors:object{name:""The name field is required."
email:"The email field is required.", ...}
the controllers look like
$validator = Validator::make($request->all(), [
'name' => 'required|max:60',
'email' => 'required|email',
'phone' => 'required|min:10|numeric',
'subject' => 'required|max:100',
'description' => 'required|max:250',
]);
if ($validator->fails()) {
return response()->json([
'success' => false, 'errors' =>$validator->errors()->all()
]);
}
You probably want to use the default Laravel validation function (available in all controllers), which handles this output automatically:
// SomeController.php
$this->validate($request, [
'name' => 'required|max:60',
// ...
]);
When the validation fails, a ValidationException is thrown which should be automatically handled in your exception handler.
You can try with using FormRequest for validation and custom messages.
https://laravel.com/docs/8.x/validation#creating-form-requests
use Illuminate\Support\Facades\Validator;
$exampleRequest = new ExampleRequest();
$validator = Validator::make($request->all(), $exampleRequest->rules(), $exampleRequest->messages());
if($validator->fails()){
return response()->json($validator->errors(), 422);
}
This will return JSON response (for an API in this case):
{
"name": [
"First name is required."
]
}
For given rules and messages in ExampleRequest:
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
// 'name' => 'required',
];
}
public function messages()
{
return [
'name.required' => 'First name is required.'
];
}

Laravel validation OR

I have some validation that requires a url or a route to be there but not both.
$this->validate($request, [
'name' => 'required|max:255',
'url' => 'required_without_all:route|url',
'route' => 'required_without_all:url|route',
'parent_items'=> 'sometimes|required|integer'
]);
I have tried using required_without and required_without_all however they both get past the validation and I am not sure why.
route is a rule in the route field
I think you are looking for required_if:
The field under validation must be present if the anotherfield field is equal to any value.
So, the validation rule would be:
$this->validate($request, [
'name' => 'required|max:255',
'url' => 'required_if:route,""',
'route' => 'required_if:url,""',
'parent_items'=> 'sometimes|required|integer'
]);
I think the easiest way would be creation your own validation rule. It could looks like.
Validator::extend('empty_if', function($attribute, $value, $parameters, Illuminate\Validation\Validator $validator) {
$fields = $validator->getData(); //data passed to your validator
foreach($parameters as $param) {
$excludeValue = array_get($fields, $param, false);
if($excludeValue) { //if exclude value is present validation not passed
return false;
}
}
return true;
});
And use it
$this->validate($request, [
'name' => 'required|max:255',
'url' => 'empty_if:route|url',
'route' => 'empty_if:url|route',
'parent_items'=> 'sometimes|required|integer'
]);
P.S. Don't forget to register this in your provider.
Edit
Add custom message
1) Add message
2) Add replacer
Validator::replacer('empty_if', function($message, $attribute, $rule, $parameters){
$replace = [$attribute, $parameters[0]];
//message is: The field :attribute cannot be filled if :other is also filled
return str_replace([':attribute', ':other'], $replace, $message);
});

Wrong Laravel validation messasges

I get the wrong error messages. My purpose is following :
1. checking username / pw combination, and if it doesn't match, "wrong username/pw combination" error through validator.
2. captcha (mews) is troubling me. Even user enters true captcha chars (no case-sensitive by config) I get the error message.
Here is my validator :
FYI: i have a table "user" instead of users, and i can use it nicely in other controllers.
protected function loginValidator()
{
$message = array(
'exists:user,username' => 'Wrong username/pass combination',
'exists' => 'Wrong :attribute.',
'required' => ':attribute cannot be empty',
'captcha' => 'Wrong captcha'
);
return Validator::make(Input::all(),[
'usernameInput' => 'required|exists:user,username',
'passwordInput' => 'required',
'captchaInput' => 'captcha|required'
], $message);
}
Even if username/pass combination is true, i get wrong captcha message.
Thanks in advance.
protected function loginValidator()
{
$validator = Validator::make(
array(
'name' => 'Dayle',
'password' => 'lamepassword',
'email' => 'email#example.com'
),
array(
'name' => 'required',
'password' => 'required|min:8',
'email' => 'required|email|unique:users'
)
);
if ($validator->fails())
{
// The given data did not pass validation
$data['messages'] = $validator->messages()->all();
}
else
{
//complete validation
}
return View::make('home.login', $data);
}

Categories