I have made a custom rule to validate mobile no. with specific pattern and requirement.
Pattern
[0-9]{3}-[0-9]{4}-[0-9]{4}
The first three digits should be one of the following numbers:
010, 020, 030, 040, 050, 060, 070, 080, 090
Below is my code for custom rule.
App/Rules/MobileNumber.php
public function passes($attribute, $value)
{
$pattern = "/^\[0-9]{4}-[0-9]{4}-[0-9]{3}$/";
return preg_match($pattern, $value);
}
My custom validator:
app/HTTP/Request/UserRequest.php
use App\Rules\MobileNumber;
......
//manipulate data before validation
public function validationData()
{
$this->merge([
'tel_number' => $this->tel_number_1.'-'. $this->tel_number_2.'-'.$this->tel_number_3,
]);
}
public function rules()
{
return [
//other rules here....
'mob_number' => 'required', new MobileNumber()
];
}
But with the above code the validation is not working.tel_number is not reaching to passes method to check for validation.
I.E If user gives alphabetic char or symbols they are being forwarded for database save method.
So I cannot check if my regex is correct or not.
It would be very helpful if someone could highlight the mistake I've made here. Also confirm if my regex is correct to pass the validation.
I can only answer the last point for the regex validation.
You switched the order in the implementation to 4-4-3 instead of 3-4-4 digits.
The sequences 010, 020, 030, 040, 050, 060, 070, 080, 090 can be matched using 0[1-9]0 and you should not escape the \[ or else you will match it literally.
The updated code might look like:
$pattern = "/^0[1-9]0-\d{4}-\d{4}$/";
Related
I have validation rule:
$rules = ['username' => 'required|string|alpha_dash']
I need prevent dash in validation, allow only underscores, letters and numbers. How I can do it? Now alpha_dash allow dashes..
I would suggests to use regex validation to get more power to customize in future if you wish. SEE https://laravel.com/docs/5.8/validation#rule-regex
'regex:/^[A-Za-z0-9_]+$/'
or more specifically
$rules = ['username' => 'required|string|regex:/^[A-Za-z0-9_]+$/']
Because as per documentation alpha_dash supports-
The field under validation may have alpha-numeric characters, as well
as dashes and underscores.
You can use regex:pattern in your validation.
$rules = ['username' => 'required|string|regex:/^[A-Za-z0-9_.]+$/']
Aside from the other answers, You can create custom validation rule
following artisan command will create a new rule in the app\Rules\ folder.
php artisan make:rule AlphaNumeric
AlphaNumeric
class AlphaNumeric implements Rule
{
public function passes($attribute, $value)
{
return preg_match('/^[A-Za-z0-9_]+$/', $value);
}
public function message()
{
return 'your custom error message.';
}
}
Controller
$rules = [
'username' => ['required', 'string', new AlphaNumeric()]
]
This approach can be use to create more complex and flexible validations.
Try this rule instead of alpha_dash
[
'username' => ['regex:/^[0-9a-zA-Z_\-]*$/']
]
My question is about Laravel validation rules.
I have two inputs a and b. a is a select input with three possible values: x, y and z. I want to write this rule:
b must have a value only if a values is x.
And b must be empty otherwise.
Is there a way to write such a rule? I tried required_with, required_without but it seems it can not cover my case.
In other words, if the previous explanation was not clear enough:
If a == x, b must have a value.
If a != x, b must be empty.
You have to create your own validation rule.
Edit app/Providers/AppServiceProvider.php and add this validation rule to the boot method:
// Extends the validator
\Validator::extendImplicit(
'empty_if',
function ($attribute, $value, $parameters, $validator) {
$data = request()->input($parameters[0]);
$parameters_values = array_slice($parameters, 1);
foreach ($parameters_values as $parameter_value) {
if ($data == $parameter_value && !empty($value)) {
return false;
}
}
return true;
});
// (optional) Display error replacement
\Validator::replacer(
'empty_if',
function ($message, $attribute, $rule, $parameters) {
return str_replace(
[':other', ':value'],
[$parameters[0], request()->input($parameters[0])],
$message
);
});
(optional) Create a message for error in resources/lang/en/validation.php:
'empty_if' => 'The :attribute field must be empty when :other is :value.',
Then use this rule in a controller (with require_if to respect both rules of the original post):
$attributes = request()->validate([
'a' => 'required',
'b' => 'required_if:a,x|empty_if:a,y,z'
]);
It works!
Side note: I will maybe create a package for this need with empty_if and empty_unless and post the link here
Required if
required_if:anotherfield,value,...
The field under validation must be present and not empty if the anotherfield field is equal to any value.
'b' => 'required_if:a,x'
Laravel has its own method for requiring a field when another field is present. The method is named required_with.
In Laravel 8+ check if prohibited and prohibited_if validators work for this:
'b' => 'required_if:a,x|prohibited_if:a,!x'
I am trying to do server side validation with custom validation for the phone and email fields. I am doing the custom validation in the forms action.
Firstly is this the correct place to do it and secondly if so how can I get the data to return to the form if it doesn't meet validation?
Currently it will clear the entire form.
public function doSubmitForm($data, Form $form) {
if (!preg_match("/^[\+_a-z0-9-'&=]+(\.[\+_a-z0-9-']+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/i",$data['Email'])) {
$form->addErrorMessage('Email', 'Invalid email', 'bad');
return $this->redirectBack();
}
if (!preg_match("/^((?:\+)|0)(\d{9,14})$/i",$data['Phone'])) {
$form->addErrorMessage('Phone', 'Please match the correct format eg: 0821234567', 'bad');
return $this->redirectBack();
}
$form->sessionMessage('Thank you for your submission','alert alert-success');
return $this->redirectBack();
}
I suggest you don't do server-side validation like that.
The easiest way is just to use the proper form-fields. Eg. EmailField and PhoneNumberField.
If these don't validate the way you want, just extend them or create your own FormField subclasses.
Here's how EmailField does it's validation: https://github.com/silverstripe/silverstripe-framework/blob/3.5/forms/EmailField.php#L39
Alternatively you could also implement a custom validator by extending Validator or RequiredFields. The validator will be applied to the whole form though and if you start validating individual field types there, you'd be better off just implementing the field as custom class (that way you have a re-usable component).
I had to implement a 10 characters length for phone numbers the other day.
https://github.com/sheadawson/silverstripe-zenvalidator
I included the module above via composer and followed the set up in the README.
For the admin interface I created a getCMSValidator() method
public function getCMSValidator() {
$validator = ZenValidator::create();
$validator->setConstraint('Phone', Constraint_length::create('range', 10, 10)->setMessage('Phone numbers must be 10 digits in length'));
$validator->setConstraint('PhoneAH', Constraint_length::create('range', 10, 10)->setMessage('Phone numbers must be 10 digits in length'));
$validator->setConstraint('PhoneMobile', Constraint_length::create('range', 10, 10)->setMessage('Mobile numbers must be 10 digits in length'));
$validator->disableParsley();
return $validator;
}
For the front end just create a $validator and then add it to the form
$validator = ZenValidator::create();
$validator->setConstraint('Phone', Constraint_length::create('range', 10, 10)->setMessage('Phone numbers must be 10 digits in length'));
$validator->disableParsley();
$Form = new Form($this, 'FormName', $fields, $actions, $validator);
Took me about 20 minutes to implement that minimum 10 & maximum 10 characters on about 5 or 6 different forms.
I hope this helps.
Cheers,
Colin
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I want to validate user input phone number where number should be exactly 11 and started with 01 and value field should be number only. How do I do it using Laravel validation?
Here is my controller:
public function saveUser(Request $request){
$this->validate($request,[
'name' => 'required|max:120',
'email' => 'required|email|unique:users',
'phone' => 'required|min:11|numeric',
'course_id'=>'required'
]);
$user = new User();
$user->name= $request->Input(['name']);
$user->email= $request->Input(['email']);
$user->phone= $request->Input(['phone']);
$user->date = date('Y-m-d');
$user->completed_status = '0';
$user->course_id=$request->Input(['course_id']);
$user->save();
return redirect('success');
}
One possible solution would to use regex.
'phone' => 'required|regex:/(01)[0-9]{9}/'
This will check the input starts with 01 and is followed by 9 numbers. By using regex you don't need the numeric or size validation rules.
If you want to reuse this validation method else where, it would be a good idea to create your own validation rule for validating phone numbers.
Docs: Custom Validation
In your AppServiceProvider's boot method:
Validator::extend('phone_number', function($attribute, $value, $parameters)
{
return substr($value, 0, 2) == '01';
});
This will allow you to use the phone_number validation rule anywhere in your application, so your form validation could be:
'phone' => 'required|numeric|phone_number|size:11'
In your validator extension you could also check if the $value is numeric and 11 characters long.
From Laravel 5.5 on you can use an artisan command to create a new Rule which you can code regarding your requirements to decide whether it passes or fail.
Ej:
php artisan make:rule PhoneNumber
Then edit app/Rules/PhoneNumber.php, on method passes
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return preg_match('%^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$%i', $value) && strlen($value) >= 10;
}
Then, use this Rule as you usually would do with the validation:
use App\Rules\PhoneNumber;
$request->validate([
'name' => ['required', new PhoneNumber],
]);
docs
Validator::extend('phone', function($attribute, $value, $parameters, $validator) {
return preg_match('%^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$%i', $value) && strlen($value) >= 10;
});
Validator::replacer('phone', function($message, $attribute, $rule, $parameters) {
return str_replace(':attribute',$attribute, ':attribute is invalid phone number');
});
Usage
Insert this code in the app/Providers/AppServiceProvider.php to be booted up with your application.
This rule validates the telephone number against the given pattern above that i found after
long search it matches the most common mobile or telephone numbers in a lot of countries
This will allow you to use the phone validation rule anywhere in your application, so your form validation could be:
'phone' => 'required|numeric|phone'
You can use this :
'mobile_number' => ['required', 'digits:10'],
Use
required|numeric|size:11
Instead of
required|min:11|numeric
You can try out this phone validator package. Laravel Phone
Update
I recently discovered another package Lavarel Phone Validator (stuyam/laravel-phone-validator), that uses the free Twilio phone lookup service
There are a lot of things to consider when validating a phone number if you really think about it. (especially international) so using a package is better than the accepted answer by far, and if you want something simple like a regex I would suggest using something better than what #SlateEntropy suggested. (something like A comprehensive regex for phone number validation)
I used the code below, and it works
'PHONE' => 'required|regex:/(0)[0-9]/|not_regex:/[a-z]/|min:9',
$request->validate([
'phone' => 'numeric|required',
'body' => 'required',
]);
I am building some user profiles and want to add social links to the profiles so users can link to their, let's say Steam, YouTube, Google+ profiles.
So i can't find any way of validating against specific url's in laravel. I want a user, if he set a link in steam text field to validate if given url is really url to steampowered.com, or if not to throw an error that url is not valid.
I have read the documentation on validation and i read that there is a URL validation, but as i have read it's only validating agains the input if it's formated as an url. so basically user can post any url and it will be validated.
Is there a filter or some additional condition to URL validation for a specific url. So the input field will be valid only if user insert like: http://steamcommunity.com in the field.
How can someone achieve that, or i must write old php regex expression?
You should definetely write your own custom Validator and use a regexp to verify that:
\Validator::extend('checkUrl', function($attribute, $value, $parameters)
{
$url = $parameters[0];
//Your pattern, not pretending to be super precise, so it's up to you
$pattern = '/^((http|https)\:\/\/)?(www\.)?'.$url.'\..+$/'
if( preg_match( $pattern,$value)
{
return true;
}
return false;
});
And to use it provide it as a rule to your validator
$rules = [
your_field => 'checkUrl:http://steamcommunity.com'
];
Such a thing is not built in. You can write a custom validation rule and then use regex as you said.
Validator::extend('steam_url', function($attribute, $value, $parameters)
{
$pattern = "#^https?://([a-z0-9-]+\.)*steamcommunity\.com(/.*)?$#";
return !! preg_match($pattern, $value);
});
Usage: 'url' => 'steam_url
Or something more generic:
Validator::extend('domain', function($attribute, $value, $parameters)
{
$domain = $parameters[0];
$pattern = "#^https?://([a-z0-9-]+\.)*".preg_quote($domain)."(/.*)?$#";
return !! preg_match($pattern, $value);
});
Usage: 'url' => 'domain:steamcommunity.com'
Both of your answers are correct guys, however i never liked using regex and i remembered what i did on some site i was making last year to match the website url, and to match it to the point where is no possible for user to input wrong url, and this will also match both http and https. So my final solution is to use parse_url method, very simple and thanks to your examples of validator parameters i can also use it on multiple different domains.
Here's my final code.
Validator::extend('checkUrl', function($attribute, $value, $parameters) {
$url = parse_url($value, PHP_URL_HOST);
return $url == $parameters[0];
EDIT: there is even simpler solution instead of using if method and returning false or true, you can just use return method with option you want to validate.
return $url == $parameters[0];
This would be resolved as
if($url == $parameters[0]) {
return true
} else {
return false
}