Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable softdeleteable filter doesn't disabled Listeners #1175

Closed
Garfield-fr opened this issue Oct 14, 2014 · 10 comments
Closed

Disable softdeleteable filter doesn't disabled Listeners #1175

Garfield-fr opened this issue Oct 14, 2014 · 10 comments

Comments

@Garfield-fr
Copy link

I would like to hard-delete a record by disabling the filter but it doesn't work because listeners are already active on my entity.

I find a solution but it's not perfect:

$manager->getFilters()->disable('softdeleteable');
foreach ($manager->getEventManager()->getListeners() as $eventName => $listeners) {
    foreach ($listeners as $listener) {
        if ($listener instanceof \Gedmo\SoftDeleteable\SoftDeleteableListener) {
            $manager->getEventManager()->removeEventListener($eventName, $listener);
        }
    }
}

Do you have another solution ?

Thank's

@Garfield-fr Garfield-fr changed the title Disable softdeleteable filter doesn't disabled Listener Disable softdeleteable filter doesn't disabled Listeners Oct 14, 2014
@gitomato
Copy link

Hello, it may be a typo.
Can you try with :

$manager->getFilters()->disable('soft-deleteable');

https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/softdeleteable.md#setup-and-autoloading

@Garfield-fr
Copy link
Author

doctrine:
        orm:
            entity_managers:
                default:
                    filters:
                        softdeleteable:
                            class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
                            enabled: true

and in my function

$em = $this->getContainer()->get('doctrine')->getManager();
$em->getFilters()->disable('softdeleteable');
...
$em->remove($user);
$em->flush();

The record is not deleted from my db, it's marked deleted with date and time. Disabled filter don't deactivated softdeletable listener.

Any solution ?

Thank's

@appeltaert
Copy link

same, doesnt seem fixed 1 year later? theres no way to disable them now. @Garfield-fr did you find a solution?

@max-kovpak
Copy link

You can create your own event listener something like this:

<?php namespace AppBundle\EventListener;

use \Gedmo\SoftDeleteable\SoftDeleteableListener as BaseSoftDeleteableListener;
use Doctrine\Common\EventArgs;

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

}

in your config:

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

@keksa
Copy link

keksa commented Jun 6, 2016

For anyone still wondering about this. It is possible to hard delete softdeleteable entity with provided listener by setting the deletedAt field to DateTime object.

So for example this would hard delete user entity:

$user->setDeletedAt(new \DateTime);
$em->remove($user);
$em->flush();

This code in Gedmo listener provides that:

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

@cadavre
Copy link

cadavre commented Nov 3, 2017

Wait a second...

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

Doesn't it mean that if you call $em->remove($entity) for a second time (on already soft-deleted entity) it will remove it from DB?

@Deveosys
Copy link

Exactly, it's up to you not to make the deletion actions available on soft deleted objects

@l3pp4rd
Copy link
Contributor

l3pp4rd commented Jan 29, 2018

there is an option now to prevent hard deletion on second call and any other, see the doc for softdelete

@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@sdev-maxime
Copy link

sdev-maxime commented Feb 23, 2022

Update:

in SoftDeleteableListener.php

if (isset($config['hardDelete']) && $config['hardDelete'] && $oldValue instanceof \DateTimeInterface && $oldValue <= $date) {
    continue; // want to hard delete
}

So, configuration in entity file can be

/**
 * @ORM\Entity(repositoryClass=MyEntityRepository::class)
 * @ORM\Table(name="my_table_name")
 * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false, hardDelete=true)  <==== SET hardDelete to true
 */
class MyEntity { ... }

Then, there is some new behaviors.

  • The first time you'll remove an entity, the entity fill deleteAt field and store/save in database : classic behavior of softdeleteable.
  • If you remove a second time the same entity (with configured hardDelete=true in entity file), the entity will be deleted in database, cause it was already soft-deleted and have deleted at field filled: hard delete behavior after soft delete (very cool).
$entity = new Entity();
$this->em->persist($entity);
$this->em->flush();
// create entity in database

$this->em->remove($entity);
$this->em->flush();
// Now entity has deletedAt field filled -> is soft-deleted

$this->em->remove($entity);
$this->em->flush();
// Now entity is hard deleted, no anymore in database.

How delete without removing twice ? just add new \DateTime() to deleted at field.

$entity = new Entity();
$this->em->persist($entity);
$this->em->flush();
// Here I have a new entity saved in database

$entity->setDeletedAt(new \DateTime());
$this->em->remove($entity);
$this->em->flush();
// Now entity is hard deleted, no anymore in database.   due to the DateTimeInterface condition on top off the topic.

Hope this will help =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants