Symfony 2:多个表单生成对象列表

时间:2015-05-08 13:53:38

标签: php forms symfony

我想生成包含用户名列表的页面,并且每个用户旁边都有我想要激活/停用此用户的按钮。

我当然可以在控制器中创建用户ID和GET方法的链接,这将在单击链接时执行操作。据我所知,由于安全问题,不建议这样做。因此,我希望有一些表单和按钮来向PUT路由提交请求以改变用户状态,而不是指向要执行操作的路由的链接。

问题:如何根据Doctrine返回的用户列表生成此类表单(按钮)?

用于在用户个人资料中创建表单/按钮的表单代码:

    /**
 * Creates a form to activate/deactivate a User entity by id.
 *
 * @param mixed $id The entity id
 *
 * @return \Symfony\Component\Form\Form The form
 */
private function createActivationDeactivationForm($id)
{
    return $this->createFormBuilder()
        ->setAction($this->generateUrl('user_activate', array('id' => $id)))
        ->setMethod('PUT')
        ->add('submit', 'submit', array('label' => 'Activate/Deactivate'))
        ->getForm()
    ;
} 

用于用户个人资料的控制器代码:

    /**
 * @Route("/user/{id}", name="user_show")
 * @Method("GET")
 * @Template()
 */
public function showUserAction($id)
{
    $em = $this->getDoctrine()->getManager();

    $user = $em->getRepository('TestUserBundle:User')->find($id);

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

    $deleteForm = $this->createDeleteForm($id);                
    $activateForm = $this->createActivationDeactivationForm($id);                

    return array(
        'user' => $user,
        'delete_form' => $deleteForm->createView(),
        'activate_form' => $activateForm->createView(),

    );
}

控制器PUT方法,用于从用户配置文件执行操作:

    /**
 * Activate a user.
 *
 * @Route("/{id}", name="user_activate")
 * @Method("PUT")
 */
public function activateAction(Request $request, $id)
{
    $form = $this->createActivationDeactivationForm($id);
    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $user = $em->getRepository('TestUserBundle:User')->find($id);

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

        $current_user_activity_flag = $user->getActive();

        $user->setActive(abs($current_user_activity_flag-1));

        $em->persist($user);
        $em->flush();
    }

    return $this->redirect($this->getRequest()->headers->get('referer'));
} 

用于用户列表的控制器代码:

    /**
 * @Route("/users", name="users_list")
 * @Method("GET")
 * @Template()
 */
public function listUsersAction()
{
    $em = $this->getDoctrine()->getManager();

    $users = $em->getRepository('TestUserBundle:User')->findExistingUsers();

    //$deleteForm = $this->createDeleteForm($id);                
    //$activateForm = $this->createActivationDeactivationForm($id);                

    return array(
        'users' => $users,
        //'delete_form' => $deleteForm->createView(),
        //'activate_form' => $activateForm->createView(),

    );
}

我无法将ID传递给表单,就像我从配置文件中操作一样,因为每个用户都有不同的ID,而Symfony只会生成第一个表单而忽略休息。

知道如何处理吗?或者我的表单/按钮方法不正确,我应该只使用链接?

1 个答案:

答案 0 :(得分:0)

我发现解决方案有效但我不确定它是否符合最佳做法。

不是在控制器中传递一个表单对象,而是使用基于用户ID的键生成它们的数组。在TWIG模板中循环遍历数组时,我使用用户ID来引用为当前用户创建的表单对象。

有问题的控制器中提到的用户列表应该如下所示:

    /**
 * @Route("/users", name="users_list")
 * @Method("GET")
 * @Template()
 */
public function listUsersAction()
{
    $em = $this->getDoctrine()->getManager();

    $users = $em->getRepository('PSUserBundle:User')->findExistingUsers();

    $activate_forms = array();
    $delete_forms = array();

    foreach($users as $user)
    {

        $activate_forms[$user->getId()] = $this->createActivationDeactivationForm($user->getId())->createView();
        $delete_forms[$user->getId()] = $this->createDeleteForm($user->getId())->createView();
    }

    return array(
        'users' => $users,
        'delete_forms' => $delete_forms,
        'activate_forms' => $activate_forms,

    );
}

......并且在foreach中以TWIG形式应该像这样提到:

    {{ form_start(activate_forms[user.id], {'attr': {'novalidate': 'novalidate'}}) }}

        {% if user.active %}
            {{ form_widget(activate_forms[user.id].submit, {'attr': {'class': 'btn btn-xs btn-warning btn-block'}, 'label' : 'Deactivate'}) }}
        {% else %}
            {{ form_widget(activate_forms[user.id].submit, {'attr': {'class': 'btn btn-xs btn-success btn-block'}, 'label' : 'Activate'}) }}
        {% endif %}


     {{ form_end(activate_forms[user.id]) }}