Media OS can run directly in your PHP application. A controller, service,
command or job can store files, create image variants and use staging without
rendering FlexFileUpload or a Filament form.
The shipped AI skill includes a dedicated references/media-os.md guide for this
workflow. Component discovery describes rendered controls; it is not the service
API reference.
Choose the right entry point
Minimal service-level storage
This example uses a trusted, existing local file and a configured private Laravel
disk. It can run inside your application service; it creates no form field.
Permanent storage inspects the actual content against the policy. Your application
still authorizes the operation and persists its own record reference. The receipt
does not automatically create a gallery row or grant permission to read the file.
For a normal HTTP request, validate the UploadedFile and use its valid local
path with MediaSource::path(). MediaSource::upload() specifically accepts a
Livewire temporary upload. See the HTTP request example.
Give the assistant a complete task
Images and Spatie
For disk-backed images, define named ImageConversion variants and choose
synchronous or queued processing. Retain the returned bundle/receipt information
needed by your application. A queued variant may not exist yet; configure a
fallback and a worker with supported encoders.
For Spatie, use the adapter with a persisted HasMedia model and SpatieOptions.
Keep Spatie’s collections, conversions and queue configuration. An extra table
for every conversion is not normally required. The Spatie guide
shows direct service storage as well as field integration.
When storage happens before the record save
Use staging when the workflow needs it. Stage, promote and confirm are distinct
operations; confirmation belongs after the durable record reference commits.
A database rollback does not roll back disk/S3 writes. Derive lease ownership
from trusted server context and follow the documented recovery contract for
ambiguous outcomes.
Read temporary uploads and recovery before implementing
this flow. Do not copy an upload field’s completion hook into a service that does
not mount that field.
Pure server-side storage needs no browser asset initialization. A custom capture
interface has a separate browser lifecycle and still needs server validation.
For ordinary same-connection hasMany galleries, inspect HasManyMediaCollection,
MediaRelationColumns and MediaRelationSnapshot. The
related gallery guide covers explicit model columns,
authorization and new-file admission, unique disk/path ownership, locked revision
baselines, transaction/rollback, order and detach. sync() maps originals into
SQL; it does not upload files, accept stages, convert or delete physical objects.
Keep the mounted field’s native/custom commit-aware acceptance contract.
Spatie remains a separate integration. Do not invent a disk uploader
relationship() option or treat a revision as authorization.
Check the deployment configuration
Ask the assistant to run fff:media:doctor with the profile matching the actual
workflow. Use --queued with the selected connection, queue and job timeout for
native background conversions, and --custom-encoder when the application supplies
its own encoder. The diagnostic report does not execute
extension factories or modify storage. Treat unverified findings as checks still
required; a valid configuration is not proof of a running worker or a successful
upload/save/reopen workflow.
For explicitly approved infrastructure checks, fff:media:probe --write can
exercise a named --disk, named --lock-store and requested --format values.
It creates synthetic diagnostic data and invokes the selected backend adapters.
Do not run it as a read-only inspection or select production targets without the
operator’s authorization. Its active probe report
states what was exercised, any failed cleanup and the remaining deployment checks. Last modified on October 20, 2026