Weave 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

Dropbox Laravel Package

graham-campbell/dropbox

Laravel package that provides a Dropbox bridge for your applications, wrapping the official Dropbox SDK in a familiar, config-driven service provider so you can authenticate, upload, download, and manage files with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Pin the version, don't trust a range. The package is published under a GrahamDeprecated organisation with zero dependents and a Laravel 5.4-era compatibility matrix. Treat the constraint as a hard pin:

composer require "graham-campbell/dropbox:^3.4" --no-update
composer update graham-campbell/dropbox --with-dependencies

Run composer why-not graham-campbell/dropbox 3.4.* first — it immediately surfaces whether the package's illuminate/support range or its dropbox/dropbox-sdk-php pin conflicts with your lockfile. If it fails, stop: depend on the official SDK directly instead.

2. Register manually. Laravel 5.4 predates package auto-discovery, so both provider and alias belong in config/app.php:

'providers' => [
    GrahamCampbell\Dropbox\DropboxServiceProvider::class,
],

'aliases' => [
    'Dropbox' => GrahamCampbell\Dropbox\Facades\Dropbox::class,
],

3. Publish and read the config.

php artisan vendor:publish --provider="GrahamCampbell\Dropbox\DropboxServiceProvider"

If nothing publishes, try the older --tag=config variant used by several Graham Campbell packages of that era. Open config/dropbox.php before editing — it is the authoritative reference for this package. Expect a default connection key plus a connections array holding app key/secret and an OAuth token.

4. Prove the wire works in tinker, not in a job.

$meta = Dropbox::getMetadata('/');
dump($meta['contents'][0]['path']);

Dropbox::uploadFileFromString('/hello.txt', 'hello from laravel');
dump(Dropbox::createShareableLink('/hello.txt'));

One synchronous round trip confirms provider, config, token and SDK pin simultaneously. Everything after that is your code.

Where to look first: src/ in the package — the service provider and the manager class behind the facade, a few hundred lines, ten minutes of reading. Then the official dropbox/dropbox-sdk-php docs for method signatures; this package does not document them, it forwards them.

Implementation Patterns

Treat the facade as a pass-through, not an API. There is no package-specific method list. Dropbox::anything($args) forwards to the underlying SDK client, so getMetadata, uploadFile, uploadFileFromString, downloadFile, createFolder, delete, createShareableLink, getAccountInfo all carry the SDK's exact signatures and return shapes. When you need to know what a call returns, read the SDK, not the README.

Inject the manager, not the facade. The facade root is the package's manager class; resolving it from the container gives the same object without the static surface and keeps services unit-testable:

use GrahamCampbell\Dropbox\DropboxManager;

class ExportService
{
    public function __construct(private DropboxManager $dropbox) {}

    public function export(string $localPath): string
    {
        $remote = '/exports/'.basename($localPath);
        $this->dropbox->uploadFile($remote, $localPath);

        return $this->dropbox->createShareableLink($remote);
    }
}

Wrap it in your own interface on day one. Given the deprecation signal, a one-file seam is the highest-value pattern available:

interface DropboxClient
{
    public function upload(string $remotePath, string $localFile): void;
    public function shareLink(string $remotePath): string;
}

Bind this to an implementation delegating to the package today and the raw SDK tomorrow. Call sites never touch GrahamCampbell\Dropbox\* types, so the eventual removal is a container rebinding, not a refactor.

Use named connections for multi-tenant or multi-app tokens. The config supports several connections; select per call rather than mutating the default:

Dropbox::connection('archive')->uploadFile($path, $local);

Drive the default from env and never commit a token:

'default' => env('DROPBOX_CONNECTION', 'main'),
// ...
'token' => env('DROPBOX_TOKEN'),

Push transfers onto the queue. Every call is a synchronous HTTP round trip. Uploads and downloads belong in a job with retries and backoff, not in a request handler:

class UploadToDropbox implements ShouldQueue
{
    public $tries = 3;
    public $backoff = [10, 60, 300];

    public function __construct(public string $local, public string $remote) {}

    public function handle(DropboxClient $client): void
    {
        $client->upload($this->remote, $this->local);
    }
}

Test by swapping the binding, not by mocking HTTP. Because everything routes through your interface, feature tests bind a fake. If you must exercise the real path, keep one integration test against a dedicated Dropbox app folder with a scoped token, tagged @group integration and excluded from the default suite.

Gotchas and Tips

No auto-discovery means silent Class not found. On 5.4 the provider and alias are your responsibility. If Dropbox:: throws, check config/app.php before anything else — snippets written for 5.5+ omit this step entirely.

The facade is not type-hinted to the SDK client. Dropbox::getMetadata() resolves the manager's default connection at call time. Resolve the manager once per job or request and hold it; do not call the facade repeatedly inside a loop with a rotating token.

Exceptions arrive from the SDK untranslated. The bridge does not wrap errors in Laravel-flavoured exceptions. Catch the SDK's own hierarchy distinctly — network/timeout vs. bad request vs. auth — and let Laravel's Handler do the rest. A blanket catch (\Exception) will hide token-expiry bugs for weeks.

Rate limits are your problem. Dropbox returns 429s under load and the SDK does not retry for you. Add exponential backoff on the job, and never fan out uploads in a tight foreach — use Bus::batch with bounded concurrency, or you will lose the tail of the batch.

Path semantics bite. Dropbox paths are case-insensitive and rooted at /, and conventions differ between SDK generations on whether a leading slash is required or whether a path/ID format is expected. Pick one convention inside your wrapper and normalise there so the rest of the app never thinks about it.

Large files. uploadFileFromString loads the entire payload into memory. For anything beyond a few MB use the SDK's chunked upload session — still reachable through the facade, but consult the SDK docs for the exact method names on your pinned version. Never stream multi-GB files through a web request.

Audit the pinned SDK for security staleness. composer show dropbox/dropbox-sdk-php — a resolved pin with known CVEs and no upstream fix is a stronger reason to exit than the deprecation notice alone.

Extension point: the manager supports extend(), so you can register a custom connection resolver without forking:

Dropbox::extend('scoped', fn () => new \Dropbox\Client(config('services.dropbox.scoped_token')));

Use this only if you are already committed short-term. Do not fork or vendor the package to patch it — you would be maintaining a wrapper around an SDK you could simply depend on.

Exit checklist, written on day one: pin the exact version in composer.json, log the dependency with a named owner and removal date, keep one integration test around your wrapper so a silent SDK/API change surfaces in CI, and re-run composer why-not before every framework or PHP bump. The replacement — the official SDK bound in a short service provider behind your DropboxClient interface — is measured in days. Budget it before the next major upgrade forces it.

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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource