$20
Mirrors new uploads silently to a backup domain - Simple!
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" />
<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...
-

Last edited:
08/13/10
8:19pmPippin 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?
- 08/13/10 8:20pm
-

Last edited:
09/10/10
4:40pmJonah 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" />
<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,
JonahPrevious 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
- 08/13/10 11:09pm
-

Last edited:
08/13/10
10:46pmJarret 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.
- 08/13/10 10:48pm
This question has expired.
Current status of this question: Completed





