Try Live
Add Docs
Rankings
Pricing
Docs
Install
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
Livewire Filemanager
https://github.com/livewire-filemanager/filemanager
Admin
A simple, friendly, and practical Livewire-powered file manager for Laravel applications, offering
...
Tokens:
24,893
Snippets:
126
Trust Score:
5.6
Update:
4 months ago
Context
Skills
Chat
Benchmark
72.3
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Livewire Filemanager ## Introduction Livewire Filemanager is a comprehensive file management package designed specifically for Laravel applications. Built with Livewire 3 and powered by Spatie's Media Library, it provides a modern, interactive interface for managing files and folders within Laravel projects. The package offers intuitive drag-and-drop functionality, real-time search capabilities, and seamless integration with Laravel's ecosystem, making it an ideal solution for developers who need robust file management without the complexity of building it from scratch. The package combines a rich user interface with a complete RESTful API, supporting both interactive web-based file management and programmatic access via API endpoints. It includes built-in support for multi-language interfaces (11 languages), dark mode theming, automatic thumbnail generation for images, and optional access control lists (ACL) for multi-user environments. The architecture leverages Laravel's authentication system, queue management for background processing, and follows Laravel's conventions for easy integration and maintenance. ## Installation and Basic Setup ### Install Package via Composer ```bash composer require livewire-filemanager/filemanager ``` ### Publish and Run Migrations ```bash # Publish filemanager migrations php artisan vendor:publish --tag=livewire-fileuploader-migrations # Publish Spatie Media Library migrations (if not already done) php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="medialibrary-migrations" # Run migrations to create folders and media tables php artisan migrate ``` ### Basic Implementation in Blade Template ```html <!DOCTYPE html> <html> <head> <title>File Manager</title> @filemanagerStyles </head> <body> <div class="container mx-auto p-4"> <h1>My File Manager</h1> <x-livewire-filemanager /> </div> @filemanagerScripts </body> </html> ``` ### Production Setup with Tailwind CSS ```javascript // tailwind.config.js module.exports = { content: [ './resources/**/*.blade.php', './vendor/livewire-filemanager/filemanager/resources/views/**/*.blade.php', ], theme: { extend: {}, }, plugins: [], } ``` ```bash # Rebuild Tailwind npm run build # Start queue workers for thumbnail generation php artisan queue:work ``` ## Configuration ### Publish Configuration File ```bash php artisan vendor:publish --tag=livewire-fileuploader-config ``` ### Complete Configuration Example ```php <?php // config/livewire-fileuploader.php return [ // Enable ACL to restrict file access to creators only 'acl_enabled' => true, // API Configuration 'api' => [ 'enabled' => true, 'prefix' => 'filemanager/v1', 'middleware' => ['api', 'auth:sanctum'], 'rate_limit' => '100,1', 'max_file_size' => 10240, // KB 'allowed_extensions' => [ 'jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'txt', 'zip' ], 'chunk_size' => 1048576, // 1MB ], // Folder Configuration 'folders' => [ 'max_depth' => 5, // Maximum folder nesting level ], // Custom Callbacks 'callbacks' => [ 'before_upload' => function($file) { // Validate file before upload \Log::info('Uploading file: ' . $file->getClientOriginalName()); }, 'after_upload' => function($media) { // Process file after upload \Log::info('File uploaded: ' . $media->file_name); }, 'access_check' => function($user, $media) { // Custom access control logic return $user->hasRole('admin') || $media->custom_properties['user_id'] === $user->id; }, ], ]; ``` ## API Authentication Setup ### Configure Laravel Sanctum for API Access ```bash # Install Sanctum (if not already installed) composer require laravel/sanctum # Publish Sanctum configuration php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" # Run Sanctum migrations php artisan migrate ``` ### Generate API Token for User ```php <?php // In your controller or tinker use App\Models\User; $user = User::find(1); // Create token with full access $token = $user->createToken('filemanager-api')->plainTextToken; // Output: 1|abcdef123456... echo $token; ``` ### Test API Authentication ```bash # Store token in variable TOKEN="1|abcdef123456..." # Test authenticated request curl -X GET "https://your-domain.com/api/filemanager/v1/folders" \ -H "Accept: application/json" \ -H "Authorization: Bearer $TOKEN" ``` ## API - List Folders ### Get All Folders with Filtering ```bash # List all folders curl -X GET "https://your-domain.com/api/filemanager/v1/folders" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" # Filter by parent folder curl -X GET "https://your-domain.com/api/filemanager/v1/folders?parent_id=5" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" # Search folders by name curl -X GET "https://your-domain.com/api/filemanager/v1/folders?search=documents" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" ``` ```json { "data": [ { "id": 1, "name": "Documents", "slug": "documents", "parent_id": null, "user_id": 1, "created_at": "2024-01-15T10:30:00.000000Z", "updated_at": "2024-01-15T10:30:00.000000Z", "children": [], "media": [] }, { "id": 2, "name": "Images", "slug": "images", "parent_id": null, "user_id": 1, "created_at": "2024-01-15T11:00:00.000000Z", "updated_at": "2024-01-15T11:00:00.000000Z", "children": [], "media": [] } ] } ``` ## API - Create Folder ### Create New Folder in Hierarchy ```bash # Create root folder curl -X POST "https://your-domain.com/api/filemanager/v1/folders" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "name": "Projects", "parent_id": null }' # Create nested folder curl -X POST "https://your-domain.com/api/filemanager/v1/folders" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "name": "2024 Projects", "parent_id": 1 }' ``` ```json { "data": { "id": 3, "name": "Projects", "slug": "projects", "parent_id": null, "user_id": 1, "created_at": "2024-01-15T14:22:00.000000Z", "updated_at": "2024-01-15T14:22:00.000000Z", "children": [], "media": [] } } ``` ## API - Update Folder ### Rename Existing Folder ```bash # Update folder name curl -X PUT "https://your-domain.com/api/filemanager/v1/folders/3" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "name": "Active Projects" }' ``` ```json { "data": { "id": 3, "name": "Active Projects", "slug": "active-projects", "parent_id": null, "user_id": 1, "created_at": "2024-01-15T14:22:00.000000Z", "updated_at": "2024-01-15T14:30:00.000000Z", "children": [], "media": [] } } ``` ## API - Delete Folder ### Remove Folder and Contents ```bash # Delete folder (cannot delete home/root folders) curl -X DELETE "https://your-domain.com/api/filemanager/v1/folders/3" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" ``` ```json { "message": "Folder deleted successfully" } ``` ```bash # Attempt to delete home folder returns error curl -X DELETE "https://your-domain.com/api/filemanager/v1/folders/1" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" ``` ```json { "message": "Cannot delete home folder" } ``` ## API - Get Folder Details ### Retrieve Single Folder with Relationships ```bash # Get folder with children and media curl -X GET "https://your-domain.com/api/filemanager/v1/folders/1" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" ``` ```json { "data": { "id": 1, "name": "Documents", "slug": "documents", "parent_id": null, "user_id": 1, "created_at": "2024-01-15T10:30:00.000000Z", "updated_at": "2024-01-15T10:30:00.000000Z", "children": [ { "id": 5, "name": "Contracts", "slug": "contracts", "parent_id": 1, "created_at": "2024-01-15T11:00:00.000000Z" } ], "media": [ { "id": 10, "name": "invoice.pdf", "file_name": "invoice.pdf", "mime_type": "application/pdf", "size": 245760 } ] } } ``` ## API - Upload File to Folder ### Upload Single or Multiple Files ```bash # Upload single file to specific folder curl -X POST "https://your-domain.com/api/filemanager/v1/folders/1/upload" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -F "files[]=@/path/to/document.pdf" \ -F "files[]=@/path/to/image.jpg" ``` ```json { "message": "Files uploaded successfully", "files": [ { "id": 15, "name": "document.pdf", "file_name": "document.pdf", "mime_type": "application/pdf", "size": 524288, "url": "https://your-domain.com/media/15/document.pdf", "thumbnail_url": null, "created_at": "2024-01-15T15:00:00.000000Z" }, { "id": 16, "name": "image.jpg", "file_name": "image.jpg", "mime_type": "image/jpeg", "size": 102400, "url": "https://your-domain.com/media/16/image.jpg", "thumbnail_url": "https://your-domain.com/media/16/conversions/image-thumbnail.jpg", "created_at": "2024-01-15T15:00:00.000000Z" } ] } ``` ## API - Bulk File Upload ### Upload Multiple Files with Error Handling ```bash # Bulk upload with mixed success/failure curl -X POST "https://your-domain.com/api/filemanager/v1/files/bulk" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -F "folder_id=1" \ -F "files[]=@/path/to/valid-file.pdf" \ -F "files[]=@/path/to/another-file.jpg" \ -F "files[]=@/path/to/invalid-file.exe" ``` ```json { "message": "Bulk upload completed", "uploaded": 2, "failed": 1, "files": [ { "id": 20, "name": "valid-file.pdf", "file_name": "valid-file.pdf", "mime_type": "application/pdf", "size": 1048576 }, { "id": 21, "name": "another-file.jpg", "file_name": "another-file.jpg", "mime_type": "image/jpeg", "size": 204800 } ], "errors": [ { "file": "invalid-file.exe", "error": "The file type is not allowed" } ] } ``` ## API - List Files ### Query Files with Pagination and Filtering ```bash # List all files with pagination curl -X GET "https://your-domain.com/api/filemanager/v1/files?page=1&per_page=20" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" # Filter files by folder curl -X GET "https://your-domain.com/api/filemanager/v1/files?folder_id=1" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" # Search files by name curl -X GET "https://your-domain.com/api/filemanager/v1/files?search=invoice" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" ``` ```json { "data": [ { "id": 10, "name": "invoice-2024.pdf", "file_name": "invoice-2024.pdf", "mime_type": "application/pdf", "size": 245760, "url": "https://your-domain.com/media/10/invoice-2024.pdf", "thumbnail_url": null, "folder_id": 1, "created_at": "2024-01-10T09:30:00.000000Z", "updated_at": "2024-01-10T09:30:00.000000Z" }, { "id": 11, "name": "logo.png", "file_name": "logo.png", "mime_type": "image/png", "size": 51200, "url": "https://your-domain.com/media/11/logo.png", "thumbnail_url": "https://your-domain.com/media/11/conversions/logo-thumbnail.jpg", "folder_id": 2, "created_at": "2024-01-12T14:00:00.000000Z", "updated_at": "2024-01-12T14:00:00.000000Z" } ] } ``` ## API - Update File ### Rename File ```bash # Update file name curl -X PUT "https://your-domain.com/api/filemanager/v1/files/10" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "name": "invoice-january-2024.pdf" }' ``` ```json { "data": { "id": 10, "name": "invoice-january-2024.pdf", "file_name": "invoice-january-2024.pdf", "mime_type": "application/pdf", "size": 245760, "url": "https://your-domain.com/media/10/invoice-january-2024.pdf", "created_at": "2024-01-10T09:30:00.000000Z", "updated_at": "2024-01-15T16:20:00.000000Z" } } ``` ## API - Delete File ### Remove File from Storage ```bash # Delete specific file curl -X DELETE "https://your-domain.com/api/filemanager/v1/files/10" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" ``` ```json { "message": "File deleted successfully" } ``` ## API - Download File ### Retrieve File Content ```bash # Download file (returns file content or download prompt) curl -X GET "https://your-domain.com/api/filemanager/v1/files/10" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -o downloaded-file.pdf # For images/PDFs, displays inline in browser # For other types, triggers download ``` ## Livewire Component Usage ### Programmatic File Upload in Livewire ```php <?php namespace App\Http\Livewire; use Livewire\Component; use Livewire\WithFileUploads; use LivewireFilemanager\Filemanager\Models\Folder; use Illuminate\Support\Facades\Auth; class DocumentUploader extends Component { use WithFileUploads; public $document; public $selectedFolder; public function mount() { // Get user's Documents folder or create it $this->selectedFolder = Folder::firstOrCreate([ 'name' => 'Documents', 'parent_id' => null, 'user_id' => Auth::id() ]); } public function uploadDocument() { $this->validate([ 'document' => 'required|file|max:10240|mimes:pdf,doc,docx' ]); try { // Upload file to folder $media = $this->selectedFolder ->addMedia($this->document->getRealPath()) ->usingName($this->document->getClientOriginalName()) ->withCustomProperties([ 'user_id' => Auth::id(), 'uploaded_via' => 'livewire-component' ]) ->toMediaCollection('medialibrary'); session()->flash('success', 'Document uploaded successfully!'); return redirect()->route('documents.show', $media->id); } catch (\Exception $e) { session()->flash('error', 'Upload failed: ' . $e->getMessage()); } } public function render() { return view('livewire.document-uploader'); } } ``` ## Direct File Access Routes ### Enable Public File Access ```php <?php // routes/web.php use LivewireFilemanager\Filemanager\Http\Controllers\Files\FileController; // Enable direct file access via URLs Route::get('files/{path}', [FileController::class, 'show']) ->where('path', '.*') ->name('assets.show') ->middleware(['auth']); // Optional: require authentication // Example URLs generated: // https://your-domain.com/files/documents/invoice.pdf // https://your-domain.com/files/images/logo.png ``` ### Generate File URL in Blade ```blade @php $file = \LivewireFilemanager\Filemanager\Models\Media::find(10); @endphp <!-- Display image with thumbnail --> <img src="{{ $file->getUrl('thumbnail') }}" alt="{{ $file->name }}" class="w-32 h-32 object-cover"> <!-- Link to full file --> <a href="{{ $file->getUrl() }}" target="_blank" class="text-blue-600 hover:underline"> View {{ $file->name }} </a> <!-- Download link --> <a href="{{ $file->getUrl() }}" download="{{ $file->file_name }}" class="btn btn-primary"> Download File </a> ``` ## Access Control (ACL) Implementation ### Enable User-Scoped File Access ```bash # Publish config files php artisan vendor:publish --tag=livewire-fileuploader-config php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="medialibrary-config" ``` ```php <?php // config/livewire-fileuploader.php return [ 'acl_enabled' => true, // ... other config ]; ``` ```php <?php // config/media-library.php return [ 'media_model' => \LivewireFilemanager\Filemanager\Models\Media::class, // ... other config ]; ``` ```php <?php // Custom Media Model with ACL namespace App\Models; use LivewireFilemanager\Filemanager\Traits\HasMediaOwner; use Spatie\MediaLibrary\MediaCollections\Models\Media as BaseMedia; class Media extends BaseMedia { use HasMediaOwner; // Files are automatically scoped to authenticated user // Users can only see and manage their own files } ``` ## Custom Callbacks for File Processing ### Implement Upload Hooks ```php <?php // config/livewire-fileuploader.php return [ 'callbacks' => [ 'before_upload' => function($file) { // Validate file type $allowedMimes = ['image/jpeg', 'image/png', 'application/pdf']; if (!in_array($file->getMimeType(), $allowedMimes)) { throw new \Exception('File type not allowed'); } // Check virus scanning (example with ClamAV) if (extension_loaded('clamav')) { $result = cl_scanfile($file->getRealPath()); if ($result !== CL_CLEAN) { throw new \Exception('File failed security scan'); } } // Log upload attempt \Log::info('File upload started', [ 'filename' => $file->getClientOriginalName(), 'size' => $file->getSize(), 'user_id' => auth()->id() ]); }, 'after_upload' => function($media) { // Send notification $user = auth()->user(); $user->notify(new \App\Notifications\FileUploaded($media)); // Update user storage quota \App\Models\UserQuota::where('user_id', $user->id) ->increment('used_space', $media->size); // Process image with custom logic if (str_starts_with($media->mime_type, 'image/')) { // Generate additional conversions $media->addMediaConversion('large') ->width(1920) ->height(1080) ->performOnCollections('medialibrary'); } // Log successful upload \Log::info('File uploaded successfully', [ 'media_id' => $media->id, 'filename' => $media->file_name ]); }, 'access_check' => function($user, $media) { // Custom access control logic if ($user->hasRole('admin')) { return true; } // Check if user owns the file if ($media->getCustomProperty('user_id') === $user->id) { return true; } // Check shared access $sharedUsers = $media->getCustomProperty('shared_with', []); if (in_array($user->id, $sharedUsers)) { return true; } return false; } ] ]; ``` ## Programmatic Folder Management ### Create and Manage Folders Programmatically ```php <?php namespace App\Services; use LivewireFilemanager\Filemanager\Models\Folder; use Illuminate\Support\Str; class FileOrganizer { public function createProjectStructure($projectName) { // Create root project folder $projectFolder = Folder::create([ 'name' => $projectName, 'slug' => Str::slug($projectName), 'parent_id' => null, 'user_id' => auth()->id() ]); // Create subfolders $subfolders = ['Documents', 'Images', 'Videos', 'Archives']; foreach ($subfolders as $folderName) { Folder::create([ 'name' => $folderName, 'slug' => Str::slug($folderName), 'parent_id' => $projectFolder->id, 'user_id' => auth()->id() ]); } return $projectFolder; } public function moveFiles($fileIds, $targetFolderId) { $targetFolder = Folder::findOrFail($targetFolderId); foreach ($fileIds as $fileId) { $media = \LivewireFilemanager\Filemanager\Models\Media::find($fileId); if ($media && $this->canMoveFile($media, $targetFolder)) { $media->model_id = $targetFolderId; $media->save(); } } } public function getFolderSize($folderId) { $folder = Folder::with('media')->findOrFail($folderId); $size = $folder->getMedia('medialibrary')->sum('size'); // Add sizes of child folders recursively foreach ($folder->children as $child) { $size += $this->getFolderSize($child->id); } return $size; } private function canMoveFile($media, $targetFolder) { // Check permissions if (config('livewire-fileuploader.acl_enabled')) { return $media->getCustomProperty('user_id') === auth()->id(); } return true; } } ``` ## Error Handling and Validation ### API Error Responses ```bash # Validation error example curl -X POST "https://your-domain.com/api/filemanager/v1/folders" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -d '{ "parent_id": 1 }' ``` ```json { "message": "The name field is required.", "errors": { "name": [ "The name field is required." ] } } ``` ```bash # Unauthorized access example curl -X DELETE "https://your-domain.com/api/filemanager/v1/files/10" \ -H "Accept: application/json" \ -H "Authorization: Bearer INVALID_TOKEN" ``` ```json { "message": "Unauthenticated." } ``` ```bash # File not found example curl -X GET "https://your-domain.com/api/filemanager/v1/files/999" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" ``` ```json { "message": "File not found" } ``` ```bash # Rate limit exceeded example # After exceeding 100 requests per minute curl -X GET "https://your-domain.com/api/filemanager/v1/folders" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_API_TOKEN" ``` ```json { "message": "Too Many Requests" } ``` ## Internationalization ### Set Application Language ```php <?php // In your middleware or controller use Illuminate\Support\Facades\App; // Set locale for entire application App::setLocale('fr'); // Available languages: // 'en' - English // 'es' - Spanish // 'fr' - French // 'it' - Italian // 'pt_BR' - Portuguese (Brazil) // 'pt_PT' - Portuguese (Portugal) // 'ar' - Arabic // 'fa' - Persian // 'he' - Hebrew // 'ro' - Romanian // 'tr' - Turkish // 'nl' - Dutch ``` ### Custom Translation Override ```php <?php // resources/lang/en/filemanager.php return [ 'upload' => 'Upload Files', 'create_folder' => 'New Folder', 'delete' => 'Delete', 'rename' => 'Rename', 'search' => 'Search files and folders...', 'empty' => 'This folder is empty', 'folder_without_title' => 'Untitled Folder', 'folder_already_exists' => 'A folder with this name already exists', 'validation' => [ 'folder_name_required' => 'Folder name is required', 'max_folder_depth_exceeded' => 'Maximum folder depth of :max levels exceeded', ], ]; ``` ## Summary and Use Cases Livewire Filemanager serves as a production-ready solution for a wide range of file management scenarios in Laravel applications. Common use cases include document management systems where users need to organize contracts, invoices, and reports in a hierarchical folder structure; content management systems requiring media library functionality with thumbnail generation and bulk upload capabilities; multi-tenant applications where ACL ensures strict data isolation between users; and API-driven platforms where external services need programmatic access to upload, retrieve, and manage files. The package excels in environments requiring user-friendly interfaces combined with developer-friendly APIs, making it suitable for both end-user applications and system integrations. The package's architecture promotes seamless integration with existing Laravel applications through its service provider pattern, middleware support, and policy-based authorization. Developers can customize behavior through configuration callbacks, extend the UI by publishing views, and implement custom access control logic through policies. The combination of Livewire for reactive interfaces, Spatie Media Library for robust file handling, and Laravel Sanctum for API authentication creates a comprehensive ecosystem that handles everything from small single-user applications to large multi-tenant platforms. With support for queue-based thumbnail generation, automatic slug generation for SEO-friendly URLs, and extensive language support, the package provides enterprise-grade features while maintaining Laravel's characteristic simplicity and elegance.