6

我正在构建一个应用程序,用户可以在其中编辑一些数据,然后显示一个屏幕,他可以在其中确认(和评论)他的编辑。

在确认表单中,我显示了对实体所做的更改。这适用于“正常”字段。下面是一些用于检查单个字段的代码:

// create $form
// bind $form

if ($form->isValid() {
    $data = $form->getData();
    // example, get changes of a "normal" field
    if ($data['color'] != $entity->getColor()) {
        // do something with changes
    }
}

但我不能对关系做同样的事情(例如 ManyToMany with Users):

    if ($data['users'] != $entity->getUsers()

不起作用,因为 $data['users'] 和 $entity->getUsers() 引用相同的持久性集合。可以调用这个函数看看有没有变化:

    if ($data['users']->isDirty())

但无法查看进行了哪些更改。

上面的第二个问题是,如果从持久化集合中删除所有项目,Doctrine 不会将其标记为“已更改”(isDirty() = true),因此我无法捕捉到用户删除所有“的具体更改”用户”来自表单中的实体。

请注意,代码一切正常,我唯一的问题是我无法查看/处理在确认步骤中所做的更改。

4

3 回答 3

6

Doctrine\ORM\PersistentCollection具有内部 API(公共)方法,getSnapshot可在. 例如,您可以在.getDeleteDiffgetInsertDiffDoctrine\ORM\UnitOfWorkonFlush

于 2013-02-14T01:38:10.840 回答
6

像这样解决它:

1) 要获取将直接对实体进行的更改,请使用以下命令:

// create form
// bind form
// form isValid()

$uow = $em->getUnitOfWork();
$uow->computeChangeSets();
$changeset = $uow->getEntityChangeSet($entity);
print_r($changeset);

2a)要更改关系,请使用上面 Lighthart 的答案:

$oldUsers = $entity->getUsers()->toArray();
// bind form
// form isValid
$newUsers = $entity->getUsers()->toArray();
// compare $oldUsers and $newUsers

2b) 在 Persistent Collection 上使用这些方法来查找插入/删除:

$newUsers = $entity->getUsers();
$inserted = $newUsers->getDeleteDiff();
$deleted  = $newUsers->getInsertDiff();

(2b) 的唯一问题是,如果删除了所有用户并且没有添加任何用户,则 getDeleteDiff() 为空,这似乎是 Doctrine 错误/特质

于 2013-02-15T17:30:56.090 回答
0

在绑定之前将原始集合存储在一个变量中,然后在绑定之后比较新集合。PHP 有不少数组比较函数,集合很容易通过 $collection->toArray() 变成原生数组;

例如:

// create form
$oldusers=$entity->getUsers()->toArray();
// bind form
if ($form->isValid() {
    $data = $form->getData();
    if ($data['users'] != $oldusers) {
        // do something with changes
    }
}
于 2013-02-15T04:55:38.283 回答