2012-11-26 21 views
7

Sto utilizzando DoctrineExtensions con StofDoctrineExtensionsBundle per ottenere il comportamento cancellabile.Comportamento gradevole e cancellazione effettiva dell'entità

Funziona davvero bene nel frontend della mia applicazione.

Nel back-end ho bisogno dell'opzione per eliminare le entità "difficili".

Ho disabile il filtro nei miei controllori di amministrazione (io uso SonataAdmin):

$filters = $this->getModelManager()->getEntityManager($this->getClass())->getFilters(); 

if (array_key_exists('softdeleteable', $filters->getEnabledFilters())) { 
    $filters->disable('softdeleteable'); 
} 

Questo funziona (entità morbido cancellati compaiono nelle liste), ma quando provo a eliminarlo, l'entità fa diventa nuovamente cancellato. Come posso forzare una cancellazione "difficile"?

risposta

10

Non è necessario disabilitare il filtro: è utilizzato solo per filtrare i record su select. È necessario disattivare ascoltatore invece:

// $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); 
     } 
    } 
} 

e quindi chiamare

$em->remove($entity); 
$em->flush(); 
+0

Come si fa a riabilitarlo dopo questo? – Jessica

+0

@Jessica, puoi usare 'addEventListener' http://api.symfony.com/2.4/Symfony/Bridge/Doctrine/ContainerAwareEventManager.html#method_addEventListener – Dmitriy

+0

Grazie mille, quello che ho fatto è stato memorizzare i nomi di tutti gli eventi che ho fatto rimuovilo da, quindi passa in rassegna quelle e aggiungilo di nuovo. – Jessica

0

Anche se questa domanda è un po 'vecchio forse è utile a qualcuno:

Creare il proprio listener di eventi potrebbe essere una migliore soluzione:

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); 
} 

} 

E l'aggiunta nella vostra configurazione:

gedmo.listener.softdeleteable: 
    class: AppBundle\EventListener\SoftDeleteableListener 
    tags: 
     - { name: doctrine.event_subscriber, connection: default } 
    calls: 
     - [ setAnnotationReader, [ @annotation_reader ] ] 

fonte: https://github.com/Atlantic18/DoctrineExtensions/issues/1175

2

Non è il modo più grazioso: si può sempre fare un vero e proprio cancellare con SQL, sarà bypassare softdeletable

$em->createQuery("DELETE MyEntity e WHERE e = :et")->setParameter('et',$entity)->execute(); 
4

Non c'è bisogno di creare un ascoltatore o nulla a DURO elimina con softdeleteable abilitato.

caso softdeleteable originale ha questa linea:

$reflProp = $meta->getReflectionProperty($config['fieldName']); 
$oldValue = $reflProp->getValue($object); 
if ($oldValue instanceof \Datetime) { 
    continue; // want to hard delete 
} 

Tutto questo significa che se si:

$entity->setDeletedAt(new \Datetime()); 
$em->flush(); 

E poi:

$em->remove($entity); 
$em->flush(); 

A quel punto verrà eliminato duro .

Se hai giá una data valida all'interno del campo deletedAt quando si chiama -> flush() dopo un -> rimuovere ($ entità) la tua entità sarà cancellato difficile

+1

Questo dovrebbe essere accettato come risposta. – Veve