DamienHarper / auditor-bundle

The missing audit log library
MIT License
386 stars 121 forks source link

Softdeleteable Entities not Logging Deletion #323

Open ixalsera opened 1 year ago

ixalsera commented 1 year ago
Q A
auditor-bundle version 5.0.3
PHP version 7.4.32
Database MySQL

Summary

Almost exactly the same issue as #122, entities tagged as soft-deletable do not seem to fire an audit event. Regular deletions are logged, updates and insertions are also logged. The deletedAt column is updated with the time when a soft-delete happens. Using v1.7.0 of StofDoctrineExtensionsBundle

Current behavior

When removing an entity annotated with @Gedmo\SoftDeletable (also tried with YAML mapping previously and did not work) with $entitymanager->remove($entity);, the entity is soft deleted as expected but no audit log entry appears for the deletion.

How to reproduce

  1. Annotate an entity with @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false)
  2. Create an instance of the entity and persist it
  3. Delete the persisted entity using the entity manager

Expected behavior

Entity should be soft deleted, an update audit entry showing the setting of deletedAt field should be generated.

samuel4x4 commented 1 year ago

I managed somehow to fix it by overwriting the DoctrineSubscriber priority like this (in my app ./config/services.yaml file):

DH\Auditor\Provider\Doctrine\Auditing\Transaction\TransactionManager:
    arguments: ['@DH\Auditor\Provider\Doctrine\DoctrineProvider']

DH\Auditor\Provider\Doctrine\Auditing\Event\DoctrineSubscriber:
    arguments: ['@DH\Auditor\Provider\Doctrine\Auditing\Transaction\TransactionManager']
    tags:
        - { name: doctrine.event_subscriber, priority: 1000 }

This results in having on the audit table a remove entry with the soft deleted object, it's a working solution for me. The perfect solution will be actually to have an update entry with the old and new values for the deletedAt property, but I couldn't manage to have this, if you have more success, please post the solution.

romeugodoi commented 1 year ago

The same bug here. v. 5.0.0

vascocajada commented 1 year ago
    class: DH\Auditor\Provider\Doctrine\Persistence\Event\CreateSchemaListener
    arguments: ['@DH\Auditor\Provider\Doctrine\DoctrineProvider']
    tags:
      - { name: doctrine.event_subscriber, priority: 1000000 }

  DH\Auditor\Provider\Doctrine\Persistence\Event\TableSchemaSubscriber:
    class: DH\Auditor\Provider\Doctrine\Persistence\Event\TableSchemaSubscriber
    arguments: ['@DH\Auditor\Provider\Doctrine\DoctrineProvider']
    tags:
      - { name: doctrine.event_subscriber, priority: 1000000 }

I had to overwrite the priority of the services above to have some sort of working solution. Still have some inconsistencies, though. It always logs the deletion of the entity, but sometimes it logs the update to the deletedAt column too.

using version 5.2 of the auditor bundle "damienharper/auditor-bundle": "^5.2" with gedmo doctrine extensions 3 "gedmo/doctrine-extensions": "^3.0",

Seros commented 6 months ago

Hi, we are also suffering from this issue with the versions

I investigated this issue based on the comments here and found a bit of hacky but less disrupting way around this issue without duplicate or inconsistent audit logs by implementing a preFlush event listener which could be helpful for others as well as long as this issue persists.

<?php

namespace App\EventListener;

use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
use Doctrine\ORM\Event\PreFlushEventArgs;
use Doctrine\ORM\Events;
use Gedmo\SoftDeleteable\SoftDeleteableListener;

#[AsDoctrineListener(event: Events::preFlush)]
class PreFlushListener
{
    /**
     * Hacky way to swap the priority of the {@see SoftDeleteableListener} to be applied after the {@see DoctrineSubscriber}.
     * @param PreFlushEventArgs $eventArgs
     * @return void
     */
    public function preFlush(PreFlushEventArgs $eventArgs): void
    {
        $eventManager = $eventArgs->getObjectManager()->getEventManager();
        $eventListeners = $eventManager->getListeners(Events::onFlush);
        foreach ($eventListeners as $eventListener) {
            if ($eventListener instanceof SoftDeleteableListener) {
                $softDeleteableListener = $eventListener;
                $eventManager->removeEventListener(Events::onFlush, $softDeleteableListener);
                break;
            }
        }
        if (isset($softDeleteableListener)) {
            $eventManager->addEventListener(Events::onFlush, $softDeleteableListener);
        }
    }
}
tlorens commented 3 months ago

Notes: I have notes in one of my subscribers while listening to LifeCycle events. /**