Laravel validation require if the user is logged in - php

So let's say I've got a custom request called CreateReviewRequest.
In this request, I've got this method:
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required_if(auth->logged)',
'comments' => 'required|max:255',
'stars' => 'required|min:1|max:5',
];
}
As you can see in the name key, I want from the client to be required to fill the name field if he's not logged in.
So my question is, how can I exactly require my client to fill the name when he's a guest?

You can use check() method:
public function rules()
{
return [
'name' => auth()->check() ? 'required' : '',
'comments' => 'required|max:255',
'stars' => 'required|min:1|max:5',
];
}

Can't you make a simple check?
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
if (auth()->check()) {
return [
'comments' => 'required|max:255',
'stars' => 'required|min:1|max:5',
];
}
return [
'name' => 'required',
'comments' => 'required|max:255',
'stars' => 'required|min:1|max:5',
];
}

Member only:
$validator = Validator::make($request->all(), [
'email' => auth()->check() ? '' : 'required|min:5|max:60|email',
]);
Guest only:
$validator = Validator::make($request->all(), [
'user_id' => auth()->check() ? 'required|integer|min:1' : '',
]);
Both:
$validator = Validator::make($request->all(), [
'message' => 'required|min:10|max:1000'
]);
Combined:
$validator = Validator::make($request->all(), [
'email' => auth()->check() ? '' : 'required|min:5|max:60|email',
'user_id' => auth()->check() ? 'required|integer|min:1' : '',
'message' => 'required|min:10|max:1000'
]);

Related

Is there a way to get input values on messages function at laravel's request file?

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'
];
}

Method for validating request in BaseController in Laravel for APIs

I've been trying to create a method in BaseController.php for validating requests in laravel for APIs. If I use the $this->validate($request, $rules) in API controller it doesn't return the required result. I used this code initially.
$validator = Validator::make($request->all(), [
'name' => 'required',
'email' => 'required|email|unique:users,email',
'phoneNo' => "required|max:15|min:11|unique:users,phoneNo",
'username' => 'required|unique:users,username',
'password' => 'required',
'c_password' => 'required|same:password'
]);
if ($validator->fails()) {
return $this->sendError('Validation Error.', $validator->errors());
}
But I don't want to do this for every method in every controller.
So, I thought that instead of writing this in every controller I should create a method in BaseController.php which I can use in every controller as all controllers are inherited from the BaseController.php.
So, I wrote this to achieve the functionality but this isn't working as it should.
class BaseController extends Controller
{
/**
* success response method.
*
* #return \Illuminate\Http\Response
*/
public function sendResponse($result, $message)
{
$response = [
'success' => true,
'data' => $result,
'message' => $message,
];
return response()->json($response, 200);
}
/**
* return error response.
*
* #return \Illuminate\Http\Response
*/
public function sendError($error, $errorMessages = [], $code = 404)
{
$response = [
'success' => false,
'message' => $error,
];
if (!empty($errorMessages)) {
$response['data'] = $errorMessages;
}
return response()->json($response, $code);
}
public function validateRequest($request, $rules)
{
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) return $this->sendError("Validation Error.", $validator->errors());
}
}
And in the register controller I use this
$this->validateRequest($request, [
'name' => 'required',
'email' => 'required|email|unique:users,email',
'phoneNo' => "required|max:15|min:11|unique:users,phoneNo",
'username' => 'required|unique:users,username',
'password' => 'required',
'c_password' => 'required|same:password',
]);
but it doesn't return an exception here. So, I have to add return to this statement in order for it to return an error. but it should stop the process itself and return the response to API here.
Any help would be appreciated.
Thank you
Update
I found the answer to it. I was a little wrong about this. I forgot to add Accept: "application/json" parameter in the header. We can simply use the same old validation method:
$request->validate([
'name' => 'required',
'email' => 'required|email|unique:users,email',
'phoneNo' => "required|max:15|min:11|unique:users,phoneNo",
'username' => 'required|unique:users,username',
'password' => 'required',
'c_password' => 'required|same:password',
]);
If you are working with API and you want to show a JSON response to this then, you can simply add this in your request headers and it will return a proper JSON response:
Accept: "application/json"

Laravel 5 Update Validation email needs to be unique

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

Returning Laravel validation errors to Ajax call

I'm trying to figure out how to pass back to my ajax call that there were validation errors if there is so that I can prevent the page from continuing on and display those errors to the user.
/*
* Create User After they complete the first part of the form.
*
*/
public function createUserAndOrder(Request $request)
{
$validation = $this->validate($request, [
'first_name' => 'required',
'last_name' => 'required',
'email' => 'required|confirmed|unique:users,email',
'email_confirmation' => 'required'
]);
$credentials = [
'first_name' => $request->input('first_name'),
'last_name' => $request->input('last_name'),
'email' => $request->input('email'),
'password' => Hash::make(str_random(8)),
];
$user = Sentinel::registerAndActivate($credentials);
$user->role()->attach(5);
return response()->json([
'success' => true,
'errors' => null
]);
}
You can try it by using Validate Facade as:
$validator = \Validator::make($request->all(), [
'first_name' => 'required',
'last_name' => 'required',
'email' => 'required|confirmed|unique:users,email',
'email_confirmation' => 'required'
]);
// Validate the input and return correct response
if ($validator->fails())
{
return response()->json(array(
'success' => false,
'errors' => $validator->getMessageBag()->toArray()
), 422);
}
This would give you a JSON response like this:
{
'success': false,
'errors': {
'first_name': [
'The first name field is required.'
],
'last_name': [
'The last name field is required.'
]
}
}

Laravel 5.1 Combine Form Request and Validator

I'm using form requests class. Work fine:
class EventFormRequest extends FormRequest
{
public function rules()
{
return [
'event' => 'required|min:10|max:255',
'event_description' => 'required|min:3|max:255',
'url' => 'url',
'date' => 'required|date',
'start_time' => 'required',
'location.street' => 'required|max:255',
'location.house_number' => 'required|min:1|max:5',
'location.place' => 'required|max:255'
];
}
}
But now, I have to add complexer rules, such as combined with Validator. Below the new rules() method of my EventFormRequest class:
public function rules()
{
$v = \Validator::make($this->request->all(),
[
'event' => 'required|min:10|max:255',
'event_description' => 'required|min:3|max:255',
'url' => 'url',
'date' => 'required|date',
'start_time' => 'required',
'location.street' => 'required|max:255',
'location.house_number' => 'required|min:1|max:5',
'location.place' => 'required|max:255'
]);
$v->sometimes('category_id', 'required|numeric', function($input) {
return $input->event_type == 'known';
});
return ($v->fails() ? $v->messages() : []); // validator validates the rules, but returns the messages
}
You see, category_id is required if the event type is 'known'. In the form request rules() method, I cannot return the applied rules as array (see example 1) from the validator, but only the messages().
I'm inspired from here: http://laravel.com/docs/5.1/validation#conditionally-adding-rules
class EventFormRequest extends FormRequest
{
public function rules()
{
$rules = [
'event' => 'required|min:10|max:255',
'event_description' => 'required|min:3|max:255',
'url' => 'url',
'date' => 'required|date',
'start_time' => 'required',
'location.street' => 'required|max:255',
'location.house_number' => 'required|min:1|max:5',
'location.place' => 'required|max:255'
];
if ($this->request->get('event_type') == 'known') {
$rules['category_id'] = 'required|numeric';
}
return $rules;
}
}

Categories