alexpts/php-data-transformer2

Convert model to dto, convert dto to model

3.1.0 2019-02-27 19:40 UTC

README

SensioLabsInsight

Build Status Code Coverage Code Climate Scrutinizer Code Quality

Библиотека представляет собой более высокий уровень билбиотеки https://github.com/alexpts/php-hydrator. Расширяя ее возможности и упрощая работу за счет:

  • Декларативного описания правил преобразования
  • Рекурсивного преобразования вложенных моделей и коллекций моделей
  • Более лаконичного синтаксиса

Базовые правила схем трансформации подробно описаны в проекте https://github.com/alexpts/php-hydrator.

Data Transformer

Класс DataTransformer является более высокогоуровневым. Он позволяет работать с HydratorService и описывать схемы преобразования для каждого класса отдельно.

Для одного класса может быть множество схем преобразования. Например для преобразования модели для сохранения в БД требуется преобразовать ее в DTO сущность. При этом все значения типа \DateTime преобразовать в timestamp. Но если мы передаем эту же модель на клиент через REST API, то схема преобразования может быть иной. Все значения \DateTime нужно представить в виде строки в формате ISO8601.

$dataTransformer = new DataTransformer;
$dataTransformer->getMapsManager()->setMapDir(UserModel::class, __DIR__ . '/data');

$model = $dataTransformer->toModel(UserModel::class, [
    'id' => 1,
    'creAt' => new \DateTime,
    'name' => 'Alex',
    'active' => 1,
]);

$dto = $dataTransformer->toDTO($model, 'dto');
$dtoForDb = $dataTransformer->toDTO($model, 'db');

А еще у нас может быть просто более компактное представлеиние этой же модели, без лишних деталей.

$shortFormatDto = $dataTransformer->toDTO($model, 'short.dto');

Коллекция моделей

Небольшой сахар, чтобы перевести коллекцию однотипных моделей в коллекцию DTO:

$mapName = 'dto';
$excludedFields = ['name'];
$dtoCollection = $dataTransformer->toDtoCollection($models, $mapName, [
	'excludeFields' => $excludedFields
]);

Вложенные модели

Если свойство модели представлено другой моделью или коллекцией моделей, то можно рекурсивно извлеч/заполнить модель. Для этого в схеме маппинга нужно использовать ключ ref.

// map file deepDto.php
return [
    'id' => [],
    'creAt' => [],
    'name' => [],
    'login' => [],
    'active' => [
        'pipe' => ['boolval']
    ],
    'email' => [
    	 'pipe' => [
    	 	[
    	 		'populate' => 'strtolower',
    	 		'extract' => 'strtoupper'
    	 	]
    	 ]
    ],
    'refModel' => [
        'ref' => [
            'model' => UserModel::class,
            'map' => 'dto'
        ]
    ],
    'refModels' => [
        'ref' => [
            'model' => UserModel::class,
            'map' => 'dto',
            'collection' => true
        ]
    ],
];

// code file
$model = $dataTransformer->toModel(UserModel::class, [
    'id' => 1,
    'creAt' => new \DateTime,
    'name' => 'Alex',
    'active' => 1,
    'refModel' => [
        'id' => 2,
        'name' => 'refModel',
    ]
], 'deepDto');

$model2 = $dataTransformer->toModel(UserModel::class, [
    'id' => 1,
    'creAt' => new \DateTime,
    'name' => 'Alex',
    'active' => 1,
    'refModels' => [ // collection ref models
        [
            'id' => 2,
            'name' => 'refModel',
        ],
        [
            'id' => 2,
            'name' => 'refModel',
        ]
    ]
], 'deepDto');