Symfony2 - 使用查询构建器进行表单验证 - 值永远不会有效

时间:2013-06-03 12:29:06

标签: forms symfony doctrine-orm query-builder

我有两个实体“会议”和“Slot”与one2many关系。

我有一个表单来更新会议(只是为了更改时间段),我想只显示空闲插槽,所以我创建了一个query_ builder。它适用于创建,但对于更新,始终存在验证错误(此值无效)。

这是我的代码:

控制器

public function editAction($id)
{
$em = $this->getDoctrine()->getManager();

$entity = $em->getRepository('NfidBusinessMeetingBundle:Meeting')->find($id);

if (!$entity) {
    throw $this->createNotFoundException('Unable to find Meeting entity.');
}

$editForm = $this->createForm(new UpdateMeetingType($entity->getUserA(),$entity->getUserB()), $entity);

if ($this->getRequest()->isMethod('POST')) {
    $editForm->bind($this->getRequest());

//            var_dump($editForm->getData() );

    if ($editForm->isValid()) {
        $entity->setDeleted(0);
        $entity->setPending(1);
        $entity->setValidated(0);
        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('meeting_front'));
    }
}
return $this->render('NfidBusinessMeetingBundle:MeetingFront:edit.html.twig', array(
    'entity' => $entity,
    'edit_form' => $editForm->createView(),
));
}

表单构建器

public function __construct($userA = null, $userB = null)
{
    $this->userA = $userA;
    $this->userB = $userB;

}
public function buildForm(FormBuilderInterface $builder, array $options)
{
//        die(var_dump($options));
    $users[] = $this->userA;
    $users[] = $this->userB;
    $builder
        ->add('slot', 'entity',
            array(
                'class' => 'NfidBusinessMeetingBundle:Slot',
                'query_builder' => function(SlotRepository $cr) use ($users) {
                    return $cr->findAllFreeSlotByUsers($users);
                }
            )
        );
 }

存储库

public function findAllFreeSlotByUsers(array $users){


    $subquery = $this->createQueryBuilder('query1');
    $subquery->select('s')
        ->from('NfidBusinessMeetingBundle:Meeting', 'm')
        ->leftJoin('m.slot', 's')
        ->leftJoin('m.userA', 'uA')
        ->leftJoin('m.userB', 'uB')
        ->where('m.userA = :userA')
        ->orWhere('m.userA = :userB')
        ->orWhere('m.userB = :userA')
        ->orWhere('m.userB = :userB')
        ->andWhere('m.validated = 1');

    $query = $this->createQueryBuilder('query');
    $query->select('s2')
        ->from('NfidBusinessMeetingBundle:Slot', 's2')
        ->where($query->expr()->notIn('s2.id', $subquery->getDQL()))
        ->setParameters(array('userA' => $users[0]->getId(), 'userB' => $users[1]->getId()));

    return $query;

}

有人可以帮助我吗?

编辑:如果这样做就可以了

public function buildForm(FormBuilderInterface $builder, array $options)
{
//        die(var_dump($options));
    $users[] = $this->userA;
    $users[] = $this->userB;
    $builder
        ->add('slot');
 }

===========================编辑=================== =================

我试过这个

public function findAllFreeSlotByUsers(array $users){


    $subquery = $this->createQueryBuilder('query1');
    $subquery->select('s')
        ->from('NfidBusinessMeetingBundle:Meeting', 'm')
        ->leftJoin('m.slot', 's')
        ->leftJoin('m.userA', 'uA')
        ->leftJoin('m.userB', 'uB')
        ->where('m.userA = :userA')
        ->orWhere('m.userA = :userB')
        ->orWhere('m.userB = :userA')
        ->orWhere('m.userB = :userB')
        ->andWhere('m.validated = 1');

    $query = $this->createQueryBuilder('query');
    $query->select('s2')
        ->from('NfidBusinessMeetingBundle:Slot', 's2')
        ->where(
            $query->expr()->orx(
                $query->expr()->notIn('s2.id', $subquery->getDQL()),
                $query->expr()->eq('s2.id', $users[2]->getId())
            )

        )
        ->setParameters(array('userA' => $users[0]->getId(), 'userB' => $users[1]->getId()));

    return $query;

}

public function buildForm(FormBuilderInterface $builder, array $options)
{
//        die(var_dump($options));
    $users[] = $this->userA;
    $users[] = $this->userB;
    $users[] = $builder->getData();

    if ($this->userConnected == User::TYPE_RESSOURCE ) {
        $builder
            ->add('slot', 'entity',
                array(
                    'class' => 'NfidBusinessMeetingBundle:Slot',
                    'query_builder' => function(SlotRepository $cr) use ($users) {
                        return $cr->findAllFreeSlotByUsers($users);
                    }
                )
            )

它总是一样的错误

string'slot:     错误:Cette valeur n'est pas valide。

1 个答案:

答案 0 :(得分:0)

<强>更新:

插入此代码并输出结果:

editAction:

var_dump($entity->getSlot()->getId());
$editForm = $this->createForm(new UpdateMeetingType($entity->getUserA(),$entity->getUserB()), $entity);

buildForm:

'query_builder' => function(SlotRepository $cr) use ($users) {
     $query = $cr->findAllFreeSlotByUsers($users);
     $results = $query->getQuery()->getResult();
     foreach ($results as $result) {
         var_dump($result->getId());
     }
     die;
}

试试这个:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $data = $builder->getData();
    $users[] = $this->userA;
    $users[] = $this->userB;
    $builder
        ->add('slot', 'entity',
            array(
                'class' => 'NfidBusinessMeetingBundle:Slot',
                'query_builder' => function(SlotRepository $cr) use ($users) {
                    return $cr->findAllFreeSlotByUsers($users, $data->getSlot());
                }
            )
        );
 }

SlotRepositoryslot_id是您从实体类型

传递的第二个参数
$query = $this->createQueryBuilder('query');      
$query->select('s2')
->from('NfidBusinessMeetingBundle:Slot', 's2')
->where(
        $query->expr()->orx(
                $query->expr()->notIn('s2.id', $subquery->getDQL()),
                $query->expr()->eq('s2.id', $slot_id)
        )

)
->setParameters(array('userA' => $users[0]->getId(), 'userB' => users[1]->getId()));

当然,如果插槽为空等,您可能需要进行一些测试。

您的问题可能

我们假设NEW会面。这是一个免费插槽列表:

Slot 1,
Slot 2,
Slot 3,

您选择Slot 2。在编辑时,因为它被使用,这是空闲插槽列表:

Slot 1,
Slot 3

由于Slot 2不在列表中,因此您的选择无效。