PHP code example of honeystone / laravel-dto-tools

1. Go to this page and download the library: Download honeystone/laravel-dto-tools library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

honeystone / laravel-dto-tools example snippets




declare(strict_types=1);

namespace App\Domains\Articles\Data;

use App\Domains\Articles\Data\Enums\Status;
use Honeystone\DtoTools\Concerns\HasTransferableData;
use Honeystone\DtoTools\Contracts\Transferable;

final readonly class ArticleData implements Transferable
{
    use HasTransferableData;

    public function __construct(
        public string $title,
        public ?string $description,
        public Status $status,
        public string $modified,
    ) {
    }
}

$data = ArticleData::make(
    title: $source['title'],
    description: $source['description'] === '' ? null : $source['description'],
    status: $source['status'] === 'published' ? Status::PUBLISHED : Status::DRAFT,
    modified: Carbon::make($source['modified'])->toIso8601String(),
);

use App\Domains\Articles\Data\Enums\Status;
use Honeystone\DtoTools\Casters\DateTimeCaster;
use Honeystone\DtoTools\Casters\EnumCaster;
use Honeystone\DtoTools\Casters\NullCaster;

final readonly class ArticleData implements Transferable
{
    use HasTransferableData;

    public function __construct(
        public string $title,

        #[NullCaster('')]
        public ?string $description,

        #[EnumCaster(Status::class)]
        public Status $status,

        #[DateTimeCaster]
        public string $modified,
    ) {
    }
}

$data = ArticleData::make(
    title: $source['title'],
    description: $source['description'],
    status: $source['status'],
    modified: $source['modified'],
);

//or even cleaner
$data = ArticleData::make(Arr::only($source, 'title', 'description', 'status', 'modified'));

#[DateTimeCaster('Y-m-d')] //takes a format string, or defaults to iso-8601
#[EnumCaster(Status::class, State::class)] //takes one or more enum class strings
#[NullCaster('', '-')] //takes one or more values that should be converted to null
#[ScalarCaster('bool', 'null')] //takes one or more accepted types, if no types match it will cast to the last type



declare(strict_types=1);

namespace App\Support\Data\Casters;

use Attribute;
use Honeystone\DtoTools\Casters\Contracts\CastsValues;

#[Attribute]
final readonly class MyCaster implements CastsValues
{
    public function cast(mixed $value): mixed
    {
        //...
    }
}

final readonly class SomeData implements Transferable
{
    use HasTransferableData;

    public function __construct(
        public string $foo,
        public string $bar,
    ) {
    }

    protected static function transformIncoming(array $parameters): array
    {
        return array_map(static fn (string $value): string => "🔥 $value 🔥", $parameters);
    }
}

echo SomeData::make(['foo', 'bar'])->getAttributes(); //['foo' => '🔥 foo 🔥', 'bar' => '🔥 bar 🔥']

final readonly class SomeData implements Transferable
{
    use HasTransferableData

    public function __construct(
        public string $foo,
        public string $bar,
    ) {
    }

    protected static function transformOutgoing(array $parameters): array
    {
        return array_map(static fn (string $value): string => "🔥 $value 🔥", $parameters);
    }
}

echo SomeData::make(['foo', 'bar'])->getAttributes(); //['foo' => 'foo',       'bar' => 'bar']
echo SomeData::make(['foo', 'bar'])->toArray();       //['foo' => '🔥 foo 🔥', 'bar' => '🔥 bar 🔥']

use Honeystone\DtoTools\Concerns\CreatableFromSnake;
use Honeystone\DtoTools\Concerns\SerializesToSnake;

final readonly class SomeData implements Transferable
{
    use HasTransferableData, CreatableFromSnake, SerializesToSnake;

    public function __construct(
        public string $someProperty,
    ) {
    }
}

echo SomeData::make(some_property: 'value')->getAttributes(); //['someProperty'  => 'value']
echo SomeData::make(some_property: 'value')->toArray();       //['some_property' => 'value']



declare(strict_types=1);

namespace App\Domains\Articles\Data;

use App\Domains\Articles\Data\Enums\Status;
use Honeystone\DtoTools\Concerns\HasStorableData;
use Honeystone\DtoTools\Contracts\Storable;

final class ArticlePatchData implements Storable
{
    use HasStorableData;

    public function __construct(
        public readonly string $title,
        public readonly ?string $description,
        public readonly Status $status,
        public readonly string $modified,
    ) {
    }
}


use Honeystone\DtoTools\Attributes\Patch;

#[Patch]
final class ArticlePatchData implements Storable
{
    use HasStorableData;

    public function __construct(
        //...
    ) {
    }
}

echo SomeData::make(foo: 'value', bar: null)->toStorableArray(); //['foo' => 'value']
echo SomeData::make(foo: 'value', bar: null)->toArray();         //['foo' => 'value', 'bar => null]

$data = echo SomeData::make(foo: 'value', bar: null);

$data->isStorable('foo'); //true
$data->isStorable('bar'); //false

$data = echo SomeData::make(foo: 'value', bar: null);

$data->force('bar');

$data->isStorable('bar'); //true


#[Patch]
final class ArticlePatchData implements Storable
{
    use HasStorableData;

    /**
    * @param array<int>|null $tags
    */
    public function __construct(
        //...
        public ?array $tags = null,
    ) {
    }
}


use Honeystone\DtoTools\Attributes\ToMany;

#[Patch]
#[ToMany(['tags' => 'int|empty'])]
final class ArticlePatchData implements Storable
{
    use HasStorableData;

    public function __construct(
        //...
    ) {
    }
}

$data = ArticlePatchData::make(...);

$data->relationships()->addToManyRelation('foo', 123, ['priority' => 5]);

$data = ArticlePatchData::make(...);

$data->relationships()->addToManyRelation('foo', TagData::make(...), TagMetaData::make(...));

#[ToOne(['foo' => 'int|string|null'])]
#[ToMany(['bar' => 'int|string|empty'])]

$data->relationships()->hasToOne('foo');
$data->relationships()->getOneRelated('foo');
$data->relationships()->setOneRelated('foo', 123);
$data->relationships()->unsetOneRelated('foo');

$data->relationships()->hasToMany('bar');
$data->relationships()->getManyRelated('bar'); //plus any additions, minus any removals
$data->relationships()->getManyAdditions('bar');
$data->relationships()->getManyRemovals('bar');
$data->relationships()->addToManyRelation('bar', 123, []); //param 3 optional
$data->relationships()->removeToManyRelation('bar', 123);
$data->relationships()->replaceToMany('bar', 123, []); //param 3 optional, clears addition and removals
$data->relationships()->resetToMany('bar'); //clears addition and removals
$data->relationships()->getMetaData('bar');
$data->relationships()->setMetaData('bar', []);



declare(strict_types=1);

namespace App\Domains\Articles\Data\Transformers;

use App\Domains\Articles\Data\ArticleData;
use Honeystone\DtoTools\Transformers\ModelTransformer;

final class ArticleTransformer extends ModelTransformer
{
    protected string $dataClass = ArticleData::class;
}

$transformer = app(ArticleTransformer::class);

$transformer->transform(Article::first());
$transformer->transformCollection(Article::all());

final class ArticleTransformer extends ModelTransformer
{
    protected string $dataClass = ArticleData::class;

    protected array $only = [
        'title',
        'description',
        'status',
        'modified',
    ];
}

final class ArticleTransformer extends ModelTransformer
{
    protected string $dataClass = ArticleData::class;

    protected function map(Model $model): array
    {
        return [
            'title' => Str::title($model->title),
            'status' => in_array($model->status, ['published', 'active']) ? 'published' : 'draft',
            ...$model->only('description', 'modified'),
        ];
    }
}

$transformer->transform(Article::first(), foo: 'bar');
$transformer->transformCollection(Article::all(), foo: 'bar', bar: 'baz');

$transformer
    ->exclude('foo', 'bar')
    ->override(['status' => 'preview'])
    ->transform(Article::first()); //transform() or transformCollection()

final class ArticleTransformer extends ModelTransformer
{
    protected string $dataClass = ArticleData::class;

    protected function map(Model $model): array
    {
        return [
            'title' => Str::title($model->title),
            'status' => in_array($model->status, ['published', 'active']) ? 'published' : 'draft',
            ...$model->only('description', 'modified'),
            'tags' => $this->includeRelated('tags', $model->tags),
            'category' => $this->

final class ArticleTransformer extends ModelTransformer
{
    protected string $dataClass = ArticleData::class;

    protected function map(Model $model): array
    {
        return [
            //...
            'category' => $this->
    }
}
shell
php artisan vendor:publish --tag=honeystone-dto-tools-config