« « Make a PHP Database out of an Excel Spreadsheet | Preassembled Minty Boost USB Phone Chargers Available » »

PHP Script to Download Basecamp Files.. Updated For New Basecamp

Feb 6, 2013 by     16 Comments    Posted under: PHP

Stelabouras has a great PHP script (here) that allows you to download all your files off of Basecamp. The only problem is the script only works for Basecamp Classic, not the newer version, Basecamp BCX. I modified his file to work with the new api. Here it is: (You can also download it here)


<?
// make sure the folder of the script is writeable (0777)
ini_set('memory_limit', '-1');//keeps the script from timing out

function BasecampCall($endPoint, $usePrefix = true) {

    // From: http://prattski.com/2008/10/22/basecamp-api-examples-using-php-and-curl-get/
    $session = curl_init();

    $basecampId     = '[Your Basecamp Account Id Here]';  //this should be a number like 9999999, You can find it in the URL when you log into Basecamp.
    $username       = '[Your Basecamp Username Here]';
    $password       = '[Your Basecamp Password Here]';
    $emailaddress   = '[Your Basecamp Email Address Here]';

    $basecampUrl     = 'https://basecamp.com/' . $basecampId . '/api/v1/';

    curl_setopt($session, CURLOPT_URL, ($usePrefix == true ? $basecampUrl : "") . $endPoint);
    curl_setopt($session, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($session, CURLOPT_HTTPGET, 1);
    curl_setopt($session, CURLOPT_HEADER, false);
    curl_setopt($session, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/json'));
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($session, CURLOPT_USERAGENT, "MyApp (".$emailaddress.")");

    curl_setopt($session,CURLOPT_USERPWD, $username . ":" . $password);

    if(ereg("^(https)",$request)) curl_setopt($session,CURLOPT_SSL_VERIFYPEER,false);

    $response = curl_exec($session);
    curl_close($session);

    if($usePrefix){
        $r = json_decode($response);
    } else {
        $r = $response;
    }

    return $r;
}

$projects = BasecampCall('projects.json');

// For each project take name and id
foreach($projects as $proj) {

    $pr = array(
        "id"    => (string)$proj->id,
        "name"  => (string)$proj->name
    );

    $n = 0;
    $i = 0;

    // Retrieve the attachments
    echo "\nSaving attachments for project: " . $pr['name'] . "...\n";

    @mkdir($pr['name']);

    $filesArray = array();

    do {

        $attachments = BasecampCall("projects/"  . $proj->id . "/attachments.json");

        if(count($attachments) > 0) {

            foreach($attachments as $attachment) {

                $file = pathinfo($attachment->name);

                @file_put_contents($pr['name'] . "/" . $file['filename'] . (in_array($file['filename'], $filesArray) ? "-" . rand() : "") . "." . $file['extension'], BasecampCall($attachment->{'url'}, false));

                $filesArray[] = $file['filename'];

                echo "Saving file " . $attachment->name . "...\n";
            }
        }

        $n += 100;

    } while(count($attachments->attachment) == 100);
}
?>

16 Comments + Add Comment

  • Thanks for a great script! Helped in making my post to todo list work!

  • How can I use this code?

    • Hi Evren,

      To use the script, save it to your desktop, or wherever you want to download the files to. Open up a terminal and type the following:

      php /path/to/dlbasecampbcx.php

      So if you saved the php file onto your desktop, you would type:

      php ~/Desktop/dlbasecampbcx.php

  • Hey Liz, thanks for this – it looks great!
    Sadly I am no PHP wizard and when I run it in the terminal I just get the code written out in the terminal and nothing actually downloads. Do you know why this is?
    Thanks again!

    • How are you running it? Are you including the php command before the file name, like this?

      php /path/to/dlbasecampbcx.php

      • yup, I’m doing exactly that, the line in the command prompt is:

        C:\PHP > php D:/EHD/dlbasecampbcx.php

        Where C:\php is where my php.exe file is and D:/EHD is where I’ve put the script. D: is an external harddrive (I haven’t the capacity on my usual drive), do you think that would matter?

      • OK, after some internet researching I’ve managed to get it to run the script by changing ‘<?' at the start to '<?php'

        It now stops due to: Undefined variable on line 27 and invalid argument supplied for foreach () on line 46

        Considering this has worked for other people I don't see why it has problems with the script when I run it, but if you have any advice that would be great! (I realise that it may start becoming a problem I need to take to a forum rather than continuing to comment on here – let me know if so)

      • Right, it is now doing its job!

        What I’ve done is… delete the if statement part (it didn’t like the undefined ‘$request’ variable it seems) on line 27 and just have ‘curl_setopt($session,CURLOPT_SSL_VERIFYPEER,false);’ always being the case.

        Surround the foreach() statement on line 46 with:

        if (is_array($projects))
        {
        foreach($projects as $proj) { …
        }
        }

        Not perfectly sure why these worked as they did, I’m not well versed with PHP as I previously mentioned, but it might help someone else who stumbles across this in the future!

        Thanks again Liz 🙂

        • Hi Bryn,

          It is the same issue i faced and rectified as suggested by you. But the list is not showing. any idea?

          Thanks.

  • If you aren’t getting any results, you probably have write errors.

    1) Make sure the folder has write permissions (“cd /path/to/folder”, then “chmod -R 777 /folder”)
    2) Replace line 27 with this: “curl_setopt($session,CURLOPT_SSL_VERIFYPEER,false);”
    3) Remove the “@” error suppressor in front of file_put_contents to see errors.
    4) Add the following code above file_put_contents

    if (!file_exists($pr[‘name’])) {
    mkdir($pr[‘name’], 0777, true);
    }

    Thanks

  • Thanks for great working.

    I am facing a problem while implementing the script. Whenever I run script it shows different errors and not loading data. Errors are as follow

    Notice: Undefined variable: request in [SOME URL]

    Warning: Invalid argument supplied for foreach() in [SOME URL]

    Am I missing something? Thanks in advance for help.

  • […] e) If you have documents in other cloud services, like Basecamp, then you may want to sync cloud services so you have a local copy of all docs for meta-tag processing. This can also be scripted. […]

  • Hello!
    Is it possible to improve perfomance of this script?
    Downloading speed is very slow otherwise my connection is not.

    • It might very well be! Give it a shot and let me know how it goes.

  • I had to change your script a little to get it to work with projects that have more that 50 files. See the subheading ‘pagination’ at Basecamp’s Github API here: https://github.com/basecamp/bcx-api/blob/master/sections/attachments.md for an explanation as to why I had to change the script.

    My updated version of the code (line 44 to end):


    foreach($projects as $proj) {

    $pr = array(
    "id" => (string)$proj->id,
    "name" => (string)$proj->name
    );

    // Retrieve the attachments
    echo "\nSaving attachments for project: " . $pr['name'] . "...\n";

    @mkdir($pr['name']);

    $filesArray = array();

    $n = 1;
    do {

    $attachments = BasecampCall("projects/" . $proj->id . "/attachments.json?page=" . $n);

    if(count($attachments) > 0) {

    foreach($attachments as $attachment) {

    $file = pathinfo($attachment->name);

    @file_put_contents($pr['name'] . "/" . $file['filename'] . (in_array($file['filename'], $filesArray) ? "-" . rand() : "") . "." . $file['extension'], BasecampCall($attachment->{'url'}, false));

    $filesArray[] = $file['filename'];

    echo "Saving file " . $attachment->name . "...\n";
    }
    }

    $n++;

    } while(count($attachments) == 50);
    }
    ?>

    • Great solution, thanks for sharing!

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>