LiipImagineBundle Dynamic Filter
Last month, I had to update the version of LiipImagineBundle that I was using in a project I work for. We have always used dynamic filters but we were overriding the ImagineController in order to do that. However, the new version of the bundle already offers the possibility for us to apply dynamic filters. This is called runtime configuration. It's a very interesting feature but not very well documented. That's why I thought this is worth a post.
First of all, for those who don't know LiipImagineBundle, it is a very useful bundle that enables us to apply filters to the photos used in our application. It integrates the Imagine library for PHP. Using this bundle, we can, for example, apply a filter that creates a thumbnail of our photos or just resize them. But why would somebody need a dynamic filter? In my case, I need to apply a watermark to a photo depending on the information I have for the user. But you can also change the size of your thumbnail if you are in a template and so on.
The first thing to do is to configure your filter in the config.yml file. I'm using the version 1.3 of LiipImagineBundle:
liip_imagine:
filter_sets:
watermark_photo:
filters:
relative_resize: { widen: 1600 }
There's much more configuration to do with this bundle. This is just an example to understand how the dynamic filter works.
For the watermark_photo filter, we just defined the size. Nothing is said about the watermark that is going to be added dynamically depending on the user.
Case 1: twig
In this case, we are going to add the dynamic filter directly on twig.
// create a runtime configuration depending on the user information
{% set image = watermark_dir ~ user.watermarkPath %}
{% set position = (user.watermarkPosition)|default('bottom') %}
{% set runtimeConfig = {"watermark": {"image": image, "position": position} } %}
// display the image using the filter and the runtime configuration
<img src="photo.imagepath | imagine_filter('watermark_photo', runtimeConfig)" >
Case 2: controller - display an image
In this case, we are going to add the dynamic filter to the image on controller and send the path to the template.
// create a runtime configuration depending on the user information
$runtimeConfig = array(
'watermark' => array(
'image' => $this->container->getParameter('watermark_dir') . $user->getWatermarkPath(),
'position' => $this->container->getParameter('watermark_dir') . $user->getWatermarkPosition() ?: "bottom"
)
);
// get the path that is going to be displayed on the image tag
$browserPath = $this->container->get('liip_imagine.cache.manager')->getBrowserPath($photo->getPath(), 'watermark_photo', $runtimeConfig);
// send the path to the template
return $this->render('MyBundle:Frontend:liipFilters.html.twig', array('browserPath' => $browserPath));
// on twig just display the path
<img src={{ browserPath }} >
Case 3: controller - download an image
In this case, we are going to add the dynamic filter to the image on controller and send the content of the photo to be downloaded on Twig. We are not going to use the runtime config. We need the image to be filtered before it is displayed. Otherwise, we can't get its content with the watermark.
// get the configuration of the filter
$filterConfig = $this->container->get('liip_imagine.filter.configuration');
$config = $filterConfig->get('watermark_photo');
// update it with new information about the watermark that depends on the user
$watermarkPath = $this->container->getParameter('watermark_dir') . $user->getWatermarkPath()
$watermarkPosition = $this->container->getParameter('watermark_dir') . $user->getWatermarkPosition() ?: "bottom";
$config['filters']['watermark']['image'] = $watermarkPath;
$config['filters']['watermark']['position'] = $watermarkPosition;
$filterConfig->set('watermark_photo', $config);
// filter the image
$this->container->get('liip_imagine.controller')->filterAction($request, $photo->getPath(), 'watermark_photo');
// get the path that could be displayed on an image tag
$browserPath = $this->container->get('liip_imagine.cache.manager')->getBrowserPath($photo->getPath(), 'watermark_photo');
// get the content of the image using this path
$content = file_get_contents($browserPath);
// send the content of the image to the template
return new Response($content, 200, array(
'Content-Type' => $photo->getFiletype(),
'Content-Disposition' => sprintf('attachment;filename="%s.%s"', $photo->getFilename(), $photo->getFiletype())
));