Laravel自定义验证规则适用于不需要空字段

时间:2018-04-01 23:49:37

标签: php laravel laravel-5

我需要将数据库中记录的文件字段作为路径。如果数据库中的字段为null,我想让它可选。在我的控制器的update操作中,我设置了以下验证:

$this->validate(request(),[
    'drawings' => 'requiredIfEmpty:'.$product->drawings.'|file|max:'. config('fox.photoMaxSize').'|mimes:pdf',

然后在app/Providers/AppServiceProvider.php我定义了requiredIfEmpty验证器:

Validator::extend('requiredIfEmpty',function ($attribute,$value,$parameters,$validator){
        if(is_null($parameters[0]) || empty($parameters[0])){
            if (is_null($value)){
                return false;
            }
        }
        return true;
    });

    Validator::replacer('requiredIfEmpty', function ($message, $attribute, $rule, $parameters) {
        return __('The :attr is required',['attr' => $attribute]);
    });

在视图_form中,我使用表单帮助器,如下所示drawings字段:

<div class="form-group {{$errors->first('drawings','has-error')}}">
    @if (!is_null($product->drawings))
    <a href="{{$product->drawings}}" target="_bfox"><img src="/imgs/pdf.png" alt="{{__('PDF File')}}" title="{{__('PDF File')}}" /></a>
    <br>
    @else
    <img src="/imgs/empty.png" width="64" height="64" alt="{{__('Empty')}}..." title="{{__('Empty')}}..." /> <br>
    @endif
    {!! Form::label('drawings', __('Drawings')) !!}        

        {!! Form::file('drawings',['class' => 'btn btn-info','title' =>__('PDF file')]); !!}
        @php ($eleE =  $errors->first('drawings'))
        @include('layouts.form-ele-error')

</div>

问题是,我的自定义验证规则没有被调用,因为该字段不是必需的,并且它具有空值。我需要任何允许两种情况的方式:

  1. drawings文件字段为空并且$product->drawings不为空时,未发生任何验证
  2. drawings文件字段为空且$product->drawings为空时,验证发生。
  3. 换句话说,我需要一个内置的验证规则,例如requiredIf,但不会将另一个表单字段作为参数,它只需要另一个值,它甚至可以在表单中工作字段值为空,不需要该字段。

2 个答案:

答案 0 :(得分:1)

您应该使用extendImplicit函数在规则值为空时运行规则。

Validator::extendImplicit('required_if_exists', function($attribute, $value, $parameters, $validator) {
    //
});

或者,在Rule类中,您应该实现ImplicitRule接口而不是Rule

use Illuminate\Contracts\Validation\ImplicitRule;

class RequiredIfExists implements ImplicitRule {
    //
}

答案 1 :(得分:0)

我找到了一个与Laravel验证无直接关系的解决方案。它将取决于保持文件字段的原始验证并保持不需要,然后在控制器的操作中生成验证逻辑,如果发现错误,则返回errorbag​​消息。该解决方案类似于以下代码段:

public function update(Request $request, Product $product)
    {       
        $product = Product::find(request('product'));
        $this->validate(request(),[

            'drawings' => 'file|max:'. config('fox.photoMaxSize').'|mimes:pdf' //Original validation

        ]);
if(is_null($request->drawings) && is_null($product->drawings)){
            return redirect()->back()->withErrors(['drawings' => __('A drawing file must be specified')]);
        } //If the field is null and the database attribute is null too an error message is returned to form's file field.
...
}

但是,此解决方案没有回答我们如何定义一个总是调用的自定义验证规则 - 不管是否需要设置字段?

Reference