Pregunta

I'd like to get a db connection from within a SonataAdmin class' configureFormFields()

For sure this doesn't work

protected function configureFormFields(FormMapper $formMapper)
{
    $mycnx = $this->get('doctrine.dbal.mycnx_connection');
//...

I need it for my extension of Sonata/UserBundle/Admin/Entity/UserAdmin

How can I call a service from this class ?


The context:

I need to have a choice field (company) whose choices come from an other connection (from a stored procedure).

¿Fue útil?

Solución

What you have to do is:

  • create a service getting the connection injected to get companies from
  • create a custom field
  • register it as a service and inject the first service in constructor
  • supply the choices to the field

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
    #...
    

Then you'll be able to simply use it from configureFormFields() with:

->add('company', 'company')

Otros consejos

How to use a second dbal connection to supply choices for a form field

You can actually have this a little easier and with less code involved...


Configuration

Your configuration looks somewhat like this if you already have setup a second connection doctrine.dbal.mycnx_connection.

app/config/config.yml

doctrine:
    dbal:
        connections:
            default:
                driver:   "%database_driver%"
                host:     "%database_host%"
                port:     "%database_port%"
                dbname:   "%database_name%"
                user:     "%database_user%"
                password: "%database_password%"
                charset:  UTF8
            mycnx_connection:                       # credentials for 2nd connection
                driver:   "pdo_mysql"
                host:     "%database_host_2%"
                port:     "%database_port_2%"
                dbname:   "%database_name_2%"
                user:     "%database_user_2%"
                password: "%database_password_2%"
                charset:  UTF8

        default_connection:   default

Now if you haven't already ... configure a second entity/document manager that is using this connection:

app/config/config.yml

doctrine:
    # dbal, ...
    orm:
        entity_managers:
            default:
                connection:       default
                mappings:
                    AcmeDemoBundle: ~
                    AcmeStoreBundle: ~
            company:      # <- setup a second em using the customer connection
                connection:       customer
                mappings:
                    AcmeCompanyBundle: ~

        default_entity_manager:   default

... this may look like much to this point but it really isn't ... as everything described above should already be present in your application if you have a second dbal connection.

I just wanted to make it really obvious for others.

You now have two services available that reflect your two entity-managers:

  • @doctrine.orm.entity_manager.default ( ... which is aliased to @doctrine.orm.entity_manager )
  • @doctrine.orm.entity_manager.company

The Entity Field-Type

Now all that's left for you to do is use the entity field-type and configure it to use the entity-manager using the company connection.

Acme/YourBundle/Form/Type/YourType.php

use Doctrine\ORM\EntityRepository;
// ...

$builder->add('users', 'entity', array(
    'class'         => 'AcmeCompanyBundle:Company',
    'em'            => 'doctrine.orm.entity_manager.company',  // <- non-default em here
    'query_builder' => function(EntityRepository $er) {
        return $er->createQueryBuilder('company')
            ->orderBy('company.name', 'ASC');
    },
));

That's it ... while you may still want to make your form a service ... you don't have to inject anything.

You don't need to use the EntityRepository $er part in 'query_builder' ... you can just return a QueryBuilder instance if you don't want to create the repository for your companies.


Just my few cents ... happy coding!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top