diff --git a/CHANGELOG.md b/CHANGELOG.md index 6937fd8..f232210 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 762b21c..591d116 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 89adc4a..41a8ae4 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 24a5e33..f31427b 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);