我有一个如下请求

"date" => "2022-05-25"
"shift" => "2"
"attendance" => array:1 [▼
  4 => array:5 [▼
    "present" => "on"
    "employee_id" => "4"
    "time_in" => "15:00"
    "time_out" => "01:00"
    "note" => null
  ]

知道每个班次都有自己的开始和离开时间,每个班次也可以 Select 跨越午夜.对于这种情况,我们有这样的转变

#attributes: array:6 [▼
    "id" => 2
    "title" => "Evening Shift"
    "starting_time" => "15:00"
    "leaving_time" => "01:00"
    "across_midnight" => 1
    "user_id" => 1
  ]

what I need is to validate the time_in and time_out to be between starting_time and leaving_time

例如,这里(在本例中)的有效值可以是17:00、18:00、22:00、00:30,而14::00不是有效值

这是我现在的验证规则,如果轮班时间不超过午夜,它会很好地工作

public function rules()
    {
        $shift = Shift::find($this->shift);
        $rules = [
            'date' => 'required|date|date_format:Y-m-d',
            'shift' => 'required|exists:shifts,id,user_id,' . auth()->id(),
            'attendance' => 'required|array',
            'attendance.*.employee_id' => 'required|exists:employees,id,user_id,' . auth()->id(),
        ];

        foreach ($this->attendance as $key => $Value) {
            $rules['attendance.' . $key . '.time_in'] = [Rule::requiredIf($this->has('attendance.' . $key . '.present')), 'date_format:H:i', 'nullable', 'after_or_equal:' . $shift?->starting_time, 'before_or_equal:' . $shift?->leaving_time];
            $rules['attendance.' . $key . '.time_out'] = [Rule::requiredIf($this->has('attendance.' . $key . '.present')), 'date_format:H:i', 'nullable', 'after_or_equal:' . $shift?->starting_time, 'before_or_equal:' . $shift?->leaving_time];
        }

        return $rules;
    }

如果轮班时间过了午夜,我会得到这样的结果

The Time In must be a date before or equal to 01:00.

The Time Out must be a date after or equal to 15:00.

推荐答案

我终于找到了解决办法.

我使用命令"php artisan make:rule CrossMiddNightTimeValidation"创建了一个规则

在创建的文件中

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class CrossMidnightTimeValidation implements Rule
{
    private $starting_time,$end_time;

    public function __construct($starting_time, $end_time)
    {
        $this->starting_time = $starting_time;
        $this->end_time = $end_time;

    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute,  $value)
    {
        return ($value >= $this->starting_time && $value <= now()->endOfDay()->format('H:i'))
            || (($value >= now()->startOfDay()->format('H:i') && $value <= $this->end_time));
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'Invalid Time (out of the shift time).';
    }
}

为了我的规则.

public function rules()
    {
        $shift = Shift::find($this->shift);
        $rules = [
            'date' => 'required|date|date_format:Y-m-d',
            'shift' => 'required|exists:shifts,id,user_id,' . auth()->id(),
            'attendance' => 'required|array',
            'attendance.*.employee_id' => 'required|exists:employees,id,user_id,' . auth()->id(),
        ];
        if ($shift->across_midnight) {
            foreach ($this->attendance as $key => $value) {
                $rules['attendance.' . $key . '.time_in'] = [Rule::requiredIf($this->has('attendance.' . $key . '.present')), 'date_format:H:i', 'nullable', new CrossMidnightTimeValidation($shift?->starting_time, $shift?->leaving_time)];
                $rules['attendance.' . $key . '.time_out'] = [Rule::requiredIf($this->has('attendance.' . $key . '.present')), 'date_format:H:i', 'nullable', new CrossMidnightTimeValidation($shift?->starting_time, $shift?->leaving_time)];
            }
        }
        else {
            foreach ($this->attendance as $key => $value) {
                $rules['attendance.' . $key . '.time_in'] = [Rule::requiredIf($this->has('attendance.' . $key . '.present')), 'date_format:H:i', 'nullable', 'before_or_equal:attendance.' . $key . '.time_out', 'after_or_equal:' . $shift?->starting_time];
                $rules['attendance.' . $key . '.time_out'] = [Rule::requiredIf($this->has('attendance.' . $key . '.present')), 'date_format:H:i', 'nullable', 'before_or_equal:' . $shift?->leaving_time, 'after_or_equal:' . $shift?->starting_time];
            }
        }
        return $rules;
    }

Laravel相关问答推荐

发送邮箱后,Laravel重定向偶尔会导致错误500

CKEditor在laravel中的p标记之前和之后添加额外的p标记

Laravel复选框值更新

如何在Vite和Rollup中完全禁用分块?

Laravel:在行的子集上同步多对多

如何在 laravel 中为另一个用户 session()->forget('cart')?

如何在 Laravel Eloquent Collection 数组之前添加一个键值对?

Laravel 5 将错误发送到Electron邮件

Laravel API 版本控制文件夹 struct

Laravel 5表单请求验证返回禁止错误

如何在使用 Laravel 在控制器中发送邮件之前更改邮件配置?

Laravel 监听器监听多个事件

如何在 Laravel 中为模型命名,以免与现有类发生冲突?

laravel 5中的配置缓存导致找不到视图

laravel 5 - assets资源 list 中未定义 css 文件?

在 laravel 6.0 中未定义命令ui

控制器外部的 Laravel 访问请求对象

如何调试 Laravel 框架?

Laravel 字符串验证以允许空字符串

在 Laravel 中翻译特定语言