Search code examples
laravellaravel-5.3

How to write custom validation rule in controller Laravel?


I have default validation rule in controller Laravel:

$validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'phone' => 'required|numeric',
            'code' => 'required|string|min:3|max:4',
            'timezone' => 'required|numeric',
            'country' => 'required|integer',
            'agreement' => 'accepted'
        ]);

I tried this, but dont know how to transfer some parameters inside function:

 public function boot()
    {
        Validator::extend('phone_unique', function($attribute, $value, $parameters) {
            return substr($value, 0, 3) == '+44';
        });
    }

How can I extent this validation by my own rule? For example I need to validate concatination of inputs:

$phone = $request->code.' '.$request->phone

After check if $phone are exists in database

I want to use this method:

>  $validator->sometimes('phone', 'required|alpha_dash|max:25', function
> ($input) {
>             if ((Auth::user()->phone == $input->phone)) {
>                 return false;
> 
>             } else {
> 
>                 $t = User::where("phone", $input->phone)->get();
>                 return ($t->count() > 0) ? false : false;
> 
>             }
>         });

It does not work under all conditions (True, False) inside.

I added new validation nickname_unique:

 $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'code' => 'required|string|min:3|max:4',
            'phone' => 'required|phone_unique',
            'timezone' => 'required|numeric',
            'country' => 'required|integer',
            'nickname' => 'required|alpha_dash|max:25',
            'agreement' => 'accepted'
        ], [
            'phone_unique' => 'Phone already exists!',
            'nickname_unique' => 'Nickname is busy!',
        ]);

It does not work, even not call validation rule below previos:

Validator::extend('nickname_unique', function ($attribute, $value, $parameters, $validator) {

            dd("Here");

});

Solution

  • You can define your custom validator inside AppServiceProvider like this:

    <?php
    
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    use Illuminate\Support\Facades\Validator;
    
    class AppServiceProvider extends ServiceProvider
    {
        /**
         * Bootstrap any application services.
         *
         * @return void
         */
        public function boot()
        {
            Validator::extend('phone_unique', function ($attribute, $value, $parameters, $validator) {
              $inputs = $validator->getData();
              $code = $inputs['code'];
              $phone = $inputs['phone'];
              $concatenated_number = $code . ' ' . $phone;
              $except_id = (!empty($parameters)) ? head($parameters) : null;
    
              $query = User::where('phone', $concatenated_number);
              if(!empty($except_id)) {
                $query->where('id', '<>', $except);
              }
    
              return $query->exists();
          });
    
        /**
         * Register the service provider.
         *
         * @return void
         */
        public function register()
        {
            //
        }
    }
    

    You can get all the inputs passed to the validator, by accessing $validator property - getData()

    You can just add an extra parameter to your rules array after your custom validation rule (just after the colon) like this:

    'phone' => 'required|phone_unique:1',
    

    Pass the id to be ignored while checking entries into the db

    The custom validator Closure receives four arguments: the name of the $attribute being validated, the $value of the attribute, an array of $parameters passed to the rule, and the Validator instance.

    Now you can call the validator like this:

    $validator = Validator::make($request->all(), [
          'email' => 'required|email',
          'code' => 'required|string|min:3|max:4',
          'phone' => 'required|phone_unique:1',
          'timezone' => 'required|numeric',
          'country' => 'required|integer',
          'agreement' => 'accepted'
      ], [
        'phone_unique' => 'Phone already exists!', // <---- pass a message for your custom validator
      ]);
    

    See more about Custom Validation Rules.