2012-11-26 10 views
7

Korzystam zz , aby uzyskać zachowanie, które można usunąć.Zachowanie podlegające agresywnej obróbce i usuwanie użytkownika z obiektu

Działa bardzo dobrze w interfejsie mojej aplikacji.

W backendach potrzebuję opcji "twardego" usuwania encji.

mam wyłączony filtr w moim kontrolerów administracyjnych (używam SonataAdmin):

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

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

Działa (soft usunięte podmioty pokazać się na listach), ale gdy próbuję go usunąć, jednostka robi się miękko - usuń ponownie. Jak mogę wymusić "trudne" usunięcie?

Odpowiedz

10

Nie trzeba wyłączać filtra - służy on tylko do filtrowania rekordów przy wyborze. Musisz wyłączyć słuchacza zamiast:

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

a następnie zadzwonić

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

Jak można ponownie włączyć go po tym? – Jessica

+0

@Jessica, możesz użyć 'addEventListener' http://api.symfony.com/2.4/Symfony/Bridge/Doctrine/ContainerAwareEventManager.html#method_addEventListener – Dmitriy

+0

Wielkie dzięki, to, co zrobiłem, to przechowywanie nazw wszystkich wydarzeń, które zrobiłem usuń go, a następnie przeprowadź przez nie pętlę i ponownie dodaj. – Jessica

0

Chociaż ta kwestia jest nieco stary może warto do kogoś:

tworzenia własnych detektor zdarzeń może być lepiej rozwiązanie:

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

} 

Dodanie do konfiguracji:

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

źródło: https://github.com/Atlantic18/DoctrineExtensions/issues/1175

2

Nie najbardziej taktowny sposób: zawsze można zrobić prawdziwy usuwać z SQL, to ominąć softdeletable

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

ma potrzeby tworzenia słuchacza lub cokolwiek ciężko usuń z włączoną opcją łagodnego wyłączania.

oryginalny softdeleteable zdarzenie ma ten wiersz:

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

Wszystko to znaczy, jeśli:

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

A potem:

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

W tym momencie zostanie trwale usunięte .

Jeśli allready mają poprawną datę wewnątrz pola deletedAt podczas połączenia -> flush() po -> usuń ($ podmiot) Twoja jednostka będzie ciężko usunięte

+1

To powinno być zaakceptowane jako odpowiedź. – Veve

Powiązane problemy