Currently, the only way to handle when a validation fails is by
`assert()`, which either throws an exception or doesn't. That means that
every time a user wants to handle the results, they must use try-catch
blocks, which may add some overhead.
This commit introduces the `ResultQuery` class that wraps a `Result`
object, providing an alternative to exception-based validation. This
allows users to handle results directly without try-catch blocks.
I’m taking a risky move here using the old method `validate()`, but I
can’t think of a better name for this method.
I've already changed the `ValidationException` so as not to let the file
and line from the Validator.php [1]. However, one could go even further
when creating more customizations on top of this library, and allowing
to customize the line could be very useful.
What motivated me making this change because it will be handy when I get
back to work on [Assertion][].
[1]: 75a9b8e94f
[Assertion]: https://github.com/Respect/Assertion
Because of how PHP works, when we instantiate an Exception object, the
`file` and `line` properties are the file and line where we created the
object. That's a desirable behaviour, but there's no value for a user to
know that we created an instance of `ValidationException` in the
`Validator` class.
This commit will overwrite the file and line in the
`ValidationException` to where the method `assert()` was called.
Note that when running `check()` it will still point to `Validator`, but
I decided not to change it, as the method `check()` got deprecated.
This commit will ensure that all rules that cannot be created because of
invalid arguments in the constructor will throw the
InvalidRuleConstructorException. It will also make ComponentException
extend LogicException, which makes it easier to determine that the
client has improperly used the library.
I also introduced some tests for two exceptions with logic in their
constructor.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
After many refactorings, no rules use the previous validation engine.
That means we can remove the unused code from the repository and switch
from the previous to the new validation engine everywhere.
This commit will also soft deprecate the methods "validate()", and
"check()" in all the rules and the "assert()" in all rules but the
Validator itself. That means using those methods will still be allowed,
but static analysis tools might complain.
This is a big step toward releasing the next major version, as the code
is pretty much the way it should be when I release the next version.
There's some documentation to be updated, and I would like to change the
behavior of a couple of rules.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Because we've changed the validation engine, those classes are not
necessary anymore. This is a major step for the new validation engine.
The NestedValidationException was one of the most important classes of
the project, the one that formatted nested messages -- and it was also
one of the buggiest and most complicated ones. With the new validation
engine, it became obsolete.
These changes are a significant step toward refactoring the whole
codebase. The changes in the Factory are there to ensure it doesn't
break for the time being.
Thank you NestedValidationException; you did an excellent job for a long
time. I can't say I will miss you, but seeing you go is weird.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
There are a few "problems" 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
it throws an exception, 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 trace does not go beyond the
exception.
Apart from that, there are many limitations with templating, and working
that out in the current implementation makes it much harder.
These changes will improve the library in many aspects, but they will
also change the behavior and break backward compatibility. However,
that's a price I'm willing to pay for the improvements we'll have.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
With this convention, it's much simpler to identify whether an exception
has a custom template or if that template came from the rule itself.
This commit is a preparation for further changes.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
In some cases, a user would like to show the parameter just as it is,
and in other cases, they need to translate a specific parameter. This
change creates that capability by adding a template-style modifier to a
parameter in the template.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Keeping the list of ISO 3166-2 up-to-date requires some maintenance. At
the same time, PHP ISO Codes maintains an up-to-date database with even
more ISO codes we could use in this library.
This change doesn't fully use all resources of PHP ISO Codes, but it
already removes some unnecessary code from the repository.
We've already used this library, but it was heavy because it included
all the localizations in it. Now, the package is much smaller (5.0M).
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Creating a specific exception for each rule adds a painful overhead. If
you want to make a custom message for your rule, you will need to create
an exception and then register that exception namespace to be able to
use it—all that is just for customizing the message of your rule.
Having different namespaces also implies that you need to fetch the
exception of the rule from another directory to change it. As Uncle Bob
said, "Classes that change together belong together. Classes that are
not reused together should not be grouped."
This commit will drastically change this library, moving all the
templates from the exceptions to the rules. Consequently, the Factory
becomes much simpler, and the library gets a bit smaller, too.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
It's easier to identify the reason for choosing a specific message in
the rule than in the exception. The same goes for the key we use to
determine the templates.
This change will simplify the `ValidationException` because it will
already receive the template it needs to use. As a consequence, the
`Factory` also becomes more straightforward.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Because now we have the concept of attributes in PHP, the rule with the
name "Attribute" makes no sense because it doesn't validate attributes
but properties.
In the future, it might be possible that Validation will have a rule
called "Attribute" to validate PHP attributes.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
The class had too much complexity and some duplication on its children.
I started doing this because I'm refactoring the tests to upgrade
PHPUnit later, and then I made some improvements along the way.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
That will make it clear that we should not overwrite some properties.
Because of this change, I've made a few refactorings here and there.
It's nice to see that I've spotted some issues just because I was
setting some properties as `readonly`.
There are a few properties that I would like to make read-only, but to
do that I'd need to refactor a lot of code, so for now, I'm keeping it
as is.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
We already have a method called "updateParams()" which has a better name
for what it does. Besides, we don't really need this for this case.
Personally, I find it ugly to create a property in the rule just to have
it available in the exception, but that's how the design is.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This change will bring many breaking changes. The good thing is that we
can finally use more modern resources available in PHP.
I can imagine that's not a popular change since it will bring many
breaking changes to users, but we shouldn't be stuck in time because of
that. Using some of those features will make it easier to contribute to
the project. At least, I hope so.
There are still some useless doc-blocks, and we're not using "readonly"
properties when we could. I aim to send those changes soon.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Most exception messages in Validation use "must" and "must not" in their
templates, but a few rules don't.
I fixed most of them, but AlwaysValid and AlwaysInvalid remain because I
wonder if they will be better if I update them.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Doing regex on phone numbers is not a great idea. This is a breaking
change, but a good one. Phone validation is now much stricter, and
allows choosing the country.
The use case for negating a keyset is very confusing, and can
lead to validators that don't do what they expect.
This commit introduces NonNegatable rules, which will throw
a Component exception if you try to wrap them in `Not`.
This change was necessary to ensure proper message reporting
when extra keys exist on the keyset.
This fixes#1349
Most Validation errors are sent to Users/Visitors or Clients and as such
might not need to know it was a Key their inputs are being validated
upon.
Co-authored-by: Henrique Moody <henriquemoody@gmail.com>
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Some amazing features had to be ignored because it conflicts with out
coring standards. I hope to soon fix them so we can use PHPStan to its
fullest potential.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
The method "current()" from NestedValidationException can return any
instance of ValidationException, but the implementation of
"getChildren()" requires it to return an instance of
"NestedValidationException".
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
There should not be too much code in the ValidationException. It is hard
to test and debug code in exceptions because PHP does not trace further
than their constructor.
This commit will move the message formatting from ValidationException
into a Formatter class (inside a Message namespace).
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
The only reason why those templates are static is so users can overwrite
the exception messages. That was useful when we didn't have a handy
translator, but now that we can define a translator through the Factory,
this is not needed anymore.
Besides, having those properties public adds complexity to the code.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
The only Identity Card we have is the Polish one, that said it makes
more sense to have a specific rule that only validates that, rather than
having a "IdentityCard" rule that only accepts one value.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
There are not other VATINs besides the one from Poland. That said, it
makes more sense to have a specific rule that only validates NIP.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit will rename the rule by removing the abbreviation to make it
a bit easier to understand what it does and much easier to find.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
The "SubdivisionCode" rule was refactored [1] and now it doesn't need
one rule per country.
This commit will also remove the exceptions that were supposed to be
removed before.
[1]: 718bacad04
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
There is no much benefit from having individual rules for each country's
subdivision, quite the opposite. It increases the amount of code and
makes it hard to change the implementation of these rules. Right now,
the only sane way to change those rules is with a customized script.
This commit will remove the Subdivision Code rules per country and
instead will put that information into JSON files.
We both wouldn't like to keep this in this library anymore, and we are
considering having another library to deal with this data [1], but since
it seems like it may take some time, looks better to do it temporarily
here.
[1]: https://github.com/sokil/php-isocodes/issues/12
Co-authored-by: Mazen Touati <mazen_touati@hotmail.com>
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>