Validation icon indicating copy to clipboard operation
Validation copied to clipboard

Roadmap to 3.0

Open henriquemoody opened this issue 1 year ago • 12 comments

To-dos

I'm almost there, and there are some awesome improvements coming!

Core

  • [ ] Improve array messages
  • [ ] Create Validator::validate() that returns an object with errors
  • [x] ? Rename Result->isValid to Result->hasPassed
  • [x] Create transformer to deal with composite rules with a single argument
  • [x] Make Simple::isValid public
  • [x] Use paths to identify when a rule fails
  • [x] Create {{placeholder|quote}}
  • [x] Create custom Stringifier, removing CallableStringifier
  • [x] Replace setName() with Named rule
  • [x] Get ignored paths for ValidationException from ValidatorDefaults
  • [x] Replace setTemplate() with Templated rule
  • [x] ~~Create class alias for old abstract classes~~
  • [x] Rename mode "negative" to "inverted"
  • [x] Add second parameter to Validator::assert()
  • [x] Create "key" prefix
  • [x] Create "length" prefix
  • [x] Create "max" prefix
  • [x] Create "min" prefix
  • [x] Create "nullOr" prefix
  • [x] Create "property" prefix
  • [x] Create "undefOr" prefix
  • [x] Make ComponentException extend LogicException
  • [x] Make getMessages() return __self__
  • [x] Make setName() update names, but not IDs
  • [x] Prefix ids when working with sibling results
  • [x] Update validation engine (todo: split into different tasks)
  • [x] Use PHP Attributes to define templates

Rules

  • [ ] Create Masked rule -- which allows masking the input
  • [ ] Promote Reducer to an actual rule
  • [ ] Enable Attributes to deal with inheritance
  • [x] Allow to use certain rules as class attributes
  • [x] Rename "Consecutive" to something shorter
  • [x] Only create Max with subsequents when possible
  • [x] Only create Min with subsequents when possible
  • [x] Only create Length with subsequents when possible
  • [x] Add support to PHP 8.4
  • [x] Update DateTimeDiff to generate results with subsequents
  • [x] Tentatively created a result with subsequents in UndefOr and NullOr
  • [x] Refactor KeySet rule
  • [x] Create DateDiff rule
  • [x] Delete MinAge, MaxAge, and Age rules
  • [x] Rename NotOptional to NotUndef
  • [x] Create BetweenExclusive rule
  • [x] Create Consecutive rule
  • [x] Create LazySequence rule
  • [x] Create a new Max rule
  • [x] Create a new Min rule
  • [x] Create aliases for deprecated/removed rules
  • [x] Delete KeyValue rule
  • [x] Do not use When as a sibling
  • [x] Refactor Length rule
  • [x] Rename Nullable to NullOr
  • [x] Rename Optional to UndefOr
  • [x] Rename Max rule to LessThanOrEqual
  • [x] Rename Min rule to GreaterThanOrEqual
  • [x] Rename the "Attribute" rule to "Property"
  • [x] Split the Key rule into Key, KeyExists, and KeyOptional
  • [x] Split the Property rule into Property, PropertyExists, and PropertyOptional

Other

  • [ ] Make documentation up to date with the changes
  • [ ] Write a blog post with the latest changes
  • [ ] Improve documentation for rules that are prefixes
  • [x] Release version 2.4 with deprecations
  • [x] Fix broken documentation links
  • [x] Rename branch master to main

Nice to have

- [ ] More integration tests for `oneOf`, `allOf` and `each` validator messages.
- [ ] Create `All` rule (similar to `Each` but creates results with subsequents)
- [ ] Create `DateTimeParseable` or (`DateTimeLenient`) rule
- [ ] Increase code coverage to 98%
- [ ] Share credentials for @TheRespectPanda with @alganet
- [ ] Extra documentation for most common support issues
  - [ ] Message translation approaches
  - [ ] Navigating the messages tree manually
  - [ ] Using validators with custom names 
  - [ ] Expressing boolean algebra

Update validation engine

Here are some "problems" I see with the current engine

  • Allowing each rule to execute assert() and check() means duplication in some cases.
  • Because we use exceptions to assert/check, we can only invert a validation (with Not) if there are errors. That means that we have limited granularity control.
  • There is a lot of logic in the exceptions. That means that even after an exception is thrown, something could still happen. We're stable on that front, but I want to simplify them. Besides, debugging exception code is painful because the stack track stops once the exception constructor is created.

On version 3.0, this won't be possible anymore:

$email = new Email():
$email->assert($input);

Instead, you would need to do that:

$validator = new Validator(new Email());
$validator->assert($input);

However, because assert() will be available only on Validator, you could do things like that:

// Passing the template as a string
v::email()->assert($input, 'Uff... {{input}} should have been an email');

// Passing an array of templates
v::intValue()->positive()->lessThan(5)->assert($input, [
    'intValue' => 'Area must be an integer',
    'positive' => 'Area must be a positive number',
    'lessThan' => 'Area cannot be bigger than m2',
]);

// Passing a custom exception
v::email()->assert($input, new DomainException('Customers must have valid emails'));

// Passing a custom callable
v::email()->assert($input, fn($exception) => new DomainException('Something failed: ' . $exception->getMessage());

henriquemoody avatar Feb 09 '24 08:02 henriquemoody

Hello, guys. When will you continue working on release 3.0?

dmitriiPopov avatar Nov 06 '24 15:11 dmitriiPopov

Are there any of these unfinished items you've listed that would be good for a new contributor to handle? We're using this library, and this 3.0 release looks like it will fix some of the issues we've had with it, so I could probably put some time toward a few issues to help get the release out.

dmjohnsson23 avatar Nov 25 '24 19:11 dmjohnsson23

I'm sorry for be belated response, peeps!

@dmitriiPopov, I've been working a lot in the last couple of weeks. I'm hoping to release version 3.0 at the beginning of next year. I think it's looking great so far, check this out: https://github.com/Respect/Validation/blob/main/docs/02-feature-guide.md

@dmjohnsson23, at the moment it's a bit tricky, because I'm at a phase that I'm myself figuring out how I really want things to work. I got most of the groundwork done, but I'm still seeing how I really want a few rules to work out. Thank you for offering help, though!

🐼

henriquemoody avatar Dec 13 '24 11:12 henriquemoody

@dmjohnsson23, if you (or anyone) could do what I did for Length in https://github.com/Respect/Validation/pull/1485 but for Each, Min, and/or Max, that would be very helpful. I've been coding intensely in the past month, I'm gonna take a break until next year, but I will probably be able to review merge requests.

henriquemoody avatar Dec 16 '24 21:12 henriquemoody

I'd be happy to give it a go. I looked at the referenced commit and I don't fully understand what all the changes are doing at this point, so I'll need to spend some time figuring out the code. I don't just want to copy/paste the same changes without fully understanding the intent. Any pointers would be welcome.

dmjohnsson23 avatar Dec 18 '24 23:12 dmjohnsson23

Replace setTemplate() with Templated rule

I'm doing a lot of stuff like this:

->allOf(v::attribute(v::stringType()->length(1, 19)->digit()->intVal())->setTemplate('This should have been valid...'))
->allOf(v::attribute(v::boolType())->setTemplate('This also should have been valid...'))

Will this still be valid in 3.0?

andus4n avatar Jan 07 '25 01:01 andus4n

@andus4n, the setTemplate() method will still be present in the Validator class, just not in every rule object/class. You don't have to worry much about it if you're just calling it from the Validator.

However, a few things will need to be replaced in your code:

  1. AllOf will require at least 2 rules (ref)
  2. Attribute will be called Property -- assuming you forgot to type the property name there (ref)
  3. Length will change a bit (ref) and you'll be able to use it as a prefix.

There will be some mechanisms in place that should allow you to run your code if you suppress deprecations.

However, even on the current versions, I think your chain could be simpler. I'm not sure why you're calling setTemplate() on the chain of the attribute rule instead of calling it in the chain of rule you're passing to attribute, could you elaborate?

I think that on version 2.3 (or 2.4), you chain could look like this:

->attribute('foo', v::stringType()->length(1, 19)->digit()->intVal()->setTemplate('This should have been valid...'))
->attribute('bar', v::boolType()->setTemplate('This also should have been valid...'))

In version 3.0, it will look like pretty much the same (just changing attribute -> property and length -> lengthBetween) not to get E_USER_DEPRECATED errors because of the renamed rules.

->property('foo', v::stringType()->lengthBetween(1, 19)->digit()->intVal()->setTemplate('This should have been valid...'))
->property('bar', v::boolType()->setTemplate('This also should have been valid...'))

But, it could be more clear on version 3.0 with the Templated rule, because it's more explicit (IMO)

->property('foo', v::templated(v::stringType()->lengthBetween(1, 19)->digit()->intVal(), 'This should have been valid...'))
->property('bar', v::templated(v::boolType(), 'This also should have been valid...'))

henriquemoody avatar Jan 07 '25 01:01 henriquemoody

Thank you for the response. I'm still using v2.2.4.

AllOf will require at least 2 rules

So basically, if i have a chain like v::stringType()->lengthBetween(1, 19) inside allOf it'll still be seen as a single rule? In other words, v::allOf(v::stringType()->lengthBetween(1, 19)) will raise an error? I'm usin' a lot of chaining and if i'd wrap them inside allOf, this would allow me to use the setTemplate() method if anything fails.

To be more precise: v::allOf(v::stringType()->lengthBetween(1, 19))->setTemplate('Invalid.') - this'll actually give me an exception with my custom message. v::stringType()->lengthBetween(1, 19)->setTemplate('Invalid') - this'll generate an internal exception message, ignoring my custom template. Is this fixed in version 2.3 / 2.4?

Attribute will be called Property -- assuming you forgot to type the property name there Length will change a bit and you'll be able to use it as a prefix

This won't be a problem. At this point i think that my best bet is to rewrite my rules in order to be able to properly use v3.0.

As a side-note, will version 2.2.4 work on PHP 8.4? I think a lot of developers are still using this version.

andus4n avatar Jan 07 '25 08:01 andus4n

So basically, if i have a chain like v::stringType()->lengthBetween(1, 19) inside allOf it'll still be seen as a single rule? In other words, v::allOf(v::stringType()->lengthBetween(1, 19)) will raise an error?

By error, I mean that it won't work, because allOf will require at least two rules, while v::stringType()->lengthBetween(1, 19) is, for allOf, a single Validator rule.

I'm usin' a lot of chaining and if i'd wrap them inside allOf, this would allow me to use the setTemplate() method if anything fails.

Oh, I got it. So you're using allOf as a way to contain chains, so you can template them as a single unit. It's not the way it was intended to, but that's a smart way of using it! That would be exactly the purpose of Templated rule in version 3.0, though.

As a side-note, will version 2.2.4 work on PHP 8.4? I think a lot of developers are still using this version.

I think so! Apart form the sf rule, all tests are passing.

henriquemoody avatar Jan 07 '25 09:01 henriquemoody

I think so! Apart form the sf rule, all tests are passing.

That sounds really well. What does sf mean, tho'? xD

andus4n avatar Jan 07 '25 13:01 andus4n

No worries, it's been removed anyways: https://respect-validation.readthedocs.io/en/2.2/rules/Sf/

henriquemoody avatar Jan 07 '25 13:01 henriquemoody

Hi! I opened a PR to rename the Result->isValid, I would like to know the reason of renaming, even though, I opened. Please let me know if this change is needed.

https://github.com/Respect/Validation/pull/1535

faabiosr avatar Mar 31 '25 10:03 faabiosr