For the implementation of one project, it became necessary to use any cloud storage. The bottom line is that there are several distributed employees, each of whom uses a special program, the result of which are separate XML files. The data of these files are necessary in order to generate reports on the site, where users could download the information available to them. The problem is that employees work on their local machines and do not interact with the Internet (that is, they do not use a single server or something like that). And so I decided to use Dropbox, I’ll set up each user with their own daddy, where their files will be synchronized, and on the site side I’ll take everything from the dropbox and use it for reporting. Under the cut will tell what came out of it.
In general, I initially thought that everything would be much simpler, since I had come across a
ready-made component for quite a long time, which installs a file source in MODX that interacts with Dropbox, but when I installed it, I received only a bunch of fatal errors. The component was developed in the 2012th year, and either used the old Dropbox PHP SDK, or there was something samopisny in general, but in any case it did not work at all. As a result, it was clear that everything will have to be rewritten. I did not find any special examples on the net, but I am pleased with the dropbox with quite good documentation
here and
here . As a result, I took the file source object in the package as a basis, uploaded the latest version of the PHP SDK (now it is 1.1.4) and finished it up to the state when you could manage the files in the dropbox through the admin panel of the site.

')
This completes the development of the package dropbox-2.0.0-beta. But the thought did not give me peace of mind that I still do not have the opportunity to receive changes from the dropbox. As far as I understand, I’ll have to deal with tens of thousands of documents in the end, and I can't just go through folders every time and check revisions on the site side (by the way, the Dropbox method
Client :: getMetadataWithChildren ($ path ) returns no more than 2000 entries, although 25000 are specified in the method. Picked up the docks, got to the
Client :: getDelta method ($ cursor = null, $ pathPrefix = null) . This is just what we need, since by passing the famous cursor into it, you can get information about the changes since its creation. But here's a little nuisance: how to get the last cursor? The fact is that if a dropbox account has been around for a long time, a whole bunch of changes can accumulate in it over the entire history, and by simply going through the cursors you can get to the current for a very long time. Interestingly, there is no such method in the PHP SDK, although
there is a method for this in the API itself. Well, okay, if there is a method in the kernel, then you don’t have to
finish your client class for a long time in order to get this information. Now you can fix a starting point for yourself and follow the changes without any sort of search. When I received all this, it became obvious to me that it would have been convenient to store this data in a database, and to put some specialized dropbox client methods into specific entities. Then just show a few examples of the use of what happened.
Register API applications.
Of course, before you do something, you need to register your Dropbox application (of course, you must be registered with
Dropbox ).
In detailTo do this, go to the
www.dropbox.com/developers/apps page and click the
Create app (By the way, the application name should be unique for the entire Dropbox (since it is possible to publish public applications, so it’s better to indicate the site’s domain or something like that for names like myApp, etc. are busy and will not save dropbox)). The types of applications created are two
Drop-ins app and
Dropbox API app , we will create the second one.

Here we will immediately take a closer look at step 3.
Can your app be limited to its own folder?If you select “My app only needs access to files it creates.”, Then the application will create its own folder, where the application will have access. I have a folder Applications / [AppName]. That is, the Applications folder is a system folder for all applications, and then for each application a folder is created.
And if you select “My app needs access to files already on Dropbox.”, The application will get access to the root folder and then the list of available files will be limited to only selected file types. That is, if you select this item, a new step appears.
What type of files does your app need to access? and there you can select either “All file types” (i.e. all files) or “Specific file types” and specify which file types are available.

After we clicked “Create App”, the application will be created and the application settings page will open. On it, among other things, we will find the
App key and the
App secret , but we will not need them yet, we will consider their use later. In the meantime, we are interested in
Access token . Generate it and copy it somewhere in an inaccessible place. You will not be able to see it again. True, you can generate a new token, and what's interesting is that the previous ones will work. I generated three tokens and they all work, and I cannot see the list of tokens used and cancel unnecessary ones, I can only delete the entire application. Katz is not a bit of a secret, but this is more of a feature than a bug.

Setting up the file source
After installing
Dropbox , a new type of file source appears in the system - Dropbox. Create a media resource with this type.
If everything is OK, then after saving the source of the files should show the contents of your dropbox (see the first picture above).
Dropbox client
The first thing I did in the updated version of the package was the ability to get the Dropbox client into a separate media resource method. You can get it, for example, like this:
$source_id = 27;
This is convenient in that you can have any number of media resources and bother with their settings, while each media resource will work with its dropbox folder.
Get information about the contents of directories
$source_id = 27;
Result Array ( [hash] => cfcf0b65c94cff03c32390b3c30a5812 [thumb_exists] => [bytes] => 0 [path] => / [is_dir] => 1 [icon] => folder [root] => dropbox [contents] => Array ( [0] => Array ( [rev] => 115ce031c0d71 [thumb_exists] => 1 [path] => /315a73ec24 - .jpg [is_dir] => [client_mtime] => Fri, 05 Dec 2014 23:12:30 +0000 [icon] => page_white_picture [bytes] => 258713 [modified] => Mon, 08 Dec 2014 02:45:31 +0000 [size] => 252.6 KB [root] => dropbox [mime_type] => image/jpeg [revision] => 71118 ) [1] => Array ( [rev] => 102d6031c0d71 [thumb_exists] => 1 [path] => /315a73ec24.jpg [is_dir] => [client_mtime] => Fri, 05 Dec 2014 23:12:30 +0000 [icon] => page_white_picture [bytes] => 258713 [modified] => Sat, 06 Dec 2014 21:21:20 +0000 [size] => 252.6 KB [root] => dropbox [mime_type] => image/jpeg [revision] => 66262 ) ) [size] => 0 bytes )
We get the contents of the file
$source_id = 27;
Or so (if the record is already in the database) $entry = $modx->getObject('DropboxEntry', array( "path" => '/315a73ec24.jpg', )); $content = $entry->getContent();
We track changes in sections
Here two stages are necessary:
1. Get the current cursor for the section and save it to the databaseIn general, it is not necessary to preserve it, but it is more convenient, because it will not disappear anywhere.
$source_id = 27;
2. We request changes. $cursor= $modx->getObject('DropboxCursor', array( "path" => '/', )); $result = $entry->getDelta(); print_r($result);
Answer Array ( [has_more] => [cursor] => AAE3sefSDffe3SiOcfkaMd7vyzjQvjxngkI1gkJGLvBQplsNUhF9tx5Okb7epnGufIziuDWjyG16sWaxjRcnt-XjT-jBD_8fDW89enF7OO3AHBjsZz9vHTBJenmeCdLUgO0f-EqRJYigzELD0rzD3hFNn-YGfDQaxUOs0bHd2F5qND3J6HX-HwOqOLWQfcbuMZMNHN1_UGN2VODIbaPzBbML0rap_B6ibV03JQxtiGHZtxwjP-mSw8drigK3yJtvqyR3XdzHP5uVsyrD8gkyGk1J9dOTLdzFRA-woImCg1Iwc9XA7l1XsZGCRvDYpXjg [entries] => Array ( ) [reset] => )
-jBD_8fDW89enF7OO3AHBjsZz9vHTBJenmeCdLUgO0f-EqRJYigzELD0rzD3hFNn-YGfDQaxUOs0bHd2F5qND3J6HX-HwOqOLWQfcbuMZMNHN1_UGN2VODIbaPzBbML0rap_B6ibV03JQxtiGHZtxwjP-mSw8drigK3yJtvqyR3XdzHP5uVsyrD8gkyGk1J9dOTLdzFRA-woImCg1Iwc9XA7l1XsZGCRvDYpXjg Array ( [has_more] => [cursor] => AAE3sefSDffe3SiOcfkaMd7vyzjQvjxngkI1gkJGLvBQplsNUhF9tx5Okb7epnGufIziuDWjyG16sWaxjRcnt-XjT-jBD_8fDW89enF7OO3AHBjsZz9vHTBJenmeCdLUgO0f-EqRJYigzELD0rzD3hFNn-YGfDQaxUOs0bHd2F5qND3J6HX-HwOqOLWQfcbuMZMNHN1_UGN2VODIbaPzBbML0rap_B6ibV03JQxtiGHZtxwjP-mSw8drigK3yJtvqyR3XdzHP5uVsyrD8gkyGk1J9dOTLdzFRA-woImCg1Iwc9XA7l1XsZGCRvDYpXjg [entries] => Array ( ) [reset] => )
If there are changes, you will see them in the
entries array.
File Revisions
$entry = $modx->getObject('DropboxEntry', array( "path" => '/315a73ec24.jpg', )); $result = $entry->getRevisions();
And you can restore the desired version of the file. $entry = $modx->getObject('DropboxEntry', array( "path" => '/315a73ec24.jpg', )); $result = $entry->restoreFile('102d6031c0d71');
In general, if you dig the official documentation, you can do a lot of things based on this. In general, there is a desire to develop under MODX a component of a file manager that could exchange files between different types of media resources, but so far there is no time / resources for this.
You can download the package from the modx.com
repository.Github Project:
github.com/Fi1osof/modx-DropboxAnd finally, a
small note about one insidious problem, which was encountered during the development of the component.
UPD: In the process, it turned out a couple of moments:
1. Dropbox PHP SDK requires PHP 5.3 minimum
2. It seems to require a 64-bit axis. The discussion is
here .