Skip to content

Commit

Permalink
fix: constructor with default parameter array does not work with context
Browse files Browse the repository at this point in the history
  • Loading branch information
MrMeshok committed Sep 13, 2024
1 parent 7585318 commit 52dc238
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed
- [GH#184](https://github.com/jolicode/automapper/pull/184) Fix error when mapping from stdClass to constructor with nullable/optional arguments
- [GH#185](https://github.com/jolicode/automapper/pull/185) Fix constructor with default parameter array does not work with constructor_arguments context

## [9.1.2] - 2024-09-03
### Fixed
Expand Down
18 changes: 11 additions & 7 deletions src/Generator/CreateTargetStatementsGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,15 @@ private function constructorArgument(GeneratorMetadata $metadata, PropertyMetada
}

if ($defaultValueExpr instanceof Expr\Array_) {
// $constructarg_3 = count($values) > 0 ? $values : array();
$argumentAssignedValue = new Expr\Ternary(new Expr\BinaryOp\Greater(new Expr\FuncCall(new Name('count'), [new Arg($output)]), create_scalar_int(0)), $output, $defaultValueExpr);
// $constructarg = count($values) > 0 ? $values : {expression};
$argumentAssignClosure = static fn (Expr $expr) => new Expr\Assign($constructVar, new Expr\Ternary(
new Expr\BinaryOp\Greater(new Expr\FuncCall(new Name('count'), [new Arg($output)]), create_scalar_int(0)),
$output,
$expr,
));
} else {
// $constructarg_0 = $values ?? array();
$argumentAssignedValue = new Expr\BinaryOp\Coalesce($output, $defaultValueExpr);
// $constructarg = $values ?? {expression};
$argumentAssignClosure = static fn (Expr $expr) => new Expr\Assign($constructVar, new Expr\BinaryOp\Coalesce($output, $expr));
}

return [
Expand All @@ -221,15 +225,15 @@ private function constructorArgument(GeneratorMetadata $metadata, PropertyMetada
]), [
'stmts' => [
...$propStatements,
new Stmt\Expression(new Expr\Assign($constructVar, new Expr\BinaryOp\Coalesce($output, new Expr\StaticCall(new Name\FullyQualified(MapperContext::class), 'getConstructorArgument', [
new Stmt\Expression($argumentAssignClosure(new Expr\StaticCall(new Name\FullyQualified(MapperContext::class), 'getConstructorArgument', [
new Arg($variableRegistry->getContext()),
new Arg(new Scalar\String_($metadata->mapperMetadata->target)),
new Arg(new Scalar\String_($propertyMetadata->target->property)),
])))),
]))),
],
'else' => new Stmt\Else_([
...$propStatements,
new Stmt\Expression(new Expr\Assign($constructVar, $argumentAssignedValue)),
new Stmt\Expression($argumentAssignClosure($defaultValueExpr)),
]),
]),
new Arg($constructVar, name: new Identifier($parameter->getName())),
Expand Down
13 changes: 13 additions & 0 deletions tests/AutoMapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,19 @@ public function testConstructor(): void
self::assertTrue($userDto->getConstructor());
}

public function testConstructorArrayArgumentFromContext(): void
{
$data = ['baz' => 'baz'];
/** @var ConstructorWithDefaultValues $userDto */
$object = $this->autoMapper->map($data, ConstructorWithDefaultValues::class, [MapperContext::CONSTRUCTOR_ARGUMENTS => [
ConstructorWithDefaultValues::class => ['someOtters' => [1]],
]]);

self::assertInstanceOf(ConstructorWithDefaultValues::class, $object);
self::assertSame('baz', $object->baz);
self::assertSame([1], $object->someOtters);
}

public function testConstructorNotAllowed(): void
{
$this->buildAutoMapper(mapPrivatePropertiesAndMethod: true, constructorStrategy: ConstructorStrategy::NEVER, classPrefix: 'NotAllowedMapper_');
Expand Down

0 comments on commit 52dc238

Please sign in to comment.