Search code examples
phplaravellaravel-5laravel-5.1laravel-validation

Laravel validation OR


I have some validation that requires a url or a route to be there but not both.

    $this->validate($request, [
        'name'  =>  'required|max:255',
        'url'   =>  'required_without_all:route|url',
        'route' =>  'required_without_all:url|route',
        'parent_items'=>  'sometimes|required|integer'
    ]);

I have tried using required_without and required_without_all however they both get past the validation and I am not sure why.

route is a rule in the route field


Solution

  • I think the easiest way would be creation your own validation rule. It could looks like.

    Validator::extend('empty_if', function($attribute, $value, $parameters, Illuminate\Validation\Validator $validator) {
    
        $fields = $validator->getData(); //data passed to your validator
    
        foreach($parameters as $param) {
            $excludeValue = array_get($fields, $param, false);
    
            if($excludeValue) { //if exclude value is present validation not passed
                return false;
            }
        }
    
        return true;
    });
    

    And use it

        $this->validate($request, [
        'name'  =>  'required|max:255',
        'url'   =>  'empty_if:route|url',
        'route' =>  'empty_if:url|route',
        'parent_items'=>  'sometimes|required|integer'
    ]);
    

    P.S. Don't forget to register this in your provider.

    Edit

    Add custom message

    1) Add message 2) Add replacer

    Validator::replacer('empty_if', function($message, $attribute, $rule, $parameters){
        $replace = [$attribute, $parameters[0]];
        //message is: The field :attribute cannot be filled if :other is also filled
        return  str_replace([':attribute', ':other'], $replace, $message);
    });