diff --git a/CHANGELOG.md b/CHANGELOG.md index 889d283..90cbdae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Fixed - [GH#207](https://github.com/jolicode/automapper/pull/207) [GH#208](https://github.com/jolicode/automapper/pull/208) Fix implicity nullable parameter deprecations +- [GH#212](https://github.com/jolicode/automapper/pull/212) Fix cases where class target has adder and remover AND constructor arguments ## [9.2.0] - 2024-11-19 ### Added diff --git a/src/Transformer/AbstractArrayTransformer.php b/src/Transformer/AbstractArrayTransformer.php index 7708fc1..83b08b7 100644 --- a/src/Transformer/AbstractArrayTransformer.php +++ b/src/Transformer/AbstractArrayTransformer.php @@ -43,7 +43,7 @@ public function transform(Expr $input, Expr $target, PropertyMetadata $propertyM /* Get the transform statements for the source property */ [$output, $itemStatements] = $this->itemTransformer->transform($loopValueVar, $target, $propertyMapping, $uniqueVariableScope, $source); - if ($propertyMapping->target->writeMutator && $propertyMapping->target->writeMutator->type === WriteMutator::TYPE_ADDER_AND_REMOVER) { + if (null === $propertyMapping->target->parameterInConstructor && $propertyMapping->target->writeMutator && $propertyMapping->target->writeMutator->type === WriteMutator::TYPE_ADDER_AND_REMOVER) { /** * Use add and remove methods. * diff --git a/tests/AutoMapperTest.php b/tests/AutoMapperTest.php index fc79223..4f9665c 100644 --- a/tests/AutoMapperTest.php +++ b/tests/AutoMapperTest.php @@ -48,6 +48,7 @@ use AutoMapper\Tests\Fixtures\ObjectWithDateTime; use AutoMapper\Tests\Fixtures\Order; use AutoMapper\Tests\Fixtures\PetOwner; +use AutoMapper\Tests\Fixtures\PetOwnerWithConstructorArguments; use AutoMapper\Tests\Fixtures\PrivatePropertyInConstructors\ChildClass; use AutoMapper\Tests\Fixtures\PrivatePropertyInConstructors\OtherClass; use AutoMapper\Tests\Fixtures\Provider\CustomProvider; @@ -1088,6 +1089,26 @@ public function testAdderAndRemoverWithNull(): void self::assertCount(0, $petOwnerData->getPets()); } + public function testAdderAndRemoverWithConstructorArguments(): void + { + if (!class_exists(ClassDiscriminatorFromClassMetadata::class)) { + self::markTestSkipped('Symfony Serializer is required to run this test.'); + } + + $petOwner = [ + 'pets' => [ + ['type' => 'cat', 'name' => 'Félix'], + ], + ]; + + $petOwnerData = $this->autoMapper->map($petOwner, PetOwnerWithConstructorArguments::class); + + self::assertIsArray($petOwnerData->getPets()); + self::assertCount(1, $petOwnerData->getPets()); + self::assertSame('Félix', $petOwnerData->getPets()[0]->name); + self::assertSame('cat', $petOwnerData->getPets()[0]->type); + } + public function testIssueTargetToPopulate(): void { $source = new Fixtures\IssueTargetToPopulate\VatModel(); diff --git a/tests/Fixtures/PetOwnerWithConstructorArguments.php b/tests/Fixtures/PetOwnerWithConstructorArguments.php new file mode 100644 index 0000000..9eb7c73 --- /dev/null +++ b/tests/Fixtures/PetOwnerWithConstructorArguments.php @@ -0,0 +1,38 @@ + */ + private $pets; + + public function __construct(array $pets) + { + $this->pets = $pets; + } + + /** + * @return Pet[] + */ + public function getPets(): array + { + return $this->pets; + } + + public function addPet(Pet $pet): void + { + $this->pets[] = $pet; + } + + public function removePet(Pet $pet): void + { + $index = array_search($pet, $this->pets); + + if ($index !== false) { + unset($this->pets[$index]); + } + } +}