We want to release version 3.0 as fresh as possible, without having to
maintain backward compatibility with the previous versions. Because that
version will be on for some time, we decided it will be best to support
only PHP version 8.5 or higher.
Acked-by: Alexandre Gomes Gaigalas <alganet@gmail.com>
We want to release version 3.0 as fresh as possible, without having to
maintain backward compatibility with the previous versions.
Acked-by: Alexandre Gomes Gaigalas <alganet@gmail.com>
There are a few cases in which we want to validate the object as a
whole, and that validation could be attached to the class as a PHP
attribute. This commit enables that capability and changes a few rules
to be class attributes.
Because of how the validation engine works now [1], there's no reason to
keep adding names to each rule. Instead, create a single rule that
handles naming rules with a few other accessories. This change is not
necessarily simple, but it shrinks the `Rule` interface, and it's more
aligned with how the library works right now.
Personally, I think this API is much more straightforward than the
`setName()` method, as it's way more explicit about which rule we're
naming. Because of this change, the behaviour changed slightly, but it's
for the best.
Because of this change, I managed to remove a lot of code, but
unfortunately, it's quite a big-bang commit. It would be too complicated
to make it atomic since names are an intrinsic part of the library.
[1]: 238f2d506a
Because of how the validation engine works, there's no reason to keep
adding templates to each rule. Instead, creating a single rule that
handles templating rules will simplify the library greatly and shrink
the `Rule` interface.
Personally, I think this API is much more straightforward than the
`setTemplate()` method, as it's way more explicit which rule is being
templated.
With this change, any rule can be used as a PHP attribute. I have wanted
to implement this feature for a while, as it allows you to bind the
validation to a specific property and just validate the object
afterwards.
There are several cases in which we need to bind the name and template
of a rule to another. We need to do that because results need
information from rules to be created, and because results come from
rules, in some cases, it's not ideal (or possible) to change the
information after the result is created.
Besides the interface's name, everything already calls this type "Rule",
not "Validatable." This commit puts a stone on it and renames the
interface for better naming.
When creating a result with a sibling in the When rule, the result
generates an unhelpful message. In most of the use cases of the When
rule, the initial rule ("when") is only helpful in determining which
will be the "real" rule to use.
Those changes will change the When rule not to generate results with
siblings.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
That helps organize the code better, making it easier to spot the core
rule. It also helps not allow the Factory to load those rules, as the
new namespace is not registered in it.
Note that the "AbstractAge", "AbstractRelated", and "AbstractRule" were
not moved. I want to do that only when I refactor them.
After I moved classes, I realized that "Comparison" and "FilteredString"
had no tests. I created the tests, and while I did that, I spotted two
bugs:
* The "Equals" rule was failing when comparing non-scalar wth scalar
values;
* The "Equals" and "Identical" rules were not working correctly because
"Comparison" was converting their values.
I fixed those bugs in this commit.
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>
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>
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>
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>
According to the official documentation [1] the correct way of writing
the "inheritDoc" tag is with the uppercase "D".
[1]: https://docs.phpdoc.org/guides/inheritance.html
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit will make sure that every class, interface, or trait will
have the "@author" annotation in it.
In order to create a list of authors, I used the "git blame" command,
which means that if someone changed or even created the file but does
not have any remaining line will not be shown in the list; it's a
trade-off worth but it is worth it. The other way to do it would be
carefully checking each file.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>