L'installation et l'utilisation de l'extension de comportement SoftDeleteable pour Doctrine 2 est assez simple. Le problème est généralement d'essayer de le désactiver pour certaines parties de code et de l'activer à nouveau. Vous voudrez peut-être faire ceci pour:
Alors, comment le désactiver?
Selon la documentation, désactivez le filtre pour le gestionnaire d'entités:
$em->getFilters()->disable('softdeleteable');
$object = $em->find('AppBundle:Object', 1); // soft-deleted entity will be loaded
Pour activer à nouveau la suppression logicielle:
$em->getFilters()->enable('softdeleteable');
Remarque: $em->clear();
peut être requis avant cette ligne, si l'entité était déjà chargée avec le filtre de suppression progressive désactivé.
Bien que cela ne soit pas mentionné dans la documentation, la première solution ne fonctionne pas si vous devez supprimer une entité et contourner le filtre de suppression progressive. Le filtre doit être supprimé des écouteurs d'événements du gestionnaire d'entités:
// initiate an array for the removed listeners
$originalEventListeners = [];
// cycle through all registered event listeners
foreach ($em->getEventManager()->getListeners() as $eventName => $listeners) {
foreach ($listeners as $listener) {
if ($listener instanceof \Gedmo\SoftDeleteable\SoftDeleteableListener) {
// store the event listener, that gets removed
$originalEventListeners[$eventName] = $listener;
// remove the SoftDeletableSubscriber event listener
$em->getEventManager()->removeEventListener($eventName, $listener);
}
}
}
// remove the entity
$em->remove($object);
$em->flush($object); // or $em->flush();
// re-add the removed listener back to the event-manager
foreach ($originalEventListeners as $eventName => $listener) {
$em->getEventManager()->addEventListener($eventName, $listener);
}
Références:
Vous pouvez utiliser un service pour désactiver et réactiver le comportement du filtre de suppression logicielle:
<?php
namespace App\Util;
use Doctrine\ORM\EntityManagerInterface;
use Gedmo\SoftDeleteable\SoftDeleteableListener;
class SoftDeleteFilter
{
/**
* @var string
*/
const EVENT_NAME = 'onFlush';
/**
* @var object
*/
private $originalEventListener;
/**
* @param EntityManagerInterface $em
*/
public function removeSoftDeleteFilter(EntityManagerInterface $em)
{
foreach ($em->getEventManager()->getListeners() as $eventName => $listeners) {
foreach ($listeners as $listener) {
if ($listener instanceof SoftDeleteableListener) {
if ($eventName === self::EVENT_NAME) {
$this->originalEventListener = $listener;
$em->getEventManager()->removeEventListener($eventName, $listener);
}
}
}
}
}
/**
* @param EntityManagerInterface $em
*/
public function undoRemoveSoftDeleteFilter(EntityManagerInterface $em)
{
if (empty($this->originalEventListener)) {
throw new \Exception('can not undo remove, soft delete listener was not removed');
}
// re-add the removed listener back to the event-manager
$em->getEventManager()->addEventListener(self::EVENT_NAME, $this->originalEventListener);
}
}
usage:
$this->softDeleteFilter->removeSoftDeleteFilter($this->entityManager);
$this->entityManager->remove($entity);
$this->entityManager->flush();
$this->softDeleteFilter->undoRemoveSoftDeleteFilter($this->entityManager);
Comme dans un commentaire précédent de qooplmao posted: Une solution simple et efficace est:
// Remove an entity entirely from the DB (skip soft delete)
$this->entityManager->remove($entity);
$this->entityManager->flush();
// Just run it a second time :-)
$this->entityManager->remove($entity);
$this->entityManager->flush();
Je viens de le poster à nouveau pour lui donner un peu plus de visibilité car il fonctionne comme un charme ...