SensioFrameworkExtraBundle icon indicating copy to clipboard operation
SensioFrameworkExtraBundle copied to clipboard

Support using `resolve_target_entities` in DoctrineParamConverter

Open mpdude opened this issue 3 years ago • 2 comments

Doctrine ORM provides a way to use Interfaces e. g. in Association Mappings. Then a config setting named resolve_target_entities can be used to supply an Interface-to-Classname mapping. Whenever Doctrine ORM encounters one of the mapped interfaces while loading metadata, it will fall back to the mapped class instead.

This PR aims to support this feature in the DoctrineParamConverter as well.

To go with the example from the above documentation section, @ParamConverter("...", class="App\Model\InvoiceSubjectInterface") would pick up the mapping to the concrete App\Entity\Customer class and pass an instance of that into the controller.

The main challenge is that inside \Doctrine\Persistence\AbstractManagerRegistry, the getManagerForClass() method only looks at the isTransient() metadata property to make a quick decision if something is an entity that could be loaded.

isTransient(), however, is always false for interfaces. The target entity resolution only happens inside Doctrines MetadataFactory when actually loading metadata.

So, to support this new use case, we cannot use getManagerForClass() but need to be a bit more elaborate. But basically, the code now present here is close to the one used inside AbstractManagerRegistry. In particular, it avoids to fetch Managers (expensive services?) as much as the previous implementation.

mpdude avatar Dec 03 '20 16:12 mpdude

Will fix the tests (-> change mock object definitions) and add tests for the new feature once I get your :+1:s.

mpdude avatar Dec 03 '20 17:12 mpdude

An alternative solution might be to couple more closely to DoctrineBundle, fetch their resolve_target_entities map and look into that directly from the DoctrineParamConverter, instead of going through the EntityManagers and having them perform the resolution.

mpdude avatar Dec 04 '20 08:12 mpdude

Closing as this repository is not maintained anymore. As of Symfony 6.2, all features have been moved to Symfony core now. See #783

fabpot avatar Dec 02 '22 09:12 fabpot