简体   繁体   English

Symfony2在bind()之后和check之前插入表单值isValid()

[英]Symfony2 insert form value after bind() and before check isValid()

I want the combination of both fbid and game_id be unique. 我希望fbid和game_id的组合都是独一无二的。 I want to test it with the form->isValid() method. 我想用form-> isValid()方法测试它。 But I don't want to pass this values by hidden input. 但我不想通过隐藏输入传递这个值。

My entity code: 我的实体代码:

/**
 * @ORM\Entity
 * @ORM\Table(name="Member",
 *     uniqueConstraints={
 *         @ORM\UniqueConstraint(columns={"fbid", "game_id"})
 *          })
 * @UniqueEntity(fields={"fbid","game"})
 */
class Member
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Game", inversedBy="members")
     * @ORM\JoinColumn(name="game_id", referencedColumnName="id")
     */
    protected $game;

    /**
     * @ORM\Column(type="string")
     */
    private $fbid;

I try: 我尝试:

if ($request->getMethod() == 'POST') {
    $form->bind($request);
    $member = $form->getData();
    $member->setGame( $this->game );
    $form->setData($member);
    if ($form->isValid()) {

But I have this problem: 但我有这个问题:

You cannot change the data of a bound form 您无法更改绑定表单的数据

Gremo 's solution is good one, but it is not good idea to create global service and listen all POST_BIND events just to handle one form POST_BIND. Gremo的解决方案很好,但创建全局服务并监听所有POST_BIND事件只是为了处理一个表单POST_BIND并不是一个好主意。 It is much cheaper to set this hook only when specified form created. 仅在创建指定表单时设置此挂钩要便宜得多。

Here is my suggestion https://gist.github.com/4167466 这是我的建议https://gist.github.com/4167466

The error tells you that you can't check form validity with isValid() if you changed form data after binding.. 如果您在绑定后更改了表单数据,则错误告诉您无法使用isValid()检查表单有效性。

Why do you need to setGame between binding and validity check ? 为什么需要在绑定和有效性检查之间设置游戏?

You should set associated game before binding your request as following : 您应该在绑定请求之前设置相关游戏,如下所示:

//For creation, you have to initialize a new object
$member = new Member();
$member->setGame( $this->game );

$form = $this->createForm(new FormType(), $member)->getForm();

if ($request->getMethod() == 'POST') {

    $validator = $this->get('validator');
    $errors = $validator->validate($member);

    if (count($errors) > 0) {
        return new Response(print_r($errors, true));
    } else {
        // persist entity ...
    }

    $form->bind($request);
    if ($form->isValid()) {

Make a service and listen to the FormEvents::POST_BIND event. 创建服务并侦听FormEvents::POST_BIND事件。 In your onPostBind() you can get the values to check, and add an error if necessary: onPostBind()您可以获取要检查的值,并在必要时添加错误:

class AddGameValidation implements EventSubscriberInterface
{   
    /**
     * {@inheritDoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
            FormEvents::POST_BIND => 'onPostBind',
        );
    }

    /**
     * @param \Symfony\Component\Form\Event\DataEvent $event
     */
    public function onPostBind(DataEvent $event)
    {
        $form = $event->getForm();

        // Get the data

        if(false === $condition) {
            $form->addError(new FormError('Some message'));
        }
    }
}

You could also use an event subscriber in your form, and listen to the FormEvents::POST_BIND event perhaps. 您也可以在表单中使用事件订阅者,也许可以收听FormEvents :: POST_BIND事件。 More on using event subscriber: http://symfony.com/doc/2.0/cookbook/form/dynamic_form_generation.html 有关使用事件订阅者的更多信息: http//symfony.com/doc/2.0/cookbook/form/dynamic_form_generation.html

And a similar stackoverflow question: Which is the suggested place to modify binded form data in Symfony? 还有一个类似的stackoverflow问题: 在Symfony中修改绑定表单数据的建议位置是哪个?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM