Symfony: unable to handle request in form

一曲冷凌霜 提交于 2020-01-07 09:04:27

问题


I have 3 form types (SearchForm - SearchField - SearchFieldType), each one including next like this:

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';
    }
}

The form renders properly, but when I submit and try to do $form->handleRequest($request) I get an exception:

Neither the property "operators" nor one of the methods "addOperator()"/"removeOperator()", "setOperators()", "operators()", "__set()" or "__call()" exist and have public access in class "AppBundle\Entity\SearchFieldType"

That's not true actually, as those methods exist and work correctly:

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:


Well you have a ManyToMany relation, so it would make sense to have the operators field be a collection. However you defined it as an entity, so now the form expects to have the setOperators and getOperators methods as entity implies a ManyToOne or OneToOne relationship. I think you need to change the statement in the class SearchFieldTypeType where adding the operators attribute to be the same as what you did before for fields in SearchFormType if you want to keep the ManyToMany relationship.



来源:https://stackoverflow.com/questions/34136594/symfony-unable-to-handle-request-in-form

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!