Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Flysystem Dropbox Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/flysystem-dropbox
    

    Ensure league/flysystem is also installed (this package depends on it).

  2. 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!');
    
  3. Key Files:

    • config/filesystems.php: Define Dropbox disk configuration.
    • .env: Store DROPBOX_TOKEN (obtain via Dropbox Developer App).

Implementation Patterns

Core Workflows

  1. File Operations:

    • Upload/Download:
      // Upload
      Storage::disk('dropbox')->put('path/file.jpg', file_get_contents('local.jpg'));
      
      // Download
      $contents = Storage::disk('dropbox')->get('path/file.jpg');
      
    • Streaming Large Files: Use fwrite()/fread() for memory efficiency:
      $stream = Storage::disk('dropbox')->readStream('large-file.zip');
      file_put_contents('local.zip', $stream);
      
  2. Directory Handling:

    • Create/Delete:
      Storage::disk('dropbox')->makeDirectory('folder/subfolder');
      Storage::disk('dropbox')->deleteDirectory('folder');
      
    • List Contents:
      $files = Storage::disk('dropbox')->files('folder/');
      $directories = Storage::disk('dropbox')->directories('folder/');
      
  3. Shared Links: Generate public links for files/folders:

    $url = Storage::disk('dropbox')->url('file.txt', [
        'expires' => now()->addHours(1),
        'raw' => true, // Force direct download
    ]);
    

Integration Tips

  • 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));
    }
    

Gotchas and Tips

Pitfalls

  1. Token Permissions:

    • Ensure your Dropbox App has:
      • files.metadata.read (for listing files).
      • files.content.read/files.content.write (for uploads/downloads).
    • Error: 403 Forbidden often indicates insufficient scopes. Regenerate the token with broader permissions.
  2. Rate Limits:

    • Dropbox API has rate limits. Cache metadata locally to avoid repeated calls:
      $metadata = Storage::disk('dropbox')->metadata('file.txt');
      cache()->put("dropbox:metadata:file.txt", $metadata, now()->addMinutes(5));
      
  3. Path Handling:

    • Dropbox paths are case-sensitive. Avoid mixed-case paths (e.g., Folder/FILE.txt vs. folder/file.txt).
    • Error: Path not found may occur if the case doesn’t match. Use strtolower() for consistency:
      $path = strtolower('Folder/FILE.txt');
      
  4. Large File Uploads:

    • Files > 150MB require chunked uploads. The adapter handles this automatically, but monitor memory usage:
      // For files > 500MB, use streaming:
      $stream = fopen('local-large-file.zip', 'r');
      Storage::disk('dropbox')->writeStream('remote-large-file.zip', $stream);
      fclose($stream);
      
  5. Webhook Delays:

    • Dropbox webhooks may take up to 10 minutes to trigger. Use exponential backoff in listeners:
      try {
          $response = Http::post('https://your-app.com/dropbox-webhook', $payload);
      } catch (\Throwable $e) {
          if ($attempts < 3) {
              sleep(2 ** $attempts);
              $attempts++;
              retry();
          }
      }
      

Debugging

  • 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

Extension Points

  1. 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()]
    );
    
  2. 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());
    });
    
  3. 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');
        });
    });
    
  4. Event Dispatching: Trigger Laravel events on file operations:

    Storage::disk('dropbox')->put('file.txt', 'content', function () {
        event(new DropboxFileUploaded('file.txt'));
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport