The "NestedValidationException" has exceptions that are its children.
However, we call them "related". This commit updates the term over the
library.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
These two branches are very different, therefore merging is becoming
very hard.
I decided to not put these changes together with 5750952 because it
seems easy to track these changes with a specific commit.
While working on this merge I realized that would make more sense to
create "AbstractComparison" to handle the rules that compare values.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
The classes that are children of "AbstractInterval" convert their values
before comparing them.
Because PHP tries to convert values when making comparisons and an
"DateTime" object cannot be converted to integer or float some
validations would result into PHP triggering an error like:
> Object of class DateTime could not be converted to int
> Object of class DateTime could not be converted to float
This commit prevents that to happen by verifying if both compared values
are scalar or not before comparing them with each other.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
There is a log of magic in the "AbstractComposite" that allows an user
to add a rule in multiple ways, remove rules, verify if a rule is
inserted or not. Because of that the class has a lot of complexity and
for unnecessary reasons since we do not use these features internally.
The ideal would be to make this class immutable, however due to many
usages is not possible to do it now, but that is the plan for a near
future - hopefully.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
When a template is set for a chain of rules, does not really matter
which messages the chain can have, the only message to be used should be
the one based on the defined template.
This commit set the same template of a parent rule to its children's
exception. Our first thought was to set the template to its children
however that would mean that if another rule would be added to the chain
we would have to set it as well. Doing that to the children's exception
make sure we only do that once.
Co-authored-by: Henrique Moody <henriquemoody@gmail.com>
Use the same condition to not include child exception into the iterator
to also not show the message of the main exception when using
"getFullMessage()".
The method created to validate that condition should probably be in the
"ValidationException" itself, but this commit is meant to be a bug fix,
which will be released in a PATH version, and creating this public
method would imply that a MINOR version should be released.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
The commit 54d17ab tried to fix the that "IntVal" would pass with values
that are not considered as an integer, but it does not change
Even thought the commit 54d17ab fixes part of the wrong behaviour it
left out the filter for boolean values.
Co-authored-by: Henrique Moody <henriquemoody@gmail.com>
Also removed the possibility of validating keys once it's possible to
reach the same behavior by combining this rule with "Call" rule.
Co-authored-by: Henrique Moody <henriquemoody@gmail.com>
Values like "500.00" or 1.0 should not be considered as integer values
even though there is no data loss when they're converted to integer.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Also introduce "uopz" extension in order to create tests for "Uploaded"
rule.
Signed-off-by: Paul Karikari <paulkarikari1@gmail.com>
Co-authored-by: Henrique Moody <henriquemoody@gmail.com>
Also add integration test for Type rule.
Signed-off-by: Paul Karikari <paulkarikari1@gmail.com>
Co-Authored-By: Henrique Moody <henriquemoody@gmail.com>
Also check if input is scalar before validation.
Signed-off-by: Paul Karikari <paulkarikari1@gmail.com>
Co-Authored-By: Henrique Moody <henriquemoody@gmail.com>
The "AbstractSearcher" already does most of the job that "CountryCode"
was doing, so using it as parent class made more sense. That also makes
the validation case-sensitive which is not a problem since the standard
ISO 3166-1 in fact enforces an specific case for the country codes.
The documentation about the rule is also updated.
Co-Authored-By: Henrique Moody <henriquemoody@gmail.com>
Also change the constructor of the rule to accept charsets as arguments
instead of being either an array or a string.
Co-Authored-By: Henrique Moody <henriquemoody@gmail.com>
Since the rule "GreaterThan" was created, there is no reason to allow
"Min" to not be inclusive.
Also apply contribution guidelines to the rule.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This changes the rule name in order to be more descriptive and explicit
(avoid abbreviation). It also applies the new contribution guidelines.
Signed-off-by: Emmerson Siqueira <emmersonsiqueira@gmail.com>
Since the rule "LessThan" was created, there is no reason to allow "Max"
to not be inclusive.
Also apply contribution guidelines to the rule.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Generally speaking it makes more sense to have it always inclusive. Even
though the word "between" does not imply that it is inclusive or
exclusive it's more natural this way.
Besides, users can always use "GreaterThan" and "LessThan" rules in case
that is necessary.
Removing this boolean parameter reduces a bit of the complexity of the
rule.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Also add an extra validation to the rule, not allowing non-integers to
be considered as even numbers.
Co-Authored-By: Henrique Moody <henriquemoody@gmail.com>
This method change the behavior of "getMessages()" by changin the keys
of its return to the "id" of the specific exception that was triggered.
It also allows users to overwrite the templates by passing an array to
it.
This is being requested by many users for a long time. It took that long
because I was thinking too much about how to improve the old method
called "findMesssage()" that I didn't realize that it could be done in a
easier way with the "getMessages()".
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Make the ValidationException a little bit less mutable than before. All
its dependencies are now passed into the constructor.
This commit also make the Factory pass the translator to the exceptions
allowing to define the translator before the exception gets created.
This change is not the ideal one, later I would like to not need the
Singleton from the Factory to do that, but for now it seems like a good
approach.
One more thing that this commit does is to introduce the "id" for
Exceptions. Key can be either the defined "name" or the name of the rule
that throwed the exception. This method will be handy to identify
exceptions better.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
The "Between" rule is composed by two rules: "Min" and "Max". However it
has its specific exception and message. This commit makes it extend the
"AbstractEnvelop" class.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This abstract class is very similar to "AbstractWrapper" the difference
is that "AbstractWapper" will throw the exceptions of the rule that is
defined inside it, while "AbstractEnvelope" uses the exception of the
rule that extends it.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
Before this change every create rule must have an exception. This commit
allows to create rules without specific exceptions, so when the
exception of the rule is not found Validation uses ValidationException
instead.
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
The "Between" rule was extending the "AllOf" rule and adding "Max" and
"Min" rules to the chain. Because of that, when the rule failed we could
get the "MinException" or the "MaxException" exception, and only if both
failed that we would get the "BetweenException".
With this change it will always get the "BetweenException" which makes
it more explicit.
Also, the "Between" is not using the same standard required in the
Contribution Guidelines.
The "Age" rule was removed because it had too many responsibilities.
Instead "MaximumAge" was created (since there is already "MinimumAge").
This commit also introduces "AbstractAge" rule that is been used in both
mentioned rules.
This commit also makes some changes in how the `DateTime` rule behaves,
by not accepting `DateTimeInterface` as valid when a format is given.
Also:
- Create `DateTimeHelper` to eliminate some code duplication;
- Create integration tests for `DateTime` rule;
- Rename "format" placeholder to "sample" in the message;
- Update documentation of "DateTime" rule.
Refactor `AbstractSearcher` class and its children. Also most of the
unnecessary logic that was on `AbstractSearcher` was put back into `In`
class.
This commit also updates all "SubdivisionCode" rules.
The script used to create the classes can be found on:
https://gist.github.com/henriquemoody/ec404f994a87b18c7771
With this code the Factory class will be used also to create Exceptions.
In order to do that, the AbstractRule::reportError() was changed, so the
tests of the AbstractRule class.
What this commit also does:
- Port code to PHP 7;
- Do not keep the default instance of the Factory in the Validator
class;
- Make Factory final.
- Add documentation to the class and its methods;
- Move RuleTestCase to Test namespace;
- Use PHP 7 type hinting;
- Rename getRuleMock() to createValidatableMock().
Due to this change it was possible to identify that NotEmptyException,
and NotOptionalException where not working as they should. A fix was
made along with this commit.
When executing `ValidationException::setTemplate()` using a template
key, it does not try to select the template, but instead it uses the
template key as the template itself.
In order to fix this behaviour, there is now a check for a key with the
defined template. In case the template was not found, use the defined
template as the template itself.
And was that, without warning that the "malkusch/bav" package was
removed from Packagist. This commit removes it as dependency but do not
remove any class that uses it in case there is a user loading the
package from a VCS repository with Composer.
`NestedValidationException` should include all `AbstractRelated` rule
exceptions.
`AbstractRelated` rule failures always indicate an interesting nested
context, which should not be omitted from the final result.
`NonOmissibleExceptionInterface` is a marker interface for
exceptions thrown by instances of `AbstractRelated`, which
facilitates identification of those rules' exceptions with
`instanceof`.
Updates the CreditCard validator regex for the MasterCard brand to match 16-digit card numbers starting with 22 - 27. Additionally, updates the unit test for CreditCard with a published test card in the new BIN range.
Additional information on the BIN range update can be found at: https://www.mastercard.us/en-us/issuers/get-support/2-series-bin-expansion.html
If calling the method `getExceptionForPath()` when the exception was
nested but had no child it was returning null. This commit ensures that
it always return a valid exception.
Then using the `findMessages()` method, tries to use the method
`getRelatedByName()` before using the `findRelated()` method.
This change was made because since on `KeyNested` rule you may have
names with '.' we'll never get the proper exception using
`findRelated()`.
When you define the name for an `AbstractRelated` instance, you expect
that it also define the name for its child. But, when the child already
had a name the `AbstractRelated` was overwriting its name with the
`reference`.
Appending a prefix to search new rules under required that the namespace
(prefix) being added always ended with a trailing namespace character so
rules could successfully be found under it. This ensures that the
separator is always present.
Changes a test for a rule which does not implement Respect's interface
to an actual class so we don't need to declare one to use as a stub.
When there is just one rule in the chain and the there is a defined
template for that, the expected behaviour when using the `check()`
method is to see the exception message with the defined template.
The `DateTime::createFromFormat()` tries to guess the date too much and
sometimes wrong parsing may happen:
```php
echo DateTime::createFromFormat('Ym', '202309')->format('Ym');
```
The output of the above code is "202310", not "202309".
Using `date_parse_from_format()` we get a more precise parsing.