Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sulu Image Optimizer Bundle Laravel Package

innomedio/sulu-image-optimizer-bundle

A Sulu CMS bundle for automatic image optimization—compresses and resizes uploaded media to cut file sizes and speed up page loads while preserving visual quality. Integrates with Sulu's media management so images are optimized without extra manual steps.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Require and register. composer require innomedio/sulu-image-optimizer-bundle. Symfony Flex may auto-register it; otherwise add the bundle class to config/bundles.php. Check the package's composer.json constraints against your Sulu and Symfony versions. Pin at minimum ^3.1 — v3.1 fixed uppercase-extension uploads (.JPG, .PNG) that previously blew up with UnsupportedImageFormat, plus related format-detection and ignore_types handling. Older tags carry that bug. The package's maintenance history is thin (historically archived with minimal stars/dependents), so even with a 3.1 patch release, treat version drift as your first risk and review the repo's recent commit activity before adopting.

  2. Read the wiring first. Open vendor/innomedio/sulu-image-optimizer-bundle/ and look at DependencyInjection/ and Resources/config/services.yaml. The key question is which Sulu service it decorates — most likely sulu_media.media_manager or the media storage adapter. That single fact tells you where in the upload lifecycle optimization happens. Confirm with bin/console debug:container sulu_media.media_manager --show-arguments.

  3. Install optimizer binaries. These bundles typically shell out to jpegoptim, optipng, pngquant, gifsicle, svgo, and/or cwebp. Add them to your Docker image or server provisioning and verify with which jpegoptim inside the runtime container. Without them, uploads either silently skip optimization or throw.

  4. First use case. Upload a 3–5 MB JPEG through the Sulu admin into a media collection, then compare the file stored under your media storage (local var/uploads or S3) with the original. Confirm the media record still renders in the admin and that Sulu's image formats generate. Then repeat with a deliberately uppercase-extension file (PHOTO.JPG) — that's the exact regression v3.1 addresses, and it's a one-second check that tells you whether you're actually on the fixed version. That one test validates wiring, binaries, config, and version together.

  5. Configuration. Publish or override the bundle config (typically config/packages/innomedio_sulu_image_optimizer.yaml or a sulu_image_optimizer key). Start with only enabled formats and quality. The ignore_types key (touched by v3.1) controls which mime types are skipped — verify its expected format against the bundle's own docs/tests before relying on it, since format-detection changes in 3.1 may alter what strings it accepts. Run bin/console cache:clear after changes.

Implementation Patterns

Drop-in default. The primary pattern is zero-code: the bundle hooks the media save path, so uploads via the admin, MediaManagerInterface::save(), or the Sulu media API are optimized before persistence. Treat it as infrastructure, not application code.

Verify the decoration point. Confirm whether it decorates sulu_media.media_manager (optimizes the UploadedFile before storage) or the storage adapter (optimizes after write). The former is cleaner and preserves Sulu's mime/extension handling. If the bundle doesn't expose this clearly, a small decorator of your own around MediaManagerInterface is often more maintainable than the package.

Normalize filenames at the edge. Even on v3.1, don't let user-supplied filenames be the only thing standing between an editor and a failed upload. If you have a form type or upload controller in front of Sulu, lowercasing the extension before handoff is cheap insurance and keeps you working if the package is ever dropped. This is especially relevant for any custom upload path that bypasses Sulu's own normalisation.

Per-collection rules. Sulu media collections are the natural place for policy — "press images keep original quality, marketing images get aggressive compression." If the bundle config is global only, wrap it: a Doctrine prePersist listener on Sulu\Bundle\MediaBundle\Entity\Media, or a decorator around the optimizer, can inspect the collection and adjust quality before optimization runs. Keep this thin; don't reimplement image processing.

Async for large assets. Synchronous optimization in the admin request is fine for a few MB but blocks editors and risks PHP timeouts on large TIFFs/PNGs. Pattern: upload normally, dispatch a Symfony Messenger message with the media ID, optimize in a worker, replace the file via StorageInterface, then invalidate Sulu's image-format cache for that media. This is the main reason to fork if the package is strictly synchronous.

Backfilling existing media. The bundle optimizes new uploads only. For an existing library, write a console command that pages through MediaRepository, resolves each file through sulu_media.storage, runs the same optimizer service, and writes back. Batch it, log before/after sizes, and invalidate caches at the end. This is destructive by definition — back up first.

CI/CD. Put binaries in the base image, not a post-deploy script. Add a functional test that calls MediaManagerInterface::save() with a fixture image and asserts the stored size is smaller than the source. Include an uppercase-extension fixture — the v3.1 fix exists precisely because nobody had that test. That catches missing binaries, version regressions, and misconfiguration in CI before editors do.

Thumbnails. Optimization applies to originals; Sulu's image formats are derived and cached separately. You get lower storage and faster thumbnail generation, but thumbnails themselves aren't optimized unless you also tune LiipImagine/Sulu image format filters. Decide which layer you're targeting.

Gotchas and Tips

  • Uppercase extensions broke uploads until v3.1. .JPG/.PNG uploads threw UnsupportedImageFormat on earlier tags. Verify your locked version, and if you're stuck below 3.1, either patch/backport the change or normalise extensions before the media manager sees them. Note this is an upload failure, not a silent skip — editors see a hard error, which is at least diagnosable, but it looks like a Sulu bug rather than a bundle bug until you check -vvv logs.
  • ignore_types semantics shifted in v3.1. Format detection and ignore_types handling both changed in the same release. If you set ignore_types on an older version, re-read your config and re-test the skipped formats after upgrading — a mime-string that previously matched may now be detected differently. Diff the bundle's config definition in DependencyInjection/Configuration.php across the upgrade rather than assuming compatibility.
  • Thin maintenance history. Low stars, few dependents, previously archived. v3.1 (a community PR from @psalamontech) shows someone is still merging fixes, but it's not evidence of sustained maintenance. Pin the version, fork into your VCS if you depend on it heavily, and budget maintenance. If the code is thin, reimplementing the decoration yourself around spatie/image-optimizer may be lower risk.
  • Silent failures are the default failure mode. Missing binaries or unsupported formats often degrade to "upload succeeds, nothing optimized." Log optimizer output and track bytes saved per upload so you notice.
  • Irreversible by design. Optimization happens before storage, so the original is gone. If editorial or legal needs the untouched asset, store originals separately (an S3 prefix or a separate collection) before optimization.
  • Metadata stripping. Many optimizers drop EXIF/IPTC/ICC. If you rely on EXIF credits, GPS, or color profiles, configure preservation or accept the loss deliberately.
  • Limits still apply. upload_max_filesize, post_max_size, memory_limit, and max_execution_time govern the request before and during optimization. A 40 MB PNG that uploads fine can still OOM during processing.
  • Format edge cases. Animated GIFs, SVGs, and already-modern WebP/AVIF are where optimizers break or mangle. Test each format you actually accept; exclude SVG unless svgo is configured carefully.
  • Cache invalidation. Replacing an original via backfill or an async worker does not automatically regenerate Sulu image formats. Clear the media/image-format cache or the admin shows stale thumbnails.
  • Decoration priority. If other bundles also decorate sulu_media.media_manager, order matters. Set decoration_priority explicitly instead of relying on load order.
  • Debugging. Reproduce outside Sulu first: run the optimizer binary manually on the same file and compare. Then use debug:container to see the actual decorated class, -vvv logs for the optimizer command, and exiftool/file on the stored asset to confirm what changed. For format-detection issues, log the detected mime type before the optimizer runs — that's where both the uppercase-extension bug and ignore_types mismatches surface.
  • Extension point of last resort. If the bundle exposes an optimizer chain, add a custom optimizer service rather than editing vendor code. If it doesn't, the clean seam is your own decorator around MediaManagerInterface — keep it the only place that knows about the package so removal later is a one-file change.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console