/simple-data-transfer-object

Simple Data Transfer Objects

Primary LanguagePHPMIT LicenseMIT

Simple Data Transfer Object

Simple DTO

Stable Version Unstable Version Total Downloads License

Installation

To get the latest version of Simple Data Transfer Object, simply require the project using Composer:

composer require dragon-code/simple-dto

Or manually update require block of composer.json and run composer update.

{
    "require": {
        "dragon-code/simple-dto": "^2.0"
    }
}

Upgrade from andrey-helldar/simple-data-transfer-object

  1. Replace "andrey-helldar/simple-data-transfer-object": "^1.0" with "dragon-code/simple-dto": "^2.0" in the composer.json file;
  2. Replace Helldar\SimpleDataTransferObject namespace prefix with DragonCode\SimpleDataTransferObject in your application;
  3. Call the composer update console command.

Upgrade from dragon-code/simple-data-transfer-object

  1. Replace dragon-code/simple-data-transfer-object with dragon-code/simple-dto in the composer.json file;
  2. Call the composer update console command.

Using

Basic

namespace App\DTO;

use DragonCode\SimpleDataTransferObject\DataTransferObject;

class YourInstance extends DataTransferObject
{
    public $foo;

    public $bar;

    public $baz;

    public $qwerty;
}

$instance = YourInstance::make([
    'foo' => 'Foo',
    'bar' => 'Bar',
    'baz' => 'Baz'
]);


return $instance->foo;
// Foo

return $instance->bar;
// Bar

return $instance->baz;
// Baz

return $instance->qwerty;
// null

Mappings

namespace App\DTO;

use DragonCode\SimpleDataTransferObject\DataTransferObject;

class YourInstance extends DataTransferObject
{
    public $foo;

    public $bar;

    public $baz;

    public $qwerty;

    protected $map = [
        'data.foo' => 'foo',
        'data.bar' => 'bar',
    ];
}

$instance = YourInstance::make([
    'data' => [
        'foo' => 'Foo',
        'bar' => 'Bar'
    ],
    'baz' => 'Baz'
]);


return $instance->foo;
// Foo

return $instance->bar;
// Bar

return $instance->baz;
// Baz

return $instance->qwerty;
// null

Casts

namespace App\DTO;

use DragonCode\SimpleDataTransferObject\DataTransferObject;
use DragonCode\Support\Facades\Helpers\Str;

class YourInstance extends DataTransferObject
{
    public $foo;

    public $bar;

    public $baz;

    public $qwerty;

    protected $map = [
        'data.foo' => 'foo',
        'data.bar' => 'bar',
    ];

    protected function castFoo($value)
    {
        return Str::upper($value);
    }
}

$instance = YourInstance::make([
    'data' => [
        'foo' => 'Foo',
        'bar' => 'Bar'
    ],
    'baz' => 'Baz'
]);


return $instance->foo;
// FOO

return $instance->bar;
// Bar

return $instance->baz;
// Baz

return $instance->qwerty;
// null

Nested Objects

With the help of casts, you can also easily create nested objects:

use Tests\Fixtures\Nested\Company;

$company = Company::make([
    'title' => 'First Company',

    'projects' => [
        [
            'title'  => 'Project 1',
            'domain' => 'https://example.com',

            'developers' => [
                [
                    'name'  => 'Andrey Helldar',
                    'email' => 'helldar@ai-rus.com',
                ],
                [
                    'name'  => 'John Doe',
                    'email' => 'doe@example.com',
                ],
            ],
        ],
    ],
]);

$company->title;
// First Company

foreach ($company->projects as $project) {
    $project->title;
    // 0: Project 1

    foreach ($project->developers as $developer) {
        $developer->name;
        // 0: Andrey Helldar
        // 1: John Doe
    }
}

For example, casting test company object:

namespace Tests\Fixtures\Nested;

use DragonCode\SimpleDataTransferObject\DataTransferObject;

class Company extends DataTransferObject
{
    public string $title;

    /** @var \Tests\Fixtures\Nested\Project[] */
    public array $projects;

    protected function castProjects(array $projects): array
    {
        return array_map(static function (array $project) {
            return Project::make($project);
        }, $projects);
    }
}

From

Array

use DragonCode\Contracts\DataTransferObject\DataTransferObject;
use Tests\Fixtures\Simple;

class Foo
{
    protected array $items = [
        'foo' => 'Foo',
        'bar' => 'Bar',
    ];

    protected function dto(): DataTransferObject
    {
        return Simple::fromArray($this->items);
    }
}

Json

use DragonCode\Contracts\DataTransferObject\DataTransferObject;
use Tests\Fixtures\Simple;

class Foo
{
    protected string $json = '{"foo":"Foo","bar":"Bar"}';

    protected function dto(): DataTransferObject
    {
        return Simple::fromJson($this->json);
    }
}

Object

use DragonCode\Contracts\DataTransferObject\DataTransferObject;
use Tests\Fixtures\CustomObject;
use Tests\Fixtures\Simple;

class Foo
{
    protected CustomObject $object;

    protected function dto(): DataTransferObject
    {
        return Simple::fromObject($this->object);
    }
}

Request

use DragonCode\Contracts\DataTransferObject\DataTransferObject;
use Symfony\Component\HttpFoundation\Request;
use Tests\Fixtures\Simple;

class Foo
{
    protected Request $request;

    protected function dto(): DataTransferObject
    {
        return Simple::fromRequest($this->request)
    }
}

Get And Set

You can use the get and set methods in your app:

namespace App\DTO;

use DragonCode\SimpleDataTransferObject\DataTransferObject;

class YourInstance extends DataTransferObject
{
    public $foo;
}

$instance = YourInstance::make([
    'foo' => 'none',
]);

return $instance->foo;
// none

return $instance->get('foo');
// none

$instance->set('foo', 'Foo');

return $instance->foo;
// Foo

Helpers

For your convenience, starting from version 2.17 of the dragon-code/contracts package, we have added a new interface that declares the implementation of the public dto method. This way you can better control your application to return DTO objects.

Of course, don't forget to implement the interface 😉

For example:

namespace App\Http\Requests\Companies;

use App\Objects\Company;
use DragonCode\Contracts\DataTransferObject\DataTransferObject;
use DragonCode\Contracts\DataTransferObject\Dtoable;

class CreateRequest implements Dtoable
{
    // ...

    public function dto(): DataTransferObject
    {
        return Company::fromRequest($this);
    }
}

// Other place
public function store(CreateRequest $request)
{
    $name = $request->dto()->name;
}