0

I have this validation:

$data = request()->validate([
        'qty100' => ['integer'],
        'qty250' => ['integer'],
        'qty500' => ['integer'],
    ]);

I would need to check if at least one of them is bigger than 0... how can this be done?

1
  • Why don't you just validate it with an if statement? If none of them is bigger than 0, then return ValidationException::withErrors([]). Commented Apr 8, 2020 at 21:08

1 Answer 1

2

I think there is no built-in validation rule does something like what you want in Laravel, so you'll need to implement a custom validator, that will let you reuse validation where needed.

this is one way of doing it.

    request()->validate([
        'intone' => ['required', 'integer', 'greaterThanZeroWithoutAll:inttwo,intthree'],
        'inttwo' => ['required', 'integer'],
        'intthree' => ['required', 'integer'],
    ]);

in your AppServiceProvider

    public function boot()
    {
        //here we are creating a custom rule. called 'greaterThanZeroWithoutAll'
        //$attribute is the name we are validating,
        //$value is the value we get from the request,
        //$parameters are the arguments we pass in like greaterThanZeroWithoutAll:inttwo,intthree inttwo and intthree are parameters 
       //$validator is the validator object.

        Validator::extend('greaterThanZeroWithoutAll', function ($attribute, $value, $parameters, $validator) {
            //$validator->getData() is all the key value pairs from greaterThanZeroWithoutAll rule.
           //array_values($validator->getData()) we are only interested in the values, so this will return all the values.
           //implode(array_values($validator->getData())) will turn it into string
           //!(int) implode(array_values($validator->getData())) this uses no glue when imploding, then explicitly casts the generated string as an integer, then uses negation to evaluate 0 as true and non-zero as false. (Ordinarily, 0 evaluates as false and all other values evaluate to true.)

            if (!(int) implode(array_values($validator->getData()))) {
              //means all values are 0
                return false;
            }

            return true;
        });
        // this is error message
        Validator::replacer('greaterThanZeroWithoutAll', function ($message, $attribute, $rule, $parameters) {
            return 'not all fields are greater 0';
        });
    }

!(int) implode(array_values($validator->getData())) this code basically checks all the values are zero, there should many other ways to do this.

The reason we only do on the first value is that, we pass the other two values in and compare with it. So, it does it.

Sign up to request clarification or add additional context in comments.

4 Comments

tahnk you! could you please explain how it works and what it does? why are you only checking intone?
Hello, only now i had the chance to implement this.. but its not working.. i get the error message: Call to undefined method Illuminate\Contracts\Validation\Validator::extend()
ok, i fixed previous error by changing the use path. But the rule does not work. It properly returns false, but does not fail validation.
Found the problem.. Data contains a "_token" too.. that is never null...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.