Giter Site home page Giter Site logo

spatie / dropbox-api Goto Github PK

View Code? Open in Web Editor NEW
283.0 9.0 76.0 245 KB

A minimal implementation of Dropbox API v2

Home Page: https://freek.dev/734-dropbox-will-turn-off-v1-of-their-api-soon-its-time-to-update-your-php-application

License: MIT License

PHP 100.00%
dropbox api php

dropbox-api's Introduction

A minimal implementation of Dropbox API v2

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

This is a minimal PHP implementation of the Dropbox API v2. It contains only the methods needed for our flysystem-dropbox adapter. We are open however to PRs that add extra methods to the client.

Here are a few examples on how you can use the package:

$client = new Spatie\Dropbox\Client($authorizationToken);

//create a folder
$client->createFolder($path);

//list a folder
$client->listFolder($path);

//get a temporary link
$client->getTemporaryLink($path);

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Installation

You can install the package via composer:

composer require spatie/dropbox-api

Usage

The first thing you need to do is get an authorization token at Dropbox. Unlike other companies Dropbox has made this very easy. You can just generate a token in the App Console for any Dropbox API app. You'll find more info at the Dropbox Developer Blog.

With an authorization token you can instantiate a Spatie\Dropbox\Client.

$client = new Spatie\Dropbox\Client($authorizationToken);

or alternatively you can implement Spatie\Dropbox\TokenProvider which will provide the access-token from its TokenProvider->getToken(): string method.

If you use oauth2 to authenticate and to acquire refresh-tokens and access-tokens, (like thephpleague/oauth2-client), you can create an adapter that internally takes care of token-expiration and refreshing tokens, and at runtime will supply the access-token via the TokenProvider->getToken(): string method.

(Dropbox announced they will be moving to short-lived access_tokens mid 2021).

// implements Spatie\Dropbox\TokenProvider
$tokenProvider = new AutoRefreshingDropBoxTokenService($refreshToken);
$client = new Spatie\Dropbox\Client($tokenProvider);

or alternatively you can authenticate as an App using your App Key & Secret.

$client = new Spatie\Dropbox\Client([$appKey, $appSecret]);

If you only need to access the public endpoints you can instantiate Spatie\Dropbox\Client without any arguments.

$client = new Spatie\Dropbox\Client();

Dropbox Endpoints

Look in the source code of Spatie\Dropbox\Client to discover the methods you can use.

Here's an example:

$content = 'hello, world';
$client->upload('/dropboxpath/filename.txt', $content, $mode='add');

$from = '/dropboxpath/somefile.txt';
$to = '/dropboxpath/archive/somefile.txt';
$client->move($from, $to);

If the destination filename already exists, dropbox will throw an Exception with 'to/conflict/file/..'

The upload() and move() methods have an optional extra 'autorename' argument to try and let dropbox automatically rename the file if there is such a conflict.

Here's an example:

$from = '/dropboxpath/somefile.txt';
$to = '/dropboxpath/archive/somefile.txt';
$client->move($from, $to, $autorename=true);
// with autorename results in 'somefile (1).txt'

If you do not find your favorite method, you can directly use the contentEndpointRequest and rpcEndpointRequest functions.

public function contentEndpointRequest(string $endpoint, array $arguments, $body): ResponseInterface

public function rpcEndpointRequest(string $endpoint, array $parameters): array

Here's an example:

$client->rpcEndpointRequest('search', ['path' => '', 'query' => 'bat cave']);

If you need to change the subdomain of the endpoint URL used in the API request, you can prefix the endpoint path with subdomain::.

Here's an example:

$client->rpcEndpointRequest('content::files/get_thumbnail_batch', $parameters);

Changelog

Please see CHANGELOG for more information what has changed recently.

Testing

composer test

Contributing

Please see CONTRIBUTING for details.

You can run composer pint to run the code style fixer, and composer phpstan to run the static analysis.

Security

If you've found a bug regarding security please mail [email protected] instead of using the issue tracker.

Postcardware

You're free to use this package (it's MIT-licensed), but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.

Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.

We publish all received postcards on our company website.

Credits

License

The MIT License (MIT). Please see License File for more information.

dropbox-api's People

Contributors

adrianmrn avatar akoepcke avatar alex-d avatar alexvanderbist avatar cklingsporn avatar dependabot[bot] avatar doekenorg avatar eusonlito avatar freekmurze avatar gdmac avatar github-actions[bot] avatar grahamcampbell avatar hajrovica avatar iget-esoares avatar iget-master avatar ilamp avatar ilfalco1992 avatar iwader avatar jmsche avatar joaopatrocinio avatar masbug avatar mohammedalkutrani avatar mozammil avatar mynameisbogdan avatar nielsvanpach avatar patinthehat avatar pryley avatar rstefanic avatar sebastiandedeyne avatar srmklive avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dropbox-api's Issues

.jpg files are supported but something went wrong

I'm trying to upload some files but having this issue.
.jpg files are supported but something went wrong

My code:

      $client = new Client(env('DROPBOX_TOKEN'));

      $name=$_FILES['uploadvideo']['name'];
      $type=$_FILES['uploadvideo']['type'];
      $cname=str_replace(" ","_",$name);
      $tmp_name=$_FILES['uploadvideo']['tmp_name'];
      $targetPath = 'justshoot/' . $cname;

      $upload = $client->upload($targetPath, $tmp_name);

The file hits dropbox in the desired destination, I can view the file but then get the error. What am I doing wrong here?

PHP 7.1 support?

When I do composer require spatie/dropbox-api in my project, I get the following error:

Using version ^1.6 for spatie/dropbox-api
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - This package requires php ~7.0.0 but your PHP version (7.1.8) does not satisfy that requirement.


Installation failed, reverting ./composer.json to its original content.

createSharedLinkWithSettings endpoint

Hi there!

Just letting you know that the "createSharedLinkWithSettings" throws an exception when used without the "settings" parameter, like the following:

$sharedLink = $dropbox->createSharedLinkWithSettings( $path );

The exception message from Dropbox:

Client error: POST https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings resulted in a 400 Bad Request response: Error in call to API function "sharing/create_shared_link_with_settings": request body: settings: expected object, got l (truncated...)

If I add the second, $settings parameter (even though it's optional based on your docs) no exceptions are thrown:

$settings = array( 'requested_visibility' => 'public' );
$sharedLink = $dropbox->createSharedLinkWithSettings( $path, $settings );

So the thing is that you default the $settings argument (if none is provided) to an empty array in the method declaration:

public function createSharedLinkWithSettings(string $path, array $settings = [])

And then use that empty array in the API call parameters:

$parameters = [
            'path' => $this->normalizePath($path),
            'settings' => $settings,
        ];

So you're actually sending an empty parameter value (instead of not setting it at all).

Just thought I'd report this. Thanks!

preparing for short-lived auth tokens

In preparation for dropbox moving to short-lived tokens (mid 2021),
i'ld like to open this issue to keep track of steps i did to with league/oath2-client.
composer require league/oauth2-client and stevenmaguire/oauth2-dropbox

use Stevenmaguire\OAuth2\Client\Provider\Dropbox;

$authClient = new Dropbox([
    'clientId' => APP_KEY,
    'clientSecret' => APP_SECRET,
    // 'redirectUri'       => '' // no redirect, we want a long lasting offline token
]);

// 1. Setup, one time refresh_token fetch. 
// Open URL in browser, user gives permission, dropbox gives connection code
// https://www.dropbox.com/oauth2/authorize?client_id=[APP_KEY]&response_type=code&token_access_type=offline
echo $authClient->getAuthorizationUrl([
    'token_access_type' => 'offline'
]);

// With the obtained code, fetch an access_token and a long-lasting refresh_token
$token = $authClient->getAccessToken('authorization_code', ['code' => $userCode]);

// 2. Normal use.
// Get token from your tokenStorage, if token->hasExpired() 
// then fetch new token with help from refresh_token (see league oauth2Client page)

// use Spatie dropbox with the access_token and the prepared guzzleClient
$dropbox = new Spatie\Dropbox\Client($token->getToken(), $authClient->getHttpClient());
$dir = $dropbox->listFolder("/Apps/");

print_r($dir);

An invalid access token does NOT throw an exception message

If you specify an invalid access token an exception IS thrown, but it does NOT contain an error message.

....
catch (Exception $e) {
  //this is an empty string
  echo $e->getMessage();
}

If you echo just the exception object the following stack trace is shown:

Spatie\Dropbox\Exceptions\BadRequest in /var/www/html/dropbox-sdk/vendor/spatie/dropbox-api/src/Client.php:657
Stack trace:
#0 /var/www/html/dropbox-sdk/vendor/spatie/dropbox-api/src/Client.php(629): Spatie\Dropbox\Client->determineException(Object(GuzzleHttp\Exception\ClientException))
#1 /var/www/html/dropbox-sdk/vendor/spatie/dropbox-api/src/Client.php(402): Spatie\Dropbox\Client->contentEndpointRequest('files/upload', Array, Resource id #19)
#2 /var/www/html/dev/dbox-test.php(17): Spatie\Dropbox\Client->upload('/testFolder/tes...', Resource id #19, 'add')

Clearly, this does not handle the exception all the way through.

Invalid access tokens can be a common occurrence.

Any idea why this behaves this way and what could be done?

Parse error

Somehow when I try to upload a file from the root of the server I get this error. But it works fine if I upload from web root.
Parse error: syntax error, unexpected '*', expecting ',' or ';' in /home/user4/cron/dropboxv2/vendor/spatie/dropbox-api/src/Client.php on line 23

BadRequest: body may contain a non json response

Reproduce

Use bad credentials <APP_KEY>:<APP_SECRET>

Current Exception

PHP Fatal error:  Uncaught Spatie\Dropbox\Exceptions\BadRequest in test-dropbox-api/vendor/spatie/dropbox-api/src/Client.php:685
Stack trace:
<Truncated>

Expected

PHP Fatal error:  Uncaught Spatie\Dropbox\Exceptions\BadRequest: Error in call to API function "files/upload": Invalid authorization value in HTTP header "Authorization": "Basic <base64-truncated>".  Expecting "Bearer <oauth2-access-token>". in test-dropbox-api/vendor/spatie/dropbox-api/src/Client.php:685
Stack trace:
<Truncated>

listFolder don't works with camelcase folders

Related to spatie/flysystem-dropbox#9

Dropbox API v1 and v2 are both case-insensitive: https://www.dropboxforum.com/t5/API-support/Case-Sensitivity-in-API-2/m-p/191279#M8337

If I try to fetch "Test1/Test2/toto.txt" that returns nothing, because Dropbox returns "test1/Test2/toto.txt" and does not match.

I think the bug is from this package, not from the Flysystem adapter.

I think it could be fixed in normalizePath method by moving path to lowercase from all parts exept the last and filename.

I continue to search!

Thanks :)

Unable to request 'files/get_thumbnail_batch'

$response = $client->rpcEndpointRequest('files/get_thumbnail_batch', $arguments);

Dropbox returns an error stating that the content endpoint must be used.

$response = $client->contentEndpointRequest('files/get_thumbnail_batch', $arguments);

Dropbox returns an unknown header error due to Dropbox-API-Arg.

This particular endpoint in the documentation states that it is an RPC endpoint, however it requires the content api. Unfortunately there is no way to make this request with this client right now.

Uploading a pdf

Hi guys,

Great work here, but i am having a small issue.

I want to upload a pdf file and i have tried the following with failure (Badrequest is thrown).

$upload = $client->upload($newFilename, file_get_contents($documentFile->getPathname()));
$upload = $client->upload($newFilename, addslashes(file_get_contents($documentFile->getPathname())));

How would i go about uploading a small pdf file?

How to use a proxy?

How can I use a proxy(like GuzzleHttp)? Cause Dropbox can't be access in China.

Development Release

Hi @freekmurze, Do you think we can setup a development release for the project. I would like to commit a few changes for Team namespaces and it'll help in testing it.

Using in conjunction with laravel-backup and flysystem-dropbox

Hi,

Thanks for releasing these great packages.

I have been able to use laravel-backup and flysystem-dropbox in order to backup my app database to a private Dropbox folder.

Dropbox also has a Business API that allows you to act as a team member with file access. I am interested in using this as it will allow me to backup the DB to my organization's shared business Dropbox folder.

There is more information from Dropbox here: https://www.dropbox.com/developers-v1/business#member-file-access

Specifically:

Member file access

Make calls to the Dropbox Core API for any member of the Dropbox Business team. Your app must have Team member file access permission.

To make calls on a member's behalf, use the OAuth token granted to the app by the team. Specify the member_id of the user that the app wants to act on using a custom HTTP header called X-Dropbox-Perform-As-Team-Member.

I am wondering if it is possible to use the API package with your laravel-backup and flysystem-Dropbox in order to post files to a shared business folder?

Thank you again!
Cory

Implement oauth2

Should Oauth2 functionality be implemented on this library?

If so, I suggest implementing it from [stevenmaguire/oauth2-dropbox](https://github.com/stevenmaguire/oauth2-dropbox], that I've just made a PR to make it compatible with Dropbox API v2.

If you agree, I can do a PR to implement it when/if @stevenmaguire merge my PR.

Edit: oauth2-dropbox is now compatible with v2.

How do I know if a folder exists?

I'm going to upload my files to folders like this:

/2019/11/06
/2019/11/07
/2019/11/08

How do I know if a folder exists? Cause I don't need to create if it is exists (it will return an 409 http error if I create the folder that already exists.)

List directory recursively not working

I have this folder structure

CMI/tool/video tool/tested/au/

Inside this folder I have 2 more with a couple of videos

2017-06/video1.mp4
2017-08/video2.mp4

When I run $this->client->listFolder($path, true); I only get until au, but neither subfolders nor videos.

Any tip will be appreciated. Thanks

Dropbox-API-Path-Root

Is it possible with this package to set the Dropbox-API-Path-Root header? You need this to access Team Shared folders. You add a header to your request with the correct namespace_id, example;

['Dropbox-API-Path-Root' => '{".tag": "namespace_id", "namespace_id": "1234"}' ];

Can't seem to find a method for this.

Bad Request 400 if using App Key and App Secret

I'm converting some existing code to use your package because the old package locked us into Guzzle 6.x. So I already have an app key, app secret, and non-expiring access token.

According to your documentation, it looks like I should be able to supply the app key and app secret in an array to the constructor of Client, or I can provide the access token as a string. The access token as a string works to connect, but with the array of app key and app secret I get a Bad Request 400 error. My test code shown below:

public function testDropboxConnection()
{
	require WILDFISH_CONFIGS_DIR . '.dropbox.php';    
	$dropboxConfig = getWassDropboxConfig('production');    
	try{
		$client = new \Spatie\Dropbox\Client( $dropboxConfig['accessToken'] );

		// For some reason this doesn't work...
		/*$client = new \Spatie\Dropbox\Client([
			$dropboxConfig['appKey'], 
			$dropboxConfig['appSecret']
		]);*/    
		dump( $client->getAccountInfo() );
	}
	catch( \Spatie\Dropbox\Exceptions\BadRequest $e )
	{
		if( ENVIRONMENT == 'development' && TRUE )
			dump( $e );
	}
	catch( \Exception $e )
	{
		if( ENVIRONMENT == 'development' && TRUE )
			dump( $e );
	}
}

Since I have it working with the access token, it's not critical for me that you fix this, but it did waste some of my time, so I thought I'd leave this here so you can take a look.

Error: Trying to access array offset on value of type bool - PHP 7.4

When trying to send a file to dropbox using a URL stream, the following error is returned:

Trying to access array offset on value of type bool

This error happens at the following location:

Client.php:343

    protected function shouldUploadChunked($contents): bool
    {
        $size = is_string($contents) ? strlen($contents) : fstat($contents)['size'];       
       if ($this->isPipe($contents)) {
            return true;
        }

        if ($size === null) {
            return true;
        }

        return $size > $this->maxChunkSize;
    }

The issue is caused when $contents is a resource stream as fstat returns false.

This results in ['size'] being accessed on a bool value.

Any accesses to fstat($contents) needs safety checking.

Bug introduced by @masbug refactoring

Hi,

We are experiencing an issue with uploading files from a popen stream.

The issue was introduced after this commit 4ac2101.

The changes were welcome since it reduces memory usage peaks, but the problem is that for some reason, it don't read streams originated from popen(). Tracking the bug, I stopped on this line:

$response = $this->client->post("https://content.dropboxapi.com/2/{$endpoint}", [

For some reason GuzzleHttp client don't read this kind of streams (not seekable and not buffered), there are a few issues on this (see guzzle/guzzle#1654 for example).

That was the reason that I made it loading chunks to memory instead of streaming it to Guzzle.

Our backup routines are broken due this changes. When I made this piece of code, I've researched a lot about this guzzle issue, and didn't found any workaround.

So I whould appreciate if @masbug can help us to find a great solution to this problem.

Bad Request

Hello

we are getting Spatie\Dropbox\Exceptions\BadRequest issue while uploading file into dropbox.

We are using latest version of package and 7.4 PHP version.

Upload an incomplete file

I'm trying to upload a 73Kb zip file (that contains a SQL dump of a DB), the process completes successfully but the file in dropbox is only 103b and obviously corrupted.

// Client instance
$client = new Client($this->dropBoxToken);
// Upload
$client->upload($target, $source);

Any idea?

Error invalid_account_type when using app_key and app_secret

Hello,

we're using dropbox-api without problem with a generated token but if we try to validate with app_key and app_secret of the same application we get the following error: Error 403 and invalid_account_type.

Is there any known issue about that?

Thanks in advance.

Exception handling

How to handle exceptions?? simple try catch is not working.

UPDATED:

I am working and laravel so catching (Exception $e) will still throw and error.

catching (Throwable $e) worked for me

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.