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

Media Bundle Laravel Package

soft-passio/media-bundle

A Laravel media bundle for uploading, storing, and managing files and images. Provides a unified media model, configurable storage disks, image conversions, and simple APIs for attaching media to Eloquent models, with support for cleanup and metadata.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package — the *Bundle suffix, SoftPassio\MediaBundle namespace, and Symfony-style service/DI conventions confirm it. Before writing any Laravel code, verify the integration cost against the cost of rolling your own media handler (usually an hour's work with Storage + Intervention\Image).

Minimal steps:

  1. composer require soft-passio/media-bundle — expect Composer to pull Symfony components (symfony/http-foundation, symfony/options-resolver, etc.). If your Laravel app doesn't already carry these (via something like laravel/symfony-* shims), you'll drag them in.
  2. Check the tag — the last release was 2020-06-26. Inspect composer.json for php and symfony/* constraints; you'll likely need to pin or override versions to install on a modern Laravel (10/11) stack. Use composer require soft-passio/media-bundle --ignore-platform-reqs only as a last resort.
  3. Register the services manually. Laravel has no bundle mechanism. The bundle's Resources/config/services.yaml (or XML) needs translating to a service provider — either a small custom provider that binds the media manager, uploader, and storage classes into the container, or a facade wrapping them.
  4. Publish configuration. The bundle ships defaults under Resources/config/ (e.g. media.yaml); copy the relevant keys into config/media.php and inject them via config() when constructing the service.
  5. First use case — the canonical one. Upload a UploadedFile, persist a media record, and render the URL:
$media = app(MediaManager::class)->handle(
    $request->file('image'),
    $request->user()
);
return $media->getUrl();

If that pipeline works end-to-end (upload → storage → URL), you've validated the integration. If it doesn't within a day, stop and rewrite — the package is unmaintained (0 stars, 0 dependents, last commit 2020) and you'll own every bug.

Look first at src/ for the MediaManager/MediaService entry point and any Entity/Media class — that's your model to map onto an Eloquent model (or wrap directly if it's a plain Doctrine entity with getters/setters).

Implementation Patterns

Adapter pattern around the bundle service. Don't let Symfony service names leak into controllers. Wrap the manager in your own App\Services\MediaService that accepts a Laravel UploadedFile, calls the bundle, and returns a plain DTO or an Eloquent Media model you control. This is the single most important pattern — it isolates you from the package's Symfony-flavored API and gives you a swap point when (not if) you replace it.

Eloquent ↔ bundle entity mapping. If the bundle ships a Doctrine Media entity, don't fight Doctrine inside Laravel. Instead:

  • Create App\Models\Media (Eloquent) with the same columns the bundle expects.
  • Implement a small bridge that hydrates the bundle's entity from your model for the duration of the call, then copies mutated fields (filename, mime, path, size, dimensions) back.
  • Or, if the bundle only uses the entity as a value object, pass a lightweight adapter implementing its interface.

Upload workflow. Typical flow: validate in a FormRequest → persist a placeholder row → let the bundle's uploader process the file to disk → update the row with path/metadata inside a DB transaction. If the uploader stores to a non-Laravel disk, register a custom Flysystem adapter bridging Symfony's filesystem interfaces to Storage::disk() — this keeps S3/Spaces config in one place.

Variant / thumbnail generation. Media bundles of this vintage usually expose image processing (Imagine or Intervention). If it delegates to Intervention, point it at Laravel's version and reuse your config/image.php. Generate variants on upload (synchronous, user waits) vs. queued (better UX, but requires the bundle's processing to be job-safe — verify it holds no request state).

Rendering URLs. In Blade, don't call bundle methods inline; add a helper or accessor: $media->url / $media->thumbnail('small'). Centralizes path/disk logic and lets you switch from local to CDN later without touching templates.

Admin / Nova integration. If you use Nova or Filament, expose media through a custom field that wraps your MediaService — never bind the bundle directly to the resource. Uploads from admin panels route through the same service, so validation, storage, and cleanup stay consistent.

Cleanup & lifecycle. Pair every upload with a deletion path. Use an Observer on your Media model to remove files on delete — the bundle almost certainly has no orphan handling, and abandoned packages are where orphaned S3 objects breed.

Gotchas and Tips

Unmaintained is the headline risk. 2020 release, zero dependents, zero stars — treat this as code you are adopting. Expect: no PHP 8.2/8.3 compatibility guarantees, no security patches, no Laravel 11 support. Pin it in composer.json with an exact version and add a note in your README explaining the fork plan.

Symfony container bleed-through. Services are wired via Symfony DI, meaning constructor arguments are Symfony services (HttpFoundation, EventDispatcher, Filesystem). You cannot app()->make() them naively. Either build a provider that manually instantiates them, or use laravel/symfony-container-bridge-style glue. Watch for Symfony\Component\EventDispatcher\EventDispatcher (does not satisfy Laravel's Illuminate\Contracts\EventDispatcher).

Config resolution mismatch. Symfony bundles use OptionsResolver with strict unknown-key errors. Merging Laravel's config('media.*') into an OptionsResolver will throw on keys the bundle doesn't know — strip unknown keys before constructing the service, or maintain a strict translation layer in config/media.php.

Path/URL generation assumes Symfony routing. getUrl() often calls RouterInterface::generate(). In Laravel that router doesn't exist. Override by wrapping the media's getPublicUrl() in your own method that calls Storage::disk(...)->url(...) — don't try to shim Symfony's router.

Temporary file handling. Uploaders of this era frequently use Symfony\Component\HttpFoundation\File\UploadedFile and Symfony's Filesystem. Laravel's UploadedFile extends Symfony...UploadedFile, so the happy path works — but methods like getClientOriginalName() vs Symfony's getClientOriginalName are the same, while storeAs() (Laravel-only) is not available. Call ->getRealPath() or ->move() at the boundary.

Debugging tips.

  • Start with APP_DEBUG=true and a single feature test asserting upload → row → URL.
  • If a MissingArgumentException fires on a constructor, you've missed a Symfony service binding — php artisan tinker and reflect the constructor to enumerate required args.
  • Enable Symfony's debug flag if the bundle exposes one; otherwise wrap calls in try/catch and dump the DI trace.
  • Log at the MediaManager boundary — you'll want request ID, file hash, and resulting path to correlate failures.

Extension points to lean on. Look for interfaces (MediaManagerInterface, StorageInterface, UrlGeneratorInterface) — bind your implementations to those interfaces in your provider. This is how you replace a broken Symfony storage adapter with Storage::disk() without forking the whole bundle. If the bundle uses concrete classes with no interfaces, subclass or wrap rather than edit vendor code.

Migration risk. No schema migrations ship with most Symfony bundles — check Resources/migrations/ or Resources/config/doctrine/. You'll likely write your own Laravel migration matching the entity. Commit that migration; it's the record of what the package expects.

Replace, don't patch. Given the maintenance profile, budget for a rewrite behind your MediaService adapter within 6–12 months. Keep the adapter surface small (upload, delete, url, variants) so the swap 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.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle