Chapters
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3
Subscribe to download the code!Compatible PHP versions: ^7.1.3
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Thumbnailing with LiipImagineBundle
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeGo back to the homepage. We're rendering these images with a width and height of 100. But the image behind this is way bigger! That's wasteful: we don't want the user to wait to download these gigantic images, just to see the tiny thumbnail.
Hello LiipImagineBundle
Google for LiipImagineBundle and find its GitHub page. They have a bunch of docs right here... but most of the information actually lives over on Symfony.com. Click "Download the Bundle" to get there... and then I'll go back to the homepage - lots of good stuff here.
Start back on the Installation page. Copy the composer require line, find your terminal, paste and... go go go!
composer require "liip/imagine-bundle:^2.1"
While we're waiting, head back over to the docs. Thanks to Flex, we don't need to enable the bundle or register the routes - that's automatic. Go back to the homepage of the docs... and click the "Filter Sets" link.
This bundle is pretty sweet. You start by creating something called a "filter set" and giving it a name - like my_thumb
or whatever you want. Next, you tell the bundle which filters, or transformations, to apply when you use the my_thumb
filter set. And there are a ton of them: you can change the size with the thumbnail
filter, add a background, add border color, replace the image entirely with a cat gif - pretty much anything you can dream of. We'll just use the thumbnail
transformation, but seriously - check out the full list.
Configuring the Filter Set
Let's go check on the install. Excellent! It's done. And the message is right on: it says we need to get to work in the new config file: liip_imagine.yaml
. Go open that: config/packages/liip_imagine.yaml
. Uncomment the root key to activate the bundle, leave the driver
alone - it defaults to gd
- and uncomment filter_sets
.
liip_imagine: | |
# # valid drivers options include "gd" or "gmagick" or "imagick" | |
# driver: "gd" | |
# | |
# # define your filter sets under this option | |
filter_sets: | |
Show Lines
|
// ... lines 7 - 42 |
Let's create our first filter set called squared_thumbnail_small
. We'll use this on the homepage to reduce the images down to 100 by 100. To do that, uncomment the filters
key and I'll copy the thumbnail
example from below, move it up here, and uncomment it.
liip_imagine: | |
Show Lines
|
// ... lines 2 - 5 |
filter_sets: | |
Show Lines
|
// ... lines 7 - 9 |
squared_thumbnail_small: | |
filters: | |
Show Lines
|
// ... lines 12 - 42 |
Set the size to 200 by 200 so it looks good on Retina displays. The mode: outbound
is how the thumbnail is applied - you can also use inbound
.
liip_imagine: | |
Show Lines
|
// ... lines 2 - 5 |
filter_sets: | |
Show Lines
|
// ... lines 7 - 9 |
squared_thumbnail_small: | |
filters: | |
thumbnail: | |
size: [200, 200] | |
mode: outbound | |
allow_upscale: true | |
Show Lines
|
// ... lines 17 - 42 |
And... I think we're ready to go! Copy the squared_thumbnail_small
name and go into homepage.html.twig
. To use this, it's so nice: |imagine_filter()
and then the name.
Show Lines
|
// ... lines 1 - 2 |
{% block body %} | |
Show Lines
|
// ... lines 4 - 20 |
{% for article in articles %} | |
<div class="article-container my-1"> | |
<a href="{{ path('article_show', {slug: article.slug}) }}"> | |
<img class="article-img" src="{{ uploaded_asset(article.imagePath)|imagine_filter('squared_thumbnail_small') }}"> | |
Show Lines
|
// ... lines 25 - 37 |
</a> | |
</div> | |
{% endfor %} | |
Show Lines
|
// ... lines 41 - 63 |
{% endblock %} |
The Thumbnailing Process
Let's go try it! Watch the image src closely. Refresh! It includes the https://127.0.0.1
part, but that's not important. The path - /media/cache/resolve/squared_thumbnail_small/...
blah, blah blah - looks like a path to a physical file, but it's not! This is actually a Symfony route and it's handled by a Symfony controller!
Check it out: at your terminal, run:
php bin/console debug:router
There it is! The first time we refresh, LiipImagineBundle generates this URL. When our browser tries to download the image, it's handled by a controller from the bundle. That controller opens the original image, applies all the filters - just a thumbnail in our case - and returns the transformed image. That's a slow operation: our browser has to wait for all of that to finish.
But, watch what happens when we refresh. Did you see it? The path changed! It was /media/cache/resolve
- but the resolve part is now gone! This time, the image is not handled by a Symfony route. Look at your public/
directory: there is now a media/
directory with cache/squared_thumbnail_small/uploads/article_image/astronaut-...jpeg
.
The full process looks like this. The first time we refreshed, LiipImagineBundle noticed that no thumbnail file existed yet. So, it created the URL that pointed to the Symfony route & controller. The page finished rendering, and our browser make a second request to that URL to load the image. That request was handled by the controller from the bundle which thumbnailed the image, saved it to the filesystem, and returned it to the user. That's slow.
But when we reloaded the page the second time, LiipImagineBundle noticed that the filename already existed and generated a URL directly to that real file. The request for that image was super fast.
Oh, also check out the .gitignore
file. Thanks to the Flex recipe, we're already ignoring the public/media
directory: we do not want to commit this stuff: it'll just regenerate if it's missing.
So, yea - it all kinda works perfectly!
Next, let's add another filter set for the show page and add an image preview to the article form.
72 Comments
Hey Lubna!
Thank you for sharing this with others! Yeah, it may depends on permissions on your server, something you may need to create those manually and set the proper permissions like you did :)
Cheers!
Just in case anyone runs into the issue I had when thumbnail images are not showing and the folders are not generating automatically. My issue was the "gd" driver was mentioned in the video I actually didn't have this installed. I only found out as a red error appeared in the server output but not on the page. Installing it to PHP resolved my issue and files started appearing.
(LINUX)
sudo apt-get update
sudo apt-get install php7.2-gd
Thanks for sharing it Nicky S.!
Hi! I'm getting a 404 from nginx, when calling the controller.
The problem is that, when calling the url :
/media/cache/resolve/squared_thumbnail_small/uploads/article_image/beaatles-5ebf1642097fb.gif
That is something that can understand, because Nginx is trying to find a static file, that obviously it isn't.
So I'm trying to allow to that prefix (/media/) on Nginx configuration, that it serves as php file and not as static file with no luck.
That is my Nginx .conf:
<blockquote> ` server {
root /var/www/html/upload-files/public/;
index index.php index.html index.htm app_dev.php;
server_name uploadfiles.test;
location / {
try_files $uri /index.php$is_args$args;
}
## Images
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
access_log off;
add_header ETag "";
}
location @rewrite {
rewrite / /index.php;
}
## Execute PHP scripts
location ~ \.php$ {
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-UA-Compatible 'IE=Edge,chrome=1';
add_header X-Processing-Time $request_time;
try_files $uri =404;
fastcgi_pass fpm:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}`</blockquote>
Things that I have tried with no luck.(Obviously once at time)
location /media/ { } # Allow access to static files in /media/
``
location /media/.*.(js|css|png|jpg|jpeg|gif|ico)$ {
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-UA-Compatible 'IE=Edge,chrome=1';
add_header X-Processing-Time $request_time;
try_files $uri =404;
fastcgi_pass fpm:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
} # media liip bundle files```
location /media {
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-UA-Compatible 'IE=Edge,chrome=1';
add_header X-Processing-Time $request_time;
try_files $uri =404;
fastcgi_pass fpm:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
} # media liip bundle files```
location /media {
} # media liip bundle files`
Any idea how to allow that routes without getting a 404 from Nginx?
Hey Beis!
Ok, so you're correct that the URL /media/cache/resolve/squared_thumbnail_small/uploads/article_image/beaatles-5ebf1642097fb.gif
is meant to be a URL that is handled by Symfony - not one that Nginx serves. Well, Nginx should proxy it through index.php, like any other URL. My guess is that it's the .gif
ending that is confusing Nginx. Try putting the URL directly in your browser and removing the .gif
extension. If you get a 404 - but it's from Symfony (not Nginx), then we'll know the extension is the problem :). I would compare your Nginx config with the official one from the docs - https://symfony.com/doc/current/setup/web_server_configuration.html#nginx - it's written specifically to make Nginx look first for a physical file and then fallback to index.php if none is found (which is exactly what we want). The /media directory should not need any special handling.
Let me know what you find out!
Cheers!
Hi weaverryan !
You are right! I took a look to the official nginx config docs from symfony.com and I changed the location like it says!
I also tested it with .gif and it is working as expected!
Thanks :)
Hello guys!
I also had error in this episode, i've fixed it now.
Try to open link in the new tab in browser and check if error exists.
Main reasons of bug:
- access rights - try to create "media" directory in "public" dir with 777 rights
- incorrectly configured GD library - Imagine\Gd\Imagine::open method throws an exception
Here is my working config
liip_imagine:
driver: 'gd'
resolvers:
default:
web_path: ~
filter_sets:
cache: ~
squared_thumbnail_small:
filters:
thumbnail: { size: [200, 200], mode: outbound, allow_upscale: true }
loaders:
default:
filesystem:
data_root:
- '%kernel.project_dir%/public'
Dockerfile:
FROM php:7.3.6-fpm
RUN apt-get update && apt-get install -y \
git \
wget \
unzip \
libzip-dev \
libmcrypt-dev \
libpng-dev \
libpq-dev \
zlib1g-dev \
libfreetype6-dev \
libjpeg62-turbo-dev \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
&& docker-php-ext-install \
pdo \
pdo_mysql \
bcmath \
zip
RUN apt-get update \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
Hey adamsafr
Check the permissions of the folder where you are trying to upload your images. Also, can you show me the error stack trace? I'm not sure about what's going on
Cheers!
Hi MolloKhan ! I fixed this :)
saw that guys have errors with thumbnails
I attached my liip_imagine config file and dockerfile config in comment above if someone needs it
Great! Thanks for sharing it to others
Cheers!
Hi,
We are still waiting for the continuation of the course
Hi, I am amazed by the magic of LiipImagineBundle (as I always used to generate thumbs explicitly)... However, I came across a 'darker side' of it, which manifests when the original file changes or is deleted: the cached versions remain unchanged and fully accessible.
Strangely, I haven't found much info on this issue, neither here or online in general.
Anyway, I seem to have come to a manual solution which works for me: in the controller (or service) I inject an instance of Liip\ImagineBundle\Imagine\Cache\CacheManager (see https://symfony.com/bundles/LiipImagineBundle/current/cache-manager.html )
Before deleting the original file, I delete the cached versions by using the method remove($path) - where $path is the relative path from the public folder of the original file (not the full absolute path).
This does the job for me, but I wonder if this is the right way to do it? It seems to be very low-level compared to how automatic it is to generate the files.
Hey Mikamatto,
Thanks for sharing your solution with others. Actually, LiipImagineBundle now has console commands that help you to clear the cached images and regenerate new ones: https://symfony.com/bundles/LiipImagineBundle/current/commands.html - please check it out, I think it will help.
Cheers!
Hi ! the allow_upscale
option is not working and has been removed from the doc (commit here)
We can achieve the desired result with this :
squared_thumbnail_small:
filters:
upscale: { min: [ 200, 200 ] }
thumbnail: { size: [ 200, 200 ], mode: outbound }
Awesome - thank you for sharing the new solution!
Hello!
Is there an option to config the folder/files permissions? They are created with permissions set to 700 which generates a 403 error in my configuration.
I found in an old version the cache_mkdir_mode option but this has been removed since long time. I did not find what has replaced it.
I am on symfony 5.3 with "oneup/flysystem-bundle" v4.4.1 and "liip/imagine-bundle" v2.7.6
Thx!
Hey be_tnt
The answer may depends on your environment. Have you read this section of the docs? It may be useful https://symfony.com/doc/cur...
Cheers!
Thx for the link. I will check it ... but I have this issue since I used oneupflysystem and liip imagine librairies. Before that, the folder and files were created with the correct permissions.
Hey, I was checking the docs of that bundle and there's a config key you can use to specify your folder/file permissions. Give it a check https://github.com/1up-lab/...
Hope it helps!
Hi ! :-)
I noticed that I have a loss of image quality when using a liip imagine filter (thumbnail or relative resize). The image is less clear. Is that possible to prevent that ?
Hey @Loqman,
You can try to adjust image quality option, you can find some docs here https://github.com/liip/Lii...
Cheers!
Thanks for your reply sadikoff !
I tried it right after posting that question 😬 but the result wasn't good enough. I will do without that bundle for now but I will try it again for smaller pictures !
BTW there is one thing, I forgot to mention, for example if you are working on MacOS you will always get little blurry images, because of retina screen. To solve it properly you should create multiple thumbs with different sizes and use`
src-set`
Cheers!
Hi,
I followed all the steps given. However, when I refresh, no media folder is being created in the uploads por any other place.
Could you please advise why that might happen?
Hello I am trying to render the thumbnails through javascript.
- I have managed to inject <b>imagineCacheManager</b> as a dependency and the urls get sent using this function
$this->imagineCacheManager->getBrowserPath('/public/uploads/media/'.$mediaItem['path'],'squared_thumbnail_small');
- The data gets correctly sent to the javascript file and the urls get shown but previous to conversion with the "resolve" in the url.
<i>http://localhost:8000/media/cache/resolve/squared_thumbnail_small/public/uploads/media/20171216-133904-60b770c84413d.jpg</i>
I get the <b>"Not Found HttpException"</b> error. triggered by <b><i>vendor\liip\imagine-bundle\Controller\ImagineController.php
(line 149)</i></b>
I wonder wether I am just asking to much to the bundle.
Hey Juan E.!
That sounds like a pretty cool setup actually :). And, everything looks good to me. Regardless of how your use that URL (in JavaScript, in a normal img tag), if you go to that URL, LiipImagineBundle should generate the image. Line 149 is this one:
> throw new NotFoundHttpException(sprintf('Source image for path "%s" could not be found', $path), $exception);
Source: https://github.com/liip/Lii...
It makes me think that there is nothing wrong with your overall approach... but simply that the source image isn't found! You might have some directories misconfigured... or you might have a type in your argument to getBrowserPath(). Do a little digging and see if you can find any issues.
Cheers!
The configuration file in the version 2.6 of Liip_inagine bundle (for Symfony 5.2) has only the following entries
`liip_imagine:
driver: "gd"`
The lines have to be added to create the thumbnails (notice the way the thumbnail entry is specified in a single line along with the braces)
`filter_sets:
cache: ~
squared_thumbnail_small:
filters:
thumbnail: { size: [253, 253], mode: outbound, allow_upscale: true }
`
EDIT : I noticed that the indentation has been lost after I saved this comment. Indent the entries appropriately
Hey sridharpandu
Thanks for sharing it with others. I believe that's due to a change to the recipe of the bundle
Cheers!
Hi. My images are rendered inside a template of script Vue.js. I cannot use twig filters LiipImagineBundle there.
How can I get thumb of my images in this case?
Hey Dmitriy!
Excellent question! It depends on how you need to get the data in Vue.
One way would be to render the image url as a data- attribute on the element that you're rendering your Vue component into. Then you could read this when you're rendering your Vue app and pass the image path as a prop. So, your element would look something like:
<div data-image-path="{{ uploaded_asset(article.imagePath)|imagine_filter('squared_thumbnail_small') }}">
The other way, which is probably more common, is when you make an AJAX request to an endpoint (e.g. for a product) and need the thumbnail path for that image. In that case, you'll need to use the ImagineBundle services directly in PHP to add a new field to your AJAX response - e.g. thumbnailUrl. How you do that depends on how you've built your API. They talk a bit about that here - https://github.com/liip/LiipImagineBundle#resolve-programmatically - that service is autowireable using the CacheManager type-hint (and there are a few other services you can autowire if they are handy https://github.com/liip/LiipImagineBundle/blob/7c469724fdf818a3611249fe619d8e0001eeb649/DependencyInjection/LiipImagineExtension.php#L100-L102 )
Let me know if that helps!
Cheers!
Hi there !
Is there a way to use LiipImagineBundle for images stored in private directory (/var for example) ?
As far as I can undertstand, when a file is not public, we have to stream it in the controller in order to make it render / download.
So I checked if I could use LiipImagineBundle inside the controller, but I couldn't figure out how to achieve this... Or maybe is there a better wey to build thumbnails for private images ?
Thanks for your help !
Hey Stileex,
Good question! I think it's not possible with LiipImagineBundle... Why? Because anyway all the images you'e showing to your users become public, i.e. use may easily download (save) them, so even if they are originally in a private place - they will be public anyway when you will show them to the users - that's how the web works.
Though, I think it should be possible to generate thumbnails from private folders, see the docs about how to generate images in PHP: https://github.com/liip/Lii... - this should helps. I haven't tried it unfortunately, but even if it's not possible by design of the bundle - you still could place the images in public/, but to make them more secure - you may think of some random hashes in their names, this way they will be not guessable for users and they won't be able to download files just guessing the URL. And then you will be able to generate the thumbnail by sending an HTTP request with e.g. Symfony or Guzzle Client to specific URL. The only problem probably would be to use a different names for those thumbnails, otherwise it's still possible to change the URL and get the original image knowing its name.
I hope this helps!
Cheers!
Hi Victor,
Thanks for your very clear answer :)
I think the "hash name" solution is the simplest way to achieve what I want now (Admin images only visible to Admin).
But there is still a not so bad feature to solve about Article references (as you named them later in this course). All references are private, and then users can download them, and that's working perfectly.
But let's say I want the images among these references to be previewed as thumbnails in the web page, so I guess I should go deeper in the use of the Liip Imagine Bundle according to the link you gave me.
Thanks again for your help :)
Hey Stileex,
You're welcome, I hope this will help with the clear solution for you! Though, feel free to open an issue and discuss your use case in the repo, it might be a good new feature request I think. Or maybe there's already an existent thread there about handing images from private folder, you probably want to double-check it first
Cheers!
Hello friends! I am trying to use the Liip-Bundle following this tut. And it is not going well. I'm on Windows (yo!) and when I start the normal PHP-Built-In server I only get 404s for the /media/cache/resolver images. Only the symfony:server instance renders the images to me. The problem is here that I can't work properly with symfony server because every request has a 2 second delay (TTFB).
Is it possible that the routes are not resolved correctly with the built.in PHP server?
Hi Metin Ö.!
Sorry you're having trouble! Let's see if we can figure some things out :).
Try this: find a /media/cache/resolver URL (that is currently 404'ing), open it in a new tab, and prefix it with index.php. So you will have something like http://localhost:8000/index.php/media/cache/resolver
Does it work now? My guess is that it will ;). If so, the problem is that the built-in PHP web server is incorrectly not executing the request through Symfony - it's sort of looking for a "physical" file at that address and then is 404'ing when it's not there. The official way to solve this is to create a "router" script to help your built-in web server... but it may not be worth it just for this one thing. You might just be better off putting /index.php at the front of the URL when you need to try this. But, you can totally also create a "router" script - you can see an example here - https://www.php.net/manual/en/features.commandline.webserver.php#example-422 - and this is the router script that used to come with Symfony that you can steal from ;) https://github.com/symfony/symfony/blob/4.4/src/Symfony/Bundle/WebServerBundle/Resources/router.php
The problem is here that I can't work properly with symfony server because every request has a 2 second delay (TTFB).
Wow! That's super weird! Have you tried it with the --allow-http
option? That's a total guess that maybe SSL is slowing things down... I'm probably wrong with my wild guess. You can also report an issue here if you'd like :) https://github.com/symfony/cli
Cheers!
Hi Ryan! Thanks for the help - nice things happend ;) I tried sooo many things, but the idea with index.php/media/ didn't occur to me. So, yes it works... and I will give the router a try, if i cant fix the symfony server issues locally. I did try all the options, even --no-tls
,... still above 2 secs. Disabling xdebug, blackfire or shutting down docker-compose didnt help. I have no clue. 🤷♂️
I have this problem when installing liip
composer require liip/imagine-bundle
You are running Composer with SSL/TLS protection disabled.
Using version ^2.3 for liip/imagine-bundle
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "4.2.*"
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Installation request for liip/imagine-bundle ^2.3 -> satisfiable by liip/imagine-bundle[2.3.0].
- liip/imagine-bundle 2.3.0 requires symfony/asset ^3.4|^4.3|^5.0 -> no matching package found.
Potential causes:
- A typo in the package name
- The package is not available in a stable-enough version according to your minimum-stability setting
see <https: getcomposer.org="" doc="" 04-schema.md#minimum-stability=""> for more details.
- It's a private package and you forgot to add a custom repository to find it
Read <https: getcomposer.org="" doc="" articles="" troubleshooting.md=""> for further common problems.
Installation failed, reverting ./composer.json to its original content.
Hey Beniamin
Try to install bundle with composer require liip/imagine-bundle:^2.2
, i think it might help
Cheers!
did not work for me. in my symfony 5 the probem its solved. Thanks. In this project force the instalation in the json file and composer update and it worked.
Yeah, it's because liip/imagine-bundle
dropped support of Symfony 4.2 in latest release, so that's why I advised to use version 2.2
Anyways, we are working on fixing it on our tutorial code, so thank you very much for report, stay tuned!
Cheers!
How to do thumb generation in controller?
All my uploaded images are private (I am using filesystem) and I cannot user filters in twig.
I have tried few things like below:
`
/**
* @Route("/{asset}/photo/view/{id}/thumb", name="private_photo_view_thumb")
*/
public function photoViewThumb(UploadedFile $file, FileUploader $uploader, FilterService $imagine)
{
// 2) Runtime configuration
$runtimeConfig = [
'thumbnail' => [
'size' => [200, 200]
],
];
$handler = $uploader->getHandler($file->getPath());
$resourcePath = $imagine->getUrlOfFilteredImageWithRuntimeFilters(
$file->getPath(),
'squared_thumbnail_small',
$runtimeConfig
);
$response = new StreamedResponse(function() use ($file, $uploader, $resourcePath) {
$outputStream = fopen('php://output', 'wb');
$fileStream = $uploader->readStream($resourcePath, false);
stream_copy_to_stream($fileStream, $outputStream);
});
$response->headers->set('Content-Type', $file->getMimeType());
return $response;
}
`
But this bundle cannot see my private files (stored in var folder)
I am getting exception:
<br />Source image "files/cygnus/cat1-jpg-5d778185db17f.jpeg" not found.<br />
I do not understand why it needs path instead of file handler, and how I can set where these thumbs will be generated, mainly I need private thumbs too.
Hey Krzysztof K.!
Hmm. Can you post a screenshot of the full stack trace? I'm not sure exactly which spot is causing the error. But... my guess is that the getUrlOfFilteredImageWithRuntimeFilters()
method doesn't like what you're passing via $file->getPath()
? Is that correct? A few things to get started:
1) In theory, if you've configured ImagineBundle to read from Flysystem, then if you pass it a path like files/cygnus/cat1-jpg-5d778185db17f.jpeg
it would know how/where to fetch that (e.g. it would get that from S3).
2) If you need to write an endpoint that does all the thumbnailing manually (including saving the thumbnailed file back your storage and streaming the image to the user), ImagineBundle becomes a much less appealing option... because you're doing much of the work that it's supposed to do. But I'm not saying that you're do something wrong - not at all - you just have a more complex use-case. What I'm saying is that it may be even simpler to graph a more "utility-based" image manipulation library (i.e. a pure PHP lib that is good at manipulating images... and that's all - like Intervention) then, in your controller, read the source image from Flysystem, send it through Intervention, save it back through Flysystem, then serve it to your user. Your controller will look very similar, but instead of trying to ask ImagineBundle to thumbnail the file (which is just awkward... as its main use-case is not for you to do this directly in code, but to use the Twig filters) you would do it yourself.
Let me know if this helps!
Cheers!
Hi Ryan, it is pretty bad that I cannot use that bundle, I have tested al different paths, and nothing works, Flysystem do not have method to return full path and ImagineBundle has no option to accept file instead of path.
My current solution:
`
/**
* @Route("/{asset}/photo/view/{id}/thumb", name="private_photo_view_thumb")
*/
public function photoViewThumb(UploadedFile $file, FileUploader $uploader)
{
if (!$uploader->has('thumbs/'.$file->getPath())) {
$imagine = new \Imagine\Gd\Imagine();
$image = $imagine->open(dirname(dirname(dirname(__DIR__))).'/var/uploads/'.$file->getPath());
$size = new \Imagine\Image\Box(300, 300);
$mode = \Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND;
$thumbnail = $image->thumbnail($size, $mode);
$resourcePath = dirname(dirname(dirname(__DIR__))).'/var/uploads/thumbs/'.$file->getPath();
$thumbnail->save($resourcePath);
}
$response = new StreamedResponse(function() use ($file, $uploader) {
$outputStream = fopen('php://output', 'wb');
$fileStream = $uploader->readStream('thumbs/'.$file->getPath(), false);
stream_copy_to_stream($fileStream, $outputStream);
});
$response->headers->set('Content-Type', $file->getMimeType());
return $response;
}
`
Hey Krzysztof K.!
Yea - that's more-or-less what I would have done. I typically prefer Intervention (http://image.intervention.io/) when I need to do direct image manipulations, but that's a minor detail. It's unfortunate the bundle doesn't have a nice interface for these direct manipulations... I think it just hasn't been its main use-case.
Happy you got it working either way!
Cheers!
uploaded_asset(article.imagePath)|imagine_filter('squared_thumbnail_small')
is not working as advertised. At least in my case (Sf 4.3 and Liip 2.1.0).
The code example as shown in the video produces an image path as follows: http://localhost:8888/symfonyproject/public/media/cache/resolve/squared_thumbnail_small/symfonyproject/public/uploads/image.jpeg
resulting in a broken image. The correct image path is http://localhost:8888/symfonyproject/public/media/cache/squared_thumbnail_small/image.jpeg
The correct path is produced by article.imagePath|imagine_filter('squared_thumbnail_small')
. As I'm a Symfony novice I haven't yet figured out how uploaded_asset() and imagine_filter() interfere, so any hint or help or solution is highly appreciated.
<b>EDIT</b>
I also noticed that in my /media/cache directory there is no /uploads subdirectory as seen in the video.
Hey Eric,
That's because you have the project in a subdirectory that's called "symfonyproject" in your case. I'd recommend you to use the "symfony serve" command or "bin/console server:run" command at least to start the built in server for this project. This way your project will be in the root directory, not in a subdirectory, and then it should work.
Otherwise, you need to add more configuration for your liip config file to get it working in a subdirectory, i.e. override some options with proper paths manually. But when your project is in the the root directory - those paths are determined correctly automatically by the liip bundle.
I hope this helps!
Cheers!
Hey Victor, thanks a lot for your fast reaction.
Using the symfony server did solve the issue. But could you point me somewhere, where I can find a way to configure liip bundle with project in subdirectories? I already tried the section at the Symfony Liip Bundle Configuration Page but without any luck.
Hey Eric,
Looks like there're only 3 options that configure paths in the bundle: web_root, cache_prefix, and data_root. That's something you need to configure for your project.
I hope this helps!
Cheers!
"Houston: no signs of life"
Start the conversation!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"aws/aws-sdk-php": "^3.87", // 3.87.10
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.10.1
"doctrine/doctrine-bundle": "^1.6.10", // 1.10.2
"doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // v2.0.0
"doctrine/orm": "^2.5.11", // v2.7.2
"knplabs/knp-markdown-bundle": "^1.7", // 1.7.1
"knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
"knplabs/knp-time-bundle": "^1.8", // 1.9.0
"league/flysystem-aws-s3-v3": "^1.0", // 1.0.22
"league/flysystem-cached-adapter": "^1.0", // 1.0.9
"liip/imagine-bundle": "^2.1", // 2.1.0
"nexylan/slack-bundle": "^2.0,<2.2.0", // v2.1.0
"oneup/flysystem-bundle": "^3.0", // 3.0.3
"php-http/guzzle6-adapter": "^1.1", // v1.1.1
"phpdocumentor/reflection-docblock": "^3.0|^4.0", // 4.3.0
"sensio/framework-extra-bundle": "^5.1", // v5.2.4
"stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
"symfony/asset": "^4.0", // v4.2.3
"symfony/console": "^4.0", // v4.2.3
"symfony/flex": "^1.9", // v1.21.6
"symfony/form": "^4.0", // v4.2.3
"symfony/framework-bundle": "^4.0", // v4.2.3
"symfony/property-access": "4.2.*", // v4.2.3
"symfony/property-info": "4.2.*", // v4.2.3
"symfony/security-bundle": "^4.0", // v4.2.3
"symfony/serializer": "4.2.*", // v4.2.3
"symfony/twig-bundle": "^4.0", // v4.2.3
"symfony/validator": "^4.0", // v4.2.3
"symfony/web-server-bundle": "^4.0", // v4.2.3
"symfony/yaml": "^4.0", // v4.2.3
"twig/extensions": "^1.5" // v1.5.4
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0", // 3.1.0
"easycorp/easy-log-handler": "^1.0.2", // v1.0.7
"fzaninotto/faker": "^1.7", // v1.8.0
"symfony/debug-bundle": "^3.3|^4.0", // v4.2.3
"symfony/dotenv": "^4.0", // v4.2.3
"symfony/maker-bundle": "^1.0", // v1.11.3
"symfony/monolog-bundle": "^3.0", // v3.3.1
"symfony/phpunit-bridge": "^3.3|^4.0", // v4.2.3
"symfony/stopwatch": "4.2.*", // v4.2.3
"symfony/var-dumper": "^3.3|^4.0", // v4.2.3
"symfony/web-profiler-bundle": "4.2.*" // v4.2.3
}
}
Thank you! Everything is functioning correctly on my local setup. When deploying to my Apache2 server, I encountered a situation where I had to manually create the necessary folders. Here's the process I followed, and I hope it might be useful to others:
Thanks again!