Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
90 views
in Technique[技术] by (71.8m points)

php - Laravel Array based date validation after_or_equal multiple dates?

I am importing excel file to collections using laravel-excel package. I am trying to validate the date field reporting_date such that it is after_or_equal two other date fields registered_date and analysis_date. With only one after_or_equal date field all this is working fine. I am dynamically populating the rules and custom messages array. The rules are applying correctly but I have problem overriding the default message by the custom message for this particular validation and instead the default message is displayed.

public function collection(Collection $rows)
{
  $data = $rows->toArray();
  $rules = [Some static rules defined];

  $messages = [];
        
        
  foreach ($data as $key => $val){
     /*Adding [complex/]conditional rules and messages.*/
     ...
     ...
    if(!empty($val['reporting_date'])){
            $rules = array_merge($rules, [$key.'.reporting_date' => ['sometimes', 'nullable', 'date', 'after_or_equal:'.$key.'.registered_date,', 'after_or_equal:'.$key.'.analysis_date']]);

            $messages["$key.reporting_date.date"] = "Error on row: <strong>".($key+2)."</strong>. The reporting_date <strong>".(Arr::exists($val, "reporting_date")?$val['reporting_date']:"").
                    "</strong> is not a valid date.";
            
            /****These messages are not overriding the default message.****/  
            $messages["$key.reporting_date.after_or_equal.$key.registered_date"] = "Error on row: <strong>".($key+2)."</strong>. The reporting_date <strong>".(Arr::exists($val, "reporting_date")?$val['reporting_date']:"").
                    "</strong> must be a date after or equal to registered_date <strong>".(Arr::exists($val, "registered_date")?$val['registered_date']:"").
                    "</strong>.";
            
            $messages["$key.reporting_date.after_or_equal.$key.analysis_date"] = "Error on row: <strong>".($key+2)."</strong>. The reporting_date <strong>".(Arr::exists($val, "reporting_date")?$val['reporting_date']:"").
                    "</strong> must be a date after or equal to analysis_date <strong>".(Arr::exists($val, "analysis_date")?$val['analysis_date']:"").
                    "</strong>.";
    ...
    ...
            
            
    }
  }  
}

The message I am getting instead is

The 0.reporting_date must be a date after or equal to 0.registered_date.
The 0.reporting_date must be a date after or equal to 0.analysis_date.

The validation rule:

"0.reporting_date" => array:5 [▼
      0 => "sometimes"
      1 => "nullable"
      2 => "date"
      3 => "after_or_equal:0.registered_date,"
      4 => "after_or_equal:0.analysis_date"
    ]

I suspect that I am not assigning the message to the correct array key and hence I am not seeing the custom message. Right now it is assigned like this and I would like this message to be displayed.

"0.reporting_date.after_or_equal.0.registered_date" => "Error on row: 2. The reporting_date 2020-09-08 must be a date after or equal to registered_date 2020-09-12."
"0.reporting_date.after_or_equal.0.analysis_date" => "Error on row: 2. The reporting_date 2020-09-08 must be a date after or equal to analysis_date 2020-09-14."

Also on debugging the error message.

dd($validator->errors()); 
0.reporting_date" => array:2 [▼
      0 => "The 0.reporting_date must be a date after or equal to 0.registered_date."
      1 => "The 0.reporting_date must be a date after or equal to 0.analysis_date."
    ]
question from:https://stackoverflow.com/questions/65888787/laravel-array-based-date-validation-after-or-equal-multiple-dates

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

To specify a custom error message only for a specific attribute, you specify the attribute's name first, followed by the rule:

field.rule => message

Like

$messages = [
    'email.required' => 'We need to know your email address!',
];

So I had to check if 0.reporting_date is after_or_equal 0.registered_date and 0.analysis_date. I had the rules set up like:

"0.reporting_date" => array:5 [▼
      0 => "sometimes"
      1 => "nullable"
      2 => "date"
      3 => "after_or_equal:0.registered_date,"
      4 => "after_or_equal:0.analysis_date"
    ]

When one of the validations of after_or_equal failed, I could override the messages like

0.reporting_date.after_or_equal => "custom message"

But when both after_or_equal:0.registered_date and after_or_equal:0.analysis_date failed, I thought it was possible to write custom messages for individual cases like below which would have been ideal.

"0.reporting_date.after_or_equal.0.registered_date" => "custom message1"
"0.reporting_date.after_or_equal.0.analysis_date" => "custom message2"

But that did not work and I had to do a bit of hack by manually comparing the dates and then appending both messages which solved the problem.

if(!(Carbon::parse(0.reporting_date)->gte(Carbon::parse(0.registered_date)) && Carbon::parse(0.reporting_date)->gte(Carbon::parse(0.analysis_date)))){
    0.reporting_date.after_or_equal => "custom message1"."custom message2"
}

I would like to see if there are other better approaches.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...