2012-11-26 24 views
7

Tôi đang sử dụng DoctrineExtensions với StofDoctrineExtensionsBundle để nhận hành vi xóa mềm.Hành vi không thể thực hiện được và thực sự xóa đối tượng

Nó hoạt động thực sự tốt trong giao diện người dùng của ứng dụng của tôi.

Trong chương trình phụ trợ, tôi cần tùy chọn xóa các thực thể "cứng".

tôi đã vô hiệu hóa bộ lọc trong bộ điều khiển quản trị của tôi (tôi sử dụng SonataAdmin):

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

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

này hoạt động (thực thể xóa mềm hiển thị trong danh sách), nhưng khi tôi cố gắng để xóa nó, đơn vị thực hiện lại bị xóa mềm. Làm thế nào tôi có thể buộc một "cứng" xóa?

Trả lời

10

Bạn không cần phải tắt bộ lọc - bộ lọc này chỉ được sử dụng để lọc các bản ghi trên lựa chọn. Bạn phải vô hiệu hóa người nghe thay vì:

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

và sau đó gọi

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

Làm thế nào để bạn kích hoạt lại nó sau này? – Jessica

+0

@Jessica, bạn có thể sử dụng 'addEventListener' http://api.symfony.com/2.4/Symfony/Bridge/Doctrine/ContainerAwareEventManager.html#method_addEventListener – Dmitriy

+0

Cảm ơn rất nhiều, những gì tôi đã làm là lưu trữ tên của bất kỳ sự kiện nào tôi đã làm loại bỏ nó, sau đó lặp lại và thêm lại. – Jessica

0

Mặc dù câu hỏi này là một chút cũ có lẽ nó rất hữu ích cho một ai đó:

Tạo lắng nghe sự kiện riêng của bạn có thể là một tốt hơn giải pháp:

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

} 

Và thêm cấu hình của bạn:

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

nguồn: https://github.com/Atlantic18/DoctrineExtensions/issues/1175

2

Không cách duyên dáng nhất: bạn luôn có thể làm một thực xóa với SQL, nó sẽ bỏ qua softdeletable

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

Không cần phải tạo ra một người biết lắng nghe hay bất cứ điều gì để HARD xóa có thể bật softdeleteable.

sự kiện softdeleteable ban đầu có dòng này:

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

Tất cả điều này có nghĩa là nếu bạn:

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

Và sau đó:

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

Vào thời điểm đó nó sẽ bị xóa cứng .

Nếu bạn allready có một ngày hợp lệ trong lĩnh vực deletedAt khi bạn gọi -> flush() sau một -> loại bỏ ($ tổ chức) tổ chức của bạn sẽ bị xóa cứng

+1

Điều này phải được chấp nhận làm câu trả lời. – Veve

Các vấn đề liên quan