Deleting / updating a cached image when updating / deleting a record using liipImagineBundle

I am new to symfony2. I use liipImagineBundle to control image thumbnail. I have a product object class that uses Lifecycle callbacks to manage the product image.

product.php

<?php namespace Svipl\AdminBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as GEDMO; use Symfony\Component\HttpFoundation\File\UploadedFile; /** * Svipl\AdminBundle\Entity\Product * @ORM\Entity * @ORM\Table(name="product") * @ORM\Entity(repositoryClass="Svipl\AdminBundle\Entity\ProductRepository") * @ORM\HasLifecycleCallbacks */ class Product{ /** * @ORM\Column(type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @ORM\Column(type="string", length=25, unique=true) */ private $name; /** * @ORM\Column(type="text") */ private $description; /** * @ORM\Column(type="float", length=8) * @var unknown */ private $price; /** * @GEDMO\Timestampable(on="update") * @ORM\Column(name="updated_at", type="datetime") */ private $updated_at; /** * @GEDMO\Timestampable(on="create") * @ORM\Column(name="created_at", type="datetime") */ private $created_at; /** * @ORM\ManyToOne(targetEntity="Category", inversedBy="products") * @ORM\JoinColumn(name="category_id", referencedColumnName="id") */ protected $category; /** * @ORM\Column(name="image", type="string", length=50) */ private $image; public function getAbsolutePath() { return null === $this->image ? null : $this->getUploadRootDir().'/'.$this->image; } public function getWebPath() { return null === $this->image ? null : $this->getUploadDir().'/'.$this->image; } protected function getUploadRootDir() { // the absolute directory path where uploaded // documents should be saved return __DIR__.'/../../../../web/'.$this->getUploadDir(); } protected function getUploadDir() { // get rid of the __DIR__ so it doesn't screw up // when displaying uploaded doc/image in the view. return 'uploads/product'; } private $file; /** * Get file. * * @return UploadedFile */ public function getFile() { return $this->file; } /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * Set name * * @param string $name * @return Product */ public function setName($name) { $this->name = $name; return $this; } /** * Get name * * @return string */ public function getName() { return $this->name; } /** * Set description * * @param string $description * @return Product */ public function setDescription($description) { $this->description = $description; return $this; } /** * Get description * * @return string */ public function getDescription() { return $this->description; } /** * Set price * * @param float $price * @return Product */ public function setPrice($price) { $this->price = $price; return $this; } /** * Get price * * @return float */ public function getPrice() { return $this->price; } /** * Set updated_at * * @param \DateTime $updatedAt * @return Product */ public function setUpdatedAt($updatedAt) { $this->updated_at = $updatedAt; return $this; } /** * Get updated_at * * @return \DateTime */ public function getUpdatedAt() { return $this->updated_at; } /** * Set created_at * * @param \DateTime $createdAt * @return Product */ public function setCreatedAt($createdAt) { $this->created_at = $createdAt; return $this; } /** * Get created_at * * @return \DateTime */ public function getCreatedAt() { return $this->created_at; } /** * Set category * * @param \Svipl\AdminBundle\Entity\Category $category * @return Product */ public function setCategory(\Svipl\AdminBundle\Entity\Category $category = null) { $this->category = $category; return $this; } /** * Get category * * @return \Svipl\AdminBundle\Entity\Category */ public function getCategory() { return $this->category; } /** * Set image * * @param string $image * @return Product */ public function setImage($image) { $this->image = $image; return $this; } /** * Get image * * @return string */ public function getImage() { return $this->image; } private $temp; /** * Sets file. * * @param UploadedFile $file */ public function setFile(UploadedFile $file = null) { $this->file = $file; // check if we have an old image path if (isset($this->image)) { // store the old name to delete after the update $this->temp = $this->image; $this->image = null; } else { $this->image = 'initial'; } } /** * @ORM\PrePersist() * @ORM\PreUpdate() */ public function preUpload() { if (null !== $this->getFile()) { // do whatever you want to generate a unique name $filename = sha1(uniqid(mt_rand(), true)); $this->image = $filename.'.'.$this->getFile()->guessExtension(); } } /** * @ORM\PostPersist() * @ORM\PostUpdate() */ public function upload() { if (null === $this->getFile()) { return; } // if there is an error when moving the file, an exception will // be automatically thrown by move(). This will properly prevent // the entity from being persisted to the database on error $this->getFile()->move($this->getUploadRootDir(), $this->image); // check if we have an old image if (isset($this->temp)) { // delete the old image unlink($this->getUploadRootDir().'/'.$this->temp); // clear the temp image path $this->temp = null; } $this->file = null; } /** * @ORM\PostRemove() */ public function removeUpload() { if ($file = $this->getAbsolutePath()) { unlink($file); } } } 

config.yml

 ... liip_imagine: filter_sets: my_thumb: quality: 75 filters: thumbnail: { size: [120, 90], mode: outbound } 

Thumbnail Generation Code

 ... <img src="{{ asset('uploads/product/' ~ form_object.vars.value.image) | imagine_filter('my_thumb', true) }}" /> ... 

Sketches are created correctly.

But I can’t find a way to update / delete the cached image on the first change of the image or delete using the form.

+7
php symfony liipimaginebundle
source share
4 answers

You need to register preUpdate and preRemove event listener / subscriber , enter the necessary service and delete the images there.

Since you do not have access to the service container (and you should not inject services into your objects), you cannot request LiipImagineBundle services to receive cached files inside your object using life cycle events.

You can enter the liip_imagine.cache.manager service and use its remove () to remove the image from the cache.

+9
source share

You need to create a recipient object and create a service. The service will call this Entity every event you want: here in PostUpdate and preRemove of your product.

In the Entity Listener, you have a method for every event you set, and you just need to clear the cache for each method or do something else.

Here is an example from this post

Service

 services: project.cacheimage_listener: class: Acme\Listener\CacheImageListener arguments: ["@liip_imagine.cache.manager"] tags: - { name: doctrine.event_listener, event: postUpdate } - { name: doctrine.event_listener, event: preRemove } 

Entity Listener

 <?php namespace Acme\Listener; use Doctrine\ORM\Event\LifecycleEventArgs; use Acme\Entity\Image; class CacheImageListener { protected $cacheManager; public function __construct($cacheManager) { $this->cacheManager = $cacheManager; } public function postUpdate(LifecycleEventArgs $args) { $entity = $args->getEntity(); if ($entity instanceof Image) { // clear cache of thumbnail $this->cacheManager->remove($entity->getUploadDir()); } } // when delete entity so remove all thumbnails related public function preRemove(LifecycleEventArgs $args) { $entity = $args->getEntity(); if ($entity instanceof Image) { $this->cacheManager->remove($entity->getWebPath()); } } } 

This solution works great on my site.

+3
source share

Remember to call the resolve () method on liip_imagine.cache.manager. Otherwise, it will not delete your cached image.

as described here: https://github.com/liip/LiipImagineBundle/issues/132

 $cacheManager = $this->get('liip_imagine.cache.manager'); $cacheManager->resolve($this->getRequest(), $pngPath, $filter); $cacheManager->remove($pngPath, $filter); 
+2
source share

I know this question is a bit old, but if someone is looking for some kind of code (I am using SF 2.3). I had this requirement to delete files. in my project, I use VichUploaderBundle to handle file downloads and LiipImagineBundle to handle thumbnails for these images. When an object is deleted, the downloaded file must be deleted, as well as a thumbnail (if it was generated). I implemented a doctrine listener, the preRemove method is as follows:

 public function preRemove(LifecycleEventArgs $args) { $filter = 'thumbnail'; //the filter that imagine bundle uses $fileEntity = $args->getEntity(); if($fileEntity instanceof FileEntity) { //get the path to the uploaded file, relative to the web url $sourcePath = $this->uploaderStorage->resolveUri($fileEntity, "file"); $this->liipCacheManager->remove($sourcePath, $filter); } } 
+2
source share

All Articles