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]
Related
i have a custom rule which i made using rule objects and its working fine except for one thing, that it doesn't pick up the custom validation message i created for it in the component and instead picks whatever it is assigned to it in the validation.php file or the equivalent translation of it from the translated validation.php file. other non-custom rules are working as expected with the custom messages for the same field.
the component:
public function rules()
{
return[
'topic' => ['required', 'string', 'max:250', 'min:5', new Profane],
'name' => ['required', 'string', 'max:250'],
'email' => ['required', 'email:rfc,dns', 'max:250']
];
}
protected $messages = [
'topic.required' => 'some message',
'topic.max' => 'some message',
'topic.min' => 'some message',
--> 'topic.profane' => 'some message',
'name.required' => 'some message',
'name.max' => 'some message.',
'email.email' => 'some message',
'email.required' => 'some message',
];
the rule object:
public function passes($attribute, $value)
{
$profane = ProfaneWord::all();
$words = $profane->pluck('word');
foreach ($words as $word)
{
if (stripos($value, $word) !== false) return false;
}
return true;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return trans('validation.profane');
}
This does not currently seem possible when using custom rules. The problem in the source the message is only ever retrieved from the message() method. However since the validation rule is your own class you can always change it:
private $message;
public __construct($message = null) {
$this->message = $message;
}
public function passes($attribute, $value)
{
$profane = ProfaneWord::all();
$words = $profane->pluck('word');
foreach ($words as $word)
{
if (stripos($value, $word) !== false) return false;
}
return true;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return $this->message??trans('validation.profane');
}
As suggested by the comment from #apokryfos and tested on Laravel 9 (v9.30.1) custom validation rule messages can be overridden with the full class name. Example below is from FormRequest usage.
public function messages(): array
{
return [
'topic.required' => 'some message',
// ... other rules
'topic.'.Profane::class => 'The :attribute can not contain ...',
];
}
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;
trying to validate it but it seems like it is not making validation and return 200 OK. I do not know what is happen with this. When I debug it, I can not still find the reason why it is not working.
rules from service class
protected $rules = [
'username' => 'required|max:20|unique:users',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required',
// **in Production **
// 'password' => [
// 'required',
// 'min:6',
// 'regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\d\X])(?=.*[!$#%]).*$/',
// 'confirmed'
// ],
/**
* Three of the five rules.
* English uppercase characters (A – Z)
* English lowercase characters (a – z)
* Base 10 digits (0 – 9)
* Non-alphanumeric (For example: !, $, #, or %)
* Unicode characters
*/
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'phone' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:5',
'role' => 'required',
];
validate method from service class
public function validate($user)
{
$validator = Validator::make($user, $this->rules);
$validator->validate();
}
store method in controller
public function store(Request $request)
{
$validate = $this->userService->validate($request->all());
if ($validate->fails()) {
return response()->json(['message' => $validate->failed()], 400);
} else {
try {
$user = $this->userService->createUser($request);
return response()->json($user, 201);
} catch (Exception $e) {
return response()->json(['message' => $e->getMessage()], 500);
}
}
}
How about changing your validate() method in your service class so that it returns something, for instance:
public function validate($user)
{
$validator = Validator::make($user, $this->rules);
if ($validator->fails()) {
/* Here you can also return something like
return redirect('yourView')
->withErrors($validator)
->withInput();
*/
// Or you can simply
return false;
}
return true;
}
And then in the controller you can check it like:
$validate = $this->userService->validate($request->all());
if ($validate)
{
// Validation was successfull
} else {
// Validation was not successfull
}
You should not validate your request in a service class, but use Larvel's Custom Form Request , which allows you to just specify the rules, it will handle the failing scenario (Returning back your browser and setting $errors variable in your template, or sending a proper JSON response).
Basically you'll have
public function store(CreateUserRequest $request)
{
// if you reach here, validation passed.
try {
$user = $this->userService->createUser($request);
return response()->json($user, 201);
} catch (Exception $e) {
return response()->json(['message' => $e->getMessage()], 500);
}
}
I have custom validation rule appointment_status. I am performing various test cases on it and decide what error message is best and throwback. it will be different for every case. I want the $validator->errors()->add('status', __('Invalid status for an appointment in past') to set the error message and it's adding. but it's not returning back to the controller. I can't access this message anywhere. it shows only the status.appointment_status one which is set in messages() function.
Custom Request class:
namespace Modules\ShopManager\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class AppointmentsRequest extends FormRequest
{
public function __construct()
{
\Validator::extend('appointment_status', 'Modules\ShopManager\Validators\CustomValidator#appointmentStatus');
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$rules = [
'services' => 'required',
'sdate' => 'required|date_format:m-d-Y|time_range:sTime,edate,eTime,timezone',
'edate' => 'required|date_format:m-d-Y|workinghours_range:sdate,sTime,edate,eTime,timezone',
'sTime' => 'required|date_format:h:i a',
'eTime' => 'required|date_format:h:i a',
'cname' => 'required',
'cphone' => 'required_without:cemail',
'cemail' => 'nullable|required_without:cphone|email',
'timezone' => 'required',
'status' => 'required|appointment_status:sdate,sTime,edate,eTime,timezone',
];
return $rules;
}
public function messages()
{
return [
'status.appointment_status' => 'Invalid status'
];
}
public function attributes()
{
return [
'services' => 'Services',
'date' => 'Date',
'sTime' => 'Start Time',
'eTime' => 'End Time',
'cname' => 'Customer name',
'cphone' => 'Customer phone',
'cemail' => 'Customer email',
'internal_note' => 'Internal note',
'status' => 'Status',
];
}
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
}
The custom validator function:
public function appointmentStatus($attribute, $value, $parameters, $validator)
{
$dateTimeOperations = new DateTimeOperations;
$sdate = array_get($validator->getData(), $parameters[0]);
$startTime = array_get($validator->getData(), $parameters[1]);
$edate = array_get($validator->getData(), $parameters[2]);
$endTime = array_get($validator->getData(), $parameters[3]);
$timezone = array_get($validator->getData(), $parameters[4]);
$now = $dateTimeOperations->getNow($timezone);
$start = $dateTimeOperations->getTimestamp($sdate, $startTime, $timezone);
$end = $dateTimeOperations->getTimestamp($edate, $endTime, $timezone);
switch ($value) {
case constants('appointments.status.pendig'):
$start->lessThan($now)
? $validator->errors()->add('status', __('Invalid status for an appointment in past'))
: '';
}
return $validator->errors()->any();
}
Adding an error just to the field without specifying the rule I don't think will work, that's why the message from the validation request takes precedence.
So change it to this:
$validator->errors()->add('status.appointment_status', __('Invalid status for an appointment in past'))
And also in your case do you maybe have a typo: pendig to be pending?
You have to create custom validator rules and add below code inside your rule wherever required, See example below:
$validator->after(function ($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add('field', 'Something is wrong with this field!');
}
});
Hello i have been using implicit controllers for a hile now but today i am having an issue i just cannot understand, i have the following in my Route.php:
/**
* Purchase
*/
Route::controllers([
'purchase' => 'PurchaseController'
]);
and in my controller i have created this method:
public function postNsano(NsanoRequest $request)
{
$data = [
'code' => $request->code,
'msg' => $request->msg,
'reference' => $request->referencecode
];
if ($request->code == "00")
{
Session::put('nsano_callback_post_data', $data);
return [
'code' => '00',
'msg' => 'success'
];
}
else
{
return [
'code' => '01',
'msg' => 'rollback'
];
}
}
Now for some reason when i try and post to this URL:
sample.com/purchase/nsano
I get this error: "Controller Method Not Found"
Which is odd for me because i can see the method right there.
I took out the $request and just used Input::get() instead and now it works can someone please explain this to me?
This is my request:
class NsanoRequest 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 [
'code' => 'required',
'msg' => 'required',
'reference' => 'required'
];
}
}
Implicit controller routing needs the HTTP verb in the method name:
public function postNsano(NsanoRequest $request)
{
//
}
Your request validates do not correct so it jumps to an url to prompt error but not found.
If you add some parameters like this and than OK.