spykapps/filament-uppy-upload
Installation:
composer require spykapps/filament-uppy-upload
Publish config (if needed):
php artisan vendor:publish --provider="SpykApps\FilamentUppyUpload\FilamentUppyUploadServiceProvider"
First Use Case: Add the field to a Filament resource/form:
use SpykApps\FilamentUppyUpload\Fields\UppyUploadField;
UppyUploadField::make('document')
->disk('s3') // or 'public', 'local', etc.
->directory('user_uploads/{user_id}') // Dynamic paths supported
->maxSize(100) // in MB
->maxFiles(5)
Where to Look First:
config/filament-uppy-upload.php for default settings (e.g., chunk size, allowed MIME types).vendor/spykapps/filament-uppy-upload/src/Fields/UppyUploadField.php for method signatures and options.Basic File Uploads:
UppyUploadField::make('profile_picture')
->disk('public')
->imageEditor() // Enable Uppy's image editor
->required()
Remote Source Integration:
UppyUploadField::make('external_file')
->disk('s3')
->remoteSources(['google-drive', 'dropbox'])
->allowedFileExtensions(['pdf', 'docx'])
Dynamic Directories: Use closures for runtime paths:
UppyUploadField::make('resume')
->disk('s3')
->directory(fn ($record) => "resumes/{$record->user_id}/{$record->job_id}")
Validation & Processing:
Override handleUploadedFiles in your resource:
protected function handleUploadedFiles(array $files): void
{
foreach ($files as $file) {
// Process metadata, rename, or trigger events
$file->update(['processed_at' => now()]);
}
}
Chunked Uploads with Custom Logic:
Configure chunk size in config/filament-ppy-upload.php:
'chunk_size' => 5, // MB
Handle chunked uploads via UppyUploadField::make()->chunkedUploads(true).
Filament Panels/Resources:
Use in both Form and Table contexts (for bulk uploads):
// In a Table column:
UppyUploadField::make('attachment')
->disk('s3')
->onlyUploadButton() // Hide file list
Event Listeners:
Listen for upload events (e.g., UppyUploaded):
use SpykApps\FilamentUppyUpload\Events\UppyUploaded;
event(new UppyUploaded($file, $record));
Custom Uppy Plugins:
Extend Uppy’s core via uppyOptions:
UppyUploadField::make('video')
->uppyOptions([
'plugins' => [
new UppyWebcam({
target: 'webcam-container',
targetBackground: '#f0f0f0',
}),
],
])
Testing:
Use mocks in tests:
$field->fakeUpload('test.pdf', 'public', 'test.pdf');
Chunked Uploads:
client_max_body_size (e.g., 100M).multipart_copy permissions.File Overwrites:
->uniqueFilename() to append timestamps:
->uniqueFilename(fn ($file) => now()->format('YmdHis').'-'.$file->getClientOriginalName())
Remote Source Quotas:
429 errors.Large File Timeouts:
max_execution_time and memory_limit for processing large uploads.Filament 5 Migration:
disk() → storageDisk()). Check the upgrade guide.Uppy Console Logs:
Enable Uppy’s debug mode in uppyOptions:
->uppyOptions(['debug' => true])
Check browser console for errors (e.g., CORS, plugin failures).
Laravel Logs:
UPLOAD_LOGGING in config to log file operations:
'logging' => [
'enabled' => true,
'channel' => 'single',
],
Common Errors:
FileNotFoundException: Verify disk/directory permissions.InvalidArgumentException: Check allowedFileExtensions or maxSize./filament-uppy-upload) is whitelisted.Custom Storage Handlers:
Extend SpykApps\FilamentUppyUpload\Services\StorageHandler to support non-Laravel storage (e.g., FTP):
class CustomStorageHandler extends StorageHandler {
public function saveFile($file, $path) {
// Custom logic
}
}
Bind it in AppServiceProvider:
$this->app->bind(SpykApps\FilamentUppyUpload\Contracts\StorageHandler::class, CustomStorageHandler::class);
Post-Processing:
Use afterUpload callback:
->afterUpload(function ($file, $record) {
// Trigger a job or update related models
ProcessVideoJob::dispatch($file->path);
})
UI Customization:
Override Uppy’s template via uppyOptions:
->uppyOptions([
'metaFields' => [
{ id: 'custom_field', name: 'Custom Field', placeholder: 'Enter value' },
],
])
Bulk Operations:
For tables, use ->bulkUpload() and handle UppyBulkUploaded events:
UppyUploadField::make('documents')
->bulkUpload()
->directory('bulk_uploads/{date:Y-m-d}')
How can I help you explore Laravel packages today?