Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Attribute to set type_map instead of config #136

Open
gabplch opened this issue Apr 25, 2024 · 3 comments
Open

Use Attribute to set type_map instead of config #136

gabplch opened this issue Apr 25, 2024 · 3 comments

Comments

@gabplch
Copy link

gabplch commented Apr 25, 2024

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;
}
@gabplch
Copy link
Author

gabplch commented Apr 25, 2024

If this case is ok for you, I can make PR, when will have some free time

@dunglas
Copy link
Owner

dunglas commented Apr 25, 2024

Good idea. PR welcome!

@crazy-weasel
Copy link

crazy-weasel commented Sep 28, 2024

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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants