How to validate email in custom rule - laravel

I use Laravel.
I use the same field for username and email. Additionally the user has to choose, if the input is an username or an email.
If the type is email, i like to add the email validation. If it's username, there is no email validation needed.
I tried to create a custom rule with the if function. But how can i then validate the email?
class StoreUserRequest extends FormRequest
{
public function rules()
{
return [
'first_name' => 'required',
'last_name' => 'required',
'password' => 'required',
'email' => ['required', new ValidateEmailRule()]
];
}
public function authorize()
{
return true;
}
}
class ValidateEmailRule implements Rule
{
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
if (request()->is_email) {
//validate email ---here i need help to get the right code---
}
return true;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The validation error message.';
}
}

Can't you just use 'email' => 'required_if:is_email:1?
EDIT:
$rules = [
'first_name' => 'required',
'last_name' => 'required',
'password' => 'required',
];
if ($this->is_email) {
$rules['email'] = 'email';
}
return $rules;

Related

Where to put Laravel validation that is not related to column

For example, I have an HTTP request that handles some entity creation (let it be Role)
And validation looks like this:
class CreateRole extends FormRequest
{
public function rules()
{
return [
'name' => 'required|string|max:255',
'permissions' => ['required', 'array'],
...
And I have some restrictions that are not related to either name or permission column.
For example the maximum amount of roles that can be created.
Such custom validation can be placed to the name property, but it looks wrong.
PS: I know about custom validators. Question about where to place it...
You can use after hook in the form request CreateRole.php
class CreateRole 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()
{
return [
'title' => ['required', 'string', 'max:255'],
'permissions' => ['required', 'array'],
];
}
/**
* Configure the validator instance.
*
* #param \Illuminate\Validation\Validator $validator
* #return void
*/
public function withValidator($validator)
{
$validator->after(function ($validator) {
if (Role::count() > 10) {
$validator->errors()->add('limit', 'Max number of Roles reached!');
}
});
}
}
You have to create custom validation class as shown in this Laravel document and place into you validatior class like below.
'name' => ['required', 'string', new CustomValidationClass],

how to unit test a controller in laravel?

This is the test function
public function testCreateSuccess(){
$user=['first_name'=>"heba",'last_name'=>"chakaron",'email'=>"hebachakaron#gmail.com",'password'=> "123456"];
$userReturned=['first_name'=>"heba",'last_name'=>"chakaron",'email'=>"hebachakaron#gmail.com",'password'=> Hash::make('123456')];
$userRequest = UserRegisterRequest::create("http://127.0.0.1:8000/api/users/", 'POST',[
'first_name'=>"heba",
'last_name'=>"chakaron",
'email'=>"hebachakaron#gmail.com",
'password'=>'123456',
'password_confirmation'=>'123456'
]);
/**
* #var UserService|\Mockery\MockInterface|\Mockery\LegacyMockInterface
*/
$mock=Mockery::mock(UserService::class);
$mock->shouldReceive('create')->with($user)
->once()
->andReturn($userReturned);
$this->userController=new UserController($mock);
$this->app->instance('App\Services\UserService', $mock);
$created=$this->userController->create($userRequest);
$this->assertSame($created['password'],$userReturned['password']);
}
This is the controller
class UserController extends Controller
{
//
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
public function create(UserRegisterRequest $request)
{
$data = $this->userService->create($request->validated());
return HTTPResponse::ok($data);
}
}
This is the UserRegisterRequest
class UserRegisterRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
];
}
}
When I run this testCreateSuccess it return There was 1 error:
Tests\Unit\UserTest::testCreateSuccess
Error: Call to a member function validated() on null
and the error is on the line $created=$this->userController->create($userRequest)

How response message() on Request

i'm need response json messages()
class StoryRequest 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 [
'name' => 'required|min:3|max:255|unique:stories',
'categories' => 'required',
'image' => 'mimes:jpeg,bmp,png, jpg',
];
}
public function messages()
{
return response()->json([
'image.mimes' => 'only .jpg, .png, .jpeg',
'name.required' => 'please name',
'name.min' => 'min 3',
'name.max' => 'max 255',
'name.unique' => 'name unique',
'categories.required' => 'please choose categories'
]);
}
}
Try this return redirect('/home')->with('success', 'Password Updated Successfully');

Error implementing Custom Validation in Laravel

I am trying to add an extra validation rule that checks to ensure that a username is a word. I created a new rule (SingleWord) like so:
public function passes($attribute, $value)
{
$dd = strpos(trim($value), ' ');
if($dd !== false){
return false;
}
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'Username must be one word';
}
I now added this rule to the validator like so:
$validator = Validator::make($data, [
'name' => 'required|string|max:255|unique:merchants',
'email' => 'required|string|email|max:255|unique:merchants',
'password' => 'required|string|min:6',
'username' => 'required|string|unique:merchants',
'username' => [new SingleWord]
],[
'name.required' => "Company name is required",
]);
return $validator;
But the validator returns the error message even when I enter one word. Please what might be wrong here?
You left out the affirmative case. Try this:
public function passes($attribute, $value)
{
$dd = strpos(trim($value), ' ');
if($dd !== false){
return false;
}
return true;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'Username must be one word';
}
Without knowing your error message, I will suggest couple of changes, first in your validation you can change your passes method to this:
public function passes($attribute, $value)
{
return !strpos(trim($value), ' ');
}
and then your validation, you can use only one key like this:
'username' => ['required', 'string', 'unique:merchants' , new SingleWord]

Customize Validation Messages in Laravel Requests

How do i customize my Validation Messages in My REQUESTS FILE?
how do i add messages next to the rules?
What i want is to put customized messages just like the common validation. Is it possible? to do just the normal way of validation in the Requests?
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class ArticleRequest extends Request
{
/**
* 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 [
'title' => 'required|min:5',
'content' =>'required',
'user_id' => 'required|numeric',
'category_id' => 'required|numeric',
'published_at' => 'required|date'
];
}
}
You can define a messages() method with validation rules for that form request only:
class StoreArticleRequest extends Request
{
//
public function messages()
{
return [
'title.required' => 'The title is required.',
'category_id.numeric' => 'Invalid category value.',
];
}
}
It takes the form of the field name and the rule name, with a dot in between, i.e. field.rule.
You may customize the error messages used by the form request by
overriding the messages method. This method should return an array of
attribute / rule pairs and their corresponding error messages:
public function messages()
{
return [
'title.required' => 'A title is required',
'body.required' => 'A message is required',
];
}
https://laravel.com/docs/5.3/validation#customizing-the-error-messages
I use this solution to translate the field labels:
...
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'title' => 'required|min:5',
'content' =>'required',
'user_id' => 'required|numeric',
'category_id' => 'required|numeric',
'published_at' => 'required|date'
];
}
/**
* Get the validation attributes that apply to the request.
*
* #return array
*/
public function attributes()
{
return [
'title' => __('app.title'),
'content' => __('app.content'),
'user_id' => __('app.user'),
'category_id' => __('app.category'),
'published_at' => __('app.published_at')
];
}

Resources