Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ObjectMapper] Class-Level Transformation and Public Constructors #60807

Open
@mttsch

Description

@mttsch

Symfony version(s) affected

7.3.0

Description

While checking out #60797 and writing a fix for it, I ran into an issue with regard to Class-Level Transformation and the InstanceCallback test case https://github.com/symfony/symfony/tree/7.3/src/Symfony/Component/ObjectMapper/Tests/Fixtures/InstanceCallback.

The documentation stats that the callback "must return a correctly initialized instance of the target class" and the example code shows a private constructor with the comment "uses a private constructor to avoid direct instantiation". The InstanceCallback, however, has a public constructor which is only not called because $ctorArguments is empty (A only has property $name and B::__constructor() expects $id, thus $ctorArguments is empty), see condition

if (!$mappingToObject && $ctorArguments && $constructor) {

How to reproduce

Currently, the test case passes, but when changing public ?string $name = null to a promoted property in \Symfony\Component\ObjectMapper\Tests\Fixtures\InstanceCallback\B, the test case fails:

1) Symfony\Component\ObjectMapper\Tests\ObjectMapperTest::testMapToWithInstanceHook
ArgumentCountError: Symfony\Component\ObjectMapper\Tests\Fixtures\InstanceCallback\B::__construct(): Argument #1 ($id) not passed

…/src/Symfony/Component/ObjectMapper/Tests/Fixtures/InstanceCallback/B.php:16
…//src/Symfony/Component/ObjectMapper/ObjectMapper.php:151
…//src/Symfony/Component/ObjectMapper/Tests/ObjectMapperTest.php:152

showing that the constructor would be called but is only not called in the original example due to $ctorArguments being empty.

Possible Solution

As the class-level transformation is expected to return a full initialized objects, never call the constructor of the target object in ObjectMapper if level-class transformation is used.

Alternatively, if calling the constructor is correct, the documentation could be clearer and constructor argument validation could be improved because \Symfony\Component\ObjectMapper\ObjectMapperInterface::map is not expected to throw a ArgumentCountError (though only catching \ReflectionException here might be an issue on its own?).

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions