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

Filament Media Library Laravel Package

lisowiecw/filament-media-library

Filament Media Library provides a ready-to-use media manager for Filament panels: upload, browse, search, and organize files, then attach media to Eloquent models. It simplifies handling images and documents in admin resources with an intuitive interface.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Upload safety as a product guarantee, not an implementation detail. The enshrined/svg-sanitize bump to ^1.0 closes four unpatched advisories (stored XSS via DTD entity/HMTL5 named-character collision, libxml DoS via DTD attribute declaration, mixed-case xlink:HrEf bypassing the <use> nesting check, and CSS injection). For any product that lets end users upload SVG and serves it back to other users, this is the difference between "we sanitize" as a claim and "we sanitize" as a fact. The key PM-relevant nuance: composer audit reported clean throughout because Packagist had not ingested the advisories, so this fix is invisible to dependency dashboards. That is an argument for treating upload-surface dependencies as a reviewed list rather than trusting automated audit alone.
  • A deliberate narrowing of accepted input. <!DOCTYPE> is stripped before parsing, so SVGs that reference a custom entity are now refused with a named file, where before they were silently stored with the entity expanded away. Declaring-but-not-using an entity still passes; a doctype with no declarations still passes. Remote references are now caught in more places (bare remote href/src, unquoted url(), url() among other declarations in a style attribute — costing the whole attribute — and remote @import/url() inside <style> text), while local /x and fragment #x references survive. This is a changed default about what is refused, and it needs a product answer: how do we tell a user whose icon set no longer uploads, and what do we tell them to do (re-export without the custom entity; make the remote reference local).
  • No retroactive effect — decide whether you care. Nothing is re-sanitized at rest. SVGs stored before this release keep the bytes 0.22 produced. If you have a media library with historical uploads and you actually rely on the sanitation guarantee, "re-upload to get the stricter pass" is a product/ops task (bulk re-upload, or accept residual risk). ADR 5 notes the privacy residual the Strict pass was written for is now largely closed upstream, but keeps Strict in force — so no relaxation decision is needed now.
  • Drop intake unifies the three Drop surfaces (inline trigger, Library tab body, Upload tab) behind one module. The user-visible win: dropping a picture onto a filled single-selection cover image now replaces it instead of refusing with "field is full." This is the surface that most obviously wants the behaviour. It also means a gallery is measured against remaining room, a single selection against the one file it replaces with, and one bad file no longer costs the rest of the gesture — refusal is absorbed per-file. The Upload tab also gains the room check the committing surfaces already had, so confirming an over-full gallery no longer uploads orphans it then leaves unattached in the library. Worth scheduling as a UX fix in release notes to end users; MediaPicker::upload() removal is internal-only and not on the promised surface.
  • Card painting centralises what a tile shows — thumbnail, BlurHash, the painting of that hash, and in-flight state — computed once per field from thumbnailUsing() and asked once per asset, rather than the library grid and a picker's attached items each assembling a card from five modules. Fewer redundant hash requests per tile. One behaviour converges on the grid's: a non-image asset beside the field is now a bare item, where a field with its own thumbnailUsing() previously asked it to paint one, and neighbouring items no longer wait on a rendering that can never arrive. That is the reason this is a minor and not a patch — if you have custom thumbnail rules that assume they'll be consulted for non-images, check them.
  • The attach rule has one home (TenantReach), shared by picker validation and AttachmentReconciler. Product consequence: what the picker offers is what a reconcile accepts, and a condition added to the rule lands on both paths or neither — no drift. Two operational changes follow. First, an application with no tenant resolver configured now gets the rule where it had none: an attach from application code, a queued job, or a seeder previously fell through to a foreign key error and now raises AttachRefused naming what the package will not do. If you were catching QueryException around attaches, expect the new exception instead. Second, programmatic reconciles asking for an id that names no live asset get AttachRefused::unknownAsset() rather than a spurious tenant mismatch; it's a second named constructor on the same class, so existing catch (AttachRefused $e) still catches both. The picker deliberately keeps one wording for every refusal, because distinguishing them would reveal whether an asset the viewer cannot reach exists (ADR 7) — don't "improve" that copy.
  • Soft-deleted assets no longer block saves. A host record whose picked asset was deleted (soft-deleted, attachment row still present) previously refused every save of that record, because the rule checked that every desired id resolved to a live asset before setting aside already-attached ids. Existence is now asked only of ids actually arriving. Attaching an id naming no asset at all is still refused. This is a real bug fix for editorial workflows and worth calling out to support.

When to Consider This Package

Adopt when:

  • You are building a Laravel media/asset field — cover images, galleries, inline media pickers — and want the field to own the whole loop (upload, drop, attach, tenancy check, thumbnail/BlurHash painting, polling) rather than assembling it from primitives.
  • Untrusted users can upload images, and SVG is in scope. The sanitize-at-upload-once design (sanitize the bytes about to be written, refuse what cannot be sanitized) plus the 1.0 upstream allowlist is the strongest argument for the package. If you are rolling your own SVG handling, this release is the case study for why you shouldn't.
  • You need tenancy to be a policy boundary, not a query scope (ADR 7) — refusals are explicit and identical in wording regardless of whether the asset exists or merely isn't yours.
  • You are multi-tenant and want picker validation and out-of-band reconciles (queued jobs, seeders, application code) held to the same rule with the same exception type.

Look elsewhere or defer when:

  • You need a stable, broad public API guarantee across the whole picker class. This package explicitly promises the field's own configuration, not every public method; MediaPicker::upload(), LibraryGrid::thumbnailUsing(), pollable(), isPollable(), MediaPicker::getThumbnailUrl() and paintsThroughPipeline() have all been removed as internals in this release. Fine if you only configure fields; a problem if you subclass or call in.
  • You cannot tolerate accepted-input narrowing in a minor release. SVGs that uploaded cleanly yesterday can be refused today. If your users upload third-party-exported SVG at volume, budget for the support tail and the comms.
  • You were relying on QueryException (rather than AttachRefused) surfacing from attaches in a non-tenanted app, or on a tenant mismatch being reported for an id that simply doesn't exist.
  • You need the library's stored SVGs retroactively hardened; this release does nothing at rest.
  • Your thumbnail rules assume they are consulted for non-image assets in picker attached items. That behaviour now matches the grid — bare item, no paint, no waiting.

How to Pitch It (Stakeholders)

To executives: This release closes four known security holes in how we clean user-uploaded SVG images — including a stored cross-site-scripting vector — by moving to a patched upstream sanitiser. It is the kind of fix our dependency scanner could not flag, so it also justifies treating the upload path as a reviewed surface. Alongside that it fixes a genuinely annoying UX behaviour (dropping a new cover image onto a filled field used to be refused; it now replaces), removes orphaned uploads from an over-full gallery confirm, and fixes a bug where a soft-deleted asset blocked every subsequent save of the record it sat on.

To engineering: The enshrined/svg-sanitize constraint moves ^0.22 → ^1.0 and is dropped, not widened to ^0.22||^1.0, because leaving 0.22 resolvable leaves the advisories resolvable. Treat this as a changed default, not housekeeping: <!DOCTYPE> is stripped pre-parse, so entity-referencing SVGs are refused by name; remote-reference matching is generalised and reaches bare remote href/src, unquoted url(), a remote url() among other declarations in a style attribute (whole attribute dropped), and remote @import/url() in <style> text; href cleaning is no longer skipped when href and xlink:href coexist and is case-insensitive; element-dense SVGs are no longer quadratic. Sanitizing still runs once at upload on the bytes about to be written, and the Strict pass on public placement still drops embedded images, <style> blocks and links. Nothing is re-sanitized at rest — re-upload is the migration. Separately, three internal refactors land: Drop intake (one module behind the three Drop surfaces; replacing-on-drop for single selection; per-file refusal absorption; Upload tab now room-checked), Card painting (one assembly per field, asked once per asset; non-image assets beside the field are now bare items, matching the grid — hence minor, not patch), and TenantReach as the single attach rule shared by picker validation and AttachmentReconciler. Two things to watch in integration: non-tenanted apps now get AttachRefused where they previously got a foreign key QueryException, and programmatic reconciles get AttachRefused::unknownAsset() for ids naming no live asset. The removed methods listed above are all off the promised surface; if we call or subclass them, that's our debt to clear in this upgrade.

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.
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
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core