Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional Validation: More then "when" #1348

Closed
tchari opened this issue Mar 10, 2021 · 2 comments
Closed

Conditional Validation: More then "when" #1348

tchari opened this issue Mar 10, 2021 · 2 comments
Labels

Comments

@tchari
Copy link

tchari commented Mar 10, 2021

When is a great rule for a binary case. Is there a rule or way to do conditional validation if the conditional key value can have more than two outcomes?
e.g.

    $cars = [
      ['manufacturer' => 'Honda', 'model' => 'Accord'],
      ['manufacturer' => 'Toyota', 'model' => 'Rav4'],
      ['manufacturer' => 'Ford', 'model' => 'notarealcar']
    ];
    Validator::arrayType()->each(
      Validator::key('manufacturer', Validator::in(['Honda', 'Toyota', 'Ford']))
      ->when(
        Validator::key('manufacturer', Validator::equals('Honda')),
        Validator::key('model', Validator::in(['Accord', 'Fit'])),
        Validator::when(
          Validator::key('manufacturer', Validator::equals('Toyota')),
          Validator::key('model', Validator::in(['Rav4', 'Camry'])),
          Validator::key('model', Validator::in(['F150', 'Bronco']))
        )
      )
    )->assert($cars);

This code works, but chaining 'when' gets a little cumbersome after a few 'manufacturers'. Is there some kind of switch-like rule?

@alganet
Copy link
Member

alganet commented Feb 20, 2023

The oneOf and allOf are the perfect conditional validators for this. You can use:

$cars = [
    ['manufacturer' => 'Honda', 'model' => 'Accord'],
    ['manufacturer' => 'Toyota', 'model' => 'Rav4'],
    ['manufacturer' => 'Ford', 'model' => 'notarealcar'],
    ['manufacturer' => 'Honda', 'model' => 'not valid'],
];

try {
    Validator::arrayType()->each(
        Validator::oneOf(
            Validator::key('manufacturer', Validator::equals('Honda'))
                ->key('model', Validator::in(['Accord', 'Fit'])),
            Validator::key('manufacturer', Validator::equals('Toyota'))
                ->key('model', Validator::in(['Rav4', 'Camry'])),
            Validator::key('manufacturer', Validator::equals('Ford'))
                ->key('model', Validator::in(['F150', 'Bronco']))
        )
    )->assert($cars);
} catch (NestedValidationException $e) {
    var_dump($e->getMessages());
}

This behaves like an if...elseif block, or a set of OR conditions.

While testing this, I noticed that my recent changes to Each were broken for this example. It should, however, work for 2.2 (except for the reporting problems) and now it is fixed on 2.3 as well (with detailed messages).

@alganet
Copy link
Member

alganet commented Feb 20, 2023

I'm closing this because it was supported before. There is an improvement related to it, but it is about the message reporting in Each and not the structuring of the oneOf itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants