In updating profile i use a validator class method:
class UpdateRequest extends Request {
public function authorize() { return true; }
public function rules() {
return [
'name' => 'required',
'email' => 'required|email',
];
}
}
How to add an additional validation error like:
public function postUpdate(UpdateRequest $request)
if($user->email == $request->get('email')) {
$request->addEerror("The email has already been taken."); //shows an fatal error
}
}
?
Thank you
You have not mentioned which Laravel version you are using, assuming 5.1
You can create a message array for different validation type, like the example below:
$rules = [
'first_name' => 'required',
'last_name' => 'required',
'email' => 'required|email|unique:users,email,'.$user->id
];
In your resources/lang/en/validation.php file
$custom_messages = [
'required' => 'The :attribute field is required.',
'email' => [
'required' => 'The email id field is required.',
'email' => 'Please enter a valid email format.',
'unique' => 'The email id has already been taken.',
]
];
This should do the trick.
Related
At my registration form, i have a bool input as newCompany with values
0=register to existed company with company code
1=create new company
Using required_if validation at different fields. And if it fails throws a validation message like "The Company Code field is required when Company is 0."
I wanna set that 0 value as Existing for 0 and New for 1. So i'm inserted them to my language file and changed :value attribute for default error message at lang/en/validation.php file.
'required_if' => 'The :attribute field is required when :other is :value.'
Here's my app/Requests/AuthRegisterRequest.php file:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Password;
use Illuminate\Validation\Rules\File;
use Illuminate\Http\Request;
class AuthRegisterRequest extends FormRequest {
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize() {
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array<string, mixed>
*/
public function rules(Request $request) {
return [
'name' => 'required|max:50|alpha',
'surname' => 'required|max:50|alpha',
'email' => 'required|email|unique:users,email',
'password' => [
'required',
Password::min(8)->numbers()->letters()->uncompromised(5)
],
'c_password' => 'required|same:password',
'newCompany' => 'required|boolean',
'companyCode' => 'nullable|required_if:newCompany,0|max:20|exists:user_companies,code',
'companyName' => 'nullable|required_if:newCompany,1|max:255',
'companyPhone' => 'nullable|required_if:newCompany,1|max:50|unique:user_companies,phone',
'activityTaxDocument' => [
'nullable',
'required_if:newCompany,1',
File::types(['jpg, jpeg, gif, png, doc, docx, pdf'])->max(5*1024) //5 MB
],
'privacyPolicies' => 'required|boolean'
];
}
public function attributes() {
return __('fieldname.AuthRegister');
}
public function messages() {
return [
'companyCode.required_if'=>__('validation.required_if', [
'value'=>__('fieldname.AuthRegister.newCompanyValues')['0']
]),
'companyName.required_if'=>__('validation.required_if', [
'value'=>__('fieldname.AuthRegister.newCompanyValues')['1']
]),
'companyPhone.required_if'=>__('validation.required_if', [
'value'=>__('fieldname.AuthRegister.newCompanyValues')['1']
]),
'activityTaxDocument.required_if'=>__('validation.required_if', [
'value'=>__('fieldname.AuthRegister.newCompanyValues')['1']
])
];
}
}
And lang/en/fieldname.php file
<?php
return [
'AuthRegister' => [
'name' => 'Name',
'surname' => 'Surname',
'email' => 'Email',
'password' => 'Password',
'c_password' => 'Confirm Password',
'newCompany' => 'Company',
'companyCode' => 'Company Code',
'companyName' => 'Company Name',
'companyPhone' => 'Company Phone',
'activityTaxDocument' => 'Activity/Tax Document',
'privacyPolicies' => 'Privacy Policy & Terms',
'newCompanyValues' => [
'1' => 'New',
'0' => 'Existing'
]
]
];
It's working but i wanna combine message for required_if validation to shorten the code according to newCompany field. But couldn't get input values at messages function.
Tried:
public function messages(Request $request) {
return [
'required_if'=>__('validation.required_if', [
'value'=>__('fieldname.AuthRegister.newCompanyValues')[$request->newCompany]
])
];
}
But it throws 500 with error below
{
"message": "Declaration of App\\Http\\Requests\\AuthRegisterRequest::messages(Illuminate\\Http\\Request $request) must be compatible with Illuminate\\Foundation\\Http\\FormRequest::messages()",
"exception": "Symfony\\Component\\ErrorHandler\\Error\\FatalError",
"file": "/var/www/html/app/Http/Requests/AuthRegisterRequest.php",
"line": 67,
"trace": []
}
I have a lot of forms like this. Some of them have much much more fields changing according a bool field. Is there a way to get input values at messages function or capture it from somewhere else?
if not, is it worth to defining a new rule, or should i just define it for each field separately?
Thanks.
I think you can use sometimes method without message() method
public function rules(Request $request) {
return [
'name' => 'required|max:50|alpha',
'surname' => 'required|max:50|alpha',
'email' => 'required|email|unique:users,email',
'password' => [
'required',
Password::min(8)->numbers()->letters()->uncompromised(5)
],
'c_password' => 'required|same:password',
'newCompany' => 'required|boolean',
'companyCode' => 'nullable|sometimes|required_if:newCompany,0|max:20|exists:user_companies,code',
'companyName' => 'nullable|sometimes|required_if:newCompany,1|max:255',
'companyPhone' => 'nullable|sometimes|required_if:newCompany,1|max:50|unique:user_companies,phone',
'activityTaxDocument' => [
'nullable',
'sometimes',
'required_if:newCompany,1',
File::types(['jpg, jpeg, gif, png, doc, docx, pdf'])->max(5*1024) //5 MB
],
'privacyPolicies' => 'required|boolean'
];
}
I am working on a registration form with Laravel 8 and Sanctum.
I have this piece of code in the AuthController to validate the form fields:
public function register(Request $request) {
$fields = $request->validate([
'first_name' => 'required|string,',
'last_name' => 'required|string',
'email' => 'required|string|unique:users,email',
'password' => 'required|string|confirmed',
'accept' => 'accepted',
]);
// More code here
}
I want to display more user-friendly validation error messages.
Rather than changing the validation.php file (resources\lang\en\validation.php), I want to change the set them for the registration form only, in the method above.
The problem
As someone that has used Codeigniter for a long time, I had, in Codeigniter, the posibility to do just that:
$this->form_validation->set_rules('first_name', 'First name', 'required', array('required' => 'The "First name" field is required'));
I was unable to do something similar in Laravel 8.
How do I get the desired result in Laravel 8?
Maybe this can work for ya.
$rules = [
'first_name' => 'required|string,',
'last_name' => 'required|string',
'email' => 'required|string|unique:users,email',
'password' => 'required|string|confirmed',
'accept' => 'accepted'
];
$customMessages = [
'required' => 'The :attribute field is required.'
];
$this->validate($request, $rules, $customMessages);
Also check out the laravel customizing error messages documentation.
The validate function excepts 3 parameters. A) request, B) the rules, C) Custome Messages.
$this->validate($request, $rules, $customMessages); It means define your custom Message Array by key value. Key is the rulename like require. For example:
[
'required' => 'The :attribute is really,really, really required if you use Login!'
'email.required' => 'Without email you dont come in ;-)'
]
I use the Request validation but I don't get message from request. Look my code and see my mistake. Only important is store function which work good if all fields is fullfiled but if any field not filled i don't get my custom message from request. For not filled field I don't give error just laravel home page.
This is my request file
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CarRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'car_type' => 'required',
'mark' => 'required',
'model' => 'required',
'fuel' => 'required',
'circuit' => 'required',
'chassis' => 'required|numeric',
'bill_type' => 'required',
'first_registration' => 'required|date',
'km' => 'required|numeric',
'structure' => 'required',
'motor_vehicle_check' => 'required|boolean',
'warranty' => 'required|boolean',
'year' => 'required|date',
'import_vehicle' => 'required|boolean',
'know_damage' => 'required',
'car_accessories' => 'required',
'email' => 'required|email'
];
}
public function messages()
{
return [
'car_type.required' => 'A car_type is required',
'mark.required' => 'A mark is required',
'model.required' => 'A model is required',
'fuel.required' => 'A fuel is required',
'circuit.required' => 'A circuit is required',
'chassis.required' => 'A chassis is required',
'bill_type.required' => 'A bill_type is required',
'first_registration.required' => 'A first_registration is required',
'km.required' => 'A km is required',
'structure.required' => 'A structure is required',
'motor_vehicle_check.required' => 'A motor_vehicle_check is required',
'warranty.required' => 'A warranty is required',
'year.required' => 'A year is required',
'import_vehicle.required' => 'A import_vehicle is required',
'know_damage.required' => 'A know_damage is required',
'car_accessories.required' => 'A car_accessories is required',
'email.required' => 'A email is required'
];
}
}
And this is my controller code
<?php
namespace App\Http\Controllers;
use App\Car;
use App\CarImages;
use App\Http\Requests\CarRequest;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Illuminate\Support\Facades\Config;
class CarController extends Controller
{
public function index()
{
$cars = Car::with(['images'])
->orderByDesc('car.created')
->get();
return response()->json($cars, 200);
}
public function search($name){
$cars = Car::where('mark', '=' , $name)->get();
return $this->response($cars);
}
public function create()
{
//
}
public function show($id)
{
$car = School::with(['images'])->find($id);
if (!$car) {
return response()->json(['message' => 'No Car found'], 404);
}
return response()->json($car, 200);
}
public function store(CarRequest $request)
{
$car = Car::create([
'car_type' => $request->input('car_type'),
'mark' => $request->input('mark'),
'model' => $request->input('model'),
'fuel' => $request->input('fuel'),
'circuit' => $request->input('circuit'),
'chassis' => $request->input('chassis'),
'bill_type' => $request->input('bill_type'),
'first_registration' => $request->input('first_registration'),
'km' => $request->input('km'),
'structure' => $request->input('structure'),
'motor_vehicle_check' => $request->input('motor_vehicle_check'),
'warranty' => $request->input('warranty'),
'year' => $request->input('year'),
'import_vehicle' => $request->input('import_vehicle'),
'know_damage' => $request->input('know_damage'),
'car_accessories' => $request->input('car_accessories'),
'email' => $request->input('email')
]);
return response()->json([
'message' => 'Your car has been successfully added',
'car' => $car
],201);
}
public function destroy($id)
{
$car = Car::destroy($id);
return response()->json($id);
}
}
I use the Request validation but I don't get message from request.
When expecting a json response, don't forget to add this header when making your requests (client side):
Accept: Application/json // <--
If I want set in my custom message example km must be numberic , how do that in messages function?
You need to specify your message for every rule like this. Let's do it for the km validation:
MyCustomRequest.php
public function rules()
{
return [
// ...
// 'first_registration' => 'required|date',
'km' => 'required|numeric', // <---
// 'structure' => 'required',
// ...
];
}
Given that km has two validations, just add one element more in the messages() function specifying the rule you want to modify:
MyCustomRequest.php
public function messages()
{
return [
// ...
'km.required' => 'A km is required',
'km.numeric' => 'The km needs to be numeric dude!', // <---
// ...
];
}
Regarding this last subject, check the documentation.
As I see you have done all things correctly. The only you missed is a little one in your store() method :
$validator = $request->validated();
right at beginning of the method's body
I'm trying to update a user, as an admin.
I'm changing the username, but it says email must be unique.
How do I fix this.
public function update($id, PutUser $request)
{
if (auth()->id() == $id) {
return redirect()->back()->withFlashDanger('Permission Denied, You can not edit own profile here.');
}
$user = User::find($id);
$user->update((array_merge($request->validated(), ['county' => request('county')])));
//Update model_has_roles model with assignees_roles
return redirect()->route('users.index')->withFlashSuccess(trans("alerts.users.updated"));
}
This is the request class
public function authorize()
{
return true;
}
public function rules()
{
$user_id = $this->input('id');
return [
'name' => 'required|string',
'username' => 'required',
'email' => 'required|email|unique:users,email'.$user_id,
'gender' => 'required',
'phone' => 'sometimes|numeric',
'address' => 'sometimes|string',
'country_id' => 'required',
];
}
}
I keep getting a failed email validation. 'Email has already been taken'. Any idea
You are missing a comma after the email label in your validation:
return [
'name' => 'required|string',
'username' => 'required',
'email' => 'required|email|unique:users,email,'.$user_id,
'gender' => 'required',
'phone' => 'sometimes|numeric',
'address' => 'sometimes|string',
'country_id' => 'required',
];
Since Laravel 5.3 (I believe), you can also use rule builders for more descriptive validation rules. Those are better to read and interpret for humans so it would result in a lower error rate:
use Illuminate\Validation\Rule;
return [
'email' => [
'required',
Rule::unique('users', 'email')->except($user_id),
]
];
https://medium.com/#tomgrohl/why-you-should-be-using-rule-objects-in-laravel-5-5-c2505e729b40
I'm having a problem validating inputs that are only going to be present sometimes in the Request.
// Controller
public function update(Request $request, User $user)
{
$updateResult = $user->updateUser($request);
return dd($updateResult);
}
// User Model
protected $validation = [
'rules' => [
'email' => [
'sometimes',
'email',
'required',
],
'password' => [
'sometimes',
'min:6',
'required',
],
'first_name' => [
'sometimes',
'required',
],
'last_name' => [
'sometimes',
'required',
],
],
'messages' => [
'email.required' => 'An email is required.',
'email.email' => 'The email must be valid.',
'password.required' => 'A password is required.',
'password.min' => 'Your password must be at least six (6) characters long.',
'first_name.required' => 'Your first name is required.',
'last_name.required' => 'Your last name is required.',
],
];
public function updateUser(Request $request)
{
$validation = Validator::make($request->all(), [
$this->validation['rules'],
$this->validation['messages'],
]);
if ($validation->fails())
{
return $validation;
}
else
{
return "OK";
}
}
So in some update pages $request->all() is only going to have a subset of these fields. However, even a field is present, but the value is null, the required doesn't trigger.
[
'first_name' => null,
'last_name' => 'Davidson',
'job_title' => 'Tech Support',
]
The above request array will return "OK"... If I remove sometimes from the fields, then when a partial input request is sent, it fails saying the fields are required.
I am clearing missing something here, but from reading the docs I thought I'd configured this correctly:
In some situations, you may wish to run validation checks against a
field only if that field is present in the input array. To quickly
accomplish this, add the sometimes rule to your rule list:
$v = Validator::make($data, [
'email' => 'sometimes|required|email', ]);
The problem you are facing is simply due to an error in your call to the validator. The second parameter is not a multidimensional array as you passed. The rules array and the messages array are separate parameters.
$validation = Validator::make($request->all(), [
$this->validation['rules'],
$this->validation['messages'],
]);
Should be replaced by
$validation = Validator::make($request->all(),
$this->validation['rules'], $this->validation['messages']);
In Laravel 5.4 empty strings are converted to Null by the ConvertEmptyStringsToNull middleware... that might cause you some issues...
You should add nullable to all your optional validations...
Hope this helps
'first_name' => [
'sometimes',
'required',
],
Will never work as expected. Sometimes indicates: if something comes, what is the next rule? In this case 'required'. Required what? Change this to:
'first_name' => [
'sometimes',
'required',
'min:1',
],
The null value will still be a null value if no input is given and won't fail. If you want to keep the value of the field in the table for updates, populate the input in the form with it's respected values.
The null value was send as '' and got nulled by the ConvertEmptyStringsToNull::class in the app\Http\kernel.php middleware.