-->

Silex + Doctrine2 ORM + Dropdown (EntityType)

2020-03-04 12:47发布

问题:

I have a controller that renders a form that is suppose to have a dropdown with titles mapped against a client_user entity. Below is code I use in my controller to create the form:

$builder = $this->get(form.factory);
$em = $this->get('doctrine.entity_manager');

$form = $builder->createBuilder(new ClientUserType($em), new ClientUser())->getForm();

Below is my ClientUserType class with a constructor that I pass the entity manager on:

<?php

  namespace Application\Form\Type;

  use Symfony\Component\Form\AbstractType;
  use Symfony\Component\Form\FormBuilderInterface;
  use Symfony\Bridge\Doctrine\Form\Type\EntityType;

 class ClientUserType extends AbstractType
 { 
   protected $entityManager;

   public function __construct($entityManager)
   {
      $this->entityManager = $entityManager;
    }

   public function buildForm(FormBuilderInterface $builder, array $options)
   {
     $builder
       ->add('title', EntityType::class, array(
         'class' => '\\Application\\Model\\Entity\\Title',
         'em' => $this->entityManager
       ))
      ->add('name')
      ->add('surname')
      ->add('contact')
      ->add('email');
    }

  public function getName()
  {
    return 'client_user_form';
   }
}

I keep on getting this catchable fatal error below and have no idea what I need to do in order to get a dropdown with titles from a database with doctrine.

Catchable fatal error: Argument 1 passed to Symfony\Bridge\Doctrine\Form\Type\DoctrineType::__construct() must be an instance of Doctrine\Common\Persistence\ManagerRegistry, none given, called in D:\web\playground-solutions\vendor\symfony\form\FormRegistry.php on line 90 and defined in D:\web\playground-solutions\vendor\symfony\doctrine-bridge\Form\Type\DoctrineType.php on line 111

Reading from that error I have no idea where I need to create a new instance of ManagerRegistry registry as it appears that the entity manager does not work. I am also thinking perhaps I need to get the ManagerRegistry straight from the entity manager itself.

Can someone please help explain the simplest way to get this to work? What could I be missing?

回答1:

Seems that doctrine-bridge form component is not configured.
Add class

namespace Your\Namespace;

use Doctrine\Common\Persistence\AbstractManagerRegistry;
use Silex\Application;

class ManagerRegistry extends AbstractManagerRegistry
{
    protected $container;

    protected function getService($name)
    {
        return $this->container[$name];
    }

    protected function resetService($name)
    {
        unset($this->container[$name]);
    }

    public function getAliasNamespace($alias)
    {
        throw new \BadMethodCallException('Namespace aliases not supported.');
    }

    public function setContainer(Application $container)
    {
        $this->container = $container;
    }
}

and configure doctrine-bridge form component

$application->register(new Silex\Provider\FormServiceProvider(), []);

$application->extend('form.extensions', function($extensions, $application) {
    if (isset($application['form.doctrine.bridge.included'])) return $extensions;
    $application['form.doctrine.bridge.included'] = 1;

    $mr = new Your\Namespace\ManagerRegistry(
        null, array(), array('em'), null, null, '\\Doctrine\\ORM\\Proxy\\Proxy'
    );
    $mr->setContainer($application);
    $extensions[] = new \Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension($mr);

    return $extensions;
});

array('em') - em is key for entity manager in $application



回答2:

For others that may find this: If you want to use the EntityType and you're not using a framework at all, you need to add the DoctrineOrmExtension to your FormFactoryBuilder like so:

$managerRegistry = new myManagerRegistry(
    'myManager',
    array('connection'),
    array('em'),
    'connection',
    'em',
    \Doctrine\ORM\Proxy\Proxy::class
);

// Setup your Manager Registry or whatever...

$doctrineOrmExtension = new DoctrineOrmExtension($managerRegistry);
$builder->addExtension($doctrineOrmExtension);

When you use EntityType, myManagerRegistry#getService($name) will be called. $name is the name of the service it needs ('em' or 'connection') and it needs to return the Doctrine entity manager or the Doctrine database connection, respectively.



回答3:

In your controller, try to call the service like that:

$em = $this->get('doctrine.orm.entity_manager');

Hope it will help you.

Edit:

Sorry, I thought you was on Symfony... I have too quickly read...