0

I am trying to create a page that will display the contents of a dropbox folder, in a presentable sandbox fashion, and allow the browsing user (who is logged into a website I have been developing) to be able to click and download the various files within the folders. Here is the code I'm using: This is the file bootstrap.php...

    <?php
// Prevent calling this script directly
if ($_SERVER["SCRIPT_FILENAME"] == __FILE__) {
    exit("Access denied!");
}

// app settings
$config = array();
$config["dropbox"]["app_key"] = "***";
$config["dropbox"]["app_secret"] = "***";
// ACCESS_TYPE should be "dropbox" or "app_folder"
$config["dropbox"]["access_type"] = "dropbox";

$config["app"]["root"] = ((!empty($_SERVER["HTTPS"])) ? "https" : "http") . "://" . $_SERVER["HTTP_HOST"] . "/";
$config["app"]["datadir"] = dirname(__FILE__) . "/data";
$config["app"]["authfile"] = $config["app"]["datadir"] . "/auth.php";

// turn on error reporting for development
error_reporting(E_ALL|E_STRICT);
ini_set("display_errors", true);

// environment check
if (!is_dir($config["app"]["datadir"]) || !is_writable($config["app"]["datadir"])) {
    exit("The data directory is not writeable!");
}
if (file_exists($config["app"]["authfile"]) && !is_writable($config["app"]["authfile"])) {
    exit("The auth storage file is not writeable!");
}

// Load libraries and start a new session
require_once "lib/dropbox/rest.php";
require_once "lib/dropbox/session.php";
require_once "lib/dropbox/client.php";

if(!isset($_SESSION)){session_start();}

// Search for a previously obtained access token
$access_token = null;
if (file_exists($config["app"]["authfile"])) {
    include_once $config["app"]["authfile"];
}

This is the file authorize.php...

<?php
require_once "bootstrap.php";

if (isset($access_token)) {
    header("Location: ./");
    exit;
}

try {
    // Start a new Dropbox session
    $session = new DropboxSession(
        $config["dropbox"]["app_key"],
        $config["dropbox"]["app_secret"],
        $config["dropbox"]["access_type"]
    );

    // The user is redirected here by Dropbox after the authorization screen
    if (!empty($_GET["oauth_token"]) && !empty($_GET["uid"])) {
        $uid = $_GET["uid"];
        $token = array(
            "oauth_token" => $_GET["oauth_token"],
            "oauth_token_secret" => ""
        );

        if (!empty($_SESSION["request_token"])) {
            $token["oauth_token_secret"] = $_SESSION["request_token"]["oauth_token_secret"];
        }

        /**
         * The access token is all you'll need for all future API requests on
         * behalf of this user, so you should store it away for safe-keeping 
         * (even though we don't for this article). By storing the access
         * token, you won't need to go through the authorization process again
         * unless the user revokes access via the Dropbox website.
         */
        if ($access_token = $session->obtainAccessToken($token)) {
            parse_str($access_token, $token);
            $access_token = $token;
            unset($token);

            // The output ov var_export is similar to:
            // array("oauth_token_secret" => "aaaa", "oauth_token" => "bbbb", "uid" => "123456")
            $data = '<?php $access_token = ' . var_export($access_token, true) . ";";
            if (file_put_contents($config["app"]["authfile"], $data) === false) {
                throw new Exception("Unable save access token");
            }

            // Authorized, redirect to index
            //header("Location: index_inside.php");
            echo "Authorized, <a href=\"list.php\">click here</a> to redirect!";
            exit;
        }
        // The access token should be stored somewhere to be reused until
        // it expires or is revoked by the user
    }
    else {
        // We must start a new authorization cycle
        if ($request_token = $session->obtainRequestToken()) {
            // The request token must be subdivided in the two components 
            // oauth_token_secret and oauth_token and kept in the session
            // because is needed in the next step
            parse_str($request_token, $token);
            $_SESSION["request_token"] = $token;

            $url = $session->buildAuthorizeURL(
                $token, 
                $config["app"]["root"] . basename($_SERVER["SCRIPT_NAME"]),
                "en-US");

            // Display or redirect to auth URL
            echo '<p>Please visit <a href="' . $url . '">Dropbox</a> and authorize this application.</p>';
            exit;
        }
        else {
            throw new Exception("Unable to get request token");
        }
    }
}
catch (Exception $e) {
    echo $e->getMessage();
}

This is the file list_inside.php...which is what is eventually included to present the list of folders (and ideally files with download links)...

<?php
require_once "bootstrap.php";

if (!isset($access_token)) {
    header("Location: authorize.php");
    exit;
}

try {
    // Start a new Dropbox session
    // The access token should be defined
    // The session should verify if the token is valid and throw an exception
    $session = new DropboxSession(
        $config["dropbox"]["app_key"], 
        $config["dropbox"]["app_secret"], 
        $config["dropbox"]["access_type"], 
        $access_token
    );
    $client = new DropboxClient($session);

    $path = (!empty($_GET["path"])) ? $_GET["path"] : "/Apps/Tools/";

    // List contents of home directory
    if ($home = $client->metadata($path)) {
        echo "<p>Metadata content for <code>" . $path . "</code></p>";
        echo "<pre>" . print_r($home, true) . "</pre>";
    }
}
catch (Exception $e) {
    echo "<strong>ERROR (" . $e->getCode() . ")</strong>: " . $e->getMessage();
    if ($e->getCode() == 401) {
        // Remove auth file
        unlink($config["app"]["authfile"]);
        // Re auth
        echo '<p><a href="authorize.php">Click Here to re-authenticate</a></p>';
    }
}

Here is the output on the above code using metadata() :

Metadata content for /Apps/Tools/ Array ( [hash] => fa7f3577894553ffeb70ac0d96e49b99 [revision] => 71425 [rev] => 1170104ef29f8 [thumb_exists] => [bytes] => 0 [modified] => Tue, 14 Jan 2014 03:10:05 +0000 [path] => /Apps/Tools [is_dir] => 1 [icon] => folder [root] => dropbox [contents] => Array ( [0] => Array ( [revision] => 71426 [rev] => 1170204ef29f8 [thumb_exists] => [bytes] => 0 [modified] => Tue, 14 Jan 2014 03:10:05 +0000 [path] => /Apps/Tools/Burnside Road Dry Creek Valley Cabernet Sauvignon [is_dir] => 1 [icon] => folder [root] => dropbox [size] => 0 bytes )

        [1] => Array
            (
                [revision] => 71436
                [rev] => 1170c04ef29f8
                [thumb_exists] => 
                [bytes] => 0
                [modified] => Tue, 14 Jan 2014 03:10:05 +0000
                [path] => /Apps/Tools/Burnside Road Dry Creek Valley Sauvignon Blanc
                [is_dir] => 1
                [icon] => folder
                [root] => dropbox
                [size] => 0 bytes
            )

        [2] => Array
            (
                [revision] => 71445
                [rev] => 1171504ef29f8
                [thumb_exists] => 
                [bytes] => 0
                [modified] => Tue, 14 Jan 2014 03:10:05 +0000
                [path] => /Apps/Tools/Burnside Road Mendocino County Zinfandel
                [is_dir] => 1
                [icon] => folder
                [root] => dropbox
                [size] => 0 bytes
            )

        [3] => Array
            (
                [revision] => 71454
                [rev] => 1171e04ef29f8
                [thumb_exists] => 
                [bytes] => 0
                [modified] => Tue, 14 Jan 2014 03:10:05 +0000
                [path] => /Apps/Tools/Burnside Road Pinot Noir California
                [is_dir] => 1
                [icon] => folder
                [root] => dropbox
                [size] => 0 bytes
            )



    )

[size] => 0 bytes )

I apologize for the choppy code, I am not extremely skilled at this, however, my friend needs help with the site, and I jumped in to help get dropbox working.

The problem is...It displays an array of information about the folders, but no files are visible with links for downloading.

Added info..here is another page code i try: (i list output for this directly below the php)

<?php
require_once "bootstrap.php";

if (!isset($access_token)) {
    header("Location: authorize.php");
    exit;
}

try {
    // Start a new Dropbox session
    // The access token should exist
    // The session should verify if the token is valid and throw an exception
    $session = new DropboxSession(
        $config["dropbox"]["app_key"], 
        $config["dropbox"]["app_secret"], 
        $config["dropbox"]["access_type"], 
        $access_token
    );

    $client = new DropboxClient($session);
    $path = (!empty($_GET["path"])) ? $_GET["path"] : "/webs.pdf";
    $dest = $config["app"]["datadir"] . "/" . basename($path);

    // Download a file
    if ($file = $client->getFile($path, $dest)) {

        if (!empty($dest)) {
            unset($file["data"]);
            echo "<p>File saved to: <code>" . $dest . "</code></p>";
            echo "<pre>" . print_r($file, true) . "</pre>";
        }
        else {
            header("Content-type: " . $file["mime"]);
            echo $file["data"];
            exit;
        }
    }
}
catch (Exception $e) {
    echo "<strong>ERROR (" . $e->getCode() . ")</strong>: " . $e->getMessage();
    if ($e->getCode() == 401) {
        // Remove auth file
        unlink($config["app"]["authfile"]);
        // Re auth
        echo '<p><a href="authorize.php">Click Here to re-authenticate</a></p>';
    }
}

Here is the output for the above code:

File saved to: /home/thisisyo/public_html/data/webs.pdf Array ( [name] => /home/thisisyo/public_html/data/webs.pdf [mime] => application/pdf [meta] => stdClass Object ( [revision] => 35075 [rev] => 890304ef29f8 [thumb_exists] => [bytes] => 703289 [modified] => Thu, 20 Jun 2013 23:39:10 +0000 [client_mtime] => Wed, 20 Feb 2013 19:19:42 +0000 [path] => /webs.pdf [is_dir] => [icon] => page_white_acrobat [root] => dropbox [mime_type] => application/pdf [size] => 686.8 KB )

)

Also, here is the class defined in client.php:

public function metadata($path, $list = true, $fileLimit = 10000, $hash = null, $revision = null, $includeDeleted = false) {
    // Prepare argument list
    $args = array(
        "file_limit" => $fileLimit,
        "hash" => $hash,
        "list" => (int) $list,
        "include_deleted" => (int) $includeDeleted,
        "rev" => $revision
    );

    // Prepend the right access string to the desired path
    if ("dropbox" == $this->accessType) {
        $path = "dropbox" . $path;
    }
    else {
        $path = "sandbox" . $path;
    }

    // Execute
    $response = $this->Session->fetch("GET", $this->dropboxAPIURL, "/metadata/" . $path, $args);
    return $response["body"];
}

This is the getFile() class define...

public function getFile($path, $outFile = null, $revision = null) {

$args = array();
if (!empty($revision)) {
    $args["rev"] = $revision;
}

// Prepend the right access string to the desired path
if ("dropbox" == $this->accessType) {
    $path = "dropbox" . $path;
}
else {
    $path = "sandbox" . $path;
}

// Get the raw response body
$response = $this->Session->fetch("GET", $this->dropboxContentAPIURL, "/files/" . $path, $args, true);

if ($outFile != null) {
    if (file_put_contents($outFile, $response["body"]) === false) {
        throw new Exception("Unable to write file '$outfile'");
    }
}

return array(
    "name" => ($outFile) ? $outFile : basename($path),
    "mime" => $response["headers"]["content-type"],
    "meta" => json_decode($response["headers"]["x-dropbox-metadata"]),
    "data" => $response["body"]
);

}

  • I should add that this code does work, it spits out a full list of the contents of folder Apps/Tools/ from my dropbox, but the problem is I want the nice sandboxy type of output, with clickable links. – user2990466 Jan 14 '14 at 04:14
  • Can you post an example output? You need to write the code to loop through the array. –  Jan 14 '14 at 04:21
  • I also tried the added code, and i'll post the code output yes. THANK YOU BTW JOSH – user2990466 Jan 14 '14 at 04:29
  • Could you clarify maybe with an example of how you would "You need to write the code to loop through the array." – user2990466 Jan 14 '14 at 05:16

2 Answers2

0

For your list_inside.php page, all you need to do is loop through your $client->metadata() array and print the HTML. Here's a sample for that page:

<?php

require_once "bootstrap.php";

if (!isset($access_token)) {
    header("Location: authorize.php");
    exit;
}

try {
    // Start a new Dropbox session
    // The access token should be defined
    // The session should verify if the token is valid and throw an exception
    $session = new DropboxSession(
        $config["dropbox"]["app_key"], 
        $config["dropbox"]["app_secret"], 
        $config["dropbox"]["access_type"], 
        $access_token
    );
    $client = new DropboxClient($session);

    $path = (!empty($_GET["path"])) ? $_GET["path"] : "/Apps/Tools/";

    // List contents of home directory
    if ($home = $client->metadata($path)) {
        echo <<<EOF
        <h1>Index of $index</h1>

        <table>
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Last Modified</th>
                    <th>Size</th>
                    <th>Type</th>
                </tr>
            </thead>
            <tbody>
        EOF;

        foreach($home as $list) {
            $link = ($list[is_dir] == 1 ? "list_inside" : "download").".php?path=".$list[path];
            $file = explode("/", $list[path]);
            $path = $file[count($file)-1];
            $size = ($list[bytes] == 0 ? "-" : $list[size]);

            echo <<<EOF
                <tr>
                    <td><a href="$link">$path</a></td>
                    <td>$list[modified]</td>
                    <td>$size</td>
                    <td>$list[type]</td>
                </tr>
            EOF;
        }

        echo <<<EOF
            </tbody>
        </table>
        EOF;
    }
} catch (Exception $e) {
    echo "<strong>ERROR (" . $e->getCode() . ")</strong>: " . $e->getMessage();
    if ($e->getCode() == 401) {
        // Remove auth file
        unlink($config["app"]["authfile"]);
        // Re auth
        echo '<p><a href="authorize.php">Click Here to re-authenticate</a></p>';
    }
}

?>
0

you just need to call a function to download the file .

require_once 'dropbox/DropboxClient.php';
$dropbox = new DropboxClient(array(
        'app_key' => DROPBX_API_KEY, 
        'app_secret' => DROPBX_API_SECRET,
        'app_full_access' => TRUE,
),'en');
$fileMetadata = $dropbox->DownloadFile($value->path,'download/'.$file);

check this if it can help you

fool-dev
  • 7,671
  • 9
  • 40
  • 54
john
  • 567
  • 8
  • 23