I created request form validation in Laravel but when I want to add new input fields, it's not working. In my form, there are no inputs named town or city. I only wanted to add one in the Controller.
$request->all() // returns perfect with new inputs.
$request->validated() // returns without new inputs. because of that validation fails.
ClientController.php
public function update(ClientRequest $request, Client $client)
{
$request->merge([
'city' => explode('/', $request->post('citytown'))[0],
'town' => explode('/', $request->post('citytown'))[1]
]);
$validated = $request->validated();
Client::whereId($client->id)->update($validated);
return redirect('/clients')->with('success', 'success');
}
ClientRequest.php
public function rules()
{
return [
'email' => "required|email|max:254|unique:clients,email,{$this->route()->client->id}",
'fullname' => 'required|max:128',
'idnumber' => "required|max:11|unique:clients,idnumber,{$this->route()->client->id}",
'gender' => 'required|digits_between:1,2',
'phone' => "required|max:10|unique:clients,phone,{$this->route()->client->id}",
'adress' => 'required',
'town' => 'required',
'city' => 'required',
];
}
You are looking for prepareForValidation() method in Illuminate\Foundation\Http\FormRequest.
$this->request->set(key, value);
Example:
protected function prepareForValidation()
{
$this->request->merge([
'city' => explode('/', $this->request->get('citytown'))[0],
'town' => explode('/', $this->request->get('citytown'))[1]
]);
}
From the question I am assuming that
Your form doesn't have fields named town AND city, but you have field named citytown which is supposed to be filed by the user in format CityName/TownName
You intend to add these fields manually only in the controller code by splitting citytown field.
If this is the case you need to remove validation rules for town and city from your request file, after this you wouldn't get validation errors for these fields.
Also, you need to add proper validation rules for citytown field in rules() method of ClientRequest class.
So this is not a case of input manipulation before validation, just add validation rules for citytown field and split it in controller method.
Related
Good day,
I am trying to update brand data using Laravel 5.8 and I made a custom validation function to validate the name of the brand but my problem is when I attempt an update, the validation fails and I get a message saying Opps name Is Exist Before
I need to update this validation function to link the brand id with the brand name to perform the update without showing the validation error.
Thanks in advance.
Here is my code:
public function update(Request $request, $id)
{
//prepare data for validation
request()->validate([
'name' => [
'required',
'min:2', // validate english name is exist before
function ($attribute, $value, $fail) {
$englishname=Brand::where(['name'=>$value,'deleted'=>1 ])->first();
if(false !=$englishname) {
$fail('Opps '.$attribute.' Is Exist Before.');
}
},
],
'keywords' => 'required|min:2',
'ar_name' => [
'required',
'min:2',// validate english name is exist before
function ($attribute, $value, $fail) {
$arname=Brand::where(['ar_name'=>$value,'deleted'=>1])->first();
if(false !=$arname) {
$fail('Opps '.$attribute.' Is Exist Before.');
}
},
],
'ar_keywords' => 'nullable',
'status' => 'required|integer',
],[],[
"name"=>"Brand Name",
'keywords' => 'Brand KeyWords',
'ar_name' => 'اسم الماركة',
'ar_keywords' => 'الكلمات الدليلية',
]);
// start pass data to model
$branddata=array(
'name' =>$request->name,
'keywords' =>$request->keywords,
'ar_name' =>$request->ar_name,
'ar_keywords' =>$request->ar_keywords,
'last_updated_by'=>auth()->user()->id,
'status' =>$request->status,
);
//start update data
$updateddata=Brand::where(['id'=>$id,'deleted'=>1])->update($branddata);
if (false !==Brand::create($updateddata))
{
return redirect(route("brand.edit"))->with("messageSuccess","Brand Updated Successfully");
}else{
return redirect(route("brand.edit"))->with("messageSuccess","Brand Updated Successfully");
}
}
You can use the unique validation rule from Laravel with extended attributes passed for the validation checks.
If you want to validate that the name attribute must be unique (but allows for the same model instance), you can do something like follow:
'name' => "required|string|email|unique:<table name for the Brand::class>,name,{$id}"
This validation rule will check for uniqueness of the provided name for every rows except the one with $id as its primary key.
If your $id variable is not a primary key, you can specify the column name for the variable as follows:
'name' => "required|string|email|unique:<table name for the Brand::class>,name,{$id},<column name of the id>"
When validating data with the validator, it's possible to get all processed data from the validator using the getData() method. However, that returns all data that has been passed into the validator. I only want the data that actually fit the validation pattern.
For example:
$data = [
'email' => email#example.com,
'unnecessaryKey' => 'whatever'
];
$validator = Validator::make($data, [
'email' => 'required|string',
]);
$validator->getData()
Would return the "unnecessaryKey" as well as the email. The question is: Is it possible to only return the email in this case, even though i passed in unnecessaryKey as well?
if you are getting the data from the $request you can try
$validator = Validator::make($request->only('email') , [
'email' => 'required|string',
]);
if you are validating a $data array then you can try
$validator = Validator::make(collect($data)->only('email')->toArray() , [
'email' => 'required|string',
]);
Hope this helps.
You should use Form Requests for this.
1) Create a Form Request Class
php artisan make:request StoreBlogPost
2) Add Rules to the Class, created at the app/Http/Requestsdirectory.
public function rules()
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
3) Retrieve the request in your controller, it's already validated.
public function store(StoreBlogPost $request)
{
// The incoming request is valid...
// Retrieve the validated input data...
$validated = $request->validated();
}
I am trying to create a register form using Laravel.
I created a request \App\Http\Requests\RegisterNewUserRequest. This is the rules() method:
public function rules()
{
return [
'email' => 'required|email|min:6|max:255|unique:members',
'password' => 'required|min:6|max:16|confirmed',
'name' => 'required|min:2|max:255|alpha',
'surname' => 'required|min:2|max:255|alpha',
];
}
This is my Membership Controller
//Route::post('{locale}/create-new-user, 'MemberController#create_new_user');
public function create_new_user($locale, RegisterNewUserRequest $request)
{
$input = $request->all();
$input['ip'] = Request::ip();
Member::create($input);
return redirect("/$locale/create-account");
}
I violate validation rules while entering information. For example, I enter two different passwords, and enter 1 character to the email field. It does not say anything about it. Also It does not save the data into database. The page is redirected to same empty register form again.
I have got a validation summary in my view
...
#foreach($errors->all() as $e)
<li>{{$e}}</li>
#endforeach
...
I trace data posted. It is posted. But something is weird in flow.
EDIT
This happens also in my contact form. If I fill the contact form properly, it sends an e-mail. But if I violate the validation rules, it doesn't say anything about validation and not send e-mail.
This is my Contact page controller
/**
* #param Requests\SendMessageRequest $
*/
public function sendMessage($locale, SendMessageRequest $request)
{
// validation
// $this->validate($request,
// ['name' => 'required|min:3',
// 'email' => 'required|min:5',
// 'subject' => 'required|min:3',
// 'message' => 'required|min:15'
// ]);
$formData = $request->all();
$formData['ip'] = Request::ip();
Mail::send('contact.send', compact('formData'),
function ($message) use ($formData) {
$message->from('frommail#example.com', 'Example')
->bcc(['bccmail#example.com'])
->to('tomail#example.com')
->subject($formData['subject']);
}
);
}
\App\Http\Requests\SendMessageRequest file's rules() method
public function rules()
{
return [
'name' => 'required|min:3',
'email' => 'required|min:5',
'subject' => 'required|min:3',
'message' => 'required|min:15',
];
}
Actually it was working before. After adding multi language feature validation did not worked. I do not know if there is any relation.
I suspect about use statements at the top of controllers and requests.
I'm currently struggling with a bit of validation on a registration form.
Basically when a user registers it will check if the unique code they have entered is valid and if not doesn't let them sign up.
But in my codes table which this reads from I also have an expiry date on the code.
I need to do another check after it is deemed valid that the expiry date hasn't passed, in other words it is not greater than now.
I think you can do this in the validator but I'm struggling a bit with the syntax and not sure where it should go. Here is my code:
protected function validator(array $data)
{
return Validator::make($data, [
'code' => 'required|exists:codes',
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'date_of_birth' => 'required|date',
'password' => 'required|min:6|confirmed',
'accept_terms' => 'required|accepted',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
Code::where('code', $data['code'])->increment('uses');
$data['code_id'] = Code::where('code', $data['code'])->value('id');
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'date_of_birth' => $data['date_of_birth'],
'accept_terms' => $data['accept_terms'],
'code' => $data['code'],
'code_id' => $data['code_id'],
'password' => bcrypt($data['password']),
]);
}
Thanks in advance :)
As long as you're using Laravel v5.3.18 (or higher) you can use the Rule Class to save you having to define a custom rule.
This:
'code' => 'required|exists:codes',
Can be replaced with:
'code' => [
'required',
Rule::exists('codes')->where(function ($query) {
$query->where('expiry_date', '>=', Carbon::now());
}),
],
(the above is assuming expiry_date is the actual name of the column in your db table).
Documentation: https://laravel.com/docs/5.3/validation#rule-exists
Just make sure you import those facades.
Hope this helps!
You can create custom validation rule. Create service provider and register it. Then add something like this:
Validator::extend('is_code_valid', function($attribute, $value, $parameters, $validator) {
$code = Code::where('code', $value)->where('date', '>', Carbon::now())->first();
return !$code->isEmpty(); // Pass if valid code exists in DB.
});
And then use it:
'code' => 'required|is_code_valid',
I have a customers table that I use a CustomerRequest to validate the fields, through the use of the rules function. The table has an email field which is required and is unique. This works fine when I create the customer, however when I update the customer info (let's say I got their last name spelled wrong) my request fails because the email address is already in the database.
Here is my CustomerRequest:
public function rules()
{
return [
'givenname' => 'required',
'surname' => 'required',
'email' => 'required|unique:customers,email',
];
}
I would like to reuse the CustomerRequest for all of the customer vaildation, how can I go about doing this?
You need to check here for request type as well as customer id for update and then return rules according to request. Something like this
public function rules(Request $customer_request)
{
return [
'givenname' => 'required',
'surname' => 'required',
'email' => 'required|unique:customers,email,'.$customer_request->get('customer_id'),
];
}