diff --git a/README.md b/README.md index 2074743..ac610e4 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ return [ 'email' => [ 'pipe' => [ [ - 'populate' => 'strtolower', + 'populate' => 'strtolower', // any callable 'extract' => 'strtoupper' ] ] @@ -122,3 +122,39 @@ $model2 = $dataTransformer->toModel(UserModel::class, [ ] ], 'deepDto'); ``` + + +### Логика в pipe обработчиках +Обработчики pipe позволяют описывать callable методы и писать любую логику, которая будет применяться к значению. +В pipe фильтрах можно кастить типы например. Либо шифровать поля перед записью в БД. +В случае необходимости, чтобы вся логика маппинга была в 1 месте, вы может прокинуть любые зависимости через замыкание +в функцию pipe, доставл ее из контейнера. + +```php +getContainer()->get('encrypter'); + +return [ + 'id' => [], + 'creAt' => [], + 'name' => [], + 'password' => [ + 'pipe' => [ + [ + 'extract' => function(string $openPassword) use($encrypter) { + return $encrypter->encrypt($openPassword, false); + }, + 'populate' => static function(string $ePassword) use($encrypter) { + return $encrypter->decrypt($ePassword, false); + }, + ] + ] + ], + +]; \ No newline at end of file diff --git a/composer.json b/composer.json index fc0365b..5b38677 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ "minimum-stability": "stable", "require": { "php": "^7.4", - "alexpts/php-hydrator": "^3.0" + "alexpts/php-hydrator": "^3.0", + "psr/container": "^1.0" }, "require-dev": { "fzaninotto/faker": "^1.9", diff --git a/composer.lock b/composer.lock index f7b7066..1c7736a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a5b9982948737b6e9e013f5b437e22b8", + "content-hash": "0f159f22315d6c4b289679f7999770e0", "packages": [ { "name": "alexpts/php-hydrator", @@ -55,6 +55,55 @@ "transform" ], "time": "2020-02-16T09:33:31+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" } ], "packages-dev": [ diff --git a/src/MapsManager.php b/src/MapsManager.php index c8772fd..914df09 100644 --- a/src/MapsManager.php +++ b/src/MapsManager.php @@ -3,6 +3,8 @@ namespace PTS\DataTransformer; +use Psr\Container\ContainerInterface; + class MapsManager { protected array $cache = []; @@ -10,6 +12,7 @@ class MapsManager protected array $mapsDirs = []; protected NormalizerInterface $normalizer; protected string $defaultMapsDirs = ''; + protected ?ContainerInterface $container = null; public function __construct(NormalizerInterface $normalizer = null, string $dir = '') { @@ -17,6 +20,17 @@ public function __construct(NormalizerInterface $normalizer = null, string $dir $this->setDefaultMapDir($dir); } + public function setContainer(ContainerInterface $container): self + { + $this->container = $container; + return $this; + } + + public function getContainer(): ?ContainerInterface + { + return $this->container; + } + public function setDefaultMapDir(string $dir): void { $this->defaultMapsDirs = $dir; @@ -32,13 +46,19 @@ public function getMap(string $entityName, string $mapName = 'dto'): array $map = $this->cache[$entityName][$mapName] ?? null; if ($map === null) { $dir = $this->getMapDir($entityName); - $rules = require $dir.DIRECTORY_SEPARATOR.$mapName.'.php'; + $rules = $this->includeMap($dir.DIRECTORY_SEPARATOR.$mapName.'.php'); $this->setMap($rules, $entityName, $mapName); } return $this->cache[$entityName][$mapName]; } + protected function includeMap(string $file): array + { + return require $file; + } + + public function getMapDir(string $entityName): string { $dir = $this->mapsDirs[$entityName] ?? null; diff --git a/test/unit/MapsManagerTest.php b/test/unit/MapsManagerTest.php index 0f4dd7c..c5f4aa3 100644 --- a/test/unit/MapsManagerTest.php +++ b/test/unit/MapsManagerTest.php @@ -5,52 +5,61 @@ use PTS\DataTransformer\MapsManager; require_once __DIR__ . '/data/UserModel.php'; +require_once __DIR__ . '/data/Container.php'; class MapsManagerTest extends TestCase { - protected MapsManager $manager; - - public function setUp(): void - { - $this->manager = new MapsManager; - } - - public function testSetMapDir(): void - { - $this->manager->setMapDir('model.user', __DIR__ . '/data'); - $result = $this->manager->getMap('model.user'); - self::assertNotNull($result); - } - - public function testGetMap(): void - { - $this->manager->setMapDir('model.user', __DIR__ . '/data'); - $map = $this->manager->getMap('model.user'); - self::assertCount(3, $map); - self::assertCount(6, $map['rules']); - self::assertCount(2, $map['pipe']); - self::assertCount(0, $map['refs']); - } - - public function testGetMapWithCache(): void - { - $this->manager->setMapDir('model.user', __DIR__ . '/data'); - $map = $this->manager->getMap('model.user'); - $map2 = $this->manager->getMap('model.user'); - self::assertCount(3, $map2); - self::assertCount(6, $map2['rules']); - self::assertCount(2, $map2['pipe']); - self::assertCount(0, $map2['refs']); - self::assertSame($map, $map2); - } - - public function testGetMapFromDefaultDir(): void - { - $this->manager->setDefaultMapDir(__DIR__ . '/data'); - $map = $this->manager->getMap('Namespace\UserModel'); - self::assertCount(3, $map); - self::assertCount(6, $map['rules']); - self::assertCount(2, $map['pipe']); - self::assertCount(0, $map['refs']); - } + protected MapsManager $manager; + + public function setUp(): void + { + $this->manager = new MapsManager; + } + + public function testSetMapDir(): void + { + $this->manager->setMapDir('model.user', __DIR__ . '/data'); + $result = $this->manager->getMap('model.user'); + self::assertNotNull($result); + } + + public function testGetMap(): void + { + $this->manager->setMapDir('model.user', __DIR__ . '/data'); + $map = $this->manager->getMap('model.user'); + self::assertCount(3, $map); + self::assertCount(6, $map['rules']); + self::assertCount(2, $map['pipe']); + self::assertCount(0, $map['refs']); + } + + public function testGetMapWithCache(): void + { + $this->manager->setMapDir('model.user', __DIR__ . '/data'); + $map = $this->manager->getMap('model.user'); + $map2 = $this->manager->getMap('model.user'); + self::assertCount(3, $map2); + self::assertCount(6, $map2['rules']); + self::assertCount(2, $map2['pipe']); + self::assertCount(0, $map2['refs']); + self::assertSame($map, $map2); + } + + public function testGetMapFromDefaultDir(): void + { + $this->manager->setDefaultMapDir(__DIR__ . '/data'); + $map = $this->manager->getMap('Namespace\UserModel'); + self::assertCount(3, $map); + self::assertCount(6, $map['rules']); + self::assertCount(2, $map['pipe']); + self::assertCount(0, $map['refs']); + } + + public function testContainer(): void + { + $container = new Container; + $this->manager->setContainer($container); + $value = $this->manager->getContainer()->get('any'); + static::assertSame(1, $value); + } } diff --git a/test/unit/data/Container.php b/test/unit/data/Container.php new file mode 100644 index 0000000..03b342f --- /dev/null +++ b/test/unit/data/Container.php @@ -0,0 +1,19 @@ + [],