Tigran
Tigran

Reputation: 653

Symfony creating choice from entity in form type

I have a lot of Categories in database.

Here is Category Entity

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="categories")
 */
class Category
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Category")
     */
    protected $rootCategory;

    /**
     * @ORM\Column(type="text")
     */
    protected $name;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Category
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set rootCategory
     *
     * @param \AppBundle\Entity\Category $rootCategory
     *
     * @return Category
     */
    public function setRootCategory(\AppBundle\Entity\Category $rootCategory = null)
    {
        $this->rootCategory = $rootCategory;

        return $this;
    }

    /**
     * Get rootCategory
     *
     * @return \AppBundle\Entity\Category
     */
    public function getRootCategory()
    {
        return $this->rootCategory;
    }
}

I want to get all categories in my edit form

EditFormType:

namespace AppBundle\Form\Type;

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

class EditPhotoFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $categoryController = new CategoryController();

        $builder->add('title', 'text');
    $builder->add('description', 'textarea');
        $builder->add('category', EntityType::class, array(
            'class' => 'AppBundle:Category',
            'choices' => $categoryController->getCategories(),
        ));
    }

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

getCategories() 

public function getCategories() {
        $em = $this->getDoctrine()->getManager();

    return $em->getRepository('AppBundle:Category')->findAll();
    }

I am getting next error:

Error: Call to a member function has() on null

Thats because there is not Doctrine in controller object. Where should i get Doctrine and Repository in this case?
How should i do it correct way?

Upvotes: 0

Views: 15711

Answers (1)

Terenoth
Terenoth

Reputation: 2598

First, you should NEVER instantiate any Controller class yourself. Controller classes are used by Symfony's Kernel to handle a request, and they are loaded automatically with dependencies to do so.

Right here, you don't even need to require the EntityManager in your FormType, because EntityType has a built-in option query_builder to do what you need:

$builder->add('category', EntityType::class, array(
    'class' => 'AppBundle:Category',
    'query_builder' => function (EntityRepository $er) {
         return $er->createQueryBuilder('c');
    },
);

This should do the trick. (check here for more details)

However, if one day you really need to import a dependancy inside your Form (whether it is EntityManager or another service), here's how you should do:

A. import the given dependency in your constructor:

private $dependency;

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

B. Declare your Form as a Service, with your dependency's id as argument:

<service id="app.form.type.edit_photo"
         class="AppBundle\Form\Type\EditPhotoFormType">
    <tag name="form.type" />
    <argument type="service" id="app.dependencies.your_dependency" />
</service>

Then use $this->dependency in your Form wherever you need.

Hope this helps! :)

Upvotes: 11

Related Questions