php - Symfony2 - Inject a service into SonataAdmin


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 ofSonata/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).




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)

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

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



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...


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


                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:


    # dbal, ...
                connection:       default
                    AcmeDemoBundle: ~
                    AcmeStoreBundle: ~
            company:      # <- setup a second em using the customer connection
                connection:       customer
                    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 )

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 thecompany connection.


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

$builder->add('users', 'entity', array(
    'class'         => 'AcmeCompanyBundle:Company',
    'em'            => '',  // <- non-default em here
    'query_builder' => function(EntityRepository $er) {
        return $er->createQueryBuilder('company')
            ->orderBy('', '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 theEntityRepository $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!

People are also looking for solutions to the problem: php - how to deal with hyphen (-) before node xml xpath


Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.