Отслеживать изменения полей в сущности Doctrine

Я хочу отслеживать изменения в поле доктрины. Я использую Symfony 2.5.0 и Doctrine 2.2.3.

Пока у меня есть EventSubscriber который подписывается на preUpdate, Здесь я хочу создать новый объект, который хранит новое и старое значение и содержит ссылку на объект, который обновляется.

Проблема в том, что я не могу найти способ сохранить эту новую сущность. Если я persist() в preUpdate а также flush() в postUpdate, это работает, если я изменяю только одну сущность. Если несколько сущностей изменены, я получаю сообщение об ошибке, что набор изменений пуст.

Я пытался играть с разными событиями с разными результатами. Пустые страницы, объекты отслеживания не сохраняются и т. Д.

Я думаю, что это должно быть распространено, но я не могу найти примеры.

4

Решение

Не используйте preUpdate или postUpdate, у вас будут проблемы. Взгляни на onFlush вместо.

На данный момент у вас есть доступ к полному набору изменений, чтобы вы могли узнать, какие поля были изменены, что было добавлено и т. Д. Вы также можете безопасно сохранять новые объекты. Обратите внимание как документы скажем, вам придется пересчитать наборы изменений, когда вы сохраните или измените объекты.

Простой пример, который я собрал вместе, не проверял, но что-то похожее на это даст вам то, что вы хотите.

public function onFlush(OnFlushEventArgs $args) {

$entityManager = $args->getEntityManager();
$unitOfWork = $entityManager->getUnitOfWork();
$updatedEntities = $unitOfWork->getScheduledEntityUpdates();

foreach ($updatedEntities as $updatedEntity) {

if ($updatedEntity instanceof YourEntity) {

$changeset = $unitOfWork->getEntityChangeSet($updatedEntity);

if (!is_array($changeset)) {

return null;
}

if (array_key_exists('someFieldInYourEntity', $changeset)) {

$changes = $changeset['someFieldInYourEntity'];

$previousValueForField = array_key_exists(0, $changes) ? $changes[0] : null;
$newValueForField = array_key_exists(1, $changes) ? $changes[1] : null;

if ($previousValueForField != $newValueForField) {

$yourChangeTrackingEntity = new YourChangeTrackingEntity();
$yourChangeTrackingEntity->setSomeFieldChanged($previousValueForField);
$yourChangeTrackingEntity->setSomeFieldChangedTo($newValueForField);

$entityManager->persist($yourChangeTrackingEntity);
$metaData = $entityManager->getClassMetadata('YourNameSpace\YourBundle\Entity\YourChangeTrackingEntity');
$unitOfWork->computeChangeSet($metaData, $yourChangeTrackingEntity);
}
}
}
}
}
7

Другие решения

Вы можете быть заинтересованы в EntityAudit bundle.

Это позволяет настроить, какие объекты должны отслеживаться. Затем он вводит понятие изменения базы данных. Каждая ревизия имеет временную метку, имя пользователя и список затронутых объектов.

Затем вы можете найти все ревизии, которые влияют на конкретную сущность:

$revisions = $auditReader->findRevisions('AppBundle\Entity\Article', 1);

или создать его в конкретной ревизии:

$oldArticle = $auditReader->find(
'AppBundle\Entity\Article',
$id = 1,
$rev = 2
);

так что вы можете легко сравнить текущее и старое состояние объекта.

Пакет также поставляется с примерами представления, демонстрирующими, как отображать список ревизий, сравнивать объекты в разных версиях и многое другое.

выбирая сравнение

сравнительный вид

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector