Skip to content

Commit

Permalink
fix: infinite loop in MapperFactory (#254)
Browse files Browse the repository at this point in the history
* fix: infinite loop in `MapperFactory`

* fix
  • Loading branch information
priyadi authored Nov 12, 2024
1 parent d117d4d commit b91b897
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 1.13.5

* fix: infinite loop in `MapperFactory`

## 1.13.4

* fix: fix list handling
Expand Down
29 changes: 27 additions & 2 deletions src/MapperFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,14 @@ class MapperFactory

private ?TransformerRegistryInterface $transformerRegistry = null;

private ?ContainerInterface $propertyMapperLocator = null;

private ?PropertyMapperResolverInterface $propertyMapperResolver = null;

private ?ObjectMapperTableFactoryInterface $objectMapperTableFactory = null;

private ?ContainerInterface $objectMapperLocator = null;

private ?ObjectMapperResolverInterface $objectMapperResolver = null;

private ?PropertyReadInfoExtractorInterface $propertyReadInfoExtractor = null;
Expand Down Expand Up @@ -443,7 +447,7 @@ protected function getObjectMapperTransformer(): TransformerInterface
if (null === $this->objectMapperTransformer) {
$this->objectMapperTransformer = new ObjectMapperTransformer(
$this->getSubMapperFactory(),
$this->getTransformersLocator(),
$this->getObjectMapperLocator(),
$this->getObjectMapperTableFactory(),
$this->getObjectMapperResolver(),
);
Expand Down Expand Up @@ -800,6 +804,23 @@ protected function getObjectMapperTableFactory(): ObjectMapperTableFactoryInterf
return $this->objectMapperTableFactory;
}

protected function getObjectMapperLocator(): ContainerInterface
{
if ($this->objectMapperLocator !== null) {
return $this->objectMapperLocator;
}

$services = [];

foreach ($this->objectMappers as $objectMapper) {
$service = $objectMapper['service'];
$class = $service::class;
$services[$class] = $service;
}

return $this->objectMapperLocator = new ServiceLocator($services);
}

protected function getObjectMapperResolver(): ObjectMapperResolverInterface
{
if (null === $this->objectMapperResolver) {
Expand All @@ -813,6 +834,10 @@ protected function getObjectMapperResolver(): ObjectMapperResolverInterface

protected function getPropertyMapperLocator(): ContainerInterface
{
if ($this->propertyMapperLocator !== null) {
return $this->propertyMapperLocator;
}

$services = [];

foreach ($this->propertyMappers as $propertyMapper) {
Expand All @@ -821,7 +846,7 @@ protected function getPropertyMapperLocator(): ContainerInterface
$services[$class] = $service;
}

return new ServiceLocator($services);
return $this->propertyMapperLocator = new ServiceLocator($services);
}

protected function getPropertyReadInfoExtractor(): PropertyReadInfoExtractorInterface
Expand Down
1 change: 1 addition & 0 deletions tests/config/rekalogika-mapper/generated-mappings.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@
$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/BasicMappingTest.php on line 33
// tests/src/IntegrationTest/IterableMapperTest.php on line 24
// tests/src/UnitTest/MapperFactoryTest.php on line 29
source: \Rekalogika\Mapper\Tests\Fixtures\Basic\Person::class,
target: \Rekalogika\Mapper\Tests\Fixtures\Basic\PersonDto::class
);
Expand Down
34 changes: 34 additions & 0 deletions tests/src/UnitTest/MapperFactoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Tests\UnitTest;

use PHPUnit\Framework\TestCase;
use Rekalogika\Mapper\MapperFactory;
use Rekalogika\Mapper\Tests\Fixtures\Basic\Person;
use Rekalogika\Mapper\Tests\Fixtures\Basic\PersonDto;

class MapperFactoryTest extends TestCase
{
public function testMapperFactory(): void
{
$mapperFactory = new MapperFactory();
$mapper = $mapperFactory->getMapper();

$source = new Person('John Doe', 30);
$target = $mapper->map($source, PersonDto::class);

$this->assertSame('John Doe', $target->name);
$this->assertSame(30, $target->age);
}
}

0 comments on commit b91b897

Please sign in to comment.