spatie/flysystem-dropbox
Flysystem adapter for Dropbox using Dropbox API v2. Connect via an authorization token and use the Spatie Dropbox client with a Flysystem Filesystem. Supports modern Flysystem versions (v2/3); see v1 branch for Flysystem v1.
Installation:
composer require spatie/flysystem-dropbox
Ensure league/flysystem is also installed (this package depends on it).
First Use Case: Store a file in Dropbox via Laravel's Filesystem:
use Spatie\Dropbox\DropboxFilesystem;
use Illuminate\Support\Facades\Storage;
// Configure Dropbox in config/filesystems.php
'dropbox' => [
'driver' => 'dropbox',
'token' => env('DROPBOX_TOKEN'),
'root' => '/laravel-app', // Optional: Default root folder
],
// Usage
Storage::disk('dropbox')->put('file.txt', 'Hello Dropbox!');
Key Files:
config/filesystems.php: Define Dropbox disk configuration..env: Store DROPBOX_TOKEN (obtain via Dropbox Developer App).File Operations:
// Upload
Storage::disk('dropbox')->put('path/file.jpg', file_get_contents('local.jpg'));
// Download
$contents = Storage::disk('dropbox')->get('path/file.jpg');
fwrite()/fread() for memory efficiency:
$stream = Storage::disk('dropbox')->readStream('large-file.zip');
file_put_contents('local.zip', $stream);
Directory Handling:
Storage::disk('dropbox')->makeDirectory('folder/subfolder');
Storage::disk('dropbox')->deleteDirectory('folder');
$files = Storage::disk('dropbox')->files('folder/');
$directories = Storage::disk('dropbox')->directories('folder/');
Shared Links: Generate public links for files/folders:
$url = Storage::disk('dropbox')->url('file.txt', [
'expires' => now()->addHours(1),
'raw' => true, // Force direct download
]);
Laravel Artisan Commands: Sync local files to Dropbox:
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
class SyncToDropbox extends Command {
protected $signature = 'dropbox:sync {source}';
public function handle() {
$files = Storage::disk('local')->files($this->argument('source'));
foreach ($files as $file) {
Storage::disk('dropbox')->put($file, Storage::disk('local')->get($file));
}
}
}
Event Listeners: Trigger actions on Dropbox file changes (e.g., via Dropbox Webhooks):
// config/filesystems.php
'dropbox' => [
'driver' => 'dropbox',
'token' => env('DROPBOX_TOKEN'),
'webhook_secret' => env('DROPBOX_WEBHOOK_SECRET'), // For verification
];
Fallback Logic: Combine with local storage for resilience:
$path = 'critical-file.txt';
if (!Storage::disk('dropbox')->exists($path)) {
Storage::disk('dropbox')->put($path, Storage::disk('local')->get($path));
}
Token Permissions:
files.metadata.read (for listing files).files.content.read/files.content.write (for uploads/downloads).403 Forbidden often indicates insufficient scopes. Regenerate the token with broader permissions.Rate Limits:
$metadata = Storage::disk('dropbox')->metadata('file.txt');
cache()->put("dropbox:metadata:file.txt", $metadata, now()->addMinutes(5));
Path Handling:
Folder/FILE.txt vs. folder/file.txt).Path not found may occur if the case doesn’t match. Use strtolower() for consistency:
$path = strtolower('Folder/FILE.txt');
Large File Uploads:
// For files > 500MB, use streaming:
$stream = fopen('local-large-file.zip', 'r');
Storage::disk('dropbox')->writeStream('remote-large-file.zip', $stream);
fclose($stream);
Webhook Delays:
try {
$response = Http::post('https://your-app.com/dropbox-webhook', $payload);
} catch (\Throwable $e) {
if ($attempts < 3) {
sleep(2 ** $attempts);
$attempts++;
retry();
}
}
Enable API Logging:
Add to config/filesystems.php:
'dropbox' => [
'driver' => 'dropbox',
'token' => env('DROPBOX_TOKEN'),
'debug' => env('APP_DEBUG'), // Logs API requests/responses
];
Check storage/logs/laravel.log for Dropbox API errors.
Common Errors:
| Error | Cause | Solution |
|---|---|---|
401 Unauthorized |
Expired/invalid token | Regenerate token via Dropbox Developer App |
409 Conflict |
File already exists | Use update() or check exists() first |
429 Too Many Requests |
Rate limit exceeded | Implement retries with backoff |
404 Not Found |
Path doesn’t exist | Verify case sensitivity and permissions |
Custom Metadata: Extend file metadata handling:
// Add custom tags to Dropbox files
$client = app(\Spatie\Dropbox\DropboxClient::class);
$client->updateFileMetadata(
'/path/to/file.txt',
['client_modified' => now()->toIso8601String()]
);
Shared Link Customization: Override URL generation in a service provider:
Storage::extend('dropbox', function ($app, $config) {
$adapter = new \Spatie\Dropbox\DropboxAdapter($config['token']);
return new \League\Flysystem\Filesystem($adapter, new \Spatie\Dropbox\DropboxVisibility());
});
Local Cache Layer: Cache Dropbox file metadata locally to reduce API calls:
Storage::disk('dropbox')->metadata('file.txt', function () {
return cache()->remember("dropbox:metadata:file.txt", now()->addMinutes(5), function () {
return $this->adapter->getMetadata('file.txt');
});
});
Event Dispatching: Trigger Laravel events on file operations:
Storage::disk('dropbox')->put('file.txt', 'content', function () {
event(new DropboxFileUploaded('file.txt'));
});
How can I help you explore Laravel packages today?