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

Null or shape? #10

Closed
Enchiridion opened this issue Nov 17, 2021 · 5 comments
Closed

Null or shape? #10

Enchiridion opened this issue Nov 17, 2021 · 5 comments

Comments

@Enchiridion
Copy link

First, great library!

Is it possible to specify that a value can be NULL or an array with a particular shape?

In this example, roadInfo can be either NULL or the shape shown below.

'roadInfo'  => array(
  'id'    => ':string',
  'type'  => ':string',
  'title' => ':string',
  'data?' => array(
    '*' => array(
      'language' => ':string',
      'data'     => ':string',
    ),
  ),
),
@lezhnev74
Copy link
Owner

Hey @Enchiridion , yeah good point.
There is a way to say that a value can be nullable with a pattern like this :array?, however it does not let you specify the array pattern. Another thought is a new key modifier (along with ?, * etc) that means key value can be nullable. Hm... Definitely a missing feature but there are more than one way to add it, need to think about it.

@Enchiridion
Copy link
Author

I'm working with an new API and just came across another issue. Some pieces of data may be multiple types, for example it can be either not present, null, false, or an array with a specific shape (the API isn't the greatest). Maybe these complex cases could be handled by a specifying a function? Then I can implement the custom logic needed and also utilize the library where possible. I think only a new rule would be needed and none of the modifiers need to be touched.

@lezhnev74
Copy link
Owner

I think you can have a new rule with your custom logic right now. Try this:

  • create a new class (take this one as example RuleArray). Maybe even extend that one.
  • that new class is not known to the package by default, so you need to extend RuleLocator as well
  • when you create a new validator instance, provide that rule locator.

See this example for more: Example/customRule.php

@Enchiridion
Copy link
Author

Thanks! I was able to use that to create a custom rule that's working great. Now that I've dug into the code more, I realized that the detailed error messages aren't being passed on, which would of been really helpful earlier when I was building the rules.

For example:

try {
  $pattern = array( 'name' => ':number' );
  $content = array( 'name' => 'foo' );
  $builder = \PASVL\Validation\ValidatorBuilder::forArray( $pattern );
  $builder->build()->validate( $content );
} catch ( \Throwable $e ) {
  echo $e->getMessage();
}

The Exception's message should be the value is not a number but it's actually Data value [foo] matched no pattern at root level. Is this a bug?

@lezhnev74
Copy link
Owner

lezhnev74 commented Dec 7, 2021

Good question, I remember that error messages were not that simple. To put it shortly it only can tell you that patterns did not match, but it can't tell you what exact pattern did not match.

That is because keys are specified as patterns in general, exact key is just a special case. So the system does not know what pattern was meant for the value.

So here is an example:

$data = [
    "ab" => "",
    "abc" => "",
];
$pattern = [
    ":string :between(1,3)" => "",
    ":string :between(2,4)" => "",
];

Both data items match both key patterns. The system just applies different combination of patterns to the data and stops whenever there is a match. Otherwise it halts with a message like the one you posted.

p.s. I get your confusion and I had the same question in the past, but I am yet to come to a general solution that allows to specify keys as patterns as well as gives better messages.

p.p.s. Hence the regular expressions function preg_match it returns bool result, it does not tell you what part of the expression failed, hm?

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

No branches or pull requests

2 participants