0

I'm fairly new to Symfony and trying to get to grips with the platform. I have managed to install Sonata CMF, FOS User Bundle, and the Sonata User Bundle. I have got to the point where I can create users, and other entities through the out of the box CMS.

I'm now trying to modify elements of the create user form for the project I'm working on. One of the things I'm currently struggling with is adding a drop down list of countries to select where the user is from.

I have managed to get the 'choice' option into the form. The part I'm struggling with is getting the countries (stored in my db) into an array to then pass to that choice. So currently I have this:

<?php

namespace Application\Sonata\UserBundle\Admin\Model;

use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\UserBundle\Admin\Model\UserAdmin as BaseType;

use MyApp\CmsBundle\Entity\Country;

class UserAdmin extends BaseType
{   
    /**
     * {@inheritdoc}
     */
    protected function configureFormFields(FormMapper $formMapper)
    {
        // TODO: get countries from DB instead of hardcoding here
        $countries = array(
            1 => 'Country 1',
            2 => 'Country 2',
            3 => 'Country 3',
            4 => 'Country 4',
            5 => 'Country 5',
        );

        $formMapper
            ->with('Profile')
                ->add('username', 'text')
                ->add('email')
                ->add('firstname', null, array('label' => 'form.firstname', 'required' => true, 'translation_domain' => 'SonataUserBundle'))
                ->add('lastname', null, array('label' => 'form.lastname', 'required' => true, 'translation_domain' => 'SonataUserBundle'))
            ->end()
            ->with('Address')
                ->add('line1', 'text', array('label' => 'form.line1', 'required' => false, 'translation_domain' => 'SonataUserBundle'))
                ->add('line2', 'text', array('label' => 'form.line2', 'required' => false, 'translation_domain' => 'SonataUserBundle'))
                ->add('city', 'text', array('label' => 'form.city', 'required' => true, 'translation_domain' => 'SonataUserBundle'))
                ->add('postcode', 'text', array('label' => 'form.postcode', 'required' => false, 'translation_domain' => 'SonataUserBundle'))
                ->add('country', 'choice', array('label' => 'form.country', 'required' => true, 'translation_domain' => 'SonataUserBundle', 'choices' => $countries))
            ->end()
        ;

        // etc...
    }

I've been Googling for a while now and the only thing I keep seeing is to use $em = $this->getDoctrine()->getManager(); but this only appears to work in a Controller class context.

So to summarise, I wish to get the $countries array from the database instead of hardcoding it.

UPDATE

I've just realised that for the case of countries, Symfony has a choice variation that can be used out of the box: http://symfony.com/doc/current/book/forms.html#choice-fields

->add('country', 'country', array('label' => 'form.country', 'required' => true, 'translation_domain' => 'SonataUserBundle'))

I would however still be interested in knowing how I can retrieve entity records in classes other than a Controller.

diggersworld
  • 12,770
  • 24
  • 84
  • 119
  • Since you're using `Sonata`, there is a registered form type named `sonata_type_model` almost identical to Symfony's form type `entity`, which would pretty much allow you to do what you've asked. – Artamiel Aug 24 '15 at 18:37

2 Answers2

0

I would however still be interested in knowing how I can retrieve entity records in classes other than a Controller.

You can declare any of your classes as service, than in you service definition in services.xml (according to best practices xml formatt prefer) you need to pass <argument type="service" id="doctrine">, than in service class assign it to some proerty in constructor and declare getter for that property, that use it like $this->getDoctrine()->getRepostitory() .... So I hope I explain base workflow. For more info look to documentation.

nowiko
  • 2,507
  • 6
  • 38
  • 82
0

This is a bad practice to use an entity inside another one. However, you can inject in constructor the entity manager like this:

<?php

namespace Application\Sonata\UserBundle\Admin\Model;

use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\UserBundle\Admin\Model\UserAdmin as BaseType;

use MyApp\CmsBundle\Entity\Country;

class UserAdmin extends BaseType
{
    private $em;

    public function __contruct($em)
    {
        parent::__construct();
        $this->em = $em;
    }
}

Then, in your entity, you can call your repository like this, an example to retrieve all the countries:

$countries = $this->em->getRepository('YourBundle:YourEntity')->findAll();
Sylvain Martin
  • 2,365
  • 3
  • 14
  • 29