Symfony 4 - 在持久化之前比较两个对象?



我有一个Symfony 4项目。 在我的控制器中,我有一个操作来编辑数据库中的对象:

/**
* Editer un groupe
* 
* @Route("/admin/validation/{id}", name="admin_validation_edit")
*
* @param GroupeValidateurs $groupeValidateurs
* @return void
*/
public function edit(GroupeValidateurs $groupeValidateurs, Request $request)
{

$form = $this->createForm(GroupeValidateursType::class, $groupeValidateurs);
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
//persist and flush in database
}

但是当我的表格被提交时,我想比较我的旧对象和我的新对象,以做出一些行动。

为此,我使用了一个会话:

$session = $this->get('session');
if (!$session->has('groupe')) {
$session->set('groupe', $groupeValidateurs);
}

当表格提交并有效时,我会将其删除。

它可以工作,但它是不正确的,因为,如果我进入一个编辑页面与一些groupeValidateur,紧接着,我进入另一个groupeValidateur的另一个编辑页面,我的会话变量将包含我以前的groupeValidateur。

请问我可以使用哪种解决方案?

$form->handleRequest($request)你的对象$groupeValidateurs仍然是原始的。

如果您想保留一些信息,有几种选择,其中非常简单明了:

处理外部对象和表单组件外部:

如果我理解正确,您只想阻止添加/删除某些用户。由于我不知道您的实体,我将假设您的对象具有返回当前用户的方法getUsers()

$oldUsers = $groupeValidateurs->getUsers(); // I assume $oldUsers is an ARRAY***
$form = $this->createForm(...)
//...
if($form->isSubmitted() && $form->isValid()) {
$newUsers = $groupeValidateurs->getUsers();
// do whatever ...
}

***( 如果这是 OneToMany 或 ManyToMany 关系,请确保返回数组而不是集合:

public function getUsers() { 
return $this->users instanceof DoctrineCommonCollectionsCollection 
? $this->users->toArray() 
: $this->users; 
}

如果您设法始终将$this->users作为Collection,则可以return $this->users->toArray();

其他选项:

  • 将事件侦听器添加到表单中,以便在编辑进入之前捕获数据,将其添加到约束中,该约束获取额外的用户列表以防止添加/删除
  • 如果用户身上有一个属性,表明它很清楚,用户永远不应该被删除,你可以把它烘焙到你的add/removeUser函数中:
    function removeUser($user) { 
    if($user->isAdmin()) { 
    return; 
    }     
    $this->users->removeElement($user); // I assume users to be a doctrine Collection
    }
    function setUsers($users) {
    foreach($this->users as $user) {
    if($user->isAdmin() && !in_array($users)) {
    $users[] = $user; // add user;
    }
    }
    $this->users = $users;
    }
    
    注意:根据您的表单,您可能需要将by_reference设置为 false。恕我直言,这不是一个真正的问题,如果 a( 您的getUsers()返回数组而不是集合(它应该如何(或 b( 如果您实现addUser/removeUser. 此外,这种方法有一个明显的警告,即没有人可以在不删除管理员权限的情况下删除该用户,所以也许这是矫枉过正 ;o(
  • 设置原则事件侦听器以更新实体类型,以检查已删除的用户并相应地重新添加它们。 为此,您要么必须以某种方式检查变更集(这可能是矫枉过正(
  • 更改对象的用户时,存储用户列表的旧版本(如果添加/删除实现,请注意不要覆盖备份(
  • 在您的实体上正确实现clone,并在更改对象之前实际生成对象的副本(通过 handleRequest(。 随意比较。
  • 获取 Andrea Manzi 描述的原始实体并与之进行比较。

在编辑"操作"中,尝试使用:

if ($form->isSubmitted() && $form->isValid()) {
$currentdata = $form->getData();
/**/
}

获取当前数据的提交

或者编写这样的"更新"操作:

public function update(Request $request, $id)
{
/* @var $em EntityManager */
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository(Entity::class)->find($id); //your GroupeValidateurs entity class
$form = $this->createForm(GroupeValidateursType::class, $groupeValidateurs);
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
//persist and flush in database
$currentdata = $form->getData();
$beforedata = $em->getUnitOfWork()->getOriginalEntityData($entity);
/*....*/
}

将对象克隆到$cloneGroupeValidateurs。将实体设置为窗体。接下来提交表单并与之前克隆的变量进行比较。

相关内容

  • 没有找到相关文章

最新更新