van-ons/laravel-attachment-library
Attach files to Laravel Eloquent models with a simple HasAttachments trait and Attachment model. Includes installer command for migrations/assets and an attachments relationship to link existing uploads to any model.
Installation:
composer require van-ons/laravel-attachment-library
php artisan attachment-library:install
This publishes migrations, config, and assets.
Configure Disk (optional):
Set ATTACHMENTS_DISK in .env to override the default public disk.
Enable Attachments on Model:
Add the HasAttachments trait to your Eloquent model:
use VanOns\LaravelAttachmentLibrary\Concerns\HasAttachments;
class Post extends Model {
use HasAttachments;
}
First Use Case: Upload and attach a file:
$attachment = \VanOns\LaravelAttachmentLibrary\Facades\AttachmentManager::upload($request->file('document'));
$post->attachments()->attach($attachment);
$post->save();
Uploading Files:
$attachment = AttachmentManager::upload($request->file('file'), [
'directory' => 'posts/' . $post->id,
'metadata' => ['user_id' => auth()->id()]
]);
Managing Attachments via Model:
// Attach existing attachment
$post->attachments()->attach($attachmentId);
// Detach attachment
$post->attachments()->detach($attachmentId);
// Sync attachments (replace all)
$post->attachments()->sync([$attachmentId1, $attachmentId2]);
Directory Management:
// Create directory for a model
$dir = AttachmentManager::createDirectory('posts/' . $post->id);
// Move attachment to directory
AttachmentManager::move($attachment, 'posts/' . $post->id);
Responsive Images:
<x-laravel-attachment-library-image :src="$post->image" size="medium" />
Or programmatically:
$resized = Resizer::src($attachment)->width(300)->height(200)->resize();
$request->validate([
'file' => 'required|file|max:10240', // 10MB
]);
filament-attachment-library for admin panel support.AttachmentCreated) to trigger notifications or logs:
event(new AttachmentCreated($attachment));
Disk Configuration:
public) unless you’ve verified they’re attachment-only.Glide Cache:
storage/app/img. Monitor cache size with:
php artisan glide:stats
php artisan glide:clear
File Naming:
ReplaceControlCharacters namer may conflict with URLs. Customize via config:
'file_namers' => [
\App\FileNamers\CustomNamer::class, // Your custom class
],
Metadata Retrievers:
'metadata_retrievers' => [
\VanOns\LaravelAttachmentLibrary\Adapters\FileMetadata\GdMetadataAdapter::class => ['image/*'],
],
Attachment Not Found:
path column.Missing Resized Images:
cache_path is writable.Resizer::src($attachment)->regenerate();
Custom Attachment Model:
Extend \VanOns\LaravelAttachmentLibrary\Models\Attachment and update config:
'class_mapping' => [
'attachment' => \App\Models\CustomAttachment::class,
],
Metadata Providers: Add custom metadata (e.g., EXIF data):
class ExifMetadataProvider extends MetadataAdapter {
protected function retrieve(string $path): FileMetadata {
$exif = exif_read_data($path);
return new FileMetadata(['exif' => $exif]);
}
}
Register in config:
'metadata_retrievers' => [
ExifMetadataProvider::class => ['image/jpeg'],
],
File Namers: Override default naming logic (e.g., UUIDs):
class UuidFileNamer extends FileNamer {
public function execute(string $value): string {
return Str::uuid()->toString();
}
}
Configure in attachment-library.php.
sync() instead of attach()/detach() loops for bulk updates.with() to avoid N+1 queries:
$post = Post::with('attachments')->find($id);
How can I help you explore Laravel packages today?