Laravel custom form array validation rules

I want to create a form request validation and don't know how to do it.

I have a form:

<form>
  <input type="text" name="fullname[0]">
  <input type="text" name="document_num[0]">

  <input type="text" name="fullname[1]">
  <input type="text" name="document_num[1]">

  <input type="text" name="fullname[2]">
  <input type="text" name="document_num[2]">

   .....

  <input type="text" name="fullname[n]">
  <input type="text" name="document_num[n]">

  <input type="submit">
</form>

      

table 'users':

  id | fullname | document_num
  1  | John     | 111
  2  | Jane     | 112
 ..  | ...      | ...

      

when the user clicks on submit a request, it is sent to the controller method where it is first validated via a form request (or it could be a regular validator). So I want to write a rule that checks:

for (i=0; i<numberOfUsersToAdd; i++)

    if  (‘document_num[$i]’ exists in ‘users’ in field ‘document_num’ ) {

       $user = Users::find(id of user in DB having this ‘document_num[$i]’) ; 

       check if (fullname[$i] == $user->fullname) {

                return true} // input-ed users name match his/her name in DB.

        else {return false}  // input-ed users name doesn't match his/her name in DB.

        } 

    else return true; // document_num[$i] doesn't exists in the database which ok

      

if in words: check if any input-ed document_num [$ i] exists in the users table, if yes get the user having this document_nubmer from the database and compare his / her full name with the full name [$ i] from the entrance.

How to do it?:)

Appreciate any help! :)

0


source to share


1 answer


Ok. The logic behind this check is as YourFormRequest

follows:

  • Mark all fields as required and document_num

    optional field as whole. You can add other additional restrictions - it doesn't matter.
  • In rules

    the YourFormRequest

    check in loop method "does the user exist for the given document_num

    ?".
  • If it does not exist, then ok - validation of this field is successful.
  • If it exists, then check if the username is equal to the given one fullname

    . If equals then ok, validation of this field is successful. Otherwise, if that fails, attach your custom rule to this field, which always fails.

Take a look at this approach with a working example.

YourFormRequest.php

public function rules()
{
    $rules = [
        'fullname.*' => 'required',
        'document_num.*' => 'required|integer',
    ];

    $documentNums = request()->get('document_num');
    $fullnames = request()->get('fullname');

    for ($i = 0; $i < count($documentNums); $i++) {
        $user = User::where('document_num', $documentNums[$i])->first();
        if ($user && ($user->fullname != $fullnames[$i]) {
            $rules['document_num.' . $i] = "document_num_fail:$i"; //some rule that always fails. As argument we pass a row number of field that fails
        }
    }
    return $rules;
}

      

CustomValidator.php (place it, for example, in the App \ Services folder)



namespace App\Services;

class CustomValidator {

    public function documentNumFailValidate($attribute, $value, $parameters, $validator) {
        return false;
    }

    public function documentNumFailReplacer($message, $attribute, $rule, $parameters) {
        return str_replace([':index'], $parameters[0], $message);
    }
}

      

You can see two functions here. First - for validation (we always get the false reason we need). The second is just a replacement for the error message. You want to know which line of the field this error was on (for example, on the third line and in the fields: fullname [2] and document_num [2] respectively). As I wrote above in the comment for attaching the failure rule, we are specifying the number of lines that does not match the validation method (the method documentNumFailReplacer

will replace the: index placeholder in the error message with a given value)

The next step is to register these methods in AppServiceProvider.php

public function boot()
{
    Validator::extend('document_num_fail',  'App\Services\CustomValidator@documentNumFailValidate');
    Validator::replacer('document_num_fail', 'App\Services\CustomValidator@documentNumFailReplacer');
}

      

And the last step is to include your personalized messages in the validation.php file

'custom' => [
        'document_num.*' => [
            'document_num_fail' => 'Input-ed user name doesn`t match his/her name in DB for specified :attribute (field position/number: :index)',
        ]
    ],

'attributes' => [
    'document_num.*' => 'document number',
],

      

+2


source







All Articles