I am trying to implement a custom validation rule within lumen and I am following the docs for lumen 5.6. It says to refer to laravel validation to see how to use the validation. I am currently trying to make a validation to check if the value is a true null or not. So $x === "" would mean it fails Here is my rule located in App\Rules folder I created.
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class TrueNull implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
if($value === "") {
return false;
} else {
return true;
}
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The :attribute cannot be an empty string.';
}
}
I copied this straight from lumen docs and make my modification to the passes function. Within my modal have
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Model;
use Laravel\Lumen\Auth\Authorizable;
use App\Rules\TrueNull;
use Validator;
Then
public function validate($data)
{
// make a new validator object
$v = Validator::make($data,
[
'x' => ['regex:/^(?=.+)(?:[1-9]\d*|0)?(?:\.\d+)?$/', new TrueNull]
]
}
But the validation for TrueNull never happens am I missing a connection or something its really frustrating because the docs says this should work.
Here is my controller calling the update I am validating.
public function update(Request $request, $id)
{
/*
In middleware need to add community id to request.
*/
try {
$site = Site::findOrFail($id);
if ($site->validate($request->all())) {
$site->fill($request->all());
// save
$site->save();
} else {
return response()->json($site->errors(), 422);
}
} catch (Exception $e) {
return response()->json($e, 422);
}
return response()->json($site, 200);
}
For future reference I found a random snippet of code that offset the basic docs of Lumen. In my class for TrueNull instead of implements Rule I changed this to implements ImplicitRule and changed the use to \ImplicitRule and it is now catching that "" is not a null.
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\ImplicitRule;
class TrueNull implements ImplicitRule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
if($value === "") {
return false;
} else {
return true;
}
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The :attribute cannot be an empty string.';
}
}
The answer is greate by #Alexander Beyers but it doesn't work for Lumen 5.3. Here is how to create organised custom rules for the Lumen 5.3.
Create a Directory name Rules under app dir and Create the Following File:
namespace App\Rules;
use Illuminate\Support\Facades\Validator;
class AlphaSpace
{
public static function validate(){
//Extending the custom validation rule.
Validator::extend('alpha_spaces', function ($attribute, $value) {
// This will only accept alpha and spaces.
// If you want to accept hyphens use: /^[\pL\s-]+$/u.
return preg_match('/^[\pL\s]+$/u', $value);
});
}
}
Open the file resources/lang/en/validation and add the following under the Custom Validation:
Note:(under the Custom Validation is only for maintenance)
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'alpha_spaces' => 'The :attribute may only contain letters and spaces.',
Call the rule in app/Providers/AppServiceProvider::boot():
use HRM\Core\Rules\AlphaSpace;
class AppServiceProvider extends ServiceProvider
{
public function boot() {
AlphaSpace::validate();
}
// class will carry on with the stuffs!
Now you can use it anywhere you want to like this:
'first_name' => 'required|alpha_spaces|min:3|max:50',
'last_name' => 'required|alpha_spaces|min:3|max:50',
Version: Lumen 7.X
First, declare your rule in app/Providers/AppServiceProvider.php.
Create a boot() with your rule method as following (I registered a rule for phone number).
public function register()
{
//
}
public function boot()
{
app('validator')->extend('phone', function ($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;
});
app('validator')->replacer('phone', function ($message, $attribute, $rule, $parameters) {
return 'Phone number has wrong format.';
});
}
Different part in opposite of Laravel, and most important is, that AppServiceProvider is not registered in Lumen by default.
You need to go to bootstrap/app.php and uncomment following line:
$app->register(App\Providers\AppServiceProvider::class);
Maybe you would like to do composer dumpautoload, just in case, but it should work without it.
Then, in your code:
$validator = Validator::make(
$request->all(),
[
'tel' => 'required|phone'
],
[
'tel.required' => 'Phone is required',
'tel.phone' => 'Phone has wrong format'
]
);
That should be it!
Related
I have created a custom midddleware using the following command
php artisan make:middleware RedirectIfPasswordNotUpdated
This is my middlware
<?php
namespace App\Http\Middleware;
use Closure;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use App;
class RedirectIfPasswordNotUpdated
{
public function handle($request, Closure $next)
{
if (!App::environment(['production'])) {
return $next($request);
}
$user = Auth::user();
if (!$user->password_updated_at) {
return redirect()->route('profile.password.edit')->with([
'message' => 'Please update your password to proceed',
'alertType' => 'warning',
]);
}
if (Carbon::now()->diffInDays(Carbon::parse($user->password_updated_at)) > 90) {
return redirect()->route('profile.password.edit')->with([
'message' => 'Your password has expired! Please update your password to proceed',
'alertType' => 'warning',
]);
}
return $next($request);
}
}
I would like to use this middleware in the constructor of my controllers like following
public function __construct()
{
$this->middleware('auth');
$this->middleware('RedirectIfPasswordNotUpdated');
}
When, I do that I get a ReflectionException (-1) that says
Class RedirectIfPasswordNotUpdated does not exist
Here's the error in detail
C:\xampp\htdocs\gmi\vendor\laravel\framework\src\Illuminate\Container\Container.php
}
/**
* Instantiate a concrete instance of the given type.
*
* #param string $concrete
* #return mixed
*
* #throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function build($concrete)
{
// If the concrete type is actually a Closure, we will just execute it and
// hand back the results of the functions, which allows functions to be
// used as resolvers for more fine-tuned resolution of these objects.
if ($concrete instanceof Closure) {
return $concrete($this, $this->getLastParameterOverride());
}
$reflector = new ReflectionClass($concrete);
// If the type is not instantiable, the developer is attempting to resolve
// an abstract type such as an Interface or Abstract Class and there is
// no binding registered for the abstractions so we need to bail out.
if (! $reflector->isInstantiable()) {
return $this->notInstantiable($concrete);
}
$this->buildStack[] = $concrete;
$constructor = $reflector->getConstructor();
// If there are no constructors, that means there are no dependencies then
// we can just resolve the instances of the objects right away, without
// resolving any other types or dependencies out of these containers.
if (is_null($constructor)) {
array_pop($this->buildStack);
return new $concrete;
}
I an using this midddleware in other Laravel (v5.4, v5.6) projects in the same way which are working without any issues. But it's not working in the current version (v5.8). What am I doing wrong?
As i can see that you haven't registered your middleware class in app\Http\Kernel.php. registering a middleware is very simple just like below:
protected $routeMiddleware = [
'middle_name' => \App\Http\Middleware\RedirectIfPasswordNotUpdated::class,
]
I have input $data =['identifier' = 'xxxxxxxxxx'];, and want to save the encrypt($data['identifier']) to the table info primary id column.
I've to validate before save it. Rule unique:info, id isn't suitable here, so I want to write a custom validation rule. And in the custom validation rule, I encrypt() the value first, then use the unique validation rule.
I know how to write a custom validation rule, but how to use the unique validation rule in my custom validation rule?
Rules "unique" and "exists" use the DatabasePresenceVerifier class. So, you don't need to really extend the unique rule, just access this presence verifier. For instance:
Validator::extend('encrypted_unique', function ($attribute, $value, $parameters, $validator) {
list ($table, $column, $ignore_id) = $parameters; // or hard-coded if fixed
$count = $validator->getPresenceVerifier()->getCount($table, $column, encrypt($value), $ignore_id);
return $count === 0;
});
Then you can use it as usual:
'identifier' => "encrypted_unique:table,column,$this_id"
Suppose you have A ModuleRequest that validates your inputs,you can write this method in this class
protected function validationData()
{
$all = parent::validationData();
$all['email'] = encrypt($all['email']);
return $all;
}
Laravel has Custom Validation Rules (https://laravel.com/docs/8.x/validation#using-rule-objects)
For example I have a table named clients who has two unique fields ecnrypt using Laravel's encryption services (https://laravel.com/docs/8.x/encryption) and because its encrypted, i can't aply the unique directive of validation method (https://laravel.com/docs/8.x/validation#rule-unique). The fields are code_client and email
That's the reason of implements a Custom Validation Rules.
this Service has two methods: passes and message. The method passes take two variables: $attributes (take de field to validate) and $value (take de value of field), and return true or false. Te method message retrieve message in case of failure.
In clients example i mentioned, folow the next steps:
php artisan make:rule ValidateFieldsClients
in class that composer creates ValidateFieldsClients, I have to declare a method for validate the fields in passes, I use this method for validate both fields (code_client and email).
next i complete de method message to retrieve the issue to user in views
additionally i declare a property $field to identify what´s the field it have the errors
The class ValidateFieldsClients example:
/***/class ValidateFieldsClients implements Rule{protected $field; /**
* 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)
{
$clients = client::all();
$this->field = $attribute;
foreach ($clients as $client ) {
if ($value == Crypt::decryptString($client->$attribute)) return false;
}
return true;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return strtoupper($this->field).' exists, check.';
}
}
Then to validate I use Form Request Validation (https://laravel.com/docs/8.x/validation#form-request-validation)
php artisan make:request ClientRequest
And in the validate method of the recently created class:
class ClientRequest 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 [
'code_client'=> ['required', new ValidateFieldsClients],
'email'=>['required', new ValidateFieldsClients],
];
}
Finally in controller:
public function store(ClientRequest $request)
{ $clientRequest = $request->validated();
foreach ($clientRequest as $key => $client) {
$encryptedClient[$key] = Crypt::encryptString($client);
}; client::create($encryptedClient+ [
'idorga' => 1,
'idcrea' => 1,
'idmodifica' => 1
]);
return redirect('clientes/create')->with('success', 'Registro creado correctamente');
//return redirect('cuadros')->with('success', 'Registro exitoso!');
}
I have a very simple Rule method in request class like below.
public function rules()
{
return [
'Subject' => 'required|max:50',
'Description' => 'required|max:500',
'DepartmentID' => 'required|integer|min:1',
'PriorityID' => 'required|integer|min:1'
];
}
Inside Controller Action method, below is the code.
private function SaveChanges(\App\Http\Requests\TicketRequest $request) {
$v = \Validator::make($request->all(), [
]);
$DepartmentAdmins = $this->getDepartmentAdmins();
//Check if department admin missing then no need to add the record
if($DepartmentAdmins == null || count($DepartmentAdmins) == 0) {
$v->errors()->add('MissingAdmins', 'Department admin missing.');
return redirect()->back()->withErrors($v->errors());
}
}
Question:
As we can see in the rule method there are 4 form fields. Is there any way to shift the check for Department Admin existence from Controller Action method to request class?
Laravel's Request has after hook that can be run after normal validation completes. This is how you can use it in your case:
namespace App\Http\Requests;
use App\Http\Requests\Request;
use App\Models\Property;
use Illuminate\Validation\Validator;
class SomeRequest extends Request
{
/**
* Get the validator instance for the request.
*
* #return Validator
*/
protected function getValidatorInstance()
{
$instance = parent::getValidatorInstance();
$instance->after(function ($validator) {
$this->validateDepartmentAdmins($validator);
});
return $instance;
}
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'Subject' => 'required|max:50',
'Description' => 'required|max:500',
'DepartmentID' => 'required|integer|min:1',
'PriorityID' => 'required|integer|min:1'
];
}
/**
* #param Validator $validator
*/
public function validateDepartmentAdmins(Validator $validator)
{
$DepartmentAdmins = $this->getDepartmentAdmins();
//Check if department admin missing then no need to add the record
if($DepartmentAdmins == null || count($DepartmentAdmins) == 0) {
$validator->errors()->add('MissingAdmins', 'Department admin missing.');
}
}
That way you won't have to do any validation in your SaveChanges controller method.
This code is used in Laravel 5.1, but I believe it will work the same in 5.2.
The Form Request Class basically has two methods. "authorize" and "rules". the best way to shift the check for Department Admin existense is to add your own custom validator(for example named "adminCountValidator") and implement your logic for checking the number of administrators there. Then use yoir newly defined validator in "rules" method like this:
public function rules()
{
return [
'Subject' => 'required|max:50',
'Description' => 'required|max:500',
'DepartmentID' => 'required|integer|min:1|adminCountValidator',
'PriorityID' => 'required|integer|min:1'
];
}
if you define a custome validation rule, you can also define the associated error message and your controller action will be much more cleaner. here is the link for defining your own custom validator
custom-validation-rules
here is a sample code for adding a custom validator within a service provider
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Validator::extend('adminCountValidator', function($attribute, $value, $parameters, $validator) {
/*
implement your getDepartmentAdmins()
function here and return true or false
*/
});
}
I am using form request validation method for validating request in laravel 5.I would like to add my own validation rule with form request validation method.My request class is given below.I want to add custom validation numeric_array with field items.
protected $rules = [
'shipping_country' => ['max:60'],
'items' => ['array|numericarray']
];
My cusotom function is given below
Validator::extend('numericarray', function($attribute, $value, $parameters) {
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
});
How can use this validation method with about form request validation in laravel5?
While the above answer is correct, in a lot of cases you might want to create a custom validation only for a certain form request. You can leverage laravel FormRequest and use dependency injection to extend the validation factory. I think this solution is much simpler than creating a service provider.
Here is how it can be done.
use Illuminate\Validation\Factory as ValidationFactory;
class UpdateMyUserRequest extends FormRequest {
public function __construct(ValidationFactory $validationFactory)
{
$validationFactory->extend(
'foo',
function ($attribute, $value, $parameters) {
return 'foo' === $value;
},
'Sorry, it failed foo validation!'
);
}
public function rules()
{
return [
'username' => 'foo',
];
}
}
Using Validator::extend() like you do is actually perfectly fine you just need to put that in a Service Provider like this:
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ValidatorServiceProvider extends ServiceProvider {
public function boot()
{
$this->app['validator']->extend('numericarray', function ($attribute, $value, $parameters)
{
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
});
}
public function register()
{
//
}
}
Then register the provider by adding it to the list in config/app.php:
'providers' => [
// Other Service Providers
'App\Providers\ValidatorServiceProvider',
],
You now can use the numericarray validation rule everywhere you want
The accepted answer works for global validation rules, but many times you will be validating certain conditions that are very specific to a form. Here's what I recommend in those circumstances (that seems to be somewhat intended from Laravel source code at line 75 of FormRequest.php):
Add a validator method to the parent Request your requests will extend:
<?php namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Validator;
abstract class Request extends FormRequest {
public function validator(){
$v = Validator::make($this->input(), $this->rules(), $this->messages(), $this->attributes());
if(method_exists($this, 'moreValidation')){
$this->moreValidation($v);
}
return $v;
}
}
Now all your specific requests will look like this:
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
class ShipRequest extends Request {
public function rules()
{
return [
'shipping_country' => 'max:60',
'items' => 'array'
];
}
// Here we can do more with the validation instance...
public function moreValidation($validator){
// Use an "after validation hook" (see laravel docs)
$validator->after(function($validator)
{
// Check to see if valid numeric array
foreach ($this->input('items') as $item) {
if (!is_int($item)) {
$validator->errors()->add('items', 'Items should all be numeric');
break;
}
}
});
}
// Bonus: I also like to take care of any custom messages here
public function messages(){
return [
'shipping_country.max' => 'Whoa! Easy there on shipping char. count!'
];
}
}
Custom Rule Object
One way to do it is by using Custom Rule Object, this way you can define as many rule as you want without need to make changes in Providers and in controller/service to set new rules.
php artisan make:rule NumericArray
In NumericArray.php
namespace App\Rules;
class NumericArray implements Rule
{
public function passes($attribute, $value)
{
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
}
public function message()
{
return 'error message...';
}
}
Then in Form request have
use App\Rules\NumericArray;
.
.
protected $rules = [
'shipping_country' => ['max:60'],
'items' => ['array', new NumericArray]
];
Alternatively to Adrian Gunawan's solution this now also can be approached like:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreBlogPost extends FormRequest
{
public function rules()
{
return [
'title' => ['required', 'not_lorem_ipsum'],
];
}
public function withValidator($validator)
{
$validator->addExtension('not_lorem_ipsum', function ($attribute, $value, $parameters, $validator) {
return $value != 'lorem ipsum';
});
$validator->addReplacer('not_lorem_ipsum', function ($message, $attribute, $rule, $parameters, $validator) {
return __("The :attribute can't be lorem ipsum.", compact('attribute'));
});
}
}
You need to override getValidatorInstance method in your Request class, for example this way:
protected function getValidatorInstance()
{
$validator = parent::getValidatorInstance();
$validator->addImplicitExtension('numericarray', function($attribute, $value, $parameters) {
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
});
return $validator;
}
You don't need to extend the validator to validate array items, you can validate each item of a array with "*" as you can see in
Array Validation
protected $rules = [
'shipping_country' => ['max:60'],
'items' => ['array'],
'items.*' => 'integer'
];
All answers on this page will solve you the problem, but... But the only right way by the Laravel conventions is solution from Ganesh Karki
One example:
Let’s take an example of a form to fill in Summer Olympic Games events – so year and city. First create one form.
<form action="/olimpicyear" method="post">
Year:<br>
<input type="text" name="year" value=""><br>
City:<br>
<input type="text" name="city" value=""><br><br>
<input type="submit" value="Submit">
</form>
Now, let’s create a validation rule that you can enter only the year of Olympic Games. These are the conditions
Games started in 1896
Year can’t be bigger than current year
Number should be divided by 4
Let’s run a command:
php artisan make:rule OlympicYear
Laravel generates a file app/Rules/OlympicYear.php. Change that file to look like this:
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class OlympicYear implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
// Set condition that should be filled
return $value >= 1896 && $value <= date('Y') && $value % 4 == 0;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
// Set custom error message.
return ':attribute should be a year of Olympic Games';
}
}
Finally, how we use this class? In controller's store() method we have this code:
public function store(Request $request)
{
$this->validate($request, ['year' => new OlympicYear]);
}
If you want to create validation by Laravel conventions follow tutorial in link below. It is easy and very well explained. It helped me a lot. Link for original tutorial is here Tutorial link.
For me works the solution that give us lukasgeiter, but with a difference that we create a class with our custom validations ,like this, for laravel 5.2.* The next example is for add a validation to a range of date in where the second date has to be equals or more big that the first one
In app/Providers create ValidatorExtended.php
<?php
namespace App\Providers;
use Illuminate\Validation\Validator as IlluminateValidator;
class ValidatorExtended extends IlluminateValidator {
private $_custom_messages = array(
"after_or_equal" => ":attribute debe ser una fecha posterior o igual a
:date.",
);
public function __construct( $translator, $data, $rules, $messages = array(),
$customAttributes = array() ) {
parent::__construct( $translator, $data, $rules, $messages,
$customAttributes );
$this->_set_custom_stuff();
}
protected function _set_custom_stuff() {
//setup our custom error messages
$this->setCustomMessages( $this->_custom_messages );
}
/**
* La fecha final debe ser mayor o igual a la fecha inicial
*
* after_or_equal
*/
protected function validateAfterOrEqual( $attribute, $value, $parameters,
$validator) {
return strtotime($validator->getData()[$parameters[0]]) <=
strtotime($value);
}
} //end of class
Ok. now lets create the Service Provider. Create ValidationExtensionServiceProvider.php inside app/Providers, and we code
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Validator;
class ValidationExtensionServiceProvider extends ServiceProvider {
public function register() {}
public function boot() {
$this->app->validator->resolver( function( $translator, $data, $rules,
$messages = array(), $customAttributes = array() ) {
return new ValidatorExtended( $translator, $data, $rules, $messages,
$customAttributes );
} );
}
} //end of class
Now we to tell Laravel to load this Service Provider, add to providers array at the end in config/app.php and
//Servicio para extender validaciones
App\Providers\ValidationExtensionServiceProvider::class,
now we can use this validation in our request in function rules
public function rules()
{
return [
'fDesde' => 'date',
'fHasta' => 'date|after_or_equal:fDesde'
];
}
or in Validator:make
$validator = Validator::make($request->all(), [
'fDesde' => 'date',
'fHasta' => 'date|after_or_equal:fDesde'
], $messages);
you have to notice that the name of the method that makes the validation has the prefix validate and is in camel case style validateAfterOrEqual but when you use the rule of validation every capital letter is replaced with underscore and the letter in lowercase letter.
All this I take it from https://www.sitepoint.com/data-validation-laravel-right-way-custom-validators// here explain in details. thanks to them.
I am upgrading my Laravel application from 4 to 5. However, I have a custom validator that I cannot get to work.
In L4, I made a validators.php file and included it in global.php using require app_path().'/validators.php';.
I tried doing somewhat the same in L5. I dropped a validator in app/Validators/Validators.php, and updated my composer.json.
"files": [
"app/Validators/Validators.php"
]
However, now nothing renders on any page. What've I done wrong?
Try the following:
Make a bind class where you can implement each rule you want extending Validator class.
Make a service provider that extends ServiceProvider.
Add your custom validator provider at config/app.php file.
You can create the bind at Services folder like this:
namespace MyApp\Services;
class Validator extends \Illuminate\Validation\Validator{
public function validateFoo($attribute, $value, $parameters){
return $value == "foo"
}
}
Then, use a service provider to extends the core:
namespace MyApp\Providers;
use MyApp\Services\Validator;
use Illuminate\Support\ServiceProvider;
class ValidatorServiceProvider extends ServiceProvider{
public function boot()
{
\Validator::resolver(function($translator, $data, $rules, $messages)
{
return new Validator($translator, $data, $rules, $messages);
});
}
public function register()
{
}
}
Finally, import your service provider at config/app.php like so:
'providers' => [
...
...
'MyApp\Providers\ValidatorServiceProvider';
]
so here's what I did on adding a custom validation. this is for laravel 5.1
run PHP Artisan make:request MyFormValidationRequest file is created under app\Requests\MyFormValidationRequest.php
Here's the initial code:
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class MyFormValidationRequest 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 [
//
];
}
}
IMPORTANT: Change the return value of authorize() method to true, if you're not doing any authentication. it's initial value is false. else you get a white page with a "Forbidden" error message.
I added a rule under the function rules(), here's what it looks like
public function rules() {
return [
'activeuntil' => 'today_onwards'
];
}
today_onwards is my new validation.
I created a folder named 'Services' under App folder
I created a file named 'ValidatorExtended.php' under App\Services folder , here's the code below:
<?php
namespace App\Services;
use Illuminate\Validation\Validator;
use Carbon\Carbon;
class ValidatorExtended extends Validator {
private $_custom_messages = array(
"today_onwards" => "The :attribute must be today onwards",
);
public function __construct( $translator, $data, $rules, $messages = array(), $customAttributes = array() ) {
parent::__construct( $translator, $data, $rules, $messages, $customAttributes );
$this->_set_custom_stuff();
}
protected function _set_custom_stuff() {
//setup our custom error messages
$this->setCustomMessages( $this->_custom_messages );
}
protected function validateTodayOnwards( $attribute, $value ) {
$now = strtotime('-1 day');
$valueDateFormat = strtotime($value);
if($valueDateFormat > $now){
return true;
}
else {
return false;
}
}
}
Note: the validateTodayOnwards method is where you put your logic.
the name of the method should always start in "validate" then the name of your new validation key which should be in title case,
Another note your validation key should be separated by underscore and all small letters, in this case, "today_onwards". the underscore should be put before all first capital letters in the method name. I hope I explained it good.
TodayOnwards method is equivalent to validation name of "today_onwards",
another example, if I created validateOldPassword, your validation key should be "old_password".
I added below code in app\Providers\AppServiceProvider.php inside boot() method.
Validator::resolver(function($translator, $data, $rules, $messages = array(), $customAttributes = array())
{
return new ValidatorExtended($translator, $data, $rules, $messages, $customAttributes);
});
Don't forget to add below library, one is the Validator class and the other is your own class which is the "ValidatorExtended".
use App\Services\ValidatorExtended;
use Illuminate\Support\Facades\Validator;
Here's what the whole file looks like, [app\Providers\AppServiceProvider.php]
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Services\ValidatorExtended;
use Illuminate\Support\Facades\Validator;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
//
Validator::resolver(function($translator, $data, $rules, $messages = array(), $customAttributes = array())
{
return new ValidatorExtended($translator, $data, $rules, $messages, $customAttributes);
});
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}
That's it. done. you created your own custom validation.
Additionally, if you want to use it in your controller, below is the code:
class testController extends Controller
{
public function updatePass(MiscValidation $request){
//code here
}
}
Instead of using Request Class you use your own class which is an extension of the Request class.