首页 文章

Symfony:无法处理表单请求

提问于
浏览
0

我有3种表单类型(SearchForm - SearchField - SearchFieldType),每一种都包含下一个,如下所示:

SearchFormType

<?php

namespace AppBundle\Form;

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

class SearchFormType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('fields', 'collection', array('type' => new SearchFieldType(),
                                                  'allow_add'    => true,
                                                  'allow_delete' => true,
                                                  'by_reference' => false))
            ->add('submit', 'submit', array('label' => "Buscar"))
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\SearchForm',
            'allow_extra_fields' => true,
            'csrf_protection' => false,
            'validation_groups' => false,
        ));
    }

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

SearchFieldType

<?php

namespace AppBundle\Form;

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

class SearchFieldType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'hidden')
            ->add('slug', 'hidden')
            ->add('value')
            ->add('choices')
            ->add('type', new SearchFieldTypeType())
            ->add('actionFilter')
            ->add('actionHighlight')
            ->add('actionShow')
        ;
    }

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

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

SearchFieldTypeType

<?php

namespace AppBundle\Form;

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

use AppBundle\Entity\SearchOperator;

class SearchFieldTypeType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $entity = $builder->getData();

        $builder
            ->add('name', 'hidden')
            ->add('operators', 'entity', array('class' => 'AppBundle:SearchOperator',
                                               'multiple' => false,
                                               'expanded' => false))
        ;
    }

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

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

表单呈现正确,但当我提交并尝试做 $form->handleRequest($request) 时,我得到一个例外:

属性“运算符”和方法“addOperator()”/“removeOperator()”,“setOperators()”,“operator()”,“__ set()”或“__call()”都不存在“AppBundle \ Entity \ SearchFieldType”类中的公共访问

事实并非如此,因为这些方法存在且工作正常:

AppBundle\Entity\SearchFieldType

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\SearchOperator;
/**
 * SearchField
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class SearchFieldType
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=100, nullable=true)
     */
    private $name;

    /**
     * @ORM\ManyToMany(targetEntity="SearchOperator", cascade={"persist", "remove"})
     * @ORM\JoinTable(
     *      joinColumns={@ORM\JoinColumn(name="type_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="operator_id", referencedColumnName="id")}
     *      )
     **/
   private $operators;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->operators = new \Doctrine\Common\Collections\ArrayCollection();
    }

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

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

        return $this;
    }

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

    /**
     * Add operator
     *
     * @param SearchOperator $operator
     *
     * @return SearchFieldType
     */
    public function addOperator(SearchOperator $operator)
    {
        $this->operators[] = $operator;

        return $this;
    }

    /**
     * Remove operator
     *
     * @param SearchOperator $operator
    */
    public function removeOperator(SearchOperator $operator)
    {
        $this->operators->removeElement($operator);
    }

    /**
     * Get operator
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getOperators()
    {
        return $this->operators;
    }

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

}

Stack trace

in vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php at line 460  +
at PropertyAccessor ->writeProperty (object(SearchFieldType), 'operators', object(SearchOperator))
in vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php at line 104  +
at PropertyAccessor ->setValue (object(SearchFieldType), object(PropertyPath), object(SearchOperator))
in vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php at line 93  +
at PropertyPathMapper ->mapFormsToData (object(RecursiveIteratorIterator), object(SearchFieldType))
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 633  +
at Form ->submit (array('operators' => '156', 'name' => 'string'), true)
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 577  +
at Form ->submit (array('type' => array('operators' => '156', 'name' => 'string'), 'value' => 'felipe', 'name' => 'Nombre', 'slug' => 'nombre'), true)
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 577

EDIT

Controller Code

$searchFormEntity = new SearchForm();
        $searchFormWithValues = $this->createForm(new SearchFormType(), $searchFormEntity, array(
                                        'action' => $this->generateUrl('candidato'),
                                        'method' => 'POST'
                                    ));
        $searchFormWithValues->add('submit', 'submit', array('label' => 'Buscar'));
        $searchFormWithValues->handleRequest($request);

1 回答

  • 0

    那么你有一个ManyToMany关系,所以将 operators 字段作为集合是有意义的 . 但是,您将其定义为实体,因此现在表单需要 setOperatorsgetOperators 方法,因为 entity 意味着ManyToOne或OneToOne关系 . 我认为你需要更改 SearchFieldTypeType 类中的语句,如果你想保持ManyToMany关系,那么在 SearchFormType 中添加 operators 属性与 fields 之前的相同 .

相关问题