Overview
The Photo model represents individual photos in LaraCMS. It integrates with Spatie Media Library for image storage and manipulation, and can belong to multiple albums.
Namespace: App\Models\Photo
Extends: Illuminate\Database\Eloquent\Model
Implements: Spatie\MediaLibrary\HasMedia
Traits:
InteractsWithMedia - Spatie Media Library integration
Properties
Table Name
protected $table = 'photos';
Fillable Attributes
The title or name of the photo
Detailed description or caption for the photo
Relationships
albums()
Type: belongsToMany
Related Model: App\Models\Album
Pivot Table: album_photo
Foreign Key: photo_id
Related Key: album_id
Description: Returns all albums that contain this photo. A photo can belong to multiple albums.
public function albums()
{
return $this->belongsToMany(Album::class, 'album_photo', 'photo_id', 'album_id');
}
Example:
$photo = Photo::find(1);
$albums = $photo->albums;
foreach ($albums as $album) {
echo $album->album_name;
}
Methods
Returns: void
Description: Registers the ‘images’ media collection for storing photo files. Unlike single-file collections, this allows multiple images to be associated with a photo if needed.
public function registerMediaCollections(): void
{
$this->addMediaCollection('images');
}
Example:
$photo = Photo::find(1);
// Add image to the collection
$photo->addMedia($request->file('image'))
->toMediaCollection('images');
Parameters:
$media - Spatie\MediaLibrary\MediaCollections\Models\Media|null
Returns: void
Description: Defines image conversions for uploaded photos. Creates a ‘preview’ conversion that fits the image to 300x300 pixels for thumbnails and previews.
public function registerMediaConversions(?Media $media = null): void
{
$this
->addMediaConversion('preview')
->fit(Fit::Contain, 300, 300)
->nonQueued();
}
Usage Examples
Creating a Photo
use App\Models\Photo;
$photo = Photo::create([
'title' => 'Sunset at the Beach',
'description' => 'Beautiful sunset captured at Santa Monica Beach',
]);
Adding Image Files
$photo = Photo::find(1);
// Add a single image
$photo->addMedia($request->file('image'))
->toMediaCollection('images');
// Add image from path
$photo->addMedia('/path/to/image.jpg')
->toMediaCollection('images');
// Add image from URL
$photo->addMediaFromUrl('https://example.com/image.jpg')
->toMediaCollection('images');
Retrieving Images
$photo = Photo::find(1);
// Get first image URL
$imageUrl = $photo->getFirstMediaUrl('images');
// Get preview (thumbnail) URL
$thumbnailUrl = $photo->getFirstMediaUrl('images', 'preview');
// Get all images in collection
$images = $photo->getMedia('images');
foreach ($images as $image) {
echo $image->getUrl();
echo $image->getUrl('preview'); // Thumbnail version
}
// Check if photo has images
if ($photo->hasMedia('images')) {
// Photo has images
}
Working with Albums
$photo = Photo::find(1);
// Attach photo to album
$photo->albums()->attach($albumId);
// Attach to multiple albums
$photo->albums()->attach([1, 2, 3]);
// Sync albums (replace all existing)
$photo->albums()->sync([1, 2]);
// Detach from album
$photo->albums()->detach($albumId);
// Detach from all albums
$photo->albums()->detach();
// Get album count
$albumCount = $photo->albums()->count();
Querying Photos
// Get all photos
$photos = Photo::all();
// Find by title
$photo = Photo::where('title', 'Sunset at the Beach')->first();
// Search photos
$photos = Photo::where('title', 'like', '%sunset%')
->orWhere('description', 'like', '%sunset%')
->get();
// Get recent photos
$recentPhotos = Photo::orderBy('created_at', 'desc')
->limit(10)
->get();
// Get photos in specific album
$album = Album::find(1);
$photos = $album->photos;
Eager Loading
// Load photos with albums
$photos = Photo::with('albums')->get();
// Load photos with media
$photos = Photo::with('media')->get();
// Load both
$photos = Photo::with(['albums', 'media'])->get();
// With album count
$photos = Photo::withCount('albums')->get();
foreach ($photos as $photo) {
echo "{$photo->title} is in {$photo->albums_count} albums";
}
Updating Photos
$photo = Photo::find(1);
$photo->update([
'title' => 'Updated Photo Title',
'description' => 'Updated description',
]);
// Update and change image
$photo->update(['title' => 'New Title']);
// Clear old images and add new one
$photo->clearMediaCollection('images');
$photo->addMedia($request->file('new_image'))
->toMediaCollection('images');
Deleting Photos
$photo = Photo::find(1);
// Delete photo (automatically removes media files)
$photo->delete();
// Detach from albums before deleting
$photo->albums()->detach();
$photo->delete();
// Delete specific media
$media = $photo->getFirstMedia('images');
$media->delete();
$photo = Photo::find(1);
// Add media with custom properties
$photo->addMedia($request->file('image'))
->withCustomProperties(['photographer' => 'John Doe'])
->toMediaCollection('images');
// Get media with properties
$media = $photo->getFirstMedia('images');
$photographer = $media->getCustomProperty('photographer');
// Set media name
$photo->addMedia($request->file('image'))
->usingName('Beach Sunset')
->toMediaCollection('images');
// Set file name
$photo->addMedia($request->file('image'))
->usingFileName('custom-name.jpg')
->toMediaCollection('images');
Database Schema
The photos table includes:
id - Primary key
title - Photo title
description - Photo description/caption
created_at - Timestamp
updated_at - Timestamp
Pivot Tables
album_photo:
album_id - Foreign key to album table
photo_id - Foreign key to photos table
- Album - Albums containing this photo
Photos use Spatie Media Library for file storage:
- Original images are stored in the configured media disk
- Preview conversions (300x300) are automatically generated
- Media files are automatically deleted when the photo is deleted
- Supports multiple file formats (JPEG, PNG, GIF, WebP, etc.)