Skip to main content

Capell uses essential storage for sessions, security, and interface preferences. Analytics and marketing storage stay off unless you accept them.

Cookie Policy
Media Library marketplace hero artwork.

Media Library

Media Library connects Capell to Curator media, media health reporting, and migration support.

Overview

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.

/ 06
6 captures Visual gallery
Install

Install on your Capell site in three steps.

Each extension ships as a standard Composer package. Purchases unlock account access immediately before you install.

Support
First-party Capell support for active marketplace customers.
Data access
May connect configured Capell content, media, or integration metadata to the named service boundaries for this package.
  1. 01

    Require the package

    composer require capell-app/media-library
  2. 02

    Register the extension

    php artisan capell:extension:enable capell-app-media-library
  3. 03

    Clear schema cache

    php artisan capell:admin:clear-schemas-cache
Works well with this

Related extensions

Browse the packages that usually pair with Media Library or buy the suite it belongs to.

Included in suites
Content launch

Editorial Foundation Suite

$0.00

Start a Capell site with Layout Builder, reusable blocks, Foundation Theme, navigation, Media Library, and blog publishing in one free content launch path.

Layout Builder Block Library Foundation Theme Navigation Media Library Blog
Migration path

Migration & Import Suite

Move existing content into Capell with validated Migration Assistant imports, WordPress previews, Media Library migration support, and Diagnostics checks.

Migration Assistant WordPress Importer Media Library Diagnostics
Media operations

Media Workflow Suite

Manage richer content intake with Media Library, provider-backed Media AI actions, shared address records, tags, and native Capell forms.

Media Library Media AI Address Tags Form Builder
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 curator table and host-app owner FK columns

What It Adds

  • Registers Capell\MediaLibrary\Models\CuratorMedia as the Capell media model and sets capell.media.backend to curator.
  • Binds Capell\Core\Contracts\Media\MediaFieldFactory to CuratorMediaFieldFactory, which renders an Awcodes CuratorPicker.
  • Adds MediaHealthPage with MediaHealthTable for 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 DispatchMissingAltMediaSignalsAction and MediaMissingAltDetected so 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 exif JSON 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-curator and MigrateSpatieMediaToCuratorAction for 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_types
  • capell.media_library.allowed_extensions
  • capell.media_library.max_upload_kb
  • capell.media_library.default_visibility
  • capell.media_library.stale_after_days
  • capell.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

  • MediaLibraryServiceProvider merges config/media-library.php, sets capell.media.backend to curator, sets capell.media.model to CuratorMedia, and binds MediaFieldFactory to CuratorMediaFieldFactory.
  • CuratorMediaFieldFactory returns an Awcodes CuratorPicker for Capell media FK fields.
  • CuratorMedia adapts Curator records to Capell's media contract, including URL, alt/title/caption, dimensions, focal point, crop preset, and existing responsive metadata accessors.
  • MediaHealthPage and MediaHealthTable expose the admin report for missing alt text, stale media, and unused assets.
  • BuildDuplicateMediaQueryAction hashes readable storage files and reports byte-identical duplicate media even when the Curator paths differ.
  • BuildMissingAltMediaQueryAction and DispatchMissingAltMediaSignalsAction expose prioritized missing-alt media candidates for automation packages such as Media AI.
  • BuildMissingRightsMetadataQueryAction parses Curator exif JSON and reports media whose configured rights keys are missing, blank, or malformed.
  • MigrateSpatieToCuratorCommand delegates migration work to MigrateSpatieMediaToCuratorAction.

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 through InteractsWithCuratorMedia.
  • 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.jpg
  • docs/screenshots/media-health-page.png
  • docs/screenshots/media-health-page-dark.png
  • docs/screenshots/media-health-table.png
  • docs/screenshots/media-health-table-dark.png
  • docs/screenshots/curator-media-field-inside-a-form.png
  • docs/screenshots/curator-media-field-inside-a-form-dark.png
  • docs/screenshots/migration-command-output-or-report.png
  • docs/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_keys for 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
History

Downloads and releases

Total downloads
0
Last downloaded
No downloads yet

Version history

1 release
  1. v1.0.0
    May 3, 2026
Write a review

Write your comment here. If you are not logged in, you will be asked to log in or create an account before it can be submitted.

Login or create an account is required before the review is saved.

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.