我想生成包含用户名列表的页面,并且每个用户旁边都有我想要激活/停用此用户的按钮。
我当然可以在控制器中创建用户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只会生成第一个表单而忽略休息。
知道如何处理吗?或者我的表单/按钮方法不正确,我应该只使用链接?
答案 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]) }}