'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]
}
]
In short I just want to validate that the pair
industry_idandlicense_idexists in theindustry_licensetable.Also, what regex value do I use to validate this string in the
business_hoursfield:"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.
Solution 1:[1]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | gitmiro |
