mrgoodbytes8667/image-bundle
A Laravel image management bundle that handles uploading, storing, and serving images with configurable sizes and variants. Simplifies resizing, thumbnails, and file organization behind a clean, framework-friendly API.
This is a low-signal package (0 stars, 0 dependents, license declared NOASSERTION, last release Nov 2024), so treat the first hour as a compatibility spike rather than an integration.
Install and inspect before wiring anything up.
composer require mrgoodbytes8667/image-bundle
Then look at vendor/mrgoodbytes8667/image-bundle/ — read README.md, composer.json (for symfony/* constraint ranges and the actual SPDX license), and src/DependencyInjection/*Extension.php + Configuration.php. Those two files tell you the config root name and every option the bundle actually supports.
Register the bundle. Symfony 5/6: add to config/bundles.php. Symfony 7 Flex projects still use config/bundles.php; there is no AppKernel path to worry about. The bundle class FQCN is in the package's composer.json under extra.symfony or in the README.
Dump the reference config rather than guessing keys.
bin/console config:dump-reference <root>
Use the root name found in step 1 (commonly image_bundle, image, or mrgoodbytes_image). If the command errors with "no extension", the bundle wasn't registered or the alias differs — check getContainerExtension().
Find the public surface. bin/console debug:container --show-private | grep -i image reveals the cache service, the resolver/loader, and any tagged handlers. That is your actual API; don't rely on documentation that may be stale relative to the Nov 2024 release.
First use case: cache a remotely-hosted or dynamically-generated image to a local adapter and serve it through a controller/Twig helper, so subsequent requests hit the cache instead of re-fetching or re-rendering. Confirm this works end-to-end with one image before you build a pipeline around it.
Service injection over static helpers. The bundle’s value is the caching service; inject it into controllers, message handlers, or Twig extensions rather than reaching for globals. Bind it once in config/services.yaml:
services:
App\Service\ImagePipeline:
arguments:
$imageCache: '@<service.id.from.debug:container>'
Controller-as-proxy pattern. The most robust day-to-day shape for an image-caching bundle is a thin controller that resolves a cache key, returns a cached response if present, otherwise generates/fetches, stores, and streams with proper headers:
public function show(string $path, ImageCache $cache, Request $request): Response
{
$key = hash('xxh128', $path . '|' . $request->get('v', ''));
if ($hit = $cache->get($key)) {
return new Response($hit->getContents(), 200, [
'Content-Type' => $hit->getMimeType(),
'Cache-Control' => 'public, max-age=31536000, immutable',
'ETag' => $key,
]);
}
// generate, $cache->set($key, $binary), return response
}
Immutable, version-keyed URLs (?v=) sidestep invalidation almost entirely — the cheapest caching strategy available.
Compose with an existing image stack. If you already run liip/imagine-bundle for filters/thumbnails, use this bundle as the storage layer behind a custom CacheResolver or a decorated controller, not as a replacement. Two image bundles fighting over the same routes and Twig helpers is a common source of confusion; pick one for transformation and one for persistence.
Warm the cache asynchronously. For a catalog of images, don't populate on first request — dispatch a Message per image from a cache:warmup command or an event subscriber (kernel.terminate for low-volume). This keeps request latency flat and makes cache behaviour observable.
Twig usage. If the bundle ships a Twig extension, prefer it for templates and reach for the service directly in controllers. Verify the extension is registered (bin/console debug:twig | grep -i image) before writing templates against it.
HTTP-level caching first. Before you tune the bundle's storage adapter, put an ETag/Last-Modified + Cache-Control on the response. Most "image caching" wins are CDN/HTTP-cache wins; the bundle's local cache is a second line of defence.
NOASSERTION. This is the single biggest blocker. NOASSERTION in composer.json may mean a non-standard or missing license file, which many legal/procurement reviews will bounce. Read LICENSE in the package root before adopting for anything commercial. If there's no license file, you have no grant of rights — do not ship it.composer.json, and check the constraint range against your Symfony minor. Test on your target PHP version before committing.dev-main/branch alias only after reading the diff; otherwise expect to fork and patch.bin/console cache:clear — a stale var/cache/*/Container*.php will silently keep old option values and produce baffling "option ignored" symptoms.var/cache or public/, the web user needs write access. var/cache is dev-friendly but wiped by cache:clear; point the pool at a stable path (e.g. %kernel.project_dir%/var/image-cache) for production.find ... -mtime +30 -delete or a custom command) or you'll fill the disk quietly.bin/console debug:container --tag=<bundle tags>, debug:config <root>, and debug:event-dispatcher are faster than reading source. For runtime, symfony/profiler's cache panel (if the bundle uses a Symfony cache pool) shows hit/miss per request.<bundle>.cache), a tagged loader/resolver interface, and event subscribers around generation. If none of those exist, the bundle is a black box — wrap it in your own thin service so you can swap it out later without touching call sites.ImageCacheInterface) in your app. If the bundle is abandoned, a Flysystem + Intervention Image implementation is a day's work, and you won't have to rewrite controllers.How can I help you explore Laravel packages today?