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
Configure Disk (optional):
Set ATTACHMENTS_DISK in .env to specify a dedicated disk (e.g., ATTACHMENTS_DISK=attachments).
Enable Attachments on a Model:
Add the HasAttachments trait to your Eloquent model:
use VanOns\LaravelAttachmentLibrary\Concerns\HasAttachments;
class Post extends Model
{
use HasAttachments;
}
First Use Case:
Upload an attachment via the AttachmentManager facade:
use VanOns\LaravelAttachmentLibrary\Facades\AttachmentManager;
$attachment = AttachmentManager::upload($request->file('document'));
$post->attachments()->attach($attachment);
Uploading Files:
$attachment = AttachmentManager::upload($file, [
'directory' => 'posts/' . $post->id,
'metadata' => ['user_id' => auth()->id()],
]);
Managing Attachments:
// Move attachment
AttachmentManager::move($attachment, 'new/directory');
// Rename attachment
AttachmentManager::rename($attachment, 'new_filename.ext');
// Delete attachment
AttachmentManager::delete($attachment);
Directory Management:
// Create directory
AttachmentManager::createDirectory('user_uploads/' . auth()->id());
// Delete directory (recursively)
AttachmentManager::deleteDirectory('old_uploads');
Image Resizing:
// Blade component (responsive)
<x-laravel-attachment-library-image :src="$image" size="medium" />
// Manual resizing
$resized = Resizer::src($image)->width(300)->height(200)->resize();
Form Requests: Validate files before upload:
public function rules()
{
return [
'document' => 'required|file|mimes:pdf,docx|max:10240',
];
}
Model Observers: Sync attachments on model events:
class PostObserver
{
public function deleted(Post $post)
{
$post->attachments()->each->delete();
}
}
API Responses: Serialize attachments with API resources:
public function toArray($request)
{
return [
'attachments' => $this->attachments->map(fn ($a) => [
'url' => $a->url,
'size' => $a->size,
]),
];
}
Disk Configuration:
ATTACHMENTS_DISK) exists in filesystems.php and is not shared with other files.'disks' => [
'attachments' => [
'driver' => 'local',
'root' => storage_path('app/attachments'),
],
],
Glide Cache:
php artisan glide:clear
php artisan glide:stats
File Naming:
ReplaceControlCharacters namer may conflict with special characters. Extend or override:
// config/attachment-library.php
'file_namers' => [
\App\FileNamers\CustomNamer::class,
],
Metadata Retrievers:
'metadata_retrievers' => [
\VanOns\LaravelAttachmentLibrary\Adapters\FileMetadata\GdMetadataAdapter::class => ['image/*'],
],
Attachment Not Found:
Verify the disk path and file permissions. Check the attachments table for correct path and disk values.
Missing URLs:
Ensure the url column in the attachments table is populated. Use:
$attachment->refreshUrl(); // Force URL regeneration
Glide Errors:
Validate glide.php config (e.g., cache_path, source_path). Test with:
php artisan glide:test
Custom Attachment Model:
Extend the base Attachment model:
class CustomAttachment extends \VanOns\LaravelAttachmentLibrary\Models\Attachment
{
protected $casts = [
'custom_field' => 'boolean',
];
}
Update config:
'class_mapping' => [
'attachment' => \App\Models\CustomAttachment::class,
],
Custom File Namers:
Implement FileNamer for unique naming logic:
class UuidFileNamer extends \VanOns\LaravelAttachmentLibrary\FileNamers\FileNamer
{
public function execute(string $value): string
{
return Str::uuid() . '.' . pathinfo($value, PATHINFO_EXTENSION);
}
}
Metadata Adapters: Add support for new file types (e.g., PDFs):
class PdfMetadataAdapter extends \VanOns\LaravelAttachmentLibrary\Adapters\FileMetadata\MetadataAdapter
{
protected function retrieve(string $path): ?FileMetadata
{
$pdf = \Spatie\PdfToText\Pdf::load($path);
return new FileMetadata(['pages' => $pdf->pageCount()]);
}
}
Register in config:
'metadata_retrievers' => [
\App\Adapters\PdfMetadataAdapter::class => ['application/pdf'],
],
Events:
Listen for attachment events (e.g., AttachmentCreated):
Attachment::created(function ($attachment) {
// Send notification or log
});
How can I help you explore Laravel packages today?