Reputation: 4000
I'm using DoctrineExtensions with StofDoctrineExtensionsBundle to get the soft-deleteable behaviour.
It works really well in the frontend of my application.
In the backend i need the option to "hard" delete entities.
I have disabled the filter in my admin controllers (i use SonataAdmin):
$filters = $this->getModelManager()->getEntityManager($this->getClass())->getFilters();
if (array_key_exists('softdeleteable', $filters->getEnabledFilters())) {
$filters->disable('softdeleteable');
}
This works (soft deleted entities show up in the lists), but when i try to delete it, the entity does get soft-deleted again. How can i force a "hard" delete?
Upvotes: 12
Views: 7071
Reputation: 529
No need to create a listener or anything to HARD delete with softdeleteable enabled.
the original softdeleteable event has this line:
$reflProp = $meta->getReflectionProperty($config['fieldName']);
$oldValue = $reflProp->getValue($object);
if ($oldValue instanceof \Datetime) {
continue; // want to hard delete
}
All this mean if you:
$entity->setDeletedAt(new \Datetime());
$em->flush();
And then:
$em->remove($entity);
$em->flush();
At that point it will be hard deleted.
If you allready have a valid date inside deletedAt field when you call ->flush() after a ->remove($entity) your entity will be hard deleted
Upvotes: 7
Reputation: 3975
Not the most graceful way : you always can do a real delete with SQL, it will bypass softdeletable
$em->createQuery("DELETE MyEntity e WHERE e = :et")->setParameter('et',$entity)->execute();
Upvotes: 3
Reputation: 69
Although this question is a bit old maybe it is useful to someone:
Creating your own event listener might be a better solution:
class SoftDeleteableListener extends BaseSoftDeleteableListener
{
/**
* @inheritdoc
*/
public function onFlush(EventArgs $args)
{
$ea = $this->getEventAdapter($args);
$om = $ea->getObjectManager();
//return from event listener if you disabled filter: $em->getFilters()->disable('softdeleteable');
if (!$om->getFilters()->isEnabled('softdeleteable')) {
return;
}
parent::onFlush($args);
}
}
And adding in your config:
gedmo.listener.softdeleteable:
class: AppBundle\EventListener\SoftDeleteableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ @annotation_reader ] ]
source: https://github.com/Atlantic18/DoctrineExtensions/issues/1175
Upvotes: 0
Reputation: 5701
You don't need to disable filter - it just used for filtering records on select. You must disable listener instead:
// $em is your EntityManager
foreach ($em->getEventManager()->getListeners() as $eventName => $listeners) {
foreach ($listeners as $listener) {
if ($listener instanceof \Gedmo\SoftDeleteable\SoftDeleteableListener) {
$em->getEventManager()->removeEventListener($eventName, $listener);
}
}
}
and then call
$em->remove($entity);
$em->flush();
Upvotes: 13