logo

$20
Mirrors new uploads silently to a backup domain - Simple!

This plugin WAS working before.. I played around with some of the code too much and now it doesnt work. )=

I simply need the SAME functionality that "Amazon S3 Plugin" offers. Anything that I upload, is backed up onto my S3 account. Now I need to expand on that idea and ALSO have a mirror/backup plugin to a custom backup domain. ( http://backup-domain.com/backups/... )


(plugin not working)
This is what I have as a plugin right now:

<?php
add_filter('wp_handle_upload', 'uploadmirror_main');
add_filter('wp_create_thumbnail', 'uploadmirror_main');
add_filter('image_make_intermediate_size', 'uploadmirror_main');
add_filter('wp_handle_upload', 'uploadmirror_main');

function uploadmirror_main($file) {
$uploads = wp_upload_dir();
$uploads['file'] = (is_string($file) ? $file : $file['url']);
$uploads['dir'] = (is_string($file) ? str_replace($uploads['basedir'], '', $uploads['file']) : str_replace($uploads['baseurl'], '', $uploads['file']));

foreach (array('uploadmirror_domain', 'uploadmirror_domain1', 'uploadmirror_domain2') as $option_name)
{
if (get_option($option_name) !== false) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'file=' . $uploads['file'] . '&dir=' . $uploads['dir']);
curl_setopt($ch, CURLOPT_URL, get_option($option_name));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$postResult = curl_exec($ch);

curl_close($ch);
}
}

return $file;
}

//Dashboard Menus
add_action('admin_menu', array('uploadmirror_admin_content', 'menu'));

class uploadmirror_admin_content {

function menu() {
add_options_page('Automatic Upload Mirror', 'Automatic Upload Mirror', 8, __FILE__, array('uploadmirror_admin_content', 'modify'));
}

function modify() {
if (!empty($_POST['do'])) {
foreach (array('uploadmirror_domain', 'uploadmirror_domain1', 'uploadmirror_domain2') as $option_name)
{
$newvalue = $_POST[$option_name];
if (get_option($option_name) != $newvalue) {
update_option($option_name, $newvalue);
} else {
$deprecated=' ';
$autoload='no';
add_option($option_name, $newvalue, $deprecated, $autoload);
}
}
if (!empty($error))
echo '<div class="error fade">' . nl2br($error) . '</div>';
else
echo '<div class="updated fade">Settings saved.</div>';
}
?>
<div class="wrap">
<h2>Automatic Upload Mirrors</h2>
<form action="" method="post" enctype="multipart/form-data">
<table class="widefat">
<tbody>
<tr>
<td>Path to filedump script #1</td>
<td><input type="text" value="<?php echo get_option('uploadmirror_domain', ''); ?>" name="uploadmirror_domain" style="width: 100%;" /></td>
</tr>
<tr>
<td>Path to filedump script #2</td>
<td><input type="text" value="<?php echo get_option('uploadmirror_domain1', ''); ?>" name="uploadmirror_domain1" style="width: 100%;" /></td>
</tr>
<tr>
<td>Path to filedump script #3</td>
<td><input type="text" value="<?php echo get_option('uploadmirror_domain2', ''); ?>" name="uploadmirror_domain2" style="width: 100%;" /></td>
</tr>
</tbody>
</table>
<input class="button-primary" name="do" value="Submit" class="button" type="submit" />
&nbsp;&nbsp;
<input name="cancel" value="Cancel" class="button" onclick="javascript:history.go(-1)" type="button" />
</form>
</div>
<?php
}


}
?>


-----------

On my OTHER domain.. I have this in a folder (chmodd "777"):


<?php
function vWritePageToFile($readurl)
{
$dir = $_POST['dir'];
$parts = explode('/', $dir);
$file = array_pop($parts);
$dir = dirname(__FILE__);
foreach ($parts as $part)
if (!empty($part))
if (!is_dir($dir .= "/$part")) mkdir($dir);

$ch = curl_init($readurl);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$rawdata = curl_exec($ch);
curl_close($ch);

if (file_exists("$dir/$file"))
unlink("$dir/$file");

$fp = fopen("$dir/$file", 'x');
fwrite($fp, $rawdata);
fclose($fp);
}

vWritePageToFile($_POST['file']);
?>



Andrew C | 08/13/10 at 8:12pm | Edit


(3) Possible Answers Submitted...

  • avatar
    Last edited:
    08/13/10
    8:19pm
    Pippin Williamson says:

    Can you post a working copy of the plugin, before you modified it?

    • 08/13/10 8:20pm

      Andrew C says:

      thats the problem lol .. I lost the original code. /=

    • 08/13/10 8:26pm

      Pippin Williamson says:

      Why don't you just redownload it?

  • avatar
    Last edited:
    09/10/10
    4:40pm
    Jonah Schulte says:

    I've got it working beautifully now on my test environment... Here's the revised/fixed code for the plugin:


    <?php
    /*
    Plugin Name: Automatic Upload Mirror
    Plugin URI:
    Description:
    Author:
    Version: 1.0
    Author URI:
    */


    add_filter('wp_handle_upload', 'uploadmirror_main');
    add_filter('wp_create_thumbnail', 'uploadmirror_main');
    add_filter('image_make_intermediate_size', 'uploadmirror_main');

    function uploadmirror_main($file) {

    $uploads = wp_upload_dir();
    $uploads['file'] = (is_string($file) ? $file : $file['url']);
    $uploads['dir'] = (is_string($file) ? str_replace($uploads['basedir'], '', $uploads['file']) : str_replace($uploads['baseurl'], '', $uploads['file']));

    // Fix url for thumbnails
    $uploads['file'] = str_replace($uploads['path'], $uploads['url'], $uploads['file']);

    foreach (array('uploadmirror_domain', 'uploadmirror_domain1', 'uploadmirror_domain2') as $option_name)
    {
    if (get_option($option_name) !== false) {

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, 'file=' . $uploads['file'] . '&dir=' . $uploads['dir']);
    curl_setopt($ch, CURLOPT_URL, get_option($option_name));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $postResult = curl_exec($ch);

    curl_close($ch);
    }
    }

    return $file;

    }


    //Dashboard Menus

    add_action('admin_menu', array('uploadmirror_admin_content', 'menu'));


    class uploadmirror_admin_content {

    function menu() {
    add_options_page('Automatic Upload Mirror', 'Automatic Upload Mirror', 8, __FILE__, array('uploadmirror_admin_content', 'modify'));
    }

    function modify() {
    if (!empty($_POST['do'])) {
    foreach (array('uploadmirror_domain', 'uploadmirror_domain1', 'uploadmirror_domain2') as $option_name)
    {
    $newvalue = $_POST[$option_name];
    if (get_option($option_name) != $newvalue) {
    update_option($option_name, $newvalue);
    } else {
    $deprecated=' ';
    $autoload='no';
    add_option($option_name, $newvalue, $deprecated, $autoload);
    }
    }

    if (!empty($error))
    {
    echo '<div class="error fade">' . nl2br($error) . '</div>';
    }
    else
    {
    echo '<div class="updated fade">Settings saved.</div>';
    }
    }

    ?>

    <div class="wrap">

    <h2>Automatic Upload Mirrors</h2>

    <form action="" method="post" enctype="multipart/form-data">

    <table class="widefat">

    <tbody>

    <tr>

    <td>Path to filedump script #1</td>

    <td><input type="text" value="<?php echo get_option('uploadmirror_domain', ''); ?>" name="uploadmirror_domain" style="width: 100%;" /></td>

    </tr>

    <tr>

    <td>Path to filedump script #2</td>

    <td><input type="text" value="<?php echo get_option('uploadmirror_domain1', ''); ?>" name="uploadmirror_domain1" style="width: 100%;" /></td>

    </tr>

    <tr>

    <td>Path to filedump script #3</td>

    <td><input type="text" value="<?php echo get_option('uploadmirror_domain2', ''); ?>" name="uploadmirror_domain2" style="width: 100%;" /></td>

    </tr>

    </tbody>

    </table>

    <input class="button-primary" name="do" value="Submit" class="button" type="submit" />

    &nbsp;&nbsp;

    <input name="cancel" value="Cancel" class="button" onclick="javascript:history.go(-1)" type="button" />

    </form>

    </div>

    <?php

    }
    }
    ?>


    And here's the code for the accompanying 'helper' file that downloads the uploads on the remote server:


    <?php
    function vWritePageToFile($readurl)
    {
    if (!$readurl)
    {
    print "No file specified.";
    return false;
    }

    $dir = $_POST['dir'];
    $parts = explode('/', $dir);
    $file = array_pop($parts);
    $dir = dirname(__FILE__);

    foreach ($parts as $part)
    {
    if (!empty($part))
    {
    if (!is_dir($dir .= "/$part"))
    {
    mkdir($dir);
    }
    }
    }

    $ch = curl_init($readurl);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
    $rawdata = curl_exec($ch);
    curl_close($ch);

    if (file_exists("$dir/$file"))
    {
    unlink("$dir/$file");
    }

    $fp = fopen("$dir/$file", 'x');
    fwrite($fp, $rawdata);
    fclose($fp);
    }

    if (isset($_POST['file']))
    {
    vWritePageToFile($_POST['file']);
    }
    else
    {
    die("No file specified.");
    }
    ?>


    Put the helper file at the root of where the backed up files should be stored. For example, if you're trying to mirror the files from one Wordpress installation to another, the place to put the helper file is /wp-content/uploads/ because that is the base directory for the uploaded content.

    This may be obvious, but you'll have to activate the "Automatic Upload Mirror" plugin in the wordpress admin and also configure the location of your remote web server's helper file in the "Automatic Upload Mirror" area under "Settings" in the admin. If you put the helper file (let's say it's called backup-mirror.php) in /wp-content/uploads/ on your wordpress install and your domain is www.mydomain.com, enter this in the "Path to filedump script #1" field in the plugin settings:

    http://www.mydomain.com/wp-content/uploads/backup-mirror.php

    If you prefer to put the helper file in another location you can modify this line in the helper script above:

    $dir = dirname(__FILE__);

    If you want to put the script in the root folder of the Wordpress install for example, change the above line to:

    $dir = dirname(__FILE__).'/wp-content/uploads';

    And then update the plugin settings to:

    http://www.mydomain.com/backup-mirror.php


    Let me know if you have any problems with this code or any questions!

    Thanks,
    Jonah

    Previous versions of this answer: 08/13/10 at 9:57pm | 08/13/10 at 9:58pm | 08/13/10 at 10:10pm | 08/13/10 at 10:15pm

    • 08/13/10 11:09pm

      Andrew C says:

      **Not working:**

      Warning: Cannot modify header information - headers already sent by (output started at /home/n2s/public_html/blog/wp-content/plugins/uploadmirror/uploadmirror.php:2) in /home/n2s/public_html/blog/wp-includes/pluggable.php on line 890

      --------

      - I only need 1 backup site right now. (http://backup-site.com)
      - http://my-real-site.com/wp-content/uploads -->> mirrors files to -->> http://backup-site.com/wp-content/uploads

    • 08/13/10 11:10pm

      Andrew C says:

      Even though I only need one backup site right now, I would need to be able to create multiple backup sites (in the future).

    • 08/14/10 12:14am

      Jonah Schulte says:

      Jarret: Using curl because the file is being copied to a different server. Other ways to do it would be rsync or scp with SSH keys between the two servers, but this is a reliable solution as well.

    • 08/14/10 12:15am

      Jonah Schulte says:

      Andrew: Are you sure there is no space between the opening "php" tag and the top of the plugin file?

      Good:

      TOP OF FILE
      <?php

      Bad:

      TOP OF FILE

      <?php

      Let me know if that's not the problem. The plugin is working fine for me here so I think it's a matter of how it's implemented on your system. I'm happy to take a closer look if you want to send me your plugin files.

      Thanks,
      Jonah

    • 08/14/10 12:24am

      Jonah Schulte says:

      One more thing, regarding your note:

      > Even though I only need one backup site right now,
      > I would need to be able to create multiple backup sites
      > (in the future).

      The plugin currently allows for 3 backup sites. Just enter additional backup sites in "Path to filedump script #2" and "Path to filedump script #3" in the plugin settings. I can make this dynamic if you like so that you can easily specify the number of dumpsites in your config, or I can increase the number to something like 10 sites which should be more than enough for any blog.

    • 08/14/10 12:26am

      Jonah Schulte says:

      If the first possible solution (removing whitespace at the top of the plugin file) is not the problem, please try changing your helper file to use this content instead:


      <?php
      function vWritePageToFile($readurl)
      {

      if (!$readurl)
      {
      return false;
      }

      $dir = $_POST['dir'];

      $parts = explode('/', $dir);

      $file = array_pop($parts);

      $dir = dirname(__FILE__);

      foreach ($parts as $part)
      {
      if (!empty($part))
      {
      if (!is_dir($dir .= "/$part"))
      {
      mkdir($dir);
      }
      }
      }

      $ch = curl_init($readurl);
      curl_setopt($ch, CURLOPT_HEADER, 0);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
      $rawdata = curl_exec($ch);
      curl_close($ch);

      if (file_exists("$dir/$file"))
      {
      unlink("$dir/$file");
      }

      $fp = fopen("$dir/$file", 'x');
      fwrite($fp, $rawdata);
      fclose($fp);
      }

      if (isset($_POST['file']))
      {
      vWritePageToFile($_POST['file']);
      }
      ?>


      It's possible that it was trying to print "No file specified" on the page which might cause the "headers already sent" message to appear.

    • 08/14/10 12:32am

      Andrew C says:

      please message me so I can give you my ftp login information

    • 08/14/10 3:11am

      Jonah Schulte says:

      Hi Andrew, I sent you a message with my email address.

      Thanks,
      Jonah

    • 08/15/10 5:58pm

      Jonah Schulte says:

      Hi Andrew,

      Just regarding Jarret's idea for using "scp" to transfer the files between servers, you need SSH access to your backup server for that command to work. At the moment your backup server does not have SSH enabled which would render the plugin useless to you. If you can contact your hosting provider and find out why your "www" site is redirecting to the "blog" site it will fix the problem with the script you are using now (the one I sent in an earlier message). You already have working code, it's just that your server is not working properly right now.

      Best,
      Jonah

  • avatar
    Last edited:
    08/13/10
    10:46pm
    Jarret Minkler says:

    Why in gods name would you use curl to move a file??

    • 08/13/10 10:48pm

      Andrew C says:

      why? *scratches head*
      how would you do it?

    • 08/14/10 9:42am

      Jarret Minkler says:

      FTP or SCP thats how the rest of the world moves files

    • 08/14/10 9:43am

      Jarret Minkler says:

      and MUCH less code

    • 08/14/10 9:55am

      Jarret Minkler says:

      $command = "scp $filename username@server:$filename"
      shell_exec($command)

    • 08/14/10 11:28am

      Andrew C says:

      if you can make that into a working plugin.. you got it.

This question has expired.





Current status of this question: Completed