Media Library
Media Library connects Capell to Curator media, media health reporting, and migration support.
What Media Library provides
Media Library connects Capell to Curator media, media health reporting, and migration support.
It gives editors a stronger media management surface for reusable assets, fields, and content relationships.
Developers get migration tooling and health checks that make legacy media moves less fragile.
The package keeps media integration concerns separate from core content modelling.
Use it when a Capell site needs a richer, maintainable media layer.
Install on your Capell site in three steps.
Each extension ships as a standard Composer package. Purchases unlock account access immediately before you install.
-
01
Require the package
composer require capell-app/media-library -
02
Register the extension
php artisan capell:extension:enable capell-app-media-library -
03
Clear schema cache
php artisan capell:admin:clear-schemas-cache
Related extensions
Browse the packages that usually pair with Media Library or buy the suite it belongs to.
WordPress Importer
Preview WordPress WXR posts and pages in Capell with durable metadata ready for Migration Assistant mapping.
Media AI
Provider-backed image editing inside Capell's media library: improve images, remove backgrounds or objects, re...
Editorial Foundation Suite
Start a Capell site with Layout Builder, reusable blocks, Foundation Theme, navigation, Media Library, and blog publishing in one free content launch path.
Migration & Import Suite
Move existing content into Capell with validated Migration Assistant imports, WordPress previews, Media Library migration support, and Diagnostics checks.
Media Workflow Suite
Manage richer content intake with Media Library, provider-backed Media AI actions, shared address records, tags, and native Capell forms.
Package README Install impact, package shape, common pitfalls, and maintenance notes. Open
Media Library
Media Library makes Awcodes Curator the media backend for Capell. It gives packages one consistent media field, one Curator-backed media model, a media-health admin page, and an idempotent migration path from Spatie Media Library.
This is a free Foundation package. It is the media plumbing other Capell packages can build on; it is not a full DAM layer with folders, galleries, generated WebP/AVIF conversions, or a visual focal-point editor.
At A Glance
- Package:
capell-app/media-library - Namespace:
Capell\MediaLibrary\ - Surfaces: Filament admin and console
- Capell dependencies:
capell-app/admin,capell-app/core - Third-party dependency:
awcodes/filament-curator - Database impact: no package-owned migrations; uses Curator's
curatortable and host-app owner FK columns
What It Adds
- Registers
Capell\MediaLibrary\Models\CuratorMediaas the Capell media model and setscapell.media.backendtocurator. - Binds
Capell\Core\Contracts\Media\MediaFieldFactorytoCuratorMediaFieldFactory, which renders an AwcodesCuratorPicker. - Adds
MediaHealthPagewithMediaHealthTablefor missing alt text, stale media, and unused asset review. - Adds content-hash duplicate, missing-alt, missing-rights-metadata, usage, orphan, and media-health query actions for reports.
- Adds
DispatchMissingAltMediaSignalsActionandMediaMissingAltDetectedso media-ai and other packages can subscribe to prioritized missing-alt candidates. - Adds selected orphan cleanup through
DeleteOrphanMediaRecordsAction, including unshared file deletion before row deletion. - Parses Curator
exifJSON structurally for rights metadata reports instead of matching raw JSON text. - Adds configurable upload validation for mime types, extensions, max file size, and default visibility.
- Adds
capell:media-migrate-to-curatorandMigrateSpatieMediaToCuratorActionfor Spatie-to-Curator migrations. - Stores and reads Curator focal point, crop preset, and responsive image metadata when that metadata already exists.
- Defers full DAM features, generated WebP/AVIF conversions, visual crop editing, folders, galleries, and where-used drill-down to a future Media Pro layer.
Current Boundaries
CuratorMedia::getSrcset()reads Curator responsive metadata or falls back to Glide thumbnail, medium, and large URLs. The package does not generate responsive conversions or modern image formats.- Focal points and crop presets are available through the PHP API, but the package does not ship a dedicated visual editor for them.
- Usage and orphan reports depend on configured or auto-discovered owner FK columns. Publish the config for nonstandard schemas.
- Duplicate reporting hashes readable storage files and groups byte-identical assets across different paths.
- Rights metadata reporting treats null, blank, malformed JSON, missing keys, and empty configured metadata values as incomplete.
- Private upload visibility is supported, but signed temporary URL handling is not part of this package yet.
Install And Setup
Install the package in the host Capell application:
composer require capell-app/media-library
Publish the config when the site needs exact usage/orphan reporting, private default uploads, upload policy changes, or a different stale-media threshold:
php artisan vendor:publish --tag=media-library-config
Configure capell.media_library.owner_foreign_keys with every table and column that points at Curator media. The reports can auto-discover common column names when this list is empty, but explicit config is safer for production schemas:
'owner_foreign_keys' => [
['table' => 'pages', 'column' => 'hero_image_id'],
['table' => 'articles', 'column' => 'thumbnail_id'],
],
Upload policy is controlled by:
capell.media_library.allowed_mime_typescapell.media_library.allowed_extensionscapell.media_library.max_upload_kbcapell.media_library.default_visibilitycapell.media_library.stale_after_dayscapell.media_library.report_cache_ttl_seconds
Admin Surface
- Page:
Capell\MediaLibrary\Filament\Pages\MediaHealthPage - Slug:
media-health - Table:
Capell\MediaLibrary\Filament\Pages\Tables\MediaHealthTable - Access: Filament Shield page permissions
The health table shows media name, size, usage count, primary issue, mime type, and last update time. It includes an issue filter and a bulk action for deleting selected orphan media after re-validating those rows through the orphan query.
Media health and orphan reports cache their computed result rows briefly through report_cache_ttl_seconds; orphan deletion bypasses that cache and revalidates live references before deleting files or rows.
Missing Alt Signals
BuildMissingAltMediaQueryAction returns image media with null, empty, or whitespace-only alt text, including a usage_count projection from configured or auto-discovered owner foreign keys. DispatchMissingAltMediaSignalsAction dispatches MediaMissingAltDetected events for that ordered queue so packages such as Media AI can generate alt text without coupling to the admin health table.
Command
php artisan capell:media-migrate-to-curator \
--dry-run \
--collection=image \
--owner-type="App\\Models\\Post" \
--chunk=500
Options:
--dry-run: report what would happen without writing.--collection=*: restrict migration to one or more Spatie collection names.--owner-type=: restrict migration to one owner model FQCN.--chunk=200: process Spatie media rows in batches.
The migration maps Spatie rows into Curator rows, preserves supported metadata, and populates per-collection owner FK columns when those columns exist.
Screenshots
The marketplace card lives at docs/assets/marketplace/extension-card.jpg.
Committed screenshot assets live in docs/screenshots/ and include light and dark captures for:
- Media health page
- Media health table
- Curator media field inside a form
- Migration command output or report
The capture contract is docs/screenshots.json. It defines the page, component, field, and console targets that should be refreshed by the deployment screenshot runner.
Code Map
| Area | Path | Purpose |
|---|---|---|
| Actions | src/Actions |
Query builders, orphan cleanup, and migration operations. |
| Config | config/media-library.php |
Owner FK discovery, upload policy, visibility, and stale threshold. |
| Data | src/Data |
Typed migration and owner-FK payloads. |
| Filament | src/Filament |
Curator field factory and media health admin page/table. |
| Health | src/Health |
Diagnostics for backend registration, schema, and owner FK config. |
| Models | src/Models |
Curator-backed media model adapter. |
| Tests | tests |
Package-level Pest coverage. |
Testing
Run package tests from the repository root:
vendor/bin/pest packages/media-library/tests --configuration=phpunit.xml
For focused metadata/docs changes, start with:
vendor/bin/pest packages/media-library/tests/Unit/MediaLibraryCoverageTest.php --configuration=phpunit.xml
Maintenance Notes
- Put behavior changes in Actions or support classes. UI classes and commands should delegate.
- Keep public render paths free of admin/editor metadata.
- Use typed Data objects at boundaries instead of passing anonymous arrays between layers.
- Do not query from public Blade. Hydrate media render data before views receive it.
Overview A shorter package overview for marketplace and account review. Open
Media Library Overview
Status: available · Kind: package · Tier: free · Bundle: foundation · Contexts: admin, console · Product group: Capell Foundation
Media Library is Capell's Curator-backed media foundation. It replaces the default media backend with Awcodes Curator, gives packages a shared media field factory, and adds operational tools for media health and Spatie Media Library migration.
It is deliberately scoped as foundation infrastructure. Advanced DAM features such as folders, galleries, generated WebP/AVIF conversions, signed private URLs, and a visual focal/crop editor are explicitly deferred to a future Media Pro/DAM layer.
Runtime Shape
MediaLibraryServiceProvidermergesconfig/media-library.php, setscapell.media.backendtocurator, setscapell.media.modeltoCuratorMedia, and bindsMediaFieldFactorytoCuratorMediaFieldFactory.CuratorMediaFieldFactoryreturns an AwcodesCuratorPickerfor Capell media FK fields.CuratorMediaadapts Curator records to Capell's media contract, including URL, alt/title/caption, dimensions, focal point, crop preset, and existing responsive metadata accessors.MediaHealthPageandMediaHealthTableexpose the admin report for missing alt text, stale media, and unused assets.BuildDuplicateMediaQueryActionhashes readable storage files and reports byte-identical duplicate media even when the Curator paths differ.BuildMissingAltMediaQueryActionandDispatchMissingAltMediaSignalsActionexpose prioritized missing-alt media candidates for automation packages such as Media AI.BuildMissingRightsMetadataQueryActionparses CuratorexifJSON and reports media whose configured rights keys are missing, blank, or malformed.MigrateSpatieToCuratorCommanddelegates migration work toMigrateSpatieMediaToCuratorAction.
Configuration
The package has no migrations of its own. It relies on Curator's curator table and owner tables that store Curator media IDs.
The config is published with the media-library-config tag and merged under capell.media_library:
owner_foreign_keys: exact table/column pairs that reference Curator media.auto_discover_owner_foreign_keys: allows report actions to find conventional media FK columns when explicit config is empty.owner_foreign_key_columns: column names considered during discovery.default_visibility: default visibility for uploads throughInteractsWithCuratorMedia.stale_after_days: media-health stale threshold.report_cache_ttl_seconds: short TTL for computed media health and orphan report rows.allowed_mime_types,allowed_extensions,max_upload_kb: upload validation policy.
Owner FK entries are schema-checked before report SQL is generated. Missing tables, missing columns, and unsafe identifiers are ignored.
Admin And Operations
The Media Health page is an admin-only Filament page registered through Capell Admin when the package is installed. It shows:
- byte-identical duplicate assets
- missing alt text
- stale assets based on
stale_after_days - unused assets based on configured or discovered owner FK references
- per-issue filtering
- selected orphan cleanup that re-validates records before deleting files and rows
The missing-alt signal actions are deliberately separate from the table UI. They return image candidates with null, empty, or whitespace-only alt text, include usage_count, and can dispatch MediaMissingAltDetected events for downstream automation.
Rights metadata reporting decodes Curator exif JSON before matching keys, so unrelated text values do not satisfy copyright/license requirements and empty metadata values remain visible.
The health and orphan report Actions cache their computed row ids and projected columns briefly, then rebuild normal Curator query builders from that cache. Destructive orphan cleanup bypasses the cache and revalidates live owner references.
The migration command is:
php artisan capell:media-migrate-to-curator
Use --dry-run before a real migration. Optional filters are --collection=*, --owner-type=, and --chunk=.
Screenshots
The committed media set is:
docs/assets/marketplace/extension-card.jpgdocs/screenshots/media-health-page.pngdocs/screenshots/media-health-page-dark.pngdocs/screenshots/media-health-table.pngdocs/screenshots/media-health-table-dark.pngdocs/screenshots/curator-media-field-inside-a-form.pngdocs/screenshots/curator-media-field-inside-a-form-dark.pngdocs/screenshots/migration-command-output-or-report.pngdocs/screenshots/migration-command-output-or-report-dark.png
The screenshot capture contract is screenshots.json. It defines four required scenarios: the media health page, the media health table component, a host form using the Curator media field factory, and the migration command output. The committed screenshot captures remain runner evidence until they show populated Capell media workflows.
Pitfalls
- Install and migrate Curator before relying on
CuratorMedia. - Publish and fill
owner_foreign_keysfor production schemas with nonstandard media columns. - Keep upload validation aligned with the assets editors are allowed to upload.
- Back up legacy Spatie media before running a real migration.
- Do not describe this package as generating responsive variants; it only reads existing responsive metadata or Curator/Glide URLs.
Verification
Run the focused metadata/docs coverage test from the repository root:
vendor/bin/pest packages/media-library/tests/Unit/MediaLibraryCoverageTest.php --configuration=phpunit.xml
Run the package suite when behavior changes go beyond docs or manifest metadata:
vendor/bin/pest packages/media-library/tests --configuration=phpunit.xml
Downloads and releases
- Total downloads
- 0
- Last downloaded
- No downloads yet
Version history
1 release-
v1.0.0May 3, 2026
No approved reviews yet. Reviews from eligible customers appear here after marketplace review.
Payment and licences
How marketplace purchases work
Capell keeps payment, account ownership, package receipts, and install access separate so a failed step can be recovered without guessing where the licence lives.
Who takes the payment?
Paid marketplace checkouts are sent to Stripe. Capell does not collect card details inside your CMS; Stripe confirms the payment and Capell activates the matching marketplace licence for the Capell account that approved the install.
How is the licence attached?
The licence is created against the signed-in Capell account first. When the hosted install flow returns to your CMS, Capell binds that licence to the requesting site and sends back the install authorization needed to continue.
Where does Anystack fit?
Anystack can be the package commerce and distribution surface for marketplace products. Capell still records the account licence and installed receipt, then relays later Anystack product or licence events only to connected sites that already have the package installed.
What happens if checkout is cancelled or expires?
No licence is created until Stripe confirms payment. If checkout is cancelled, start it again from the same review screen. If the quote expires, return to the marketplace in your CMS and start a fresh install flow so pricing and package metadata are recalculated.
What should I do if something looks wrong?
Keep the support reference shown on the review screen or receipt, then contact support before retrying with a different account. For missing licences, failed returns, or Anystack receipt mismatches, Capell can reconcile the Stripe session, Capell account, package receipt, and connected site from that reference.