Install the Package Run the Moox installer to scaffold configurations and migrations:
php artisan moox:install
Media model and PathGenerator.Configure Database Run migrations to create tables for media collections and translations:
php artisan migrate
First Use Case: Attach Media to a Model Extend a model with the required traits and interface:
use Moox\Media\Traits\HasMediaUsable;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Post extends Model implements HasMedia
{
use HasMediaUsable, InteractsWithMedia;
protected $fillable = ['image']; // JSON field for media metadata
}
MediaPicker component in Filament forms to attach media:
use Moox\Media\Components\MediaPicker;
MediaPicker::make('image')
->collection('images') // Optional: specify collection name
->required()
Model Integration
HasMedia and use HasMediaUsable for translation support.image) to store media metadata (e.g., {"id": 1, "url": "/path/to/image.jpg"}).$post->getMedia('image'); // Returns a Media model
$post->getFirstMedia('image')->getUrl(); // Direct URL access
Filament Integration
MediaPicker::make('hero_image')
->collection('hero_images')
->multiple() // Allow multiple files
->acceptedFileTypes(['image/jpeg', 'image/png'])
MediaViewer component to render media in Filament tables/panels:
use Moox\Media\Components\MediaViewer;
MediaViewer::make('image')
->collection('images')
->width(100)
->height(100)
Collections and Organization
media config:
'collections' => [
'images' => [
'disk' => 'public',
'path' => 'images/posts',
],
'documents' => [
'disk' => 'public',
'path' => 'documents',
],
],
$post->addMedia($file)->usingCollection('custom_collection')->save();
Translations
translate() method:
$media = $post->getFirstMedia('image');
$media->translate('alt', 'en', 'Sunset Photo');
$media->translate('alt', 'es', 'Foto del Atardecer');
$altText = $media->getTranslation('alt', 'en');
Custom Paths: Extend the PathGenerator to dynamically set paths based on model attributes:
use Moox\Media\PathGenerators\PathGenerator;
class CustomPathGenerator extends PathGenerator
{
public function getPath(Media $media): string
{
return "posts/{$media->model->id}/{$media->collection_name}";
}
}
Register it in config/media.php:
'path_generator' => \App\PathGenerators\CustomPathGenerator::class,
Validation: Validate media attachments in Filament forms:
use Moox\Media\Rules\ValidMedia;
$form->validate(
ValidMedia::make()
->collection('images')
->maxSize(5 * 1024) // 5MB
);
Events: Listen to media events (e.g., MediaWasAdded, MediaWasDeleted) for side effects:
use Moox\Media\Events\MediaWasAdded;
MediaWasAdded::listen(function (Media $media) {
// Log or process the added media
});
Missing JSON Column
image) in the model’s $fillable or database schema.json in the model:
protected $casts = [
'image' => 'json',
];
Collection Mismatch
config/media.php or dynamically create them:
$post->addMedia($file)->usingCollection('dynamic_collection')->save();
Translation Conflicts
getTranslation() with a fallback locale:
$altText = $media->getTranslation('alt', 'en', 'Default Alt Text');
Filament Component Registration
AppServiceProvider:
Filament::serving(function () {
Filament::registerComponents([
\Moox\Media\Components\MediaPicker::class,
\Moox\Media\Components\MediaViewer::class,
]);
});
Disk Configuration
public vs. local).disk setting in config/media.php and ensure the disk is configured in config/filesystems.php.if ($post->getFirstMedia('image')) {
// Media exists
}
\Log::info('Media path:', [
'url' => $media->getUrl(),
'path' => $media->path,
]);
php artisan config:clear and check config/media.php for typos or missing settings.Custom Media Models
Extend the base Media model to add custom fields:
use Moox\Media\Models\Media as BaseMedia;
class CustomMedia extends BaseMedia
{
protected $casts = [
'custom_field' => 'string',
];
}
Update the config to use your model:
'model' => \App\Models\CustomMedia::class,
Dynamic Collections Create collections dynamically based on model attributes:
$post->addMedia($file)
->usingCollection("posts_{$post->category->slug}")
->save();
Presets and Conversions
Use Spatie’s MediaLibrary presets for image resizing:
$media = $post->addMedia($file)->toMediaCollection('images');
$media->regeneratePresets();
Define presets in config/media.php:
'presets' => [
'thumbnails' => [
'width' => 200,
'height' => 200,
'fit' => \Spatie\Image\Enums\Fit::Crop,
],
],
API Responses Serialize media data for APIs:
$post->append(['media' => function ($post) {
return $post->getMedia('image')->map->only(['id', 'url', 'alt']);
}]);
How can I help you explore Laravel packages today?