Chapters
40 Chapters
|
4:39:58
|
Login to bookmark this video
-
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!
17.
Flysystem <3 LiipImagineBundle
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part 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.
This tutorial is built on Symfony 4 but works great in Symfony 5!
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
}
}
26 Comments
If you are using the
league/flysystem-bundleFlysystem bundle, which is created by the authors of Flysystem and seems to be more actively maintained, your configuration will look a little different:The way this bundle's configuration works is a little more straightforward in my opinion, but the LiipImagine bundle does detail configuration options for both bundles in their docs.
Thanks for sharing it @jdevine
case 1. If I use no filter and point to the original photo, I have no pb.
case 2. If I point to the original photo with the "square thumbnail small" filter, I get a response with status 403 (forbidden).
case 3. If I point directly to media / cache and the user has not viewed the photo at least once, it does not exist in this folder
`
"mRender": function (data, type, full) {
case 1 - return "<a href='https://folder/" + full.photo_file_name + "' target='_blank'><img src='https://folder/" + full.photo_file_name + "') }} ></a>" => ok
case 2 - return "<a href='https://folder/" + full.photo_file_name + "' target='_blank'><img src='https://folder/" + full.photo_file_name + "| imagine_filter('squared_thumbnail_small')') }} ></a>" => 403. status forbiden
case 3 - return "<a href='https://folder/" + full.photo_file_name + "' alt='photo du joueur' target='_blank'><img src='https://.../media/cache/squared_thumbnail_small/photos/" + full.photo_file_name + "') }} ></a>" => does not exist if the user has not seen the photo at least once
`
Do you think this is from my setup on S3? if yes do you have a solution if not do you have any suggestions
bucket: character
folder1: photo
file2: passport
folder3: media / cache
....
Do I have to show my scripts
ok i understood the origin of my problem. I was generating my filter from javascript through Datatable. The filter was not performing correctly. So, I generate it directly in TWIG and everything works normally. I will look later on how to dynamically generate a filter with js or if you have already done this I am interested
Hi Kehlhoffner E.!
I'm glad you figured it out - and thanks for following up with your solution :).
If I understand the situation correctly, it's a very common thing. Since your Symfony app (via the Twig filter) is responsible for thumbnailing the image and returning the correct path, that logic *must* be done in your Symfony app (via the Twig filter), it can't be done in JavaScript (as you correctly determined). There's... not much way around this: it would effectively be similar to trying to look up a value in the database from JavaScript: it's just not information / a capability that JavaScript has. If you *did* want to do the work in JavaScript, you would need to probably setup an API endpoint that you could send the original image filename to... and it would return the thumbnailed path. That's... probably added complexity that's not worth the benefit.
What I would personally do (and this may be the exact solution you're doing) is return HTML from your data tables AJAX endpoint (if possible, I can't remember the rules around datatables). This isn't a workaround: I love doing this! My Twig template is already really good at returning HTML... so even if I need some new content from JavaScript, I'll get that content by making an AJAX call that returns the HTML (instead of returning the JSON... and then turning that into HTML in JavaScript). But, again, this all depends on how your app works and the rules of datatables (which you know better).
Anyways, that was a long way of saying: I would probably stick with whatever your current Twig solution is: that is the correct solution to me :). But if you have any questions or doubts, let us know.
Cheers!
case 1 is ok
case 2 and 3 should be the same, I mean there shouldn't be any difference in this 2 definitions
So from my point of view we need to solve this 403 error, why it's thrown and what part of code is responsible for it. To check case 3 try to run
php bin/console debug:routerand check for this routesBTW there is one way to burst the cache programatically
Cheers!
Hello, this is the first time that I participate in a discussion...
First of all, well done for the quality of the explanations. I managed to set up Uploads of files (pdf) + photos (jpg) :)
If I understood correctly, the thumbnail is stored in media / cache at the time of reading?
Here is my problem:
A user (role_user) saves a photo from a form and is then redirected to a page.
Consequently, the user has not necessarily viewed his photo.
So at the moment the photo is not yet stored in media / cache.
As director (role_dir) I would like to have access to this thumbnail but from media / cache and not from the original photo folder (too heavy & slower)
In other words, can I force the saving of the photo in media / cache even before it is viewed by the user (role_user)
Or do you have another solution?
I don't know where to put my scripts
Hey Kehlhoffner E.
Hm probably I don't see the full picture, but it's no matter who is trying to see your photo thumbnail it totally depends on template and what url of image are you using. It should be generated on the fly. You can see examples in the chapter 11 of this course!
Cheers
Hey there ,
Came across an error:
`Liip\ImagineBundle\Imagine\Cache\Resolver\FlysystemResolver::__construct(): Argument #1 ($flysystem) must be of type League\Flysystem\FilesystemInterface, League\Flysystem\Filesystem given, called in /var/www/erp/var/cache/dev/ContainerEyPR8ga/App_KernelDevDebugContainer.php on line 1323`
liip_imagine.yaml
`resolvers:
Hey Petru L.
What version of the Flysistem library are you using? The latest version comes with a few critical changes that are not compatible with the version used for this tutorial
Cheers!
Hey MolloKhan ,
"oneup/flysystem-bundle": "^4.0",Is there anything i could do to fix it? This package simplify my work greatly and i would like to keep using it. Thank you
Hey Petru! Yea, there must be a way. Have you read this answer of Ryan? https://symfonycasts.com/sc...
Perhaps if you read this guide you may find out a solution https://flysystem.thephplea...
Cheers!
MolloKhan , yes i've done exactly what he did, and i couldn't find anything on that migration guide. I'm guessing this is more of a oneup_flysystem bundle issue?
Hi,
I try to use Flysystem loader. I write this
into liip_imagine.yaml and I change my template
src="{{ photo.imagePath|imagine_filter('image_thumb') }}"but there is no generation of new thumbnail image
The dump of
{{ dump(photo.imagePath) }}display the right path for image and name of fileHave you any advise to debug this ?
Hey Stephane!
Hmm. Yes, this stuff can be difficult to debug! When you use the
|imagine_filter('image_thumb')filter, that should output a different URL that (when things work) returns the image. Depending on your situation, the URL that this will output will be 1 of 2 things:1) If imagine_filter detects that the thumbnail for this image does not exist yet, it will return a URL that actually points to a Symfony route & controller from the bundle. When the user's browser hits this URL it should (when things are working) actually create the thumbnail, save it, and return it.
2) If imagine_filter DOES think that the thumbnail for the image already exists (this is possible, in your situation, it's possible it thinks the thumbnail exists, but then it generates the wrong URL to it), then it will generate a direct URL to the real image (it will not point to a Symfony route and controller).
So to debug this, I would look at the
src=attribute on your image. If the URL has a path like/media/cache/resolvein it, then you are in situation 1. Else, you are in situation 2.Situation (1) is a bit easier. You can open the URL of the image in a new browser tab and (hopefully) it will show you some error (like it can't find the source image for some reason). This is trickier to debug when you have Flysystem as an extra layer of abstraction.
Situation (2) is a bit trickier. It means (most likely) that the thumbnail WAS successfully created. But then it is generating an incorrect URL to the public image. This would, once again, be some sort of configuration issue - related to the public path of the images.
Let me know if this helps!
Cheers!
Hey @Ryan
Thank for your reply.
I have try to open the URL of image and I have a page error 500 :
Liip\ImagineBundle\Binary\Loader\FlysystemLoader::__construct(): Argument #2 ($filesystem) must be of type League\Flysystem\FilesystemInterface, League\Flysystem\Filesystem given, called in /home/stephane/www/perso/symfony/snowTrickv2/var/cache/dev/ContainerIG8Gtvi/getLiipImagine_Binary_Loader_PublicUploadsAdapterService.php on line 26
I think that is why I use $publicUploadsFilesystem: '@oneup_flysystem.public_uploads_adapter_filesystem' into my service.yaml file.
I don't know this is the right service to use.
When I use symfony console debug:container flysystem
I have this list :
[0 ] liip_imagine.binary.loader.prototype.flysystem
[1 ] liip_imagine.cache.resolver.prototype.flysystem
[2 ] oneup_flysystem.adapter_factory.local
[3 ] oneup_flysystem.adapter_factory.awss3v3
[4 ] oneup_flysystem.adapter_factory.ftp
[5 ] oneup_flysystem.adapter_factory.sftp
[6 ] oneup_flysystem.adapter_factory.in_memory
[7 ] oneup_flysystem.adapter_factory.customadapter
[8 ] oneup_flysystem.adapter_factory.async_aws_s3
[9 ] oneup_flysystem.adapter_factory.gitlab
[10] oneup_flysystem.adapter.local
[11] oneup_flysystem.adapter.awss3v3
[12] oneup_flysystem.adapter.ftp
[13] oneup_flysystem.adapter.sftp
[14] oneup_flysystem.adapter.memory
[15] oneup_flysystem.adapter.async_aws_s3
[16] oneup_flysystem.adapter.gitlab
[17] oneup_flysystem.mount_manager
[18] oneup_flysystem.filesystem
[19] oneup_flysystem.public_uploads_adapter_adapter
[20] oneup_flysystem.public_uploads_adapter_filesystem
[21] League\Flysystem\Filesystem
[22] League\Flysystem\FilesystemOperator $publicUploadsAdapterFilesystem
Have you an idea of which is the right one ?
Cheers!
Hi again!
Sorry for the slow reply! Ok, here’s the situation. You’re using a new version of Flysystem (v2). That’s fine except that LiipImagineBundle doesn’t support it yet. Or, to be more accurate, support for v2 *has* been added, but we are waiting for a new release of the bundle that contains this change :).
So, you have 2 options:
- use flysystem v1. You would do that by changing the version of one up flysystem bundle in your composer.json to ^3.7 and then running composer update (v4 of that bundle only works with flysystem 2).
2) or, use the unreleased version of liip imagine bundle. You would do this by setting the version to “dev-main” in composer.json and run composer update.
I’m going to follow up on tying to get a new release for the bundle... and check to see if flysystem 2 will require any other changes. Sorry for the troubles!
Cheers!
Hi Ryan,
Thank for your advice.
I have succeeded to display images with flysystem loader to update liipimagine bundle to dev branch (2.x-dev exactly).
Finally I use https://github.com/thephple... for manage flysystem and not https://github.com/1up-lab/... that you use for this tutorial.
What do you thing if it is better or not ?
I have seen that you are speaker for SymfonyLive Online on 9 april. Nice. I am impatient to learn more about panther.
Cheers!
Hi Stéphane!
Nice work! And thanks for following up so that I know that this combination works :).
About your question about the phpleague flysystem, you probably already saw my reply on your other thread, but for the benefit of others, here’s the link: https://symfonycasts.com/sc...
> I have seen that you are speaker for SymfonyLive Online on 9 april. Nice. I am impatient to learn more about panther.
Yaaaay! I’m super excited by MANY enhancements in testing tools over the past 6 months, Panther being just one of them ;).
“See” you there!
Cheers!
Hey, how's it going?
I thought a couple of minutes about a twig ext function we made before and why not use it so far ('uploaded_asset()')?
Just delete a 'public' from path which is provided by \App\Service\UploadHelper::getPublicPath and that's it
Hey Roman P.
It may make sense to do that but it depends on your application. If other services will need to know the public path of your assets, then you want to have such logic in only one place, and injecting a TwigExtension class into other services is not really a good idea
Cheers!
Hi
How would you go about deleting the cache thumbnails when the main image is changed? Is this possible or should I just clear the cached images and have them re-generate?
I've copied the code that deletes the main image and set it to :
$result = $filesystem->delete('media/cache/squared_thumbnail_small/'.$directory.'/'.$existingFilename);
However I need to check all the thumbnail locations (filter sets from liip_imagine.yaml).
Thanks
Steve
Hey Steve D.
Here is a slightly better approach: https://github.com/liip/Lii...
Also there are some commands for clearing cached images: https://symfony.com/doc/2.0...
Cheers!
Hi Diego
Thank you for the info. Thats pretty much what I did. I think I've learnt more on this tutorial than any other. Superb series. Thanks
Cool! Let's keep learning ;)
I've managed to sort this, brought in the cache manager and passed the directory and filename.
$this->cacheManager->remove($directory . '/' . $existingFilename);
Regards
"Houston: no signs of life"
Start the conversation!