doctrine-json-odm
doctrine-json-odm copied to clipboard
Use Attribute to set type_map instead of config
In new Symfony version a lot of configs are migrationg to attributes. What about to make smae this in this bundle?
E.g. wa have POPO model FooBar:
#[TypeMap('foo_bar')]
class FooBar {
private string $someProperty;
}
If this case is ok for you, I can make PR, when will have some free time
Good idea. PR welcome!
Hi :)
I implemented basic support for attributes in one of my projects, with a custom compiler pass.
In my implementation I ignore the type_map and only use my own attribute, but for the general case I think it's best to merge these two. It could be useful, when some of the classes are not editable (e.g. because they are from a library,..)
Do you have any thoughts on that?
Maybe just like this:
$typeMap = array_merge($config['type_map'] ?? [], $this->loadTypeMapFromAttributes($container));
if ($typeMap) {
$container->getDefinition('dunglas_doctrine_json_odm.type_mapper')->addArgument($config['type_map']);
} else {
$container->removeDefinition('dunglas_doctrine_json_odm.type_mapper');
}
The attribute could be just a simple one with only one property called type, and for the loading:
private function loadTypeMapFromAttributes(ContainerBuilder $container): array
{
$typeMap = [];
foreach ($container->getDefinitions() as $id => $definition) {
$class = $container->getReflectionClass($definition->getClass(), false);
if ($class) {
$typeMapAttr = $class->getAttributes(TypeMap::class);
$typeMapAttrCount = count($typeMapAttr);
if ($typeMapAttrCount === 1) {
$typeMapAttr = $typeMapAttr[0]->newInstance();
$typeMap[$typeMapAttr->name] = $definition->getClass();
}
elseif ($typeMapAttrCount > 1) {
throw new \Exception('only one TypeMap-attribute is allowed on class ' . $definition->getClass());
}
}
}
return $typeMap;
}
Greetings :)