2

I would like to create a PHP script to backup files from a particular directory on my website to my Dropbox account.

I tried to search for examples and how to work around it but I only found code to backup databases or to buy ready made solutions.

This is the code I tried

<?php
  $passw = "jason"; //change this to a password of your choice.
  if ($_POST) {
    require 'DropboxUploader.php';


    try {
        // Rename uploaded file to reflect original name
        if ($_FILES['file']['error'] !== UPLOAD_ERR_OK)
            throw new Exception('File was not successfully uploaded from your computer.');

        $tmpDir = uniqid('/tmpCapes/');
        if (!mkdir($tmpDir))
            throw new Exception('Cannot create temporary directory!');

        if ($_FILES['file']['name'] === "")
            throw new Exception('File name not supplied by the browser.');

        $tmpFile = $tmpDir.'/'.str_replace("/\0", '_', $_FILES['file']['name']);
        if (!move_uploaded_file($_FILES['file']['tmp_name'], $tmpFile))
            throw new Exception('Cannot rename uploaded file!');

    if ($_POST['txtPassword'] != $passw)
            throw new Exception('Wrong Password');

        // Upload
    $uploader = new DropboxUploader('user@example.com', 'password');// enter dropbox credentials
        $uploader->upload($tmpFile, $_POST['dest']);

        echo '<span style="color: green;font-weight:bold;margin-left:393px;">File successfully uploaded to my Dropbox!</span>';
    } catch(Exception $e) {
        echo '<span style="color: red;font-weight:bold;margin-left:393px;">Error: ' . htmlspecialchars($e->getMessage()) . '</span>';
    }

    // Clean up
    if (isset($tmpFile) && file_exists($tmpFile))
        unlink($tmpFile);

    if (isset($tmpDir) && file_exists($tmpDir))
        rmdir($tmpDir);
}
?>

But instead of uploading the image from my PC to Dropbox via my website. I want to modify the above code to copy files in a specific directory on my website to Dropbox.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
maltadolls
  • 191
  • 2
  • 11
  • 1
    Here is a guide on using dropbox with php http://www.dropbox-php.com/ but nobody here will do your work for you. People are more likely to help if you show what you have before and give some code examples. – Jacob Tomlinson Mar 12 '13 at 08:51
  • Hi Jacob. I upaded my question with the code i am trying to use to find a solution to my query. – maltadolls Mar 12 '13 at 08:54
  • You need recursive code, I think. Your $uploader->upload() function does not go down the directory tree, I imagine. See my answer. I think it will work for you. You just need to model your code after my pattern. – Buttle Butkus Mar 16 '13 at 01:48
  • Four questions from the OP on this topic: [One](http://stackoverflow.com/a/15356995/472495), [Two](http://stackoverflow.com/q/15444085/472495), [Three](http://stackoverflow.com/q/15506402/472495), [Four](http://stackoverflow.com/q/15510107/472495). – halfer Mar 20 '13 at 19:17
  • Four questions from you on this topic: [One](http://stackoverflow.com/a/15356995/472495), [Two](http://stackoverflow.com/q/15444085/472495), [Three](http://stackoverflow.com/q/15506402/472495), [Four](http://stackoverflow.com/q/15510107/472495). This is the first of the sequence, so I'll vote to close at least numbers two and three, which are exact duplicates (and which have created quite a bit of duplicate effort). – halfer Mar 20 '13 at 19:19

2 Answers2

2

You need recursive code.

Write a function that takes a dir as its argument.

Have it loop through the dir looking at each file. For each file, it checks if it's a dir, and if it's not, it copies it.

If it is a dir, the function calls itself.

e.g.

// your code
require 'DropboxUploader.php';

$dirtocopy = './example_directory/';
$dropboxdir = 'backupdir/';
$uploader = new DropboxUploader('sample-email@gmail.com', 'password');// enter dropbox credentials

$errors = array(); // to store errors.


// function definition
function copyDirRecursive($dir) {
  global $uploader; // makes the "$uploader" below the one from outside the function
  if(is_dir($dir)) { // added if/else to check if is dir, and create handle for while loop
    $handle = opendir($dir); 
    if($handle === false) { // add if statements like this wherever you want to check for an error
      $errors[] = $php_errormsg; // http://php.net/manual/en/reserved.variables.phperrormsg.php
    }
  } else {
    return false;
  }
  while(false !== ($file = readdir($handle))) { // changed foreach to while loop
    if(!isdir($file)) {
      // copy the file
      // cp $dir . '/' . $file to $dropbox . '/' . $dir . '/' . $file; // pseudocode
      // below is actual code that hopefully will work
      $uploader->upload($dir.$file,$dropboxdir.$file);
    } else {
      if(!is_link($file)) { // probably best not to follow symlinks, so we check that with is_link()
        copyDirRecursive($dir . '/' . $file); // recursion time
      }
    }

  }
}

// CALL THE FUNCTION
copyDirRecursive($dirtocopy); // you have to call a function for it to do anything

print_r($errors); // use this or var_dump($errors) to see what errors came up
Buttle Butkus
  • 9,206
  • 13
  • 79
  • 120
  • Ok I added it. It was just one line. Let me know if it works. – Buttle Butkus Mar 16 '13 at 02:39
  • Also, you could change your $uploader->upload() function to handle the recursion itself... that's what I would probably do. But I don't know what that function looks like. The above code should work. And if you think about it for a few minutes, I'm sure you can figure out how to put the functionality into the upload() method. – Buttle Butkus Mar 16 '13 at 02:44
  • Trust me I tried and I tried but with no success. Would it be a problem if you could show me a working example? – maltadolls Mar 16 '13 at 02:47
  • I've changed my code to put your $uploader->upload() function into my code example. Did you try it that way yet? – Buttle Butkus Mar 16 '13 at 02:49
  • No, don't change anything. You do have to actually CALL the function though. So you would copy that function into your file. Then, after the function, put `copyDirRecursive($dirtocopy);` But you must have already done that, right? – Buttle Butkus Mar 16 '13 at 02:58
  • I am still learning PHP 3 weeks ago and its getting a bit complicated now. So I am a bit lost. – maltadolls Mar 16 '13 at 02:59
  • You are in pretty deep for having only started 3 weeks ago. I will add some stuff to hopefully make it even more clear. – Buttle Butkus Mar 16 '13 at 04:03
  • Thanks. I like to try things on my own because I like coding. I appreciate your help. I look forward to your additions to my code. – maltadolls Mar 16 '13 at 19:10
  • Hi, I changed the code a bit. Try it again now and see if it works. Also, you can add your own error checking after every operation if you want. I will add an example of that after `$handle = opendir($dir);` – Buttle Butkus Mar 16 '13 at 21:35
  • Did you call the function? – Buttle Butkus Mar 16 '13 at 21:50
  • How do I call the function? – maltadolls Mar 16 '13 at 23:29
  • Please don't be ridiculous. I even put the line in my code that says `// CALL THE FUNCTION`. Come on. "Call a function" simply means "use a function." You want to USE the function right? Or do you just want to admire its beauty? – Buttle Butkus Mar 17 '13 at 00:53
  • I used your code. Nothing is being produced. It is giving me a server error. The error_log told me _[17-Mar-2013 04:02:34] PHP Fatal error: Call to undefined function isdir() in /home5/magimag1/public_html/../upload_dropbox.php on line 24_ I am calling the function ;-) – maltadolls Mar 17 '13 at 10:10
  • You have to make at least some use of your brain, dude. If I got the error you just got, the first thing I would do is google "isdir php". So, instead of telling you why you got that error, I'm going to suggest you use google. Then come back and tell me what you discover. – Buttle Butkus Mar 17 '13 at 22:59
  • I'm a lady so I cannot be a dude. I am in my 3rd week of learning PHP, I'm still green so forgive my ignorance. Plus I found the error _is_dir()_ Now it is telling me _PHP Fatal error: Call to a member function upload() on a non-object in /home5/../upload_dropbox.php on line 29_ which refers to _ $uploader->upload($dir.$file,$dropboxdir.$file); _ – maltadolls Mar 17 '13 at 23:09
  • Ok. So when you call a function with this `->` it means it's an object function (a class function). The error is telling you that $uploader is not an object. The reason for that is this: variables (including objects like $uploader) declared inside of a function have no relation to those declared outside of that function, unless you specify it. I am about to add 1 line at the top of the function that will do just that. – Buttle Butkus Mar 17 '13 at 23:16
  • No. You need to read up on how functions work. `function copyDirRecursive($dir) {` is the "function signature". When you actually call the function below, you feed it $dirtocopy `copyDirRecursive($dirtocopy);`. The argument `$dir` in the function signature is what is used in the body of the function definition to describe what should be done with *whatever* argument you put into the function *call*. – Buttle Butkus Mar 18 '13 at 01:07
  • It is now copying files but as in my original problem. It is creating a folder for every file e.g. xyz.jpg is having a folder too with the same name xyz.jpg/xyz.jpg – maltadolls Mar 19 '13 at 15:42
  • I think I found a better solution. Though I have some queries - http://stackoverflow.com/questions/15506402/how-to-copy-files-from-server-to-dropbox-using-php/ – maltadolls Mar 19 '13 at 17:37
1

Based on the code you have you want something along the lines of

require 'DropboxUploader.php';

$dirtocopy = './example_directory/';
$dropboxdir = '/backupdir/';
$uploader = new DropboxUploader('email@gmail.com', 'Password');// enter dropbox credentials

if ($handle = opendir($dirtocopy)) {
    while (false !== ($entry = readdir($handle))) {
        if ($entry != "." && $entry != "..") {

            $uploader->upload($dirtocopy.$entry, $dropboxdir.$entry);

        }
    }
    closedir($handle);
}

I'm not 100% sure on the dropbox directory code as I've just pulled it out of your example and you may want to drop the first / in $dropboxdir. But I'm sure you can figure that out.

For reference the code for looping a directory is example #2 from http://php.net/manual/en/function.readdir.php

For recursive directory copying

require 'DropboxUploader.php';

function uploaddirtodropbox($dirtocopy, $dropboxdir, $uploader){
    if ($handle = opendir($dirtocopy)) {
        while (false !== ($entry = readdir($handle))) {
            if ($entry != "." && $entry != "..") {

                if(is_dir($entry)){
                    uploaddirtodropbox($dirtocopy.$entry.'/', $dropboxdir.$entry.'/', $uploader);
                } else {
                    $uploader->upload($dirtocopy.$entry, $dropboxdir.$entry);
                }

            }
        }
        closedir($handle);
    }
}

$dirtocopy = './example_directory/';
$dropboxdir = '/backupdir/';
$uploader = new DropboxUploader('email@gmail.com', 'Password');// enter dropbox credentials

uploaddirtodropbox($dirtocopy, $dropboxdir, $uploader);

In the question you have asked for help with using this https://github.com/jakajancar/DropboxUploader/ and I have given you code to do so, however if you read the github page it says

Its development was started before Dropbox released their API, and to work, it scrapes their website. So you can and probably should use their API now.

So it might be a good idea for you to look for an alternative.

Jacob Tomlinson
  • 3,341
  • 2
  • 31
  • 62
  • Thanks Jackob. I will try it out later when I'm at home. I will tell you the result. I appreciate your help. – maltadolls Mar 12 '13 at 09:17
  • 1
    Hi Jackob. It worked perfectly. All I need to do is amend $dirtocopy to copy files from another directory in the same level (same parent). – maltadolls Mar 14 '13 at 08:52
  • 1
    Just so you know, you shared your (or someone else's) username and password to your dropbox, you should change your password assap (the author is copy/pasting your code to other questions aswell). – Jonast92 Mar 16 '13 at 00:07
  • Thanks. I actually just copied from user details from the question. – Jacob Tomlinson Mar 16 '13 at 08:16
  • Hi Jackob. Your code worked perfectly. Though unfortunately its not copying folders and their contents within them. Any help please? – maltadolls Mar 16 '13 at 19:17
  • So are you saying that inside the directory you want to copy to Dropbox there are other directories and you want to copy them recursively? – Jacob Tomlinson Mar 17 '13 at 08:18