TheGPWorx
TheGPWorx

Reputation: 887

How to pass the value of an item in an array to the validation rule of another parameter in Laravel?

$validator = Validator::make($data, [
        'business_hours' => ['string','max:100','regex:/([0-7]:([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9],?)?/'],
        'industries' => 'array',
        'industries.*.industry' => 'numeric',
        'industries.*.license' => 'array',
        'industries.*.license.*' => 'numeric|exists:industry_license,license_id,industry_id',
    ]);

In the validation rule above I would want to validate that the value in "industries.*.industry" and 'industries.*.license.*' is being validated such that in the exists rule in "industries.*.license.*", both the industry value and license value are being validated.

This is the migration script for the industry_license table.

Schema::create('industry_license', function (Blueprint $table) {
        $table->unsignedInteger('license_id');
        $table->unsignedInteger('industry_id');

        $table->primary(['license_id', 'industry_id']);
    });

This is the sample body of the request:

"business_hours": "2:10:00:14:00,3:0:00:23:00,4:0:00:23:00,5:0:00:23:00,6:0:00:23:00,7:0:00:23:00,1:0:00:23:00",
"industries": [
    {
        "industry" : 3,
        "license": [2,4,7]
    },
    {
        "industry" : 2,
        "license": [3]
    }
]
  1. In short I just want to validate that the pair industry_id and license_id exists in the industry_license table.

  2. Also, what regex value do I use to validate this string in the business_hours field:

    "2:10:00:14:00,3:0:00:23:00,4:0:00:23:00,5:0:00:23:00,6:0:00:23:00,7:0:00:23:00,1:0:00:23:00"

The expected value in the business_hours field is {day}:{start_time}:{end_time}, ex. (2:10:00:14:00) which would translate to Tuesday 10am - 2pm. Basically it's a comma delimited string of scheduled dates.

Upvotes: 0

Views: 507

Answers (1)

gitmiro
gitmiro

Reputation: 126

As for question 1, you might use a Custom Rule.

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
use Illuminate\Validation\Validator;


class IndustryValidator implements Rule, ValidatorAwareRule
{

  protected Validator $validator;

  public function setValidator($validator)
  {
    $this->validator = $validator;

    return $this;
  }


  public function passes($attribute, $value)
  {
    collect($value)->each(function ($pair) {
        if ($industry = $pair["industry"] && ($license = $pair["license"])) {
            $this->checkIndustryLicensePairExists($industry, $license);
        }
    });

    return !$this->validator->errors();
  }

  private function checkIndustryLicensePairExists($industry, $license)
  {
    // ... make your checks

    // on fail
    $this->validator->addFailure("industry.*.{$industry}", "exists");
  }

  public function message()
  {
    //
  }
}

And call it in your client code:

$validator = Validator::make($toTest, [
        "industries" => new IndustryValidator(),
        "industries.*.industry" => "numeric|required",
        "industries.*.license" => "array|required",
        "industries.*.license.*" => "numeric",
    ]);

    $valid = $validator->validate();

Question 2 is more a regex thing. Try that in an non Laravel specific section.

Upvotes: 1

Related Questions