Symfony2 choice field not working

2019-03-30 23:43发布

问题:

I asked a question here How to use Repository custom functions in a FormType but nobody anwsered, so i did a little digging and advanced a little but i still get this error:

Notice: Object of class Proxies\__CG__\Kpr\CentarZdravljaBundle\Entity\Category 
could not be converted to int in /home/kprhr/public_html/CZ_Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php line 457 

Now this is how my CategoryType looks like:

<?php

namespace Kpr\CentarZdravljaBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Bridge\Doctrine\RegistryInterface;

class CategoryType extends AbstractType
{
    private $doctrine;

    public function __construct(RegistryInterface $doctrine)
    {
        $this->doctrine = $doctrine;
    }
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Kpr\CentarZdravljaBundle\Entity\Category',
            'catID' => null,
        ));
    }
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $someId = $builder->getData()->getId();
        $param = ($someId) ? $someId : 0;
        $catID = $options['catID'];
        $builder->add('name', 'text', array('attr'   =>  array('class' => 'span6')));
        $builder->add('file', 'file', array('image_path' => 'webPath', 'required' => false));
        $builder->add('parent', 'choice', array(
                    'choices' => $this->getAllChildren($catID),
                    'required' => false,
                    'attr'   =>  array('data-placeholder' => '--Izaberite Opciju--'),
                    ));
        $builder->add('tags', 'tag_selector', array(
            'required'  => false,
        ));
        $builder->add('status', 'choice', array(
            'choices'   => array('1' => 'Aktivna', '0' => 'Neaktivna'),
            'required'  => true,
        ));
        $builder->add('queue', 'text', array('attr'   =>  array('class' => 'span3')));
    }
    private function getAllChildren($catID)
    {
        $choices = array();
        $children = $this->doctrine->getRepository('KprCentarZdravljaBundle:Category')->findByParenting($catID);

        foreach ($children as $child) {
            $choices[$child->getId()] = $child->getName();
        }

        return $choices;
    }

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

}

I am accessing the CategoryRepository function findByParenting($parent) from the CategoryType and I am getting the array populated with accurate data back from the function getAllChildren($catID) but the error is there, i think that Symfony framework is expecting an entity field instead of choice field, but dont know how to fix it. I also changet the formCreate call in the controller giving $this->getDoctrine() as an argument to CategoryType():

$form = $this->createForm(new CategoryType($this->getDoctrine()), $cat, array('catID' => $id));

回答1:

Ok i managed to resolve the dilemma. The answer was easy all I had to do is change

$builder->add('parent', 'choice', array(
 'choices' => $this->getAllChildren($catID),
 'required' => false,
 'attr'   =>  array('data-placeholder' => '--Izaberite Opciju--'),
));

to this:

 $builder->add('parent', 'entity', array(
                'class' => 'KprCentarZdravljaBundle:Category',
                'choices' => $this->getAllChildren($catID),
                'property' => 'name',
                'required' => false,
                'attr'   =>  array('data-placeholder' => '--Izaberite Opciju--'),
                ));

And change the getAllChildren(..) function so that it returns objects

private function getAllChildren($catID)
{
    $choices = array();
    $children = $this->doctrine->getRepository('KprCentarZdravljaBundle:Category')->findByParenting($catID);

    foreach ($children as $child) {
        $choices[$child->getId()] = $child->getName();
    }

    return $choices;
}

I changed it to:

private function getAllChildren($catID)
{
    $children = $this->doctrine->getRepository('KprCentarZdravljaBundle:Category')->findByParenting($catID)

    return $children;
}

Lots of thanks to user redbirdo for pointing out the choices option on an entity field.



回答2:

It seems like you are doing something too much complicated.
You are on the right way when you write Symfony framework is expecting an entity field instead of choice field.

To do this, replace:

$builder->add('parent', 'choice', array(
     'choices' => $this->getAllChildren($catID),
     'required' => false,
     'attr'   =>  array('data-placeholder' => '--Izaberite Opciju--'),
));

by:

$builder->add('users', 'entity', array(
    'class' => 'KprCentarZdravljaBundle:Category',
    'property' => 'name',
    'query_builder' => function(EntityRepository $er) use($catID) {
        return $er->findByParenting($catID);
    },
    'required' => false,
    'empty_value' => '--Izaberite Opciju--'
));

(and you don't need getAllChildren($catID) anymore unless used somewhere else)

http://symfony.com/doc/current/reference/forms/types/entity.html