From dbb8911a5fcd2bf9bf5c212a7bf82c26112d7a62 Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo <1102197+priyadi@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:03:35 +0700 Subject: [PATCH] feat(`PresetMappingFactory`): Add `fromObjectCache()` and `fromObjectCacheReversed()`. --- CHANGELOG.md | 1 + .../Context/PresetMappingFactory.php | 26 +++++++++++++++++++ .../RememberingMapper/RememberingMapper.php | 2 +- tests/IntegrationTest/PresetMappingTest.php | 23 +++++++++++++--- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6937fd82..f232210c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ * feat: Mapping to existing values in a dynamic property. * perf(`ObjectToObjectTransformer`): Prevent delegating to `MainTransformer` if the current value in a dynamic property is a scalar. +* feat(`PresetMappingFactory`): Add `fromObjectCache()` and `fromObjectCacheReversed()`. ## 1.0.0 diff --git a/src/Transformer/Context/PresetMappingFactory.php b/src/Transformer/Context/PresetMappingFactory.php index 762b21c1..591d1161 100644 --- a/src/Transformer/Context/PresetMappingFactory.php +++ b/src/Transformer/Context/PresetMappingFactory.php @@ -30,6 +30,32 @@ public static function fromObjectCache(ObjectCache $objectCache): PresetMapping /** @var SplObjectStorageWrapper> */ $presetMapping = new SplObjectStorageWrapper(new \SplObjectStorage()); + /** + * @var object $source + * @var \ArrayObject $classToTargetMapping + */ + foreach ($objectCacheWeakMap as $source => $classToTargetMapping) { + foreach ($classToTargetMapping as $targetClass => $target) { + if (!$presetMapping->offsetExists($source)) { + /** @var \ArrayObject */ + $arrayObject = new \ArrayObject(); + $presetMapping->offsetSet($source, $arrayObject); + } + + $presetMapping->offsetGet($source)?->offsetSet($targetClass, $target); + } + } + + return new PresetMapping($presetMapping); + } + + public static function fromObjectCacheReversed(ObjectCache $objectCache): PresetMapping + { + $objectCacheWeakMap = $objectCache->getInternalMapping(); + + /** @var SplObjectStorageWrapper> */ + $presetMapping = new SplObjectStorageWrapper(new \SplObjectStorage()); + /** * @var object $source * @var \ArrayObject $classToTargetMapping diff --git a/tests/Fixtures/RememberingMapper/RememberingMapper.php b/tests/Fixtures/RememberingMapper/RememberingMapper.php index 89adc4a2..41a8ae43 100644 --- a/tests/Fixtures/RememberingMapper/RememberingMapper.php +++ b/tests/Fixtures/RememberingMapper/RememberingMapper.php @@ -57,7 +57,7 @@ public function map(object $source, object|string $target, ?Context $context = n throw new UnexpectedValueException(sprintf('Expected instance of "%s", got "%s"', $target, get_class($result))); } - $newPresetMapping = PresetMappingFactory::fromObjectCache($objectCache); + $newPresetMapping = PresetMappingFactory::fromObjectCacheReversed($objectCache); $this->presetMapping->mergeFrom($newPresetMapping); return $result; diff --git a/tests/IntegrationTest/PresetMappingTest.php b/tests/IntegrationTest/PresetMappingTest.php index 24a5e33b..f31427b4 100644 --- a/tests/IntegrationTest/PresetMappingTest.php +++ b/tests/IntegrationTest/PresetMappingTest.php @@ -36,13 +36,30 @@ public function testFromObjectCache(): void $objectCache = $this->createObjectCache(); $source = new ObjectWithScalarProperties(); - $targetType = TypeFactory::objectOfClass(ObjectWithScalarProperties::class); + $targetType = TypeFactory::objectOfClass(ObjectWithScalarPropertiesDto::class); $target = new ObjectWithScalarPropertiesDto(); $objectCache->saveTarget($source, $targetType, $target); $presetMapping = PresetMappingFactory::fromObjectCache($objectCache); + $result = $presetMapping->findResult($source, ObjectWithScalarPropertiesDto::class); + + $this->assertSame($target, $result); + } + + public function testFromObjectCacheReversed(): void + { + $objectCache = $this->createObjectCache(); + + $source = new ObjectWithScalarProperties(); + $targetType = TypeFactory::objectOfClass(ObjectWithScalarProperties::class); + $target = new ObjectWithScalarPropertiesDto(); + + $objectCache->saveTarget($source, $targetType, $target); + + $presetMapping = PresetMappingFactory::fromObjectCacheReversed($objectCache); + $result = $presetMapping->findResult($target, $source::class); $this->assertSame($source, $result); @@ -58,7 +75,7 @@ public function testMerge(): void $objectCache->saveTarget($source, $targetType, $target); - $presetMapping = PresetMappingFactory::fromObjectCache($objectCache); + $presetMapping = PresetMappingFactory::fromObjectCacheReversed($objectCache); $source2 = new ObjectWithScalarProperties(); $targetType2 = TypeFactory::objectOfClass(ObjectWithScalarProperties::class); @@ -66,7 +83,7 @@ public function testMerge(): void $objectCache->saveTarget($source2, $targetType2, $target2); - $presetMapping2 = PresetMappingFactory::fromObjectCache($objectCache); + $presetMapping2 = PresetMappingFactory::fromObjectCacheReversed($objectCache); $presetMapping->mergeFrom($presetMapping2);