Проверка полей условно с помощью Laravel
У меня есть следующие правила проверки для Laravel:
return [
'offer_type' => 'required|in:permanent,temporary',
'start_date' => 'required_if:offer_type,temporary|date_format:d/m/Y',
'end_date' => 'required_if:offer_type,temporary|date_format:d/m/Y|after:start_date',
];
В основном, если offer_type
является temporary
, start_date
а также end_date
требуется и должен следовать d/m/Y
формат. Так же end_date
должно быть после start_date
,
Если offerType
является permanent
нет необходимости подтверждать start_date
или же end_date
так как они даже не используются.
Проблема у меня заключается в том, что, если пользователь отправляет данные следующим образом:
offerType
: постоянныйstartDate
: fooendDate
: бар
Тогда Laravel выдаст ошибку проверки, даже если start_date
а также end_date
не требует проверки, так как тип предложения permanent
,
Как я могу сделать так, чтобы Laravel только проверял start_date
а также end_date
если offer_type
является temporary
,
Мое (плохое) решение
Единственный способ найти эту проблему - сделать следующее:
Измените приведенные выше правила проверки на следующее:
return [
'offer_type' => 'required|in:permanent,temporary',
'start_date' => 'required_if:offer_type,temporary',
'end_date' => 'required_if:offer_type,temporary',
];
и добавьте следующий код в валидатор:
$validator->after(function (Validator $validator) {
$data = $validator->getData();
$failed = $validator->failed();
if (array_key_exists('offerType', $data) &&
$data['offerType'] === 'temporary' &&
array_key_exists('start_date', $data) &&
array_key_exists('end_date', $data) &&
!array_key_exists('start_date', $failed) &&
!array_key_exists('end_date', $failed)
) {
$startDateString = $data['start_date'];
$endDateString = $data['end_date'];
$startDate = Carbon::createFromFormat('d/m/Y', $startDateString);
$endDate = Carbon::createFromFormat('d/m/Y', $endDateString);
if ($startDate === false) {
$validator->errors()->add('start_date', 'Start date must be in the format "dd/mm/yyyy"');
}
if ($endDate === false) {
$validator->errors()->add('end_date', 'End date must be in the format "dd/mm/yyyy"');
}
if ($startDate !== false && $endDate !== false && $endDate->lt($startDate)) {
$validator->errors()->add('end_date', 'End date must be after or equal to the start date');
}
}
});
1 ответ
Я бы предложил вам иметь отдельный класс FormRequest. Тогда ваш rules()
будет выглядеть так:
public function rules()
{
$rules = [
'offer_type' => 'required|in:permanent,temporary',
'start_date' => 'required_if:offer_type,temporary',
'end_date' => 'required_if:offer_type,temporary',
];
if ($this->offer_type == 'permament') {
$this->getInputSource()->remove('start_date'); // optionally you may remove start_date from request
$this->getInputSource()->remove('end_date'); // same of end_date
unset($rules['start_date']);
unset($rules['end_date']);
}
return $rules;
}
Документы Laravel о проверке формы запроса