fab2s / laravel-dt0

Laravel support for fab2s/dt0, a DTO implementation that can both secure mutability and implement convenient ways to take control over input and output in various formats.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Laravel Dt0

CI QA codecov Latest Stable Version PRs Welcome License

Laravel support for fab2s/dt0, a DTO (Data-Transfer-Object) PHP implementation that can both secure mutability and implement convenient ways to take control over input and output in various formats.

Installation

Dt0 can be installed using composer:

composer require "fab2s/laravel-dt0"

Usage

Laravel Dt0 only adds Validation implementation and model attribute casting to Dt0. All other features will work exactly the same. Have a look at Dt0 to find out more.

Caster

In addition to Dt0 casters, Laravel Dt0 adds a CollectionOfCaster which can be used to strongly type a Laravel Collection:

    #[Cast(in: new CollectionOfCaster(MyDt0::class))] // Dt0|UnitEnum|ScalarType|string
    public readonly Collection $prop;

It can be used as an inspiration to cast into more types.

Validation

Laravel Dt0 is able to leverage the full power of Laravel validation on each of its public properties. The validation is performed on the input data prior to any property casting or instantiation.

Laravel Dt0 comes with a Validator out of the box that can leverage the full power of laravel validation.

To use it on any Dt0, just add the Validate class attribute :

#[Validate(Validator::class)] // same as #[Validate(new Validator)]
class MyDt0 extends Dt0 {
    // ...
}

Rules can be added in three ways:

  • using the second argument of the Validate class attribute:

    use fab2s\Dt0\Attribute\Rule;
    use fab2s\Dt0\Attribute\Rules;
    use fab2s\Dt0\Attribute\Validate;
    use fab2s\Dt0\Laravel\Dt0;
    use fab2s\Dt0\Laravel\Validator;
    
    #[Validate(
        Validator::class,
        new Rules(
            propName: new Rule('string|size:2'),
            // ...
        ),
    )]
    class MyDt0 extends Dt0 {
        public readonly string $propName;
    }
  • using the Rules class attribute:

    use fab2s\Dt0\Attribute\Rule;
    use fab2s\Dt0\Attribute\Rules;
    use fab2s\Dt0\Attribute\Validate;
    use fab2s\Dt0\Laravel\Dt0;
    use fab2s\Dt0\Laravel\Validator;
    
    #[Validate(Validator::class)]
    #[Rules(
        propName: new Rule(['required', 'string', 'size:2']),
        // ...
    )]
    class MyDt0 extends Dt0 {
        public readonly string $propName;
    }
  • using the Rule property attribute:

    use fab2s\Dt0\Attribute\Rule;
    use fab2s\Dt0\Attribute\Rules;
    use fab2s\Dt0\Attribute\Validate;
    use fab2s\Dt0\Laravel\Dt0;
    use fab2s\Dt0\Laravel\Validator;
    use fab2s\Dt0\Laravel\Tests\Artifacts\Rules\Lowercase;
    
    #[Validate(Validator::class)]
    class MyDt0 extends Dt0 {
        #[Rule(new Lowercase)] // or any custom rule instance
        public readonly string $propName;
    }

Combo of the above three are permitted as illustrated in ValidatableDt0.

In case of redundancy, priority will be first in Validate, Rules then Rule. Dt0 has no opinion of the method used to define rules. They will all perform the same as they are compiled once per process and kept ready for any reuse.

Validation is performed using withValidation method:

// either get a Dt0 instance or a ValidationException
$dt0 = SomeValidatableDt0::withValidation(...Request::all());

Model Attribute casting

Should you want to use a Dt0 as a Laravel Model attribute, you can directly cast it as your Dt0 thanks to the generic cast Dt0Cast.

Only requirement is for your Dt0 to extend fab2s\Dt0\Laravel\Dt0 or to extend fab2s\Dt0\Dt0 and use fab2s\Dt0\Laravel\LaravelDt0Trait.

use Illuminate\Database\Eloquent\Model;

class SomeModel extends Model
{
    protected $casts = [
        'some_dt0'          => SomeDt0::class,
        'some_nullable_dt0' => SomeNullableDt0::class.':nullable',
    ];
}

$model = new SomeModel;

$model->some_dt0 = '{"field":"value"}';
// or 
$model->some_dt0 = ['field' => 'value'];
// or 
$model->some_dt0 = SomeDt0::from(['field' => 'value']);

// then
$model->some_dt0->equals(SomeDt0::from('{"field":"value"}')); // true

$model->some_dt0 = null; // throws a NotNullableException
$model->some_nullable_dt0 = null; // works

// can thus be tried
$model->some_nullable_dt0 = SomeNullableDt0::tryFrom($anyInput);

Requirements

Dt0 is tested against php 8.1 and 8.2 and Laravel 10 / 11

Contributing

Contributions are welcome, do not hesitate to open issues and submit pull requests.

License

Dt0 is open-sourced software licensed under the MIT license.

About

Laravel support for fab2s/dt0, a DTO implementation that can both secure mutability and implement convenient ways to take control over input and output in various formats.

License:MIT License


Languages

Language:PHP 100.0%