v2.0.0
This major release introduces a complete rewrite of the package, moving from an inheritance-based handler model to a modern, attribute-based DTO architecture.
Features
- Attribute-based DTOs: Define request structures using
#[Field]attributes on typed properties - Type-Safe Properties: Full IDE autocomplete and static analysis support with strict typing
- Automatic Type Casting: Built-in support for
int,float,bool,string,array, andDateTime/DateTimeImmutable - Custom Generators: Auto-generate field values (UUIDs, IDs, etc.) via
generatorparameter with custom options - Route Parameter Placeholders: Use
{placeholder}syntax in validation rules with$routeParamsinjection - Field Grouping: Organize fields into logical groups with
groupparameter and extract viagroup()method - Nested Mapping: Map deeply nested input data to flat properties via
mapFromwith dot notation - Processing Pipeline: Support for
preProcessandpostProcesshooks (functions, classes, or static methods) - Auto Trim: Automatic whitespace trimming for string inputs (configurable)
- Custom Messages: Override validation error messages via
messages()method - Configuration Validation: Early detection of invalid configurations via
ConfigurationException - Reflection Caching: Optimized performance with cached metadata
- Exclude Fields: Exclude fields from
toArray()output withexclude: true
Breaking Changes
- Removed
AbstractRequestHandler— request classes now extendRequestbase class - Removed
Field::for()fluent builder — use#[Field]attribute instead - Removed
authorize(),transform()methods from request classes - Removed
ParameterParserhelper class - New
RequestHandlerservice handles request processing handle()returns typed DTO object instead of array- All interfaces moved to
Contracts/namespace - Requires PHP 8.2+
Improvements
- Full static analysis compliance (PHPStan Level 8)
- 100% test coverage
- PSR-12 coding standard compliance
- Custom casters via
CasterInterface - Custom processors via
ProcessorInterface - Custom generators via
GeneratorInterface - All interfaces consolidated in
Contracts/namespace
Migration
// Before (v1.x)
Field::for('name')->validate('required|string')->preprocess('trim')
// After (v2.0)
#[Field(rules: 'required|string', preProcess: 'trim')]
public string $name;