6

I think I may have found a PHP program to upload files from a specific folder onto my Dropbox account. The full solution can be found here.

The code seems to work because files and folders a like are being uploaded. However, I don't want the files on my server to be compressed beforehand: I want to copy all files with the files and folders within.

How can the code be modified please? All I want is to copy a specific directory called uploads from my server to dropbox. After modifying the code I managed to arrive at this code:

    <?php

    // Set the timezone so filenames are correct
    date_default_timezone_set('Europe/London');

    // Dropbox username/password
    $dropbox_email='dropbox@dropbox.com';
    $dropbox_pass='password';


    // Filenames for backup files
    $backup_files = "files_" . date("Y.m.d-h.i.s_l") . '.zip';


    // File to backup
    $siteroot = "/site/home/public_html/website/parent/child/uploads/";


    // Backup all files in public_html apart from the gz
    system("zip -r $backup_files $siteroot");


    include("DropboxUploader.php");

    $uploader = new DropboxUploader($dropbox_email, $dropbox_pass);
    $uploader->upload($backup_files,'Backup/Files/');

    system("rm $backup_files");

    ?>

Actual Solution Special thanks to Alireza Noori, halfer and everyone else.

<?php

// Set the timezone so filenames are correct
date_default_timezone_set('Europe/London');

// Backup all files in public_html apart from the gz
$siteroot = "/path/to/backup";

$dropbox_email='dropbox@email';  //Dropbox username
$dropbox_pass='pass';   // Dropbox password

include("DropboxUploader.php");

$uploader = new DropboxUploader($dropbox_email, $dropbox_pass);

function FolderToDropbox($dir, $dropbox_link){    
    $dropbox_folder = 'FolderInDropboxRoot/';
    $files = scandir($dir);
    foreach($files as $item){
        if($item != '.' && $item != '..'){
            if(is_dir($dir.'/'.$item)) FolderToDropbox($dir.'/'.$item,$dropbox_link);
            else if(is_file($dir.'/'.$item)) {
                $clean_dir = str_replace("/path/to/backup", "", $dir);
                $dropbox_link->upload($dir.'/'.$item,$dropbox_folder.$clean_dir.'/');  
            } 
        }
    }
}

FolderToDropbox($siteroot,$uploader);

?>
maltadolls
  • 191
  • 2
  • 11
  • I've not used the API, but I guess you need to list the contents of a directory recursively, and then send them one at a time to the `upload` method. There's some simple illustrations on how to do that here: http://php.net/manual/en/class.recursivedirectoryiterator.php – halfer Mar 19 '13 at 22:52
  • I had someone helping me on that its a bit too complicated for what I had in mind. I was thinking more of a PHP solution similar to the the lines I have above – maltadolls Mar 19 '13 at 23:00
  • 1
    Err, I suggested something that is easy (4 or 5 lines of code) and in PHP too! You'd integrate the lines into your solution, not use them in isolation (all they do is list files in a directory). – halfer Mar 19 '13 at 23:03
  • I am in my 3rd week of learning PHP so everything is brand new and green to me. Can you provide me with code example please? – maltadolls Mar 19 '13 at 23:12
  • 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:16

3 Answers3

3

What @halfer is suggesting is this (I just modified your potential solution based on his idea) so he should take credit:

<?php

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

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

            }
        }
        closedir($handle);
    }
}

// Dropbox username/password
$dropbox_email='dropbox@dropbox.com';
$dropbox_pass='password';

// File to backup
$siteroot = "./";

include("DropboxUploader.php");

$uploader = new DropboxUploader($dropbox_email, $dropbox_pass);

uploadx($siteroot, 'Backup/Files/', $uploader);

?>

BTW, the function above is from here: How to backup files from a specific directory to Dropbox using PHP only?

Community
  • 1
  • 1
Alireza Noori
  • 14,961
  • 30
  • 95
  • 179
  • I tried your code. It is copying files, though unfortunately its not copying the folders and the files within the folders, just the files where the directory is. – maltadolls Mar 20 '13 at 00:14
  • 2
    If you want to recreate the files and folders, you need to handle the recursion yourself. I'll post the code tomorrow if no one else has done so by then. It's 5AM here and I'm sooo sleepy ;) OK? – Alireza Noori Mar 20 '13 at 00:19
  • Thank you @Alireza Noori :) – maltadolls Mar 20 '13 at 00:20
  • 1
    @maltadolls I couldn't sleep without writing this. Try this one and let me know if it works. – Alireza Noori Mar 20 '13 at 00:30
  • 1
    @Alireza, think there's a function discrepancy - `uploaddirtodropbox` versus `uploadx`. Good work though! – halfer Mar 20 '13 at 00:34
  • Thanks for your kind help. Unfortunately it didn't work. It just did the same thing as per your original solution. Though now it created a problem. Say I have a file called hello.php its now creating a folder for it with the same name i.e. hello.php/hello.php – maltadolls Mar 20 '13 at 00:36
  • @maltadolls Sorry my bad, try this one again. – Alireza Noori Mar 20 '13 at 00:37
  • @halfer Thanks. I tried to simplify the name. Forgot the recursive call. – Alireza Noori Mar 20 '13 at 00:38
  • It didn't resolve anything. The problem remained the same re not copying directories and their contents, and that existing files are being created in a directory with their same name. – maltadolls Mar 20 '13 at 00:44
  • OK. So maybe the function's code is wrong (although it seems fine). Tomorrow I'll check it. I have to test it myself. – Alireza Noori Mar 20 '13 at 00:53
  • I checked the code. Seems fine. What is the error you're getting? – Alireza Noori Mar 20 '13 at 09:33
  • Its not giving me any errors in the error log. The problem is that it is not copying the files and folders within the location there is. Another problem I am encountering is that that in our original code it used to copy say xyz.php to Dropbox xyz.php. Now it is creating a folder called xyz.php so to access xyz.php the directory is xyz.php/xyz.php; and say abc.php as abc.php/abc.php. The folder is taking the name of the file. – maltadolls Mar 20 '13 at 12:50
  • The code is fine. I think there is an issue with the result of `is_dir` function. Maybe you're on a shared server and safe mode is on and you don't have access to the directory! Just to be sure, replace this line:`$uploader->upload($dirtocopy.$entry, $dropboxdir.$entry);` with `echo $dirtocopy.$entry.' to '.$dropboxdir.$entry.'
    ';` It should print the expected structure.
    – Alireza Noori Mar 20 '13 at 14:16
  • 1
    Ah, thanks for the link @Alireza - it reveals that the OP has now asked this question **four** times in various guises. I will try to close some of them - what a waste of time! – halfer Mar 20 '13 at 19:10
  • @halfer I haven't seen the other 2 but thanks for checking them out. I just tried to help him/her. I don't know why there is a problem. The code is fine!!! – Alireza Noori Mar 21 '13 at 00:37
  • @Alireza - np, I try to spot multiple re-asks of a question, since it just creates duplicate effort. It's part help-vampire fighting, part education. Yeah, it's good to help, but there comes a point where one has to recommend a course of study (as in this case). – halfer Mar 21 '13 at 00:50
  • @halfer and Alireza I flagged my other posts for deletion, as its not letting me delete them myself. I did phpinfo.php and its telling me that safemode is off. When I replaced $uploader->upload($dirtocopy.$entry, $dropboxdir.$entry); with echo $dirtocopy.$entry.' to '.$dropboxdir.$entry.'
    '; it gave me a list of files in the directory but it did not copy any files to dropbox and no error_log was produced.
    – maltadolls Mar 21 '13 at 07:27
  • @maltadolls The `echo` command is meant for printing the list only. As I said, you should only check if the list is correct. If it is, then the problem is with your system's configuration, not the code. – Alireza Noori Mar 21 '13 at 09:49
  • The list is correct. When I use the code without echo, it is giving me the same problem. Did you actually try your code with a Dropbox account and see if it gives you the same problem? – maltadolls Mar 21 '13 at 09:53
  • @AlirezaNoori Did you manage, please? – maltadolls Mar 21 '13 at 20:12
  • Thank you @halfer - managed of find the code. I am posting it. I appreciate both your help and kind patience. – maltadolls Mar 21 '13 at 21:49
  • 1
    @maltadolls - no worries, glad we could help - pleased you got it working. On another question I linked to an article [on how to use StackOverflow](http://blog.jondh.me.uk/2012/09/how-to-use-stack-overflow/) - the page was deleted by a moderator, so I offer it again. Hope it is of some use! – halfer Mar 21 '13 at 22:24
  • @maltadolls Sorry I missed the party. I'm glad you solved your problem. – Alireza Noori Mar 21 '13 at 22:57
  • Lol no problem. I enjoyed learning from you both. Thanks again. I am very grateflul. – maltadolls Mar 21 '13 at 23:04
  • @Alireza Noori . can you show me how i upload one remote image file to dropbox using your code instead of entire folder ? – user1788736 Nov 03 '13 at 23:05
  • Actually, this is not my code, I just modified it. But you can use `$uploader->upload($file, $dest);` I guess. – Alireza Noori Nov 03 '13 at 23:25
  • Can I copy a remote file (zip) to my Dropbox folder with this function? Thank you. – Silvio Delgado Dec 24 '14 at 04:30
  • @SilvioDelgado This code here uses a class and searches the local directory. I don't think you can use much of this code to do what you want. You should look around a bit. Maybe you'll find something. – Alireza Noori Dec 24 '14 at 14:48
  • 1
    I've found the solution with the Dropbox API, using the PHP fopen method before pass the argument. Thank you. – Silvio Delgado Dec 24 '14 at 18:45
2

Here's a snippet of code from the PHP site that I pointed you to in the comments. All it does is take a directory path (as a string) and output the full pathname of all files inside it (as a number of strings). This is very useful, as we can use this ability to do something to files on an individual basis (like upload them to Dropbox).

<?php

$path = realpath('/etc');
$objects = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($path),
    RecursiveIteratorIterator::SELF_FIRST
);
foreach($objects as $name => $object) {
    echo "$name\n";
}

So, since you're wanting to learn PHP, and since you'll not learn anything if I give you a ready-made solution :-), try the following:

  1. Remove the system call from your code, since you don't want to do any compression
  2. Get the snippet I've provided working on your machine (it will work on its own), changing '/etc' to whatever path you want
  3. Change $path in my code to $siteroot which you use in yours
  4. Remove the $path = ... line in my code (since you define $siteroot yourself)
  5. Test the snippet again
  6. Add in the $objects line from my code after you define $siteroot, into your code
  7. Wrap the $uploader->upload() line in your code with the for loop I provide, removing the echo statement from my code
  8. Change $name to $backup_files in your code

Jiggle it all about a bit, and it should work. Good luck, and feel free to ask questions!

halfer
  • 19,824
  • 17
  • 99
  • 186
  • I followed your instructions and updated my question as per your instructions as _Potential Solution_. Unfortunately the error log is telling me _[19-Mar-2013 17:43:47] PHP Warning: Missing argument 1 for DropboxUploader::upload(), called in /home5/../upload_dropbox.php on line 30 and defined in /home5/../DropboxUploader.php on line 66. Did I do something wrong when following your instructions, please? – maltadolls Mar 19 '13 at 23:49
  • @maltadolls I posted an answer but choose this one as answer if it works. – Alireza Noori Mar 20 '13 at 00:06
  • @maltadolls: yes, Alireza has the right idea. In step 7, I wanted you to **wrap** the `$uploader->upload()` with the `foreach` loop, i.e. put the `foreach` before this line and the closing brace after it. – halfer Mar 20 '13 at 00:22
  • @halfer Thank you. Your solution works, as I then modified my code on Alireza's suggestion. Though its not copying the folders and the files within the folders. – maltadolls Mar 20 '13 at 00:28
  • 1
    It should certainly be copying all files within folders (but just to one target folder). Try removing the second parameter entirely, or swapping `/Backup/Files/` for a remote path that you know exists in Dropbox. Create a new path on Dropbox using their web interface if required. – halfer Mar 20 '13 at 00:32
0

What about using the command line version of dropbox? http://www.dropboxwiki.com/Using_Dropbox_CLI

Copy the files to the dropbox folder and let the deamon do what it needs to do.