The Masked validator was a proxy for what the new Formatted validator
already does, so it is being removed to reduce redundancy. All tests and
documentation have been updated accordingly.
Assisted-by: OpenCode (ollama-cloud/glm-4.7)
The Formatted validator decorates another validator to transform how
input values appear in error messages, while still validating the
original unmodified input.
This is useful for improving the readability of error messages by
displaying values in a user-friendly formatd.
The validator accepts any Respect\StringFormatter\Formatter implementation,
allowing direct use of StringFormatter's fluent builder. As StringFormatter
expands with more formatters in future releases, users will automatically
benefit from the full range of formatting options.
Assisted-by: Claude Code (Opus 4.5)
Rename the Composite class to LogicalComposite to more accurately reflect
its purpose as a validator that combines child validators using logical
operations (AND, OR, NAND, XOR).
This better naming also opens the door for additional composite patterns
beyond logical operations, enabling future validator compositions.
Assisted-by: OpenCode (GLM 4.5)
This commit introduces a mechanism for validators to return early once
the validation outcome is determined, rather than evaluating all child
validators.
The ShortCircuit validator evaluates validators sequentially and stops
at the first failure, similar to how PHP's && operator works. This is
useful when later validators depend on earlier ones passing, or when
you want only the first error message.
The ShortCircuitCapable interface allows composite validators (AllOf,
AnyOf, OneOf, NoneOf, Each, All) to implement their own short-circuit
logic.
Why "ShortCircuit" instead of "FailFast":
The name "FailFast" was initially considered but proved misleading.
While AllOf stops on failure (fail fast), AnyOf stops on success
(succeed fast), and OneOf stops on the second success. The common
behavior is not about failing quickly, but about returning as soon as
the outcome is determined—which is exactly what short-circuit
evaluation means. This terminology is familiar to developers from
boolean operators (&& and ||), making the behavior immediately
understandable.
Co-authored-by: Alexandre Gomes Gaigalas <alganet@gmail.com>
Assisted-by: Claude Code (Opus 4.5)
I ran the `bin/console spdx --fix` with different strategies for
different files. For most of the core classes, since they've been
drastically rebuilt, I've run it with the `git-blame` strategy, for for
the `src/Validators`, in which the API changed completely but the logic
remains the same, I use the `git-log` strategy.
The previous name was confusing as it focused on the implementation
detail (calling a callable) rather than what the validator actually
does. The new name "After" better conveys the validator's purpose:
validating the input after applying a transformation.
Assisted-by: Claude Code (Opus 4.5)
The previous name was confusing as it focused on the implementation
detail (receiving a callback) rather than what the validator actually
does. The new name "Satisfies" better conveys the validator's purpose:
checking whether the input satisfies a given condition.
Assisted-by: Claude Code (Opus 4.5)
The name "Factory" better conveys the validator's purpose: dynamically
creating a validator at runtime based on the input value. "Lazy" was
misleading as it suggested simple deferred evaluation rather than
input-dependent validator construction.
Also renamed the constructor argument from `$validatorCreator` to
`$factory` for improved expressiveness.
Assisted-by: Claude Code (Opus 4.5)
- Changed Property so it doesn't have an unreachable line anymore.
- Rename ValidatorTest to ValidatorBuilderTest to better reflect
the source.
- Added missing tests for KeyExists's ArrayAccess support.
- Added tests for using custom exceptions.
With PHP's promoted properties, there is little reason to have an
abstract class that only provides a constructor and a proxy method.
The greater part of the classes that extended Wrapper had their own
implementation of evaluate(), hence it made very little sense to keep
Wrapper in the codebase.
Assisted-by: Claude Code (Opus 4.5)
Now empty values are again allowed in FilteredArray-style
validators.
To solve the issue with negation, a Result attribute was
added to signal indeciseveness (when a result cannot be
reliably inverted). On such cases, we consider that result
to be valid.
For example, `v::not(v::min(v::equals(10)))` says "The
lowest value of the iterable input should not be equal 10".
If the input is empty, we cannot decide whether its minimum
is equal to 10 or not, so the validator essentially becomes
a null-op.
Users that want to ensure these validators have a valid
decidable target must use it in combination with `Length`
or other similar validators to achieve the same result.
The Masked validator decorates other validators to mask sensitive input
values in error messages while still validating the original unmasked
data.
This validator is essential for applications handling sensitive
information such as passwords, credit cards, or email addresses. Without
it, users would need to implement a custom layer between Validation and
the end user to prevent PII from appearing in error messages or logs.
With Masked, sensitive data protection is built directly into the
validation workflow with no additional abstraction required.
Assisted-by: Claude Code (Opus 4.5)
This commit removes validators described in #1642, refactoring
to clean up after their removal.
- Url was refactored to use the function `filter_var` instead.
- tests/bootstrap.php is no longer needed and was removed.
- Updated migration guide with recommendations for replacements.
We've always considered renaming this directory, as it's not a common
standard to name `library` the directory where the source code of a
library it. Having it as `src/` is a common pattern we find in several
PHP libraries these days.
Acked-by: Alexandre Gomes Gaigalas <alganet@gmail.com>