LF-DevJourney
LF-DevJourney

Reputation: 28529

how to use laravel's validation rule in custom validation rule?

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?

Upvotes: 6

Views: 1137

Answers (3)

Esteban Cabrera
Esteban Cabrera

Reputation: 11

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:

  1. php artisan make:rule ValidateFieldsClients

  2. 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).

  3. next i complete de method message to retrieve the issue to user in views

  4. additionally i declare a property $field to identify what´s the field it have the errors

  5. 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.';
        }
    }
    
  6. Then to validate I use Form Request Validation (https://laravel.com/docs/8.x/validation#form-request-validation)

  7. php artisan make:request ClientRequest

  8. 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],
        ];
    }
    
  9. 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!');
        }
    

Upvotes: 0

alepeino
alepeino

Reputation: 9771

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"

Upvotes: 3

wahdan
wahdan

Reputation: 1258

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;

}

Upvotes: 1

Related Questions