Overview
Lunar uses the Laravel-medialibrary package by Spatie to handle media across all models. Rather than reinvent the wheel, Lunar leverages this battle-tested package and adds its own conventions on top, including per-model media definition classes, automatic image conversions, and primary image management.Supported Models
The following models support media out of the box via theLunar\Core\Models\Concerns\HasMedia trait:
Lunar\Core\Models\ProductVariant does not use the HasMedia trait. Instead, it uses a many-to-many relationship with media through a pivot table. See Product Variant Images for details.Configuration
The media configuration is published atconfig/lunar/media.php.
The
definitions keys use aliases derived from the model class name (a snake-cased basename, e.g. Product becomes product, ProductOptionValue becomes product-option-value, ProductType becomes product_type). The fully qualified class name can also be used as the key.
Adding Media
Adding media to a model follows the standard Spatie Media Library API.Retrieving Media
Primary Images
Lunar adds a concept of “primary” images on top of Spatie’s media library. Each model can have one image marked as primary per collection, tracked via aprimary custom property on the media item.
Thumbnail Relationship
Models using theHasMedia trait have a thumbnail relationship that returns the primary image, scoped to the configured media collection (config('lunar.media.collection'), images by default):
Automatic Primary Management
Lunar includes aLunar\Core\Observers\MediaObserver that automatically enforces the following rules for the configured media collection:
- When a media item is marked as primary, all other items in the same collection are unmarked.
- When the primary image is deleted, the first remaining image in the collection is automatically promoted to primary.
- When a new image is added to an empty collection, it is automatically marked as primary.
Setting the Primary Image
Product Variant Images
Lunar\Core\Models\ProductVariant handles media differently from other models. Instead of using the HasMedia trait, it uses a many-to-many relationship with the media table through a media_product_variant pivot table.
Relationships
Pivot columns (media_product_variant)
getThumbnail() returns the image whose pivot primary flag is set; if none is marked, it falls back to the parent product’s thumbnail.
Fallback Images
If a model has no media, callinggetFirstMediaUrl or getFirstMediaPath returns an empty string by default. Fallback images can be configured in config/lunar/media.php or via environment variables:
useFallbackUrl and useFallbackPath methods on the media collection.
Default Conversions
Lunar\Core\Media\StandardDefinitions, the default media definition class, registers the following image conversions:
All conversions use
Spatie\Image\Enums\Fit::Fill for sizing, a white background and border, and preserve the original image format.
Custom Media Definitions
To customize the media collections and conversions for a model, create a class that implementsLunar\Core\Contracts\MediaDefinitions:
config/lunar/media.php:
Regenerating Conversions
After changing conversion definitions, regenerate existing conversions using the Spatie artisan command:Extending Your Own Models
Custom models can be given media support using the LunarHasMedia trait:
Definition Resolution
TheHasMedia trait resolves the media definition class for a model using the following priority:
- A snake_case alias in
config('lunar.media.definitions')(e.g.productforProduct) - The fully qualified class name in the config
- The parent class name in the config (useful for extended models)
- Falls back to
Lunar\Core\Media\StandardDefinitions