6

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?

LF00
  • 27,015
  • 29
  • 156
  • 295
  • 1
    Does https://laravel.com/docs/5.4/validation#custom-validation-rules not suffice? – ceejayoz Jun 28 '17 at 03:53
  • @ceejayoz please read my question more. Here I'm not writing a custom validation rule. I want to extent the unique rule. – LF00 Jun 28 '17 at 03:55
  • What is the initial value of `id`? does it `int` then it will be encrypted?! – SaidbakR Jun 28 '17 at 03:58
  • In other words, what do you mean by "extend unique rule"? Unique is unique! i.e it checks your table for exactly the same value! – SaidbakR Jun 28 '17 at 04:00
  • @SaidbakR the id is string type, and I need to encrypt the idenfitier then store here. Here I use extend may not proper, I need a validation rule that encrypt on the input value first, then do the same as unique. – LF00 Jun 28 '17 at 04:04
  • 2
    @KrisRoofe You say "extend the unique rule". I say that's a custom validation rule. The `unique` rule is just a validation rule - you can make your own that mimics it with your specific requirements. – ceejayoz Jun 28 '17 at 13:56
  • @ceejayoz Thank you. Maybe I should change my question to how to use laravel's validation rule in custom validation rule is proper. – LF00 Jun 29 '17 at 01:45

3 Answers3

3

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"
alepeino
  • 9,551
  • 3
  • 28
  • 48
1

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;

}
wahdan
  • 1,208
  • 3
  • 16
  • 26
  • I know this works. I want to use this `encrypt()` in the validation rule as stated in my question. – LF00 Jun 28 '17 at 08:02
0

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!');
        }