VichUploaderBundle icon indicating copy to clipboard operation
VichUploaderBundle copied to clipboard

Delete entity when file is deleting

Open devcut opened this issue 4 years ago • 10 comments

Q A
Bundle version 1.16.0
Symfony version 5.1.8
PHP version 7.4.6

Support Question

I want to remove attachment entity when file is deleting but the flush not working.

services.yaml

app.listener.removed_file_listener:
    class: App\EventListener\RemovedFileListener
    tags:
      - { name: kernel.event_listener, event: vich_uploader.post_remove }

EventListener

class RemovedFileListener
{
    private EntityManagerInterface $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    // Make sure a file entity object is removed after the file is deleted
    public function onVichuploaderPostremove(Event $event)
    {
        // Get the file object
        $entity = $event->getObject();

        // Remove the file object from the database
        $this->em->remove($entity);
        $this->em->flush();
    }
}

devcut avatar Dec 28 '20 10:12 devcut

There's an option for that: see https://github.com/dustin10/VichUploaderBundle/blob/master/docs/usage.md#step-3-configure-the-lifecycle-events-optional-step

garak avatar Dec 29 '20 10:12 garak

There's an option for that: see https://github.com/dustin10/VichUploaderBundle/blob/master/docs/usage.md#step-3-configure-the-lifecycle-events-optional-step

This is for delete file. Not entity. When deleting file using form, the file is deleted, but not the entity row :

image

bastien70 avatar Apr 15 '21 10:04 bastien70

You're righe @bastien70. Anyway, you can listen to vich_uploader.post_remove and implement your logic to delete object.

garak avatar Apr 15 '21 11:04 garak

You're righe @bastien70. Anyway, you can listen to vich_uploader.post_remove and implement your logic to delete object.

I tried, removing the database record from the listener. But oddly, it removes it well, but it recreates a record right after, with the filename and imageSize in null, it's very weird

bastien70 avatar Apr 15 '21 13:04 bastien70

You're righe @bastien70. Anyway, you can listen to vich_uploader.post_remove and implement your logic to delete object.

I tried, removing the database record from the listener. But oddly, it removes it well, but it recreates a record right after, with the filename and imageSize in null, it's very weird

Isn't that removing the entity will also remove the object at the same time?

fd6130 avatar May 16 '21 15:05 fd6130

I tried, removing the database record from the listener. But oddly, it removes it well, but it recreates a record right after, with the filename and imageSize in null, it's very weird

I discover the same problem as @bastien70 . No idea why this is happening. Currently I can only disable this setting delete_on_remove and take of this myself.

codedge avatar Sep 24 '21 10:09 codedge

You're righe @bastien70. Anyway, you can listen to vich_uploader.post_remove and implement your logic to delete object.

I tried, removing the database record from the listener. But oddly, it removes it well, but it recreates a record right after, with the filename and imageSize in null, it's very weird

I'm getting the same problem.. listener delete the record and re-create right after

celsoandrade avatar Mar 21 '23 17:03 celsoandrade

I also had the same problem on my side but I was able to solve it. Make sure that the entity you want to delete is no longer attached to a parent entity.

vich_uploader.post_remove event occurs during FormEvents::POST_SUBMIT and therefore before the Doctrine flush. Doctrine still has the element in "memory" and will recreate it during the flush.

Kaaly avatar Jun 23 '23 15:06 Kaaly

Make sure that the entity you want to delete is no longer attached to a parent entity.

Could you please provide the code on how to do that?

celsoandrade avatar Aug 08 '23 18:08 celsoandrade

I've still the same problem. Is there a solution now ?

I've a generic Media entity :

#[ORM\Entity(repositoryClass: MediaRepository::class)]
#[ORM\HasLifecycleCallbacks]
#[Vich\Uploadable]
class Media implements \Stringable
{
    use PrimaryKeyTrait;
    use CreatedAtTrait;
    use UpdatedAtTrait;

    #[ORM\Column(type: Types::INTEGER, nullable: true)]
    private ?int $size = null;

    #[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
    private ?string $mimeType = null;

    #[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
    private ?string $originalName = null;

    #[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
    private ?string $fileName = null;

    #[Vich\UploadableField(
        mapping: 'media',
        fileNameProperty: 'fileName',
        size: 'size',
        mimeType: 'mimeType',
        originalName: 'originalName'
    )]
    private ?File $file = null;

    public function __construct()
    {
        $this->createdAt = new \DateTimeImmutable();
        $this->updatedAt = new \DateTimeImmutable();
    }

    public function setFile(File $file = null): self
    {
        $this->file = $file;

        if ($file) {
            $this->updatedAt = new \DateTimeImmutable();
        }

        return $this;
    }

    public function getFile(): ?File
    {
        return $this->file;
    }
    
    // other getters/setters...
}

And I associate it with my entities. By example, in my User entity, I've an avatar field :

#[ORM\OneToOne(cascade: ['persist', 'remove'], fetch: 'EAGER')]
    private ?Media $avatar = null;

In the vich_uploader.yaml :

vich_uploader:
    db_driver: orm
    storage: flysystem
    mappings:
        media:
            upload_destination: 'media.storage'
            namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
            inject_on_load: true
            delete_on_update: true
            delete_on_remove: true

When clicking inside the checkbox and submitting the form to remove current avatar relation, the file is deleted, the Media entity is truncated, but it creates a new media (with just createdAt and updatedAt values) instead of just deleting by the way the "media" row in database

bastien70 avatar Dec 01 '23 13:12 bastien70