kali
kali

Reputation: 25

Symfony2 - Access of the Repository from Entity

I'm trying to learn Symfony, and I found it don't access the doctrine from the entity.

I created an Entity

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Facility
 *
 * @ORM\Table()
 * @ORM\Entity
 * @ORM\Entity(repositoryClass="AppBundle\Entity\FacilityRepository")
 */
class Facility
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="label", type="string", length=200)
     */
    private $label;

    /**
     * @ORM\OneToOne(targetEntity="Facility")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     */
    private $parent;

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

    /**
     * Set label
     *
     * @param string $label
     * @return Facility
     */
    public function setLabel($label)
    {
        $this->label = $label;

        return $this;
    }

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

    /**
     * Set parent
     *
     * @param \AppBundle\Entity\Facility $parent
     * @return Facility
     */
    public function setParent(\AppBundle\Entity\Facility $parent = null)
    {
        $this->parent = $parent;

        return $this;
    }

    /**
     * Get parent
     *
     * @return \AppBundle\Entity\Facility
     */
    public function getParent()
    {
        return $this->parent;
    }

    public function __toString()
    {
        return $this->label;
    }
}

and for FacilityType.php

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class FacilityType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('parent')
            ->add('label')
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Facility'
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'appbundle_facility';
    }
}

How can I get just the parents in the $builder->add('parent') (dropdown select) and not all the data.

Thanks in advance.

Upvotes: 1

Views: 253

Answers (2)

Ryan
Ryan

Reputation: 5066

It depends on your case. If your filter criteria is fixed, then @b.b3rn4rd's answer is best. If the criteria depends on the current facility then you probably want to use a form event listener. Symfony forms have a fairly powerful architecture, where a single form type is created and then cloned for each instance. The buildForm() method is only called once for each form even if the field type is repeated multiple times on the page. In some cases the field is only rendered once, and that is fine but the safest way is to use a form listener. Rather than adding a generic parent field to the form builder, you are adding a specific field to the form instance.

public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder->add('label');

    $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) {
        $form = $event->getForm();
        /** @var Facility $facility */
        $facility = $event->getData();
        $form->add(
            'parent',
            'entity',
            array(
                'class' => 'AppBundle:Facility',
                'query_builder' => function (FacilityRepository $repository) use ($facility) {
                    return $repository->createQueryBuilder('f')->findParents($facility);
                },
            )
        );
    });
}

Upvotes: 1

b.b3rn4rd
b.b3rn4rd

Reputation: 8840

You don't need to access repository from an entity class. Entities should be plain php objects. If you want to limit options in your dropdown use query_builder property.

$builder->add('parent', 'entity', array(
    'class' => 'AppBundle:Facility',
    'query_builder' => function (EntityRepository $er) {
        return $er->createQueryBuilder('f')
            ->where('/* ... */');
    },
));

Upvotes: 2

Related Questions