Version Description
- Backup file size now in log file
- Paged Logs Table
- added Backup Archives Page
- Grammar fixes
- Bug fixes
Download this release
Release Info
| Developer | danielhuesken |
| Plugin | |
| Version | 1.2.0 |
| Comparing to | |
| See all releases | |
Code changes from version 1.1.1 to 1.2.0
- app/backwpup_dojob.php +196 -183
- app/css/options.css +11 -11
- app/functions.php +228 -104
- app/libs/S3.php +1365 -1365
- app/options-backups.php +165 -0
- app/options-logs.php +59 -24
- app/options-runnow.php +1 -0
- app/options-save.php +105 -2
- app/options-settings.php +1 -0
- app/options-tools.php +1 -0
- app/options-view_log.php +1 -0
- app/options.php +1 -0
- backwpup.php +57 -57
- readme.txt +53 -46
app/backwpup_dojob.php
CHANGED
|
@@ -1,23 +1,23 @@
|
|
| 1 |
<?php
|
| 2 |
-
// don't load directly
|
| 3 |
-
if ( !defined('ABSPATH') )
|
| 4 |
die('-1');
|
| 5 |
|
| 6 |
-
|
| 7 |
-
//function for PHP error handling
|
| 8 |
function backwpup_joberrorhandler($errno, $errstr, $errfile, $errline) {
|
| 9 |
global $backwpup_logfile;
|
| 10 |
-
|
| 11 |
//genrate timestamp
|
| 12 |
if (!function_exists('memory_get_usage')) { // test if memory functions compiled in
|
| 13 |
$timestamp="<span style=\"background-color:c3c3c3;\" title=\"[Line: ".$errline."|File: ".basename($errfile)."\">".date_i18n('Y-m-d H:i.s').":</span> ";
|
| 14 |
} else {
|
| 15 |
if (version_compare(phpversion(), '5.2.0', '<'))
|
| 16 |
$timestamp="<span style=\"background-color:c3c3c3;\" title=\"[Line: ".$errline."|File: ".basename($errfile)."|Mem: ".backwpup_formatBytes(@memory_get_usage())."|Mem Max: ".backwpup_formatBytes(@memory_get_peak_usage())."|Mem Limit: ".ini_get('memory_limit')."]\">".date_i18n('Y-m-d H:i.s').":</span> ";
|
| 17 |
-
else
|
| 18 |
$timestamp="<span style=\"background-color:c3c3c3;\" title=\"[Line: ".$errline."|File: ".basename($errfile)."|Mem: ".backwpup_formatBytes(@memory_get_usage(true))."|Mem Max: ".backwpup_formatBytes(@memory_get_peak_usage(true))."|Mem Limit: ".ini_get('memory_limit')."]\">".date_i18n('Y-m-d H:i.s').":</span> ";
|
| 19 |
}
|
| 20 |
-
|
| 21 |
switch ($errno) {
|
| 22 |
case E_NOTICE:
|
| 23 |
case E_USER_NOTICE:
|
|
@@ -36,7 +36,7 @@ function backwpup_joberrorhandler($errno, $errstr, $errfile, $errline) {
|
|
| 36 |
break;
|
| 37 |
case E_DEPRECATED:
|
| 38 |
case E_USER_DEPRECATED:
|
| 39 |
-
$massage=$timestamp."<span>".__('[DEPRECATED]','backwpup')." ".$errstr."</span>";
|
| 40 |
break;
|
| 41 |
case E_STRICT:
|
| 42 |
$massage=$timestamp."<span>".__('[STRICT NOTICE]','backwpup')." ".$errstr."</span>";
|
|
@@ -48,20 +48,20 @@ function backwpup_joberrorhandler($errno, $errstr, $errfile, $errline) {
|
|
| 48 |
$massage=$timestamp."<span>[".$errno."] ".$errstr."</span>";
|
| 49 |
break;
|
| 50 |
}
|
| 51 |
-
|
| 52 |
if (!empty($massage)) {
|
| 53 |
//wirte log file
|
| 54 |
$fd=@fopen($backwpup_logfile,"a+");
|
| 55 |
@fputs($fd,$massage."<br />\n");
|
| 56 |
@fclose($fd);
|
| 57 |
-
|
| 58 |
-
//output on run now
|
| 59 |
if (!defined('DOING_CRON')) {
|
| 60 |
echo $massage."<script type=\"text/javascript\">window.scrollBy(0, 15);</script><br />\n";
|
| 61 |
@flush();
|
| 62 |
@ob_flush();
|
| 63 |
}
|
| 64 |
-
|
| 65 |
//write new log header
|
| 66 |
if (isset($errors) or isset($warnings)) {
|
| 67 |
$fd=@fopen($backwpup_logfile,"r+");
|
|
@@ -81,10 +81,10 @@ function backwpup_joberrorhandler($errno, $errstr, $errfile, $errline) {
|
|
| 81 |
}
|
| 82 |
@fclose($fd);
|
| 83 |
}
|
| 84 |
-
|
| 85 |
if ($errno==E_ERROR or $errno==E_CORE_ERROR or $errno==E_COMPILE_ERROR) //Die on fatal php errors.
|
| 86 |
die();
|
| 87 |
-
|
| 88 |
|
| 89 |
@set_time_limit(300); //300 is most webserver time limit. 0= max time! Give script 5 min. more to work.
|
| 90 |
//true for no more php error hadling.
|
|
@@ -100,29 +100,29 @@ function backwpup_jobshutdown() {
|
|
| 100 |
$logheader=backwpup_read_logheader($backwpup_logfile); //read waring count from log header
|
| 101 |
$cfg=get_option('backwpup'); //load config
|
| 102 |
$jobs=get_option('backwpup_jobs'); //load job options
|
| 103 |
-
|
| 104 |
if (!empty($jobs[$logheader['jobid']]['stoptime'])) //abort if job exits normaly
|
| 105 |
return;
|
| 106 |
-
|
| 107 |
-
backwpup_joberrorhandler(E_USER_WARNING, __('Job shutdown function is working! Please delete temp
|
| 108 |
-
|
| 109 |
//try to get last error
|
| 110 |
$lasterror=error_get_last();
|
| 111 |
backwpup_joberrorhandler($lasterror['type'], __('Last ERROR:','backwpup').' '.$lasterror['message'], $lasterror['file'], $lasterror['line']);
|
| 112 |
-
|
| 113 |
//set Temp Dir
|
| 114 |
$tempdir=trailingslashit($cfg['dirtemp']);
|
| 115 |
-
if ($tempdir=='/')
|
| 116 |
$tempdir=backwpup_get_upload_dir();
|
| 117 |
-
|
| 118 |
if (is_file($tempdir.DB_NAME.'.sql') ) { //delete sql temp file
|
| 119 |
unlink($tempdir.DB_NAME.'.sql');
|
| 120 |
}
|
| 121 |
-
|
| 122 |
if (is_file($tempdir.'wordpress.' . date( 'Y-m-d' ) . '.xml') ) { //delete WP XML Export temp file
|
| 123 |
unlink($tempdir.'wordpress.' . date( 'Y-m-d' ) . '.xml');
|
| 124 |
}
|
| 125 |
-
|
| 126 |
$jobs[$logheader['jobid']]['stoptime']=current_time('timestamp');
|
| 127 |
$jobs[$logheader['jobid']]['lastrun']=$jobs[$logheader['jobid']]['starttime'];
|
| 128 |
$jobs[$logheader['jobid']]['lastruntime']=$jobs[$logheader['jobid']]['stoptime']-$jobs[$logheader['jobid']]['starttime'];
|
|
@@ -155,12 +155,12 @@ function backwpup_jobshutdown() {
|
|
| 155 |
if ($sendmail) {
|
| 156 |
$mailbody=__("Jobname:","backwpup")." ".$logdata['name']."\n";
|
| 157 |
$mailbody.=__("Jobtype:","backwpup")." ".$logdata['type']."\n";
|
| 158 |
-
if (!empty($logdata['errors']))
|
| 159 |
$mailbody.=__("Errors:","backwpup")." ".$logdata['errors']."\n";
|
| 160 |
if (!empty($logdata['warnings']))
|
| 161 |
$mailbody.=__("Warnings:","backwpup")." ".$logdata['warnings']."\n";
|
| 162 |
wp_mail($jobs[$logheader['jobid']]['mailaddresslog'],__('BackWPup Log File from','backwpup').' '.date_i18n('Y-m-d H:i',$jobs[$logheader['jobid']]['starttime']).': '.$jobs[$logheader['jobid']]['name'] ,$mailbody,'',array($backwpup_logfile));
|
| 163 |
-
}
|
| 164 |
}
|
| 165 |
|
| 166 |
/**
|
|
@@ -168,7 +168,7 @@ function backwpup_jobshutdown() {
|
|
| 168 |
*
|
| 169 |
*/
|
| 170 |
class backwpup_dojob {
|
| 171 |
-
|
| 172 |
private $jobid=0;
|
| 173 |
private $filelist=array();
|
| 174 |
private $tempfilelist=array();
|
|
@@ -182,7 +182,7 @@ class backwpup_dojob {
|
|
| 182 |
private $tempdir='';
|
| 183 |
private $cfg=array();
|
| 184 |
private $job=array();
|
| 185 |
-
|
| 186 |
public function __construct($jobid) {
|
| 187 |
global $backwpup_logfile,$backwpup_dojob;
|
| 188 |
@ini_get('safe_mode','Off'); //disable safe mode
|
|
@@ -204,7 +204,7 @@ class backwpup_dojob {
|
|
| 204 |
$this->backupfileformat=$this->job['fileformart'];
|
| 205 |
//set Temp Dir
|
| 206 |
$this->tempdir=trailingslashit($this->cfg['dirtemp']);
|
| 207 |
-
if (empty($this->tempdir) or $this->tempdir=='/')
|
| 208 |
$this->tempdir=backwpup_get_upload_dir();
|
| 209 |
//set Backup Dir
|
| 210 |
$this->backupdir=$this->job['backupdir'];
|
|
@@ -217,10 +217,10 @@ class backwpup_dojob {
|
|
| 217 |
$this->logdir=str_replace('\\','/',trailingslashit(WP_CONTENT_DIR)).'backwpup-'.$rand.'-logs/';
|
| 218 |
}
|
| 219 |
//set Backup file name only for jos that makes backups
|
| 220 |
-
if (in_array('FILE',$this->todo) or in_array('DB',$this->todo) or in_array('WPEXP',$this->todo))
|
| 221 |
$this->backupfile='backwpup_'.$this->jobid.'_'.date_i18n('Y-m-d_H-i-s').$this->backupfileformat;
|
| 222 |
//set Log file name
|
| 223 |
-
$this->logfile='backwpup_log_'.date_i18n('Y-m-d_H-i-s').'.html';
|
| 224 |
$backwpup_logfile=$this->logdir.$this->logfile;
|
| 225 |
//Create log file
|
| 226 |
if (!$this->_check_folders($this->logdir))
|
|
@@ -234,15 +234,16 @@ class backwpup_dojob {
|
|
| 234 |
@fputs($fd,"<meta name=\"backwpup_jobid\" content=\"".$this->jobid."\" />\n");
|
| 235 |
@fputs($fd,"<meta name=\"backwpup_jobname\" content=\"".$this->job['name']."\" />\n");
|
| 236 |
@fputs($fd,"<meta name=\"backwpup_jobtype\" content=\"".$this->job['type']."\" />\n");
|
| 237 |
-
if (!empty($this->backupfile)
|
| 238 |
-
@fputs($fd,"<meta name=\"backwpup_backupfile\" content=\"".$this->
|
|
|
|
| 239 |
@fputs($fd,str_pad("<meta name=\"backwpup_jobruntime\" content=\"0\" />",100)."\n");
|
| 240 |
@fputs($fd,"<title>".sprintf(__('BackWPup Log for %1$s from %2$s at %3$s','backwpup'),$this->job['name'],date_i18n(get_option('date_format')),date_i18n(get_option('time_format')))."</title>\n</head>\n<body style=\"font-family:monospace;font-size:12px;white-space:nowrap;\">\n");
|
| 241 |
@fclose($fd);
|
| 242 |
//set function for PHP user defineid error handling
|
| 243 |
if (defined(WP_DEBUG) and WP_DEBUG)
|
| 244 |
set_error_handler('backwpup_joberrorhandler',E_ALL | E_STRICT);
|
| 245 |
-
else
|
| 246 |
set_error_handler('backwpup_joberrorhandler',E_ALL & ~E_NOTICE);
|
| 247 |
//set a schutdown function.
|
| 248 |
register_shutdown_function('backwpup_jobshutdown');
|
|
@@ -252,12 +253,12 @@ class backwpup_dojob {
|
|
| 252 |
return false;
|
| 253 |
}
|
| 254 |
//check max script execution tme
|
| 255 |
-
if (ini_get('safe_mode') or strtolower(ini_get('safe_mode'))=='on' or ini_get('safe_mode')=='1')
|
| 256 |
trigger_error(sprintf(__('PHP Safe Mode is on!!! Max exec time is %1$d sec.','backwpup'),ini_get('max_execution_time')),E_USER_WARNING);
|
| 257 |
// check function for memorylimit
|
| 258 |
if (!function_exists('memory_get_usage')) {
|
| 259 |
ini_set('memory_limit', apply_filters( 'admin_memory_limit', '256M' )); //Wordpress default
|
| 260 |
-
trigger_error(sprintf(__('Memory limit set to %1$s ,because can not use PHP: memory_get_usage() function to
|
| 261 |
}
|
| 262 |
//run job parts
|
| 263 |
foreach($this->todo as $key => $value) {
|
|
@@ -280,13 +281,13 @@ class backwpup_dojob {
|
|
| 280 |
elseif ($this->backupfileformat==".tar.gz" or $this->backupfileformat==".tar.bz2" or $this->backupfileformat==".tar")
|
| 281 |
$this->tar_pack_files();
|
| 282 |
}
|
| 283 |
-
if (
|
| 284 |
$this->destination_mail();
|
| 285 |
$this->destination_ftp();
|
| 286 |
$this->destination_s3();
|
| 287 |
$this->destination_dir();
|
| 288 |
}
|
| 289 |
-
|
| 290 |
foreach($this->todo as $key => $value) {
|
| 291 |
switch ($value) {
|
| 292 |
case 'CHECK':
|
|
@@ -296,9 +297,9 @@ class backwpup_dojob {
|
|
| 296 |
$this->optimize_db();
|
| 297 |
break;
|
| 298 |
}
|
| 299 |
-
}
|
| 300 |
-
}
|
| 301 |
-
|
| 302 |
private function _check_folders($folder) {
|
| 303 |
if (!is_dir($folder)) { //create dir if not exists
|
| 304 |
if (!mkdir($folder,0777,true)) {
|
|
@@ -307,8 +308,8 @@ class backwpup_dojob {
|
|
| 307 |
}
|
| 308 |
}
|
| 309 |
if (!is_writeable($folder)) { //test if folder wirteable
|
| 310 |
-
trigger_error(sprintf(__('Can not write to Folder: %1$s','backwpup'),$folder),E_USER_ERROR);
|
| 311 |
-
return false;
|
| 312 |
}
|
| 313 |
//create .htaccess for apache and index.html for other
|
| 314 |
if (strtolower(substr($_SERVER["SERVER_SOFTWARE"],0,6))=="apache") { //check if it a apache webserver
|
|
@@ -323,18 +324,18 @@ class backwpup_dojob {
|
|
| 323 |
if($file = fopen($folder.'index.html', 'w')) {
|
| 324 |
fwrite($file,"\n");
|
| 325 |
fclose($file);
|
| 326 |
-
}
|
| 327 |
}
|
| 328 |
if (!is_file($folder.'index.php')) {
|
| 329 |
if($file = fopen($folder.'index.php', 'w')) {
|
| 330 |
fwrite($file,"\n");
|
| 331 |
fclose($file);
|
| 332 |
-
}
|
| 333 |
}
|
| 334 |
}
|
| 335 |
return true;
|
| 336 |
}
|
| 337 |
-
|
| 338 |
private function need_free_memory($memneed) {
|
| 339 |
//fail back if fuction not exist
|
| 340 |
if (!function_exists('memory_get_usage'))
|
|
@@ -344,7 +345,7 @@ class backwpup_dojob {
|
|
| 344 |
trigger_error(sprintf(__('PHP Safe Mode is on!!! Can not increase Memory Limit is %1$s','backwpup'),ini_get('memory_limit')),E_USER_WARNING);
|
| 345 |
return false;
|
| 346 |
}
|
| 347 |
-
|
| 348 |
//calc mem to bytes
|
| 349 |
if (strtoupper(substr(trim(ini_get('memory_limit')),-1))=='K')
|
| 350 |
$memory=trim(substr(ini_get('memory_limit'),0,-1))*1024;
|
|
@@ -354,73 +355,73 @@ class backwpup_dojob {
|
|
| 354 |
$memory=trim(substr(ini_get('memory_limit'),0,-1))*1024*1024*1024;
|
| 355 |
else
|
| 356 |
$memory=trim(ini_get('memory_limit'));
|
| 357 |
-
|
| 358 |
//use real memory at php version 5.2.0
|
| 359 |
if (version_compare(phpversion(), '5.2.0', '<'))
|
| 360 |
$memnow=memory_get_usage();
|
| 361 |
-
else
|
| 362 |
$memnow=memory_get_usage(true);
|
| 363 |
-
|
| 364 |
//need memory
|
| 365 |
$needmemory=$memnow+$memneed;
|
| 366 |
-
|
| 367 |
-
// increase Memory
|
| 368 |
-
if ($needmemory>$memory) {
|
| 369 |
$newmemory=round($needmemory/1024/1024)+1;
|
| 370 |
-
if ($oldmem=ini_set('memory_limit', $newmemory.'M'))
|
| 371 |
trigger_error(sprintf(__('Memory increased from %1$s to %2$s','backwpup'),$oldmem,ini_get('memory_limit')),E_USER_NOTICE);
|
| 372 |
-
else
|
| 373 |
trigger_error(sprintf(__('Can not increase Memory Limit is %1$s','backwpup'),ini_get('memory_limit')),E_USER_WARNING);
|
| 374 |
}
|
| 375 |
-
return true;
|
| 376 |
}
|
| 377 |
-
|
| 378 |
private function maintenance_mode($enable = false) {
|
| 379 |
if (!$this->job['maintenance'])
|
| 380 |
return;
|
| 381 |
-
|
| 382 |
if ( $enable ) {
|
| 383 |
trigger_error(__('Set Blog to Maintenance Mode','backwpup'),E_USER_NOTICE);
|
| 384 |
if ( class_exists('WPMaintenanceMode') ) { //Support for WP Maintenance Mode Plugin
|
| 385 |
-
update_option('wp-maintenance-mode-msqld','1');
|
| 386 |
} elseif ( class_exists('MaintenanceMode') ) { //Support for Maintenance Mode Plugin
|
| 387 |
$mamo=get_option('plugin_maintenance-mode');
|
| 388 |
$mamo['mamo_activate']='on_'.current_time('timestamp');
|
| 389 |
$mamo['mamo_backtime_days']='0';
|
| 390 |
$mamo['mamo_backtime_hours']='0';
|
| 391 |
$mamo['mamo_backtime_mins']='5';
|
| 392 |
-
update_option('plugin_maintenance-mode',$mamo);
|
| 393 |
} else { //WP Support
|
| 394 |
$fdmain=fopen(trailingslashit(ABSPATH).'.maintenance','w');
|
| 395 |
fputs($fdmain,'<?php $upgrading = ' . time() . '; ?>');
|
| 396 |
-
fclose($fdmain);
|
| 397 |
}
|
| 398 |
} else {
|
| 399 |
trigger_error(__('Set Blog to normal Mode','backwpup'),E_USER_NOTICE);
|
| 400 |
if ( class_exists('WPMaintenanceMode') ) { //Support for WP Maintenance Mode Plugin
|
| 401 |
-
update_option('wp-maintenance-mode-msqld','0');
|
| 402 |
} elseif ( class_exists('MaintenanceMode') ) { //Support for Maintenance Mode Plugin
|
| 403 |
$mamo=get_option('plugin_maintenance-mode');
|
| 404 |
$mamo['mamo_activate']='off';
|
| 405 |
-
update_option('plugin_maintenance-mode',$mamo);
|
| 406 |
} else { //WP Support
|
| 407 |
@unlink(trailingslashit(ABSPATH).'.maintenance');
|
| 408 |
}
|
| 409 |
}
|
| 410 |
}
|
| 411 |
-
|
| 412 |
private function check_db() {
|
| 413 |
global $wpdb;
|
| 414 |
-
|
| 415 |
trigger_error(__('Run Database check...','backwpup'),E_USER_NOTICE);
|
| 416 |
-
|
| 417 |
$tables=$wpdb->get_col('SHOW TABLES FROM `'.DB_NAME.'`');
|
| 418 |
//exclude tables from check
|
| 419 |
foreach($tables as $tablekey => $tablevalue) {
|
| 420 |
if (in_array($tablevalue,$this->job['dbexclude']))
|
| 421 |
unset($tables[$tablekey]);
|
| 422 |
}
|
| 423 |
-
|
| 424 |
//check tables
|
| 425 |
if (sizeof($tables)>0) {
|
| 426 |
$this->maintenance_mode(true);
|
|
@@ -431,8 +432,8 @@ class backwpup_dojob {
|
|
| 431 |
elseif ($check['Msg_type']=='warning')
|
| 432 |
trigger_error(sprintf(__('Result of table check for %1$s is: %2$s','backwpup'), $table, $check['Msg_text']),E_USER_WARNING);
|
| 433 |
else
|
| 434 |
-
trigger_error(sprintf(__('Result of table check for %1$s is: %2$s','backwpup'), $table, $check['Msg_text']),E_USER_NOTICE);
|
| 435 |
-
|
| 436 |
if ($sqlerr=mysql_error($wpdb->dbh)) //aditional SQL error
|
| 437 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), $sqlerr, $sqlerr->last_query),E_USER_ERROR);
|
| 438 |
//Try to Repair tabele
|
|
@@ -443,8 +444,8 @@ class backwpup_dojob {
|
|
| 443 |
elseif ($repair['Msg_type']=='warning')
|
| 444 |
trigger_error(sprintf(__('Result of table repair for %1$s is: %2$s','backwpup'), $table, $repair['Msg_text']),E_USER_WARNING);
|
| 445 |
else
|
| 446 |
-
trigger_error(sprintf(__('Result of table repair for %1$s is: %2$s','backwpup'), $table, $repair['Msg_text']),E_USER_NOTICE);
|
| 447 |
-
|
| 448 |
if ($sqlerr=mysql_error($wpdb->dbh)) //aditional SQL error
|
| 449 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), $sqlerr, $sqlerr->last_query),E_USER_ERROR);
|
| 450 |
}
|
|
@@ -454,7 +455,7 @@ class backwpup_dojob {
|
|
| 454 |
trigger_error(__('Database check done!','backwpup'),E_USER_NOTICE);
|
| 455 |
} else {
|
| 456 |
trigger_error(__('No Tables to check','backwpup'),E_USER_WARNING);
|
| 457 |
-
}
|
| 458 |
}
|
| 459 |
|
| 460 |
private function dump_db_table($table,$status,$file) {
|
|
@@ -464,7 +465,7 @@ class backwpup_dojob {
|
|
| 464 |
fwrite($file, "--\n");
|
| 465 |
fwrite($file, "-- Table structure for table $table\n");
|
| 466 |
fwrite($file, "--\n\n");
|
| 467 |
-
fwrite($file, "DROP TABLE IF EXISTS `" . $table . "`;\n");
|
| 468 |
fwrite($file, "/*!40101 SET @saved_cs_client = @@character_set_client */;\n");
|
| 469 |
fwrite($file, "/*!40101 SET character_set_client = '".mysql_client_encoding()."' */;\n");
|
| 470 |
//Dump the table structure
|
|
@@ -476,14 +477,14 @@ class backwpup_dojob {
|
|
| 476 |
$tablestruc=mysql_fetch_assoc($result);
|
| 477 |
fwrite($file, $tablestruc['Create Table'].";\n");
|
| 478 |
fwrite($file, "/*!40101 SET character_set_client = @saved_cs_client */;\n");
|
| 479 |
-
|
| 480 |
//take data of table
|
| 481 |
$result=mysql_query("SELECT * FROM `".$table."`");
|
| 482 |
if (!$result) {
|
| 483 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), mysql_error(), "SELECT * FROM `".$table."`"),E_USER_ERROR);
|
| 484 |
return false;
|
| 485 |
}
|
| 486 |
-
|
| 487 |
fwrite($file, "--\n");
|
| 488 |
fwrite($file, "-- Dumping data for table $table\n");
|
| 489 |
fwrite($file, "--\n\n");
|
|
@@ -491,7 +492,7 @@ class backwpup_dojob {
|
|
| 491 |
if ($status['Engine']=='MyISAM')
|
| 492 |
fwrite($file, "/*!40000 ALTER TABLE `".$table."` DISABLE KEYS */;\n");
|
| 493 |
|
| 494 |
-
|
| 495 |
while ($data = mysql_fetch_assoc($result)) {
|
| 496 |
$keys = array();
|
| 497 |
$values = array();
|
|
@@ -522,22 +523,22 @@ class backwpup_dojob {
|
|
| 522 |
global $wpdb;
|
| 523 |
trigger_error(__('Run Database Dump to file...','backwpup'),E_USER_NOTICE);
|
| 524 |
$this->maintenance_mode(true);
|
| 525 |
-
|
| 526 |
-
//Tables to backup
|
| 527 |
$tables=$wpdb->get_col('SHOW TABLES FROM `'.DB_NAME.'`');
|
| 528 |
-
if ($sqlerr=mysql_error($wpdb->dbh))
|
| 529 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), $sqlerr, "SHOW TABLES FROM `'.DB_NAME.'`"),E_USER_ERROR);
|
| 530 |
-
|
| 531 |
foreach($tables as $tablekey => $tablevalue) {
|
| 532 |
if (in_array($tablevalue,$this->job['dbexclude']))
|
| 533 |
unset($tables[$tablekey]);
|
| 534 |
}
|
| 535 |
sort($tables);
|
| 536 |
-
|
| 537 |
|
| 538 |
if (sizeof($tables)>0) {
|
| 539 |
$result=$wpdb->get_results("SHOW TABLE STATUS FROM `".DB_NAME."`;", ARRAY_A); //get table status
|
| 540 |
-
if ($sqlerr=mysql_error($wpdb->dbh))
|
| 541 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), $sqlerr, "SHOW TABLE STATUS FROM `".DB_NAME."`;"),E_USER_ERROR);
|
| 542 |
foreach($result as $statusdata) {
|
| 543 |
$status[$statusdata['Name']]=$statusdata;
|
|
@@ -549,9 +550,9 @@ class backwpup_dojob {
|
|
| 549 |
fwrite($file, "-- Plugin for WordPress by Daniel Huesken\n");
|
| 550 |
fwrite($file, "-- http://danielhuesken.de/portfolio/backwpup/\n");
|
| 551 |
fwrite($file, "-- Blog Name: ".get_option('blogname')."\n");
|
| 552 |
-
if (defined('WP_SITEURL'))
|
| 553 |
fwrite($file, "-- Blog URL: ".trailingslashit(WP_SITEURL)."\n");
|
| 554 |
-
else
|
| 555 |
fwrite($file, "-- Blog URL: ".trailingslashit(get_option('siteurl'))."\n");
|
| 556 |
fwrite($file, "-- Blog ABSPATH: ".trailingslashit(ABSPATH)."\n");
|
| 557 |
fwrite($file, "-- Table Prefix: ".$wpdb->prefix."\n");
|
|
@@ -598,9 +599,11 @@ class backwpup_dojob {
|
|
| 598 |
trigger_error(__('Add Database Dump to Backup:','backwpup').' '.DB_NAME.'.sql '.backwpup_formatBytes(filesize($this->tempdir.DB_NAME.'.sql')),E_USER_NOTICE);
|
| 599 |
$this->allfilesize+=filesize($this->tempdir.DB_NAME.'.sql');
|
| 600 |
$this->filelist[]=array(79001=>$this->tempdir.DB_NAME.'.sql',79003=>DB_NAME.'.sql');
|
| 601 |
-
|
| 602 |
$this->maintenance_mode(false);
|
| 603 |
-
}
|
|
|
|
|
|
|
| 604 |
|
| 605 |
private function export_wp() {
|
| 606 |
trigger_error(__('Run Wordpress Export to XML file...','backwpup'),E_USER_NOTICE);
|
|
@@ -613,20 +616,20 @@ class backwpup_dojob {
|
|
| 613 |
} else {
|
| 614 |
trigger_error(__('Can not Export to XML!','backwpup'),E_USER_ERROR);
|
| 615 |
}
|
| 616 |
-
}
|
| 617 |
|
| 618 |
private function optimize_db() {
|
| 619 |
global $wpdb;
|
| 620 |
-
|
| 621 |
trigger_error(__('Run Database optimize...','backwpup'),E_USER_NOTICE);
|
| 622 |
-
|
| 623 |
$tables=$wpdb->get_col('SHOW TABLES FROM `'.DB_NAME.'`');
|
| 624 |
//exclude tables from optimize
|
| 625 |
foreach($tables as $tablekey => $tablevalue) {
|
| 626 |
if (in_array($tablevalue,$this->job['dbexclude']))
|
| 627 |
unset($tables[$tablekey]);
|
| 628 |
}
|
| 629 |
-
|
| 630 |
if (sizeof($tables)>0) {
|
| 631 |
$this->maintenance_mode(true);
|
| 632 |
foreach ($tables as $table) {
|
|
@@ -636,9 +639,9 @@ class backwpup_dojob {
|
|
| 636 |
elseif ($optimize['Msg_type']=='warning')
|
| 637 |
trigger_error(sprintf(__('Result of table optimize for %1$s is: %2$s','backwpup'), $table, $optimize['Msg_text']),E_USER_WARNING);
|
| 638 |
else
|
| 639 |
-
trigger_error(sprintf(__('Result of table optimize for %1$s is: %2$s','backwpup'), $table, $optimize['Msg_text']),E_USER_NOTICE);
|
| 640 |
-
|
| 641 |
-
if ($sqlerr=mysql_error($wpdb->dbh))
|
| 642 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), $sqlerr, $sqlerr->last_query),E_USER_ERROR);
|
| 643 |
}
|
| 644 |
$wpdb->flush();
|
|
@@ -646,7 +649,7 @@ class backwpup_dojob {
|
|
| 646 |
$this->maintenance_mode(false);
|
| 647 |
} else {
|
| 648 |
trigger_error(__('No Tables to optimize','backwpup'),E_USER_WARNING);
|
| 649 |
-
}
|
| 650 |
}
|
| 651 |
|
| 652 |
private function _file_list_folder( $folder = '', $levels = 100, $excludes,$excludedirs=array()) {
|
|
@@ -677,41 +680,41 @@ class backwpup_dojob {
|
|
| 677 |
}
|
| 678 |
}
|
| 679 |
@closedir( $dir );
|
| 680 |
-
}
|
| 681 |
}
|
| 682 |
-
|
| 683 |
private function file_list() {
|
| 684 |
|
| 685 |
//Make filelist
|
| 686 |
trigger_error(__('Make a list of files to Backup ....','backwpup'),E_USER_NOTICE);
|
| 687 |
-
|
| 688 |
$this->tempfilelist=array();
|
| 689 |
-
|
| 690 |
$backwpup_exclude=explode(',',trim($this->job['fileexclude']));
|
| 691 |
//Exclude Temp Files
|
| 692 |
$backwpup_exclude[]=$this->tempdir.DB_NAME.'.sql';
|
| 693 |
$backwpup_exclude[]=$this->tempdir.'wordpress.' . date( 'Y-m-d' ) . '.xml';
|
| 694 |
$backwpup_exclude=array_unique($backwpup_exclude,SORT_STRING);
|
| 695 |
-
|
| 696 |
//File list for blog folders
|
| 697 |
if ($this->job['backuproot'])
|
| 698 |
-
$this->_file_list_folder(untrailingslashit(str_replace('\\','/',ABSPATH)),100,$backwpup_exclude,array_merge($this->job['backuprootexcludedirs'],backwpup_get_exclude_wp_dirs(ABSPATH)));
|
| 699 |
if ($this->job['backupcontent'])
|
| 700 |
$this->_file_list_folder(untrailingslashit(str_replace('\\','/',WP_CONTENT_DIR)),100,$backwpup_exclude,array_merge($this->job['backupcontentexcludedirs'],backwpup_get_exclude_wp_dirs(WP_CONTENT_DIR)));
|
| 701 |
if ($this->job['backupplugins'])
|
| 702 |
$this->_file_list_folder(untrailingslashit(str_replace('\\','/',WP_PLUGIN_DIR)),100,$backwpup_exclude,array_merge($this->job['backuppluginsexcludedirs'],backwpup_get_exclude_wp_dirs(WP_PLUGIN_DIR)));
|
| 703 |
-
if ($this->job['backupthemes'])
|
| 704 |
$this->_file_list_folder(untrailingslashit(str_replace('\\','/',trailingslashit(WP_CONTENT_DIR).'themes')),100,$backwpup_exclude,array_merge($this->job['backupthemesexcludedirs'],backwpup_get_exclude_wp_dirs(trailingslashit(WP_CONTENT_DIR).'themes')));
|
| 705 |
if ($this->job['backupuploads'])
|
| 706 |
$this->_file_list_folder(untrailingslashit(backwpup_get_upload_dir()),100,$backwpup_exclude,array_merge($this->job['backupuploadsexcludedirs'],backwpup_get_exclude_wp_dirs(backwpup_get_upload_dir())));
|
| 707 |
-
|
| 708 |
-
//include dirs
|
| 709 |
$dirinclude=explode(',',$this->job['dirinclude']);
|
| 710 |
$dirinclude=array_unique($dirinclude,SORT_STRING);
|
| 711 |
//Crate file list
|
| 712 |
if (is_array($dirinclude)) {
|
| 713 |
foreach($dirinclude as $dirincludevalue) {
|
| 714 |
-
if (is_dir($dirincludevalue))
|
| 715 |
$this->_file_list_folder(untrailingslashit(str_replace('\\','/',$dirincludevalue)),100,$backwpup_exclude);
|
| 716 |
}
|
| 717 |
}
|
|
@@ -722,22 +725,22 @@ class backwpup_dojob {
|
|
| 722 |
$this->filelist[]=array(79001=>$files,79003=>str_replace(str_replace('\\','/',trailingslashit(ABSPATH)),'',$files));
|
| 723 |
}
|
| 724 |
$this->tempfilelist=array();
|
| 725 |
-
|
| 726 |
if (!is_array($this->filelist[0])) {
|
| 727 |
trigger_error(__('No files to Backup','backwpup'),E_USER_ERROR);
|
| 728 |
} else {
|
| 729 |
trigger_error(__('Size off all files:','backwpup').' '.backwpup_formatBytes($this->allfilesize),E_USER_NOTICE);
|
| 730 |
}
|
| 731 |
-
|
| 732 |
-
}
|
| 733 |
|
| 734 |
private function zip_files() {
|
| 735 |
-
|
| 736 |
if (class_exists('ZipArchive')) { //use php zip lib
|
| 737 |
trigger_error(__('Create Backup Zip file...','backwpup'),E_USER_NOTICE);
|
| 738 |
$zip = new ZipArchive;
|
| 739 |
if ($res=$zip->open($this->backupdir.$this->backupfile,ZIPARCHIVE::CREATE) === TRUE) {
|
| 740 |
-
foreach($this->filelist as $key => $files) {
|
| 741 |
if (!is_file($files[79001])) //check file exists
|
| 742 |
continue;
|
| 743 |
if ($zip->addFile($files[79001], $files[79003])) {
|
|
@@ -751,31 +754,31 @@ class backwpup_dojob {
|
|
| 751 |
} else {
|
| 752 |
trigger_error(__('Can not create Backup ZIP file:','backwpup').' '.$res,E_USER_ERROR);
|
| 753 |
}
|
| 754 |
-
|
| 755 |
} else { //use PclZip
|
| 756 |
define( 'PCLZIP_TEMPORARY_DIR', $this->tempdir );
|
| 757 |
-
if (!class_exists('PclZip'))
|
| 758 |
require_once (plugin_dir_path(__FILE__).'libs/pclzip.lib.php');
|
| 759 |
-
|
| 760 |
//Create Zip File
|
| 761 |
if (is_array($this->filelist[0])) {
|
| 762 |
$this->need_free_memory(10485760); //10MB free memory for zip
|
| 763 |
trigger_error(__('Create Backup Zip (PclZip) file...','backwpup'),E_USER_NOTICE);
|
| 764 |
foreach($this->filelist as $key => $files) {
|
| 765 |
trigger_error(__('Add File to ZIP file:','backwpup').' '.$files[79001].' '.backwpup_formatBytes(filesize($files[79001])),E_USER_NOTICE);
|
| 766 |
-
}
|
| 767 |
$zipbackupfile = new PclZip($this->backupdir.$this->backupfile);
|
| 768 |
if (0==$zipbackupfile -> create($this->filelist,PCLZIP_OPT_ADD_TEMP_FILE_ON)) {
|
| 769 |
trigger_error(__('Zip file create:','backwpup').' '.$zipbackupfile->errorInfo(true),E_USER_ERROR);
|
| 770 |
-
} else {
|
| 771 |
trigger_error(__('Backup Zip file create done!','backwpup'),E_USER_NOTICE);
|
| 772 |
}
|
| 773 |
}
|
| 774 |
}
|
| 775 |
}
|
| 776 |
-
|
| 777 |
private function tar_pack_files() {
|
| 778 |
-
|
| 779 |
if ($this->backupfileformat=='.tar.gz') {
|
| 780 |
$tarbackup=gzopen($this->backupdir.$this->backupfile,'w9');
|
| 781 |
} elseif ($this->backupfileformat=='.tar.bz2') {
|
|
@@ -783,23 +786,23 @@ class backwpup_dojob {
|
|
| 783 |
} else {
|
| 784 |
$tarbackup=fopen($this->backupdir.$this->backupfile,'w');
|
| 785 |
}
|
| 786 |
-
|
| 787 |
if (!$tarbackup) {
|
| 788 |
trigger_error(__('Can not create TAR Backup file','backwpup'),E_USER_ERROR);
|
| 789 |
return;
|
| 790 |
} else {
|
| 791 |
trigger_error(__('Create Backup Archive file...','backwpup'),E_USER_NOTICE);
|
| 792 |
}
|
| 793 |
-
|
| 794 |
$this->need_free_memory(1048576); //1MB free memory for zip
|
| 795 |
-
|
| 796 |
foreach($this->filelist as $key => $files) {
|
| 797 |
trigger_error(__('Add File to Backup Archive:','backwpup').' '.$files[79001].' '.backwpup_formatBytes(filesize($files[79001])),E_USER_NOTICE);
|
| 798 |
-
|
| 799 |
//check file exists
|
| 800 |
if (!is_file($files[79001]))
|
| 801 |
continue;
|
| 802 |
-
|
| 803 |
// Get file information
|
| 804 |
$file_information = stat($files[79001]);
|
| 805 |
|
|
@@ -822,15 +825,15 @@ class backwpup_dojob {
|
|
| 822 |
"", //device minor number 8
|
| 823 |
substr($files[79003],101), //prefix for file name 155
|
| 824 |
""); //fill block 512K
|
| 825 |
-
|
| 826 |
// Computes the unsigned Checksum of a file's header
|
| 827 |
$checksum = 0;
|
| 828 |
for ($i = 0; $i < 512; $i++)
|
| 829 |
$checksum += ord(substr($header, $i, 1));
|
| 830 |
$checksum = pack("a8", sprintf("%07o", $checksum));
|
| 831 |
-
|
| 832 |
$header = substr_replace($header, $checksum, 148, 8);
|
| 833 |
-
|
| 834 |
if ($this->backupfileformat=='.tar.gz') {
|
| 835 |
gzwrite($tarbackup, $header);
|
| 836 |
} elseif ($this->backupfileformat=='.tar.bz2') {
|
|
@@ -838,7 +841,7 @@ class backwpup_dojob {
|
|
| 838 |
} else {
|
| 839 |
fwrite($tarbackup, $header);
|
| 840 |
}
|
| 841 |
-
|
| 842 |
// read/write files in 512K Blocks
|
| 843 |
$fd=fopen($files[79001],'rb');
|
| 844 |
while(!feof($fd)) {
|
|
@@ -855,23 +858,23 @@ class backwpup_dojob {
|
|
| 855 |
}
|
| 856 |
fclose($fd);
|
| 857 |
}
|
| 858 |
-
|
| 859 |
-
|
| 860 |
if ($this->backupfileformat=='.tar.gz') {
|
| 861 |
gzwrite($tarbackup, pack("a1024", "")); // Add 1024 bytes of NULLs to designate EOF
|
| 862 |
-
gzclose($tarbackup);
|
| 863 |
} elseif ($this->backupfileformat=='.tar.bz2') {
|
| 864 |
bzwrite($tarbackup, pack("a1024", "")); // Add 1024 bytes of NULLs to designate EOF
|
| 865 |
bzclose($tarbackup);
|
| 866 |
} else {
|
| 867 |
fwrite($tarbackup, pack("a1024", "")); // Add 1024 bytes of NULLs to designate EOF
|
| 868 |
-
fclose($tarbackup);
|
| 869 |
}
|
| 870 |
-
|
| 871 |
trigger_error(__('Backup Archive file create done!','backwpup'),E_USER_NOTICE);
|
| 872 |
}
|
| 873 |
-
|
| 874 |
-
|
| 875 |
private function _ftp_raw_helper($ftp_conn_id,$command) { //FTP Comands helper function
|
| 876 |
$return=ftp_raw($ftp_conn_id,$command);
|
| 877 |
if (strtoupper(substr(trim($command),0,4))=="PASS") {
|
|
@@ -899,13 +902,13 @@ class backwpup_dojob {
|
|
| 899 |
}
|
| 900 |
}
|
| 901 |
}
|
| 902 |
-
|
| 903 |
-
|
| 904 |
private function destination_ftp() {
|
| 905 |
-
|
| 906 |
-
if (empty($this->job['ftphost']) or empty($this->job['ftpuser']) or empty($this->job['ftppass']))
|
| 907 |
return false;
|
| 908 |
-
|
| 909 |
$ftpport=21;
|
| 910 |
$ftphost=$this->job['ftphost'];
|
| 911 |
if (false !== strpos($this->job['ftphost'],':')) //look for port
|
|
@@ -913,17 +916,15 @@ class backwpup_dojob {
|
|
| 913 |
|
| 914 |
if (function_exists('ftp_ssl_connect')) { //make SSL FTP connection
|
| 915 |
$ftp_conn_id = ftp_ssl_connect($ftphost,$ftpport,10);
|
| 916 |
-
if ($ftp_conn_id)
|
| 917 |
trigger_error(__('Connected by SSL to FTP server:','backwpup').' '.$this->job['ftphost'],E_USER_NOTICE);
|
| 918 |
-
}
|
| 919 |
}
|
| 920 |
if (!$ftp_conn_id) { //make normal FTP conection if SSL not work
|
| 921 |
$ftp_conn_id = ftp_connect($ftphost,$ftpport,10);
|
| 922 |
-
if ($ftp_conn_id)
|
| 923 |
trigger_error(__('Connected insecure to FTP server:','backwpup').' '.$this->job['ftphost'],E_USER_NOTICE);
|
| 924 |
-
}
|
| 925 |
}
|
| 926 |
-
|
| 927 |
if (!$ftp_conn_id) {
|
| 928 |
trigger_error(__('Can not connect to FTP server:','backwpup').' '.$this->job['ftphost'],E_USER_ERROR);
|
| 929 |
return false;
|
|
@@ -941,45 +942,45 @@ class backwpup_dojob {
|
|
| 941 |
}
|
| 942 |
}
|
| 943 |
}
|
| 944 |
-
|
| 945 |
//if (ftp_login($ftp_conn_id, $jobs[$jobid]['ftpuser'], $jobs[$jobid]['ftppass'])) {
|
| 946 |
-
if (!$loginok)
|
| 947 |
return false;
|
| 948 |
-
|
| 949 |
//SYSTYPE
|
| 950 |
$this->_ftp_raw_helper($ftp_conn_id,'SYST');
|
| 951 |
//PASV
|
| 952 |
trigger_error(__('FTP Client command:','backwpup').' PASV',E_USER_NOTICE);
|
| 953 |
if (ftp_pasv($ftp_conn_id, true))
|
| 954 |
trigger_error(__('Server Completion reply: 227 Entering Passive Mode','backwpup'),E_USER_NOTICE);
|
| 955 |
-
else
|
| 956 |
trigger_error(__('FTP Server reply:','backwpup').' '.__('Can not Entering Passive Mode','backwpup'),E_USER_WARNING);
|
| 957 |
//ALLO show no erros in log if do not work
|
| 958 |
trigger_error(__('FTP Client command:','backwpup').' ALLO',E_USER_NOTICE);
|
| 959 |
ftp_alloc($ftp_conn_id,filesize($this->backupdir.$this->backupfile),$result);
|
| 960 |
trigger_error(__('FTP Server reply:','backwpup').' '.$result,E_USER_NOTICE);
|
| 961 |
-
|
| 962 |
//test ftp dir and create it f not exists
|
| 963 |
$ftpdirs=explode("/", untrailingslashit($this->job['ftpdir']));
|
| 964 |
foreach ($ftpdirs as $ftpdir) {
|
| 965 |
if (empty($ftpdir))
|
| 966 |
continue;
|
| 967 |
if (!@ftp_chdir($ftp_conn_id, $ftpdir)) {
|
| 968 |
-
trigger_error('"'.$ftpdir.'" '.__('FTP
|
| 969 |
if (@ftp_mkdir($ftp_conn_id, $ftpdir)) {
|
| 970 |
-
trigger_error('"'.$ftpdir.'" '.__('FTP
|
| 971 |
ftp_chdir($ftp_conn_id, $ftpdir);
|
| 972 |
} else {
|
| 973 |
-
trigger_error('"'.$ftpdir.'" '.__('FTP
|
| 974 |
}
|
| 975 |
}
|
| 976 |
}
|
| 977 |
-
|
| 978 |
if (ftp_put($ftp_conn_id, $this->job['ftpdir'].$this->backupfile, $this->backupdir.$this->backupfile, FTP_BINARY)) //transfere file
|
| 979 |
trigger_error(__('Backup File transferred to FTP Server:','backwpup').' '.$this->job['ftpdir'].$this->backupfile,E_USER_NOTICE);
|
| 980 |
else
|
| 981 |
trigger_error(__('Can not transfer backup to FTP server.','backwpup'),E_USER_ERROR);
|
| 982 |
-
|
| 983 |
if ($this->job['ftpmaxbackups']>0) { //Delete old backups
|
| 984 |
$backupfilelist=array();
|
| 985 |
if ($filelist=ftp_nlist($ftp_conn_id, $this->job['ftpdir'])) {
|
|
@@ -993,7 +994,7 @@ class backwpup_dojob {
|
|
| 993 |
for ($i=$this->job['ftpmaxbackups'];$i<sizeof($backupfilelist);$i++) {
|
| 994 |
if (ftp_delete($ftp_conn_id, $this->job['ftpdir'].$backupfilelist[$i])) //delte files on ftp
|
| 995 |
$numdeltefiles++;
|
| 996 |
-
else
|
| 997 |
trigger_error(__('Can not delete file on FTP Server:','backwpup').' '.$this->job['ftpdir'].$backupfilelist[$i],E_USER_ERROR);
|
| 998 |
}
|
| 999 |
if ($numdeltefiles>0)
|
|
@@ -1001,16 +1002,16 @@ class backwpup_dojob {
|
|
| 1001 |
}
|
| 1002 |
}
|
| 1003 |
}
|
| 1004 |
-
ftp_close($ftp_conn_id);
|
| 1005 |
|
| 1006 |
-
}
|
| 1007 |
|
| 1008 |
private function destination_mail() {
|
| 1009 |
if (empty($this->job['mailaddress']))
|
| 1010 |
return false;
|
| 1011 |
-
|
| 1012 |
-
trigger_error(__('Prepare Sending
|
| 1013 |
-
|
| 1014 |
//Crate PHP Mailer
|
| 1015 |
require_once(ABSPATH.WPINC.'/class-phpmailer.php');
|
| 1016 |
require_once(ABSPATH.WPINC.'/class-smtp.php');
|
|
@@ -1038,16 +1039,16 @@ class backwpup_dojob {
|
|
| 1038 |
$phpmailer->IsMail();
|
| 1039 |
trigger_error(__('Send mail with PHP mail','backwpup'),E_USER_NOTICE);
|
| 1040 |
}
|
| 1041 |
-
|
| 1042 |
|
| 1043 |
trigger_error(__('Creating mail','backwpup'),E_USER_NOTICE);
|
| 1044 |
$phpmailer->From = $this->cfg['mailsndemail'];
|
| 1045 |
$phpmailer->FromName = $this->cfg['mailsndname'];
|
| 1046 |
-
$phpmailer->AddAddress($this->job['mailaddress']);
|
| 1047 |
$phpmailer->Subject = __('BackWPup File from','backwpup').' '.date_i18n('Y-m-d H:i',$this->job['starttime']).': '.$this->job['name'];
|
| 1048 |
$phpmailer->IsHTML(false);
|
| 1049 |
$phpmailer->Body = 'Backup File';
|
| 1050 |
-
|
| 1051 |
//check file Size
|
| 1052 |
if (!empty($this->job['mailefilesize'])) {
|
| 1053 |
$maxfilezise=abs($this->job['mailefilesize']*1024*1024);
|
|
@@ -1056,23 +1057,23 @@ class backwpup_dojob {
|
|
| 1056 |
return false;
|
| 1057 |
}
|
| 1058 |
}
|
| 1059 |
-
|
| 1060 |
trigger_error(__('Adding Attachment to mail','backwpup'),E_USER_NOTICE);
|
| 1061 |
$this->need_free_memory(filesize($this->backupdir.$this->backupfile)*5);
|
| 1062 |
-
$phpmailer->AddAttachment($this->backupdir.$this->backupfile);
|
| 1063 |
-
|
| 1064 |
trigger_error(__('Send mail....','backwpup'),E_USER_NOTICE);
|
| 1065 |
if (false == $phpmailer->Send()) {
|
| 1066 |
trigger_error(__('Can not send mail:','backwpup').' '.$phpmailer->ErrorInfo,E_USER_ERROR);
|
| 1067 |
} else {
|
| 1068 |
trigger_error(__('Mail send!!!','backwpup'),E_USER_NOTICE);
|
| 1069 |
-
}
|
| 1070 |
-
|
| 1071 |
}
|
| 1072 |
|
| 1073 |
private function destination_s3() {
|
| 1074 |
-
|
| 1075 |
-
if (empty($this->job['awsAccessKey']) or empty($this->job['awsSecretKey']) or empty($this->job['awsBucket']))
|
| 1076 |
return false;
|
| 1077 |
|
| 1078 |
if (!(extension_loaded('curl') or @dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll'))) {
|
|
@@ -1080,9 +1081,9 @@ class backwpup_dojob {
|
|
| 1080 |
return false;
|
| 1081 |
}
|
| 1082 |
|
| 1083 |
-
if (!class_exists('S3'))
|
| 1084 |
require_once(plugin_dir_path(__FILE__).'libs/S3.php');
|
| 1085 |
-
|
| 1086 |
$s3 = new S3($this->job['awsAccessKey'], $this->job['awsSecretKey'], $this->job['awsSSL']);
|
| 1087 |
|
| 1088 |
if (in_array($this->job['awsBucket'],$s3->listBuckets())) {
|
|
@@ -1092,7 +1093,7 @@ class backwpup_dojob {
|
|
| 1092 |
trigger_error(__('Backup File transferred to S3://','backwpup').$this->job['awsBucket'].'/'.$this->job['awsdir'].$this->backupfile,E_USER_NOTICE);
|
| 1093 |
else
|
| 1094 |
trigger_error(__('Can not transfer backup to S3.','backwpup'),E_USER_ERROR);
|
| 1095 |
-
|
| 1096 |
if ($this->job['awsmaxbackups']>0) { //Delete old backups
|
| 1097 |
$backupfilelist=array();
|
| 1098 |
if (($contents = $s3->getBucket($this->job['awsBucket'],$this->job['awsdir'])) !== false) {
|
|
@@ -1110,7 +1111,7 @@ class backwpup_dojob {
|
|
| 1110 |
for ($i=$this->job['awsmaxbackups'];$i<sizeof($backupfilelist);$i++) {
|
| 1111 |
if ($s3->deleteObject($this->job['awsBucket'], $this->job['awsdir'].$backupfilelist[$i])) //delte files on S3
|
| 1112 |
$numdeltefiles++;
|
| 1113 |
-
else
|
| 1114 |
trigger_error(__('Can not delete file on S3//:','backwpup').$this->job['awsBucket'].'/'.$this->job['awsdir'].$backupfilelist[$i],E_USER_ERROR);
|
| 1115 |
}
|
| 1116 |
if ($numdeltefiles>0)
|
|
@@ -1128,7 +1129,7 @@ class backwpup_dojob {
|
|
| 1128 |
//Delete old Backupfiles
|
| 1129 |
$backupfilelist=array();
|
| 1130 |
if (!empty($this->job['maxbackups'])) {
|
| 1131 |
-
if ( $dir = @opendir($this->job['backupdir']) ) { //make file list
|
| 1132 |
while (($file = readdir($dir)) !== false ) {
|
| 1133 |
if ('backwpup_'.$this->jobid.'_' == substr($file,0,strlen('backwpup_'.$this->jobid.'_')) and $this->backupfileformat == substr($file,-strlen($this->backupfileformat)))
|
| 1134 |
$backupfilelist[]=$file;
|
|
@@ -1147,29 +1148,33 @@ class backwpup_dojob {
|
|
| 1147 |
}
|
| 1148 |
}
|
| 1149 |
}
|
| 1150 |
-
|
| 1151 |
public function __destruct() {
|
| 1152 |
global $backwpup_logfile;
|
| 1153 |
-
|
| 1154 |
if (is_file($this->backupdir.$this->backupfile)) {
|
| 1155 |
-
|
|
|
|
| 1156 |
}
|
| 1157 |
|
|
|
|
|
|
|
|
|
|
| 1158 |
if (is_file($this->tempdir.DB_NAME.'.sql') ) { //delete sql temp file
|
| 1159 |
unlink($this->tempdir.DB_NAME.'.sql');
|
| 1160 |
}
|
| 1161 |
-
|
| 1162 |
if (is_file($this->tempdir.'wordpress.' . date( 'Y-m-d' ) . '.xml') ) { //delete WP XML Export temp file
|
| 1163 |
unlink($this->tempdir.'wordpress.' . date( 'Y-m-d' ) . '.xml');
|
| 1164 |
}
|
| 1165 |
-
|
| 1166 |
if (empty($this->job['backupdir']) and is_file($this->backupdir.$this->backupfile)) { //delete backup file in temp dir
|
| 1167 |
unlink($this->backupdir.$this->backupfile);
|
| 1168 |
}
|
| 1169 |
-
|
| 1170 |
//delete old logs
|
| 1171 |
if (!empty($this->cfg['maxlogs'])) {
|
| 1172 |
-
if ( $dir = @opendir($this->logdir) ) { //make file list
|
| 1173 |
while (($file = readdir($dir)) !== false ) {
|
| 1174 |
if ('backwpup_log_' == substr($file,0,strlen('backwpup_log_')) and ".html" == substr($file,-5))
|
| 1175 |
$logfilelist[]=$file;
|
|
@@ -1186,8 +1191,8 @@ class backwpup_dojob {
|
|
| 1186 |
if ($numdeltefiles>0)
|
| 1187 |
trigger_error($numdeltefiles.' '.__('old Log files deleted!!!','backwpup'),E_USER_NOTICE);
|
| 1188 |
}
|
| 1189 |
-
}
|
| 1190 |
-
|
| 1191 |
$jobs=get_option('backwpup_jobs');
|
| 1192 |
$jobs[$this->jobid]['stoptime']=current_time('timestamp');
|
| 1193 |
$jobs[$this->jobid]['lastrun']=$jobs[$this->jobid]['starttime'];
|
|
@@ -1197,13 +1202,21 @@ class backwpup_dojob {
|
|
| 1197 |
|
| 1198 |
//write runtime header
|
| 1199 |
$fd=@fopen($backwpup_logfile,"r+");
|
|
|
|
| 1200 |
while (!feof($fd)) {
|
| 1201 |
$line=@fgets($fd);
|
| 1202 |
if (stripos($line,"<meta name=\"backwpup_jobruntime\"") !== false) {
|
| 1203 |
@fseek($fd,$filepos);
|
| 1204 |
@fputs($fd,str_pad("<meta name=\"backwpup_jobruntime\" content=\"".$jobs[$this->jobid]['lastruntime']."\" />",100)."\n");
|
| 1205 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1206 |
}
|
|
|
|
|
|
|
| 1207 |
$filepos=ftell($fd);
|
| 1208 |
}
|
| 1209 |
@fclose($fd);
|
|
@@ -1222,7 +1235,7 @@ class backwpup_dojob {
|
|
| 1222 |
if ($sendmail) {
|
| 1223 |
$mailbody=__("Jobname:","backwpup")." ".$logdata['name']."\n";
|
| 1224 |
$mailbody.=__("Jobtype:","backwpup")." ".$logdata['type']."\n";
|
| 1225 |
-
if (!empty($logdata['errors']))
|
| 1226 |
$mailbody.=__("Errors:","backwpup")." ".$logdata['errors']."\n";
|
| 1227 |
if (!empty($logdata['warnings']))
|
| 1228 |
$mailbody.=__("Warnings:","backwpup")." ".$logdata['warnings']."\n";
|
| 1 |
<?php
|
| 2 |
+
// don't load directly
|
| 3 |
+
if ( !defined('ABSPATH') )
|
| 4 |
die('-1');
|
| 5 |
|
| 6 |
+
|
| 7 |
+
//function for PHP error handling
|
| 8 |
function backwpup_joberrorhandler($errno, $errstr, $errfile, $errline) {
|
| 9 |
global $backwpup_logfile;
|
| 10 |
+
|
| 11 |
//genrate timestamp
|
| 12 |
if (!function_exists('memory_get_usage')) { // test if memory functions compiled in
|
| 13 |
$timestamp="<span style=\"background-color:c3c3c3;\" title=\"[Line: ".$errline."|File: ".basename($errfile)."\">".date_i18n('Y-m-d H:i.s').":</span> ";
|
| 14 |
} else {
|
| 15 |
if (version_compare(phpversion(), '5.2.0', '<'))
|
| 16 |
$timestamp="<span style=\"background-color:c3c3c3;\" title=\"[Line: ".$errline."|File: ".basename($errfile)."|Mem: ".backwpup_formatBytes(@memory_get_usage())."|Mem Max: ".backwpup_formatBytes(@memory_get_peak_usage())."|Mem Limit: ".ini_get('memory_limit')."]\">".date_i18n('Y-m-d H:i.s').":</span> ";
|
| 17 |
+
else
|
| 18 |
$timestamp="<span style=\"background-color:c3c3c3;\" title=\"[Line: ".$errline."|File: ".basename($errfile)."|Mem: ".backwpup_formatBytes(@memory_get_usage(true))."|Mem Max: ".backwpup_formatBytes(@memory_get_peak_usage(true))."|Mem Limit: ".ini_get('memory_limit')."]\">".date_i18n('Y-m-d H:i.s').":</span> ";
|
| 19 |
}
|
| 20 |
+
|
| 21 |
switch ($errno) {
|
| 22 |
case E_NOTICE:
|
| 23 |
case E_USER_NOTICE:
|
| 36 |
break;
|
| 37 |
case E_DEPRECATED:
|
| 38 |
case E_USER_DEPRECATED:
|
| 39 |
+
$massage=$timestamp."<span>".__('[DEPRECATED]','backwpup')." ".$errstr."</span>";
|
| 40 |
break;
|
| 41 |
case E_STRICT:
|
| 42 |
$massage=$timestamp."<span>".__('[STRICT NOTICE]','backwpup')." ".$errstr."</span>";
|
| 48 |
$massage=$timestamp."<span>[".$errno."] ".$errstr."</span>";
|
| 49 |
break;
|
| 50 |
}
|
| 51 |
+
|
| 52 |
if (!empty($massage)) {
|
| 53 |
//wirte log file
|
| 54 |
$fd=@fopen($backwpup_logfile,"a+");
|
| 55 |
@fputs($fd,$massage."<br />\n");
|
| 56 |
@fclose($fd);
|
| 57 |
+
|
| 58 |
+
//output on run now
|
| 59 |
if (!defined('DOING_CRON')) {
|
| 60 |
echo $massage."<script type=\"text/javascript\">window.scrollBy(0, 15);</script><br />\n";
|
| 61 |
@flush();
|
| 62 |
@ob_flush();
|
| 63 |
}
|
| 64 |
+
|
| 65 |
//write new log header
|
| 66 |
if (isset($errors) or isset($warnings)) {
|
| 67 |
$fd=@fopen($backwpup_logfile,"r+");
|
| 81 |
}
|
| 82 |
@fclose($fd);
|
| 83 |
}
|
| 84 |
+
|
| 85 |
if ($errno==E_ERROR or $errno==E_CORE_ERROR or $errno==E_COMPILE_ERROR) //Die on fatal php errors.
|
| 86 |
die();
|
| 87 |
+
|
| 88 |
|
| 89 |
@set_time_limit(300); //300 is most webserver time limit. 0= max time! Give script 5 min. more to work.
|
| 90 |
//true for no more php error hadling.
|
| 100 |
$logheader=backwpup_read_logheader($backwpup_logfile); //read waring count from log header
|
| 101 |
$cfg=get_option('backwpup'); //load config
|
| 102 |
$jobs=get_option('backwpup_jobs'); //load job options
|
| 103 |
+
|
| 104 |
if (!empty($jobs[$logheader['jobid']]['stoptime'])) //abort if job exits normaly
|
| 105 |
return;
|
| 106 |
+
|
| 107 |
+
backwpup_joberrorhandler(E_USER_WARNING, __('Job shutdown function is working! Please delete temp Backup files by hand.','backwpup'), __FILE__, __LINE__);
|
| 108 |
+
|
| 109 |
//try to get last error
|
| 110 |
$lasterror=error_get_last();
|
| 111 |
backwpup_joberrorhandler($lasterror['type'], __('Last ERROR:','backwpup').' '.$lasterror['message'], $lasterror['file'], $lasterror['line']);
|
| 112 |
+
|
| 113 |
//set Temp Dir
|
| 114 |
$tempdir=trailingslashit($cfg['dirtemp']);
|
| 115 |
+
if ($tempdir=='/')
|
| 116 |
$tempdir=backwpup_get_upload_dir();
|
| 117 |
+
|
| 118 |
if (is_file($tempdir.DB_NAME.'.sql') ) { //delete sql temp file
|
| 119 |
unlink($tempdir.DB_NAME.'.sql');
|
| 120 |
}
|
| 121 |
+
|
| 122 |
if (is_file($tempdir.'wordpress.' . date( 'Y-m-d' ) . '.xml') ) { //delete WP XML Export temp file
|
| 123 |
unlink($tempdir.'wordpress.' . date( 'Y-m-d' ) . '.xml');
|
| 124 |
}
|
| 125 |
+
|
| 126 |
$jobs[$logheader['jobid']]['stoptime']=current_time('timestamp');
|
| 127 |
$jobs[$logheader['jobid']]['lastrun']=$jobs[$logheader['jobid']]['starttime'];
|
| 128 |
$jobs[$logheader['jobid']]['lastruntime']=$jobs[$logheader['jobid']]['stoptime']-$jobs[$logheader['jobid']]['starttime'];
|
| 155 |
if ($sendmail) {
|
| 156 |
$mailbody=__("Jobname:","backwpup")." ".$logdata['name']."\n";
|
| 157 |
$mailbody.=__("Jobtype:","backwpup")." ".$logdata['type']."\n";
|
| 158 |
+
if (!empty($logdata['errors']))
|
| 159 |
$mailbody.=__("Errors:","backwpup")." ".$logdata['errors']."\n";
|
| 160 |
if (!empty($logdata['warnings']))
|
| 161 |
$mailbody.=__("Warnings:","backwpup")." ".$logdata['warnings']."\n";
|
| 162 |
wp_mail($jobs[$logheader['jobid']]['mailaddresslog'],__('BackWPup Log File from','backwpup').' '.date_i18n('Y-m-d H:i',$jobs[$logheader['jobid']]['starttime']).': '.$jobs[$logheader['jobid']]['name'] ,$mailbody,'',array($backwpup_logfile));
|
| 163 |
+
}
|
| 164 |
}
|
| 165 |
|
| 166 |
/**
|
| 168 |
*
|
| 169 |
*/
|
| 170 |
class backwpup_dojob {
|
| 171 |
+
|
| 172 |
private $jobid=0;
|
| 173 |
private $filelist=array();
|
| 174 |
private $tempfilelist=array();
|
| 182 |
private $tempdir='';
|
| 183 |
private $cfg=array();
|
| 184 |
private $job=array();
|
| 185 |
+
|
| 186 |
public function __construct($jobid) {
|
| 187 |
global $backwpup_logfile,$backwpup_dojob;
|
| 188 |
@ini_get('safe_mode','Off'); //disable safe mode
|
| 204 |
$this->backupfileformat=$this->job['fileformart'];
|
| 205 |
//set Temp Dir
|
| 206 |
$this->tempdir=trailingslashit($this->cfg['dirtemp']);
|
| 207 |
+
if (empty($this->tempdir) or $this->tempdir=='/')
|
| 208 |
$this->tempdir=backwpup_get_upload_dir();
|
| 209 |
//set Backup Dir
|
| 210 |
$this->backupdir=$this->job['backupdir'];
|
| 217 |
$this->logdir=str_replace('\\','/',trailingslashit(WP_CONTENT_DIR)).'backwpup-'.$rand.'-logs/';
|
| 218 |
}
|
| 219 |
//set Backup file name only for jos that makes backups
|
| 220 |
+
if (in_array('FILE',$this->todo) or in_array('DB',$this->todo) or in_array('WPEXP',$this->todo))
|
| 221 |
$this->backupfile='backwpup_'.$this->jobid.'_'.date_i18n('Y-m-d_H-i-s').$this->backupfileformat;
|
| 222 |
//set Log file name
|
| 223 |
+
$this->logfile='backwpup_log_'.date_i18n('Y-m-d_H-i-s').'.html';
|
| 224 |
$backwpup_logfile=$this->logdir.$this->logfile;
|
| 225 |
//Create log file
|
| 226 |
if (!$this->_check_folders($this->logdir))
|
| 234 |
@fputs($fd,"<meta name=\"backwpup_jobid\" content=\"".$this->jobid."\" />\n");
|
| 235 |
@fputs($fd,"<meta name=\"backwpup_jobname\" content=\"".$this->job['name']."\" />\n");
|
| 236 |
@fputs($fd,"<meta name=\"backwpup_jobtype\" content=\"".$this->job['type']."\" />\n");
|
| 237 |
+
if (!empty($this->backupfile))
|
| 238 |
+
@fputs($fd,"<meta name=\"backwpup_backupfile\" content=\"".$this->backupfile."\" />\n");
|
| 239 |
+
@fputs($fd,str_pad("<meta name=\"backwpup_backupfilesize\" content=\"0\" />",100)."\n");
|
| 240 |
@fputs($fd,str_pad("<meta name=\"backwpup_jobruntime\" content=\"0\" />",100)."\n");
|
| 241 |
@fputs($fd,"<title>".sprintf(__('BackWPup Log for %1$s from %2$s at %3$s','backwpup'),$this->job['name'],date_i18n(get_option('date_format')),date_i18n(get_option('time_format')))."</title>\n</head>\n<body style=\"font-family:monospace;font-size:12px;white-space:nowrap;\">\n");
|
| 242 |
@fclose($fd);
|
| 243 |
//set function for PHP user defineid error handling
|
| 244 |
if (defined(WP_DEBUG) and WP_DEBUG)
|
| 245 |
set_error_handler('backwpup_joberrorhandler',E_ALL | E_STRICT);
|
| 246 |
+
else
|
| 247 |
set_error_handler('backwpup_joberrorhandler',E_ALL & ~E_NOTICE);
|
| 248 |
//set a schutdown function.
|
| 249 |
register_shutdown_function('backwpup_jobshutdown');
|
| 253 |
return false;
|
| 254 |
}
|
| 255 |
//check max script execution tme
|
| 256 |
+
if (ini_get('safe_mode') or strtolower(ini_get('safe_mode'))=='on' or ini_get('safe_mode')=='1')
|
| 257 |
trigger_error(sprintf(__('PHP Safe Mode is on!!! Max exec time is %1$d sec.','backwpup'),ini_get('max_execution_time')),E_USER_WARNING);
|
| 258 |
// check function for memorylimit
|
| 259 |
if (!function_exists('memory_get_usage')) {
|
| 260 |
ini_set('memory_limit', apply_filters( 'admin_memory_limit', '256M' )); //Wordpress default
|
| 261 |
+
trigger_error(sprintf(__('Memory limit set to %1$s ,because can not use PHP: memory_get_usage() function to dynamically increase the Memory!','backwpup'),ini_get('memory_limit')),E_USER_WARNING);
|
| 262 |
}
|
| 263 |
//run job parts
|
| 264 |
foreach($this->todo as $key => $value) {
|
| 281 |
elseif ($this->backupfileformat==".tar.gz" or $this->backupfileformat==".tar.bz2" or $this->backupfileformat==".tar")
|
| 282 |
$this->tar_pack_files();
|
| 283 |
}
|
| 284 |
+
if (is_file($this->backupdir.$this->backupfile)) { // Put backup file to destination
|
| 285 |
$this->destination_mail();
|
| 286 |
$this->destination_ftp();
|
| 287 |
$this->destination_s3();
|
| 288 |
$this->destination_dir();
|
| 289 |
}
|
| 290 |
+
|
| 291 |
foreach($this->todo as $key => $value) {
|
| 292 |
switch ($value) {
|
| 293 |
case 'CHECK':
|
| 297 |
$this->optimize_db();
|
| 298 |
break;
|
| 299 |
}
|
| 300 |
+
}
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
private function _check_folders($folder) {
|
| 304 |
if (!is_dir($folder)) { //create dir if not exists
|
| 305 |
if (!mkdir($folder,0777,true)) {
|
| 308 |
}
|
| 309 |
}
|
| 310 |
if (!is_writeable($folder)) { //test if folder wirteable
|
| 311 |
+
trigger_error(sprintf(__('Can not write to Folder: %1$s','backwpup'),$folder),E_USER_ERROR);
|
| 312 |
+
return false;
|
| 313 |
}
|
| 314 |
//create .htaccess for apache and index.html for other
|
| 315 |
if (strtolower(substr($_SERVER["SERVER_SOFTWARE"],0,6))=="apache") { //check if it a apache webserver
|
| 324 |
if($file = fopen($folder.'index.html', 'w')) {
|
| 325 |
fwrite($file,"\n");
|
| 326 |
fclose($file);
|
| 327 |
+
}
|
| 328 |
}
|
| 329 |
if (!is_file($folder.'index.php')) {
|
| 330 |
if($file = fopen($folder.'index.php', 'w')) {
|
| 331 |
fwrite($file,"\n");
|
| 332 |
fclose($file);
|
| 333 |
+
}
|
| 334 |
}
|
| 335 |
}
|
| 336 |
return true;
|
| 337 |
}
|
| 338 |
+
|
| 339 |
private function need_free_memory($memneed) {
|
| 340 |
//fail back if fuction not exist
|
| 341 |
if (!function_exists('memory_get_usage'))
|
| 345 |
trigger_error(sprintf(__('PHP Safe Mode is on!!! Can not increase Memory Limit is %1$s','backwpup'),ini_get('memory_limit')),E_USER_WARNING);
|
| 346 |
return false;
|
| 347 |
}
|
| 348 |
+
|
| 349 |
//calc mem to bytes
|
| 350 |
if (strtoupper(substr(trim(ini_get('memory_limit')),-1))=='K')
|
| 351 |
$memory=trim(substr(ini_get('memory_limit'),0,-1))*1024;
|
| 355 |
$memory=trim(substr(ini_get('memory_limit'),0,-1))*1024*1024*1024;
|
| 356 |
else
|
| 357 |
$memory=trim(ini_get('memory_limit'));
|
| 358 |
+
|
| 359 |
//use real memory at php version 5.2.0
|
| 360 |
if (version_compare(phpversion(), '5.2.0', '<'))
|
| 361 |
$memnow=memory_get_usage();
|
| 362 |
+
else
|
| 363 |
$memnow=memory_get_usage(true);
|
| 364 |
+
|
| 365 |
//need memory
|
| 366 |
$needmemory=$memnow+$memneed;
|
| 367 |
+
|
| 368 |
+
// increase Memory
|
| 369 |
+
if ($needmemory>$memory) {
|
| 370 |
$newmemory=round($needmemory/1024/1024)+1;
|
| 371 |
+
if ($oldmem=ini_set('memory_limit', $newmemory.'M'))
|
| 372 |
trigger_error(sprintf(__('Memory increased from %1$s to %2$s','backwpup'),$oldmem,ini_get('memory_limit')),E_USER_NOTICE);
|
| 373 |
+
else
|
| 374 |
trigger_error(sprintf(__('Can not increase Memory Limit is %1$s','backwpup'),ini_get('memory_limit')),E_USER_WARNING);
|
| 375 |
}
|
| 376 |
+
return true;
|
| 377 |
}
|
| 378 |
+
|
| 379 |
private function maintenance_mode($enable = false) {
|
| 380 |
if (!$this->job['maintenance'])
|
| 381 |
return;
|
| 382 |
+
|
| 383 |
if ( $enable ) {
|
| 384 |
trigger_error(__('Set Blog to Maintenance Mode','backwpup'),E_USER_NOTICE);
|
| 385 |
if ( class_exists('WPMaintenanceMode') ) { //Support for WP Maintenance Mode Plugin
|
| 386 |
+
update_option('wp-maintenance-mode-msqld','1');
|
| 387 |
} elseif ( class_exists('MaintenanceMode') ) { //Support for Maintenance Mode Plugin
|
| 388 |
$mamo=get_option('plugin_maintenance-mode');
|
| 389 |
$mamo['mamo_activate']='on_'.current_time('timestamp');
|
| 390 |
$mamo['mamo_backtime_days']='0';
|
| 391 |
$mamo['mamo_backtime_hours']='0';
|
| 392 |
$mamo['mamo_backtime_mins']='5';
|
| 393 |
+
update_option('plugin_maintenance-mode',$mamo);
|
| 394 |
} else { //WP Support
|
| 395 |
$fdmain=fopen(trailingslashit(ABSPATH).'.maintenance','w');
|
| 396 |
fputs($fdmain,'<?php $upgrading = ' . time() . '; ?>');
|
| 397 |
+
fclose($fdmain);
|
| 398 |
}
|
| 399 |
} else {
|
| 400 |
trigger_error(__('Set Blog to normal Mode','backwpup'),E_USER_NOTICE);
|
| 401 |
if ( class_exists('WPMaintenanceMode') ) { //Support for WP Maintenance Mode Plugin
|
| 402 |
+
update_option('wp-maintenance-mode-msqld','0');
|
| 403 |
} elseif ( class_exists('MaintenanceMode') ) { //Support for Maintenance Mode Plugin
|
| 404 |
$mamo=get_option('plugin_maintenance-mode');
|
| 405 |
$mamo['mamo_activate']='off';
|
| 406 |
+
update_option('plugin_maintenance-mode',$mamo);
|
| 407 |
} else { //WP Support
|
| 408 |
@unlink(trailingslashit(ABSPATH).'.maintenance');
|
| 409 |
}
|
| 410 |
}
|
| 411 |
}
|
| 412 |
+
|
| 413 |
private function check_db() {
|
| 414 |
global $wpdb;
|
| 415 |
+
|
| 416 |
trigger_error(__('Run Database check...','backwpup'),E_USER_NOTICE);
|
| 417 |
+
|
| 418 |
$tables=$wpdb->get_col('SHOW TABLES FROM `'.DB_NAME.'`');
|
| 419 |
//exclude tables from check
|
| 420 |
foreach($tables as $tablekey => $tablevalue) {
|
| 421 |
if (in_array($tablevalue,$this->job['dbexclude']))
|
| 422 |
unset($tables[$tablekey]);
|
| 423 |
}
|
| 424 |
+
|
| 425 |
//check tables
|
| 426 |
if (sizeof($tables)>0) {
|
| 427 |
$this->maintenance_mode(true);
|
| 432 |
elseif ($check['Msg_type']=='warning')
|
| 433 |
trigger_error(sprintf(__('Result of table check for %1$s is: %2$s','backwpup'), $table, $check['Msg_text']),E_USER_WARNING);
|
| 434 |
else
|
| 435 |
+
trigger_error(sprintf(__('Result of table check for %1$s is: %2$s','backwpup'), $table, $check['Msg_text']),E_USER_NOTICE);
|
| 436 |
+
|
| 437 |
if ($sqlerr=mysql_error($wpdb->dbh)) //aditional SQL error
|
| 438 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), $sqlerr, $sqlerr->last_query),E_USER_ERROR);
|
| 439 |
//Try to Repair tabele
|
| 444 |
elseif ($repair['Msg_type']=='warning')
|
| 445 |
trigger_error(sprintf(__('Result of table repair for %1$s is: %2$s','backwpup'), $table, $repair['Msg_text']),E_USER_WARNING);
|
| 446 |
else
|
| 447 |
+
trigger_error(sprintf(__('Result of table repair for %1$s is: %2$s','backwpup'), $table, $repair['Msg_text']),E_USER_NOTICE);
|
| 448 |
+
|
| 449 |
if ($sqlerr=mysql_error($wpdb->dbh)) //aditional SQL error
|
| 450 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), $sqlerr, $sqlerr->last_query),E_USER_ERROR);
|
| 451 |
}
|
| 455 |
trigger_error(__('Database check done!','backwpup'),E_USER_NOTICE);
|
| 456 |
} else {
|
| 457 |
trigger_error(__('No Tables to check','backwpup'),E_USER_WARNING);
|
| 458 |
+
}
|
| 459 |
}
|
| 460 |
|
| 461 |
private function dump_db_table($table,$status,$file) {
|
| 465 |
fwrite($file, "--\n");
|
| 466 |
fwrite($file, "-- Table structure for table $table\n");
|
| 467 |
fwrite($file, "--\n\n");
|
| 468 |
+
fwrite($file, "DROP TABLE IF EXISTS `" . $table . "`;\n");
|
| 469 |
fwrite($file, "/*!40101 SET @saved_cs_client = @@character_set_client */;\n");
|
| 470 |
fwrite($file, "/*!40101 SET character_set_client = '".mysql_client_encoding()."' */;\n");
|
| 471 |
//Dump the table structure
|
| 477 |
$tablestruc=mysql_fetch_assoc($result);
|
| 478 |
fwrite($file, $tablestruc['Create Table'].";\n");
|
| 479 |
fwrite($file, "/*!40101 SET character_set_client = @saved_cs_client */;\n");
|
| 480 |
+
|
| 481 |
//take data of table
|
| 482 |
$result=mysql_query("SELECT * FROM `".$table."`");
|
| 483 |
if (!$result) {
|
| 484 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), mysql_error(), "SELECT * FROM `".$table."`"),E_USER_ERROR);
|
| 485 |
return false;
|
| 486 |
}
|
| 487 |
+
|
| 488 |
fwrite($file, "--\n");
|
| 489 |
fwrite($file, "-- Dumping data for table $table\n");
|
| 490 |
fwrite($file, "--\n\n");
|
| 492 |
if ($status['Engine']=='MyISAM')
|
| 493 |
fwrite($file, "/*!40000 ALTER TABLE `".$table."` DISABLE KEYS */;\n");
|
| 494 |
|
| 495 |
+
|
| 496 |
while ($data = mysql_fetch_assoc($result)) {
|
| 497 |
$keys = array();
|
| 498 |
$values = array();
|
| 523 |
global $wpdb;
|
| 524 |
trigger_error(__('Run Database Dump to file...','backwpup'),E_USER_NOTICE);
|
| 525 |
$this->maintenance_mode(true);
|
| 526 |
+
|
| 527 |
+
//Tables to backup
|
| 528 |
$tables=$wpdb->get_col('SHOW TABLES FROM `'.DB_NAME.'`');
|
| 529 |
+
if ($sqlerr=mysql_error($wpdb->dbh))
|
| 530 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), $sqlerr, "SHOW TABLES FROM `'.DB_NAME.'`"),E_USER_ERROR);
|
| 531 |
+
|
| 532 |
foreach($tables as $tablekey => $tablevalue) {
|
| 533 |
if (in_array($tablevalue,$this->job['dbexclude']))
|
| 534 |
unset($tables[$tablekey]);
|
| 535 |
}
|
| 536 |
sort($tables);
|
| 537 |
+
|
| 538 |
|
| 539 |
if (sizeof($tables)>0) {
|
| 540 |
$result=$wpdb->get_results("SHOW TABLE STATUS FROM `".DB_NAME."`;", ARRAY_A); //get table status
|
| 541 |
+
if ($sqlerr=mysql_error($wpdb->dbh))
|
| 542 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), $sqlerr, "SHOW TABLE STATUS FROM `".DB_NAME."`;"),E_USER_ERROR);
|
| 543 |
foreach($result as $statusdata) {
|
| 544 |
$status[$statusdata['Name']]=$statusdata;
|
| 550 |
fwrite($file, "-- Plugin for WordPress by Daniel Huesken\n");
|
| 551 |
fwrite($file, "-- http://danielhuesken.de/portfolio/backwpup/\n");
|
| 552 |
fwrite($file, "-- Blog Name: ".get_option('blogname')."\n");
|
| 553 |
+
if (defined('WP_SITEURL'))
|
| 554 |
fwrite($file, "-- Blog URL: ".trailingslashit(WP_SITEURL)."\n");
|
| 555 |
+
else
|
| 556 |
fwrite($file, "-- Blog URL: ".trailingslashit(get_option('siteurl'))."\n");
|
| 557 |
fwrite($file, "-- Blog ABSPATH: ".trailingslashit(ABSPATH)."\n");
|
| 558 |
fwrite($file, "-- Table Prefix: ".$wpdb->prefix."\n");
|
| 599 |
trigger_error(__('Add Database Dump to Backup:','backwpup').' '.DB_NAME.'.sql '.backwpup_formatBytes(filesize($this->tempdir.DB_NAME.'.sql')),E_USER_NOTICE);
|
| 600 |
$this->allfilesize+=filesize($this->tempdir.DB_NAME.'.sql');
|
| 601 |
$this->filelist[]=array(79001=>$this->tempdir.DB_NAME.'.sql',79003=>DB_NAME.'.sql');
|
| 602 |
+
|
| 603 |
$this->maintenance_mode(false);
|
| 604 |
+
}
|
| 605 |
+
|
| 606 |
+
|
| 607 |
|
| 608 |
private function export_wp() {
|
| 609 |
trigger_error(__('Run Wordpress Export to XML file...','backwpup'),E_USER_NOTICE);
|
| 616 |
} else {
|
| 617 |
trigger_error(__('Can not Export to XML!','backwpup'),E_USER_ERROR);
|
| 618 |
}
|
| 619 |
+
}
|
| 620 |
|
| 621 |
private function optimize_db() {
|
| 622 |
global $wpdb;
|
| 623 |
+
|
| 624 |
trigger_error(__('Run Database optimize...','backwpup'),E_USER_NOTICE);
|
| 625 |
+
|
| 626 |
$tables=$wpdb->get_col('SHOW TABLES FROM `'.DB_NAME.'`');
|
| 627 |
//exclude tables from optimize
|
| 628 |
foreach($tables as $tablekey => $tablevalue) {
|
| 629 |
if (in_array($tablevalue,$this->job['dbexclude']))
|
| 630 |
unset($tables[$tablekey]);
|
| 631 |
}
|
| 632 |
+
|
| 633 |
if (sizeof($tables)>0) {
|
| 634 |
$this->maintenance_mode(true);
|
| 635 |
foreach ($tables as $table) {
|
| 639 |
elseif ($optimize['Msg_type']=='warning')
|
| 640 |
trigger_error(sprintf(__('Result of table optimize for %1$s is: %2$s','backwpup'), $table, $optimize['Msg_text']),E_USER_WARNING);
|
| 641 |
else
|
| 642 |
+
trigger_error(sprintf(__('Result of table optimize for %1$s is: %2$s','backwpup'), $table, $optimize['Msg_text']),E_USER_NOTICE);
|
| 643 |
+
|
| 644 |
+
if ($sqlerr=mysql_error($wpdb->dbh))
|
| 645 |
trigger_error(sprintf(__('BackWPup database error %1$s for query %2$s','backwpup'), $sqlerr, $sqlerr->last_query),E_USER_ERROR);
|
| 646 |
}
|
| 647 |
$wpdb->flush();
|
| 649 |
$this->maintenance_mode(false);
|
| 650 |
} else {
|
| 651 |
trigger_error(__('No Tables to optimize','backwpup'),E_USER_WARNING);
|
| 652 |
+
}
|
| 653 |
}
|
| 654 |
|
| 655 |
private function _file_list_folder( $folder = '', $levels = 100, $excludes,$excludedirs=array()) {
|
| 680 |
}
|
| 681 |
}
|
| 682 |
@closedir( $dir );
|
| 683 |
+
}
|
| 684 |
}
|
| 685 |
+
|
| 686 |
private function file_list() {
|
| 687 |
|
| 688 |
//Make filelist
|
| 689 |
trigger_error(__('Make a list of files to Backup ....','backwpup'),E_USER_NOTICE);
|
| 690 |
+
|
| 691 |
$this->tempfilelist=array();
|
| 692 |
+
|
| 693 |
$backwpup_exclude=explode(',',trim($this->job['fileexclude']));
|
| 694 |
//Exclude Temp Files
|
| 695 |
$backwpup_exclude[]=$this->tempdir.DB_NAME.'.sql';
|
| 696 |
$backwpup_exclude[]=$this->tempdir.'wordpress.' . date( 'Y-m-d' ) . '.xml';
|
| 697 |
$backwpup_exclude=array_unique($backwpup_exclude,SORT_STRING);
|
| 698 |
+
|
| 699 |
//File list for blog folders
|
| 700 |
if ($this->job['backuproot'])
|
| 701 |
+
$this->_file_list_folder(untrailingslashit(str_replace('\\','/',ABSPATH)),100,$backwpup_exclude,array_merge($this->job['backuprootexcludedirs'],backwpup_get_exclude_wp_dirs(ABSPATH)));
|
| 702 |
if ($this->job['backupcontent'])
|
| 703 |
$this->_file_list_folder(untrailingslashit(str_replace('\\','/',WP_CONTENT_DIR)),100,$backwpup_exclude,array_merge($this->job['backupcontentexcludedirs'],backwpup_get_exclude_wp_dirs(WP_CONTENT_DIR)));
|
| 704 |
if ($this->job['backupplugins'])
|
| 705 |
$this->_file_list_folder(untrailingslashit(str_replace('\\','/',WP_PLUGIN_DIR)),100,$backwpup_exclude,array_merge($this->job['backuppluginsexcludedirs'],backwpup_get_exclude_wp_dirs(WP_PLUGIN_DIR)));
|
| 706 |
+
if ($this->job['backupthemes'])
|
| 707 |
$this->_file_list_folder(untrailingslashit(str_replace('\\','/',trailingslashit(WP_CONTENT_DIR).'themes')),100,$backwpup_exclude,array_merge($this->job['backupthemesexcludedirs'],backwpup_get_exclude_wp_dirs(trailingslashit(WP_CONTENT_DIR).'themes')));
|
| 708 |
if ($this->job['backupuploads'])
|
| 709 |
$this->_file_list_folder(untrailingslashit(backwpup_get_upload_dir()),100,$backwpup_exclude,array_merge($this->job['backupuploadsexcludedirs'],backwpup_get_exclude_wp_dirs(backwpup_get_upload_dir())));
|
| 710 |
+
|
| 711 |
+
//include dirs
|
| 712 |
$dirinclude=explode(',',$this->job['dirinclude']);
|
| 713 |
$dirinclude=array_unique($dirinclude,SORT_STRING);
|
| 714 |
//Crate file list
|
| 715 |
if (is_array($dirinclude)) {
|
| 716 |
foreach($dirinclude as $dirincludevalue) {
|
| 717 |
+
if (is_dir($dirincludevalue))
|
| 718 |
$this->_file_list_folder(untrailingslashit(str_replace('\\','/',$dirincludevalue)),100,$backwpup_exclude);
|
| 719 |
}
|
| 720 |
}
|
| 725 |
$this->filelist[]=array(79001=>$files,79003=>str_replace(str_replace('\\','/',trailingslashit(ABSPATH)),'',$files));
|
| 726 |
}
|
| 727 |
$this->tempfilelist=array();
|
| 728 |
+
|
| 729 |
if (!is_array($this->filelist[0])) {
|
| 730 |
trigger_error(__('No files to Backup','backwpup'),E_USER_ERROR);
|
| 731 |
} else {
|
| 732 |
trigger_error(__('Size off all files:','backwpup').' '.backwpup_formatBytes($this->allfilesize),E_USER_NOTICE);
|
| 733 |
}
|
| 734 |
+
|
| 735 |
+
}
|
| 736 |
|
| 737 |
private function zip_files() {
|
| 738 |
+
|
| 739 |
if (class_exists('ZipArchive')) { //use php zip lib
|
| 740 |
trigger_error(__('Create Backup Zip file...','backwpup'),E_USER_NOTICE);
|
| 741 |
$zip = new ZipArchive;
|
| 742 |
if ($res=$zip->open($this->backupdir.$this->backupfile,ZIPARCHIVE::CREATE) === TRUE) {
|
| 743 |
+
foreach($this->filelist as $key => $files) {
|
| 744 |
if (!is_file($files[79001])) //check file exists
|
| 745 |
continue;
|
| 746 |
if ($zip->addFile($files[79001], $files[79003])) {
|
| 754 |
} else {
|
| 755 |
trigger_error(__('Can not create Backup ZIP file:','backwpup').' '.$res,E_USER_ERROR);
|
| 756 |
}
|
| 757 |
+
|
| 758 |
} else { //use PclZip
|
| 759 |
define( 'PCLZIP_TEMPORARY_DIR', $this->tempdir );
|
| 760 |
+
if (!class_exists('PclZip'))
|
| 761 |
require_once (plugin_dir_path(__FILE__).'libs/pclzip.lib.php');
|
| 762 |
+
|
| 763 |
//Create Zip File
|
| 764 |
if (is_array($this->filelist[0])) {
|
| 765 |
$this->need_free_memory(10485760); //10MB free memory for zip
|
| 766 |
trigger_error(__('Create Backup Zip (PclZip) file...','backwpup'),E_USER_NOTICE);
|
| 767 |
foreach($this->filelist as $key => $files) {
|
| 768 |
trigger_error(__('Add File to ZIP file:','backwpup').' '.$files[79001].' '.backwpup_formatBytes(filesize($files[79001])),E_USER_NOTICE);
|
| 769 |
+
}
|
| 770 |
$zipbackupfile = new PclZip($this->backupdir.$this->backupfile);
|
| 771 |
if (0==$zipbackupfile -> create($this->filelist,PCLZIP_OPT_ADD_TEMP_FILE_ON)) {
|
| 772 |
trigger_error(__('Zip file create:','backwpup').' '.$zipbackupfile->errorInfo(true),E_USER_ERROR);
|
| 773 |
+
} else {
|
| 774 |
trigger_error(__('Backup Zip file create done!','backwpup'),E_USER_NOTICE);
|
| 775 |
}
|
| 776 |
}
|
| 777 |
}
|
| 778 |
}
|
| 779 |
+
|
| 780 |
private function tar_pack_files() {
|
| 781 |
+
|
| 782 |
if ($this->backupfileformat=='.tar.gz') {
|
| 783 |
$tarbackup=gzopen($this->backupdir.$this->backupfile,'w9');
|
| 784 |
} elseif ($this->backupfileformat=='.tar.bz2') {
|
| 786 |
} else {
|
| 787 |
$tarbackup=fopen($this->backupdir.$this->backupfile,'w');
|
| 788 |
}
|
| 789 |
+
|
| 790 |
if (!$tarbackup) {
|
| 791 |
trigger_error(__('Can not create TAR Backup file','backwpup'),E_USER_ERROR);
|
| 792 |
return;
|
| 793 |
} else {
|
| 794 |
trigger_error(__('Create Backup Archive file...','backwpup'),E_USER_NOTICE);
|
| 795 |
}
|
| 796 |
+
|
| 797 |
$this->need_free_memory(1048576); //1MB free memory for zip
|
| 798 |
+
|
| 799 |
foreach($this->filelist as $key => $files) {
|
| 800 |
trigger_error(__('Add File to Backup Archive:','backwpup').' '.$files[79001].' '.backwpup_formatBytes(filesize($files[79001])),E_USER_NOTICE);
|
| 801 |
+
|
| 802 |
//check file exists
|
| 803 |
if (!is_file($files[79001]))
|
| 804 |
continue;
|
| 805 |
+
|
| 806 |
// Get file information
|
| 807 |
$file_information = stat($files[79001]);
|
| 808 |
|
| 825 |
"", //device minor number 8
|
| 826 |
substr($files[79003],101), //prefix for file name 155
|
| 827 |
""); //fill block 512K
|
| 828 |
+
|
| 829 |
// Computes the unsigned Checksum of a file's header
|
| 830 |
$checksum = 0;
|
| 831 |
for ($i = 0; $i < 512; $i++)
|
| 832 |
$checksum += ord(substr($header, $i, 1));
|
| 833 |
$checksum = pack("a8", sprintf("%07o", $checksum));
|
| 834 |
+
|
| 835 |
$header = substr_replace($header, $checksum, 148, 8);
|
| 836 |
+
|
| 837 |
if ($this->backupfileformat=='.tar.gz') {
|
| 838 |
gzwrite($tarbackup, $header);
|
| 839 |
} elseif ($this->backupfileformat=='.tar.bz2') {
|
| 841 |
} else {
|
| 842 |
fwrite($tarbackup, $header);
|
| 843 |
}
|
| 844 |
+
|
| 845 |
// read/write files in 512K Blocks
|
| 846 |
$fd=fopen($files[79001],'rb');
|
| 847 |
while(!feof($fd)) {
|
| 858 |
}
|
| 859 |
fclose($fd);
|
| 860 |
}
|
| 861 |
+
|
| 862 |
+
|
| 863 |
if ($this->backupfileformat=='.tar.gz') {
|
| 864 |
gzwrite($tarbackup, pack("a1024", "")); // Add 1024 bytes of NULLs to designate EOF
|
| 865 |
+
gzclose($tarbackup);
|
| 866 |
} elseif ($this->backupfileformat=='.tar.bz2') {
|
| 867 |
bzwrite($tarbackup, pack("a1024", "")); // Add 1024 bytes of NULLs to designate EOF
|
| 868 |
bzclose($tarbackup);
|
| 869 |
} else {
|
| 870 |
fwrite($tarbackup, pack("a1024", "")); // Add 1024 bytes of NULLs to designate EOF
|
| 871 |
+
fclose($tarbackup);
|
| 872 |
}
|
| 873 |
+
|
| 874 |
trigger_error(__('Backup Archive file create done!','backwpup'),E_USER_NOTICE);
|
| 875 |
}
|
| 876 |
+
|
| 877 |
+
|
| 878 |
private function _ftp_raw_helper($ftp_conn_id,$command) { //FTP Comands helper function
|
| 879 |
$return=ftp_raw($ftp_conn_id,$command);
|
| 880 |
if (strtoupper(substr(trim($command),0,4))=="PASS") {
|
| 902 |
}
|
| 903 |
}
|
| 904 |
}
|
| 905 |
+
|
| 906 |
+
|
| 907 |
private function destination_ftp() {
|
| 908 |
+
|
| 909 |
+
if (empty($this->job['ftphost']) or empty($this->job['ftpuser']) or empty($this->job['ftppass']))
|
| 910 |
return false;
|
| 911 |
+
|
| 912 |
$ftpport=21;
|
| 913 |
$ftphost=$this->job['ftphost'];
|
| 914 |
if (false !== strpos($this->job['ftphost'],':')) //look for port
|
| 916 |
|
| 917 |
if (function_exists('ftp_ssl_connect')) { //make SSL FTP connection
|
| 918 |
$ftp_conn_id = ftp_ssl_connect($ftphost,$ftpport,10);
|
| 919 |
+
if ($ftp_conn_id)
|
| 920 |
trigger_error(__('Connected by SSL to FTP server:','backwpup').' '.$this->job['ftphost'],E_USER_NOTICE);
|
|
|
|
| 921 |
}
|
| 922 |
if (!$ftp_conn_id) { //make normal FTP conection if SSL not work
|
| 923 |
$ftp_conn_id = ftp_connect($ftphost,$ftpport,10);
|
| 924 |
+
if ($ftp_conn_id)
|
| 925 |
trigger_error(__('Connected insecure to FTP server:','backwpup').' '.$this->job['ftphost'],E_USER_NOTICE);
|
|
|
|
| 926 |
}
|
| 927 |
+
|
| 928 |
if (!$ftp_conn_id) {
|
| 929 |
trigger_error(__('Can not connect to FTP server:','backwpup').' '.$this->job['ftphost'],E_USER_ERROR);
|
| 930 |
return false;
|
| 942 |
}
|
| 943 |
}
|
| 944 |
}
|
| 945 |
+
|
| 946 |
//if (ftp_login($ftp_conn_id, $jobs[$jobid]['ftpuser'], $jobs[$jobid]['ftppass'])) {
|
| 947 |
+
if (!$loginok)
|
| 948 |
return false;
|
| 949 |
+
|
| 950 |
//SYSTYPE
|
| 951 |
$this->_ftp_raw_helper($ftp_conn_id,'SYST');
|
| 952 |
//PASV
|
| 953 |
trigger_error(__('FTP Client command:','backwpup').' PASV',E_USER_NOTICE);
|
| 954 |
if (ftp_pasv($ftp_conn_id, true))
|
| 955 |
trigger_error(__('Server Completion reply: 227 Entering Passive Mode','backwpup'),E_USER_NOTICE);
|
| 956 |
+
else
|
| 957 |
trigger_error(__('FTP Server reply:','backwpup').' '.__('Can not Entering Passive Mode','backwpup'),E_USER_WARNING);
|
| 958 |
//ALLO show no erros in log if do not work
|
| 959 |
trigger_error(__('FTP Client command:','backwpup').' ALLO',E_USER_NOTICE);
|
| 960 |
ftp_alloc($ftp_conn_id,filesize($this->backupdir.$this->backupfile),$result);
|
| 961 |
trigger_error(__('FTP Server reply:','backwpup').' '.$result,E_USER_NOTICE);
|
| 962 |
+
|
| 963 |
//test ftp dir and create it f not exists
|
| 964 |
$ftpdirs=explode("/", untrailingslashit($this->job['ftpdir']));
|
| 965 |
foreach ($ftpdirs as $ftpdir) {
|
| 966 |
if (empty($ftpdir))
|
| 967 |
continue;
|
| 968 |
if (!@ftp_chdir($ftp_conn_id, $ftpdir)) {
|
| 969 |
+
trigger_error('"'.$ftpdir.'" '.__('FTP Folder on Server not exists!','backwpup'),E_USER_WARNING);
|
| 970 |
if (@ftp_mkdir($ftp_conn_id, $ftpdir)) {
|
| 971 |
+
trigger_error('"'.$ftpdir.'" '.__('FTP Folder created!','backwpup'),E_USER_NOTICE);
|
| 972 |
ftp_chdir($ftp_conn_id, $ftpdir);
|
| 973 |
} else {
|
| 974 |
+
trigger_error('"'.$ftpdir.'" '.__('FTP Folder on Server can not created!','backwpup'),E_USER_ERROR);
|
| 975 |
}
|
| 976 |
}
|
| 977 |
}
|
| 978 |
+
|
| 979 |
if (ftp_put($ftp_conn_id, $this->job['ftpdir'].$this->backupfile, $this->backupdir.$this->backupfile, FTP_BINARY)) //transfere file
|
| 980 |
trigger_error(__('Backup File transferred to FTP Server:','backwpup').' '.$this->job['ftpdir'].$this->backupfile,E_USER_NOTICE);
|
| 981 |
else
|
| 982 |
trigger_error(__('Can not transfer backup to FTP server.','backwpup'),E_USER_ERROR);
|
| 983 |
+
|
| 984 |
if ($this->job['ftpmaxbackups']>0) { //Delete old backups
|
| 985 |
$backupfilelist=array();
|
| 986 |
if ($filelist=ftp_nlist($ftp_conn_id, $this->job['ftpdir'])) {
|
| 994 |
for ($i=$this->job['ftpmaxbackups'];$i<sizeof($backupfilelist);$i++) {
|
| 995 |
if (ftp_delete($ftp_conn_id, $this->job['ftpdir'].$backupfilelist[$i])) //delte files on ftp
|
| 996 |
$numdeltefiles++;
|
| 997 |
+
else
|
| 998 |
trigger_error(__('Can not delete file on FTP Server:','backwpup').' '.$this->job['ftpdir'].$backupfilelist[$i],E_USER_ERROR);
|
| 999 |
}
|
| 1000 |
if ($numdeltefiles>0)
|
| 1002 |
}
|
| 1003 |
}
|
| 1004 |
}
|
| 1005 |
+
ftp_close($ftp_conn_id);
|
| 1006 |
|
| 1007 |
+
}
|
| 1008 |
|
| 1009 |
private function destination_mail() {
|
| 1010 |
if (empty($this->job['mailaddress']))
|
| 1011 |
return false;
|
| 1012 |
+
|
| 1013 |
+
trigger_error(__('Prepare Sending backup file with mail...','backwpup'),E_USER_NOTICE);
|
| 1014 |
+
|
| 1015 |
//Crate PHP Mailer
|
| 1016 |
require_once(ABSPATH.WPINC.'/class-phpmailer.php');
|
| 1017 |
require_once(ABSPATH.WPINC.'/class-smtp.php');
|
| 1039 |
$phpmailer->IsMail();
|
| 1040 |
trigger_error(__('Send mail with PHP mail','backwpup'),E_USER_NOTICE);
|
| 1041 |
}
|
| 1042 |
+
|
| 1043 |
|
| 1044 |
trigger_error(__('Creating mail','backwpup'),E_USER_NOTICE);
|
| 1045 |
$phpmailer->From = $this->cfg['mailsndemail'];
|
| 1046 |
$phpmailer->FromName = $this->cfg['mailsndname'];
|
| 1047 |
+
$phpmailer->AddAddress($this->job['mailaddress']);
|
| 1048 |
$phpmailer->Subject = __('BackWPup File from','backwpup').' '.date_i18n('Y-m-d H:i',$this->job['starttime']).': '.$this->job['name'];
|
| 1049 |
$phpmailer->IsHTML(false);
|
| 1050 |
$phpmailer->Body = 'Backup File';
|
| 1051 |
+
|
| 1052 |
//check file Size
|
| 1053 |
if (!empty($this->job['mailefilesize'])) {
|
| 1054 |
$maxfilezise=abs($this->job['mailefilesize']*1024*1024);
|
| 1057 |
return false;
|
| 1058 |
}
|
| 1059 |
}
|
| 1060 |
+
|
| 1061 |
trigger_error(__('Adding Attachment to mail','backwpup'),E_USER_NOTICE);
|
| 1062 |
$this->need_free_memory(filesize($this->backupdir.$this->backupfile)*5);
|
| 1063 |
+
$phpmailer->AddAttachment($this->backupdir.$this->backupfile);
|
| 1064 |
+
|
| 1065 |
trigger_error(__('Send mail....','backwpup'),E_USER_NOTICE);
|
| 1066 |
if (false == $phpmailer->Send()) {
|
| 1067 |
trigger_error(__('Can not send mail:','backwpup').' '.$phpmailer->ErrorInfo,E_USER_ERROR);
|
| 1068 |
} else {
|
| 1069 |
trigger_error(__('Mail send!!!','backwpup'),E_USER_NOTICE);
|
| 1070 |
+
}
|
| 1071 |
+
|
| 1072 |
}
|
| 1073 |
|
| 1074 |
private function destination_s3() {
|
| 1075 |
+
|
| 1076 |
+
if (empty($this->job['awsAccessKey']) or empty($this->job['awsSecretKey']) or empty($this->job['awsBucket']))
|
| 1077 |
return false;
|
| 1078 |
|
| 1079 |
if (!(extension_loaded('curl') or @dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll'))) {
|
| 1081 |
return false;
|
| 1082 |
}
|
| 1083 |
|
| 1084 |
+
if (!class_exists('S3'))
|
| 1085 |
require_once(plugin_dir_path(__FILE__).'libs/S3.php');
|
| 1086 |
+
|
| 1087 |
$s3 = new S3($this->job['awsAccessKey'], $this->job['awsSecretKey'], $this->job['awsSSL']);
|
| 1088 |
|
| 1089 |
if (in_array($this->job['awsBucket'],$s3->listBuckets())) {
|
| 1093 |
trigger_error(__('Backup File transferred to S3://','backwpup').$this->job['awsBucket'].'/'.$this->job['awsdir'].$this->backupfile,E_USER_NOTICE);
|
| 1094 |
else
|
| 1095 |
trigger_error(__('Can not transfer backup to S3.','backwpup'),E_USER_ERROR);
|
| 1096 |
+
|
| 1097 |
if ($this->job['awsmaxbackups']>0) { //Delete old backups
|
| 1098 |
$backupfilelist=array();
|
| 1099 |
if (($contents = $s3->getBucket($this->job['awsBucket'],$this->job['awsdir'])) !== false) {
|
| 1111 |
for ($i=$this->job['awsmaxbackups'];$i<sizeof($backupfilelist);$i++) {
|
| 1112 |
if ($s3->deleteObject($this->job['awsBucket'], $this->job['awsdir'].$backupfilelist[$i])) //delte files on S3
|
| 1113 |
$numdeltefiles++;
|
| 1114 |
+
else
|
| 1115 |
trigger_error(__('Can not delete file on S3//:','backwpup').$this->job['awsBucket'].'/'.$this->job['awsdir'].$backupfilelist[$i],E_USER_ERROR);
|
| 1116 |
}
|
| 1117 |
if ($numdeltefiles>0)
|
| 1129 |
//Delete old Backupfiles
|
| 1130 |
$backupfilelist=array();
|
| 1131 |
if (!empty($this->job['maxbackups'])) {
|
| 1132 |
+
if ( $dir = @opendir($this->job['backupdir']) ) { //make file list
|
| 1133 |
while (($file = readdir($dir)) !== false ) {
|
| 1134 |
if ('backwpup_'.$this->jobid.'_' == substr($file,0,strlen('backwpup_'.$this->jobid.'_')) and $this->backupfileformat == substr($file,-strlen($this->backupfileformat)))
|
| 1135 |
$backupfilelist[]=$file;
|
| 1148 |
}
|
| 1149 |
}
|
| 1150 |
}
|
| 1151 |
+
|
| 1152 |
public function __destruct() {
|
| 1153 |
global $backwpup_logfile;
|
| 1154 |
+
|
| 1155 |
if (is_file($this->backupdir.$this->backupfile)) {
|
| 1156 |
+
$filesize=filesize($this->backupdir.$this->backupfile);
|
| 1157 |
+
trigger_error(sprintf(__('Backup Archive File size is %1s','backwpup'),backwpup_formatBytes($filesize)),E_USER_NOTICE);
|
| 1158 |
}
|
| 1159 |
|
| 1160 |
+
if (empty($filesize)) //Set the filezie corectly
|
| 1161 |
+
$filesize=0;
|
| 1162 |
+
|
| 1163 |
if (is_file($this->tempdir.DB_NAME.'.sql') ) { //delete sql temp file
|
| 1164 |
unlink($this->tempdir.DB_NAME.'.sql');
|
| 1165 |
}
|
| 1166 |
+
|
| 1167 |
if (is_file($this->tempdir.'wordpress.' . date( 'Y-m-d' ) . '.xml') ) { //delete WP XML Export temp file
|
| 1168 |
unlink($this->tempdir.'wordpress.' . date( 'Y-m-d' ) . '.xml');
|
| 1169 |
}
|
| 1170 |
+
|
| 1171 |
if (empty($this->job['backupdir']) and is_file($this->backupdir.$this->backupfile)) { //delete backup file in temp dir
|
| 1172 |
unlink($this->backupdir.$this->backupfile);
|
| 1173 |
}
|
| 1174 |
+
|
| 1175 |
//delete old logs
|
| 1176 |
if (!empty($this->cfg['maxlogs'])) {
|
| 1177 |
+
if ( $dir = @opendir($this->logdir) ) { //make file list
|
| 1178 |
while (($file = readdir($dir)) !== false ) {
|
| 1179 |
if ('backwpup_log_' == substr($file,0,strlen('backwpup_log_')) and ".html" == substr($file,-5))
|
| 1180 |
$logfilelist[]=$file;
|
| 1191 |
if ($numdeltefiles>0)
|
| 1192 |
trigger_error($numdeltefiles.' '.__('old Log files deleted!!!','backwpup'),E_USER_NOTICE);
|
| 1193 |
}
|
| 1194 |
+
}
|
| 1195 |
+
|
| 1196 |
$jobs=get_option('backwpup_jobs');
|
| 1197 |
$jobs[$this->jobid]['stoptime']=current_time('timestamp');
|
| 1198 |
$jobs[$this->jobid]['lastrun']=$jobs[$this->jobid]['starttime'];
|
| 1202 |
|
| 1203 |
//write runtime header
|
| 1204 |
$fd=@fopen($backwpup_logfile,"r+");
|
| 1205 |
+
$found=0;
|
| 1206 |
while (!feof($fd)) {
|
| 1207 |
$line=@fgets($fd);
|
| 1208 |
if (stripos($line,"<meta name=\"backwpup_jobruntime\"") !== false) {
|
| 1209 |
@fseek($fd,$filepos);
|
| 1210 |
@fputs($fd,str_pad("<meta name=\"backwpup_jobruntime\" content=\"".$jobs[$this->jobid]['lastruntime']."\" />",100)."\n");
|
| 1211 |
+
$found++;
|
| 1212 |
+
}
|
| 1213 |
+
if (stripos($line,"<meta name=\"backwpup_backupfilesize\"") !== false) {
|
| 1214 |
+
@fseek($fd,$filepos);
|
| 1215 |
+
@fputs($fd,str_pad("<meta name=\"backwpup_backupfilesize\" content=\"".$filesize."\" />",100)."\n");
|
| 1216 |
+
$found++;
|
| 1217 |
}
|
| 1218 |
+
if ($found>=2)
|
| 1219 |
+
break;
|
| 1220 |
$filepos=ftell($fd);
|
| 1221 |
}
|
| 1222 |
@fclose($fd);
|
| 1235 |
if ($sendmail) {
|
| 1236 |
$mailbody=__("Jobname:","backwpup")." ".$logdata['name']."\n";
|
| 1237 |
$mailbody.=__("Jobtype:","backwpup")." ".$logdata['type']."\n";
|
| 1238 |
+
if (!empty($logdata['errors']))
|
| 1239 |
$mailbody.=__("Errors:","backwpup")." ".$logdata['errors']."\n";
|
| 1240 |
if (!empty($logdata['warnings']))
|
| 1241 |
$mailbody.=__("Warnings:","backwpup")." ".$logdata['warnings']."\n";
|
app/css/options.css
CHANGED
|
@@ -1,12 +1,12 @@
|
|
| 1 |
-
.column-id {
|
| 2 |
-
width:40px;text-align:center;
|
| 3 |
-
}
|
| 4 |
-
.column-runtime, .column-last, .column-next , .column-status {
|
| 5 |
-
width:125px;
|
| 6 |
-
}
|
| 7 |
-
.column-type {
|
| 8 |
-
width:125px;
|
| 9 |
-
}
|
| 10 |
-
.column-size {
|
| 11 |
-
width:75px;
|
| 12 |
}
|
| 1 |
+
.column-id {
|
| 2 |
+
width:40px;text-align:center;
|
| 3 |
+
}
|
| 4 |
+
.column-runtime, .column-last, .column-next , .column-status {
|
| 5 |
+
width:125px;
|
| 6 |
+
}
|
| 7 |
+
.column-type {
|
| 8 |
+
width:125px;
|
| 9 |
+
}
|
| 10 |
+
.column-size {
|
| 11 |
+
width:75px;
|
| 12 |
}
|
app/functions.php
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
<?PHP
|
| 2 |
-
// don't load directly
|
| 3 |
-
if ( !defined('ABSPATH') )
|
| 4 |
die('-1');
|
| 5 |
-
|
| 6 |
//Thems Option menu entry
|
| 7 |
function backwpup_menu_entry() {
|
| 8 |
$hook = add_management_page(__('BackWPup','backwpup'), __('BackWPup','backwpup'), '10', 'BackWPup','backwpup_options_page') ;
|
|
@@ -10,6 +10,7 @@ if ( !defined('ABSPATH') )
|
|
| 10 |
add_contextual_help($hook,backwpup_show_help());
|
| 11 |
switch($_REQUEST['action']) {
|
| 12 |
case 'logs':
|
|
|
|
| 13 |
register_column_headers($hook,array('cb'=>'<input type="checkbox" />','id'=>__('Job','backwpup'),'type'=>__('Type','backwpup'),'log'=>__('Backup/Log Date/Time','backwpup'),'status'=>__('Status','backwpup'),'size'=>__('Size','backwpup'),'runtime'=>__('Runtime','backwpup')));
|
| 14 |
break;
|
| 15 |
case 'edit':
|
|
@@ -18,18 +19,24 @@ if ( !defined('ABSPATH') )
|
|
| 18 |
break;
|
| 19 |
case 'tools':
|
| 20 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
case 'runnow':
|
| 22 |
add_action('load-'.$hook, 'backwpup_send_no_cache_header');
|
| 23 |
add_action('admin_head-'.$hook, 'backwpup_meta_no_cache');
|
| 24 |
break;
|
| 25 |
case 'view_log':
|
| 26 |
break;
|
|
|
|
|
|
|
| 27 |
default:
|
| 28 |
register_column_headers($hook,array('cb'=>'<input type="checkbox" />','id'=>__('ID','backwpup'),'jobname'=>__('Job Name','backwpup'),'type'=>__('Type','backwpup'),'next'=>__('Next Run','backwpup'),'last'=>__('Last Run','backwpup')));
|
| 29 |
break;
|
| 30 |
}
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
// Help too display
|
| 34 |
function backwpup_show_help() {
|
| 35 |
$help .= '<div class="metabox-prefs">';
|
|
@@ -42,20 +49,20 @@ if ( !defined('ABSPATH') )
|
|
| 42 |
var flattr_btn = 'compact';
|
| 43 |
var flattr_url = 'http://danielhuesken.de/portfolio/backwpup/';
|
| 44 |
</script><script src=\"http://api.flattr.com/button/load.js\" type=\"text/javascript\"></script>";
|
| 45 |
-
$help .= "</div>\n";
|
| 46 |
$help .= '<div class="metabox-prefs">';
|
| 47 |
$help .= __('Version:', 'backwpup').' '.BACKWPUP_VERSION.' | ';
|
| 48 |
$help .= __('Author:', 'backwpup').' <a href="http://danielhuesken.de" target="_blank">Daniel Hüsken</a>';
|
| 49 |
$help .= "</div>\n";
|
| 50 |
return $help;
|
| 51 |
}
|
| 52 |
-
|
| 53 |
//Options Page
|
| 54 |
function backwpup_options_page() {
|
| 55 |
global $wpdb,$backwpup_message,$page_hook;
|
| 56 |
-
if (!current_user_can(10))
|
| 57 |
wp_die('No rights');
|
| 58 |
-
if(!empty($backwpup_message))
|
| 59 |
echo '<div id="message" class="updated fade"><p><strong>'.$backwpup_message.'</strong></p></div>';
|
| 60 |
switch($_REQUEST['action']) {
|
| 61 |
case 'edit':
|
|
@@ -75,6 +82,9 @@ if ( !defined('ABSPATH') )
|
|
| 75 |
case 'tools':
|
| 76 |
require_once(plugin_dir_path(__FILE__).'options-tools.php');
|
| 77 |
break;
|
|
|
|
|
|
|
|
|
|
| 78 |
case 'runnow':
|
| 79 |
$jobid = (int) $_GET['jobid'];
|
| 80 |
check_admin_referer('runnow-job_' . $jobid);
|
|
@@ -89,13 +99,13 @@ if ( !defined('ABSPATH') )
|
|
| 89 |
$jobs=get_option('backwpup_jobs');
|
| 90 |
require_once(plugin_dir_path(__FILE__).'options.php');
|
| 91 |
break;
|
| 92 |
-
}
|
| 93 |
}
|
| 94 |
-
|
| 95 |
//Options Page
|
| 96 |
function backwpup_options_load() {
|
| 97 |
global $wpdb,$backwpup_message;
|
| 98 |
-
if (!current_user_can(10))
|
| 99 |
wp_die('No rights');
|
| 100 |
//Css for Admin Section
|
| 101 |
wp_enqueue_style('BackWpup',plugins_url('css/options.css',__FILE__),'',BACKWPUP_VERSION,'screen');
|
|
@@ -103,7 +113,7 @@ if ( !defined('ABSPATH') )
|
|
| 103 |
//For save Options
|
| 104 |
require_once(plugin_dir_path(__FILE__).'options-save.php');
|
| 105 |
}
|
| 106 |
-
|
| 107 |
//delete Otions
|
| 108 |
function backwpup_plugin_uninstall() {
|
| 109 |
delete_option('backwpup');
|
|
@@ -124,39 +134,39 @@ if ( !defined('ABSPATH') )
|
|
| 124 |
$jobsettings['type']=implode('+',$todo);
|
| 125 |
if (empty($jobsettings['type']))
|
| 126 |
$jobsettings['type']='DB+FILE';
|
| 127 |
-
|
| 128 |
if (empty($jobsettings['name']) or !is_string($jobsettings['name']))
|
| 129 |
$jobsettings['name']= __('New');
|
| 130 |
-
|
| 131 |
-
if (!isset($jobsettings['activated']) or !is_bool($jobsettings['activated']))
|
| 132 |
$jobsettings['activated']=false;
|
| 133 |
-
|
| 134 |
if (!isset($jobsettings['scheduletime']) or !is_numeric($jobsettings['scheduletime']))
|
| 135 |
$jobsettings['scheduletime']=current_time('timestamp');
|
| 136 |
-
|
| 137 |
-
if (!isset($jobsettings['scheduleintervaltype']) or !is_int($jobsettings['scheduleintervaltype']))
|
| 138 |
$jobsettings['scheduleintervaltype']=3600;
|
| 139 |
if ($jobsettings['scheduleintervaltype']!=60 and $jobsettings['scheduleintervaltype']!=3600 and $jobsettings['scheduleintervaltype']!=86400)
|
| 140 |
$jobsettings['scheduleintervaltype']=3600;
|
| 141 |
-
|
| 142 |
if (!isset($jobsettings['scheduleintervalteimes']) or !is_int($jobsettings['scheduleintervalteimes']) or ($jobsettings['scheduleintervalteimes']<1 and $jobsettings['scheduleintervalteimes']>100))
|
| 143 |
$jobsettings['scheduleintervalteimes']=1;
|
| 144 |
-
|
| 145 |
$jobsettings['scheduleinterval']=$jobsettings['scheduleintervaltype']*$jobsettings['scheduleintervalteimes'];
|
| 146 |
-
|
| 147 |
if (!is_string($jobsettings['mailaddresslog']) or false === $pos=strpos($jobsettings['mailaddresslog'],'@') or false === strpos($jobsettings['mailaddresslog'],'.',$pos))
|
| 148 |
$jobsettings['mailaddresslog']=get_option('admin_email');
|
| 149 |
-
|
| 150 |
if (!isset($jobsettings['mailerroronly']) or !is_bool($jobsettings['mailerroronly']))
|
| 151 |
$jobsettings['mailerroronly']=true;
|
| 152 |
-
|
| 153 |
if (!isset($jobsettings['dbexclude']) or !is_array($jobsettings['dbexclude'])) {
|
| 154 |
$jobsettings['dbexclude']=array();
|
| 155 |
$tables=$wpdb->get_col('SHOW TABLES FROM `'.DB_NAME.'`');
|
| 156 |
foreach ($tables as $table) {
|
| 157 |
if (substr($table,0,strlen($wpdb->prefix))!=$wpdb->prefix)
|
| 158 |
$jobsettings['dbexclude'][]=$table;
|
| 159 |
-
}
|
| 160 |
}
|
| 161 |
$tables=$wpdb->get_col('SHOW TABLES FROM `'.DB_NAME.'`');
|
| 162 |
foreach($jobsettings['dbexclude'] as $key => $value) {
|
|
@@ -164,13 +174,13 @@ if ( !defined('ABSPATH') )
|
|
| 164 |
unset($jobsettings['dbexclude'][$key]);
|
| 165 |
}
|
| 166 |
sort($jobsettings['dbexclude']);
|
| 167 |
-
|
| 168 |
if (!isset($jobsettings['dbshortinsert']) or !is_bool($jobsettings['dbshortinsert']))
|
| 169 |
$jobsettings['dbshortinsert']=false;
|
| 170 |
-
|
| 171 |
if (!isset($jobsettings['maintenance']) or !is_bool($jobsettings['maintenance']))
|
| 172 |
$jobsettings['maintenance']=false;
|
| 173 |
-
|
| 174 |
if (!isset($jobsettings['fileexclude']) or !is_string($jobsettings['fileexclude']))
|
| 175 |
$jobsettings['fileexclude']='';
|
| 176 |
$fileexclude=explode(',',$jobsettings['fileexclude']);
|
|
@@ -180,8 +190,8 @@ if ( !defined('ABSPATH') )
|
|
| 180 |
unset($fileexclude[$key]);
|
| 181 |
}
|
| 182 |
sort($fileexclude);
|
| 183 |
-
$jobsettings['fileexclude']=implode(',',$fileexclude);
|
| 184 |
-
|
| 185 |
if (!isset($jobsettings['dirinclude']) or !is_string($jobsettings['dirinclude']))
|
| 186 |
$jobsettings['dirinclude']='';
|
| 187 |
$dirinclude=explode(',',$jobsettings['dirinclude']);
|
|
@@ -191,17 +201,17 @@ if ( !defined('ABSPATH') )
|
|
| 191 |
unset($dirinclude[$key]);
|
| 192 |
}
|
| 193 |
sort($dirinclude);
|
| 194 |
-
$jobsettings['dirinclude']=implode(',',$dirinclude);
|
| 195 |
|
| 196 |
if (!isset($jobsettings['backuproot']) or !is_bool($jobsettings['backuproot']))
|
| 197 |
$jobsettings['backuproot']=true;
|
| 198 |
-
|
| 199 |
if (!isset($jobsettings['backupcontent']) or !is_bool($jobsettings['backupcontent']))
|
| 200 |
$jobsettings['backupcontent']=true;
|
| 201 |
-
|
| 202 |
if (!isset($jobsettings['backupplugins']) or !is_bool($jobsettings['backupplugins']))
|
| 203 |
$jobsettings['backupplugins']=true;
|
| 204 |
-
|
| 205 |
if (!isset($jobsettings['backupthemes']) or !is_bool($jobsettings['backupthemes']))
|
| 206 |
$jobsettings['backupthemes']=true;
|
| 207 |
|
|
@@ -252,78 +262,78 @@ if ( !defined('ABSPATH') )
|
|
| 252 |
unset($jobsettings['backupuploadsexcludedirs'][$key]);
|
| 253 |
}
|
| 254 |
sort($jobsettings['backupuploadsexcludedirs']);
|
| 255 |
-
|
| 256 |
$fileformarts=array('.zip','.tar.gz','tar.bz2','.tar');
|
| 257 |
if (!isset($jobsettings['fileformart']) or !in_array($jobsettings['fileformart'],$fileformarts))
|
| 258 |
$jobsettings['fileformart']='.zip';
|
| 259 |
-
|
| 260 |
if (!isset($jobsettings['mailefilesize']) or !is_float($jobsettings['mailefilesize']))
|
| 261 |
$jobsettings['mailefilesize']=0;
|
| 262 |
-
|
| 263 |
if (!isset($jobsettings['backupdir']) or (!is_dir($jobsettings['backupdir']) and !empty($jobsettings['backupdir']))) {
|
| 264 |
$rand = substr( md5( md5( SECURE_AUTH_KEY ) ), -5 );
|
| 265 |
-
$jobsettings['backupdir']=str_replace('\\','/',trailingslashit(WP_CONTENT_DIR)).'backwpup-'.$rand.'/';
|
| 266 |
}
|
| 267 |
$jobsettings['backupdir']=trailingslashit(str_replace('//','/',str_replace('\\','/',trim($jobsettings['backupdir']))));
|
| 268 |
if ($jobsettings['backupdir']=='/')
|
| 269 |
$jobsettings['backupdir']='';
|
| 270 |
-
|
| 271 |
if (!isset($jobsettings['maxbackups']) or !is_int($jobsettings['maxbackups']))
|
| 272 |
$jobsettings['maxbackups']=0;
|
| 273 |
-
|
| 274 |
if (!isset($jobsettings['ftphost']) or !is_string($jobsettings['ftphost']))
|
| 275 |
$jobsettings['ftphost']='';
|
| 276 |
-
|
| 277 |
-
if (!isset($jobsettings['ftpuser']) or !is_string($jobsettings['ftpuser']))
|
| 278 |
$jobsettings['ftpuser']='';
|
| 279 |
-
|
| 280 |
if (!isset($jobsettings['ftppass']) or !is_string($jobsettings['ftppass']))
|
| 281 |
$jobsettings['ftppass']='';
|
| 282 |
|
| 283 |
-
if (!isset($jobsettings['ftpdir']) or !is_string($jobsettings['ftpdir']) or $jobsettings['ftpdir']=='/')
|
| 284 |
$jobsettings['ftpdir']='';
|
| 285 |
$jobsettings['ftpdir']=trailingslashit(str_replace('//','/',str_replace('\\','/',trim($jobsettings['ftpdir']))));
|
| 286 |
-
if (substr($jobsettings['ftpdir'],0,1)
|
| 287 |
-
$jobsettings['ftpdir']=
|
| 288 |
-
|
| 289 |
if (!isset($jobsettings['ftpmaxbackups']) or !is_int($jobsettings['ftpmaxbackups']))
|
| 290 |
$jobsettings['ftpmaxbackups']=0;
|
| 291 |
-
|
| 292 |
if (!isset($jobsettings['awsAccessKey']) or !is_string($jobsettings['awsAccessKey']))
|
| 293 |
$jobsettings['awsAccessKey']='';
|
| 294 |
-
|
| 295 |
if (!isset($jobsettings['awsSecretKey']) or !is_string($jobsettings['awsSecretKey']))
|
| 296 |
$jobsettings['awsSecretKey']='';
|
| 297 |
-
|
| 298 |
if (!isset($jobsettings['awsSSL']) or !is_bool($jobsettings['awsSSL']))
|
| 299 |
$jobsettings['awsSSL']=true;
|
| 300 |
-
|
| 301 |
if (!isset($jobsettings['awsBucket']) or !is_string($jobsettings['awsBucket']))
|
| 302 |
$jobsettings['awsBucket']='';
|
| 303 |
-
|
| 304 |
-
if (!isset($jobsettings['awsdir']) or !is_string($jobsettings['awsdir']) or $jobsettings['awsdir']=='/')
|
| 305 |
$jobsettings['awsdir']='';
|
| 306 |
$jobsettings['awsdir']=trailingslashit(str_replace('//','/',str_replace('\\','/',trim($jobsettings['awsdir']))));
|
| 307 |
if (substr($jobsettings['awsdir'],0,1)=='/')
|
| 308 |
$jobsettings['awsdir']=substr($jobsettings['awsdir'],1);
|
| 309 |
-
|
| 310 |
if (!isset($jobsettings['awsmaxbackups']) or !is_int($jobsettings['awsmaxbackups']))
|
| 311 |
-
$jobsettings['awsmaxbackups']=0;
|
| 312 |
-
|
| 313 |
if (!is_string($jobsettings['mailaddress']) or false === $pos=strpos($jobsettings['mailaddress'],'@') or false === strpos($jobsettings['mailaddress'],'.',$pos))
|
| 314 |
$jobsettings['mailaddress']='';
|
| 315 |
|
| 316 |
return $jobsettings;
|
| 317 |
}
|
| 318 |
|
| 319 |
-
|
| 320 |
//On Plugin activate
|
| 321 |
function backwpup_plugin_activate() {
|
| 322 |
//add cron jobs
|
| 323 |
$jobs=get_option('backwpup_jobs');
|
| 324 |
-
if (is_array($jobs)) {
|
| 325 |
foreach ($jobs as $jobid => $jobvalue) {
|
| 326 |
-
if ($jobvalue['activated'] and wp_get_schedule('backwpup_cron',array('jobid'=>$jobid)) === false)
|
| 327 |
wp_schedule_event($jobvalue['scheduletime'], 'backwpup_int_'.$jobid, 'backwpup_cron',array('jobid'=>$jobid));
|
| 328 |
}
|
| 329 |
}
|
|
@@ -340,25 +350,25 @@ if ( !defined('ABSPATH') )
|
|
| 340 |
}
|
| 341 |
if (empty($cfg['dirlogs'])) {
|
| 342 |
$rand = substr( md5( md5( SECURE_AUTH_KEY ) ), -5 );
|
| 343 |
-
$cfg['dirlogs']=str_replace('\\','/',trailingslashit(WP_CONTENT_DIR)).'
|
| 344 |
}
|
| 345 |
update_option('backwpup',$cfg);
|
| 346 |
}
|
| 347 |
-
|
| 348 |
//on Plugin deaktivate
|
| 349 |
function backwpup_plugin_deactivate() {
|
| 350 |
//remove cron jobs
|
| 351 |
$jobs=get_option('backwpup_jobs');
|
| 352 |
wp_clear_scheduled_hook('backwpup_cron');
|
| 353 |
}
|
| 354 |
-
|
| 355 |
//add edit setting to plugins page
|
| 356 |
function backwpup_plugin_options_link($links) {
|
| 357 |
$settings_link='<a href="admin.php?page=BackWPup" title="' . __('Go to Settings Page','backwpup') . '" class="edit">' . __('Settings') . '</a>';
|
| 358 |
-
array_unshift( $links, $settings_link );
|
| 359 |
return $links;
|
| 360 |
}
|
| 361 |
-
|
| 362 |
//add links on plugins page
|
| 363 |
function backwpup_plugin_links($links, $file) {
|
| 364 |
if ($file == BACKWPUP_PLUGIN_BASEDIR.'/backwpup.php') {
|
|
@@ -368,7 +378,7 @@ if ( !defined('ABSPATH') )
|
|
| 368 |
}
|
| 369 |
return $links;
|
| 370 |
}
|
| 371 |
-
|
| 372 |
//Add cron interval
|
| 373 |
function backwpup_intervals($schedules) {
|
| 374 |
$jobs=get_option('backwpup_jobs'); //Load Settings
|
|
@@ -377,9 +387,9 @@ if ( !defined('ABSPATH') )
|
|
| 377 |
if (!empty($jobvalue['scheduleinterval']))
|
| 378 |
$intervals['backwpup_int_'.$jobkey]=array('interval' => $jobvalue['scheduleinterval'], 'display' => __('BackWPup Job '.$jobkey, 'backwpup'));
|
| 379 |
}
|
| 380 |
-
if (is_array($intervals))
|
| 381 |
$schedules=array_merge($intervals,$schedules);
|
| 382 |
-
}
|
| 383 |
return $schedules;
|
| 384 |
}
|
| 385 |
|
|
@@ -390,14 +400,14 @@ if ( !defined('ABSPATH') )
|
|
| 390 |
extract($args, EXTR_SKIP );
|
| 391 |
else
|
| 392 |
$jobid=$args;
|
| 393 |
-
if (empty($jobid))
|
| 394 |
return false;
|
| 395 |
require_once('backwpup_dojob.php');
|
| 396 |
$backwpup_dojob= new backwpup_dojob($jobid);
|
| 397 |
unset($backwpup_dojob);
|
| 398 |
return $backwpup_logfile;
|
| 399 |
}
|
| 400 |
-
|
| 401 |
//file size
|
| 402 |
function backwpup_formatBytes($bytes, $precision = 2) {
|
| 403 |
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
|
@@ -406,8 +416,8 @@ if ( !defined('ABSPATH') )
|
|
| 406 |
$pow = min($pow, count($units) - 1);
|
| 407 |
$bytes /= pow(1024, $pow);
|
| 408 |
return round($bytes, $precision) . ' ' . $units[$pow];
|
| 409 |
-
}
|
| 410 |
-
|
| 411 |
//echo long backup type name
|
| 412 |
function backwpup_backup_types($type='',$echo=false) {
|
| 413 |
$typename='';
|
|
@@ -420,7 +430,7 @@ if ( !defined('ABSPATH') )
|
|
| 420 |
break;
|
| 421 |
case 'DB':
|
| 422 |
$typename.=__('Database Backup','backwpup')."<br />";
|
| 423 |
-
break;
|
| 424 |
case 'FILE':
|
| 425 |
$typename.=__('File Backup','backwpup')."<br />";
|
| 426 |
break;
|
|
@@ -435,16 +445,16 @@ if ( !defined('ABSPATH') )
|
|
| 435 |
} else {
|
| 436 |
$typename=array('WPEXP','DB','FILE','OPTIMIZE','CHECK');
|
| 437 |
}
|
| 438 |
-
|
| 439 |
-
if ($echo)
|
| 440 |
echo $typename;
|
| 441 |
else
|
| 442 |
return $typename;
|
| 443 |
}
|
| 444 |
-
|
| 445 |
//read log file header
|
| 446 |
function backwpup_read_logheader($logfile) {
|
| 447 |
-
$headers=array("backwpup_version" => "version","backwpup_logtime" => "logtime","backwpup_errors" => "errors","backwpup_warnings" => "warnings","backwpup_jobid" => "jobid","backwpup_jobname" => "name","backwpup_jobtype" => "type","backwpup_jobruntime" => "runtime","backwpup_backupfile" => "backupfile");
|
| 448 |
if (!is_readable($logfile))
|
| 449 |
return false;
|
| 450 |
//Read file
|
|
@@ -460,14 +470,14 @@ if ( !defined('ABSPATH') )
|
|
| 460 |
else
|
| 461 |
$joddata[$field]='';
|
| 462 |
}
|
| 463 |
-
|
| 464 |
if (empty($joddata['logtime']))
|
| 465 |
$joddata['logtime']=filectime($logfile);
|
| 466 |
-
|
| 467 |
return $joddata;
|
| 468 |
}
|
| 469 |
-
|
| 470 |
-
|
| 471 |
//Dashboard widget
|
| 472 |
function backwpup_dashboard_output() {
|
| 473 |
global $wpdb;
|
|
@@ -483,25 +493,25 @@ if ( !defined('ABSPATH') )
|
|
| 483 |
closedir( $dir );
|
| 484 |
rsort($logfiles);
|
| 485 |
}
|
| 486 |
-
|
| 487 |
if (is_array($logfiles)) {
|
| 488 |
$count=0;
|
| 489 |
foreach ($logfiles as $logfile) {
|
| 490 |
$logdata=backwpup_read_logheader($cfg['dirlogs'].'/'.$logfile);
|
| 491 |
echo '<a href="'.wp_nonce_url('admin.php?page=BackWPup&action=view_log&logfile='.$cfg['dirlogs'].'/'.$logfile, 'view-log_'.$logfile).'" title="'.__('View Log','backwpup').'">'.date_i18n(get_option('date_format'),$logdata['logtime']).' '.date_i18n(get_option('time_format'),$logdata['logtime']).': <i>';
|
| 492 |
-
if (empty($logdata['name']))
|
| 493 |
echo $logdata['type'];
|
| 494 |
else
|
| 495 |
echo $logdata['name'];
|
| 496 |
echo '</i>';
|
| 497 |
-
if($logdata['errors']>0 or $logdata['warnings']>0) {
|
| 498 |
if ($logdata['errors']>0)
|
| 499 |
-
echo ' <span style="color:red;">'.$logdata['errors'].' '.__('ERROR(S)','backwpup').'</span>';
|
| 500 |
if ($logdata['warnings']>0)
|
| 501 |
-
echo ' <span style="color:yellow;">'.$logdata['warnings'].' '.__('WARNING(S)','backwpup').'</span>';
|
| 502 |
-
} else {
|
| 503 |
-
echo ' <span style="color:green;">'.__('OK','backwpup').'</span>';
|
| 504 |
-
}
|
| 505 |
echo '</a><br />';
|
| 506 |
$count++;
|
| 507 |
if ($count>=5)
|
|
@@ -512,7 +522,7 @@ if ( !defined('ABSPATH') )
|
|
| 512 |
}
|
| 513 |
$jobs=get_option('backwpup_jobs');
|
| 514 |
echo '<strong>'.__('Scheduled Jobs:','backwpup').'</strong><br />';
|
| 515 |
-
if (is_array($jobs)) {
|
| 516 |
foreach ($jobs as $jobid => $jobvalue) {
|
| 517 |
if (wp_next_scheduled('backwpup_cron',array('jobid'=>$jobid))) {
|
| 518 |
echo '<a href="'.wp_nonce_url('admin.php?page=BackWPup&action=edit&jobid='.$jobid, 'edit-job').'" title="'.__('Edit Job','backwpup').'">';
|
|
@@ -529,19 +539,19 @@ if ( !defined('ABSPATH') )
|
|
| 529 |
echo '<i>'.__('none','backwpup').'</i><br />';
|
| 530 |
}
|
| 531 |
}
|
| 532 |
-
|
| 533 |
//add dashboard widget
|
| 534 |
function backwpup_add_dashboard() {
|
| 535 |
-
wp_add_dashboard_widget( 'backwpup_dashboard_widget', 'BackWPup', 'backwpup_dashboard_output' );
|
| 536 |
}
|
| 537 |
-
|
| 538 |
//turn cache off
|
| 539 |
function backwpup_meta_no_cache() {
|
| 540 |
echo "<meta http-equiv=\"expires\" content=\"0\" />\n";
|
| 541 |
echo "<meta http-equiv=\"pragma\" content=\"no-cache\" />\n";
|
| 542 |
echo "<meta http-equiv=\"cache-control\" content=\"no-cache\" />\n";
|
| 543 |
}
|
| 544 |
-
|
| 545 |
function backwpup_send_no_cache_header() {
|
| 546 |
header("Expires: 0");
|
| 547 |
header("Cache-Control: no-cache, must-revalidate");
|
|
@@ -564,7 +574,7 @@ if ( !defined('ABSPATH') )
|
|
| 564 |
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
|
| 565 |
$dir = path_join( ABSPATH, $dir );
|
| 566 |
}
|
| 567 |
-
}
|
| 568 |
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
|
| 569 |
$dir = ABSPATH . UPLOADS;
|
| 570 |
}
|
|
@@ -574,10 +584,10 @@ if ( !defined('ABSPATH') )
|
|
| 574 |
$dir = untrailingslashit(BLOGUPLOADDIR);
|
| 575 |
}
|
| 576 |
}
|
| 577 |
-
|
| 578 |
return str_replace('\\','/',trailingslashit($dir));
|
| 579 |
}
|
| 580 |
-
|
| 581 |
function backwpup_get_exclude_wp_dirs($folder) {
|
| 582 |
$folder=trailingslashit(str_replace('\\','/',$folder));
|
| 583 |
$excludedir=array();
|
|
@@ -593,13 +603,127 @@ if ( !defined('ABSPATH') )
|
|
| 593 |
$excludedir[]=backwpup_get_upload_dir();
|
| 594 |
//Exclude Backup dirs
|
| 595 |
$jobs=get_option('backwpup_jobs');
|
| 596 |
-
foreach($jobs as $jobsvale) {
|
| 597 |
if (!empty($jobsvale['backupdir']) and $jobsvale['backupdir']!='/')
|
| 598 |
$excludedir[]=trailingslashit(str_replace('\\','/',$jobsvale['backupdir']));
|
| 599 |
}
|
| 600 |
return $excludedir;
|
| 601 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 602 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 603 |
//ajax/normal get buckests select box
|
| 604 |
function backwpup_get_aws_buckets($args='') {
|
| 605 |
if (is_array($args)) {
|
|
@@ -619,13 +743,13 @@ if ( !defined('ABSPATH') )
|
|
| 619 |
if (empty($awsSecretKey)) {
|
| 620 |
echo '<span id="awsBucket" style="color:red;">'.__('Missing Secret Access Key!','backwpup').'</span>';
|
| 621 |
die();
|
| 622 |
-
}
|
| 623 |
$s3 = new S3($awsAccessKey, $awsSecretKey, false);
|
| 624 |
$buckets=@$s3->listBuckets();
|
| 625 |
if (!is_array($buckets)) {
|
| 626 |
echo '<span id="awsBucket" style="color:red;">'.__('No Buckets found! Or wrong Keys!','backwpup').'</span>';
|
| 627 |
die();
|
| 628 |
-
}
|
| 629 |
echo '<select name="awsBucket" id="awsBucket">';
|
| 630 |
foreach ($buckets as $bucket) {
|
| 631 |
echo "<option ".selected(strtolower($selected),strtolower($bucket),false).">".$bucket."</option>";
|
|
@@ -634,7 +758,7 @@ if ( !defined('ABSPATH') )
|
|
| 634 |
if ($ajax)
|
| 635 |
die();
|
| 636 |
}
|
| 637 |
-
|
| 638 |
// add all action and so on only if plugin loaded.
|
| 639 |
function backwpup_init() {
|
| 640 |
//Disabele WP_Corn
|
|
@@ -644,19 +768,19 @@ if ( !defined('ABSPATH') )
|
|
| 644 |
//add Menu
|
| 645 |
add_action('admin_menu', 'backwpup_menu_entry');
|
| 646 |
//Additional links on the plugin page
|
| 647 |
-
if (current_user_can(10))
|
| 648 |
add_filter('plugin_action_links_'.BACKWPUP_PLUGIN_BASEDIR.'/backwpup.php', 'backwpup_plugin_options_link');
|
| 649 |
-
if (current_user_can('install_plugins'))
|
| 650 |
add_filter('plugin_row_meta', 'backwpup_plugin_links',10,2);
|
| 651 |
//add cron intervals
|
| 652 |
add_filter('cron_schedules', 'backwpup_intervals');
|
| 653 |
//Actions for Cron job
|
| 654 |
add_action('backwpup_cron', 'backwpup_dojob');
|
| 655 |
//add Dashboard widget
|
| 656 |
-
if (current_user_can(10))
|
| 657 |
add_action('wp_dashboard_setup', 'backwpup_add_dashboard');
|
| 658 |
// add ajax function
|
| 659 |
add_action('wp_ajax_backwpup_get_aws_buckets', 'backwpup_get_aws_buckets');
|
| 660 |
-
}
|
| 661 |
|
| 662 |
?>
|
| 1 |
<?PHP
|
| 2 |
+
// don't load directly
|
| 3 |
+
if ( !defined('ABSPATH') )
|
| 4 |
die('-1');
|
| 5 |
+
|
| 6 |
//Thems Option menu entry
|
| 7 |
function backwpup_menu_entry() {
|
| 8 |
$hook = add_management_page(__('BackWPup','backwpup'), __('BackWPup','backwpup'), '10', 'BackWPup','backwpup_options_page') ;
|
| 10 |
add_contextual_help($hook,backwpup_show_help());
|
| 11 |
switch($_REQUEST['action']) {
|
| 12 |
case 'logs':
|
| 13 |
+
case 'delete-logs':
|
| 14 |
register_column_headers($hook,array('cb'=>'<input type="checkbox" />','id'=>__('Job','backwpup'),'type'=>__('Type','backwpup'),'log'=>__('Backup/Log Date/Time','backwpup'),'status'=>__('Status','backwpup'),'size'=>__('Size','backwpup'),'runtime'=>__('Runtime','backwpup')));
|
| 15 |
break;
|
| 16 |
case 'edit':
|
| 19 |
break;
|
| 20 |
case 'tools':
|
| 21 |
break;
|
| 22 |
+
case 'backups':
|
| 23 |
+
case 'delete-backup':
|
| 24 |
+
register_column_headers($hook,array('cb'=>'<input type="checkbox" />','id'=>__('Job','backwpup'),'backup'=>__('Backupfile','backwpup'),'size'=>__('Size','backwpup')));
|
| 25 |
+
break;
|
| 26 |
case 'runnow':
|
| 27 |
add_action('load-'.$hook, 'backwpup_send_no_cache_header');
|
| 28 |
add_action('admin_head-'.$hook, 'backwpup_meta_no_cache');
|
| 29 |
break;
|
| 30 |
case 'view_log':
|
| 31 |
break;
|
| 32 |
+
case 'delete':
|
| 33 |
+
case 'copy':
|
| 34 |
default:
|
| 35 |
register_column_headers($hook,array('cb'=>'<input type="checkbox" />','id'=>__('ID','backwpup'),'jobname'=>__('Job Name','backwpup'),'type'=>__('Type','backwpup'),'next'=>__('Next Run','backwpup'),'last'=>__('Last Run','backwpup')));
|
| 36 |
break;
|
| 37 |
}
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
// Help too display
|
| 41 |
function backwpup_show_help() {
|
| 42 |
$help .= '<div class="metabox-prefs">';
|
| 49 |
var flattr_btn = 'compact';
|
| 50 |
var flattr_url = 'http://danielhuesken.de/portfolio/backwpup/';
|
| 51 |
</script><script src=\"http://api.flattr.com/button/load.js\" type=\"text/javascript\"></script>";
|
| 52 |
+
$help .= "</div>\n";
|
| 53 |
$help .= '<div class="metabox-prefs">';
|
| 54 |
$help .= __('Version:', 'backwpup').' '.BACKWPUP_VERSION.' | ';
|
| 55 |
$help .= __('Author:', 'backwpup').' <a href="http://danielhuesken.de" target="_blank">Daniel Hüsken</a>';
|
| 56 |
$help .= "</div>\n";
|
| 57 |
return $help;
|
| 58 |
}
|
| 59 |
+
|
| 60 |
//Options Page
|
| 61 |
function backwpup_options_page() {
|
| 62 |
global $wpdb,$backwpup_message,$page_hook;
|
| 63 |
+
if (!current_user_can(10))
|
| 64 |
wp_die('No rights');
|
| 65 |
+
if(!empty($backwpup_message))
|
| 66 |
echo '<div id="message" class="updated fade"><p><strong>'.$backwpup_message.'</strong></p></div>';
|
| 67 |
switch($_REQUEST['action']) {
|
| 68 |
case 'edit':
|
| 82 |
case 'tools':
|
| 83 |
require_once(plugin_dir_path(__FILE__).'options-tools.php');
|
| 84 |
break;
|
| 85 |
+
case 'backups':
|
| 86 |
+
require_once(plugin_dir_path(__FILE__).'options-backups.php');
|
| 87 |
+
break;
|
| 88 |
case 'runnow':
|
| 89 |
$jobid = (int) $_GET['jobid'];
|
| 90 |
check_admin_referer('runnow-job_' . $jobid);
|
| 99 |
$jobs=get_option('backwpup_jobs');
|
| 100 |
require_once(plugin_dir_path(__FILE__).'options.php');
|
| 101 |
break;
|
| 102 |
+
}
|
| 103 |
}
|
| 104 |
+
|
| 105 |
//Options Page
|
| 106 |
function backwpup_options_load() {
|
| 107 |
global $wpdb,$backwpup_message;
|
| 108 |
+
if (!current_user_can(10))
|
| 109 |
wp_die('No rights');
|
| 110 |
//Css for Admin Section
|
| 111 |
wp_enqueue_style('BackWpup',plugins_url('css/options.css',__FILE__),'',BACKWPUP_VERSION,'screen');
|
| 113 |
//For save Options
|
| 114 |
require_once(plugin_dir_path(__FILE__).'options-save.php');
|
| 115 |
}
|
| 116 |
+
|
| 117 |
//delete Otions
|
| 118 |
function backwpup_plugin_uninstall() {
|
| 119 |
delete_option('backwpup');
|
| 134 |
$jobsettings['type']=implode('+',$todo);
|
| 135 |
if (empty($jobsettings['type']))
|
| 136 |
$jobsettings['type']='DB+FILE';
|
| 137 |
+
|
| 138 |
if (empty($jobsettings['name']) or !is_string($jobsettings['name']))
|
| 139 |
$jobsettings['name']= __('New');
|
| 140 |
+
|
| 141 |
+
if (!isset($jobsettings['activated']) or !is_bool($jobsettings['activated']))
|
| 142 |
$jobsettings['activated']=false;
|
| 143 |
+
|
| 144 |
if (!isset($jobsettings['scheduletime']) or !is_numeric($jobsettings['scheduletime']))
|
| 145 |
$jobsettings['scheduletime']=current_time('timestamp');
|
| 146 |
+
|
| 147 |
+
if (!isset($jobsettings['scheduleintervaltype']) or !is_int($jobsettings['scheduleintervaltype']))
|
| 148 |
$jobsettings['scheduleintervaltype']=3600;
|
| 149 |
if ($jobsettings['scheduleintervaltype']!=60 and $jobsettings['scheduleintervaltype']!=3600 and $jobsettings['scheduleintervaltype']!=86400)
|
| 150 |
$jobsettings['scheduleintervaltype']=3600;
|
| 151 |
+
|
| 152 |
if (!isset($jobsettings['scheduleintervalteimes']) or !is_int($jobsettings['scheduleintervalteimes']) or ($jobsettings['scheduleintervalteimes']<1 and $jobsettings['scheduleintervalteimes']>100))
|
| 153 |
$jobsettings['scheduleintervalteimes']=1;
|
| 154 |
+
|
| 155 |
$jobsettings['scheduleinterval']=$jobsettings['scheduleintervaltype']*$jobsettings['scheduleintervalteimes'];
|
| 156 |
+
|
| 157 |
if (!is_string($jobsettings['mailaddresslog']) or false === $pos=strpos($jobsettings['mailaddresslog'],'@') or false === strpos($jobsettings['mailaddresslog'],'.',$pos))
|
| 158 |
$jobsettings['mailaddresslog']=get_option('admin_email');
|
| 159 |
+
|
| 160 |
if (!isset($jobsettings['mailerroronly']) or !is_bool($jobsettings['mailerroronly']))
|
| 161 |
$jobsettings['mailerroronly']=true;
|
| 162 |
+
|
| 163 |
if (!isset($jobsettings['dbexclude']) or !is_array($jobsettings['dbexclude'])) {
|
| 164 |
$jobsettings['dbexclude']=array();
|
| 165 |
$tables=$wpdb->get_col('SHOW TABLES FROM `'.DB_NAME.'`');
|
| 166 |
foreach ($tables as $table) {
|
| 167 |
if (substr($table,0,strlen($wpdb->prefix))!=$wpdb->prefix)
|
| 168 |
$jobsettings['dbexclude'][]=$table;
|
| 169 |
+
}
|
| 170 |
}
|
| 171 |
$tables=$wpdb->get_col('SHOW TABLES FROM `'.DB_NAME.'`');
|
| 172 |
foreach($jobsettings['dbexclude'] as $key => $value) {
|
| 174 |
unset($jobsettings['dbexclude'][$key]);
|
| 175 |
}
|
| 176 |
sort($jobsettings['dbexclude']);
|
| 177 |
+
|
| 178 |
if (!isset($jobsettings['dbshortinsert']) or !is_bool($jobsettings['dbshortinsert']))
|
| 179 |
$jobsettings['dbshortinsert']=false;
|
| 180 |
+
|
| 181 |
if (!isset($jobsettings['maintenance']) or !is_bool($jobsettings['maintenance']))
|
| 182 |
$jobsettings['maintenance']=false;
|
| 183 |
+
|
| 184 |
if (!isset($jobsettings['fileexclude']) or !is_string($jobsettings['fileexclude']))
|
| 185 |
$jobsettings['fileexclude']='';
|
| 186 |
$fileexclude=explode(',',$jobsettings['fileexclude']);
|
| 190 |
unset($fileexclude[$key]);
|
| 191 |
}
|
| 192 |
sort($fileexclude);
|
| 193 |
+
$jobsettings['fileexclude']=implode(',',$fileexclude);
|
| 194 |
+
|
| 195 |
if (!isset($jobsettings['dirinclude']) or !is_string($jobsettings['dirinclude']))
|
| 196 |
$jobsettings['dirinclude']='';
|
| 197 |
$dirinclude=explode(',',$jobsettings['dirinclude']);
|
| 201 |
unset($dirinclude[$key]);
|
| 202 |
}
|
| 203 |
sort($dirinclude);
|
| 204 |
+
$jobsettings['dirinclude']=implode(',',$dirinclude);
|
| 205 |
|
| 206 |
if (!isset($jobsettings['backuproot']) or !is_bool($jobsettings['backuproot']))
|
| 207 |
$jobsettings['backuproot']=true;
|
| 208 |
+
|
| 209 |
if (!isset($jobsettings['backupcontent']) or !is_bool($jobsettings['backupcontent']))
|
| 210 |
$jobsettings['backupcontent']=true;
|
| 211 |
+
|
| 212 |
if (!isset($jobsettings['backupplugins']) or !is_bool($jobsettings['backupplugins']))
|
| 213 |
$jobsettings['backupplugins']=true;
|
| 214 |
+
|
| 215 |
if (!isset($jobsettings['backupthemes']) or !is_bool($jobsettings['backupthemes']))
|
| 216 |
$jobsettings['backupthemes']=true;
|
| 217 |
|
| 262 |
unset($jobsettings['backupuploadsexcludedirs'][$key]);
|
| 263 |
}
|
| 264 |
sort($jobsettings['backupuploadsexcludedirs']);
|
| 265 |
+
|
| 266 |
$fileformarts=array('.zip','.tar.gz','tar.bz2','.tar');
|
| 267 |
if (!isset($jobsettings['fileformart']) or !in_array($jobsettings['fileformart'],$fileformarts))
|
| 268 |
$jobsettings['fileformart']='.zip';
|
| 269 |
+
|
| 270 |
if (!isset($jobsettings['mailefilesize']) or !is_float($jobsettings['mailefilesize']))
|
| 271 |
$jobsettings['mailefilesize']=0;
|
| 272 |
+
|
| 273 |
if (!isset($jobsettings['backupdir']) or (!is_dir($jobsettings['backupdir']) and !empty($jobsettings['backupdir']))) {
|
| 274 |
$rand = substr( md5( md5( SECURE_AUTH_KEY ) ), -5 );
|
| 275 |
+
$jobsettings['backupdir']=str_replace('\\','/',trailingslashit(WP_CONTENT_DIR)).'backwpup-'.$rand.'/';
|
| 276 |
}
|
| 277 |
$jobsettings['backupdir']=trailingslashit(str_replace('//','/',str_replace('\\','/',trim($jobsettings['backupdir']))));
|
| 278 |
if ($jobsettings['backupdir']=='/')
|
| 279 |
$jobsettings['backupdir']='';
|
| 280 |
+
|
| 281 |
if (!isset($jobsettings['maxbackups']) or !is_int($jobsettings['maxbackups']))
|
| 282 |
$jobsettings['maxbackups']=0;
|
| 283 |
+
|
| 284 |
if (!isset($jobsettings['ftphost']) or !is_string($jobsettings['ftphost']))
|
| 285 |
$jobsettings['ftphost']='';
|
| 286 |
+
|
| 287 |
+
if (!isset($jobsettings['ftpuser']) or !is_string($jobsettings['ftpuser']))
|
| 288 |
$jobsettings['ftpuser']='';
|
| 289 |
+
|
| 290 |
if (!isset($jobsettings['ftppass']) or !is_string($jobsettings['ftppass']))
|
| 291 |
$jobsettings['ftppass']='';
|
| 292 |
|
| 293 |
+
if (!isset($jobsettings['ftpdir']) or !is_string($jobsettings['ftpdir']) or $jobsettings['ftpdir']=='/')
|
| 294 |
$jobsettings['ftpdir']='';
|
| 295 |
$jobsettings['ftpdir']=trailingslashit(str_replace('//','/',str_replace('\\','/',trim($jobsettings['ftpdir']))));
|
| 296 |
+
if (substr($jobsettings['ftpdir'],0,1)!='/')
|
| 297 |
+
$jobsettings['ftpdir']='/'.$jobsettings['ftpdir'];
|
| 298 |
+
|
| 299 |
if (!isset($jobsettings['ftpmaxbackups']) or !is_int($jobsettings['ftpmaxbackups']))
|
| 300 |
$jobsettings['ftpmaxbackups']=0;
|
| 301 |
+
|
| 302 |
if (!isset($jobsettings['awsAccessKey']) or !is_string($jobsettings['awsAccessKey']))
|
| 303 |
$jobsettings['awsAccessKey']='';
|
| 304 |
+
|
| 305 |
if (!isset($jobsettings['awsSecretKey']) or !is_string($jobsettings['awsSecretKey']))
|
| 306 |
$jobsettings['awsSecretKey']='';
|
| 307 |
+
|
| 308 |
if (!isset($jobsettings['awsSSL']) or !is_bool($jobsettings['awsSSL']))
|
| 309 |
$jobsettings['awsSSL']=true;
|
| 310 |
+
|
| 311 |
if (!isset($jobsettings['awsBucket']) or !is_string($jobsettings['awsBucket']))
|
| 312 |
$jobsettings['awsBucket']='';
|
| 313 |
+
|
| 314 |
+
if (!isset($jobsettings['awsdir']) or !is_string($jobsettings['awsdir']) or $jobsettings['awsdir']=='/')
|
| 315 |
$jobsettings['awsdir']='';
|
| 316 |
$jobsettings['awsdir']=trailingslashit(str_replace('//','/',str_replace('\\','/',trim($jobsettings['awsdir']))));
|
| 317 |
if (substr($jobsettings['awsdir'],0,1)=='/')
|
| 318 |
$jobsettings['awsdir']=substr($jobsettings['awsdir'],1);
|
| 319 |
+
|
| 320 |
if (!isset($jobsettings['awsmaxbackups']) or !is_int($jobsettings['awsmaxbackups']))
|
| 321 |
+
$jobsettings['awsmaxbackups']=0;
|
| 322 |
+
|
| 323 |
if (!is_string($jobsettings['mailaddress']) or false === $pos=strpos($jobsettings['mailaddress'],'@') or false === strpos($jobsettings['mailaddress'],'.',$pos))
|
| 324 |
$jobsettings['mailaddress']='';
|
| 325 |
|
| 326 |
return $jobsettings;
|
| 327 |
}
|
| 328 |
|
| 329 |
+
|
| 330 |
//On Plugin activate
|
| 331 |
function backwpup_plugin_activate() {
|
| 332 |
//add cron jobs
|
| 333 |
$jobs=get_option('backwpup_jobs');
|
| 334 |
+
if (is_array($jobs)) {
|
| 335 |
foreach ($jobs as $jobid => $jobvalue) {
|
| 336 |
+
if ($jobvalue['activated'] and wp_get_schedule('backwpup_cron',array('jobid'=>$jobid)) === false)
|
| 337 |
wp_schedule_event($jobvalue['scheduletime'], 'backwpup_int_'.$jobid, 'backwpup_cron',array('jobid'=>$jobid));
|
| 338 |
}
|
| 339 |
}
|
| 350 |
}
|
| 351 |
if (empty($cfg['dirlogs'])) {
|
| 352 |
$rand = substr( md5( md5( SECURE_AUTH_KEY ) ), -5 );
|
| 353 |
+
$cfg['dirlogs']=str_replace('\\','/',trailingslashit(WP_CONTENT_DIR)).'backwpup-'.$rand.'-logs/';
|
| 354 |
}
|
| 355 |
update_option('backwpup',$cfg);
|
| 356 |
}
|
| 357 |
+
|
| 358 |
//on Plugin deaktivate
|
| 359 |
function backwpup_plugin_deactivate() {
|
| 360 |
//remove cron jobs
|
| 361 |
$jobs=get_option('backwpup_jobs');
|
| 362 |
wp_clear_scheduled_hook('backwpup_cron');
|
| 363 |
}
|
| 364 |
+
|
| 365 |
//add edit setting to plugins page
|
| 366 |
function backwpup_plugin_options_link($links) {
|
| 367 |
$settings_link='<a href="admin.php?page=BackWPup" title="' . __('Go to Settings Page','backwpup') . '" class="edit">' . __('Settings') . '</a>';
|
| 368 |
+
array_unshift( $links, $settings_link );
|
| 369 |
return $links;
|
| 370 |
}
|
| 371 |
+
|
| 372 |
//add links on plugins page
|
| 373 |
function backwpup_plugin_links($links, $file) {
|
| 374 |
if ($file == BACKWPUP_PLUGIN_BASEDIR.'/backwpup.php') {
|
| 378 |
}
|
| 379 |
return $links;
|
| 380 |
}
|
| 381 |
+
|
| 382 |
//Add cron interval
|
| 383 |
function backwpup_intervals($schedules) {
|
| 384 |
$jobs=get_option('backwpup_jobs'); //Load Settings
|
| 387 |
if (!empty($jobvalue['scheduleinterval']))
|
| 388 |
$intervals['backwpup_int_'.$jobkey]=array('interval' => $jobvalue['scheduleinterval'], 'display' => __('BackWPup Job '.$jobkey, 'backwpup'));
|
| 389 |
}
|
| 390 |
+
if (is_array($intervals))
|
| 391 |
$schedules=array_merge($intervals,$schedules);
|
| 392 |
+
}
|
| 393 |
return $schedules;
|
| 394 |
}
|
| 395 |
|
| 400 |
extract($args, EXTR_SKIP );
|
| 401 |
else
|
| 402 |
$jobid=$args;
|
| 403 |
+
if (empty($jobid))
|
| 404 |
return false;
|
| 405 |
require_once('backwpup_dojob.php');
|
| 406 |
$backwpup_dojob= new backwpup_dojob($jobid);
|
| 407 |
unset($backwpup_dojob);
|
| 408 |
return $backwpup_logfile;
|
| 409 |
}
|
| 410 |
+
|
| 411 |
//file size
|
| 412 |
function backwpup_formatBytes($bytes, $precision = 2) {
|
| 413 |
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
| 416 |
$pow = min($pow, count($units) - 1);
|
| 417 |
$bytes /= pow(1024, $pow);
|
| 418 |
return round($bytes, $precision) . ' ' . $units[$pow];
|
| 419 |
+
}
|
| 420 |
+
|
| 421 |
//echo long backup type name
|
| 422 |
function backwpup_backup_types($type='',$echo=false) {
|
| 423 |
$typename='';
|
| 430 |
break;
|
| 431 |
case 'DB':
|
| 432 |
$typename.=__('Database Backup','backwpup')."<br />";
|
| 433 |
+
break;
|
| 434 |
case 'FILE':
|
| 435 |
$typename.=__('File Backup','backwpup')."<br />";
|
| 436 |
break;
|
| 445 |
} else {
|
| 446 |
$typename=array('WPEXP','DB','FILE','OPTIMIZE','CHECK');
|
| 447 |
}
|
| 448 |
+
|
| 449 |
+
if ($echo)
|
| 450 |
echo $typename;
|
| 451 |
else
|
| 452 |
return $typename;
|
| 453 |
}
|
| 454 |
+
|
| 455 |
//read log file header
|
| 456 |
function backwpup_read_logheader($logfile) {
|
| 457 |
+
$headers=array("backwpup_version" => "version","backwpup_logtime" => "logtime","backwpup_errors" => "errors","backwpup_warnings" => "warnings","backwpup_jobid" => "jobid","backwpup_jobname" => "name","backwpup_jobtype" => "type","backwpup_jobruntime" => "runtime","backwpup_backupfile" => "backupfile","backwpup_backupfilesize" => "backupfilesize");
|
| 458 |
if (!is_readable($logfile))
|
| 459 |
return false;
|
| 460 |
//Read file
|
| 470 |
else
|
| 471 |
$joddata[$field]='';
|
| 472 |
}
|
| 473 |
+
|
| 474 |
if (empty($joddata['logtime']))
|
| 475 |
$joddata['logtime']=filectime($logfile);
|
| 476 |
+
|
| 477 |
return $joddata;
|
| 478 |
}
|
| 479 |
+
|
| 480 |
+
|
| 481 |
//Dashboard widget
|
| 482 |
function backwpup_dashboard_output() {
|
| 483 |
global $wpdb;
|
| 493 |
closedir( $dir );
|
| 494 |
rsort($logfiles);
|
| 495 |
}
|
| 496 |
+
|
| 497 |
if (is_array($logfiles)) {
|
| 498 |
$count=0;
|
| 499 |
foreach ($logfiles as $logfile) {
|
| 500 |
$logdata=backwpup_read_logheader($cfg['dirlogs'].'/'.$logfile);
|
| 501 |
echo '<a href="'.wp_nonce_url('admin.php?page=BackWPup&action=view_log&logfile='.$cfg['dirlogs'].'/'.$logfile, 'view-log_'.$logfile).'" title="'.__('View Log','backwpup').'">'.date_i18n(get_option('date_format'),$logdata['logtime']).' '.date_i18n(get_option('time_format'),$logdata['logtime']).': <i>';
|
| 502 |
+
if (empty($logdata['name']))
|
| 503 |
echo $logdata['type'];
|
| 504 |
else
|
| 505 |
echo $logdata['name'];
|
| 506 |
echo '</i>';
|
| 507 |
+
if($logdata['errors']>0 or $logdata['warnings']>0) {
|
| 508 |
if ($logdata['errors']>0)
|
| 509 |
+
echo ' <span style="color:red;">'.$logdata['errors'].' '.__('ERROR(S)','backwpup').'</span>';
|
| 510 |
if ($logdata['warnings']>0)
|
| 511 |
+
echo ' <span style="color:yellow;">'.$logdata['warnings'].' '.__('WARNING(S)','backwpup').'</span>';
|
| 512 |
+
} else {
|
| 513 |
+
echo ' <span style="color:green;">'.__('OK','backwpup').'</span>';
|
| 514 |
+
}
|
| 515 |
echo '</a><br />';
|
| 516 |
$count++;
|
| 517 |
if ($count>=5)
|
| 522 |
}
|
| 523 |
$jobs=get_option('backwpup_jobs');
|
| 524 |
echo '<strong>'.__('Scheduled Jobs:','backwpup').'</strong><br />';
|
| 525 |
+
if (is_array($jobs)) {
|
| 526 |
foreach ($jobs as $jobid => $jobvalue) {
|
| 527 |
if (wp_next_scheduled('backwpup_cron',array('jobid'=>$jobid))) {
|
| 528 |
echo '<a href="'.wp_nonce_url('admin.php?page=BackWPup&action=edit&jobid='.$jobid, 'edit-job').'" title="'.__('Edit Job','backwpup').'">';
|
| 539 |
echo '<i>'.__('none','backwpup').'</i><br />';
|
| 540 |
}
|
| 541 |
}
|
| 542 |
+
|
| 543 |
//add dashboard widget
|
| 544 |
function backwpup_add_dashboard() {
|
| 545 |
+
wp_add_dashboard_widget( 'backwpup_dashboard_widget', 'BackWPup', 'backwpup_dashboard_output' );
|
| 546 |
}
|
| 547 |
+
|
| 548 |
//turn cache off
|
| 549 |
function backwpup_meta_no_cache() {
|
| 550 |
echo "<meta http-equiv=\"expires\" content=\"0\" />\n";
|
| 551 |
echo "<meta http-equiv=\"pragma\" content=\"no-cache\" />\n";
|
| 552 |
echo "<meta http-equiv=\"cache-control\" content=\"no-cache\" />\n";
|
| 553 |
}
|
| 554 |
+
|
| 555 |
function backwpup_send_no_cache_header() {
|
| 556 |
header("Expires: 0");
|
| 557 |
header("Cache-Control: no-cache, must-revalidate");
|
| 574 |
// $dir is absolute, $upload_path is (maybe) relative to ABSPATH
|
| 575 |
$dir = path_join( ABSPATH, $dir );
|
| 576 |
}
|
| 577 |
+
}
|
| 578 |
if ( defined('UPLOADS') && !$main_override && ( !isset( $switched ) || $switched === false ) ) {
|
| 579 |
$dir = ABSPATH . UPLOADS;
|
| 580 |
}
|
| 584 |
$dir = untrailingslashit(BLOGUPLOADDIR);
|
| 585 |
}
|
| 586 |
}
|
| 587 |
+
|
| 588 |
return str_replace('\\','/',trailingslashit($dir));
|
| 589 |
}
|
| 590 |
+
|
| 591 |
function backwpup_get_exclude_wp_dirs($folder) {
|
| 592 |
$folder=trailingslashit(str_replace('\\','/',$folder));
|
| 593 |
$excludedir=array();
|
| 603 |
$excludedir[]=backwpup_get_upload_dir();
|
| 604 |
//Exclude Backup dirs
|
| 605 |
$jobs=get_option('backwpup_jobs');
|
| 606 |
+
foreach((array)$jobs as $jobsvale) {
|
| 607 |
if (!empty($jobsvale['backupdir']) and $jobsvale['backupdir']!='/')
|
| 608 |
$excludedir[]=trailingslashit(str_replace('\\','/',$jobsvale['backupdir']));
|
| 609 |
}
|
| 610 |
return $excludedir;
|
| 611 |
}
|
| 612 |
+
|
| 613 |
+
//ajax/normal get backup files and infos
|
| 614 |
+
function backwpup_get_backup_files() {
|
| 615 |
+
$jobs=get_option('backwpup_jobs'); //Load jobs
|
| 616 |
+
$filecounter=0;
|
| 617 |
+
$files=array();
|
| 618 |
+
if (extension_loaded('curl') or @dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll')) {
|
| 619 |
+
if (!class_exists('S3'))
|
| 620 |
+
require_once(plugin_dir_path(__FILE__).'libs/S3.php');
|
| 621 |
+
}
|
| 622 |
+
|
| 623 |
+
if (!is_array($jobs)) //return is Jobs empty
|
| 624 |
+
return false;
|
| 625 |
|
| 626 |
+
foreach ($jobs as $jobid => $jobvalue) { //go job by job
|
| 627 |
+
$jobvalue=backwpup_check_job_vars($jobvalue); //Check job values
|
| 628 |
+
$todo=explode('+',$jobvalue['type']); //only for backup jobs
|
| 629 |
+
if (!in_array('FILE',$todo) and !in_array('DB',$todo) and !in_array('WPEXP',$todo))
|
| 630 |
+
continue;
|
| 631 |
+
|
| 632 |
+
//Get files/filinfo in backup folder
|
| 633 |
+
if (!empty($jobvalue['backupdir'])) {
|
| 634 |
+
if ( $dir = @opendir( $jobvalue['backupdir'] ) ) {
|
| 635 |
+
while (($file = readdir( $dir ) ) !== false ) {
|
| 636 |
+
if (substr($file,0,1)=='.' or strtolower(substr($file,-4))=='.zip' or !(strtolower(substr($file,-4))=='.tar' or strtolower(substr($file,-7))=='.tar.gz' or strtolower(substr($file,-4))=='.tar.bz2'))
|
| 637 |
+
continue;
|
| 638 |
+
if (is_file($jobvalue['backupdir'].$file)) {
|
| 639 |
+
$files[$filecounter]['type']='FOLDER';
|
| 640 |
+
$files[$filecounter]['jobid']=$jobid;
|
| 641 |
+
$files[$filecounter]['file']=$jobvalue['backupdir'].$file;
|
| 642 |
+
$files[$filecounter]['filename']=$file;
|
| 643 |
+
$files[$filecounter]['downloadurl']=wp_nonce_url('admin.php?page=BackWPup&action=download&file='.$jobvalue['backupdir'].$file, 'download-backup_'.$file);
|
| 644 |
+
$files[$filecounter]['filesize']=filesize($jobvalue['backupdir'].$file);
|
| 645 |
+
$files[$filecounter]['time']=filemtime($jobvalue['backupdir'].$file);
|
| 646 |
+
$filecounter++;
|
| 647 |
+
}
|
| 648 |
+
}
|
| 649 |
+
closedir( $dir );
|
| 650 |
+
}
|
| 651 |
+
}
|
| 652 |
+
//Get files/filinfo from S3
|
| 653 |
+
if (class_exists('S3')) {
|
| 654 |
+
if (!empty($jobvalue['awsAccessKey']) and !empty($jobvalue['awsSecretKey']) and !empty($jobvalue['awsBucket'])) {
|
| 655 |
+
$s3 = new S3($jobvalue['awsAccessKey'], $jobvalue['awsSecretKey'], $jobvalue['awsSSL']);
|
| 656 |
+
if (($contents = $s3->getBucket($jobvalue['awsBucket'],$jobvalue['awsdir'])) !== false) {
|
| 657 |
+
foreach ($contents as $object) {
|
| 658 |
+
if (strtolower(substr($object['name'],-4))=='.zip' or strtolower(substr($object['name'],-4))=='.tar' or strtolower(substr($object['name'],-7))=='.tar.gz' or strtolower(substr($object['name'],-4))=='.tar.bz2') {
|
| 659 |
+
$files[$filecounter]['type']='S3';
|
| 660 |
+
$files[$filecounter]['jobid']=$jobid;
|
| 661 |
+
$files[$filecounter]['file']=$object['name'];
|
| 662 |
+
$files[$filecounter]['filename']=basename($object['name']);
|
| 663 |
+
$files[$filecounter]['downloadurl']=wp_nonce_url('admin.php?page=BackWPup&action=downloads3&file='.$object['name'].'&jobid='.$jobid, 'downloads3-backup_'.$object['name']);
|
| 664 |
+
$files[$filecounter]['filesize']=$object['size'];
|
| 665 |
+
$files[$filecounter]['time']=$object['time'];
|
| 666 |
+
$filecounter++;
|
| 667 |
+
}
|
| 668 |
+
}
|
| 669 |
+
}
|
| 670 |
+
}
|
| 671 |
+
}
|
| 672 |
+
//Get files/filinfo from FTP
|
| 673 |
+
if (!empty($jobvalue['ftphost']) and !empty($jobvalue['ftpuser']) and !empty($jobvalue['ftppass'])) {
|
| 674 |
+
$ftpport=21;
|
| 675 |
+
$ftphost=$jobvalue['ftphost'];
|
| 676 |
+
if (false !== strpos($jobvalue['ftphost'],':')) //look for port
|
| 677 |
+
list($ftphost,$ftpport)=explode(':',$jobvalue,2);
|
| 678 |
+
|
| 679 |
+
$SSL=false;
|
| 680 |
+
if (function_exists('ftp_ssl_connect')) { //make SSL FTP connection
|
| 681 |
+
$ftp_conn_id = ftp_ssl_connect($ftphost,$ftpport,10);
|
| 682 |
+
if ($ftp_conn_id)
|
| 683 |
+
$SSL=true;
|
| 684 |
+
}
|
| 685 |
+
if (!$ftp_conn_id) { //make normal FTP conection if SSL not work
|
| 686 |
+
$ftp_conn_id = ftp_connect($ftphost,$ftpport,10);
|
| 687 |
+
}
|
| 688 |
+
if ($ftp_conn_id) {
|
| 689 |
+
//FTP Login
|
| 690 |
+
$loginok=false;
|
| 691 |
+
if (@ftp_login($ftp_conn_id, $jobvalue['ftpuser'], base64_decode($jobvalue['ftppass']))) {
|
| 692 |
+
$loginok=true;
|
| 693 |
+
} else { //if PHP ftp login don't work use raw login
|
| 694 |
+
if (substr(trim(ftp_raw($ftp_conn_id,'USER '.$jobvalue['ftpuser'])),0,3)<400) {
|
| 695 |
+
if (substr(trim(ftp_raw($ftp_conn_id,'PASS '.base64_decode($jobvalue['ftppass']))),0,3)<400) {
|
| 696 |
+
$loginok=true;
|
| 697 |
+
}
|
| 698 |
+
}
|
| 699 |
+
}
|
| 700 |
+
}
|
| 701 |
+
if ($loginok) {
|
| 702 |
+
ftp_pasv($ftp_conn_id, true);
|
| 703 |
+
if ($ftpfilelist=ftp_nlist($ftp_conn_id, $jobvalue['ftpdir'])) {
|
| 704 |
+
foreach($ftpfilelist as $ftpfiles) {
|
| 705 |
+
if (basename($ftpfiles)=='.' or basename($ftpfiles)=='..' or substr(basename($ftpfiles),0,1)=='.' or !(strtolower(substr($ftpfiles,-4))=='.zip' or strtolower(substr($ftpfiles,-4))=='.tar' or strtolower(substr($ftpfiles,-7))=='.tar.gz' or strtolower(substr($ftpfiles,-4))=='.tar.bz2'))
|
| 706 |
+
continue;
|
| 707 |
+
$files[$filecounter]['type']='FTP';
|
| 708 |
+
$files[$filecounter]['jobid']=$jobid;
|
| 709 |
+
$files[$filecounter]['file']=$ftpfiles;
|
| 710 |
+
$files[$filecounter]['filename']=basename($ftpfiles);
|
| 711 |
+
$files[$filecounter]['downloadurl']="ftp://".$jobvalue['ftpuser'].":".base64_decode($jobvalue['ftppass'])."@".$jobvalue['ftphost'].$ftpfiles;
|
| 712 |
+
$files[$filecounter]['filesize']=ftp_size($ftp_conn_id,$ftpfiles);
|
| 713 |
+
$filecounter++;
|
| 714 |
+
}
|
| 715 |
+
}
|
| 716 |
+
}
|
| 717 |
+
}
|
| 718 |
+
}
|
| 719 |
+
//Sort list
|
| 720 |
+
$tmp = Array();
|
| 721 |
+
foreach($files as &$ma)
|
| 722 |
+
$tmp[] = &$ma["filename"];
|
| 723 |
+
array_multisort($tmp, SORT_DESC, $files);
|
| 724 |
+
return $files;
|
| 725 |
+
}
|
| 726 |
+
|
| 727 |
//ajax/normal get buckests select box
|
| 728 |
function backwpup_get_aws_buckets($args='') {
|
| 729 |
if (is_array($args)) {
|
| 743 |
if (empty($awsSecretKey)) {
|
| 744 |
echo '<span id="awsBucket" style="color:red;">'.__('Missing Secret Access Key!','backwpup').'</span>';
|
| 745 |
die();
|
| 746 |
+
}
|
| 747 |
$s3 = new S3($awsAccessKey, $awsSecretKey, false);
|
| 748 |
$buckets=@$s3->listBuckets();
|
| 749 |
if (!is_array($buckets)) {
|
| 750 |
echo '<span id="awsBucket" style="color:red;">'.__('No Buckets found! Or wrong Keys!','backwpup').'</span>';
|
| 751 |
die();
|
| 752 |
+
}
|
| 753 |
echo '<select name="awsBucket" id="awsBucket">';
|
| 754 |
foreach ($buckets as $bucket) {
|
| 755 |
echo "<option ".selected(strtolower($selected),strtolower($bucket),false).">".$bucket."</option>";
|
| 758 |
if ($ajax)
|
| 759 |
die();
|
| 760 |
}
|
| 761 |
+
|
| 762 |
// add all action and so on only if plugin loaded.
|
| 763 |
function backwpup_init() {
|
| 764 |
//Disabele WP_Corn
|
| 768 |
//add Menu
|
| 769 |
add_action('admin_menu', 'backwpup_menu_entry');
|
| 770 |
//Additional links on the plugin page
|
| 771 |
+
if (current_user_can(10))
|
| 772 |
add_filter('plugin_action_links_'.BACKWPUP_PLUGIN_BASEDIR.'/backwpup.php', 'backwpup_plugin_options_link');
|
| 773 |
+
if (current_user_can('install_plugins'))
|
| 774 |
add_filter('plugin_row_meta', 'backwpup_plugin_links',10,2);
|
| 775 |
//add cron intervals
|
| 776 |
add_filter('cron_schedules', 'backwpup_intervals');
|
| 777 |
//Actions for Cron job
|
| 778 |
add_action('backwpup_cron', 'backwpup_dojob');
|
| 779 |
//add Dashboard widget
|
| 780 |
+
if (current_user_can(10))
|
| 781 |
add_action('wp_dashboard_setup', 'backwpup_add_dashboard');
|
| 782 |
// add ajax function
|
| 783 |
add_action('wp_ajax_backwpup_get_aws_buckets', 'backwpup_get_aws_buckets');
|
| 784 |
+
}
|
| 785 |
|
| 786 |
?>
|
app/libs/S3.php
CHANGED
|
@@ -1,1365 +1,1365 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/**
|
| 3 |
-
* $Id: S3.php 47 2009-07-20 01:25:40Z don.schonknecht $
|
| 4 |
-
*
|
| 5 |
-
* Copyright (c) 2008, Donovan Schönknecht. All rights reserved.
|
| 6 |
-
*
|
| 7 |
-
* Redistribution and use in source and binary forms, with or without
|
| 8 |
-
* modification, are permitted provided that the following conditions are met:
|
| 9 |
-
*
|
| 10 |
-
* - Redistributions of source code must retain the above copyright notice,
|
| 11 |
-
* this list of conditions and the following disclaimer.
|
| 12 |
-
* - Redistributions in binary form must reproduce the above copyright
|
| 13 |
-
* notice, this list of conditions and the following disclaimer in the
|
| 14 |
-
* documentation and/or other materials provided with the distribution.
|
| 15 |
-
*
|
| 16 |
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
| 17 |
-
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| 18 |
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
| 19 |
-
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
| 20 |
-
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
| 21 |
-
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
| 22 |
-
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
| 23 |
-
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
| 24 |
-
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
| 25 |
-
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
| 26 |
-
* POSSIBILITY OF SUCH DAMAGE.
|
| 27 |
-
*
|
| 28 |
-
* Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
|
| 29 |
-
*/
|
| 30 |
-
|
| 31 |
-
/**
|
| 32 |
-
* Amazon S3 PHP class
|
| 33 |
-
*
|
| 34 |
-
* @link http://undesigned.org.za/2007/10/22/amazon-s3-php-class
|
| 35 |
-
* @version 0.4.0
|
| 36 |
-
*/
|
| 37 |
-
class S3 {
|
| 38 |
-
// ACL flags
|
| 39 |
-
const ACL_PRIVATE = 'private';
|
| 40 |
-
const ACL_PUBLIC_READ = 'public-read';
|
| 41 |
-
const ACL_PUBLIC_READ_WRITE = 'public-read-write';
|
| 42 |
-
const ACL_AUTHENTICATED_READ = 'authenticated-read';
|
| 43 |
-
|
| 44 |
-
public static $useSSL = true;
|
| 45 |
-
|
| 46 |
-
private static $__accessKey; // AWS Access key
|
| 47 |
-
private static $__secretKey; // AWS Secret key
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
/**
|
| 51 |
-
* Constructor - if you're not using the class statically
|
| 52 |
-
*
|
| 53 |
-
* @param string $accessKey Access key
|
| 54 |
-
* @param string $secretKey Secret key
|
| 55 |
-
* @param boolean $useSSL Enable SSL
|
| 56 |
-
* @return void
|
| 57 |
-
*/
|
| 58 |
-
public function __construct($accessKey = null, $secretKey = null, $useSSL = true) {
|
| 59 |
-
if ($accessKey !== null && $secretKey !== null)
|
| 60 |
-
self::setAuth($accessKey, $secretKey);
|
| 61 |
-
self::$useSSL = $useSSL;
|
| 62 |
-
}
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
/**
|
| 66 |
-
* Set AWS access key and secret key
|
| 67 |
-
*
|
| 68 |
-
* @param string $accessKey Access key
|
| 69 |
-
* @param string $secretKey Secret key
|
| 70 |
-
* @return void
|
| 71 |
-
*/
|
| 72 |
-
public static function setAuth($accessKey, $secretKey) {
|
| 73 |
-
self::$__accessKey = $accessKey;
|
| 74 |
-
self::$__secretKey = $secretKey;
|
| 75 |
-
}
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
/**
|
| 79 |
-
* Get a list of buckets
|
| 80 |
-
*
|
| 81 |
-
* @param boolean $detailed Returns detailed bucket list when true
|
| 82 |
-
* @return array | false
|
| 83 |
-
*/
|
| 84 |
-
public static function listBuckets($detailed = false) {
|
| 85 |
-
$rest = new S3Request('GET', '', '');
|
| 86 |
-
$rest = $rest->getResponse();
|
| 87 |
-
if ($rest->error === false && $rest->code !== 200)
|
| 88 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 89 |
-
if ($rest->error !== false) {
|
| 90 |
-
trigger_error(sprintf("S3::listBuckets(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 91 |
-
return false;
|
| 92 |
-
}
|
| 93 |
-
$results = array();
|
| 94 |
-
if (!isset($rest->body->Buckets)) return $results;
|
| 95 |
-
|
| 96 |
-
if ($detailed) {
|
| 97 |
-
if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName))
|
| 98 |
-
$results['owner'] = array(
|
| 99 |
-
'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->ID
|
| 100 |
-
);
|
| 101 |
-
$results['buckets'] = array();
|
| 102 |
-
foreach ($rest->body->Buckets->Bucket as $b)
|
| 103 |
-
$results['buckets'][] = array(
|
| 104 |
-
'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate)
|
| 105 |
-
);
|
| 106 |
-
} else
|
| 107 |
-
foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name;
|
| 108 |
-
|
| 109 |
-
return $results;
|
| 110 |
-
}
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
/*
|
| 114 |
-
* Get contents for a bucket
|
| 115 |
-
*
|
| 116 |
-
* If maxKeys is null this method will loop through truncated result sets
|
| 117 |
-
*
|
| 118 |
-
* @param string $bucket Bucket name
|
| 119 |
-
* @param string $prefix Prefix
|
| 120 |
-
* @param string $marker Marker (last file listed)
|
| 121 |
-
* @param string $maxKeys Max keys (maximum number of keys to return)
|
| 122 |
-
* @param string $delimiter Delimiter
|
| 123 |
-
* @param boolean $returnCommonPrefixes Set to true to return CommonPrefixes
|
| 124 |
-
* @return array | false
|
| 125 |
-
*/
|
| 126 |
-
public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null, $delimiter = null, $returnCommonPrefixes = false) {
|
| 127 |
-
$rest = new S3Request('GET', $bucket, '');
|
| 128 |
-
if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
|
| 129 |
-
if ($marker !== null && $marker !== '') $rest->setParameter('marker', $marker);
|
| 130 |
-
if ($maxKeys !== null && $maxKeys !== '') $rest->setParameter('max-keys', $maxKeys);
|
| 131 |
-
if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
|
| 132 |
-
$response = $rest->getResponse();
|
| 133 |
-
if ($response->error === false && $response->code !== 200)
|
| 134 |
-
$response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status');
|
| 135 |
-
if ($response->error !== false) {
|
| 136 |
-
trigger_error(sprintf("S3::getBucket(): [%s] %s", $response->error['code'], $response->error['message']), E_USER_WARNING);
|
| 137 |
-
return false;
|
| 138 |
-
}
|
| 139 |
-
|
| 140 |
-
$results = array();
|
| 141 |
-
|
| 142 |
-
$nextMarker = null;
|
| 143 |
-
if (isset($response->body, $response->body->Contents))
|
| 144 |
-
foreach ($response->body->Contents as $c) {
|
| 145 |
-
$results[(string)$c->Key] = array(
|
| 146 |
-
'name' => (string)$c->Key,
|
| 147 |
-
'time' => strtotime((string)$c->LastModified),
|
| 148 |
-
'size' => (int)$c->Size,
|
| 149 |
-
'hash' => substr((string)$c->ETag, 1, -1)
|
| 150 |
-
);
|
| 151 |
-
$nextMarker = (string)$c->Key;
|
| 152 |
-
}
|
| 153 |
-
|
| 154 |
-
if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
|
| 155 |
-
foreach ($response->body->CommonPrefixes as $c)
|
| 156 |
-
$results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
|
| 157 |
-
|
| 158 |
-
if (isset($response->body, $response->body->IsTruncated) &&
|
| 159 |
-
(string)$response->body->IsTruncated == 'false') return $results;
|
| 160 |
-
|
| 161 |
-
if (isset($response->body, $response->body->NextMarker))
|
| 162 |
-
$nextMarker = (string)$response->body->NextMarker;
|
| 163 |
-
|
| 164 |
-
// Loop through truncated results if maxKeys isn't specified
|
| 165 |
-
if ($maxKeys == null && $nextMarker !== null && (string)$response->body->IsTruncated == 'true')
|
| 166 |
-
do {
|
| 167 |
-
$rest = new S3Request('GET', $bucket, '');
|
| 168 |
-
if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
|
| 169 |
-
$rest->setParameter('marker', $nextMarker);
|
| 170 |
-
if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
|
| 171 |
-
|
| 172 |
-
if (($response = $rest->getResponse(true)) == false || $response->code !== 200) break;
|
| 173 |
-
|
| 174 |
-
if (isset($response->body, $response->body->Contents))
|
| 175 |
-
foreach ($response->body->Contents as $c) {
|
| 176 |
-
$results[(string)$c->Key] = array(
|
| 177 |
-
'name' => (string)$c->Key,
|
| 178 |
-
'time' => strtotime((string)$c->LastModified),
|
| 179 |
-
'size' => (int)$c->Size,
|
| 180 |
-
'hash' => substr((string)$c->ETag, 1, -1)
|
| 181 |
-
);
|
| 182 |
-
$nextMarker = (string)$c->Key;
|
| 183 |
-
}
|
| 184 |
-
|
| 185 |
-
if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
|
| 186 |
-
foreach ($response->body->CommonPrefixes as $c)
|
| 187 |
-
$results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
|
| 188 |
-
|
| 189 |
-
if (isset($response->body, $response->body->NextMarker))
|
| 190 |
-
$nextMarker = (string)$response->body->NextMarker;
|
| 191 |
-
|
| 192 |
-
} while ($response !== false && (string)$response->body->IsTruncated == 'true');
|
| 193 |
-
|
| 194 |
-
return $results;
|
| 195 |
-
}
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
/**
|
| 199 |
-
* Put a bucket
|
| 200 |
-
*
|
| 201 |
-
* @param string $bucket Bucket name
|
| 202 |
-
* @param constant $acl ACL flag
|
| 203 |
-
* @param string $location Set as "EU" to create buckets hosted in Europe
|
| 204 |
-
* @return boolean
|
| 205 |
-
*/
|
| 206 |
-
public static function putBucket($bucket, $acl = self::ACL_PRIVATE, $location = false) {
|
| 207 |
-
$rest = new S3Request('PUT', $bucket, '');
|
| 208 |
-
$rest->setAmzHeader('x-amz-acl', $acl);
|
| 209 |
-
|
| 210 |
-
if ($location !== false) {
|
| 211 |
-
$dom = new DOMDocument;
|
| 212 |
-
$createBucketConfiguration = $dom->createElement('CreateBucketConfiguration');
|
| 213 |
-
$locationConstraint = $dom->createElement('LocationConstraint', strtoupper($location));
|
| 214 |
-
$createBucketConfiguration->appendChild($locationConstraint);
|
| 215 |
-
$dom->appendChild($createBucketConfiguration);
|
| 216 |
-
$rest->data = $dom->saveXML();
|
| 217 |
-
$rest->size = strlen($rest->data);
|
| 218 |
-
$rest->setHeader('Content-Type', 'application/xml');
|
| 219 |
-
}
|
| 220 |
-
$rest = $rest->getResponse();
|
| 221 |
-
|
| 222 |
-
if ($rest->error === false && $rest->code !== 200)
|
| 223 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 224 |
-
if ($rest->error !== false) {
|
| 225 |
-
trigger_error(sprintf("S3::putBucket({$bucket}, {$acl}, {$location}): [%s] %s",
|
| 226 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 227 |
-
return false;
|
| 228 |
-
}
|
| 229 |
-
return true;
|
| 230 |
-
}
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
/**
|
| 234 |
-
* Delete an empty bucket
|
| 235 |
-
*
|
| 236 |
-
* @param string $bucket Bucket name
|
| 237 |
-
* @return boolean
|
| 238 |
-
*/
|
| 239 |
-
public static function deleteBucket($bucket) {
|
| 240 |
-
$rest = new S3Request('DELETE', $bucket);
|
| 241 |
-
$rest = $rest->getResponse();
|
| 242 |
-
if ($rest->error === false && $rest->code !== 204)
|
| 243 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 244 |
-
if ($rest->error !== false) {
|
| 245 |
-
trigger_error(sprintf("S3::deleteBucket({$bucket}): [%s] %s",
|
| 246 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 247 |
-
return false;
|
| 248 |
-
}
|
| 249 |
-
return true;
|
| 250 |
-
}
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
/**
|
| 254 |
-
* Create input info array for putObject()
|
| 255 |
-
*
|
| 256 |
-
* @param string $file Input file
|
| 257 |
-
* @param mixed $md5sum Use MD5 hash (supply a string if you want to use your own)
|
| 258 |
-
* @return array | false
|
| 259 |
-
*/
|
| 260 |
-
public static function inputFile($file, $md5sum = true) {
|
| 261 |
-
if (!file_exists($file) || !is_file($file) || !is_readable($file)) {
|
| 262 |
-
trigger_error('S3::inputFile(): Unable to open input file: '.$file, E_USER_WARNING);
|
| 263 |
-
return false;
|
| 264 |
-
}
|
| 265 |
-
return array('file' => $file, 'size' => filesize($file),
|
| 266 |
-
'md5sum' => $md5sum !== false ? (is_string($md5sum) ? $md5sum :
|
| 267 |
-
base64_encode(md5_file($file, true))) : '');
|
| 268 |
-
}
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
/**
|
| 272 |
-
* Create input array info for putObject() with a resource
|
| 273 |
-
*
|
| 274 |
-
* @param string $resource Input resource to read from
|
| 275 |
-
* @param integer $bufferSize Input byte size
|
| 276 |
-
* @param string $md5sum MD5 hash to send (optional)
|
| 277 |
-
* @return array | false
|
| 278 |
-
*/
|
| 279 |
-
public static function inputResource(&$resource, $bufferSize, $md5sum = '') {
|
| 280 |
-
if (!is_resource($resource) || $bufferSize < 0) {
|
| 281 |
-
trigger_error('S3::inputResource(): Invalid resource or buffer size', E_USER_WARNING);
|
| 282 |
-
return false;
|
| 283 |
-
}
|
| 284 |
-
$input = array('size' => $bufferSize, 'md5sum' => $md5sum);
|
| 285 |
-
$input['fp'] =& $resource;
|
| 286 |
-
return $input;
|
| 287 |
-
}
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
/**
|
| 291 |
-
* Put an object
|
| 292 |
-
*
|
| 293 |
-
* @param mixed $input Input data
|
| 294 |
-
* @param string $bucket Bucket name
|
| 295 |
-
* @param string $uri Object URI
|
| 296 |
-
* @param constant $acl ACL constant
|
| 297 |
-
* @param array $metaHeaders Array of x-amz-meta-* headers
|
| 298 |
-
* @param array $requestHeaders Array of request headers or content type as a string
|
| 299 |
-
* @return boolean
|
| 300 |
-
*/
|
| 301 |
-
public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
|
| 302 |
-
if ($input === false) return false;
|
| 303 |
-
$rest = new S3Request('PUT', $bucket, $uri);
|
| 304 |
-
|
| 305 |
-
if (is_string($input)) $input = array(
|
| 306 |
-
'data' => $input, 'size' => strlen($input),
|
| 307 |
-
'md5sum' => base64_encode(md5($input, true))
|
| 308 |
-
);
|
| 309 |
-
|
| 310 |
-
// Data
|
| 311 |
-
if (isset($input['fp']))
|
| 312 |
-
$rest->fp =& $input['fp'];
|
| 313 |
-
elseif (isset($input['file']))
|
| 314 |
-
$rest->fp = @fopen($input['file'], 'rb');
|
| 315 |
-
elseif (isset($input['data']))
|
| 316 |
-
$rest->data = $input['data'];
|
| 317 |
-
|
| 318 |
-
// Content-Length (required)
|
| 319 |
-
if (isset($input['size']) && $input['size'] >= 0)
|
| 320 |
-
$rest->size = $input['size'];
|
| 321 |
-
else {
|
| 322 |
-
if (isset($input['file']))
|
| 323 |
-
$rest->size = filesize($input['file']);
|
| 324 |
-
elseif (isset($input['data']))
|
| 325 |
-
$rest->size = strlen($input['data']);
|
| 326 |
-
}
|
| 327 |
-
|
| 328 |
-
// Custom request headers (Content-Type, Content-Disposition, Content-Encoding)
|
| 329 |
-
if (is_array($requestHeaders))
|
| 330 |
-
foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
|
| 331 |
-
elseif (is_string($requestHeaders)) // Support for legacy contentType parameter
|
| 332 |
-
$input['type'] = $requestHeaders;
|
| 333 |
-
|
| 334 |
-
// Content-Type
|
| 335 |
-
if (!isset($input['type'])) {
|
| 336 |
-
if (isset($requestHeaders['Content-Type']))
|
| 337 |
-
$input['type'] =& $requestHeaders['Content-Type'];
|
| 338 |
-
elseif (isset($input['file']))
|
| 339 |
-
$input['type'] = self::__getMimeType($input['file']);
|
| 340 |
-
else
|
| 341 |
-
$input['type'] = 'application/octet-stream';
|
| 342 |
-
}
|
| 343 |
-
|
| 344 |
-
// We need to post with Content-Length and Content-Type, MD5 is optional
|
| 345 |
-
if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false)) {
|
| 346 |
-
$rest->setHeader('Content-Type', $input['type']);
|
| 347 |
-
if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']);
|
| 348 |
-
|
| 349 |
-
$rest->setAmzHeader('x-amz-acl', $acl);
|
| 350 |
-
foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
|
| 351 |
-
$rest->getResponse();
|
| 352 |
-
} else
|
| 353 |
-
$rest->response->error = array('code' => 0, 'message' => 'Missing input parameters');
|
| 354 |
-
|
| 355 |
-
if ($rest->response->error === false && $rest->response->code !== 200)
|
| 356 |
-
$rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
|
| 357 |
-
if ($rest->response->error !== false) {
|
| 358 |
-
trigger_error(sprintf("S3::putObject(): [%s] %s", $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
|
| 359 |
-
return false;
|
| 360 |
-
}
|
| 361 |
-
return true;
|
| 362 |
-
}
|
| 363 |
-
|
| 364 |
-
|
| 365 |
-
/**
|
| 366 |
-
* Put an object from a file (legacy function)
|
| 367 |
-
*
|
| 368 |
-
* @param string $file Input file path
|
| 369 |
-
* @param string $bucket Bucket name
|
| 370 |
-
* @param string $uri Object URI
|
| 371 |
-
* @param constant $acl ACL constant
|
| 372 |
-
* @param array $metaHeaders Array of x-amz-meta-* headers
|
| 373 |
-
* @param string $contentType Content type
|
| 374 |
-
* @return boolean
|
| 375 |
-
*/
|
| 376 |
-
public static function putObjectFile($file, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null) {
|
| 377 |
-
return self::putObject(self::inputFile($file), $bucket, $uri, $acl, $metaHeaders, $contentType);
|
| 378 |
-
}
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
/**
|
| 382 |
-
* Put an object from a string (legacy function)
|
| 383 |
-
*
|
| 384 |
-
* @param string $string Input data
|
| 385 |
-
* @param string $bucket Bucket name
|
| 386 |
-
* @param string $uri Object URI
|
| 387 |
-
* @param constant $acl ACL constant
|
| 388 |
-
* @param array $metaHeaders Array of x-amz-meta-* headers
|
| 389 |
-
* @param string $contentType Content type
|
| 390 |
-
* @return boolean
|
| 391 |
-
*/
|
| 392 |
-
public static function putObjectString($string, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = 'text/plain') {
|
| 393 |
-
return self::putObject($string, $bucket, $uri, $acl, $metaHeaders, $contentType);
|
| 394 |
-
}
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
/**
|
| 398 |
-
* Get an object
|
| 399 |
-
*
|
| 400 |
-
* @param string $bucket Bucket name
|
| 401 |
-
* @param string $uri Object URI
|
| 402 |
-
* @param mixed $saveTo Filename or resource to write to
|
| 403 |
-
* @return mixed
|
| 404 |
-
*/
|
| 405 |
-
public static function getObject($bucket, $uri, $saveTo = false) {
|
| 406 |
-
$rest = new S3Request('GET', $bucket, $uri);
|
| 407 |
-
if ($saveTo !== false) {
|
| 408 |
-
if (is_resource($saveTo))
|
| 409 |
-
$rest->fp =& $saveTo;
|
| 410 |
-
else
|
| 411 |
-
if (($rest->fp = @fopen($saveTo, 'wb')) !== false)
|
| 412 |
-
$rest->file = realpath($saveTo);
|
| 413 |
-
else
|
| 414 |
-
$rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo);
|
| 415 |
-
}
|
| 416 |
-
if ($rest->response->error === false) $rest->getResponse();
|
| 417 |
-
|
| 418 |
-
if ($rest->response->error === false && $rest->response->code !== 200)
|
| 419 |
-
$rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
|
| 420 |
-
if ($rest->response->error !== false) {
|
| 421 |
-
trigger_error(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s",
|
| 422 |
-
$rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
|
| 423 |
-
return false;
|
| 424 |
-
}
|
| 425 |
-
return $rest->response;
|
| 426 |
-
}
|
| 427 |
-
|
| 428 |
-
|
| 429 |
-
/**
|
| 430 |
-
* Get object information
|
| 431 |
-
*
|
| 432 |
-
* @param string $bucket Bucket name
|
| 433 |
-
* @param string $uri Object URI
|
| 434 |
-
* @param boolean $returnInfo Return response information
|
| 435 |
-
* @return mixed | false
|
| 436 |
-
*/
|
| 437 |
-
public static function getObjectInfo($bucket, $uri, $returnInfo = true) {
|
| 438 |
-
$rest = new S3Request('HEAD', $bucket, $uri);
|
| 439 |
-
$rest = $rest->getResponse();
|
| 440 |
-
if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404))
|
| 441 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 442 |
-
if ($rest->error !== false) {
|
| 443 |
-
trigger_error(sprintf("S3::getObjectInfo({$bucket}, {$uri}): [%s] %s",
|
| 444 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 445 |
-
return false;
|
| 446 |
-
}
|
| 447 |
-
return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false;
|
| 448 |
-
}
|
| 449 |
-
|
| 450 |
-
|
| 451 |
-
/**
|
| 452 |
-
* Copy an object
|
| 453 |
-
*
|
| 454 |
-
* @param string $bucket Source bucket name
|
| 455 |
-
* @param string $uri Source object URI
|
| 456 |
-
* @param string $bucket Destination bucket name
|
| 457 |
-
* @param string $uri Destination object URI
|
| 458 |
-
* @param constant $acl ACL constant
|
| 459 |
-
* @param array $metaHeaders Optional array of x-amz-meta-* headers
|
| 460 |
-
* @param array $requestHeaders Optional array of request headers (content type, disposition, etc.)
|
| 461 |
-
* @return mixed | false
|
| 462 |
-
*/
|
| 463 |
-
public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
|
| 464 |
-
$rest = new S3Request('PUT', $bucket, $uri);
|
| 465 |
-
$rest->setHeader('Content-Length', 0);
|
| 466 |
-
foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
|
| 467 |
-
foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
|
| 468 |
-
$rest->setAmzHeader('x-amz-acl', $acl);
|
| 469 |
-
$rest->setAmzHeader('x-amz-copy-source', sprintf('/%s/%s', $srcBucket, $srcUri));
|
| 470 |
-
if (sizeof($requestHeaders) > 0 || sizeof($metaHeaders) > 0)
|
| 471 |
-
$rest->setAmzHeader('x-amz-metadata-directive', 'REPLACE');
|
| 472 |
-
$rest = $rest->getResponse();
|
| 473 |
-
if ($rest->error === false && $rest->code !== 200)
|
| 474 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 475 |
-
if ($rest->error !== false) {
|
| 476 |
-
trigger_error(sprintf("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): [%s] %s",
|
| 477 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 478 |
-
return false;
|
| 479 |
-
}
|
| 480 |
-
return isset($rest->body->LastModified, $rest->body->ETag) ? array(
|
| 481 |
-
'time' => strtotime((string)$rest->body->LastModified),
|
| 482 |
-
'hash' => substr((string)$rest->body->ETag, 1, -1)
|
| 483 |
-
) : false;
|
| 484 |
-
}
|
| 485 |
-
|
| 486 |
-
|
| 487 |
-
/**
|
| 488 |
-
* Set logging for a bucket
|
| 489 |
-
*
|
| 490 |
-
* @param string $bucket Bucket name
|
| 491 |
-
* @param string $targetBucket Target bucket (where logs are stored)
|
| 492 |
-
* @param string $targetPrefix Log prefix (e,g; domain.com-)
|
| 493 |
-
* @return boolean
|
| 494 |
-
*/
|
| 495 |
-
public static function setBucketLogging($bucket, $targetBucket, $targetPrefix = null) {
|
| 496 |
-
// The S3 log delivery group has to be added to the target bucket's ACP
|
| 497 |
-
if ($targetBucket !== null && ($acp = self::getAccessControlPolicy($targetBucket, '')) !== false) {
|
| 498 |
-
// Only add permissions to the target bucket when they do not exist
|
| 499 |
-
$aclWriteSet = false;
|
| 500 |
-
$aclReadSet = false;
|
| 501 |
-
foreach ($acp['acl'] as $acl)
|
| 502 |
-
if ($acl['type'] == 'Group' && $acl['uri'] == 'http://acs.amazonaws.com/groups/s3/LogDelivery') {
|
| 503 |
-
if ($acl['permission'] == 'WRITE') $aclWriteSet = true;
|
| 504 |
-
elseif ($acl['permission'] == 'READ_ACP') $aclReadSet = true;
|
| 505 |
-
}
|
| 506 |
-
if (!$aclWriteSet) $acp['acl'][] = array(
|
| 507 |
-
'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'WRITE'
|
| 508 |
-
);
|
| 509 |
-
if (!$aclReadSet) $acp['acl'][] = array(
|
| 510 |
-
'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'READ_ACP'
|
| 511 |
-
);
|
| 512 |
-
if (!$aclReadSet || !$aclWriteSet) self::setAccessControlPolicy($targetBucket, '', $acp);
|
| 513 |
-
}
|
| 514 |
-
|
| 515 |
-
$dom = new DOMDocument;
|
| 516 |
-
$bucketLoggingStatus = $dom->createElement('BucketLoggingStatus');
|
| 517 |
-
$bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/');
|
| 518 |
-
if ($targetBucket !== null) {
|
| 519 |
-
if ($targetPrefix == null) $targetPrefix = $bucket . '-';
|
| 520 |
-
$loggingEnabled = $dom->createElement('LoggingEnabled');
|
| 521 |
-
$loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket));
|
| 522 |
-
$loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix));
|
| 523 |
-
// TODO: Add TargetGrants?
|
| 524 |
-
$bucketLoggingStatus->appendChild($loggingEnabled);
|
| 525 |
-
}
|
| 526 |
-
$dom->appendChild($bucketLoggingStatus);
|
| 527 |
-
|
| 528 |
-
$rest = new S3Request('PUT', $bucket, '');
|
| 529 |
-
$rest->setParameter('logging', null);
|
| 530 |
-
$rest->data = $dom->saveXML();
|
| 531 |
-
$rest->size = strlen($rest->data);
|
| 532 |
-
$rest->setHeader('Content-Type', 'application/xml');
|
| 533 |
-
$rest = $rest->getResponse();
|
| 534 |
-
if ($rest->error === false && $rest->code !== 200)
|
| 535 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 536 |
-
if ($rest->error !== false) {
|
| 537 |
-
trigger_error(sprintf("S3::setBucketLogging({$bucket}, {$uri}): [%s] %s",
|
| 538 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 539 |
-
return false;
|
| 540 |
-
}
|
| 541 |
-
return true;
|
| 542 |
-
}
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
/**
|
| 546 |
-
* Get logging status for a bucket
|
| 547 |
-
*
|
| 548 |
-
* This will return false if logging is not enabled.
|
| 549 |
-
* Note: To enable logging, you also need to grant write access to the log group
|
| 550 |
-
*
|
| 551 |
-
* @param string $bucket Bucket name
|
| 552 |
-
* @return array | false
|
| 553 |
-
*/
|
| 554 |
-
public static function getBucketLogging($bucket) {
|
| 555 |
-
$rest = new S3Request('GET', $bucket, '');
|
| 556 |
-
$rest->setParameter('logging', null);
|
| 557 |
-
$rest = $rest->getResponse();
|
| 558 |
-
if ($rest->error === false && $rest->code !== 200)
|
| 559 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 560 |
-
if ($rest->error !== false) {
|
| 561 |
-
trigger_error(sprintf("S3::getBucketLogging({$bucket}): [%s] %s",
|
| 562 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 563 |
-
return false;
|
| 564 |
-
}
|
| 565 |
-
if (!isset($rest->body->LoggingEnabled)) return false; // No logging
|
| 566 |
-
return array(
|
| 567 |
-
'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket,
|
| 568 |
-
'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix,
|
| 569 |
-
);
|
| 570 |
-
}
|
| 571 |
-
|
| 572 |
-
|
| 573 |
-
/**
|
| 574 |
-
* Disable bucket logging
|
| 575 |
-
*
|
| 576 |
-
* @param string $bucket Bucket name
|
| 577 |
-
* @return boolean
|
| 578 |
-
*/
|
| 579 |
-
public static function disableBucketLogging($bucket) {
|
| 580 |
-
return self::setBucketLogging($bucket, null);
|
| 581 |
-
}
|
| 582 |
-
|
| 583 |
-
|
| 584 |
-
/**
|
| 585 |
-
* Get a bucket's location
|
| 586 |
-
*
|
| 587 |
-
* @param string $bucket Bucket name
|
| 588 |
-
* @return string | false
|
| 589 |
-
*/
|
| 590 |
-
public static function getBucketLocation($bucket) {
|
| 591 |
-
$rest = new S3Request('GET', $bucket, '');
|
| 592 |
-
$rest->setParameter('location', null);
|
| 593 |
-
$rest = $rest->getResponse();
|
| 594 |
-
if ($rest->error === false && $rest->code !== 200)
|
| 595 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 596 |
-
if ($rest->error !== false) {
|
| 597 |
-
trigger_error(sprintf("S3::getBucketLocation({$bucket}): [%s] %s",
|
| 598 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 599 |
-
return false;
|
| 600 |
-
}
|
| 601 |
-
return (isset($rest->body[0]) && (string)$rest->body[0] !== '') ? (string)$rest->body[0] : 'US';
|
| 602 |
-
}
|
| 603 |
-
|
| 604 |
-
|
| 605 |
-
/**
|
| 606 |
-
* Set object or bucket Access Control Policy
|
| 607 |
-
*
|
| 608 |
-
* @param string $bucket Bucket name
|
| 609 |
-
* @param string $uri Object URI
|
| 610 |
-
* @param array $acp Access Control Policy Data (same as the data returned from getAccessControlPolicy)
|
| 611 |
-
* @return boolean
|
| 612 |
-
*/
|
| 613 |
-
public static function setAccessControlPolicy($bucket, $uri = '', $acp = array()) {
|
| 614 |
-
$dom = new DOMDocument;
|
| 615 |
-
$dom->formatOutput = true;
|
| 616 |
-
$accessControlPolicy = $dom->createElement('AccessControlPolicy');
|
| 617 |
-
$accessControlList = $dom->createElement('AccessControlList');
|
| 618 |
-
|
| 619 |
-
// It seems the owner has to be passed along too
|
| 620 |
-
$owner = $dom->createElement('Owner');
|
| 621 |
-
$owner->appendChild($dom->createElement('ID', $acp['owner']['id']));
|
| 622 |
-
$owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name']));
|
| 623 |
-
$accessControlPolicy->appendChild($owner);
|
| 624 |
-
|
| 625 |
-
foreach ($acp['acl'] as $g) {
|
| 626 |
-
$grant = $dom->createElement('Grant');
|
| 627 |
-
$grantee = $dom->createElement('Grantee');
|
| 628 |
-
$grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
|
| 629 |
-
if (isset($g['id'])) { // CanonicalUser (DisplayName is omitted)
|
| 630 |
-
$grantee->setAttribute('xsi:type', 'CanonicalUser');
|
| 631 |
-
$grantee->appendChild($dom->createElement('ID', $g['id']));
|
| 632 |
-
} elseif (isset($g['email'])) { // AmazonCustomerByEmail
|
| 633 |
-
$grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail');
|
| 634 |
-
$grantee->appendChild($dom->createElement('EmailAddress', $g['email']));
|
| 635 |
-
} elseif ($g['type'] == 'Group') { // Group
|
| 636 |
-
$grantee->setAttribute('xsi:type', 'Group');
|
| 637 |
-
$grantee->appendChild($dom->createElement('URI', $g['uri']));
|
| 638 |
-
}
|
| 639 |
-
$grant->appendChild($grantee);
|
| 640 |
-
$grant->appendChild($dom->createElement('Permission', $g['permission']));
|
| 641 |
-
$accessControlList->appendChild($grant);
|
| 642 |
-
}
|
| 643 |
-
|
| 644 |
-
$accessControlPolicy->appendChild($accessControlList);
|
| 645 |
-
$dom->appendChild($accessControlPolicy);
|
| 646 |
-
|
| 647 |
-
$rest = new S3Request('PUT', $bucket, $uri);
|
| 648 |
-
$rest->setParameter('acl', null);
|
| 649 |
-
$rest->data = $dom->saveXML();
|
| 650 |
-
$rest->size = strlen($rest->data);
|
| 651 |
-
$rest->setHeader('Content-Type', 'application/xml');
|
| 652 |
-
$rest = $rest->getResponse();
|
| 653 |
-
if ($rest->error === false && $rest->code !== 200)
|
| 654 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 655 |
-
if ($rest->error !== false) {
|
| 656 |
-
trigger_error(sprintf("S3::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
|
| 657 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 658 |
-
return false;
|
| 659 |
-
}
|
| 660 |
-
return true;
|
| 661 |
-
}
|
| 662 |
-
|
| 663 |
-
|
| 664 |
-
/**
|
| 665 |
-
* Get object or bucket Access Control Policy
|
| 666 |
-
*
|
| 667 |
-
* @param string $bucket Bucket name
|
| 668 |
-
* @param string $uri Object URI
|
| 669 |
-
* @return mixed | false
|
| 670 |
-
*/
|
| 671 |
-
public static function getAccessControlPolicy($bucket, $uri = '') {
|
| 672 |
-
$rest = new S3Request('GET', $bucket, $uri);
|
| 673 |
-
$rest->setParameter('acl', null);
|
| 674 |
-
$rest = $rest->getResponse();
|
| 675 |
-
if ($rest->error === false && $rest->code !== 200)
|
| 676 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 677 |
-
if ($rest->error !== false) {
|
| 678 |
-
trigger_error(sprintf("S3::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
|
| 679 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 680 |
-
return false;
|
| 681 |
-
}
|
| 682 |
-
|
| 683 |
-
$acp = array();
|
| 684 |
-
if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) {
|
| 685 |
-
$acp['owner'] = array(
|
| 686 |
-
'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName
|
| 687 |
-
);
|
| 688 |
-
}
|
| 689 |
-
if (isset($rest->body->AccessControlList)) {
|
| 690 |
-
$acp['acl'] = array();
|
| 691 |
-
foreach ($rest->body->AccessControlList->Grant as $grant) {
|
| 692 |
-
foreach ($grant->Grantee as $grantee) {
|
| 693 |
-
if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser
|
| 694 |
-
$acp['acl'][] = array(
|
| 695 |
-
'type' => 'CanonicalUser',
|
| 696 |
-
'id' => (string)$grantee->ID,
|
| 697 |
-
'name' => (string)$grantee->DisplayName,
|
| 698 |
-
'permission' => (string)$grant->Permission
|
| 699 |
-
);
|
| 700 |
-
elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail
|
| 701 |
-
$acp['acl'][] = array(
|
| 702 |
-
'type' => 'AmazonCustomerByEmail',
|
| 703 |
-
'email' => (string)$grantee->EmailAddress,
|
| 704 |
-
'permission' => (string)$grant->Permission
|
| 705 |
-
);
|
| 706 |
-
elseif (isset($grantee->URI)) // Group
|
| 707 |
-
$acp['acl'][] = array(
|
| 708 |
-
'type' => 'Group',
|
| 709 |
-
'uri' => (string)$grantee->URI,
|
| 710 |
-
'permission' => (string)$grant->Permission
|
| 711 |
-
);
|
| 712 |
-
else continue;
|
| 713 |
-
}
|
| 714 |
-
}
|
| 715 |
-
}
|
| 716 |
-
return $acp;
|
| 717 |
-
}
|
| 718 |
-
|
| 719 |
-
|
| 720 |
-
/**
|
| 721 |
-
* Delete an object
|
| 722 |
-
*
|
| 723 |
-
* @param string $bucket Bucket name
|
| 724 |
-
* @param string $uri Object URI
|
| 725 |
-
* @return boolean
|
| 726 |
-
*/
|
| 727 |
-
public static function deleteObject($bucket, $uri) {
|
| 728 |
-
$rest = new S3Request('DELETE', $bucket, $uri);
|
| 729 |
-
$rest = $rest->getResponse();
|
| 730 |
-
if ($rest->error === false && $rest->code !== 204)
|
| 731 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 732 |
-
if ($rest->error !== false) {
|
| 733 |
-
trigger_error(sprintf("S3::deleteObject(): [%s] %s",
|
| 734 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 735 |
-
return false;
|
| 736 |
-
}
|
| 737 |
-
return true;
|
| 738 |
-
}
|
| 739 |
-
|
| 740 |
-
|
| 741 |
-
/**
|
| 742 |
-
* Get a query string authenticated URL
|
| 743 |
-
*
|
| 744 |
-
* @param string $bucket Bucket name
|
| 745 |
-
* @param string $uri Object URI
|
| 746 |
-
* @param integer $lifetime Lifetime in seconds
|
| 747 |
-
* @param boolean $hostBucket Use the bucket name as the hostname
|
| 748 |
-
* @param boolean $https Use HTTPS ($hostBucket should be false for SSL verification)
|
| 749 |
-
* @return string
|
| 750 |
-
*/
|
| 751 |
-
public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false) {
|
| 752 |
-
$expires = time() + $lifetime;
|
| 753 |
-
$uri = str_replace('%2F', '/', rawurlencode($uri)); // URI should be encoded (thanks Sean O'Dea)
|
| 754 |
-
return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s',
|
| 755 |
-
$hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires,
|
| 756 |
-
urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}")));
|
| 757 |
-
}
|
| 758 |
-
|
| 759 |
-
/**
|
| 760 |
-
* Get upload POST parameters for form uploads
|
| 761 |
-
*
|
| 762 |
-
* @param string $bucket Bucket name
|
| 763 |
-
* @param string $uriPrefix Object URI prefix
|
| 764 |
-
* @param constant $acl ACL constant
|
| 765 |
-
* @param integer $lifetime Lifetime in seconds
|
| 766 |
-
* @param integer $maxFileSize Maximum filesize in bytes (default 5MB)
|
| 767 |
-
* @param string $successRedirect Redirect URL or 200 / 201 status code
|
| 768 |
-
* @param array $amzHeaders Array of x-amz-meta-* headers
|
| 769 |
-
* @param array $headers Array of request headers or content type as a string
|
| 770 |
-
* @param boolean $flashVars Includes additional "Filename" variable posted by Flash
|
| 771 |
-
* @return object
|
| 772 |
-
*/
|
| 773 |
-
public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = self::ACL_PRIVATE, $lifetime = 3600, $maxFileSize = 5242880, $successRedirect = "201", $amzHeaders = array(), $headers = array(), $flashVars = false) {
|
| 774 |
-
// Create policy object
|
| 775 |
-
$policy = new stdClass;
|
| 776 |
-
$policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime));
|
| 777 |
-
$policy->conditions = array();
|
| 778 |
-
$obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj);
|
| 779 |
-
$obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj);
|
| 780 |
-
|
| 781 |
-
$obj = new stdClass; // 200 for non-redirect uploads
|
| 782 |
-
if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
|
| 783 |
-
$obj->success_action_status = (string)$successRedirect;
|
| 784 |
-
else // URL
|
| 785 |
-
$obj->success_action_redirect = $successRedirect;
|
| 786 |
-
array_push($policy->conditions, $obj);
|
| 787 |
-
|
| 788 |
-
array_push($policy->conditions, array('starts-with', '$key', $uriPrefix));
|
| 789 |
-
if ($flashVars) array_push($policy->conditions, array('starts-with', '$Filename', ''));
|
| 790 |
-
foreach (array_keys($headers) as $headerKey)
|
| 791 |
-
array_push($policy->conditions, array('starts-with', '$'.$headerKey, ''));
|
| 792 |
-
foreach ($amzHeaders as $headerKey => $headerVal) {
|
| 793 |
-
$obj = new stdClass; $obj->{$headerKey} = (string)$headerVal; array_push($policy->conditions, $obj);
|
| 794 |
-
}
|
| 795 |
-
array_push($policy->conditions, array('content-length-range', 0, $maxFileSize));
|
| 796 |
-
$policy = base64_encode(str_replace('\/', '/', json_encode($policy)));
|
| 797 |
-
|
| 798 |
-
// Create parameters
|
| 799 |
-
$params = new stdClass;
|
| 800 |
-
$params->AWSAccessKeyId = self::$__accessKey;
|
| 801 |
-
$params->key = $uriPrefix.'${filename}';
|
| 802 |
-
$params->acl = $acl;
|
| 803 |
-
$params->policy = $policy; unset($policy);
|
| 804 |
-
$params->signature = self::__getHash($params->policy);
|
| 805 |
-
if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
|
| 806 |
-
$params->success_action_status = (string)$successRedirect;
|
| 807 |
-
else
|
| 808 |
-
$params->success_action_redirect = $successRedirect;
|
| 809 |
-
foreach ($headers as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
|
| 810 |
-
foreach ($amzHeaders as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
|
| 811 |
-
return $params;
|
| 812 |
-
}
|
| 813 |
-
|
| 814 |
-
/**
|
| 815 |
-
* Create a CloudFront distribution
|
| 816 |
-
*
|
| 817 |
-
* @param string $bucket Bucket name
|
| 818 |
-
* @param boolean $enabled Enabled (true/false)
|
| 819 |
-
* @param array $cnames Array containing CNAME aliases
|
| 820 |
-
* @param string $comment Use the bucket name as the hostname
|
| 821 |
-
* @return array | false
|
| 822 |
-
*/
|
| 823 |
-
public static function createDistribution($bucket, $enabled = true, $cnames = array(), $comment = '') {
|
| 824 |
-
self::$useSSL = true; // CloudFront requires SSL
|
| 825 |
-
$rest = new S3Request('POST', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com');
|
| 826 |
-
$rest->data = self::__getCloudFrontDistributionConfigXML($bucket.'.s3.amazonaws.com', $enabled, $comment, (string)microtime(true), $cnames);
|
| 827 |
-
$rest->size = strlen($rest->data);
|
| 828 |
-
$rest->setHeader('Content-Type', 'application/xml');
|
| 829 |
-
$rest = self::__getCloudFrontResponse($rest);
|
| 830 |
-
|
| 831 |
-
if ($rest->error === false && $rest->code !== 201)
|
| 832 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 833 |
-
if ($rest->error !== false) {
|
| 834 |
-
trigger_error(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", '$comment'): [%s] %s",
|
| 835 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 836 |
-
return false;
|
| 837 |
-
} elseif ($rest->body instanceof SimpleXMLElement)
|
| 838 |
-
return self::__parseCloudFrontDistributionConfig($rest->body);
|
| 839 |
-
return false;
|
| 840 |
-
}
|
| 841 |
-
|
| 842 |
-
|
| 843 |
-
/**
|
| 844 |
-
* Get CloudFront distribution info
|
| 845 |
-
*
|
| 846 |
-
* @param string $distributionId Distribution ID from listDistributions()
|
| 847 |
-
* @return array | false
|
| 848 |
-
*/
|
| 849 |
-
public static function getDistribution($distributionId) {
|
| 850 |
-
self::$useSSL = true; // CloudFront requires SSL
|
| 851 |
-
$rest = new S3Request('GET', '', '2008-06-30/distribution/'.$distributionId, 'cloudfront.amazonaws.com');
|
| 852 |
-
$rest = self::__getCloudFrontResponse($rest);
|
| 853 |
-
|
| 854 |
-
if ($rest->error === false && $rest->code !== 200)
|
| 855 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 856 |
-
if ($rest->error !== false) {
|
| 857 |
-
trigger_error(sprintf("S3::getDistribution($distributionId): [%s] %s",
|
| 858 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 859 |
-
return false;
|
| 860 |
-
} elseif ($rest->body instanceof SimpleXMLElement) {
|
| 861 |
-
$dist = self::__parseCloudFrontDistributionConfig($rest->body);
|
| 862 |
-
$dist['hash'] = $rest->headers['hash'];
|
| 863 |
-
return $dist;
|
| 864 |
-
}
|
| 865 |
-
return false;
|
| 866 |
-
}
|
| 867 |
-
|
| 868 |
-
|
| 869 |
-
/**
|
| 870 |
-
* Update a CloudFront distribution
|
| 871 |
-
*
|
| 872 |
-
* @param array $dist Distribution array info identical to output of getDistribution()
|
| 873 |
-
* @return array | false
|
| 874 |
-
*/
|
| 875 |
-
public static function updateDistribution($dist) {
|
| 876 |
-
self::$useSSL = true; // CloudFront requires SSL
|
| 877 |
-
$rest = new S3Request('PUT', '', '2008-06-30/distribution/'.$dist['id'].'/config', 'cloudfront.amazonaws.com');
|
| 878 |
-
$rest->data = self::__getCloudFrontDistributionConfigXML($dist['origin'], $dist['enabled'], $dist['comment'], $dist['callerReference'], $dist['cnames']);
|
| 879 |
-
$rest->size = strlen($rest->data);
|
| 880 |
-
$rest->setHeader('If-Match', $dist['hash']);
|
| 881 |
-
$rest = self::__getCloudFrontResponse($rest);
|
| 882 |
-
|
| 883 |
-
if ($rest->error === false && $rest->code !== 200)
|
| 884 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 885 |
-
if ($rest->error !== false) {
|
| 886 |
-
trigger_error(sprintf("S3::updateDistribution({$dist['id']}, ".(int)$enabled.", '$comment'): [%s] %s",
|
| 887 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 888 |
-
return false;
|
| 889 |
-
} else {
|
| 890 |
-
$dist = self::__parseCloudFrontDistributionConfig($rest->body);
|
| 891 |
-
$dist['hash'] = $rest->headers['hash'];
|
| 892 |
-
return $dist;
|
| 893 |
-
}
|
| 894 |
-
return false;
|
| 895 |
-
}
|
| 896 |
-
|
| 897 |
-
|
| 898 |
-
/**
|
| 899 |
-
* Delete a CloudFront distribution
|
| 900 |
-
*
|
| 901 |
-
* @param array $dist Distribution array info identical to output of getDistribution()
|
| 902 |
-
* @return boolean
|
| 903 |
-
*/
|
| 904 |
-
public static function deleteDistribution($dist) {
|
| 905 |
-
self::$useSSL = true; // CloudFront requires SSL
|
| 906 |
-
$rest = new S3Request('DELETE', '', '2008-06-30/distribution/'.$dist['id'], 'cloudfront.amazonaws.com');
|
| 907 |
-
$rest->setHeader('If-Match', $dist['hash']);
|
| 908 |
-
$rest = self::__getCloudFrontResponse($rest);
|
| 909 |
-
|
| 910 |
-
if ($rest->error === false && $rest->code !== 204)
|
| 911 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 912 |
-
if ($rest->error !== false) {
|
| 913 |
-
trigger_error(sprintf("S3::deleteDistribution({$dist['id']}): [%s] %s",
|
| 914 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 915 |
-
return false;
|
| 916 |
-
}
|
| 917 |
-
return true;
|
| 918 |
-
}
|
| 919 |
-
|
| 920 |
-
|
| 921 |
-
/**
|
| 922 |
-
* Get a list of CloudFront distributions
|
| 923 |
-
*
|
| 924 |
-
* @return array
|
| 925 |
-
*/
|
| 926 |
-
public static function listDistributions() {
|
| 927 |
-
self::$useSSL = true; // CloudFront requires SSL
|
| 928 |
-
$rest = new S3Request('GET', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com');
|
| 929 |
-
$rest = self::__getCloudFrontResponse($rest);
|
| 930 |
-
|
| 931 |
-
if ($rest->error === false && $rest->code !== 200)
|
| 932 |
-
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 933 |
-
if ($rest->error !== false) {
|
| 934 |
-
trigger_error(sprintf("S3::listDistributions(): [%s] %s",
|
| 935 |
-
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 936 |
-
return false;
|
| 937 |
-
} elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->DistributionSummary)) {
|
| 938 |
-
$list = array();
|
| 939 |
-
if (isset($rest->body->Marker, $rest->body->MaxItems, $rest->body->IsTruncated)) {
|
| 940 |
-
//$info['marker'] = (string)$rest->body->Marker;
|
| 941 |
-
//$info['maxItems'] = (int)$rest->body->MaxItems;
|
| 942 |
-
//$info['isTruncated'] = (string)$rest->body->IsTruncated == 'true' ? true : false;
|
| 943 |
-
}
|
| 944 |
-
foreach ($rest->body->DistributionSummary as $summary) {
|
| 945 |
-
$list[(string)$summary->Id] = self::__parseCloudFrontDistributionConfig($summary);
|
| 946 |
-
}
|
| 947 |
-
return $list;
|
| 948 |
-
}
|
| 949 |
-
return array();
|
| 950 |
-
}
|
| 951 |
-
|
| 952 |
-
|
| 953 |
-
/**
|
| 954 |
-
* Get a DistributionConfig DOMDocument
|
| 955 |
-
*
|
| 956 |
-
* @internal Used to create XML in createDistribution() and updateDistribution()
|
| 957 |
-
* @param string $bucket Origin bucket
|
| 958 |
-
* @param boolean $enabled Enabled (true/false)
|
| 959 |
-
* @param string $comment Comment to append
|
| 960 |
-
* @param string $callerReference Caller reference
|
| 961 |
-
* @param array $cnames Array of CNAME aliases
|
| 962 |
-
* @return string
|
| 963 |
-
*/
|
| 964 |
-
private static function __getCloudFrontDistributionConfigXML($bucket, $enabled, $comment, $callerReference = '0', $cnames = array()) {
|
| 965 |
-
$dom = new DOMDocument('1.0', 'UTF-8');
|
| 966 |
-
$dom->formatOutput = true;
|
| 967 |
-
$distributionConfig = $dom->createElement('DistributionConfig');
|
| 968 |
-
$distributionConfig->setAttribute('xmlns', 'http://cloudfront.amazonaws.com/doc/2008-06-30/');
|
| 969 |
-
$distributionConfig->appendChild($dom->createElement('Origin', $bucket));
|
| 970 |
-
$distributionConfig->appendChild($dom->createElement('CallerReference', $callerReference));
|
| 971 |
-
foreach ($cnames as $cname)
|
| 972 |
-
$distributionConfig->appendChild($dom->createElement('CNAME', $cname));
|
| 973 |
-
if ($comment !== '') $distributionConfig->appendChild($dom->createElement('Comment', $comment));
|
| 974 |
-
$distributionConfig->appendChild($dom->createElement('Enabled', $enabled ? 'true' : 'false'));
|
| 975 |
-
$dom->appendChild($distributionConfig);
|
| 976 |
-
return $dom->saveXML();
|
| 977 |
-
}
|
| 978 |
-
|
| 979 |
-
|
| 980 |
-
/**
|
| 981 |
-
* Parse a CloudFront distribution config
|
| 982 |
-
*
|
| 983 |
-
* @internal Used to parse the CloudFront DistributionConfig node to an array
|
| 984 |
-
* @param object &$node DOMNode
|
| 985 |
-
* @return array
|
| 986 |
-
*/
|
| 987 |
-
private static function __parseCloudFrontDistributionConfig(&$node) {
|
| 988 |
-
$dist = array();
|
| 989 |
-
if (isset($node->Id, $node->Status, $node->LastModifiedTime, $node->DomainName)) {
|
| 990 |
-
$dist['id'] = (string)$node->Id;
|
| 991 |
-
$dist['status'] = (string)$node->Status;
|
| 992 |
-
$dist['time'] = strtotime((string)$node->LastModifiedTime);
|
| 993 |
-
$dist['domain'] = (string)$node->DomainName;
|
| 994 |
-
}
|
| 995 |
-
if (isset($node->CallerReference))
|
| 996 |
-
$dist['callerReference'] = (string)$node->CallerReference;
|
| 997 |
-
if (isset($node->Comment))
|
| 998 |
-
$dist['comment'] = (string)$node->Comment;
|
| 999 |
-
if (isset($node->Enabled, $node->Origin)) {
|
| 1000 |
-
$dist['origin'] = (string)$node->Origin;
|
| 1001 |
-
$dist['enabled'] = (string)$node->Enabled == 'true' ? true : false;
|
| 1002 |
-
} elseif (isset($node->DistributionConfig)) {
|
| 1003 |
-
$dist = array_merge($dist, self::__parseCloudFrontDistributionConfig($node->DistributionConfig));
|
| 1004 |
-
}
|
| 1005 |
-
if (isset($node->CNAME)) {
|
| 1006 |
-
$dist['cnames'] = array();
|
| 1007 |
-
foreach ($node->CNAME as $cname) $dist['cnames'][(string)$cname] = (string)$cname;
|
| 1008 |
-
}
|
| 1009 |
-
return $dist;
|
| 1010 |
-
}
|
| 1011 |
-
|
| 1012 |
-
|
| 1013 |
-
/**
|
| 1014 |
-
* Grab CloudFront response
|
| 1015 |
-
*
|
| 1016 |
-
* @internal Used to parse the CloudFront S3Request::getResponse() output
|
| 1017 |
-
* @param object &$rest S3Request instance
|
| 1018 |
-
* @return object
|
| 1019 |
-
*/
|
| 1020 |
-
private static function __getCloudFrontResponse(&$rest) {
|
| 1021 |
-
$rest->getResponse();
|
| 1022 |
-
if ($rest->response->error === false && isset($rest->response->body) &&
|
| 1023 |
-
is_string($rest->response->body) && substr($rest->response->body, 0, 5) == '<?xml') {
|
| 1024 |
-
$rest->response->body = simplexml_load_string($rest->response->body);
|
| 1025 |
-
// Grab CloudFront errors
|
| 1026 |
-
if (isset($rest->response->body->Error, $rest->response->body->Error->Code,
|
| 1027 |
-
$rest->response->body->Error->Message)) {
|
| 1028 |
-
$rest->response->error = array(
|
| 1029 |
-
'code' => (string)$rest->response->body->Error->Code,
|
| 1030 |
-
'message' => (string)$rest->response->body->Error->Message
|
| 1031 |
-
);
|
| 1032 |
-
unset($rest->response->body);
|
| 1033 |
-
}
|
| 1034 |
-
}
|
| 1035 |
-
return $rest->response;
|
| 1036 |
-
}
|
| 1037 |
-
|
| 1038 |
-
|
| 1039 |
-
/**
|
| 1040 |
-
* Get MIME type for file
|
| 1041 |
-
*
|
| 1042 |
-
* @internal Used to get mime types
|
| 1043 |
-
* @param string &$file File path
|
| 1044 |
-
* @return string
|
| 1045 |
-
*/
|
| 1046 |
-
public static function __getMimeType(&$file) {
|
| 1047 |
-
$type = false;
|
| 1048 |
-
// Fileinfo documentation says fileinfo_open() will use the
|
| 1049 |
-
// MAGIC env var for the magic file
|
| 1050 |
-
if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) &&
|
| 1051 |
-
($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false) {
|
| 1052 |
-
if (($type = finfo_file($finfo, $file)) !== false) {
|
| 1053 |
-
// Remove the charset and grab the last content-type
|
| 1054 |
-
$type = explode(' ', str_replace('; charset=', ';charset=', $type));
|
| 1055 |
-
$type = array_pop($type);
|
| 1056 |
-
$type = explode(';', $type);
|
| 1057 |
-
$type = trim(array_shift($type));
|
| 1058 |
-
}
|
| 1059 |
-
finfo_close($finfo);
|
| 1060 |
-
|
| 1061 |
-
// If anyone is still using mime_content_type()
|
| 1062 |
-
} elseif (function_exists('mime_content_type'))
|
| 1063 |
-
$type = trim(mime_content_type($file));
|
| 1064 |
-
|
| 1065 |
-
if ($type !== false && strlen($type) > 0) return $type;
|
| 1066 |
-
|
| 1067 |
-
// Otherwise do it the old fashioned way
|
| 1068 |
-
static $exts = array(
|
| 1069 |
-
'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png',
|
| 1070 |
-
'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon',
|
| 1071 |
-
'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf',
|
| 1072 |
-
'zip' => 'application/zip', 'gz' => 'application/x-gzip',
|
| 1073 |
-
'tar' => 'application/x-tar', 'bz' => 'application/x-bzip',
|
| 1074 |
-
'bz2' => 'application/x-bzip2', 'txt' => 'text/plain',
|
| 1075 |
-
'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html',
|
| 1076 |
-
'css' => 'text/css', 'js' => 'text/javascript',
|
| 1077 |
-
'xml' => 'text/xml', 'xsl' => 'application/xsl+xml',
|
| 1078 |
-
'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav',
|
| 1079 |
-
'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
|
| 1080 |
-
'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php'
|
| 1081 |
-
);
|
| 1082 |
-
$ext = strtolower(pathInfo($file, PATHINFO_EXTENSION));
|
| 1083 |
-
return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream';
|
| 1084 |
-
}
|
| 1085 |
-
|
| 1086 |
-
|
| 1087 |
-
/**
|
| 1088 |
-
* Generate the auth string: "AWS AccessKey:Signature"
|
| 1089 |
-
*
|
| 1090 |
-
* @internal Used by S3Request::getResponse()
|
| 1091 |
-
* @param string $string String to sign
|
| 1092 |
-
* @return string
|
| 1093 |
-
*/
|
| 1094 |
-
public static function __getSignature($string) {
|
| 1095 |
-
return 'AWS '.self::$__accessKey.':'.self::__getHash($string);
|
| 1096 |
-
}
|
| 1097 |
-
|
| 1098 |
-
|
| 1099 |
-
/**
|
| 1100 |
-
* Creates a HMAC-SHA1 hash
|
| 1101 |
-
*
|
| 1102 |
-
* This uses the hash extension if loaded
|
| 1103 |
-
*
|
| 1104 |
-
* @internal Used by __getSignature()
|
| 1105 |
-
* @param string $string String to sign
|
| 1106 |
-
* @return string
|
| 1107 |
-
*/
|
| 1108 |
-
private static function __getHash($string) {
|
| 1109 |
-
return base64_encode(extension_loaded('hash') ?
|
| 1110 |
-
hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1(
|
| 1111 |
-
(str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
|
| 1112 |
-
pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^
|
| 1113 |
-
(str_repeat(chr(0x36), 64))) . $string)))));
|
| 1114 |
-
}
|
| 1115 |
-
|
| 1116 |
-
}
|
| 1117 |
-
|
| 1118 |
-
final class S3Request {
|
| 1119 |
-
private $verb, $bucket, $uri, $resource = '', $parameters = array(),
|
| 1120 |
-
$amzHeaders = array(), $headers = array(
|
| 1121 |
-
'Host' => '', 'Date' => '', 'Content-MD5' => '', 'Content-Type' => ''
|
| 1122 |
-
);
|
| 1123 |
-
public $fp = false, $size = 0, $data = false, $response;
|
| 1124 |
-
|
| 1125 |
-
|
| 1126 |
-
/**
|
| 1127 |
-
* Constructor
|
| 1128 |
-
*
|
| 1129 |
-
* @param string $verb Verb
|
| 1130 |
-
* @param string $bucket Bucket name
|
| 1131 |
-
* @param string $uri Object URI
|
| 1132 |
-
* @return mixed
|
| 1133 |
-
*/
|
| 1134 |
-
function __construct($verb, $bucket = '', $uri = '', $defaultHost = 's3.amazonaws.com') {
|
| 1135 |
-
$this->verb = $verb;
|
| 1136 |
-
$this->bucket = strtolower($bucket);
|
| 1137 |
-
$this->uri = $uri !== '' ? '/'.str_replace('%2F', '/', rawurlencode($uri)) : '/';
|
| 1138 |
-
|
| 1139 |
-
if ($this->bucket !== '') {
|
| 1140 |
-
$this->headers['Host'] = $this->bucket.'.'.$defaultHost;
|
| 1141 |
-
$this->resource = '/'.$this->bucket.$this->uri;
|
| 1142 |
-
} else {
|
| 1143 |
-
$this->headers['Host'] = $defaultHost;
|
| 1144 |
-
//$this->resource = strlen($this->uri) > 1 ? '/'.$this->bucket.$this->uri : $this->uri;
|
| 1145 |
-
$this->resource = $this->uri;
|
| 1146 |
-
}
|
| 1147 |
-
$this->headers['Date'] = gmdate('D, d M Y H:i:s T');
|
| 1148 |
-
|
| 1149 |
-
$this->response = new STDClass;
|
| 1150 |
-
$this->response->error = false;
|
| 1151 |
-
}
|
| 1152 |
-
|
| 1153 |
-
|
| 1154 |
-
/**
|
| 1155 |
-
* Set request parameter
|
| 1156 |
-
*
|
| 1157 |
-
* @param string $key Key
|
| 1158 |
-
* @param string $value Value
|
| 1159 |
-
* @return void
|
| 1160 |
-
*/
|
| 1161 |
-
public function setParameter($key, $value) {
|
| 1162 |
-
$this->parameters[$key] = $value;
|
| 1163 |
-
}
|
| 1164 |
-
|
| 1165 |
-
|
| 1166 |
-
/**
|
| 1167 |
-
* Set request header
|
| 1168 |
-
*
|
| 1169 |
-
* @param string $key Key
|
| 1170 |
-
* @param string $value Value
|
| 1171 |
-
* @return void
|
| 1172 |
-
*/
|
| 1173 |
-
public function setHeader($key, $value) {
|
| 1174 |
-
$this->headers[$key] = $value;
|
| 1175 |
-
}
|
| 1176 |
-
|
| 1177 |
-
|
| 1178 |
-
/**
|
| 1179 |
-
* Set x-amz-meta-* header
|
| 1180 |
-
*
|
| 1181 |
-
* @param string $key Key
|
| 1182 |
-
* @param string $value Value
|
| 1183 |
-
* @return void
|
| 1184 |
-
*/
|
| 1185 |
-
public function setAmzHeader($key, $value) {
|
| 1186 |
-
$this->amzHeaders[$key] = $value;
|
| 1187 |
-
}
|
| 1188 |
-
|
| 1189 |
-
|
| 1190 |
-
/**
|
| 1191 |
-
* Get the S3 response
|
| 1192 |
-
*
|
| 1193 |
-
* @return object | false
|
| 1194 |
-
*/
|
| 1195 |
-
public function getResponse() {
|
| 1196 |
-
$query = '';
|
| 1197 |
-
if (sizeof($this->parameters) > 0) {
|
| 1198 |
-
$query = substr($this->uri, -1) !== '?' ? '?' : '&';
|
| 1199 |
-
foreach ($this->parameters as $var => $value)
|
| 1200 |
-
if ($value == null || $value == '') $query .= $var.'&';
|
| 1201 |
-
// Parameters should be encoded (thanks Sean O'Dea)
|
| 1202 |
-
else $query .= $var.'='.rawurlencode($value).'&';
|
| 1203 |
-
$query = substr($query, 0, -1);
|
| 1204 |
-
$this->uri .= $query;
|
| 1205 |
-
|
| 1206 |
-
if (array_key_exists('acl', $this->parameters) ||
|
| 1207 |
-
array_key_exists('location', $this->parameters) ||
|
| 1208 |
-
array_key_exists('torrent', $this->parameters) ||
|
| 1209 |
-
array_key_exists('logging', $this->parameters))
|
| 1210 |
-
$this->resource .= $query;
|
| 1211 |
-
}
|
| 1212 |
-
$url = ((S3::$useSSL && extension_loaded('openssl')) ?
|
| 1213 |
-
'https://':'http://').$this->headers['Host'].$this->uri;
|
| 1214 |
-
//var_dump($this->bucket, $this->uri, $this->resource, $url);
|
| 1215 |
-
|
| 1216 |
-
// Basic setup
|
| 1217 |
-
$curl = curl_init();
|
| 1218 |
-
curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php');
|
| 1219 |
-
|
| 1220 |
-
if (S3::$useSSL) {
|
| 1221 |
-
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
|
| 1222 |
-
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1);
|
| 1223 |
-
}
|
| 1224 |
-
|
| 1225 |
-
curl_setopt($curl, CURLOPT_URL, $url);
|
| 1226 |
-
|
| 1227 |
-
// Headers
|
| 1228 |
-
$headers = array(); $amz = array();
|
| 1229 |
-
foreach ($this->amzHeaders as $header => $value)
|
| 1230 |
-
if (strlen($value) > 0) $headers[] = $header.': '.$value;
|
| 1231 |
-
foreach ($this->headers as $header => $value)
|
| 1232 |
-
if (strlen($value) > 0) $headers[] = $header.': '.$value;
|
| 1233 |
-
|
| 1234 |
-
// Collect AMZ headers for signature
|
| 1235 |
-
foreach ($this->amzHeaders as $header => $value)
|
| 1236 |
-
if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value;
|
| 1237 |
-
|
| 1238 |
-
// AMZ headers must be sorted
|
| 1239 |
-
if (sizeof($amz) > 0) {
|
| 1240 |
-
sort($amz);
|
| 1241 |
-
$amz = "\n".implode("\n", $amz);
|
| 1242 |
-
} else $amz = '';
|
| 1243 |
-
|
| 1244 |
-
// Authorization string (CloudFront stringToSign should only contain a date)
|
| 1245 |
-
$headers[] = 'Authorization: ' . S3::__getSignature(
|
| 1246 |
-
$this->headers['Host'] == 'cloudfront.amazonaws.com' ? $this->headers['Date'] :
|
| 1247 |
-
$this->verb."\n".$this->headers['Content-MD5']."\n".
|
| 1248 |
-
$this->headers['Content-Type']."\n".$this->headers['Date'].$amz."\n".$this->resource
|
| 1249 |
-
);
|
| 1250 |
-
|
| 1251 |
-
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
| 1252 |
-
curl_setopt($curl, CURLOPT_HEADER, false);
|
| 1253 |
-
curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
|
| 1254 |
-
curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
|
| 1255 |
-
curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback'));
|
| 1256 |
-
//curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
| 1257 |
-
|
| 1258 |
-
// Request types
|
| 1259 |
-
switch ($this->verb) {
|
| 1260 |
-
case 'GET': break;
|
| 1261 |
-
case 'PUT': case 'POST': // POST only used for CloudFront
|
| 1262 |
-
if ($this->fp !== false) {
|
| 1263 |
-
curl_setopt($curl, CURLOPT_PUT, true);
|
| 1264 |
-
curl_setopt($curl, CURLOPT_INFILE, $this->fp);
|
| 1265 |
-
if ($this->size >= 0)
|
| 1266 |
-
curl_setopt($curl, CURLOPT_INFILESIZE, $this->size);
|
| 1267 |
-
} elseif ($this->data !== false) {
|
| 1268 |
-
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
|
| 1269 |
-
curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
|
| 1270 |
-
if ($this->size >= 0)
|
| 1271 |
-
curl_setopt($curl, CURLOPT_BUFFERSIZE, $this->size);
|
| 1272 |
-
} else
|
| 1273 |
-
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
|
| 1274 |
-
break;
|
| 1275 |
-
case 'HEAD':
|
| 1276 |
-
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
|
| 1277 |
-
curl_setopt($curl, CURLOPT_NOBODY, true);
|
| 1278 |
-
break;
|
| 1279 |
-
case 'DELETE':
|
| 1280 |
-
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
| 1281 |
-
break;
|
| 1282 |
-
default: break;
|
| 1283 |
-
}
|
| 1284 |
-
|
| 1285 |
-
// Execute, grab errors
|
| 1286 |
-
if (curl_exec($curl))
|
| 1287 |
-
$this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
| 1288 |
-
else
|
| 1289 |
-
$this->response->error = array(
|
| 1290 |
-
'code' => curl_errno($curl),
|
| 1291 |
-
'message' => curl_error($curl),
|
| 1292 |
-
'resource' => $this->resource
|
| 1293 |
-
);
|
| 1294 |
-
|
| 1295 |
-
@curl_close($curl);
|
| 1296 |
-
|
| 1297 |
-
// Parse body into XML
|
| 1298 |
-
if ($this->response->error === false && isset($this->response->headers['type']) &&
|
| 1299 |
-
$this->response->headers['type'] == 'application/xml' && isset($this->response->body)) {
|
| 1300 |
-
$this->response->body = simplexml_load_string($this->response->body);
|
| 1301 |
-
|
| 1302 |
-
// Grab S3 errors
|
| 1303 |
-
if (!in_array($this->response->code, array(200, 204)) &&
|
| 1304 |
-
isset($this->response->body->Code, $this->response->body->Message)) {
|
| 1305 |
-
$this->response->error = array(
|
| 1306 |
-
'code' => (string)$this->response->body->Code,
|
| 1307 |
-
'message' => (string)$this->response->body->Message
|
| 1308 |
-
);
|
| 1309 |
-
if (isset($this->response->body->Resource))
|
| 1310 |
-
$this->response->error['resource'] = (string)$this->response->body->Resource;
|
| 1311 |
-
unset($this->response->body);
|
| 1312 |
-
}
|
| 1313 |
-
}
|
| 1314 |
-
|
| 1315 |
-
// Clean up file resources
|
| 1316 |
-
if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp);
|
| 1317 |
-
|
| 1318 |
-
return $this->response;
|
| 1319 |
-
}
|
| 1320 |
-
|
| 1321 |
-
|
| 1322 |
-
/**
|
| 1323 |
-
* CURL write callback
|
| 1324 |
-
*
|
| 1325 |
-
* @param resource &$curl CURL resource
|
| 1326 |
-
* @param string &$data Data
|
| 1327 |
-
* @return integer
|
| 1328 |
-
*/
|
| 1329 |
-
private function __responseWriteCallback(&$curl, &$data) {
|
| 1330 |
-
if ($this->response->code == 200 && $this->fp !== false)
|
| 1331 |
-
return fwrite($this->fp, $data);
|
| 1332 |
-
else
|
| 1333 |
-
$this->response->body .= $data;
|
| 1334 |
-
return strlen($data);
|
| 1335 |
-
}
|
| 1336 |
-
|
| 1337 |
-
|
| 1338 |
-
/**
|
| 1339 |
-
* CURL header callback
|
| 1340 |
-
*
|
| 1341 |
-
* @param resource &$curl CURL resource
|
| 1342 |
-
* @param string &$data Data
|
| 1343 |
-
* @return integer
|
| 1344 |
-
*/
|
| 1345 |
-
private function __responseHeaderCallback(&$curl, &$data) {
|
| 1346 |
-
if (($strlen = strlen($data)) <= 2) return $strlen;
|
| 1347 |
-
if (substr($data, 0, 4) == 'HTTP')
|
| 1348 |
-
$this->response->code = (int)substr($data, 9, 3);
|
| 1349 |
-
else {
|
| 1350 |
-
list($header, $value) = explode(': ', trim($data), 2);
|
| 1351 |
-
if ($header == 'Last-Modified')
|
| 1352 |
-
$this->response->headers['time'] = strtotime($value);
|
| 1353 |
-
elseif ($header == 'Content-Length')
|
| 1354 |
-
$this->response->headers['size'] = (int)$value;
|
| 1355 |
-
elseif ($header == 'Content-Type')
|
| 1356 |
-
$this->response->headers['type'] = $value;
|
| 1357 |
-
elseif ($header == 'ETag')
|
| 1358 |
-
$this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value;
|
| 1359 |
-
elseif (preg_match('/^x-amz-meta-.*$/', $header))
|
| 1360 |
-
$this->response->headers[$header] = is_numeric($value) ? (int)$value : $value;
|
| 1361 |
-
}
|
| 1362 |
-
return $strlen;
|
| 1363 |
-
}
|
| 1364 |
-
|
| 1365 |
-
}
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* $Id: S3.php 47 2009-07-20 01:25:40Z don.schonknecht $
|
| 4 |
+
*
|
| 5 |
+
* Copyright (c) 2008, Donovan Schönknecht. All rights reserved.
|
| 6 |
+
*
|
| 7 |
+
* Redistribution and use in source and binary forms, with or without
|
| 8 |
+
* modification, are permitted provided that the following conditions are met:
|
| 9 |
+
*
|
| 10 |
+
* - Redistributions of source code must retain the above copyright notice,
|
| 11 |
+
* this list of conditions and the following disclaimer.
|
| 12 |
+
* - Redistributions in binary form must reproduce the above copyright
|
| 13 |
+
* notice, this list of conditions and the following disclaimer in the
|
| 14 |
+
* documentation and/or other materials provided with the distribution.
|
| 15 |
+
*
|
| 16 |
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
| 17 |
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| 18 |
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
| 19 |
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
| 20 |
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
| 21 |
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
| 22 |
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
| 23 |
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
| 24 |
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
| 25 |
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
| 26 |
+
* POSSIBILITY OF SUCH DAMAGE.
|
| 27 |
+
*
|
| 28 |
+
* Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
|
| 29 |
+
*/
|
| 30 |
+
|
| 31 |
+
/**
|
| 32 |
+
* Amazon S3 PHP class
|
| 33 |
+
*
|
| 34 |
+
* @link http://undesigned.org.za/2007/10/22/amazon-s3-php-class
|
| 35 |
+
* @version 0.4.0
|
| 36 |
+
*/
|
| 37 |
+
class S3 {
|
| 38 |
+
// ACL flags
|
| 39 |
+
const ACL_PRIVATE = 'private';
|
| 40 |
+
const ACL_PUBLIC_READ = 'public-read';
|
| 41 |
+
const ACL_PUBLIC_READ_WRITE = 'public-read-write';
|
| 42 |
+
const ACL_AUTHENTICATED_READ = 'authenticated-read';
|
| 43 |
+
|
| 44 |
+
public static $useSSL = true;
|
| 45 |
+
|
| 46 |
+
private static $__accessKey; // AWS Access key
|
| 47 |
+
private static $__secretKey; // AWS Secret key
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
/**
|
| 51 |
+
* Constructor - if you're not using the class statically
|
| 52 |
+
*
|
| 53 |
+
* @param string $accessKey Access key
|
| 54 |
+
* @param string $secretKey Secret key
|
| 55 |
+
* @param boolean $useSSL Enable SSL
|
| 56 |
+
* @return void
|
| 57 |
+
*/
|
| 58 |
+
public function __construct($accessKey = null, $secretKey = null, $useSSL = true) {
|
| 59 |
+
if ($accessKey !== null && $secretKey !== null)
|
| 60 |
+
self::setAuth($accessKey, $secretKey);
|
| 61 |
+
self::$useSSL = $useSSL;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
/**
|
| 66 |
+
* Set AWS access key and secret key
|
| 67 |
+
*
|
| 68 |
+
* @param string $accessKey Access key
|
| 69 |
+
* @param string $secretKey Secret key
|
| 70 |
+
* @return void
|
| 71 |
+
*/
|
| 72 |
+
public static function setAuth($accessKey, $secretKey) {
|
| 73 |
+
self::$__accessKey = $accessKey;
|
| 74 |
+
self::$__secretKey = $secretKey;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
/**
|
| 79 |
+
* Get a list of buckets
|
| 80 |
+
*
|
| 81 |
+
* @param boolean $detailed Returns detailed bucket list when true
|
| 82 |
+
* @return array | false
|
| 83 |
+
*/
|
| 84 |
+
public static function listBuckets($detailed = false) {
|
| 85 |
+
$rest = new S3Request('GET', '', '');
|
| 86 |
+
$rest = $rest->getResponse();
|
| 87 |
+
if ($rest->error === false && $rest->code !== 200)
|
| 88 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 89 |
+
if ($rest->error !== false) {
|
| 90 |
+
trigger_error(sprintf("S3::listBuckets(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 91 |
+
return false;
|
| 92 |
+
}
|
| 93 |
+
$results = array();
|
| 94 |
+
if (!isset($rest->body->Buckets)) return $results;
|
| 95 |
+
|
| 96 |
+
if ($detailed) {
|
| 97 |
+
if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName))
|
| 98 |
+
$results['owner'] = array(
|
| 99 |
+
'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->ID
|
| 100 |
+
);
|
| 101 |
+
$results['buckets'] = array();
|
| 102 |
+
foreach ($rest->body->Buckets->Bucket as $b)
|
| 103 |
+
$results['buckets'][] = array(
|
| 104 |
+
'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate)
|
| 105 |
+
);
|
| 106 |
+
} else
|
| 107 |
+
foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name;
|
| 108 |
+
|
| 109 |
+
return $results;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
/*
|
| 114 |
+
* Get contents for a bucket
|
| 115 |
+
*
|
| 116 |
+
* If maxKeys is null this method will loop through truncated result sets
|
| 117 |
+
*
|
| 118 |
+
* @param string $bucket Bucket name
|
| 119 |
+
* @param string $prefix Prefix
|
| 120 |
+
* @param string $marker Marker (last file listed)
|
| 121 |
+
* @param string $maxKeys Max keys (maximum number of keys to return)
|
| 122 |
+
* @param string $delimiter Delimiter
|
| 123 |
+
* @param boolean $returnCommonPrefixes Set to true to return CommonPrefixes
|
| 124 |
+
* @return array | false
|
| 125 |
+
*/
|
| 126 |
+
public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null, $delimiter = null, $returnCommonPrefixes = false) {
|
| 127 |
+
$rest = new S3Request('GET', $bucket, '');
|
| 128 |
+
if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
|
| 129 |
+
if ($marker !== null && $marker !== '') $rest->setParameter('marker', $marker);
|
| 130 |
+
if ($maxKeys !== null && $maxKeys !== '') $rest->setParameter('max-keys', $maxKeys);
|
| 131 |
+
if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
|
| 132 |
+
$response = $rest->getResponse();
|
| 133 |
+
if ($response->error === false && $response->code !== 200)
|
| 134 |
+
$response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status');
|
| 135 |
+
if ($response->error !== false) {
|
| 136 |
+
trigger_error(sprintf("S3::getBucket(): [%s] %s", $response->error['code'], $response->error['message']), E_USER_WARNING);
|
| 137 |
+
return false;
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
$results = array();
|
| 141 |
+
|
| 142 |
+
$nextMarker = null;
|
| 143 |
+
if (isset($response->body, $response->body->Contents))
|
| 144 |
+
foreach ($response->body->Contents as $c) {
|
| 145 |
+
$results[(string)$c->Key] = array(
|
| 146 |
+
'name' => (string)$c->Key,
|
| 147 |
+
'time' => strtotime((string)$c->LastModified),
|
| 148 |
+
'size' => (int)$c->Size,
|
| 149 |
+
'hash' => substr((string)$c->ETag, 1, -1)
|
| 150 |
+
);
|
| 151 |
+
$nextMarker = (string)$c->Key;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
|
| 155 |
+
foreach ($response->body->CommonPrefixes as $c)
|
| 156 |
+
$results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
|
| 157 |
+
|
| 158 |
+
if (isset($response->body, $response->body->IsTruncated) &&
|
| 159 |
+
(string)$response->body->IsTruncated == 'false') return $results;
|
| 160 |
+
|
| 161 |
+
if (isset($response->body, $response->body->NextMarker))
|
| 162 |
+
$nextMarker = (string)$response->body->NextMarker;
|
| 163 |
+
|
| 164 |
+
// Loop through truncated results if maxKeys isn't specified
|
| 165 |
+
if ($maxKeys == null && $nextMarker !== null && (string)$response->body->IsTruncated == 'true')
|
| 166 |
+
do {
|
| 167 |
+
$rest = new S3Request('GET', $bucket, '');
|
| 168 |
+
if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
|
| 169 |
+
$rest->setParameter('marker', $nextMarker);
|
| 170 |
+
if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
|
| 171 |
+
|
| 172 |
+
if (($response = $rest->getResponse(true)) == false || $response->code !== 200) break;
|
| 173 |
+
|
| 174 |
+
if (isset($response->body, $response->body->Contents))
|
| 175 |
+
foreach ($response->body->Contents as $c) {
|
| 176 |
+
$results[(string)$c->Key] = array(
|
| 177 |
+
'name' => (string)$c->Key,
|
| 178 |
+
'time' => strtotime((string)$c->LastModified),
|
| 179 |
+
'size' => (int)$c->Size,
|
| 180 |
+
'hash' => substr((string)$c->ETag, 1, -1)
|
| 181 |
+
);
|
| 182 |
+
$nextMarker = (string)$c->Key;
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
|
| 186 |
+
foreach ($response->body->CommonPrefixes as $c)
|
| 187 |
+
$results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
|
| 188 |
+
|
| 189 |
+
if (isset($response->body, $response->body->NextMarker))
|
| 190 |
+
$nextMarker = (string)$response->body->NextMarker;
|
| 191 |
+
|
| 192 |
+
} while ($response !== false && (string)$response->body->IsTruncated == 'true');
|
| 193 |
+
|
| 194 |
+
return $results;
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
/**
|
| 199 |
+
* Put a bucket
|
| 200 |
+
*
|
| 201 |
+
* @param string $bucket Bucket name
|
| 202 |
+
* @param constant $acl ACL flag
|
| 203 |
+
* @param string $location Set as "EU" to create buckets hosted in Europe
|
| 204 |
+
* @return boolean
|
| 205 |
+
*/
|
| 206 |
+
public static function putBucket($bucket, $acl = self::ACL_PRIVATE, $location = false) {
|
| 207 |
+
$rest = new S3Request('PUT', $bucket, '');
|
| 208 |
+
$rest->setAmzHeader('x-amz-acl', $acl);
|
| 209 |
+
|
| 210 |
+
if ($location !== false) {
|
| 211 |
+
$dom = new DOMDocument;
|
| 212 |
+
$createBucketConfiguration = $dom->createElement('CreateBucketConfiguration');
|
| 213 |
+
$locationConstraint = $dom->createElement('LocationConstraint', strtoupper($location));
|
| 214 |
+
$createBucketConfiguration->appendChild($locationConstraint);
|
| 215 |
+
$dom->appendChild($createBucketConfiguration);
|
| 216 |
+
$rest->data = $dom->saveXML();
|
| 217 |
+
$rest->size = strlen($rest->data);
|
| 218 |
+
$rest->setHeader('Content-Type', 'application/xml');
|
| 219 |
+
}
|
| 220 |
+
$rest = $rest->getResponse();
|
| 221 |
+
|
| 222 |
+
if ($rest->error === false && $rest->code !== 200)
|
| 223 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 224 |
+
if ($rest->error !== false) {
|
| 225 |
+
trigger_error(sprintf("S3::putBucket({$bucket}, {$acl}, {$location}): [%s] %s",
|
| 226 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 227 |
+
return false;
|
| 228 |
+
}
|
| 229 |
+
return true;
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
|
| 233 |
+
/**
|
| 234 |
+
* Delete an empty bucket
|
| 235 |
+
*
|
| 236 |
+
* @param string $bucket Bucket name
|
| 237 |
+
* @return boolean
|
| 238 |
+
*/
|
| 239 |
+
public static function deleteBucket($bucket) {
|
| 240 |
+
$rest = new S3Request('DELETE', $bucket);
|
| 241 |
+
$rest = $rest->getResponse();
|
| 242 |
+
if ($rest->error === false && $rest->code !== 204)
|
| 243 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 244 |
+
if ($rest->error !== false) {
|
| 245 |
+
trigger_error(sprintf("S3::deleteBucket({$bucket}): [%s] %s",
|
| 246 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 247 |
+
return false;
|
| 248 |
+
}
|
| 249 |
+
return true;
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
/**
|
| 254 |
+
* Create input info array for putObject()
|
| 255 |
+
*
|
| 256 |
+
* @param string $file Input file
|
| 257 |
+
* @param mixed $md5sum Use MD5 hash (supply a string if you want to use your own)
|
| 258 |
+
* @return array | false
|
| 259 |
+
*/
|
| 260 |
+
public static function inputFile($file, $md5sum = true) {
|
| 261 |
+
if (!file_exists($file) || !is_file($file) || !is_readable($file)) {
|
| 262 |
+
trigger_error('S3::inputFile(): Unable to open input file: '.$file, E_USER_WARNING);
|
| 263 |
+
return false;
|
| 264 |
+
}
|
| 265 |
+
return array('file' => $file, 'size' => filesize($file),
|
| 266 |
+
'md5sum' => $md5sum !== false ? (is_string($md5sum) ? $md5sum :
|
| 267 |
+
base64_encode(md5_file($file, true))) : '');
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
|
| 271 |
+
/**
|
| 272 |
+
* Create input array info for putObject() with a resource
|
| 273 |
+
*
|
| 274 |
+
* @param string $resource Input resource to read from
|
| 275 |
+
* @param integer $bufferSize Input byte size
|
| 276 |
+
* @param string $md5sum MD5 hash to send (optional)
|
| 277 |
+
* @return array | false
|
| 278 |
+
*/
|
| 279 |
+
public static function inputResource(&$resource, $bufferSize, $md5sum = '') {
|
| 280 |
+
if (!is_resource($resource) || $bufferSize < 0) {
|
| 281 |
+
trigger_error('S3::inputResource(): Invalid resource or buffer size', E_USER_WARNING);
|
| 282 |
+
return false;
|
| 283 |
+
}
|
| 284 |
+
$input = array('size' => $bufferSize, 'md5sum' => $md5sum);
|
| 285 |
+
$input['fp'] =& $resource;
|
| 286 |
+
return $input;
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
|
| 290 |
+
/**
|
| 291 |
+
* Put an object
|
| 292 |
+
*
|
| 293 |
+
* @param mixed $input Input data
|
| 294 |
+
* @param string $bucket Bucket name
|
| 295 |
+
* @param string $uri Object URI
|
| 296 |
+
* @param constant $acl ACL constant
|
| 297 |
+
* @param array $metaHeaders Array of x-amz-meta-* headers
|
| 298 |
+
* @param array $requestHeaders Array of request headers or content type as a string
|
| 299 |
+
* @return boolean
|
| 300 |
+
*/
|
| 301 |
+
public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
|
| 302 |
+
if ($input === false) return false;
|
| 303 |
+
$rest = new S3Request('PUT', $bucket, $uri);
|
| 304 |
+
|
| 305 |
+
if (is_string($input)) $input = array(
|
| 306 |
+
'data' => $input, 'size' => strlen($input),
|
| 307 |
+
'md5sum' => base64_encode(md5($input, true))
|
| 308 |
+
);
|
| 309 |
+
|
| 310 |
+
// Data
|
| 311 |
+
if (isset($input['fp']))
|
| 312 |
+
$rest->fp =& $input['fp'];
|
| 313 |
+
elseif (isset($input['file']))
|
| 314 |
+
$rest->fp = @fopen($input['file'], 'rb');
|
| 315 |
+
elseif (isset($input['data']))
|
| 316 |
+
$rest->data = $input['data'];
|
| 317 |
+
|
| 318 |
+
// Content-Length (required)
|
| 319 |
+
if (isset($input['size']) && $input['size'] >= 0)
|
| 320 |
+
$rest->size = $input['size'];
|
| 321 |
+
else {
|
| 322 |
+
if (isset($input['file']))
|
| 323 |
+
$rest->size = filesize($input['file']);
|
| 324 |
+
elseif (isset($input['data']))
|
| 325 |
+
$rest->size = strlen($input['data']);
|
| 326 |
+
}
|
| 327 |
+
|
| 328 |
+
// Custom request headers (Content-Type, Content-Disposition, Content-Encoding)
|
| 329 |
+
if (is_array($requestHeaders))
|
| 330 |
+
foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
|
| 331 |
+
elseif (is_string($requestHeaders)) // Support for legacy contentType parameter
|
| 332 |
+
$input['type'] = $requestHeaders;
|
| 333 |
+
|
| 334 |
+
// Content-Type
|
| 335 |
+
if (!isset($input['type'])) {
|
| 336 |
+
if (isset($requestHeaders['Content-Type']))
|
| 337 |
+
$input['type'] =& $requestHeaders['Content-Type'];
|
| 338 |
+
elseif (isset($input['file']))
|
| 339 |
+
$input['type'] = self::__getMimeType($input['file']);
|
| 340 |
+
else
|
| 341 |
+
$input['type'] = 'application/octet-stream';
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
// We need to post with Content-Length and Content-Type, MD5 is optional
|
| 345 |
+
if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false)) {
|
| 346 |
+
$rest->setHeader('Content-Type', $input['type']);
|
| 347 |
+
if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']);
|
| 348 |
+
|
| 349 |
+
$rest->setAmzHeader('x-amz-acl', $acl);
|
| 350 |
+
foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
|
| 351 |
+
$rest->getResponse();
|
| 352 |
+
} else
|
| 353 |
+
$rest->response->error = array('code' => 0, 'message' => 'Missing input parameters');
|
| 354 |
+
|
| 355 |
+
if ($rest->response->error === false && $rest->response->code !== 200)
|
| 356 |
+
$rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
|
| 357 |
+
if ($rest->response->error !== false) {
|
| 358 |
+
trigger_error(sprintf("S3::putObject(): [%s] %s", $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
|
| 359 |
+
return false;
|
| 360 |
+
}
|
| 361 |
+
return true;
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
|
| 365 |
+
/**
|
| 366 |
+
* Put an object from a file (legacy function)
|
| 367 |
+
*
|
| 368 |
+
* @param string $file Input file path
|
| 369 |
+
* @param string $bucket Bucket name
|
| 370 |
+
* @param string $uri Object URI
|
| 371 |
+
* @param constant $acl ACL constant
|
| 372 |
+
* @param array $metaHeaders Array of x-amz-meta-* headers
|
| 373 |
+
* @param string $contentType Content type
|
| 374 |
+
* @return boolean
|
| 375 |
+
*/
|
| 376 |
+
public static function putObjectFile($file, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null) {
|
| 377 |
+
return self::putObject(self::inputFile($file), $bucket, $uri, $acl, $metaHeaders, $contentType);
|
| 378 |
+
}
|
| 379 |
+
|
| 380 |
+
|
| 381 |
+
/**
|
| 382 |
+
* Put an object from a string (legacy function)
|
| 383 |
+
*
|
| 384 |
+
* @param string $string Input data
|
| 385 |
+
* @param string $bucket Bucket name
|
| 386 |
+
* @param string $uri Object URI
|
| 387 |
+
* @param constant $acl ACL constant
|
| 388 |
+
* @param array $metaHeaders Array of x-amz-meta-* headers
|
| 389 |
+
* @param string $contentType Content type
|
| 390 |
+
* @return boolean
|
| 391 |
+
*/
|
| 392 |
+
public static function putObjectString($string, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = 'text/plain') {
|
| 393 |
+
return self::putObject($string, $bucket, $uri, $acl, $metaHeaders, $contentType);
|
| 394 |
+
}
|
| 395 |
+
|
| 396 |
+
|
| 397 |
+
/**
|
| 398 |
+
* Get an object
|
| 399 |
+
*
|
| 400 |
+
* @param string $bucket Bucket name
|
| 401 |
+
* @param string $uri Object URI
|
| 402 |
+
* @param mixed $saveTo Filename or resource to write to
|
| 403 |
+
* @return mixed
|
| 404 |
+
*/
|
| 405 |
+
public static function getObject($bucket, $uri, $saveTo = false) {
|
| 406 |
+
$rest = new S3Request('GET', $bucket, $uri);
|
| 407 |
+
if ($saveTo !== false) {
|
| 408 |
+
if (is_resource($saveTo))
|
| 409 |
+
$rest->fp =& $saveTo;
|
| 410 |
+
else
|
| 411 |
+
if (($rest->fp = @fopen($saveTo, 'wb')) !== false)
|
| 412 |
+
$rest->file = realpath($saveTo);
|
| 413 |
+
else
|
| 414 |
+
$rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo);
|
| 415 |
+
}
|
| 416 |
+
if ($rest->response->error === false) $rest->getResponse();
|
| 417 |
+
|
| 418 |
+
if ($rest->response->error === false && $rest->response->code !== 200)
|
| 419 |
+
$rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
|
| 420 |
+
if ($rest->response->error !== false) {
|
| 421 |
+
trigger_error(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s",
|
| 422 |
+
$rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
|
| 423 |
+
return false;
|
| 424 |
+
}
|
| 425 |
+
return $rest->response;
|
| 426 |
+
}
|
| 427 |
+
|
| 428 |
+
|
| 429 |
+
/**
|
| 430 |
+
* Get object information
|
| 431 |
+
*
|
| 432 |
+
* @param string $bucket Bucket name
|
| 433 |
+
* @param string $uri Object URI
|
| 434 |
+
* @param boolean $returnInfo Return response information
|
| 435 |
+
* @return mixed | false
|
| 436 |
+
*/
|
| 437 |
+
public static function getObjectInfo($bucket, $uri, $returnInfo = true) {
|
| 438 |
+
$rest = new S3Request('HEAD', $bucket, $uri);
|
| 439 |
+
$rest = $rest->getResponse();
|
| 440 |
+
if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404))
|
| 441 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 442 |
+
if ($rest->error !== false) {
|
| 443 |
+
trigger_error(sprintf("S3::getObjectInfo({$bucket}, {$uri}): [%s] %s",
|
| 444 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 445 |
+
return false;
|
| 446 |
+
}
|
| 447 |
+
return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false;
|
| 448 |
+
}
|
| 449 |
+
|
| 450 |
+
|
| 451 |
+
/**
|
| 452 |
+
* Copy an object
|
| 453 |
+
*
|
| 454 |
+
* @param string $bucket Source bucket name
|
| 455 |
+
* @param string $uri Source object URI
|
| 456 |
+
* @param string $bucket Destination bucket name
|
| 457 |
+
* @param string $uri Destination object URI
|
| 458 |
+
* @param constant $acl ACL constant
|
| 459 |
+
* @param array $metaHeaders Optional array of x-amz-meta-* headers
|
| 460 |
+
* @param array $requestHeaders Optional array of request headers (content type, disposition, etc.)
|
| 461 |
+
* @return mixed | false
|
| 462 |
+
*/
|
| 463 |
+
public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
|
| 464 |
+
$rest = new S3Request('PUT', $bucket, $uri);
|
| 465 |
+
$rest->setHeader('Content-Length', 0);
|
| 466 |
+
foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
|
| 467 |
+
foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
|
| 468 |
+
$rest->setAmzHeader('x-amz-acl', $acl);
|
| 469 |
+
$rest->setAmzHeader('x-amz-copy-source', sprintf('/%s/%s', $srcBucket, $srcUri));
|
| 470 |
+
if (sizeof($requestHeaders) > 0 || sizeof($metaHeaders) > 0)
|
| 471 |
+
$rest->setAmzHeader('x-amz-metadata-directive', 'REPLACE');
|
| 472 |
+
$rest = $rest->getResponse();
|
| 473 |
+
if ($rest->error === false && $rest->code !== 200)
|
| 474 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 475 |
+
if ($rest->error !== false) {
|
| 476 |
+
trigger_error(sprintf("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): [%s] %s",
|
| 477 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 478 |
+
return false;
|
| 479 |
+
}
|
| 480 |
+
return isset($rest->body->LastModified, $rest->body->ETag) ? array(
|
| 481 |
+
'time' => strtotime((string)$rest->body->LastModified),
|
| 482 |
+
'hash' => substr((string)$rest->body->ETag, 1, -1)
|
| 483 |
+
) : false;
|
| 484 |
+
}
|
| 485 |
+
|
| 486 |
+
|
| 487 |
+
/**
|
| 488 |
+
* Set logging for a bucket
|
| 489 |
+
*
|
| 490 |
+
* @param string $bucket Bucket name
|
| 491 |
+
* @param string $targetBucket Target bucket (where logs are stored)
|
| 492 |
+
* @param string $targetPrefix Log prefix (e,g; domain.com-)
|
| 493 |
+
* @return boolean
|
| 494 |
+
*/
|
| 495 |
+
public static function setBucketLogging($bucket, $targetBucket, $targetPrefix = null) {
|
| 496 |
+
// The S3 log delivery group has to be added to the target bucket's ACP
|
| 497 |
+
if ($targetBucket !== null && ($acp = self::getAccessControlPolicy($targetBucket, '')) !== false) {
|
| 498 |
+
// Only add permissions to the target bucket when they do not exist
|
| 499 |
+
$aclWriteSet = false;
|
| 500 |
+
$aclReadSet = false;
|
| 501 |
+
foreach ($acp['acl'] as $acl)
|
| 502 |
+
if ($acl['type'] == 'Group' && $acl['uri'] == 'http://acs.amazonaws.com/groups/s3/LogDelivery') {
|
| 503 |
+
if ($acl['permission'] == 'WRITE') $aclWriteSet = true;
|
| 504 |
+
elseif ($acl['permission'] == 'READ_ACP') $aclReadSet = true;
|
| 505 |
+
}
|
| 506 |
+
if (!$aclWriteSet) $acp['acl'][] = array(
|
| 507 |
+
'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'WRITE'
|
| 508 |
+
);
|
| 509 |
+
if (!$aclReadSet) $acp['acl'][] = array(
|
| 510 |
+
'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'READ_ACP'
|
| 511 |
+
);
|
| 512 |
+
if (!$aclReadSet || !$aclWriteSet) self::setAccessControlPolicy($targetBucket, '', $acp);
|
| 513 |
+
}
|
| 514 |
+
|
| 515 |
+
$dom = new DOMDocument;
|
| 516 |
+
$bucketLoggingStatus = $dom->createElement('BucketLoggingStatus');
|
| 517 |
+
$bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/');
|
| 518 |
+
if ($targetBucket !== null) {
|
| 519 |
+
if ($targetPrefix == null) $targetPrefix = $bucket . '-';
|
| 520 |
+
$loggingEnabled = $dom->createElement('LoggingEnabled');
|
| 521 |
+
$loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket));
|
| 522 |
+
$loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix));
|
| 523 |
+
// TODO: Add TargetGrants?
|
| 524 |
+
$bucketLoggingStatus->appendChild($loggingEnabled);
|
| 525 |
+
}
|
| 526 |
+
$dom->appendChild($bucketLoggingStatus);
|
| 527 |
+
|
| 528 |
+
$rest = new S3Request('PUT', $bucket, '');
|
| 529 |
+
$rest->setParameter('logging', null);
|
| 530 |
+
$rest->data = $dom->saveXML();
|
| 531 |
+
$rest->size = strlen($rest->data);
|
| 532 |
+
$rest->setHeader('Content-Type', 'application/xml');
|
| 533 |
+
$rest = $rest->getResponse();
|
| 534 |
+
if ($rest->error === false && $rest->code !== 200)
|
| 535 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 536 |
+
if ($rest->error !== false) {
|
| 537 |
+
trigger_error(sprintf("S3::setBucketLogging({$bucket}, {$uri}): [%s] %s",
|
| 538 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 539 |
+
return false;
|
| 540 |
+
}
|
| 541 |
+
return true;
|
| 542 |
+
}
|
| 543 |
+
|
| 544 |
+
|
| 545 |
+
/**
|
| 546 |
+
* Get logging status for a bucket
|
| 547 |
+
*
|
| 548 |
+
* This will return false if logging is not enabled.
|
| 549 |
+
* Note: To enable logging, you also need to grant write access to the log group
|
| 550 |
+
*
|
| 551 |
+
* @param string $bucket Bucket name
|
| 552 |
+
* @return array | false
|
| 553 |
+
*/
|
| 554 |
+
public static function getBucketLogging($bucket) {
|
| 555 |
+
$rest = new S3Request('GET', $bucket, '');
|
| 556 |
+
$rest->setParameter('logging', null);
|
| 557 |
+
$rest = $rest->getResponse();
|
| 558 |
+
if ($rest->error === false && $rest->code !== 200)
|
| 559 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 560 |
+
if ($rest->error !== false) {
|
| 561 |
+
trigger_error(sprintf("S3::getBucketLogging({$bucket}): [%s] %s",
|
| 562 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 563 |
+
return false;
|
| 564 |
+
}
|
| 565 |
+
if (!isset($rest->body->LoggingEnabled)) return false; // No logging
|
| 566 |
+
return array(
|
| 567 |
+
'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket,
|
| 568 |
+
'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix,
|
| 569 |
+
);
|
| 570 |
+
}
|
| 571 |
+
|
| 572 |
+
|
| 573 |
+
/**
|
| 574 |
+
* Disable bucket logging
|
| 575 |
+
*
|
| 576 |
+
* @param string $bucket Bucket name
|
| 577 |
+
* @return boolean
|
| 578 |
+
*/
|
| 579 |
+
public static function disableBucketLogging($bucket) {
|
| 580 |
+
return self::setBucketLogging($bucket, null);
|
| 581 |
+
}
|
| 582 |
+
|
| 583 |
+
|
| 584 |
+
/**
|
| 585 |
+
* Get a bucket's location
|
| 586 |
+
*
|
| 587 |
+
* @param string $bucket Bucket name
|
| 588 |
+
* @return string | false
|
| 589 |
+
*/
|
| 590 |
+
public static function getBucketLocation($bucket) {
|
| 591 |
+
$rest = new S3Request('GET', $bucket, '');
|
| 592 |
+
$rest->setParameter('location', null);
|
| 593 |
+
$rest = $rest->getResponse();
|
| 594 |
+
if ($rest->error === false && $rest->code !== 200)
|
| 595 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 596 |
+
if ($rest->error !== false) {
|
| 597 |
+
trigger_error(sprintf("S3::getBucketLocation({$bucket}): [%s] %s",
|
| 598 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 599 |
+
return false;
|
| 600 |
+
}
|
| 601 |
+
return (isset($rest->body[0]) && (string)$rest->body[0] !== '') ? (string)$rest->body[0] : 'US';
|
| 602 |
+
}
|
| 603 |
+
|
| 604 |
+
|
| 605 |
+
/**
|
| 606 |
+
* Set object or bucket Access Control Policy
|
| 607 |
+
*
|
| 608 |
+
* @param string $bucket Bucket name
|
| 609 |
+
* @param string $uri Object URI
|
| 610 |
+
* @param array $acp Access Control Policy Data (same as the data returned from getAccessControlPolicy)
|
| 611 |
+
* @return boolean
|
| 612 |
+
*/
|
| 613 |
+
public static function setAccessControlPolicy($bucket, $uri = '', $acp = array()) {
|
| 614 |
+
$dom = new DOMDocument;
|
| 615 |
+
$dom->formatOutput = true;
|
| 616 |
+
$accessControlPolicy = $dom->createElement('AccessControlPolicy');
|
| 617 |
+
$accessControlList = $dom->createElement('AccessControlList');
|
| 618 |
+
|
| 619 |
+
// It seems the owner has to be passed along too
|
| 620 |
+
$owner = $dom->createElement('Owner');
|
| 621 |
+
$owner->appendChild($dom->createElement('ID', $acp['owner']['id']));
|
| 622 |
+
$owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name']));
|
| 623 |
+
$accessControlPolicy->appendChild($owner);
|
| 624 |
+
|
| 625 |
+
foreach ($acp['acl'] as $g) {
|
| 626 |
+
$grant = $dom->createElement('Grant');
|
| 627 |
+
$grantee = $dom->createElement('Grantee');
|
| 628 |
+
$grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
|
| 629 |
+
if (isset($g['id'])) { // CanonicalUser (DisplayName is omitted)
|
| 630 |
+
$grantee->setAttribute('xsi:type', 'CanonicalUser');
|
| 631 |
+
$grantee->appendChild($dom->createElement('ID', $g['id']));
|
| 632 |
+
} elseif (isset($g['email'])) { // AmazonCustomerByEmail
|
| 633 |
+
$grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail');
|
| 634 |
+
$grantee->appendChild($dom->createElement('EmailAddress', $g['email']));
|
| 635 |
+
} elseif ($g['type'] == 'Group') { // Group
|
| 636 |
+
$grantee->setAttribute('xsi:type', 'Group');
|
| 637 |
+
$grantee->appendChild($dom->createElement('URI', $g['uri']));
|
| 638 |
+
}
|
| 639 |
+
$grant->appendChild($grantee);
|
| 640 |
+
$grant->appendChild($dom->createElement('Permission', $g['permission']));
|
| 641 |
+
$accessControlList->appendChild($grant);
|
| 642 |
+
}
|
| 643 |
+
|
| 644 |
+
$accessControlPolicy->appendChild($accessControlList);
|
| 645 |
+
$dom->appendChild($accessControlPolicy);
|
| 646 |
+
|
| 647 |
+
$rest = new S3Request('PUT', $bucket, $uri);
|
| 648 |
+
$rest->setParameter('acl', null);
|
| 649 |
+
$rest->data = $dom->saveXML();
|
| 650 |
+
$rest->size = strlen($rest->data);
|
| 651 |
+
$rest->setHeader('Content-Type', 'application/xml');
|
| 652 |
+
$rest = $rest->getResponse();
|
| 653 |
+
if ($rest->error === false && $rest->code !== 200)
|
| 654 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 655 |
+
if ($rest->error !== false) {
|
| 656 |
+
trigger_error(sprintf("S3::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
|
| 657 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 658 |
+
return false;
|
| 659 |
+
}
|
| 660 |
+
return true;
|
| 661 |
+
}
|
| 662 |
+
|
| 663 |
+
|
| 664 |
+
/**
|
| 665 |
+
* Get object or bucket Access Control Policy
|
| 666 |
+
*
|
| 667 |
+
* @param string $bucket Bucket name
|
| 668 |
+
* @param string $uri Object URI
|
| 669 |
+
* @return mixed | false
|
| 670 |
+
*/
|
| 671 |
+
public static function getAccessControlPolicy($bucket, $uri = '') {
|
| 672 |
+
$rest = new S3Request('GET', $bucket, $uri);
|
| 673 |
+
$rest->setParameter('acl', null);
|
| 674 |
+
$rest = $rest->getResponse();
|
| 675 |
+
if ($rest->error === false && $rest->code !== 200)
|
| 676 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 677 |
+
if ($rest->error !== false) {
|
| 678 |
+
trigger_error(sprintf("S3::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
|
| 679 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 680 |
+
return false;
|
| 681 |
+
}
|
| 682 |
+
|
| 683 |
+
$acp = array();
|
| 684 |
+
if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) {
|
| 685 |
+
$acp['owner'] = array(
|
| 686 |
+
'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName
|
| 687 |
+
);
|
| 688 |
+
}
|
| 689 |
+
if (isset($rest->body->AccessControlList)) {
|
| 690 |
+
$acp['acl'] = array();
|
| 691 |
+
foreach ($rest->body->AccessControlList->Grant as $grant) {
|
| 692 |
+
foreach ($grant->Grantee as $grantee) {
|
| 693 |
+
if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser
|
| 694 |
+
$acp['acl'][] = array(
|
| 695 |
+
'type' => 'CanonicalUser',
|
| 696 |
+
'id' => (string)$grantee->ID,
|
| 697 |
+
'name' => (string)$grantee->DisplayName,
|
| 698 |
+
'permission' => (string)$grant->Permission
|
| 699 |
+
);
|
| 700 |
+
elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail
|
| 701 |
+
$acp['acl'][] = array(
|
| 702 |
+
'type' => 'AmazonCustomerByEmail',
|
| 703 |
+
'email' => (string)$grantee->EmailAddress,
|
| 704 |
+
'permission' => (string)$grant->Permission
|
| 705 |
+
);
|
| 706 |
+
elseif (isset($grantee->URI)) // Group
|
| 707 |
+
$acp['acl'][] = array(
|
| 708 |
+
'type' => 'Group',
|
| 709 |
+
'uri' => (string)$grantee->URI,
|
| 710 |
+
'permission' => (string)$grant->Permission
|
| 711 |
+
);
|
| 712 |
+
else continue;
|
| 713 |
+
}
|
| 714 |
+
}
|
| 715 |
+
}
|
| 716 |
+
return $acp;
|
| 717 |
+
}
|
| 718 |
+
|
| 719 |
+
|
| 720 |
+
/**
|
| 721 |
+
* Delete an object
|
| 722 |
+
*
|
| 723 |
+
* @param string $bucket Bucket name
|
| 724 |
+
* @param string $uri Object URI
|
| 725 |
+
* @return boolean
|
| 726 |
+
*/
|
| 727 |
+
public static function deleteObject($bucket, $uri) {
|
| 728 |
+
$rest = new S3Request('DELETE', $bucket, $uri);
|
| 729 |
+
$rest = $rest->getResponse();
|
| 730 |
+
if ($rest->error === false && $rest->code !== 204)
|
| 731 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 732 |
+
if ($rest->error !== false) {
|
| 733 |
+
trigger_error(sprintf("S3::deleteObject(): [%s] %s",
|
| 734 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 735 |
+
return false;
|
| 736 |
+
}
|
| 737 |
+
return true;
|
| 738 |
+
}
|
| 739 |
+
|
| 740 |
+
|
| 741 |
+
/**
|
| 742 |
+
* Get a query string authenticated URL
|
| 743 |
+
*
|
| 744 |
+
* @param string $bucket Bucket name
|
| 745 |
+
* @param string $uri Object URI
|
| 746 |
+
* @param integer $lifetime Lifetime in seconds
|
| 747 |
+
* @param boolean $hostBucket Use the bucket name as the hostname
|
| 748 |
+
* @param boolean $https Use HTTPS ($hostBucket should be false for SSL verification)
|
| 749 |
+
* @return string
|
| 750 |
+
*/
|
| 751 |
+
public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false) {
|
| 752 |
+
$expires = time() + $lifetime;
|
| 753 |
+
$uri = str_replace('%2F', '/', rawurlencode($uri)); // URI should be encoded (thanks Sean O'Dea)
|
| 754 |
+
return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s',
|
| 755 |
+
$hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires,
|
| 756 |
+
urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}")));
|
| 757 |
+
}
|
| 758 |
+
|
| 759 |
+
/**
|
| 760 |
+
* Get upload POST parameters for form uploads
|
| 761 |
+
*
|
| 762 |
+
* @param string $bucket Bucket name
|
| 763 |
+
* @param string $uriPrefix Object URI prefix
|
| 764 |
+
* @param constant $acl ACL constant
|
| 765 |
+
* @param integer $lifetime Lifetime in seconds
|
| 766 |
+
* @param integer $maxFileSize Maximum filesize in bytes (default 5MB)
|
| 767 |
+
* @param string $successRedirect Redirect URL or 200 / 201 status code
|
| 768 |
+
* @param array $amzHeaders Array of x-amz-meta-* headers
|
| 769 |
+
* @param array $headers Array of request headers or content type as a string
|
| 770 |
+
* @param boolean $flashVars Includes additional "Filename" variable posted by Flash
|
| 771 |
+
* @return object
|
| 772 |
+
*/
|
| 773 |
+
public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = self::ACL_PRIVATE, $lifetime = 3600, $maxFileSize = 5242880, $successRedirect = "201", $amzHeaders = array(), $headers = array(), $flashVars = false) {
|
| 774 |
+
// Create policy object
|
| 775 |
+
$policy = new stdClass;
|
| 776 |
+
$policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime));
|
| 777 |
+
$policy->conditions = array();
|
| 778 |
+
$obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj);
|
| 779 |
+
$obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj);
|
| 780 |
+
|
| 781 |
+
$obj = new stdClass; // 200 for non-redirect uploads
|
| 782 |
+
if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
|
| 783 |
+
$obj->success_action_status = (string)$successRedirect;
|
| 784 |
+
else // URL
|
| 785 |
+
$obj->success_action_redirect = $successRedirect;
|
| 786 |
+
array_push($policy->conditions, $obj);
|
| 787 |
+
|
| 788 |
+
array_push($policy->conditions, array('starts-with', '$key', $uriPrefix));
|
| 789 |
+
if ($flashVars) array_push($policy->conditions, array('starts-with', '$Filename', ''));
|
| 790 |
+
foreach (array_keys($headers) as $headerKey)
|
| 791 |
+
array_push($policy->conditions, array('starts-with', '$'.$headerKey, ''));
|
| 792 |
+
foreach ($amzHeaders as $headerKey => $headerVal) {
|
| 793 |
+
$obj = new stdClass; $obj->{$headerKey} = (string)$headerVal; array_push($policy->conditions, $obj);
|
| 794 |
+
}
|
| 795 |
+
array_push($policy->conditions, array('content-length-range', 0, $maxFileSize));
|
| 796 |
+
$policy = base64_encode(str_replace('\/', '/', json_encode($policy)));
|
| 797 |
+
|
| 798 |
+
// Create parameters
|
| 799 |
+
$params = new stdClass;
|
| 800 |
+
$params->AWSAccessKeyId = self::$__accessKey;
|
| 801 |
+
$params->key = $uriPrefix.'${filename}';
|
| 802 |
+
$params->acl = $acl;
|
| 803 |
+
$params->policy = $policy; unset($policy);
|
| 804 |
+
$params->signature = self::__getHash($params->policy);
|
| 805 |
+
if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
|
| 806 |
+
$params->success_action_status = (string)$successRedirect;
|
| 807 |
+
else
|
| 808 |
+
$params->success_action_redirect = $successRedirect;
|
| 809 |
+
foreach ($headers as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
|
| 810 |
+
foreach ($amzHeaders as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
|
| 811 |
+
return $params;
|
| 812 |
+
}
|
| 813 |
+
|
| 814 |
+
/**
|
| 815 |
+
* Create a CloudFront distribution
|
| 816 |
+
*
|
| 817 |
+
* @param string $bucket Bucket name
|
| 818 |
+
* @param boolean $enabled Enabled (true/false)
|
| 819 |
+
* @param array $cnames Array containing CNAME aliases
|
| 820 |
+
* @param string $comment Use the bucket name as the hostname
|
| 821 |
+
* @return array | false
|
| 822 |
+
*/
|
| 823 |
+
public static function createDistribution($bucket, $enabled = true, $cnames = array(), $comment = '') {
|
| 824 |
+
self::$useSSL = true; // CloudFront requires SSL
|
| 825 |
+
$rest = new S3Request('POST', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com');
|
| 826 |
+
$rest->data = self::__getCloudFrontDistributionConfigXML($bucket.'.s3.amazonaws.com', $enabled, $comment, (string)microtime(true), $cnames);
|
| 827 |
+
$rest->size = strlen($rest->data);
|
| 828 |
+
$rest->setHeader('Content-Type', 'application/xml');
|
| 829 |
+
$rest = self::__getCloudFrontResponse($rest);
|
| 830 |
+
|
| 831 |
+
if ($rest->error === false && $rest->code !== 201)
|
| 832 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 833 |
+
if ($rest->error !== false) {
|
| 834 |
+
trigger_error(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", '$comment'): [%s] %s",
|
| 835 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 836 |
+
return false;
|
| 837 |
+
} elseif ($rest->body instanceof SimpleXMLElement)
|
| 838 |
+
return self::__parseCloudFrontDistributionConfig($rest->body);
|
| 839 |
+
return false;
|
| 840 |
+
}
|
| 841 |
+
|
| 842 |
+
|
| 843 |
+
/**
|
| 844 |
+
* Get CloudFront distribution info
|
| 845 |
+
*
|
| 846 |
+
* @param string $distributionId Distribution ID from listDistributions()
|
| 847 |
+
* @return array | false
|
| 848 |
+
*/
|
| 849 |
+
public static function getDistribution($distributionId) {
|
| 850 |
+
self::$useSSL = true; // CloudFront requires SSL
|
| 851 |
+
$rest = new S3Request('GET', '', '2008-06-30/distribution/'.$distributionId, 'cloudfront.amazonaws.com');
|
| 852 |
+
$rest = self::__getCloudFrontResponse($rest);
|
| 853 |
+
|
| 854 |
+
if ($rest->error === false && $rest->code !== 200)
|
| 855 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 856 |
+
if ($rest->error !== false) {
|
| 857 |
+
trigger_error(sprintf("S3::getDistribution($distributionId): [%s] %s",
|
| 858 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 859 |
+
return false;
|
| 860 |
+
} elseif ($rest->body instanceof SimpleXMLElement) {
|
| 861 |
+
$dist = self::__parseCloudFrontDistributionConfig($rest->body);
|
| 862 |
+
$dist['hash'] = $rest->headers['hash'];
|
| 863 |
+
return $dist;
|
| 864 |
+
}
|
| 865 |
+
return false;
|
| 866 |
+
}
|
| 867 |
+
|
| 868 |
+
|
| 869 |
+
/**
|
| 870 |
+
* Update a CloudFront distribution
|
| 871 |
+
*
|
| 872 |
+
* @param array $dist Distribution array info identical to output of getDistribution()
|
| 873 |
+
* @return array | false
|
| 874 |
+
*/
|
| 875 |
+
public static function updateDistribution($dist) {
|
| 876 |
+
self::$useSSL = true; // CloudFront requires SSL
|
| 877 |
+
$rest = new S3Request('PUT', '', '2008-06-30/distribution/'.$dist['id'].'/config', 'cloudfront.amazonaws.com');
|
| 878 |
+
$rest->data = self::__getCloudFrontDistributionConfigXML($dist['origin'], $dist['enabled'], $dist['comment'], $dist['callerReference'], $dist['cnames']);
|
| 879 |
+
$rest->size = strlen($rest->data);
|
| 880 |
+
$rest->setHeader('If-Match', $dist['hash']);
|
| 881 |
+
$rest = self::__getCloudFrontResponse($rest);
|
| 882 |
+
|
| 883 |
+
if ($rest->error === false && $rest->code !== 200)
|
| 884 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 885 |
+
if ($rest->error !== false) {
|
| 886 |
+
trigger_error(sprintf("S3::updateDistribution({$dist['id']}, ".(int)$enabled.", '$comment'): [%s] %s",
|
| 887 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 888 |
+
return false;
|
| 889 |
+
} else {
|
| 890 |
+
$dist = self::__parseCloudFrontDistributionConfig($rest->body);
|
| 891 |
+
$dist['hash'] = $rest->headers['hash'];
|
| 892 |
+
return $dist;
|
| 893 |
+
}
|
| 894 |
+
return false;
|
| 895 |
+
}
|
| 896 |
+
|
| 897 |
+
|
| 898 |
+
/**
|
| 899 |
+
* Delete a CloudFront distribution
|
| 900 |
+
*
|
| 901 |
+
* @param array $dist Distribution array info identical to output of getDistribution()
|
| 902 |
+
* @return boolean
|
| 903 |
+
*/
|
| 904 |
+
public static function deleteDistribution($dist) {
|
| 905 |
+
self::$useSSL = true; // CloudFront requires SSL
|
| 906 |
+
$rest = new S3Request('DELETE', '', '2008-06-30/distribution/'.$dist['id'], 'cloudfront.amazonaws.com');
|
| 907 |
+
$rest->setHeader('If-Match', $dist['hash']);
|
| 908 |
+
$rest = self::__getCloudFrontResponse($rest);
|
| 909 |
+
|
| 910 |
+
if ($rest->error === false && $rest->code !== 204)
|
| 911 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 912 |
+
if ($rest->error !== false) {
|
| 913 |
+
trigger_error(sprintf("S3::deleteDistribution({$dist['id']}): [%s] %s",
|
| 914 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 915 |
+
return false;
|
| 916 |
+
}
|
| 917 |
+
return true;
|
| 918 |
+
}
|
| 919 |
+
|
| 920 |
+
|
| 921 |
+
/**
|
| 922 |
+
* Get a list of CloudFront distributions
|
| 923 |
+
*
|
| 924 |
+
* @return array
|
| 925 |
+
*/
|
| 926 |
+
public static function listDistributions() {
|
| 927 |
+
self::$useSSL = true; // CloudFront requires SSL
|
| 928 |
+
$rest = new S3Request('GET', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com');
|
| 929 |
+
$rest = self::__getCloudFrontResponse($rest);
|
| 930 |
+
|
| 931 |
+
if ($rest->error === false && $rest->code !== 200)
|
| 932 |
+
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
| 933 |
+
if ($rest->error !== false) {
|
| 934 |
+
trigger_error(sprintf("S3::listDistributions(): [%s] %s",
|
| 935 |
+
$rest->error['code'], $rest->error['message']), E_USER_WARNING);
|
| 936 |
+
return false;
|
| 937 |
+
} elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->DistributionSummary)) {
|
| 938 |
+
$list = array();
|
| 939 |
+
if (isset($rest->body->Marker, $rest->body->MaxItems, $rest->body->IsTruncated)) {
|
| 940 |
+
//$info['marker'] = (string)$rest->body->Marker;
|
| 941 |
+
//$info['maxItems'] = (int)$rest->body->MaxItems;
|
| 942 |
+
//$info['isTruncated'] = (string)$rest->body->IsTruncated == 'true' ? true : false;
|
| 943 |
+
}
|
| 944 |
+
foreach ($rest->body->DistributionSummary as $summary) {
|
| 945 |
+
$list[(string)$summary->Id] = self::__parseCloudFrontDistributionConfig($summary);
|
| 946 |
+
}
|
| 947 |
+
return $list;
|
| 948 |
+
}
|
| 949 |
+
return array();
|
| 950 |
+
}
|
| 951 |
+
|
| 952 |
+
|
| 953 |
+
/**
|
| 954 |
+
* Get a DistributionConfig DOMDocument
|
| 955 |
+
*
|
| 956 |
+
* @internal Used to create XML in createDistribution() and updateDistribution()
|
| 957 |
+
* @param string $bucket Origin bucket
|
| 958 |
+
* @param boolean $enabled Enabled (true/false)
|
| 959 |
+
* @param string $comment Comment to append
|
| 960 |
+
* @param string $callerReference Caller reference
|
| 961 |
+
* @param array $cnames Array of CNAME aliases
|
| 962 |
+
* @return string
|
| 963 |
+
*/
|
| 964 |
+
private static function __getCloudFrontDistributionConfigXML($bucket, $enabled, $comment, $callerReference = '0', $cnames = array()) {
|
| 965 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
| 966 |
+
$dom->formatOutput = true;
|
| 967 |
+
$distributionConfig = $dom->createElement('DistributionConfig');
|
| 968 |
+
$distributionConfig->setAttribute('xmlns', 'http://cloudfront.amazonaws.com/doc/2008-06-30/');
|
| 969 |
+
$distributionConfig->appendChild($dom->createElement('Origin', $bucket));
|
| 970 |
+
$distributionConfig->appendChild($dom->createElement('CallerReference', $callerReference));
|
| 971 |
+
foreach ($cnames as $cname)
|
| 972 |
+
$distributionConfig->appendChild($dom->createElement('CNAME', $cname));
|
| 973 |
+
if ($comment !== '') $distributionConfig->appendChild($dom->createElement('Comment', $comment));
|
| 974 |
+
$distributionConfig->appendChild($dom->createElement('Enabled', $enabled ? 'true' : 'false'));
|
| 975 |
+
$dom->appendChild($distributionConfig);
|
| 976 |
+
return $dom->saveXML();
|
| 977 |
+
}
|
| 978 |
+
|
| 979 |
+
|
| 980 |
+
/**
|
| 981 |
+
* Parse a CloudFront distribution config
|
| 982 |
+
*
|
| 983 |
+
* @internal Used to parse the CloudFront DistributionConfig node to an array
|
| 984 |
+
* @param object &$node DOMNode
|
| 985 |
+
* @return array
|
| 986 |
+
*/
|
| 987 |
+
private static function __parseCloudFrontDistributionConfig(&$node) {
|
| 988 |
+
$dist = array();
|
| 989 |
+
if (isset($node->Id, $node->Status, $node->LastModifiedTime, $node->DomainName)) {
|
| 990 |
+
$dist['id'] = (string)$node->Id;
|
| 991 |
+
$dist['status'] = (string)$node->Status;
|
| 992 |
+
$dist['time'] = strtotime((string)$node->LastModifiedTime);
|
| 993 |
+
$dist['domain'] = (string)$node->DomainName;
|
| 994 |
+
}
|
| 995 |
+
if (isset($node->CallerReference))
|
| 996 |
+
$dist['callerReference'] = (string)$node->CallerReference;
|
| 997 |
+
if (isset($node->Comment))
|
| 998 |
+
$dist['comment'] = (string)$node->Comment;
|
| 999 |
+
if (isset($node->Enabled, $node->Origin)) {
|
| 1000 |
+
$dist['origin'] = (string)$node->Origin;
|
| 1001 |
+
$dist['enabled'] = (string)$node->Enabled == 'true' ? true : false;
|
| 1002 |
+
} elseif (isset($node->DistributionConfig)) {
|
| 1003 |
+
$dist = array_merge($dist, self::__parseCloudFrontDistributionConfig($node->DistributionConfig));
|
| 1004 |
+
}
|
| 1005 |
+
if (isset($node->CNAME)) {
|
| 1006 |
+
$dist['cnames'] = array();
|
| 1007 |
+
foreach ($node->CNAME as $cname) $dist['cnames'][(string)$cname] = (string)$cname;
|
| 1008 |
+
}
|
| 1009 |
+
return $dist;
|
| 1010 |
+
}
|
| 1011 |
+
|
| 1012 |
+
|
| 1013 |
+
/**
|
| 1014 |
+
* Grab CloudFront response
|
| 1015 |
+
*
|
| 1016 |
+
* @internal Used to parse the CloudFront S3Request::getResponse() output
|
| 1017 |
+
* @param object &$rest S3Request instance
|
| 1018 |
+
* @return object
|
| 1019 |
+
*/
|
| 1020 |
+
private static function __getCloudFrontResponse(&$rest) {
|
| 1021 |
+
$rest->getResponse();
|
| 1022 |
+
if ($rest->response->error === false && isset($rest->response->body) &&
|
| 1023 |
+
is_string($rest->response->body) && substr($rest->response->body, 0, 5) == '<?xml') {
|
| 1024 |
+
$rest->response->body = simplexml_load_string($rest->response->body);
|
| 1025 |
+
// Grab CloudFront errors
|
| 1026 |
+
if (isset($rest->response->body->Error, $rest->response->body->Error->Code,
|
| 1027 |
+
$rest->response->body->Error->Message)) {
|
| 1028 |
+
$rest->response->error = array(
|
| 1029 |
+
'code' => (string)$rest->response->body->Error->Code,
|
| 1030 |
+
'message' => (string)$rest->response->body->Error->Message
|
| 1031 |
+
);
|
| 1032 |
+
unset($rest->response->body);
|
| 1033 |
+
}
|
| 1034 |
+
}
|
| 1035 |
+
return $rest->response;
|
| 1036 |
+
}
|
| 1037 |
+
|
| 1038 |
+
|
| 1039 |
+
/**
|
| 1040 |
+
* Get MIME type for file
|
| 1041 |
+
*
|
| 1042 |
+
* @internal Used to get mime types
|
| 1043 |
+
* @param string &$file File path
|
| 1044 |
+
* @return string
|
| 1045 |
+
*/
|
| 1046 |
+
public static function __getMimeType(&$file) {
|
| 1047 |
+
$type = false;
|
| 1048 |
+
// Fileinfo documentation says fileinfo_open() will use the
|
| 1049 |
+
// MAGIC env var for the magic file
|
| 1050 |
+
if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) &&
|
| 1051 |
+
($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false) {
|
| 1052 |
+
if (($type = finfo_file($finfo, $file)) !== false) {
|
| 1053 |
+
// Remove the charset and grab the last content-type
|
| 1054 |
+
$type = explode(' ', str_replace('; charset=', ';charset=', $type));
|
| 1055 |
+
$type = array_pop($type);
|
| 1056 |
+
$type = explode(';', $type);
|
| 1057 |
+
$type = trim(array_shift($type));
|
| 1058 |
+
}
|
| 1059 |
+
finfo_close($finfo);
|
| 1060 |
+
|
| 1061 |
+
// If anyone is still using mime_content_type()
|
| 1062 |
+
} elseif (function_exists('mime_content_type'))
|
| 1063 |
+
$type = trim(mime_content_type($file));
|
| 1064 |
+
|
| 1065 |
+
if ($type !== false && strlen($type) > 0) return $type;
|
| 1066 |
+
|
| 1067 |
+
// Otherwise do it the old fashioned way
|
| 1068 |
+
static $exts = array(
|
| 1069 |
+
'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png',
|
| 1070 |
+
'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon',
|
| 1071 |
+
'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf',
|
| 1072 |
+
'zip' => 'application/zip', 'gz' => 'application/x-gzip',
|
| 1073 |
+
'tar' => 'application/x-tar', 'bz' => 'application/x-bzip',
|
| 1074 |
+
'bz2' => 'application/x-bzip2', 'txt' => 'text/plain',
|
| 1075 |
+
'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html',
|
| 1076 |
+
'css' => 'text/css', 'js' => 'text/javascript',
|
| 1077 |
+
'xml' => 'text/xml', 'xsl' => 'application/xsl+xml',
|
| 1078 |
+
'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav',
|
| 1079 |
+
'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
|
| 1080 |
+
'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php'
|
| 1081 |
+
);
|
| 1082 |
+
$ext = strtolower(pathInfo($file, PATHINFO_EXTENSION));
|
| 1083 |
+
return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream';
|
| 1084 |
+
}
|
| 1085 |
+
|
| 1086 |
+
|
| 1087 |
+
/**
|
| 1088 |
+
* Generate the auth string: "AWS AccessKey:Signature"
|
| 1089 |
+
*
|
| 1090 |
+
* @internal Used by S3Request::getResponse()
|
| 1091 |
+
* @param string $string String to sign
|
| 1092 |
+
* @return string
|
| 1093 |
+
*/
|
| 1094 |
+
public static function __getSignature($string) {
|
| 1095 |
+
return 'AWS '.self::$__accessKey.':'.self::__getHash($string);
|
| 1096 |
+
}
|
| 1097 |
+
|
| 1098 |
+
|
| 1099 |
+
/**
|
| 1100 |
+
* Creates a HMAC-SHA1 hash
|
| 1101 |
+
*
|
| 1102 |
+
* This uses the hash extension if loaded
|
| 1103 |
+
*
|
| 1104 |
+
* @internal Used by __getSignature()
|
| 1105 |
+
* @param string $string String to sign
|
| 1106 |
+
* @return string
|
| 1107 |
+
*/
|
| 1108 |
+
private static function __getHash($string) {
|
| 1109 |
+
return base64_encode(extension_loaded('hash') ?
|
| 1110 |
+
hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1(
|
| 1111 |
+
(str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
|
| 1112 |
+
pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^
|
| 1113 |
+
(str_repeat(chr(0x36), 64))) . $string)))));
|
| 1114 |
+
}
|
| 1115 |
+
|
| 1116 |
+
}
|
| 1117 |
+
|
| 1118 |
+
final class S3Request {
|
| 1119 |
+
private $verb, $bucket, $uri, $resource = '', $parameters = array(),
|
| 1120 |
+
$amzHeaders = array(), $headers = array(
|
| 1121 |
+
'Host' => '', 'Date' => '', 'Content-MD5' => '', 'Content-Type' => ''
|
| 1122 |
+
);
|
| 1123 |
+
public $fp = false, $size = 0, $data = false, $response;
|
| 1124 |
+
|
| 1125 |
+
|
| 1126 |
+
/**
|
| 1127 |
+
* Constructor
|
| 1128 |
+
*
|
| 1129 |
+
* @param string $verb Verb
|
| 1130 |
+
* @param string $bucket Bucket name
|
| 1131 |
+
* @param string $uri Object URI
|
| 1132 |
+
* @return mixed
|
| 1133 |
+
*/
|
| 1134 |
+
function __construct($verb, $bucket = '', $uri = '', $defaultHost = 's3.amazonaws.com') {
|
| 1135 |
+
$this->verb = $verb;
|
| 1136 |
+
$this->bucket = strtolower($bucket);
|
| 1137 |
+
$this->uri = $uri !== '' ? '/'.str_replace('%2F', '/', rawurlencode($uri)) : '/';
|
| 1138 |
+
|
| 1139 |
+
if ($this->bucket !== '') {
|
| 1140 |
+
$this->headers['Host'] = $this->bucket.'.'.$defaultHost;
|
| 1141 |
+
$this->resource = '/'.$this->bucket.$this->uri;
|
| 1142 |
+
} else {
|
| 1143 |
+
$this->headers['Host'] = $defaultHost;
|
| 1144 |
+
//$this->resource = strlen($this->uri) > 1 ? '/'.$this->bucket.$this->uri : $this->uri;
|
| 1145 |
+
$this->resource = $this->uri;
|
| 1146 |
+
}
|
| 1147 |
+
$this->headers['Date'] = gmdate('D, d M Y H:i:s T');
|
| 1148 |
+
|
| 1149 |
+
$this->response = new STDClass;
|
| 1150 |
+
$this->response->error = false;
|
| 1151 |
+
}
|
| 1152 |
+
|
| 1153 |
+
|
| 1154 |
+
/**
|
| 1155 |
+
* Set request parameter
|
| 1156 |
+
*
|
| 1157 |
+
* @param string $key Key
|
| 1158 |
+
* @param string $value Value
|
| 1159 |
+
* @return void
|
| 1160 |
+
*/
|
| 1161 |
+
public function setParameter($key, $value) {
|
| 1162 |
+
$this->parameters[$key] = $value;
|
| 1163 |
+
}
|
| 1164 |
+
|
| 1165 |
+
|
| 1166 |
+
/**
|
| 1167 |
+
* Set request header
|
| 1168 |
+
*
|
| 1169 |
+
* @param string $key Key
|
| 1170 |
+
* @param string $value Value
|
| 1171 |
+
* @return void
|
| 1172 |
+
*/
|
| 1173 |
+
public function setHeader($key, $value) {
|
| 1174 |
+
$this->headers[$key] = $value;
|
| 1175 |
+
}
|
| 1176 |
+
|
| 1177 |
+
|
| 1178 |
+
/**
|
| 1179 |
+
* Set x-amz-meta-* header
|
| 1180 |
+
*
|
| 1181 |
+
* @param string $key Key
|
| 1182 |
+
* @param string $value Value
|
| 1183 |
+
* @return void
|
| 1184 |
+
*/
|
| 1185 |
+
public function setAmzHeader($key, $value) {
|
| 1186 |
+
$this->amzHeaders[$key] = $value;
|
| 1187 |
+
}
|
| 1188 |
+
|
| 1189 |
+
|
| 1190 |
+
/**
|
| 1191 |
+
* Get the S3 response
|
| 1192 |
+
*
|
| 1193 |
+
* @return object | false
|
| 1194 |
+
*/
|
| 1195 |
+
public function getResponse() {
|
| 1196 |
+
$query = '';
|
| 1197 |
+
if (sizeof($this->parameters) > 0) {
|
| 1198 |
+
$query = substr($this->uri, -1) !== '?' ? '?' : '&';
|
| 1199 |
+
foreach ($this->parameters as $var => $value)
|
| 1200 |
+
if ($value == null || $value == '') $query .= $var.'&';
|
| 1201 |
+
// Parameters should be encoded (thanks Sean O'Dea)
|
| 1202 |
+
else $query .= $var.'='.rawurlencode($value).'&';
|
| 1203 |
+
$query = substr($query, 0, -1);
|
| 1204 |
+
$this->uri .= $query;
|
| 1205 |
+
|
| 1206 |
+
if (array_key_exists('acl', $this->parameters) ||
|
| 1207 |
+
array_key_exists('location', $this->parameters) ||
|
| 1208 |
+
array_key_exists('torrent', $this->parameters) ||
|
| 1209 |
+
array_key_exists('logging', $this->parameters))
|
| 1210 |
+
$this->resource .= $query;
|
| 1211 |
+
}
|
| 1212 |
+
$url = ((S3::$useSSL && extension_loaded('openssl')) ?
|
| 1213 |
+
'https://':'http://').$this->headers['Host'].$this->uri;
|
| 1214 |
+
//var_dump($this->bucket, $this->uri, $this->resource, $url);
|
| 1215 |
+
|
| 1216 |
+
// Basic setup
|
| 1217 |
+
$curl = curl_init();
|
| 1218 |
+
curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php');
|
| 1219 |
+
|
| 1220 |
+
if (S3::$useSSL) {
|
| 1221 |
+
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
|
| 1222 |
+
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1);
|
| 1223 |
+
}
|
| 1224 |
+
|
| 1225 |
+
curl_setopt($curl, CURLOPT_URL, $url);
|
| 1226 |
+
|
| 1227 |
+
// Headers
|
| 1228 |
+
$headers = array(); $amz = array();
|
| 1229 |
+
foreach ($this->amzHeaders as $header => $value)
|
| 1230 |
+
if (strlen($value) > 0) $headers[] = $header.': '.$value;
|
| 1231 |
+
foreach ($this->headers as $header => $value)
|
| 1232 |
+
if (strlen($value) > 0) $headers[] = $header.': '.$value;
|
| 1233 |
+
|
| 1234 |
+
// Collect AMZ headers for signature
|
| 1235 |
+
foreach ($this->amzHeaders as $header => $value)
|
| 1236 |
+
if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value;
|
| 1237 |
+
|
| 1238 |
+
// AMZ headers must be sorted
|
| 1239 |
+
if (sizeof($amz) > 0) {
|
| 1240 |
+
sort($amz);
|
| 1241 |
+
$amz = "\n".implode("\n", $amz);
|
| 1242 |
+
} else $amz = '';
|
| 1243 |
+
|
| 1244 |
+
// Authorization string (CloudFront stringToSign should only contain a date)
|
| 1245 |
+
$headers[] = 'Authorization: ' . S3::__getSignature(
|
| 1246 |
+
$this->headers['Host'] == 'cloudfront.amazonaws.com' ? $this->headers['Date'] :
|
| 1247 |
+
$this->verb."\n".$this->headers['Content-MD5']."\n".
|
| 1248 |
+
$this->headers['Content-Type']."\n".$this->headers['Date'].$amz."\n".$this->resource
|
| 1249 |
+
);
|
| 1250 |
+
|
| 1251 |
+
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
| 1252 |
+
curl_setopt($curl, CURLOPT_HEADER, false);
|
| 1253 |
+
curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
|
| 1254 |
+
curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
|
| 1255 |
+
curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback'));
|
| 1256 |
+
//curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
| 1257 |
+
|
| 1258 |
+
// Request types
|
| 1259 |
+
switch ($this->verb) {
|
| 1260 |
+
case 'GET': break;
|
| 1261 |
+
case 'PUT': case 'POST': // POST only used for CloudFront
|
| 1262 |
+
if ($this->fp !== false) {
|
| 1263 |
+
curl_setopt($curl, CURLOPT_PUT, true);
|
| 1264 |
+
curl_setopt($curl, CURLOPT_INFILE, $this->fp);
|
| 1265 |
+
if ($this->size >= 0)
|
| 1266 |
+
curl_setopt($curl, CURLOPT_INFILESIZE, $this->size);
|
| 1267 |
+
} elseif ($this->data !== false) {
|
| 1268 |
+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
|
| 1269 |
+
curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
|
| 1270 |
+
if ($this->size >= 0)
|
| 1271 |
+
curl_setopt($curl, CURLOPT_BUFFERSIZE, $this->size);
|
| 1272 |
+
} else
|
| 1273 |
+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
|
| 1274 |
+
break;
|
| 1275 |
+
case 'HEAD':
|
| 1276 |
+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
|
| 1277 |
+
curl_setopt($curl, CURLOPT_NOBODY, true);
|
| 1278 |
+
break;
|
| 1279 |
+
case 'DELETE':
|
| 1280 |
+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
| 1281 |
+
break;
|
| 1282 |
+
default: break;
|
| 1283 |
+
}
|
| 1284 |
+
|
| 1285 |
+
// Execute, grab errors
|
| 1286 |
+
if (curl_exec($curl))
|
| 1287 |
+
$this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
| 1288 |
+
else
|
| 1289 |
+
$this->response->error = array(
|
| 1290 |
+
'code' => curl_errno($curl),
|
| 1291 |
+
'message' => curl_error($curl),
|
| 1292 |
+
'resource' => $this->resource
|
| 1293 |
+
);
|
| 1294 |
+
|
| 1295 |
+
@curl_close($curl);
|
| 1296 |
+
|
| 1297 |
+
// Parse body into XML
|
| 1298 |
+
if ($this->response->error === false && isset($this->response->headers['type']) &&
|
| 1299 |
+
$this->response->headers['type'] == 'application/xml' && isset($this->response->body)) {
|
| 1300 |
+
$this->response->body = simplexml_load_string($this->response->body);
|
| 1301 |
+
|
| 1302 |
+
// Grab S3 errors
|
| 1303 |
+
if (!in_array($this->response->code, array(200, 204)) &&
|
| 1304 |
+
isset($this->response->body->Code, $this->response->body->Message)) {
|
| 1305 |
+
$this->response->error = array(
|
| 1306 |
+
'code' => (string)$this->response->body->Code,
|
| 1307 |
+
'message' => (string)$this->response->body->Message
|
| 1308 |
+
);
|
| 1309 |
+
if (isset($this->response->body->Resource))
|
| 1310 |
+
$this->response->error['resource'] = (string)$this->response->body->Resource;
|
| 1311 |
+
unset($this->response->body);
|
| 1312 |
+
}
|
| 1313 |
+
}
|
| 1314 |
+
|
| 1315 |
+
// Clean up file resources
|
| 1316 |
+
if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp);
|
| 1317 |
+
|
| 1318 |
+
return $this->response;
|
| 1319 |
+
}
|
| 1320 |
+
|
| 1321 |
+
|
| 1322 |
+
/**
|
| 1323 |
+
* CURL write callback
|
| 1324 |
+
*
|
| 1325 |
+
* @param resource &$curl CURL resource
|
| 1326 |
+
* @param string &$data Data
|
| 1327 |
+
* @return integer
|
| 1328 |
+
*/
|
| 1329 |
+
private function __responseWriteCallback(&$curl, &$data) {
|
| 1330 |
+
if ($this->response->code == 200 && $this->fp !== false)
|
| 1331 |
+
return fwrite($this->fp, $data);
|
| 1332 |
+
else
|
| 1333 |
+
$this->response->body .= $data;
|
| 1334 |
+
return strlen($data);
|
| 1335 |
+
}
|
| 1336 |
+
|
| 1337 |
+
|
| 1338 |
+
/**
|
| 1339 |
+
* CURL header callback
|
| 1340 |
+
*
|
| 1341 |
+
* @param resource &$curl CURL resource
|
| 1342 |
+
* @param string &$data Data
|
| 1343 |
+
* @return integer
|
| 1344 |
+
*/
|
| 1345 |
+
private function __responseHeaderCallback(&$curl, &$data) {
|
| 1346 |
+
if (($strlen = strlen($data)) <= 2) return $strlen;
|
| 1347 |
+
if (substr($data, 0, 4) == 'HTTP')
|
| 1348 |
+
$this->response->code = (int)substr($data, 9, 3);
|
| 1349 |
+
else {
|
| 1350 |
+
list($header, $value) = explode(': ', trim($data), 2);
|
| 1351 |
+
if ($header == 'Last-Modified')
|
| 1352 |
+
$this->response->headers['time'] = strtotime($value);
|
| 1353 |
+
elseif ($header == 'Content-Length')
|
| 1354 |
+
$this->response->headers['size'] = (int)$value;
|
| 1355 |
+
elseif ($header == 'Content-Type')
|
| 1356 |
+
$this->response->headers['type'] = $value;
|
| 1357 |
+
elseif ($header == 'ETag')
|
| 1358 |
+
$this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value;
|
| 1359 |
+
elseif (preg_match('/^x-amz-meta-.*$/', $header))
|
| 1360 |
+
$this->response->headers[$header] = is_numeric($value) ? (int)$value : $value;
|
| 1361 |
+
}
|
| 1362 |
+
return $strlen;
|
| 1363 |
+
}
|
| 1364 |
+
|
| 1365 |
+
}
|
app/options-backups.php
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?PHP
|
| 2 |
+
// don't load directly
|
| 3 |
+
if ( !defined('ABSPATH') )
|
| 4 |
+
die('-1');
|
| 5 |
+
|
| 6 |
+
//get GET data
|
| 7 |
+
if (isset($_GET['paged'])) $paged=$_GET['paged'];
|
| 8 |
+
|
| 9 |
+
//Get Backup files
|
| 10 |
+
$backups=backwpup_get_backup_files();
|
| 11 |
+
|
| 12 |
+
//Page links
|
| 13 |
+
$per_page = 20;
|
| 14 |
+
|
| 15 |
+
$pagenum = isset( $paged ) ? absint( $paged ) : 0;
|
| 16 |
+
if ( empty($pagenum) )
|
| 17 |
+
$pagenum = 1;
|
| 18 |
+
|
| 19 |
+
$num_backups = count($backups);
|
| 20 |
+
$num_pages = ceil($num_backups / $per_page);
|
| 21 |
+
|
| 22 |
+
$page_links = paginate_links( array(
|
| 23 |
+
'base' => add_query_arg('paged', '%#%'),
|
| 24 |
+
'format' => '',
|
| 25 |
+
'prev_text' => __('«'),
|
| 26 |
+
'next_text' => __('»'),
|
| 27 |
+
'total' => $num_pages,
|
| 28 |
+
'current' => $pagenum
|
| 29 |
+
));
|
| 30 |
+
?>
|
| 31 |
+
<div class="wrap">
|
| 32 |
+
<div id="icon-tools" class="icon32"><br /></div>
|
| 33 |
+
<h2><?php _e("BackWPup Manage Backups", "backwpup"); ?></h2>
|
| 34 |
+
<ul class="subsubsub">
|
| 35 |
+
<li><a href="admin.php?page=BackWPup"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 36 |
+
<li><a href="admin.php?page=BackWPup&action=logs"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
| 37 |
+
<li><a href="admin.php?page=BackWPup&action=backups" class="current"><?PHP _e('Backups','backwpup'); ?></a> |</li>
|
| 38 |
+
<li><a href="admin.php?page=BackWPup&action=tools"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 39 |
+
<li><a href="admin.php?page=BackWPup&action=settings"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 40 |
+
</ul>
|
| 41 |
+
|
| 42 |
+
<form id="logs-filter" action="" method="post">
|
| 43 |
+
<?php wp_nonce_field('actions-backups'); ?>
|
| 44 |
+
<input type="hidden" name="page" value="BackWPup" />
|
| 45 |
+
<div class="tablenav">
|
| 46 |
+
|
| 47 |
+
<div class="alignleft actions">
|
| 48 |
+
<select name="action" class="select-action">
|
| 49 |
+
<option value="backups" selected="selected"><?PHP _e('Bulk Actions','backwpup'); ?></option>
|
| 50 |
+
<option value="delete-backup"><?PHP _e('Delete','backwpup'); ?></option>
|
| 51 |
+
</select>
|
| 52 |
+
<input type="submit" value="<?PHP _e('Apply','backwpup'); ?>" name="doaction" id="doaction" class="button-secondary action" />
|
| 53 |
+
</div>
|
| 54 |
+
|
| 55 |
+
<?php if ( $page_links ) { ?>
|
| 56 |
+
<div class="tablenav-pages"><?php $page_links_text = sprintf( '<span class="displaying-num">' . __( 'Displaying %s–%s of %s' ) . '</span>%s',
|
| 57 |
+
number_format_i18n( ( $pagenum - 1 ) * $per_page + 1 ),
|
| 58 |
+
number_format_i18n( min( $pagenum * $per_page, $num_backups ) ),
|
| 59 |
+
number_format_i18n( $num_backups ),
|
| 60 |
+
$page_links
|
| 61 |
+
); echo $page_links_text; ?></div>
|
| 62 |
+
<?php } ?>
|
| 63 |
+
<div class="clear"></div>
|
| 64 |
+
</div>
|
| 65 |
+
|
| 66 |
+
<div class="clear"></div>
|
| 67 |
+
|
| 68 |
+
<table class="widefat" cellspacing="0">
|
| 69 |
+
<thead>
|
| 70 |
+
<tr>
|
| 71 |
+
<?php print_column_headers($page_hook); ?>
|
| 72 |
+
</tr>
|
| 73 |
+
</thead>
|
| 74 |
+
|
| 75 |
+
<tfoot>
|
| 76 |
+
<tr>
|
| 77 |
+
<?php print_column_headers($page_hook, false); ?>
|
| 78 |
+
</tr>
|
| 79 |
+
</tfoot>
|
| 80 |
+
|
| 81 |
+
<tbody id="the-list" class="list:post">
|
| 82 |
+
|
| 83 |
+
<?php
|
| 84 |
+
$item_columns = get_column_headers($page_hook);
|
| 85 |
+
$hidden = get_hidden_columns($page_hook);
|
| 86 |
+
$jobs=get_option('backwpup_jobs'); //Load jobs
|
| 87 |
+
|
| 88 |
+
foreach ($backups as $backupnum => $backup) {
|
| 89 |
+
if (!($backupnum>=($pagenum*$per_page-$per_page) and $backupnum<($pagenum*$per_page)))
|
| 90 |
+
continue;
|
| 91 |
+
$jobvalue=backwpup_check_job_vars($jobs[$backup['jobid']]); //Check job values
|
| 92 |
+
?><tr id="<?PHP echo $logfile?>" valign="top"><?PHP
|
| 93 |
+
foreach($item_columns as $column_name=>$column_display_name) {
|
| 94 |
+
$class = "class=\"column-$column_name\"";
|
| 95 |
+
|
| 96 |
+
$style = '';
|
| 97 |
+
if ( in_array($column_name, $hidden) )
|
| 98 |
+
$style = ' style="display:none;"';
|
| 99 |
+
|
| 100 |
+
$attributes = "$class$style";
|
| 101 |
+
|
| 102 |
+
switch($column_name) {
|
| 103 |
+
case 'cb':
|
| 104 |
+
echo '<th scope="row" class="check-column"><input type="checkbox" name="backupfiles[]" value="'. esc_attr($backup['file'].':'.$backup['jobid'].':'.$backup['type']) .'" /></th>';
|
| 105 |
+
break;
|
| 106 |
+
case 'id':
|
| 107 |
+
echo "<td $attributes>".$backup['jobid']."</td>";
|
| 108 |
+
break;
|
| 109 |
+
case 'backup':
|
| 110 |
+
if ($backup['type']=='FOLDER') {
|
| 111 |
+
echo "<td $attributes><strong>".basename($backup['file'])."</strong><br />".dirname($backup['file'])."/";
|
| 112 |
+
} elseif ($backup['type']=='S3') {
|
| 113 |
+
echo "<td $attributes><strong>".basename($backup['file'])."</strong><br />S3://".$jobvalue['awsBucket']."/".dirname($backup['file'])."/";
|
| 114 |
+
} elseif ($backup['type']=='FTP') {
|
| 115 |
+
echo "<td $attributes><strong>".basename($backup['file'])."</strong><br />ftp://".$jobvalue['ftphost'].dirname($backup['file'])."/";
|
| 116 |
+
}
|
| 117 |
+
$actions = array();
|
| 118 |
+
$actions['delete'] = "<a class=\"submitdelete\" href=\"" . wp_nonce_url('admin.php?page=BackWPup&action=delete-backup&paged='.$paged.'&backupfile='.$backup['file'].'&jobid='.$backup['jobid'].'&type='.$backup['type'], 'delete-backup_'.basename($backup['file'])) . "\" onclick=\"if ( confirm('" . esc_js(__("You are about to delete this Backup Archive. \n 'Cancel' to stop, 'OK' to delete.","backwpup")) . "') ) { return true;}return false;\">" . __('Delete') . "</a>";
|
| 119 |
+
$actions['download'] = "<a class=\"submitdelete\" href=\"" . $backup['downloadurl'] . "\">" . __('Download','backwpup') . "</a>";
|
| 120 |
+
$action_count = count($actions);
|
| 121 |
+
$i = 0;
|
| 122 |
+
echo '<br /><div class="row-actions">';
|
| 123 |
+
foreach ( $actions as $action => $linkaction ) {
|
| 124 |
+
++$i;
|
| 125 |
+
( $i == $action_count ) ? $sep = '' : $sep = ' | ';
|
| 126 |
+
echo "<span class='$action'>$linkaction$sep</span>";
|
| 127 |
+
}
|
| 128 |
+
echo '</div>';
|
| 129 |
+
echo "</td>";
|
| 130 |
+
break;
|
| 131 |
+
case 'size':
|
| 132 |
+
echo "<td $attributes>";
|
| 133 |
+
if (!empty($backup['filesize']) and $backup['filesize']!=-1) {
|
| 134 |
+
echo backwpup_formatBytes($backup['filesize']);
|
| 135 |
+
} else {
|
| 136 |
+
_e('?','backwpup');
|
| 137 |
+
}
|
| 138 |
+
echo "</td>";
|
| 139 |
+
break;
|
| 140 |
+
}
|
| 141 |
+
}
|
| 142 |
+
echo "\n </tr>\n";
|
| 143 |
+
}
|
| 144 |
+
?></tbody>
|
| 145 |
+
</table>
|
| 146 |
+
|
| 147 |
+
<div class="tablenav">
|
| 148 |
+
<div class="alignleft actions">
|
| 149 |
+
<select name="action2" class="select-action">
|
| 150 |
+
<option value="backups" selected="selected"><?PHP _e('Bulk Actions','backwpup'); ?></option>
|
| 151 |
+
<option value="delete-backup"><?PHP _e('Delete','backwpup'); ?></option>
|
| 152 |
+
</select>
|
| 153 |
+
<input type="submit" value="<?PHP _e('Apply','backwpup'); ?>" name="doaction2" id="doaction2" class="button-secondary action" />
|
| 154 |
+
</div>
|
| 155 |
+
|
| 156 |
+
<br class="clear" />
|
| 157 |
+
<?php
|
| 158 |
+
if ( $page_links )
|
| 159 |
+
echo "<div class='tablenav-pages'>$page_links_text</div>";
|
| 160 |
+
?>
|
| 161 |
+
</div>
|
| 162 |
+
</form>
|
| 163 |
+
<br class="clear" />
|
| 164 |
+
|
| 165 |
+
</div>
|
app/options-logs.php
CHANGED
|
@@ -2,6 +2,40 @@
|
|
| 2 |
// don't load directly
|
| 3 |
if ( !defined('ABSPATH') )
|
| 4 |
die('-1');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
?>
|
| 6 |
<div class="wrap">
|
| 7 |
<div id="icon-tools" class="icon32"><br /></div>
|
|
@@ -9,6 +43,7 @@ if ( !defined('ABSPATH') )
|
|
| 9 |
<ul class="subsubsub">
|
| 10 |
<li><a href="admin.php?page=BackWPup"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 11 |
<li><a href="admin.php?page=BackWPup&action=logs" class="current"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
|
|
|
| 12 |
<li><a href="admin.php?page=BackWPup&action=tools"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 13 |
<li><a href="admin.php?page=BackWPup&action=settings"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 14 |
</ul>
|
|
@@ -20,13 +55,21 @@ if ( !defined('ABSPATH') )
|
|
| 20 |
|
| 21 |
<div class="alignleft actions">
|
| 22 |
<select name="action" class="select-action">
|
| 23 |
-
<option value="
|
| 24 |
<option value="delete-logs"><?PHP _e('Delete','backwpup'); ?></option>
|
| 25 |
</select>
|
| 26 |
<input type="submit" value="<?PHP _e('Apply','backwpup'); ?>" name="doaction" id="doaction" class="button-secondary action" />
|
| 27 |
</div>
|
| 28 |
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
</div>
|
| 31 |
|
| 32 |
<div class="clear"></div>
|
|
@@ -50,19 +93,9 @@ if ( !defined('ABSPATH') )
|
|
| 50 |
$item_columns = get_column_headers($page_hook);
|
| 51 |
$hidden = get_hidden_columns($page_hook);
|
| 52 |
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
while (($file = readdir( $dir ) ) !== false ) {
|
| 57 |
-
if (is_file($cfg['dirlogs'].'/'.$file) and 'backwpup_log_' == substr($file,0,strlen('backwpup_log_')) and '.html' == substr($file,-5))
|
| 58 |
-
$logfiles[]=$file;
|
| 59 |
-
}
|
| 60 |
-
closedir( $dir );
|
| 61 |
-
rsort($logfiles);
|
| 62 |
-
}
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
foreach ($logfiles as $logfile) {
|
| 66 |
$logdata=backwpup_read_logheader($cfg['dirlogs'].'/'.$logfile);
|
| 67 |
?><tr id="<?PHP echo $logfile?>" valign="top"><?PHP
|
| 68 |
foreach($item_columns as $column_name=>$column_display_name) {
|
|
@@ -94,10 +127,8 @@ if ( !defined('ABSPATH') )
|
|
| 94 |
echo "<td $attributes><strong><a href=\"".wp_nonce_url('admin.php?page=BackWPup&action=view_log&logfile='.$cfg['dirlogs'].'/'.$logfile, 'view-log_'.$logfile)."\" title=\"".__('View log','backwpup')."\">".date_i18n(get_option('date_format'),$logdata['logtime'])." ".date_i18n(get_option('time_format'),$logdata['logtime']).": <i>".$logdata['name']."</i></a></strong>";
|
| 95 |
$actions = array();
|
| 96 |
$actions['view'] = "<a href=\"" . wp_nonce_url('admin.php?page=BackWPup&action=view_log&logfile='.$cfg['dirlogs'].'/'.$logfile, 'view-log_'.$logfile) . "\">" . __('View','backwpup') . "</a>";
|
| 97 |
-
$actions['delete'] = "<a class=\"submitdelete\" href=\"" . wp_nonce_url('admin.php?page=BackWPup&action=delete-logs&logfile='.$logfile, 'delete-log_'.$logfile) . "\" onclick=\"if ( confirm('" . esc_js(__("You are about to delete this Job. \n 'Cancel' to stop, 'OK' to delete.","backwpup")) . "') ) { return true;}return false;\">" . __('Delete') . "</a>";
|
| 98 |
-
$actions['
|
| 99 |
-
if (!empty($logdata['backupfile']) and is_file($logdata['backupfile']))
|
| 100 |
-
$actions['downloadbackup'] = "<a class=\"submitdelete\" href=\"" . wp_nonce_url('admin.php?page=BackWPup&action=download&file='.$logdata['backupfile'], 'download-backup_'.basename($logdata['backupfile'])) . "\">" . __('Download Backup','backwpup') . "</a>";
|
| 101 |
$action_count = count($actions);
|
| 102 |
$i = 0;
|
| 103 |
echo '<br /><div class="row-actions">';
|
|
@@ -123,10 +154,10 @@ if ( !defined('ABSPATH') )
|
|
| 123 |
break;
|
| 124 |
case 'size':
|
| 125 |
echo "<td $attributes>";
|
| 126 |
-
if (!empty($logdata['backupfile']) and
|
| 127 |
-
echo backwpup_formatBytes(
|
| 128 |
} elseif (!empty($logdata['backupfile'])) {
|
| 129 |
-
_e('
|
| 130 |
} else {
|
| 131 |
_e('only Log','backwpup');
|
| 132 |
}
|
|
@@ -147,13 +178,17 @@ if ( !defined('ABSPATH') )
|
|
| 147 |
<div class="tablenav">
|
| 148 |
<div class="alignleft actions">
|
| 149 |
<select name="action2" class="select-action">
|
| 150 |
-
<option value="
|
| 151 |
<option value="delete-logs"><?PHP _e('Delete','backwpup'); ?></option>
|
| 152 |
</select>
|
| 153 |
<input type="submit" value="<?PHP _e('Apply','backwpup'); ?>" name="doaction2" id="doaction2" class="button-secondary action" />
|
| 154 |
</div>
|
| 155 |
|
| 156 |
-
<br class="clear" />
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
</div>
|
| 158 |
</form>
|
| 159 |
<br class="clear" />
|
| 2 |
// don't load directly
|
| 3 |
if ( !defined('ABSPATH') )
|
| 4 |
die('-1');
|
| 5 |
+
|
| 6 |
+
//get GET data
|
| 7 |
+
if (isset($_GET['paged'])) $paged=$_GET['paged'];
|
| 8 |
+
|
| 9 |
+
//Get log files
|
| 10 |
+
$logfiles=array();
|
| 11 |
+
if ( $dir = @opendir( $cfg['dirlogs'] ) ) {
|
| 12 |
+
while (($file = readdir( $dir ) ) !== false ) {
|
| 13 |
+
if (is_file($cfg['dirlogs'].'/'.$file) and 'backwpup_log_' == substr($file,0,strlen('backwpup_log_')) and '.html' == substr($file,-5))
|
| 14 |
+
$logfiles[]=$file;
|
| 15 |
+
}
|
| 16 |
+
closedir( $dir );
|
| 17 |
+
rsort($logfiles);
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
//Page links
|
| 21 |
+
$per_page = 20;
|
| 22 |
+
|
| 23 |
+
$pagenum = isset( $paged ) ? absint( $paged ) : 0;
|
| 24 |
+
if ( empty($pagenum) )
|
| 25 |
+
$pagenum = 1;
|
| 26 |
+
|
| 27 |
+
$num_logs = count($logfiles);
|
| 28 |
+
$num_pages = ceil($num_logs / $per_page);
|
| 29 |
+
|
| 30 |
+
$page_links = paginate_links( array(
|
| 31 |
+
'base' => add_query_arg('paged', '%#%'),
|
| 32 |
+
'format' => '',
|
| 33 |
+
'prev_text' => __('«'),
|
| 34 |
+
'next_text' => __('»'),
|
| 35 |
+
'total' => $num_pages,
|
| 36 |
+
'current' => $pagenum
|
| 37 |
+
));
|
| 38 |
+
|
| 39 |
?>
|
| 40 |
<div class="wrap">
|
| 41 |
<div id="icon-tools" class="icon32"><br /></div>
|
| 43 |
<ul class="subsubsub">
|
| 44 |
<li><a href="admin.php?page=BackWPup"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 45 |
<li><a href="admin.php?page=BackWPup&action=logs" class="current"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
| 46 |
+
<li><a href="admin.php?page=BackWPup&action=backups"><?PHP _e('Backups','backwpup'); ?></a> |</li>
|
| 47 |
<li><a href="admin.php?page=BackWPup&action=tools"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 48 |
<li><a href="admin.php?page=BackWPup&action=settings"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 49 |
</ul>
|
| 55 |
|
| 56 |
<div class="alignleft actions">
|
| 57 |
<select name="action" class="select-action">
|
| 58 |
+
<option value="logs" selected="selected"><?PHP _e('Bulk Actions','backwpup'); ?></option>
|
| 59 |
<option value="delete-logs"><?PHP _e('Delete','backwpup'); ?></option>
|
| 60 |
</select>
|
| 61 |
<input type="submit" value="<?PHP _e('Apply','backwpup'); ?>" name="doaction" id="doaction" class="button-secondary action" />
|
| 62 |
</div>
|
| 63 |
|
| 64 |
+
<?php if ( $page_links ) { ?>
|
| 65 |
+
<div class="tablenav-pages"><?php $page_links_text = sprintf( '<span class="displaying-num">' . __( 'Displaying %s–%s of %s' ) . '</span>%s',
|
| 66 |
+
number_format_i18n( ( $pagenum - 1 ) * $per_page + 1 ),
|
| 67 |
+
number_format_i18n( min( $pagenum * $per_page, $num_logs ) ),
|
| 68 |
+
number_format_i18n( $num_logs ),
|
| 69 |
+
$page_links
|
| 70 |
+
); echo $page_links_text; ?></div>
|
| 71 |
+
<?php } ?>
|
| 72 |
+
<div class="clear"></div>
|
| 73 |
</div>
|
| 74 |
|
| 75 |
<div class="clear"></div>
|
| 93 |
$item_columns = get_column_headers($page_hook);
|
| 94 |
$hidden = get_hidden_columns($page_hook);
|
| 95 |
|
| 96 |
+
foreach ($logfiles as $lognum => $logfile) {
|
| 97 |
+
if (!($lognum>=($pagenum*$per_page-$per_page) and $lognum<($pagenum*$per_page)))
|
| 98 |
+
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
$logdata=backwpup_read_logheader($cfg['dirlogs'].'/'.$logfile);
|
| 100 |
?><tr id="<?PHP echo $logfile?>" valign="top"><?PHP
|
| 101 |
foreach($item_columns as $column_name=>$column_display_name) {
|
| 127 |
echo "<td $attributes><strong><a href=\"".wp_nonce_url('admin.php?page=BackWPup&action=view_log&logfile='.$cfg['dirlogs'].'/'.$logfile, 'view-log_'.$logfile)."\" title=\"".__('View log','backwpup')."\">".date_i18n(get_option('date_format'),$logdata['logtime'])." ".date_i18n(get_option('time_format'),$logdata['logtime']).": <i>".$logdata['name']."</i></a></strong>";
|
| 128 |
$actions = array();
|
| 129 |
$actions['view'] = "<a href=\"" . wp_nonce_url('admin.php?page=BackWPup&action=view_log&logfile='.$cfg['dirlogs'].'/'.$logfile, 'view-log_'.$logfile) . "\">" . __('View','backwpup') . "</a>";
|
| 130 |
+
$actions['delete'] = "<a class=\"submitdelete\" href=\"" . wp_nonce_url('admin.php?page=BackWPup&action=delete-logs&paged='.$paged.'&logfile='.$logfile, 'delete-log_'.$logfile) . "\" onclick=\"if ( confirm('" . esc_js(__("You are about to delete this Job. \n 'Cancel' to stop, 'OK' to delete.","backwpup")) . "') ) { return true;}return false;\">" . __('Delete') . "</a>";
|
| 131 |
+
$actions['download'] = "<a class=\"submitdelete\" href=\"" . wp_nonce_url('admin.php?page=BackWPup&action=download&file='.$cfg['dirlogs'].'/'.$logfile, 'download-backup_'.$logfile) . "\">" . __('Download','backwpup') . "</a>";
|
|
|
|
|
|
|
| 132 |
$action_count = count($actions);
|
| 133 |
$i = 0;
|
| 134 |
echo '<br /><div class="row-actions">';
|
| 154 |
break;
|
| 155 |
case 'size':
|
| 156 |
echo "<td $attributes>";
|
| 157 |
+
if (!empty($logdata['backupfile']) and !empty($logdata['backupfilesize'])) {
|
| 158 |
+
echo backwpup_formatBytes($logdata['backupfilesize']);
|
| 159 |
} elseif (!empty($logdata['backupfile'])) {
|
| 160 |
+
_e('?','backwpup');
|
| 161 |
} else {
|
| 162 |
_e('only Log','backwpup');
|
| 163 |
}
|
| 178 |
<div class="tablenav">
|
| 179 |
<div class="alignleft actions">
|
| 180 |
<select name="action2" class="select-action">
|
| 181 |
+
<option value="logs" selected="selected"><?PHP _e('Bulk Actions','backwpup'); ?></option>
|
| 182 |
<option value="delete-logs"><?PHP _e('Delete','backwpup'); ?></option>
|
| 183 |
</select>
|
| 184 |
<input type="submit" value="<?PHP _e('Apply','backwpup'); ?>" name="doaction2" id="doaction2" class="button-secondary action" />
|
| 185 |
</div>
|
| 186 |
|
| 187 |
+
<br class="clear" />
|
| 188 |
+
<?php
|
| 189 |
+
if ( $page_links )
|
| 190 |
+
echo "<div class='tablenav-pages'>$page_links_text</div>";
|
| 191 |
+
?>
|
| 192 |
</div>
|
| 193 |
</form>
|
| 194 |
<br class="clear" />
|
app/options-runnow.php
CHANGED
|
@@ -9,6 +9,7 @@ if ( !defined('ABSPATH') )
|
|
| 9 |
<ul class="subsubsub">
|
| 10 |
<li><a href="admin.php?page=BackWPup"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 11 |
<li><a href="admin.php?page=BackWPup&action=logs"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
|
|
|
| 12 |
<li><a href="admin.php?page=BackWPup&action=tools"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 13 |
<li><a href="admin.php?page=BackWPup&action=settings"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 14 |
</ul>
|
| 9 |
<ul class="subsubsub">
|
| 10 |
<li><a href="admin.php?page=BackWPup"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 11 |
<li><a href="admin.php?page=BackWPup&action=logs"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
| 12 |
+
<li><a href="admin.php?page=BackWPup&action=backups"><?PHP _e('Backups','backwpup'); ?></a> |</li>
|
| 13 |
<li><a href="admin.php?page=BackWPup&action=tools"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 14 |
<li><a href="admin.php?page=BackWPup&action=settings"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 15 |
</ul>
|
app/options-save.php
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
if ( !defined('ABSPATH') )
|
| 4 |
die('-1');
|
| 5 |
|
| 6 |
-
if ($_REQUEST['action2']!='-1' and !empty($_REQUEST['doaction2']))
|
| 7 |
$_REQUEST['action']=$_REQUEST['action2'];
|
| 8 |
|
| 9 |
switch($_REQUEST['action']) {
|
|
@@ -49,6 +49,86 @@ case 'delete-logs': //Delete Log
|
|
| 49 |
}
|
| 50 |
$_REQUEST['action']='logs';
|
| 51 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
case 'savecfg': //Save config form Setings page
|
| 53 |
check_admin_referer('backwpup-cfg');
|
| 54 |
$cfg=get_option('backwpup'); //Load Settings
|
|
@@ -106,11 +186,34 @@ case 'download': //Download Backup
|
|
| 106 |
header("Content-Transfer-Encoding: binary");
|
| 107 |
header("Content-Length: ".filesize($_GET['file']));
|
| 108 |
@readfile($_GET['file']);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
} else {
|
| 110 |
header('HTTP/1.0 404 Not Found');
|
| 111 |
die(__('File does not exist.', 'backwpup'));
|
| 112 |
}
|
| 113 |
-
$_REQUEST['action']='logs';
|
| 114 |
break;
|
| 115 |
case 'saveeditjob': //Save Job settings
|
| 116 |
$jobid = (int) $_POST['jobid'];
|
| 3 |
if ( !defined('ABSPATH') )
|
| 4 |
die('-1');
|
| 5 |
|
| 6 |
+
if ($_REQUEST['action2']!='backups' and $_REQUEST['action2']!='logs' and $_REQUEST['action2']!='-1' and !empty($_REQUEST['doaction2']))
|
| 7 |
$_REQUEST['action']=$_REQUEST['action2'];
|
| 8 |
|
| 9 |
switch($_REQUEST['action']) {
|
| 49 |
}
|
| 50 |
$_REQUEST['action']='logs';
|
| 51 |
break;
|
| 52 |
+
case 'delete-backup': //Delete Backup archives
|
| 53 |
+
$deletebackups=array();
|
| 54 |
+
if (is_Array($_POST['backupfiles'])) {
|
| 55 |
+
check_admin_referer('actions-backups');
|
| 56 |
+
$i=0;
|
| 57 |
+
foreach ($_POST['backupfiles'] as $backupfile) {
|
| 58 |
+
list($deletebackups[$i]['file'],$deletebackups[$i]['jobid'],$deletebackups[$i]['type'])=explode(':',$backupfile,3);
|
| 59 |
+
$i++;
|
| 60 |
+
}
|
| 61 |
+
} else {
|
| 62 |
+
check_admin_referer('delete-backup_' . basename($_GET['backupfile']));
|
| 63 |
+
$deletebackups[0]['type']=$_GET['type'];
|
| 64 |
+
$deletebackups[0]['jobid']=$_GET['jobid'];
|
| 65 |
+
$deletebackups[0]['file']=$_GET['backupfile'];
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
if(empty($deletebackups)) {
|
| 69 |
+
$_REQUEST['action']='backups';
|
| 70 |
+
break;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
$jobs=get_option('backwpup_jobs'); //Load jobs
|
| 74 |
+
if (extension_loaded('curl') or @dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll')) {
|
| 75 |
+
if (!class_exists('S3'))
|
| 76 |
+
require_once(plugin_dir_path(__FILE__).'libs/S3.php');
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
$num=0;
|
| 80 |
+
foreach ($deletebackups as $backups) {
|
| 81 |
+
$jobvalue=backwpup_check_job_vars($jobs[$backups['jobid']]); //Check job values
|
| 82 |
+
if ($backups['type']=='FOLDER') {
|
| 83 |
+
if (is_file($backups['file']))
|
| 84 |
+
unlink($backups['file']);
|
| 85 |
+
} elseif ($backups['type']=='S3') {
|
| 86 |
+
if (class_exists('S3')) {
|
| 87 |
+
if (!empty($jobvalue['awsAccessKey']) and !empty($jobvalue['awsSecretKey']) and !empty($jobvalue['awsBucket'])) {
|
| 88 |
+
$s3 = new S3($jobvalue['awsAccessKey'], $jobvalue['awsSecretKey'], $jobvalue['awsSSL']);
|
| 89 |
+
$s3->deleteObject($jobvalue['awsBucket'],$backups['file']);
|
| 90 |
+
}
|
| 91 |
+
}
|
| 92 |
+
} elseif ($backups['type']=='FTP') {
|
| 93 |
+
if (!empty($jobvalue['ftphost']) and !empty($jobvalue['ftpuser']) and !empty($jobvalue['ftppass'])) {
|
| 94 |
+
$ftpport=21;
|
| 95 |
+
$ftphost=$jobvalue['ftphost'];
|
| 96 |
+
if (false !== strpos($jobvalue['ftphost'],':')) //look for port
|
| 97 |
+
list($ftphost,$ftpport)=explode(':',$jobvalue,2);
|
| 98 |
+
|
| 99 |
+
$SSL=false;
|
| 100 |
+
if (function_exists('ftp_ssl_connect')) { //make SSL FTP connection
|
| 101 |
+
$ftp_conn_id = ftp_ssl_connect($ftphost,$ftpport,10);
|
| 102 |
+
if ($ftp_conn_id)
|
| 103 |
+
$SSL=true;
|
| 104 |
+
}
|
| 105 |
+
if (!$ftp_conn_id) { //make normal FTP conection if SSL not work
|
| 106 |
+
$ftp_conn_id = ftp_connect($ftphost,$ftpport,10);
|
| 107 |
+
}
|
| 108 |
+
if ($ftp_conn_id) {
|
| 109 |
+
//FTP Login
|
| 110 |
+
$loginok=false;
|
| 111 |
+
if (@ftp_login($ftp_conn_id, $jobvalue['ftpuser'], base64_decode($jobvalue['ftppass']))) {
|
| 112 |
+
$loginok=true;
|
| 113 |
+
} else { //if PHP ftp login don't work use raw login
|
| 114 |
+
if (substr(trim(ftp_raw($ftp_conn_id,'USER '.$jobvalue['ftpuser'])),0,3)<400) {
|
| 115 |
+
if (substr(trim(ftp_raw($ftp_conn_id,'PASS '.base64_decode($jobvalue['ftppass']))),0,3)<400) {
|
| 116 |
+
$loginok=true;
|
| 117 |
+
}
|
| 118 |
+
}
|
| 119 |
+
}
|
| 120 |
+
}
|
| 121 |
+
if ($loginok) {
|
| 122 |
+
ftp_pasv($ftp_conn_id, true);
|
| 123 |
+
ftp_delete($ftp_conn_id, $backups['file']);
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
}
|
| 127 |
+
$num++;
|
| 128 |
+
}
|
| 129 |
+
$backwpup_message=$num.' '.__('Backup Archives deleted', 'backwpup');
|
| 130 |
+
$_REQUEST['action']='backups';
|
| 131 |
+
break;
|
| 132 |
case 'savecfg': //Save config form Setings page
|
| 133 |
check_admin_referer('backwpup-cfg');
|
| 134 |
$cfg=get_option('backwpup'); //Load Settings
|
| 186 |
header("Content-Transfer-Encoding: binary");
|
| 187 |
header("Content-Length: ".filesize($_GET['file']));
|
| 188 |
@readfile($_GET['file']);
|
| 189 |
+
die();
|
| 190 |
+
} else {
|
| 191 |
+
header('HTTP/1.0 404 Not Found');
|
| 192 |
+
die(__('File does not exist.', 'backwpup'));
|
| 193 |
+
}
|
| 194 |
+
break;
|
| 195 |
+
case 'downloads3': //Download S3 Backup
|
| 196 |
+
//check_admin_referer('download-backup_'.basename($_GET['file']));
|
| 197 |
+
require_once(plugin_dir_path(__FILE__).'libs/S3.php');
|
| 198 |
+
$jobs=get_option('backwpup_jobs');
|
| 199 |
+
$jobid=$_GET['jobid'];
|
| 200 |
+
$s3 = new S3($jobs[$jobid]['awsAccessKey'], $jobs[$jobid]['awsSecretKey'],$jobs[$jobid]['awsSSL']);
|
| 201 |
+
if ($contents = $s3->getObjectInfo($jobs[$jobid]['awsBucket'],$_GET['file'])) {
|
| 202 |
+
header("Pragma: public");
|
| 203 |
+
header("Expires: 0");
|
| 204 |
+
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
| 205 |
+
header("Content-Type: application/force-download");
|
| 206 |
+
header("Content-Type: application/octet-stream");
|
| 207 |
+
header("Content-Type: application/download");
|
| 208 |
+
header("Content-Disposition: attachment; filename=".basename($_GET['file']).";");
|
| 209 |
+
header("Content-Transfer-Encoding: binary");
|
| 210 |
+
//header("Content-Length: ".$contents['size']);
|
| 211 |
+
var_dump($s3->getObject($jobs[$jobid]['awsBucket'], $_GET['file']));
|
| 212 |
+
die();
|
| 213 |
} else {
|
| 214 |
header('HTTP/1.0 404 Not Found');
|
| 215 |
die(__('File does not exist.', 'backwpup'));
|
| 216 |
}
|
|
|
|
| 217 |
break;
|
| 218 |
case 'saveeditjob': //Save Job settings
|
| 219 |
$jobid = (int) $_POST['jobid'];
|
app/options-settings.php
CHANGED
|
@@ -9,6 +9,7 @@ if ( !defined('ABSPATH') )
|
|
| 9 |
<ul class="subsubsub">
|
| 10 |
<li><a href="admin.php?page=BackWPup"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 11 |
<li><a href="admin.php?page=BackWPup&action=logs"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
|
|
|
| 12 |
<li><a href="admin.php?page=BackWPup&action=tools"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 13 |
<li><a href="admin.php?page=BackWPup&action=settings" class="current"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 14 |
</ul>
|
| 9 |
<ul class="subsubsub">
|
| 10 |
<li><a href="admin.php?page=BackWPup"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 11 |
<li><a href="admin.php?page=BackWPup&action=logs"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
| 12 |
+
<li><a href="admin.php?page=BackWPup&action=backups"><?PHP _e('Backups','backwpup'); ?></a> |</li>
|
| 13 |
<li><a href="admin.php?page=BackWPup&action=tools"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 14 |
<li><a href="admin.php?page=BackWPup&action=settings" class="current"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 15 |
</ul>
|
app/options-tools.php
CHANGED
|
@@ -10,6 +10,7 @@ if ( !defined('ABSPATH') )
|
|
| 10 |
<ul class="subsubsub">
|
| 11 |
<li><a href="admin.php?page=BackWPup"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 12 |
<li><a href="admin.php?page=BackWPup&action=logs"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
|
|
|
| 13 |
<li><a href="admin.php?page=BackWPup&action=tools" class="current"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 14 |
<li><a href="admin.php?page=BackWPup&action=settings"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 15 |
</ul>
|
| 10 |
<ul class="subsubsub">
|
| 11 |
<li><a href="admin.php?page=BackWPup"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 12 |
<li><a href="admin.php?page=BackWPup&action=logs"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
| 13 |
+
<li><a href="admin.php?page=BackWPup&action=backups"><?PHP _e('Backups','backwpup'); ?></a> |</li>
|
| 14 |
<li><a href="admin.php?page=BackWPup&action=tools" class="current"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 15 |
<li><a href="admin.php?page=BackWPup&action=settings"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 16 |
</ul>
|
app/options-view_log.php
CHANGED
|
@@ -9,6 +9,7 @@ if ( !defined('ABSPATH') )
|
|
| 9 |
<ul class="subsubsub">
|
| 10 |
<li><a href="admin.php?page=BackWPup"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 11 |
<li><a href="admin.php?page=BackWPup&action=logs"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
|
|
|
| 12 |
<li><a href="admin.php?page=BackWPup&action=tools"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 13 |
<li><a href="admin.php?page=BackWPup&action=settings"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 14 |
</ul>
|
| 9 |
<ul class="subsubsub">
|
| 10 |
<li><a href="admin.php?page=BackWPup"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 11 |
<li><a href="admin.php?page=BackWPup&action=logs"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
| 12 |
+
<li><a href="admin.php?page=BackWPup&action=backups"><?PHP _e('Backups','backwpup'); ?></a> |</li>
|
| 13 |
<li><a href="admin.php?page=BackWPup&action=tools"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 14 |
<li><a href="admin.php?page=BackWPup&action=settings"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 15 |
</ul>
|
app/options.php
CHANGED
|
@@ -9,6 +9,7 @@ if ( !defined('ABSPATH') )
|
|
| 9 |
<ul class="subsubsub">
|
| 10 |
<li><a href="admin.php?page=BackWPup" class="current"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 11 |
<li><a href="admin.php?page=BackWPup&action=logs"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
|
|
|
| 12 |
<li><a href="admin.php?page=BackWPup&action=tools"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 13 |
<li><a href="admin.php?page=BackWPup&action=settings"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 14 |
</ul>
|
| 9 |
<ul class="subsubsub">
|
| 10 |
<li><a href="admin.php?page=BackWPup" class="current"><?PHP _e('Jobs','backwpup'); ?></a> |</li>
|
| 11 |
<li><a href="admin.php?page=BackWPup&action=logs"><?PHP _e('Logs','backwpup'); ?></a> |</li>
|
| 12 |
+
<li><a href="admin.php?page=BackWPup&action=backups"><?PHP _e('Backups','backwpup'); ?></a> |</li>
|
| 13 |
<li><a href="admin.php?page=BackWPup&action=tools"><?PHP _e('Tools','backwpup'); ?></a> |</li>
|
| 14 |
<li><a href="admin.php?page=BackWPup&action=settings"><?PHP _e('Settings','backwpup'); ?></a></li>
|
| 15 |
</ul>
|
backwpup.php
CHANGED
|
@@ -1,57 +1,57 @@
|
|
| 1 |
-
<?php
|
| 2 |
-
/*
|
| 3 |
-
Plugin Name: BackWPup
|
| 4 |
-
Plugin URI: http://danielhuesken.de/portfolio/backwpup/
|
| 5 |
-
Description: Backup and more of your WordPress Blog Database and Files.
|
| 6 |
-
Author: Daniel Hüsken
|
| 7 |
-
Version: 1.
|
| 8 |
-
Author URI: http://danielhuesken.de
|
| 9 |
-
Text Domain: backwpup
|
| 10 |
-
Domain Path: /lang/
|
| 11 |
-
*/
|
| 12 |
-
|
| 13 |
-
/*
|
| 14 |
-
Copyright 2009 Daniel H�sken (email : daniel@huesken-net.de)
|
| 15 |
-
|
| 16 |
-
This program is free software; you can redistribute it and/or modify
|
| 17 |
-
it under the terms of the GNU General Public License as published by
|
| 18 |
-
the Free Software Foundation; either version 2 of the License, or
|
| 19 |
-
(at your option) any later version.
|
| 20 |
-
|
| 21 |
-
This program is distributed in the hope that it will be useful,
|
| 22 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 23 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 24 |
-
GNU General Public License for more details.
|
| 25 |
-
|
| 26 |
-
You should have received a copy of the GNU General Public License
|
| 27 |
-
along with this program; if not, write to the Free Software
|
| 28 |
-
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
| 29 |
-
*/
|
| 30 |
-
|
| 31 |
-
// don't load directly
|
| 32 |
-
if ( !defined('ABSPATH') )
|
| 33 |
-
die('-1');
|
| 34 |
-
|
| 35 |
-
//Set plugin dirname
|
| 36 |
-
define('BACKWPUP_PLUGIN_BASEDIR', dirname(plugin_basename(__FILE__)));
|
| 37 |
-
//Set Plugin Version
|
| 38 |
-
define('BACKWPUP_VERSION', '1.
|
| 39 |
-
//load Text Domain
|
| 40 |
-
load_plugin_textdomain('backwpup', false, BACKWPUP_PLUGIN_BASEDIR.'/lang');
|
| 41 |
-
//Load functions file
|
| 42 |
-
require_once(plugin_dir_path(__FILE__).'app/functions.php');
|
| 43 |
-
//Plugin activate
|
| 44 |
-
register_activation_hook(__FILE__, 'backwpup_plugin_activate');
|
| 45 |
-
//Plugin deactivate
|
| 46 |
-
register_deactivation_hook(__FILE__, 'backwpup_plugin_deactivate');
|
| 47 |
-
//Plugin uninstall
|
| 48 |
-
register_uninstall_hook(__FILE__, 'backwpup_plugin_uninstall');
|
| 49 |
-
|
| 50 |
-
//Version check
|
| 51 |
-
if (version_compare($wp_version, '2.8', '<') and version_compare(phpversion(), '5.0.0', '<')) { // Let only Activate on WordPress Version 2.8 or
|
| 52 |
-
add_action('admin_notices', create_function('', 'echo \'<div id="message" class="error fade"><p><strong>' . __('Sorry, BackWPup works only with WordPress 2.8 and PHP 5.0.0 or
|
| 53 |
-
} else {
|
| 54 |
-
//Plugin init
|
| 55 |
-
add_action('plugins_loaded', 'backwpup_init');
|
| 56 |
-
}
|
| 57 |
-
?>
|
| 1 |
+
<?php
|
| 2 |
+
/*
|
| 3 |
+
Plugin Name: BackWPup
|
| 4 |
+
Plugin URI: http://danielhuesken.de/portfolio/backwpup/
|
| 5 |
+
Description: Backup and more of your WordPress Blog Database and Files.
|
| 6 |
+
Author: Daniel Hüsken
|
| 7 |
+
Version: 1.2.0
|
| 8 |
+
Author URI: http://danielhuesken.de
|
| 9 |
+
Text Domain: backwpup
|
| 10 |
+
Domain Path: /lang/
|
| 11 |
+
*/
|
| 12 |
+
|
| 13 |
+
/*
|
| 14 |
+
Copyright 2009 Daniel H�sken (email : daniel@huesken-net.de)
|
| 15 |
+
|
| 16 |
+
This program is free software; you can redistribute it and/or modify
|
| 17 |
+
it under the terms of the GNU General Public License as published by
|
| 18 |
+
the Free Software Foundation; either version 2 of the License, or
|
| 19 |
+
(at your option) any later version.
|
| 20 |
+
|
| 21 |
+
This program is distributed in the hope that it will be useful,
|
| 22 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 23 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 24 |
+
GNU General Public License for more details.
|
| 25 |
+
|
| 26 |
+
You should have received a copy of the GNU General Public License
|
| 27 |
+
along with this program; if not, write to the Free Software
|
| 28 |
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
| 29 |
+
*/
|
| 30 |
+
|
| 31 |
+
// don't load directly
|
| 32 |
+
if ( !defined('ABSPATH') )
|
| 33 |
+
die('-1');
|
| 34 |
+
|
| 35 |
+
//Set plugin dirname
|
| 36 |
+
define('BACKWPUP_PLUGIN_BASEDIR', dirname(plugin_basename(__FILE__)));
|
| 37 |
+
//Set Plugin Version
|
| 38 |
+
define('BACKWPUP_VERSION', '1.2.0');
|
| 39 |
+
//load Text Domain
|
| 40 |
+
load_plugin_textdomain('backwpup', false, BACKWPUP_PLUGIN_BASEDIR.'/lang');
|
| 41 |
+
//Load functions file
|
| 42 |
+
require_once(plugin_dir_path(__FILE__).'app/functions.php');
|
| 43 |
+
//Plugin activate
|
| 44 |
+
register_activation_hook(__FILE__, 'backwpup_plugin_activate');
|
| 45 |
+
//Plugin deactivate
|
| 46 |
+
register_deactivation_hook(__FILE__, 'backwpup_plugin_deactivate');
|
| 47 |
+
//Plugin uninstall
|
| 48 |
+
register_uninstall_hook(__FILE__, 'backwpup_plugin_uninstall');
|
| 49 |
+
|
| 50 |
+
//Version check
|
| 51 |
+
if (version_compare($wp_version, '2.8', '<') and version_compare(phpversion(), '5.0.0', '<')) { // Let only Activate on WordPress Version 2.8 or higher
|
| 52 |
+
add_action('admin_notices', create_function('', 'echo \'<div id="message" class="error fade"><p><strong>' . __('Sorry, BackWPup works only with WordPress 2.8 and PHP 5.0.0 or higher!!!','backwpup') . '</strong></p></div>\';'));
|
| 53 |
+
} else {
|
| 54 |
+
//Plugin init
|
| 55 |
+
add_action('plugins_loaded', 'backwpup_init');
|
| 56 |
+
}
|
| 57 |
+
?>
|
readme.txt
CHANGED
|
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=danie
|
|
| 4 |
Tags: backup, admin, file, Database, mysql, cron, ftp, S3, export
|
| 5 |
Requires at least: 2.8
|
| 6 |
Tested up to: 3.0.0
|
| 7 |
-
Stable tag: 1.
|
| 8 |
|
| 9 |
Backup and more of your WordPress Blog Database and Files
|
| 10 |
|
|
@@ -13,11 +13,11 @@ Backup and more of your WordPress Blog Database and Files
|
|
| 13 |
Backup and more your Blog.
|
| 14 |
|
| 15 |
* Database Backup
|
| 16 |
-
*
|
| 17 |
* Optimize Database
|
| 18 |
* Check\Repair Database
|
| 19 |
* File Backup
|
| 20 |
-
* Backups in zip,tar,tar.gz,tar.bz2
|
| 21 |
* Store backup to Folder
|
| 22 |
* Store backup to FTP Server
|
| 23 |
* Store backup to Amazon S3
|
|
@@ -31,12 +31,12 @@ I can give no WARRANTY to any backups...
|
|
| 31 |
|
| 32 |
1. Download BackWPup Plugin.
|
| 33 |
1. Decompress and upload the contents of the archive into /wp-content/plugins/.
|
| 34 |
-
1. Activate the
|
| 35 |
|
| 36 |
== Frequently Asked Questions ==
|
| 37 |
= Requires =
|
| 38 |
* PHP 5.0.0
|
| 39 |
-
*
|
| 40 |
* curl (for Amazon S3 Support)
|
| 41 |
* gzip (for PCLZIP and gzip archives)
|
| 42 |
* bzip2 (for bzip2 archives)
|
|
@@ -44,54 +44,61 @@ I can give no WARRANTY to any backups...
|
|
| 44 |
= Where is the Database dump File =
|
| 45 |
in the root folder of the Archive. <i>DBName</i>.sql
|
| 46 |
|
| 47 |
-
= Where is the
|
| 48 |
in the root folder of the Archive. wordpress.<i>jjjj-mm-dd</i>.xml
|
| 49 |
|
| 50 |
= Zip File Support =
|
| 51 |
-
Plugin use PCLZIP lib if not
|
| 52 |
|
| 53 |
-
=
|
| 54 |
Supported Plugins
|
| 55 |
* maintenance-mode
|
| 56 |
* wp-maintenance-mode
|
| 57 |
-
*
|
| 58 |
|
| 59 |
-
if your
|
| 60 |
|
| 61 |
-
=
|
| 62 |
-
Copy the <i>DBName</i>.sql in the root folder of the
|
| 63 |
-
You
|
| 64 |
|
| 65 |
= Abnormal Script aborts =
|
| 66 |
-
Webserver
|
| 67 |
-
PHP
|
| 68 |
|
| 69 |
= Memory usage =
|
| 70 |
* The Plugin is coded to use low memory
|
| 71 |
-
* The Plugin will try to increase Memory
|
| 72 |
-
* PCLZIP lib need 8MB free
|
| 73 |
* Mail a archive need many Memory
|
| 74 |
|
| 75 |
-
= Mail
|
| 76 |
I have build in many options to Optimize the Mailing but the mailing lib uses high Memory.
|
| 77 |
-
|
| 78 |
|
| 79 |
== Screenshots ==
|
| 80 |
|
| 81 |
1. Job Page
|
| 82 |
|
| 83 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
= 1.1.1 =
|
| 85 |
* fixed S3 lib not found bug again.
|
| 86 |
* improved reschedule on activation problem.
|
| 87 |
|
| 88 |
= 1.1.0 =
|
| 89 |
-
* added
|
| 90 |
-
* added no
|
| 91 |
-
* changed error handling a bit and remove PHP errors that can't
|
| 92 |
-
* fixed problem with not compiled --enable-memory-limit in
|
| 93 |
* removed setting for memory limit use WP filter and default now (256M)
|
| 94 |
-
* now a time limit of 5 mins is set again for job execution but it will be
|
| 95 |
* added a shutdown function if __destruct not called for job
|
| 96 |
* added more flexible Backup file selection
|
| 97 |
|
|
@@ -99,11 +106,11 @@ Pleace mail only littele archives
|
|
| 99 |
* fix "Undefined index: dbshortinsert"
|
| 100 |
|
| 101 |
= 1.0.9 =
|
| 102 |
-
* change s3 class to hide
|
| 103 |
-
* add option to make MySQL INSERTs shorter (
|
| 104 |
-
* add
|
| 105 |
-
*
|
| 106 |
-
* add S3
|
| 107 |
|
| 108 |
= 1.0.8 =
|
| 109 |
* fix temp backup file not deleted if no destination folder
|
|
@@ -124,42 +131,42 @@ Pleace mail only littele archives
|
|
| 124 |
|
| 125 |
= 1.0.4 =
|
| 126 |
* fixed bugs in DB restore
|
| 127 |
-
* use WP functions to get
|
| 128 |
|
| 129 |
= 1.0.3 =
|
| 130 |
-
*
|
| 131 |
|
| 132 |
= 1.0.2 =
|
| 133 |
-
*
|
| 134 |
|
| 135 |
= 1.0.1 =
|
| 136 |
-
*
|
| 137 |
|
| 138 |
= 1.0.0 =
|
| 139 |
-
* now
|
| 140 |
* new backup files formats tar, tar.gz, tar.bz2
|
| 141 |
* all job types can made in one job
|
| 142 |
-
* added
|
| 143 |
* removed PclZip trace code
|
| 144 |
* fixed time display and schedule bugs
|
| 145 |
* added some security
|
| 146 |
-
*
|
| 147 |
* new Design on some Pages
|
| 148 |
|
| 149 |
= 0.8.1 =
|
| 150 |
-
* use global var
|
| 151 |
-
*
|
| 152 |
|
| 153 |
= 0.8.0 =
|
| 154 |
-
*
|
| 155 |
-
* crate .htaccsses on Apache and index.html on other
|
| 156 |
* fixed global for $wp_version
|
| 157 |
-
* set max execution time to 0 for
|
| 158 |
* use WP function to generate options tables
|
| 159 |
* Backup file list and zip creation changes
|
| 160 |
* Added support for Amazon S3
|
| 161 |
* Only works with PHP 5 now
|
| 162 |
-
*
|
| 163 |
* PHP errors now in Backup log
|
| 164 |
* Log now in files
|
| 165 |
|
|
@@ -169,15 +176,15 @@ Pleace mail only littele archives
|
|
| 169 |
* make date with date_i18n
|
| 170 |
|
| 171 |
= 0.7.1 =
|
| 172 |
-
* FTP
|
| 173 |
* no Errors in Log for FTP ALLO command.
|
| 174 |
|
| 175 |
= 0.7.0 =
|
| 176 |
* set ftp Connection timeout to 10 sec
|
| 177 |
* fix bug for DB tables exclude
|
| 178 |
-
* DB Backup in
|
| 179 |
* Fixed missing ; in DB Backup
|
| 180 |
-
* Added tool DB Restore with automatic Blog
|
| 181 |
|
| 182 |
= 0.6.5 =
|
| 183 |
* Prevent direct file loading
|
|
@@ -197,7 +204,7 @@ Pleace mail only littele archives
|
|
| 197 |
* use ftp_row for login and other commands
|
| 198 |
* Add option to send only email on errors
|
| 199 |
* Internal structure changes
|
| 200 |
-
* Add option to disable WP-Cron and use
|
| 201 |
* bug fixes
|
| 202 |
|
| 203 |
= 0.6.2 =
|
| 4 |
Tags: backup, admin, file, Database, mysql, cron, ftp, S3, export
|
| 5 |
Requires at least: 2.8
|
| 6 |
Tested up to: 3.0.0
|
| 7 |
+
Stable tag: 1.2.0
|
| 8 |
|
| 9 |
Backup and more of your WordPress Blog Database and Files
|
| 10 |
|
| 13 |
Backup and more your Blog.
|
| 14 |
|
| 15 |
* Database Backup
|
| 16 |
+
* WordPress XML Export
|
| 17 |
* Optimize Database
|
| 18 |
* Check\Repair Database
|
| 19 |
* File Backup
|
| 20 |
+
* Backups in zip,tar,tar.gz,tar.bz2 format
|
| 21 |
* Store backup to Folder
|
| 22 |
* Store backup to FTP Server
|
| 23 |
* Store backup to Amazon S3
|
| 31 |
|
| 32 |
1. Download BackWPup Plugin.
|
| 33 |
1. Decompress and upload the contents of the archive into /wp-content/plugins/.
|
| 34 |
+
1. Activate the Plugin through the 'Plugins' menu in WordPress
|
| 35 |
|
| 36 |
== Frequently Asked Questions ==
|
| 37 |
= Requires =
|
| 38 |
* PHP 5.0.0
|
| 39 |
+
* WordPress 2.8
|
| 40 |
* curl (for Amazon S3 Support)
|
| 41 |
* gzip (for PCLZIP and gzip archives)
|
| 42 |
* bzip2 (for bzip2 archives)
|
| 44 |
= Where is the Database dump File =
|
| 45 |
in the root folder of the Archive. <i>DBName</i>.sql
|
| 46 |
|
| 47 |
+
= Where is the WordPress Export File =
|
| 48 |
in the root folder of the Archive. wordpress.<i>jjjj-mm-dd</i>.xml
|
| 49 |
|
| 50 |
= Zip File Support =
|
| 51 |
+
Plugin use PCLZIP lib if not PHP uses zip extension
|
| 52 |
|
| 53 |
+
= Maintenance Mode =
|
| 54 |
Supported Plugins
|
| 55 |
* maintenance-mode
|
| 56 |
* wp-maintenance-mode
|
| 57 |
+
* WordPress .maintenance file
|
| 58 |
|
| 59 |
+
if your Blog do not come back from Maintenance Mode switch back from Maintenance Mode by changing the Plugin options or delete the <i>.maintenance</i> file in Blog root folder.
|
| 60 |
|
| 61 |
+
= Restore a Blog Database =
|
| 62 |
+
Copy the <i>DBName</i>.sql in the root folder of the Blog and go to the tools tab in the Plugin.
|
| 63 |
+
You can use PHPMyAdmin also.
|
| 64 |
|
| 65 |
= Abnormal Script aborts =
|
| 66 |
+
Webserver normally abort Scrips that works longer then 300s.
|
| 67 |
+
PHP normally abort Script that works longer then 30s but the Plugin try too switch off the abortion.
|
| 68 |
|
| 69 |
= Memory usage =
|
| 70 |
* The Plugin is coded to use low memory
|
| 71 |
+
* The Plugin will try to increase Memory automatically if needed
|
| 72 |
+
* PCLZIP lib need 8MB free Memory for zipping
|
| 73 |
* Mail a archive need many Memory
|
| 74 |
|
| 75 |
+
= Mail archives =
|
| 76 |
I have build in many options to Optimize the Mailing but the mailing lib uses high Memory.
|
| 77 |
+
Place mail only little archives
|
| 78 |
|
| 79 |
== Screenshots ==
|
| 80 |
|
| 81 |
1. Job Page
|
| 82 |
|
| 83 |
== Changelog ==
|
| 84 |
+
= 1.2.0 =
|
| 85 |
+
* Backup file size now in log file
|
| 86 |
+
* Paged Logs Table
|
| 87 |
+
* added Backup Archives Page
|
| 88 |
+
* Grammar fixes
|
| 89 |
+
* Bug fixes
|
| 90 |
+
|
| 91 |
= 1.1.1 =
|
| 92 |
* fixed S3 lib not found bug again.
|
| 93 |
* improved reschedule on activation problem.
|
| 94 |
|
| 95 |
= 1.1.0 =
|
| 96 |
+
* added function to check/update job settings
|
| 97 |
+
* added no Ajax bucket list to job page
|
| 98 |
+
* changed error handling a bit and remove PHP errors that can't handled
|
| 99 |
+
* fixed problem with not compiled --enable-memory-limit in PHP
|
| 100 |
* removed setting for memory limit use WP filter and default now (256M)
|
| 101 |
+
* now a time limit of 5 mins. is set again for job execution but it will be reseted on every message. (prevent never ending jobs.)
|
| 102 |
* added a shutdown function if __destruct not called for job
|
| 103 |
* added more flexible Backup file selection
|
| 104 |
|
| 106 |
* fix "Undefined index: dbshortinsert"
|
| 107 |
|
| 108 |
= 1.0.9 =
|
| 109 |
+
* change s3 class to hide warnings
|
| 110 |
+
* add option to make MySQL INSERTs shorter (smaller dump file size.)
|
| 111 |
+
* add requirements checks
|
| 112 |
+
* Ajaxed S3 bucket selection in job settings
|
| 113 |
+
* add S3 Bucket can made in job settings
|
| 114 |
|
| 115 |
= 1.0.8 =
|
| 116 |
* fix temp backup file not deleted if no destination folder
|
| 131 |
|
| 132 |
= 1.0.4 =
|
| 133 |
* fixed bugs in DB restore
|
| 134 |
+
* use WP functions to get Plugin dirs
|
| 135 |
|
| 136 |
= 1.0.3 =
|
| 137 |
+
* hopefully fixed a cache problem on run now
|
| 138 |
|
| 139 |
= 1.0.2 =
|
| 140 |
+
* fixed bug for file excludes
|
| 141 |
|
| 142 |
= 1.0.1 =
|
| 143 |
+
* fixed bug for https
|
| 144 |
|
| 145 |
= 1.0.0 =
|
| 146 |
+
* now WordPress Exports to XML can made
|
| 147 |
* new backup files formats tar, tar.gz, tar.bz2
|
| 148 |
* all job types can made in one job
|
| 149 |
+
* added PHP zip extension support (use pclzip only if not supported)
|
| 150 |
* removed PclZip trace code
|
| 151 |
* fixed time display and schedule bugs
|
| 152 |
* added some security
|
| 153 |
+
* Maintenance Mode on MySQL Operations
|
| 154 |
* new Design on some Pages
|
| 155 |
|
| 156 |
= 0.8.1 =
|
| 157 |
+
* use global var instead of constant for log file
|
| 158 |
+
* PCLZip Trace included with setting for log Level
|
| 159 |
|
| 160 |
= 0.8.0 =
|
| 161 |
+
* Fixed not working default settings on settings page
|
| 162 |
+
* crate .htaccsses on Apache and index.html on other Webserver
|
| 163 |
* fixed global for $wp_version
|
| 164 |
+
* set max execution time to 0 for unlimited
|
| 165 |
* use WP function to generate options tables
|
| 166 |
* Backup file list and zip creation changes
|
| 167 |
* Added support for Amazon S3
|
| 168 |
* Only works with PHP 5 now
|
| 169 |
+
* Complete rewrite of job doing as PHP5 class
|
| 170 |
* PHP errors now in Backup log
|
| 171 |
* Log now in files
|
| 172 |
|
| 176 |
* make date with date_i18n
|
| 177 |
|
| 178 |
= 0.7.1 =
|
| 179 |
+
* FTP Connection test changes
|
| 180 |
* no Errors in Log for FTP ALLO command.
|
| 181 |
|
| 182 |
= 0.7.0 =
|
| 183 |
* set ftp Connection timeout to 10 sec
|
| 184 |
* fix bug for DB tables exclude
|
| 185 |
+
* DB Backup in MySQL Client encoding now
|
| 186 |
* Fixed missing ; in DB Backup
|
| 187 |
+
* Added tool DB Restore with automatic Blog URL/Path change
|
| 188 |
|
| 189 |
= 0.6.5 =
|
| 190 |
* Prevent direct file loading
|
| 204 |
* use ftp_row for login and other commands
|
| 205 |
* Add option to send only email on errors
|
| 206 |
* Internal structure changes
|
| 207 |
+
* Add option to disable WP-Cron and use Hosters cron
|
| 208 |
* bug fixes
|
| 209 |
|
| 210 |
= 0.6.2 =
|
