From 2832de77c4c25fb85cccc51804d1bfc253e1e7bc Mon Sep 17 00:00:00 2001 From: alexpts Date: Thu, 28 May 2020 22:12:02 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=20=D0=B2?= =?UTF-8?q?=20=D0=BA=D0=B0=D1=80=D1=82=D1=8B=20#4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 38 +++++++++++++- composer.json | 3 +- composer.lock | 51 +++++++++++++++++- src/MapsManager.php | 22 +++++++- test/unit/MapsManagerTest.php | 99 +++++++++++++++++++---------------- test/unit/data/Container.php | 19 +++++++ test/unit/data/UserModel.php | 20 ++++--- test/unit/data/dto.php | 5 ++ 8 files changed, 197 insertions(+), 60 deletions(-) create mode 100644 test/unit/data/Container.php 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 @@ + [],