简体   繁体   中英

How to use a resolved target entity in a Symfony2 form type?

There is src/AppBundle/Entity/ShoppingCart/Order.php which resolve OrderInterface and it works fine with Doctrine.

If try use it in form 'class' => OrderInterface::class then I got an error:

Class "ShoppingCartBundle\\Entity\\OrderInterface" seems not to be a managed Doctrine entity. Did you forget to map it?"

Of course it is possible define 'class' => Order::class directly, but in that case loses advantages of resolve target entities configs.

src/ComplaintsBundle/Form/Type/ComplaintType.php

...
public function buildForm(FormBuilderInterface $builder, array $options)
{
   $builder
        ->add('order', EntityType::class,
            array(
                'required'    => true,
                'class'       => OrderInterface::class,
                'property'    => 'id',
            )
        );
}
...

app/config/config.yml

orm:
    auto_generate_proxy_classes: %kernel.debug%
    auto_mapping: true
    resolve_target_entities:
        ShoppingCartBundle\Entity\OrderInterface: AppBundle\Entity\ShoppingCart\Order

Inject doctrine.dbal.connection.event_manager in your form as evm and EntityManager as em .

After that you could try something like this:

private function resolveClass(string $className): string
{
    $eventArgs = new OnClassMetadataNotFoundEventArgs($className, $this->em);
    $this->evm->dispatchEvent(Events::onClassMetadataNotFound, $eventArgs);

    $metadata = $eventArgs->getFoundMetadata();
    if ($metadata === null) {
        throw new InvalidArgumentException("Failed to resolve class $className");
    }

    return $metadata->getName();
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
   $builder
        ->add('order', EntityType::class,
            array(
                'required'    => true,
                'class'       => $this->resolveClass(OrderInterface::class),
                'property'    => 'id',
            )
        );
}

I didn't actually test this, just looked at how Doctrine does this .

Real class name is resolved during metadata loading. To get real class name by interface metadata loading should be triggered. This may be achieved with next code

$entityManager = $managerRegistry->getManager();
$metadata = $entityManager->getClassMetadata(OrderInterface::class);
$realClassName = $metadata->getName();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM