presta/image-bundle
Symfony bundle for image handling and manipulation, providing filters, thumbnails, and caching through a simple, configurable API for generating and serving optimized images.
This is a small, low-adoption Symfony bundle (24 stars, 0 dependents) built for the classic "upload + resize + display" flow. Treat it as a focused helper, not a full media library. v5.1.1 is a dependency-compatibility release, not a feature release — there is no new API to learn, but the install story changed slightly in your favour.
Install and register
composer require presta/image-bundleconfig/bundles.php (or AppKernel on legacy apps). Because the bundle predates Symfony Flex, expect to add the bundle entry manually and to import its routing/config only if the docs say so.vich/uploader-bundle 3.x (PR #104). If your app is already on Vich 3, v5.0.0 would have blocked resolution — go straight to 5.1.1. If you are still on Vich 2.x, either upgrade Vich first or pin presta/image-bundle:5.0.*; do not mix (see Gotchas).symfony/* constraints against your Symfony version first. Vich compatibility is now solved; Symfony major compatibility is still the single biggest go/no-go signal.Configure the upload target
upload_dir / upload_root style keys). If the bundle ships a Configuration.php, read it — it is the authoritative reference since documentation is sparse.mapping/uri_prefix. Keep them pointed at the same physical directory or you will debug a broken image for an hour.First use case — a single image field on an entity
ImageType form field instead of a raw FileType. It bundles the preview, the "delete/replace" affordance, and the resize call in one widget.$form->handleRequest() and $form->isValid(), let the uploader move the file and the bundle's image manager produce resized variants, then set the resulting filename on your entity and flush.Render it
Where to look first: DependencyInjection/Configuration.php, the ImageType class, and the image manager service. Those three files define the whole contract.
Standard upload flow (entity-backed image)
ImageType with options for preview sizing and delete label.presta_image.manager) to move/resize the temp file into the upload root.Letting Vich own the lifecycle (the v5.1.x-friendly pattern)
@Vich\Uploadable, the 3.x upgrade is the real work, not the Presta bump.Remote image ingestion
http/https only) and a size/time limit — see Gotchas.Resize presets rather than ad-hoc dimensions
Multiple image fields / collections
CollectionType and let each child own its filename. The bundle handles one image per field; it is not a gallery manager, so keep the collection/ordering logic in your own entity.Deletion and replacement
delete as an explicit checkbox in ImageType (if supported) or as a separate action. On delete: remove the DB reference, then unlink the stored file — and ideally the cached resized variants too. With Vich in play, use its listener rather than hand-rolled unlink so both layers agree on what was removed.Integration tips
ImageUploader) so controllers stay thin and you can unit-test the flow without the form.updatedAt on the image or entity and append it as a cache-busting query string to image URLs — the bundle's cache resolver won't always invalidate regenerated thumbnails.composer.json comment or upgrade notes.Content-Type before handing bytes to Imagine.0775 vs 0777 issue or a mismatch between the configured web path and the real document root — now more likely, because two config surfaces (Vich + Presta) must agree. Log the resolved absolute path on failure; the bundle's exceptions are often terse.?v=<timestamp> to URLs.ImageType may swallow a failed upload and leave the field empty rather than erroring. Always assert after handling the form that the expected filename is non-null when the field is required.upload_dir: uploads/ and upload_dir: uploads can resolve differently. Use absolute paths for the filesystem root and relative paths only for the public URL.ImageType can be extended via form type extensions if you need extra validation.uri_prefix matches the real document root → URL reachable in the browser → cache variant generated. Most "broken image" reports stop at steps two or three.How can I help you explore Laravel packages today?