PluginProbe
ManageWP Worker / 3.9.8
ManageWP Worker v3.9.8
4.9.38 4.9.37 4.9.36 4.9.35 4.9.34 3.8.7 3.8.8 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.2 3.9.20 3.9.21 3.9.22 3.9.23 3.9.24 All 73 releases
worker / backup.class.php

backup.class.php in ManageWP Worker 3.9.8, at backup.class.php

1,457 lines 51.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*************************************************************
3 *
4 * backup.class.php
5 *
6 * Manage Backups
7 *
8 *
9 * Copyright (c) 2011 Prelovac Media
10 * www.prelovac.com
11 **************************************************************/
12
13 class MMB_Backup extends MMB_Core
14 {
15 var $site_name;
16 function __construct()
17 {
18 parent::__construct();
19 $this->site_name = str_replace("/","-",rtrim($this->remove_http(get_bloginfo('home')),"/"));
20 }
21
22 function get_backup_settings()
23 {
24 $backup_settings = get_option('mwp_backup_tasks');
25 if (!empty($backup_settings))
26 return $backup_settings;
27 else
28 return false;
29 }
30
31 function set_backup_task($params)
32 {
33 //$params => [$task_name, $args, $error]
34 if (!empty($params)) {
35 extract($params);
36
37 $before = $this->get_backup_settings();
38 if (!$before || empty($before))
39 $before = array();
40
41 if (isset($args['remove'])) {
42 unset($before[$task_name]);
43 $return = array(
44 'removed' => true
45 );
46 } else {
47 if(is_array($params['account_info'])){ //only if sends from master first time(secure data)
48 $args['account_info'] = $account_info;
49 }
50
51 $before[$task_name]['task_args'] = $args;
52 if (strlen($args['schedule']))
53 $before[$task_name]['task_args']['next'] = $this->schedule_next($args['type'], $args['schedule']);
54
55 $return = $before[$task_name];
56 }
57
58 if ($error) {
59 if(is_array($error)){
60 $before[$task_name]['task_results'][count($before[$task_name]['task_results'])-1]['error'] = $error['error'];
61 } else {
62 $before[$task_name]['task_results'][count($before[$task_name]['task_results'])]['error'] = $error;
63 }
64 }
65 update_option('mwp_backup_tasks', $before);
66
67 if ($task_name == 'Backup Now') {
68 $result = $this->backup($args, $task_name);
69 $backup_settings = $this->get_backup_settings();
70 if (is_array($result) && array_key_exists('error', $result)) {
71 $return = $result;
72 } else {
73 $return = $backup_settings[$task_name];
74 }
75 }
76 return $return;
77 }
78 return false;
79 }
80
81 //Cron check
82 function check_backup_tasks()
83 {
84 $settings = $this->get_backup_settings();
85 if (is_array($settings) && !empty($settings)) {
86 foreach ($settings as $task_name => $setting) {
87 if ($setting['task_args']['next'] && $setting['task_args']['next'] < time()) {
88 //Update task with next schedule
89 $this->set_backup_task(array(
90 'task_name' => $task_name,
91 'args' => $settings[$task_name]['task_args']
92 ));
93
94 $result = $this->backup($setting['task_args'], $task_name);
95 $error = '';
96 if (is_array($result) && array_key_exists('error', $result)) {
97 $error = $result;
98 $this->set_backup_task(array(
99 'task_name' => $task_name,
100 'args' => $settings[$task_name]['task_args'],
101 'error' => $error
102 ));
103 } else {
104 $error = '';
105 }
106
107
108 break;
109 }
110 }
111 }
112
113 }
114
115
116
117 /*
118 * If Task Name not set then it's manual backup
119 * Backup args:
120 * type -> db, full
121 * what -> daily, weekly, monthly
122 * account_info -> ftp, amazons3, dropbox
123 * exclude-> array of paths to exclude from backup
124 */
125
126 function backup($args, $task_name = false)
127 {
128 if (!$args || empty($args))
129 return false;
130
131 extract($args); //extract settings
132
133 //try increase memory limit
134 @ini_set('memory_limit', '1000M');
135 @set_time_limit(600); //ten minutes
136
137 //Remove old backup(s)
138 if ($type == 'manual') {
139 $old = get_option('mwp_manual_backup');
140 if ($old['file_path'] && file_exists($old['file_path']))
141 @unlink($old['file_path']);
142 } else {
143 $this->remove_old_backups($task_name);
144 }
145
146 $sec_string = md5('mmb-worker');
147 $file = "/$sec_string/mwp_backups";
148 $new_file_path = WP_CONTENT_DIR . $file;
149
150 if (!file_exists($new_file_path)) {
151 if (!mkdir($new_file_path, 0755, true))
152 return array(
153 'error' => 'Permission denied, make sure you have write permission to wp-content folder.'
154 );
155 }
156
157 @file_put_contents($new_file_path . '/index.php', ''); //safe
158
159 //Delete possible breaked previous backups - don't need it anymore (works only for previous wrokers)
160 foreach (glob($new_file_path . "/*.zip") as $filename) {
161 $short = basename($filename);
162 preg_match('/^wp\-content(.*)/Ui', $short, $matches);
163 if ($matches)
164 @unlink($filename);
165 }
166
167 //Prepare .zip file name
168 $site_name = $this->remove_http(get_bloginfo('url'));
169 $site_name = str_replace(array(
170 "_",
171 "/"
172 ), array(
173 "",
174 "-"
175 ), $site_name);
176
177 $hash = md5(time());
178 $label = $type ? $type : 'manual';
179 $backup_file = $new_file_path . '/' . $site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
180 $backup_url = WP_CONTENT_URL . $file . '/' . $site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
181
182
183 //What to backup - db or full
184 if (trim($what) == 'db') {
185 //take database backup
186
187 $db_result = $this->backup_db();
188 if ($db_result == false) {
189 return array(
190 'error' => 'Failed to backup database.'
191 );
192 } else if (is_array($db_result) && isset($db_result['error'])) {
193 return array(
194 'error' => $db_result['error']
195 );
196
197 } else {
198 if ($this->mmb_exec('which zip')) {
199 chdir(WP_CONTENT_DIR);
200 $command = "zip -r $backup_file 'mwp_db'";
201
202 ob_start();
203 $result = $this->mmb_exec($command);
204 ob_get_clean();
205 } else {
206 require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
207 $archive = new PclZip($backup_file);
208 $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR);
209 }
210
211 @unlink($db_result);
212 if (!$result)
213 return array(
214 'error' => 'Failed to zip database.'
215 );
216 }
217 } elseif (trim($what) == 'full') {
218 $content_backup = $this->backup_full($backup_file, $exclude);
219 if (is_array($content_backup) && array_key_exists('error', $content_backup)) {
220 return array(
221 'error' => $content_backup['error']
222 );
223 }
224 }
225
226 //Update backup info
227 if ($task_name) {
228 //backup task (scheduled)
229 $backup_settings = $this->get_backup_settings();
230 $paths = array();
231 $size = ceil(filesize($backup_file) / 1024);
232
233 if ($size > 1000) {
234 $paths['size'] = ceil($size / 1024) . 'Mb';
235 } else {
236 $paths['size'] = $size . 'kb';
237 }
238 $paths['time'] = time();
239
240 if ($task_name != 'Backup Now') {
241 if (!$backup_settings[$task_name]['task_args']['del_host_file']) {
242 $paths['server'] = array(
243 'file_path' => $backup_file,
244 'file_url' => $backup_url
245 );
246 }
247 } else {
248 $paths['server'] = array(
249 'file_path' => $backup_file,
250 'file_url' => $backup_url
251 );
252 }
253
254 if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_ftp'])) {
255 $paths['ftp'] = basename($backup_url);
256 }
257
258 if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_amazon_s3'])) {
259 $paths['amazons3'] = basename($backup_url);
260 }
261
262 if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_dropbox'])) {
263 $paths['dropbox'] = basename($backup_url);
264 }
265
266 if ($backup_settings[$task_name]['task_args']['email_backup']) {
267 $paths['email'] = $backup_settings[$task_name]['task_args']['email_backup'];
268 }
269
270 $temp = $backup_settings[$task_name]['task_results'];
271 $temp['temp'] = $paths;
272 $backup_settings[$task_name]['task_results'] = array_values($temp);
273 update_option('mwp_backup_tasks', $backup_settings);
274 } else {
275 //manual - predefined backup used for cloning
276 $manual_backup = $args;
277 $manual_backup['file_path'] = $backup_file;
278 $manual_backup['file_url'] = $backup_url;
279 update_option('mwp_manual_backup', $manual_backup);
280 }
281
282
283 //Additional: Email, ftp, amazon_s3, dropbox...
284 if (isset($optimize_tables) && !empty($optimize_tables)) {
285 $this->optimize_tables();
286 }
287
288 if ($task_name != 'Backup Now') {
289 if (isset($account_info['mwp_ftp']) && !empty($account_info['mwp_ftp'])) {
290 $account_info['mwp_ftp']['backup_file'] = $backup_file;
291 $ftp_result = $this->ftp_backup($account_info['mwp_ftp']);
292 if(is_array($ftp_result) && isset($ftp_result['error'])){
293 return $ftp_result;
294 }
295 }
296
297 if (isset($account_info['mwp_amazon_s3']) && !empty($account_info['mwp_amazon_s3'])) {
298 $account_info['mwp_amazon_s3']['backup_file'] = $backup_file;
299 $amazons3_result = $this->amazons3_backup($account_info['mwp_amazon_s3']);
300 if(is_array($amazons3_result) && isset($amazons3_result['error'])){
301 return $amazons3_result;
302 }
303 }
304
305 if (isset($account_info['mwp_dropbox']) && !empty($account_info['mwp_dropbox'])) {
306 $account_info['mwp_dropbox']['backup_file'] = $backup_file;
307 $dropbox_result = $this->dropbox_backup($account_info['mwp_dropbox']);
308 if(is_array($dropbox_result) && isset($dropbox_result['error'])){
309 return $dropbox_result;
310 }
311 }
312
313 if (isset($email_backup) && is_email($email_backup)) {
314 $mail_args = array(
315 'email' => $email_backup,
316 'task_name' => $task_name,
317 'file_path' => $backup_file
318 );
319 $this->email_backup($mail_args);
320 }
321
322 if ($del_host_file) {
323 @unlink($backup_file);
324 }
325
326 } //end additional
327
328 return $backup_url; //Return url to backup file (we need return only for manual backup)
329 }
330
331 function backup_full($backup_file, $exclude = array())
332 {
333 $db_result = $this->backup_db();
334 if ($db_result == false) {
335 return array(
336 'error' => 'Failed to backup database.'
337 );
338 } else if (is_array($db_result) && isset($db_result['error'])) {
339 return array(
340 'error' => $db_result['error']
341 );
342 }
343
344 $sec_string = md5('mmb-worker');
345 $remove = array(
346 "wp-content/$sec_string/mwp_backups",
347 "wp-content/mwp_db"
348 );
349
350 if ($this->mmb_exec('which zip')) {
351 chdir(ABSPATH);
352
353 //exclude paths
354 $exclude_data = "-x";
355 if (!empty($exclude)) {
356 foreach ($exclude as $data) {
357 if ($data)
358 $exclude_data .= " '$data/*'";
359 }
360 }
361
362 foreach ($remove as $data) {
363 $exclude_data .= " '$data/*'";
364 }
365
366 $command = "zip -r $backup_file './' $exclude_data";
367 ob_start();
368 $result = $this->mmb_exec($command);
369 ob_get_clean();
370
371 //Add database file
372 chdir(WP_CONTENT_DIR);
373 $command = "zip -r $backup_file 'mwp_db'";
374 ob_start();
375 $result = $this->mmb_exec($command);
376 ob_get_clean();
377
378 @unlink($db_result);
379
380 if ($result) {
381 return true;
382 } else {
383 return array(
384 'error' => 'Failed to backup site.'
385 );
386 }
387
388 } else { //php zip
389
390 require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
391 $archive = new PclZip($backup_file);
392 $result = $archive->add(ABSPATH, PCLZIP_OPT_REMOVE_PATH, ABSPATH);
393 $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR);
394 $exclude_data = array();
395 if (!empty($exclude) && $result) {
396 $exclude_data = array();
397 foreach ($exclude as $data) {
398 if ($data)
399 $exclude_data[] = $data . '/';
400 }
401 }
402 foreach ($remove as $rem) {
403 $exclude_data[] = $rem . '/';
404 }
405
406 $result = $archive->delete(PCLZIP_OPT_BY_NAME, $exclude_data);
407
408 @unlink($db_result);
409 if ($result) {
410 return true;
411 } else {
412 if ($archive->error_code == '-10') {
413 return array(
414 'error' => 'Failed to backup site. Try increasing memory limit and/or free space on your server.'
415 );
416 } else {
417 return array(
418 'error' => 'Failed to backup site. Try to enable Zip on your server.'
419 );
420 }
421 }
422 }
423 }
424
425
426 function backup_db()
427 {
428 $db_folder = ABSPATH . 'wp-content/mwp_db/';
429 if (!file_exists($db_folder)) {
430 if (!mkdir($db_folder, 0755, true))
431 return array(
432 'error' => 'Error creating database backup folder. Make sure you have write permissions to your site root folder.'
433 );
434 }
435
436 $file = $db_folder . DB_NAME . '.sql';
437 $mysqldump = $this->check_mysqldump();
438 if (is_array($mysqldump)) {
439 $result = $this->backup_db_dump($file, $mysqldump);
440
441 } else {
442 $result = $this->backup_db_php($file);
443 }
444 return $result;
445 }
446
447 function backup_db_dump($file, $mysqldump)
448 {
449 global $wpdb;
450 $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
451 $command = $brace . $mysqldump['mysqldump'] . $brace . ' --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables "' . DB_NAME . '" > ' . $brace . $file . $brace;
452
453 ob_start();
454 $result = $this->mmb_exec($command);
455 ob_get_clean();
456 if (!$result) {
457 $result = $this->backup_db_php($file);
458 return $result;
459 }
460
461 if (filesize($file) == 0 || !is_file($file) || !$result) {
462 @unlink($file);
463 return false;
464 } else {
465 return $file;
466 }
467 }
468
469 function backup_db_php($file)
470 {
471 global $wpdb;
472 $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
473 foreach ($tables as $table) {
474 //drop existing table
475 $dump_data = "DROP TABLE IF EXISTS $table[0];";
476 //create table
477 $create_table = $wpdb->get_row("SHOW CREATE TABLE $table[0]", ARRAY_N);
478 $dump_data .= "\n\n" . $create_table[1] . ";\n\n";
479
480 $count = $wpdb->get_var("SELECT count(*) FROM $table[0]");
481 if ($count > 100)
482 $count = ceil($count / 100) - 1;
483 else
484 $count = 1;
485 for ($i = 0; $i < $count; $i++) {
486 $low_limit = $i * 100;
487 $qry = "SELECT * FROM $table[0] LIMIT $low_limit, 100";
488 $rows = $wpdb->get_results($qry, ARRAY_A);
489 if (is_array($rows)) {
490 foreach ($rows as $row) {
491 //insert single row
492 $dump_data .= "INSERT INTO $table[0] VALUES(";
493 $num_values = count($row);
494 $j = 1;
495 foreach ($row as $value) {
496 $value = addslashes($value);
497 $value = preg_replace("/\n/Ui", "\\n", $value);
498 $num_values == $j ? $dump_data .= "'" . $value . "'" : $dump_data .= "'" . $value . "', ";
499 $j++;
500 unset($value);
501 }
502 $dump_data .= ");\n";
503 }
504 }
505 }
506 $dump_data .= "\n\n\n";
507
508 unset($rows);
509 file_put_contents($file, $dump_data, FILE_APPEND);
510 unset($dump_data);
511 }
512
513 if (filesize($file) == 0 || !is_file($file)) {
514 @unlink($file);
515 return false;
516 }
517
518 return $file;
519
520 }
521
522 function restore($args)
523 {
524 global $wpdb;
525 if (empty($args)) {
526 return false;
527 }
528
529 extract($args);
530 @ini_set('memory_limit', '300M');
531 @set_time_limit(300);
532
533 $unlink_file = true; //Delete file after restore
534
535 //Detect source
536 if ($backup_url) {
537 //This is for clone (overwrite)
538 include_once ABSPATH . 'wp-admin/includes/file.php';
539 $backup_file = download_url($backup_url);
540 if (is_wp_error($backup_file)) {
541 return array(
542 'error' => $backup_file->get_error_message()
543 );
544 }
545 $what = 'full';
546 } else {
547 $tasks = $this->get_backup_settings();
548 $task = $tasks[$task_name];
549 if (isset($task['task_results'][$result_id]['server'])) {
550 $backup_file = $task['task_results'][$result_id]['server']['file_path'];
551 $unlink_file = false; //Don't delete file if stored on server
552 } elseif (isset($task['task_results'][$result_id]['ftp'])) {
553 $ftp_file = $task['task_results'][$result_id]['ftp'];
554 $args = $task['task_args']['account_info']['mwp_ftp'];
555 $args['backup_file'] = $ftp_file;
556 $backup_file = $this->get_ftp_backup($args);
557 if ($backup_file == false) {
558 return array(
559 'error' => 'Failed to download file from FTP'
560 );
561 }
562 } elseif (isset($task['task_results'][$result_id]['amazons3'])) {
563 $amazons3_file = $task['task_results'][$result_id]['amazons3'];
564 $args = $task['task_args']['account_info']['mwp_amazon_s3'];
565 $args['backup_file'] = $ftp_file;
566 $backup_file = $this->get_amazons3_backup($args);
567 if ($backup_file == false) {
568 return array(
569 'error' => 'Failed to download file from Amazon S3'
570 );
571 }
572 }
573
574 $what = $tasks[$task_name]['task_args']['what'];
575 }
576
577 if ($backup_file && file_exists($backup_file)) {
578 if ($overwrite) {
579 //Keep old db credentials before overwrite
580 if (!rename(ABSPATH . 'wp-config.php', ABSPATH . 'mwp-temp-wp-config.php')) {
581 return array(
582 'error' => 'Error creating wp-config. Please check your write permisions.'
583 );
584 }
585
586 $db_host = DB_HOST;
587 $db_user = DB_USER;
588 $db_password = DB_PASSWORD;
589 $home = rtrim(get_option('home'),"/");
590 $site_url = get_option('site_url');
591 }
592
593 if ($this->mmb_exec('which unzip')) {
594 chdir(ABSPATH);
595 $command = "unzip -o $backup_file";
596 ob_start();
597 $result = $this->mmb_exec($command);
598 ob_get_clean();
599
600 } else {
601 require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
602 $archive = new PclZip($backup_file);
603 $result = $archive->extract(PCLZIP_OPT_PATH, ABSPATH);
604 }
605
606 if ($unlink_file) {
607 @unlink($backup_file);
608 }
609
610 if (!$result) {
611 return array(
612 'error' => 'Error extracting backup file.'
613 );
614 }
615
616 $db_result = $this->restore_db();
617
618 if (!$db_result) {
619 return array(
620 'error' => 'Error restoring database.'
621 );
622 }
623
624
625
626 } else {
627 return array(
628 'error' => 'Error restoring. Cannot find backup file.'
629 );
630 }
631
632 //Replace options and content urls
633 if ($overwrite) {
634 //Get New Table prefix
635 $new_table_prefix = trim($this->get_table_prefix());
636
637 //Retrieve old wp_config
638 @unlink(ABSPATH . 'wp-config.php');
639
640 //Replace table prefix
641 $lines = file(ABSPATH . 'mwp-temp-wp-config.php');
642 foreach ($lines as $line) {
643 if (strstr($line, '$table_prefix')) {
644 $line = '$table_prefix = "' . $new_table_prefix . '";' . PHP_EOL;
645 }
646 file_put_contents(ABSPATH . 'wp-config.php', $line, FILE_APPEND);
647 }
648
649 @unlink(ABSPATH . 'mwp-temp-wp-config.php');
650
651 //Replace options
652 $query = "SELECT option_value FROM " . $new_table_prefix . "options WHERE option_name = 'home'";
653 $old = $wpdb->get_var($wpdb->prepare($query));
654 $old = rtrim($old,"/");
655 $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$home' WHERE option_name = 'home'";
656 $wpdb->query($wpdb->prepare($query));
657 $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$home' WHERE option_name = 'siteurl'";
658 $wpdb->query($wpdb->prepare($query));
659 //Replace content urls
660 $query = "UPDATE " . $new_table_prefix . "posts SET post_content = REPLACE (post_content, '$old','$home') WHERE post_content REGEXP 'src=\"(.*)$old(.*)\"' OR post_content REGEXP 'href=\"(.*)$old(.*)\"'";
661 $wpdb->query($wpdb->prepare($query));
662 }
663
664 return true;
665 }
666
667 function restore_db()
668 {
669 global $wpdb;
670 $mysqldump = $this->check_mysqldump();
671 $file_path = ABSPATH . 'mwp_db';
672 $file_name = glob($file_path . '/*.sql');
673 $file_name = $file_name[0];
674
675 if (is_array($mysqldump)) {
676 $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
677 $command = $brace . $mysqldump['mysql'] . $brace . ' --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" ' . DB_NAME . ' < ' . $brace . $file_name . $brace;
678
679 ob_start();
680 $result = $this->mmb_exec($command);
681 ob_get_clean();
682 if (!$result) {
683 //try php
684 $this->restore_db_php($file_name);
685 }
686
687 } else {
688 $this->restore_db_php($file_name);
689 }
690
691 @unlink($file_name);
692 return true;
693 }
694
695 function restore_db_php($file_name)
696 {
697 $current_query = '';
698 // Read in entire file
699 $lines = file($file_name);
700 // Loop through each line
701 foreach ($lines as $line) {
702 // Skip it if it's a comment
703 if (substr($line, 0, 2) == '--' || $line == '')
704 continue;
705
706 // Add this line to the current query
707 $current_query .= $line;
708 // If it has a semicolon at the end, it's the end of the query
709 if (substr(trim($line), -1, 1) == ';') {
710 // Perform the query
711 $result = $wpdb->query($current_query);
712 if ($result === false)
713 return FALSE;
714 // Reset temp variable to empty
715 $current_query = '';
716 }
717 }
718
719 @unlink($file_name);
720 return true;
721 }
722
723 function get_table_prefix()
724 {
725 $lines = file(ABSPATH . 'wp-config.php');
726 foreach ($lines as $line) {
727 if (strstr($line, '$table_prefix')) {
728 $pattern = "/(\'|\")[^(\'|\")]*/";
729 preg_match($pattern, $line, $matches);
730 $prefix = substr($matches[0], 1);
731 return $prefix;
732 break;
733 }
734 }
735 return 'wp_'; //default
736 }
737
738 function optimize_tables()
739 {
740 global $wpdb;
741 $query = 'SHOW TABLE STATUS FROM ' . DB_NAME;
742 $tables = $wpdb->get_results($wpdb->prepare($query), ARRAY_A);
743 foreach ($tables as $table) {
744 if (in_array($table['Engine'], array(
745 'MyISAM',
746 'ISAM',
747 'HEAP',
748 'MEMORY',
749 'ARCHIVE'
750 )))
751 $table_string .= $table['Name'] . ",";
752 elseif ($table['Engine'] == 'InnoDB') {
753 $optimize = $wpdb->query("ALTER TABLE {$table['Name']} ENGINE=InnoDB");
754 }
755 }
756
757 $table_string = rtrim($table_string);
758 $optimize = $wpdb->query("OPTIMIZE TABLE $table_string");
759
760 return $optimize ? true : false;
761 }
762
763 ### Function: Auto Detect MYSQL and MYSQL Dump Paths
764 function check_mysqldump()
765 {
766 global $wpdb;
767 $paths = array(
768 'mysq' => '',
769 'mysqldump' => ''
770 );
771 if (substr(PHP_OS, 0, 3) == 'WIN') {
772 $mysql_install = $wpdb->get_row("SHOW VARIABLES LIKE 'basedir'");
773 if ($mysql_install) {
774 $install_path = str_replace('\\', '/', $mysql_install->Value);
775 $paths['mysql'] = $install_path . 'bin/mysql.exe';
776 $paths['mysqldump'] = $install_path . 'bin/mysqldump.exe';
777 } else {
778 $paths['mysql'] = 'mysql.exe';
779 $paths['mysqldump'] = 'mysqldump.exe';
780 }
781 } else {
782 if ($this->check_sys()) {
783 $paths['mysql'] = $this->mmb_exec('which mysql', true);
784 $paths['mysqldump'] = $this->mmb_exec('which mysqldump', true);
785 } else {
786 $paths['mysql'] = 'mysql';
787 $paths['mysqldump'] = 'mysqldump';
788 }
789 }
790
791 if (!@file_exists(stripslashes($paths['mysqldump']))) {
792 return false;
793 }
794 if (!@file_exists(stripslashes($paths['mysql']))) {
795 return false;
796 }
797
798 return $paths;
799 }
800
801 //Check if exec, system, passthru functions exist
802 function check_sys()
803 {
804 if ($this->mmb_function_exists('exec'))
805 return 'exec';
806
807 if ($this->mmb_function_exists('system'))
808 return 'system';
809
810 if ($this->mmb_function_exists('passhtru'))
811 return 'passthru';
812
813 return false;
814
815 }
816
817 function mmb_exec($command, $string = false)
818 {
819 if ($command == '')
820 return false;
821
822 if ($this->mmb_function_exists('exec')) {
823 $log = @exec($command, $output, $return);
824
825 if ($string)
826 return $log;
827 return $return ? false : true;
828 } elseif ($this->mmb_function_exists('system')) {
829 $log = @system($command, $return);
830
831 if ($string)
832 return $log;
833 return $return ? false : true;
834 } elseif ($this->mmb_function_exists('passthru')) {
835 $log = passthru($command, $return);
836
837 return $return ? false : true;
838 } else {
839 return false;
840 }
841 }
842
843 function check_backup_compat()
844 {
845 $reqs = array();
846 if (strpos($_SERVER['DOCUMENT_ROOT'], '/') === 0) {
847 $reqs['Server OS']['status'] = 'Linux (or compatible)';
848 $reqs['Server OS']['pass'] = true;
849 } else {
850 $reqs['Server OS']['status'] = 'Windows';
851 $reqs['Server OS']['pass'] = false;
852 $pass = false;
853 }
854 $reqs['PHP Version']['status'] = phpversion();
855 if ((float) phpversion() >= 5.1) {
856 $reqs['PHP Version']['pass'] = true;
857 } else {
858 $reqs['PHP Version']['pass'] = false;
859 $pass = false;
860 }
861
862
863 if (is_writable(WP_CONTENT_DIR)) {
864 $reqs['Backup Folder']['status'] = "writable";
865 $reqs['Backup Folder']['pass'] = true;
866 } else {
867 $reqs['Backup Folder']['status'] = "not writable";
868 $reqs['Backup Folder']['pass'] = false;
869 }
870
871 $sec_string = md5('mmb-worker');
872 $file = "/$sec_string/mwp_backups";
873 $file_path = WP_CONTENT_DIR . $file;
874 $reqs['Backup Folder']['status'] .= ' (' . $file_path . ')';
875
876 if ($func = $this->check_sys()) {
877 $reqs['Execute Function']['status'] = $func;
878 $reqs['Execute Function']['pass'] = true;
879 } else {
880 $reqs['Execute Function']['status'] = "not found";
881 $reqs['Execute Function']['info'] = "(will try with PHP)";
882 $reqs['Execute Function']['pass'] = false;
883 }
884
885 if ($this->mmb_exec('which zip')) {
886 $reqs['Zip']['status'] = "enabled";
887 $reqs['Zip']['pass'] = true;
888 } else {
889 $reqs['Zip']['status'] = "not found";
890 $reqs['Zip']['info'] = "(will try with PHP pclZip class)";
891 $reqs['Zip']['pass'] = false;
892 }
893
894 if ($this->mmb_exec('which unzip')) {
895 $reqs['Unzip']['status'] = "enabled";
896 $reqs['Unzip']['pass'] = true;
897 } else {
898 $reqs['Unzip']['status'] = "not found";
899 $reqs['Unzip']['info'] = "(will try with PHP pclZip class)";
900 $reqs['Unzip']['pass'] = false;
901 }
902 if (is_array($this->check_mysqldump())) {
903 $reqs['MySQL Dump']['status'] = "enabled";
904 $reqs['MySQL Dump']['pass'] = true;
905 } else {
906 $reqs['MySQL Dump']['status'] = "not found";
907 $reqs['MySQL Dump']['info'] = "(will try PHP)";
908 $reqs['MySQL Dump']['pass'] = false;
909 }
910
911
912
913 return $reqs;
914 }
915
916 function email_backup($args)
917 {
918 $email = $args['email'];
919 $backup_file = $args['file_path'];
920 $task_name = isset($args['task_name']) ? $args['task_name'] . ' on ' : '';
921 if (file_exists($backup_file) && $email) {
922 $attachments = array(
923 $backup_file
924 );
925 $headers = 'From: ManageWP <no-reply@managewp.com>' . "\r\n";
926 $subject = "ManageWP Backup - " . $task_name . date('F jS, G:i');
927 ob_start();
928 wp_mail($email, $subject, $subject, $headers, $attachments);
929 ob_end_clean();
930
931 }
932
933 return true;
934
935 }
936
937 function ftp_backup($args)
938 {
939 extract($args);
940 //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder, $ftp_site_folder
941 if($ftp_site_folder)
942 $ftp_remote_folder .= '/'.$this->site_name;
943
944
945 if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
946 $conn_id = ftp_ssl_connect($ftp_hostname);
947 } else if (function_exists('ftp_connect')) {
948 $conn_id = ftp_connect($ftp_hostname);
949 if ($conn_id === false) {
950 return array(
951 'error' => 'Failed to connect to ' . $ftp_hostname,
952 'partial' => 1
953 );
954 }
955 } else {
956 return array(
957 'error' => 'Your server doesn\'t support FTP',
958 'partial' => 1
959 );
960 }
961
962 $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
963 if ($login === false) {
964 return array(
965 'error' => 'FTP login failed for ' . $ftp_username . ', ' . $ftp_password,
966 'partial' => 1
967 );
968 }
969
970 @ftp_mkdir($conn_id, $ftp_remote_folder);
971
972
973 $upload = @ftp_put($conn_id, $ftp_remote_folder . '/' . basename($backup_file), $backup_file, FTP_BINARY);
974 if ($upload === false) {
975 return array(
976 'error' => 'Failed to upload file to FTP. Please check your specified path.',
977 'partial' => 1
978 );
979 }
980
981 ftp_close($conn_id);
982
983 return true;
984 }
985
986 function remove_ftp_backup($args)
987 {
988 extract($args);
989 //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
990 if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
991 $conn_id = ftp_ssl_connect($ftp_hostname);
992
993 } else if (function_exists('ftp_connect')) {
994 $conn_id = ftp_connect($ftp_hostname);
995 if ($conn_id === false) {
996 }
997 } else {
998 }
999 $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1000 if ($login === false) {
1001 } else {
1002 }
1003
1004 if($ftp_site_folder)
1005 $ftp_remote_folder .= '/'.$this->site_name;
1006
1007 $delete = ftp_delete($conn_id, $ftp_remote_folder . '/' . $backup_file);
1008 if ($delete === false) {
1009 } else {
1010 }
1011 ftp_close($conn_id);
1012
1013 }
1014
1015 function get_ftp_backup($args)
1016 {
1017 extract($args);
1018 //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
1019 if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
1020 $conn_id = ftp_ssl_connect($ftp_hostname);
1021
1022 } else if (function_exists('ftp_connect')) {
1023 $conn_id = ftp_connect($ftp_hostname);
1024 if ($conn_id === false) {
1025 return false;
1026 }
1027 } else {
1028 }
1029 $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1030 if ($login === false) {
1031 return false;
1032 } else {
1033 }
1034
1035 if($ftp_site_folder)
1036 $ftp_remote_folder .= '/'.$this->site_name;
1037
1038 $temp = ABSPATH . 'mwp_temp_backup.zip';
1039 $get = ftp_get($conn_id, $temp, $ftp_remote_folder . '/' . $backup_file, FTP_BINARY);
1040 if ($get === false) {
1041 return false;
1042 } else {
1043 }
1044 ftp_close($conn_id);
1045
1046 return $temp;
1047 }
1048
1049 function dropbox_backup($args)
1050 {
1051 require_once('lib/dropbox.php');
1052 extract($args);
1053
1054 //$email, $password, $backup_file, $destination, $dropbox_site_folder
1055 if($dropbox_site_folder == true)
1056 $dropbox_destination .= '/'.$this->site_name;
1057
1058 try {
1059 $uploader = new DropboxUploader($dropbox_username, $dropbox_password);
1060 $uploader->upload($backup_file, $dropbox_destination);
1061 }
1062 catch (Exception $e) {
1063 return array(
1064 'error' => $e->getMessage(),
1065 'partial' => 1
1066 );
1067 }
1068
1069 return true;
1070
1071 }
1072
1073 function amazons3_backup($args)
1074 {
1075 require_once('lib/s3.php');
1076 extract($args);
1077
1078 if($as3_site_folder == true)
1079 $as3_directory .= '/'.$this->site_name;
1080
1081
1082 $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key));
1083
1084 $s3->putBucket($as3_bucket, S3::ACL_PUBLIC_READ);
1085
1086 if ($s3->putObjectFile($backup_file, $as3_bucket, $as3_directory . '/' . basename($backup_file), S3::ACL_PRIVATE)) {
1087 return true;
1088 } else {
1089 return array(
1090 'error' => 'Failed to upload to Amazon S3. Please check your details and set upload/delete permissions on your bucket.',
1091 'partial' => 1
1092 );
1093 }
1094
1095 }
1096
1097 function remove_amazons3_backup($args)
1098 {
1099 require_once('lib/s3.php');
1100 extract($args);
1101 if($as3_site_folder == true)
1102 $as3_directory .= '/'.$this->site_name;
1103
1104 $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key));
1105 $s3->deleteObject($as3_bucket, $as3_directory . '/' . $backup_file);
1106 }
1107
1108 function get_amazons3_backup($args)
1109 {
1110 require_once('lib/s3.php');
1111 extract($args);
1112 $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key));
1113 if($as3_site_folder == true)
1114 $as3_directory .= '/'.$this->site_name;
1115
1116 $s3->getObject($as3_bucket, $as3_directory . '/' . $backup_file, $temp);
1117 $temp = ABSPATH . 'mwp_temp_backup.zip';
1118 return $temp;
1119 }
1120
1121 function schedule_next($type, $schedule)
1122 {
1123 $schedule = explode("|", $schedule);
1124 if (empty($schedule))
1125 return false;
1126 switch ($type) {
1127
1128 case 'daily':
1129
1130 if ($schedule[1]) {
1131 $delay_time = $schedule[1] * 60;
1132 }
1133
1134 $current_hour = date("H");
1135 $schedule_hour = $schedule[0];
1136 if ($current_hour >= $schedule_hour)
1137 $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + 1, date("Y"));
1138 else
1139 $time = mktime($schedule_hour, 0, 0, date("m"), date("d"), date("Y"));
1140 break;
1141
1142
1143 case 'weekly':
1144 if ($schedule[2]) {
1145 $delay_time = $schedule[2] * 60;
1146 }
1147 $current_weekday = date('w');
1148 $schedule_weekday = $schedule[1];
1149 $current_hour = date("H");
1150 $schedule_hour = $schedule[0];
1151
1152 if ($current_weekday > $schedule_weekday)
1153 $weekday_offset = 7 - ($week_day - $task_schedule[1]);
1154 else
1155 $weekday_offset = $schedule_weekday - $current_weekday;
1156
1157
1158 if (!$weekday_offset) { //today is scheduled weekday
1159 if ($current_hour >= $schedule_hour)
1160 $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + 7, date("Y"));
1161 else
1162 $time = mktime($schedule_hour, 0, 0, date("m"), date("d"), date("Y"));
1163 } else {
1164 $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + $weekday_offset, date("Y"));
1165 }
1166
1167 break;
1168
1169 case 'monthly':
1170 if ($schedule[2]) {
1171 $delay_time = $schedule[2] * 60;
1172 }
1173 $current_monthday = date('j');
1174 $schedule_monthday = $schedule[1];
1175 $current_hour = date("H");
1176 $schedule_hour = $schedule[0];
1177
1178 if ($current_monthday > $schedule_monthday) {
1179 $time = mktime($schedule_hour, 0, 0, date("m") + 1, $schedule_monthday, date("Y"));
1180 } else if ($current_monthday < $schedule_monthday) {
1181 $time = mktime($schedule_hour, 0, 0, date("m"), $schedule_monthday, date("Y"));
1182 } else if ($current_monthday == $schedule_monthday) {
1183 if ($current_hour >= $schedule_hour)
1184 $time = mktime($schedule_hour, 0, 0, date("m") + 1, $schedule_monthday, date("Y"));
1185 else
1186 $time = mktime($schedule_hour, 0, 0, date("m"), $schedule_monthday, date("Y"));
1187 break;
1188 }
1189
1190 break;
1191 default:
1192 break;
1193 }
1194
1195 if ($delay_time) {
1196 $time += $delay_time;
1197 }
1198
1199
1200 return $time;
1201
1202 }
1203
1204 //Parse task arguments for info on master
1205 function get_backup_stats()
1206 {
1207 $stats = array();
1208 $tasks = get_option('mwp_backup_tasks');
1209 if (is_array($tasks) && !empty($tasks)) {
1210 foreach ($tasks as $task_name => $info) {
1211
1212 if(is_array($info['task_results']) && !empty($info['task_results']))
1213 {
1214 foreach($info['task_results'] as $key => $result){
1215 if(isset($result['server'])){
1216 if(!file_exists($result['server']['file_path'])){
1217 unset($info['task_results'][$key]);
1218 }
1219 }
1220 }
1221 }
1222
1223 $stats[$task_name] = $info['task_results'];
1224
1225 }
1226 }
1227 return $stats;
1228 }
1229
1230 function get_next_schedules(){
1231 $stats = array();
1232 $tasks = get_option('mwp_backup_tasks');
1233 if (is_array($tasks) && !empty($tasks)) {
1234 foreach ($tasks as $task_name => $info) {
1235 $stats[$task_name] = $info['task_args']['next'];
1236 }
1237 }
1238 return $stats;
1239 }
1240
1241 function remove_old_backups($task_name)
1242 {
1243 $backups = $this->get_backup_settings();
1244 if (count($backups[$task_name]['task_results']) >= $backups[$task_name]['task_args']['limit']) {
1245 // ? how many to remove
1246 $remove_num = (count($backups[$task_name]['task_results']) - $backups[$task_name]['task_args']['limit']) + 1;
1247
1248 for ($i = 0; $i < $remove_num; $i++) {
1249 if (!isset($backups[$task_name]['task_results'][$i]['error'])) {
1250 //Remove from the server
1251 if (isset($backups[$task_name]['task_results'][$i]['server'])) {
1252 @unlink($backups[$task_name]['task_results'][$i]['server']['file_path']);
1253 }
1254
1255 //Remove from ftp
1256 if (isset($backups[$task_name]['task_results'][$i]['ftp'])) {
1257 $ftp_file = $backups[$task_name]['task_results'][$i]['ftp'];
1258 $args = $backups[$task_name]['task_args']['account_info']['mwp_ftp'];
1259 $args['backup_file'] = $ftp_file;
1260 $this->remove_ftp_backup($args);
1261 }
1262
1263 if (isset($backups[$task_name]['task_results'][$i]['amazons3'])) {
1264 $amazons3_file = $backups[$task_name]['task_results'][$i]['amazons3'];
1265 $args = $backups[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
1266 $args['backup_file'] = $amazons3_file;
1267 $this->remove_amazons3_backup($args);
1268 }
1269
1270 if (isset($backups[$task_name]['task_results'][$i]['dropbox'])) {
1271 }
1272
1273 }
1274 //Remove database backup info
1275 unset($backups[$task_name]['task_results'][$i]);
1276 update_option('mwp_backup_tasks', $backups);
1277
1278 } //end foreach
1279 }
1280 }
1281
1282 /**
1283 * Delete specified backup
1284 * Args: $task_name, $result_id
1285 */
1286
1287 function delete_backup($args)
1288 {
1289 if (empty($args))
1290 return false;
1291 extract($args);
1292
1293 $tasks = $this->get_backup_settings();
1294 $task = $tasks[$task_name];
1295 $backups = $task['task_results'];
1296 $backup = $backups[$result_id];
1297
1298 if (isset($backup['server'])) {
1299 @unlink($backup['server']['file_path']);
1300 }
1301
1302 //Remove from ftp
1303 if (isset($backup['ftp'])) {
1304 $ftp_file = $backup['ftp'];
1305 $args = $tasks[$task_name]['task_args']['account_info']['mwp_ftp'];
1306 $args['backup_file'] = $ftp_file;
1307 $this->remove_ftp_backup($args);
1308 }
1309
1310 if (isset($backup['amazons3'])) {
1311 $amazons3_file = $backup['amazons3'];
1312 $args = $tasks[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
1313 $args['backup_file'] = $amazons3_file;
1314 $this->remove_amazons3_backup($args);
1315 }
1316
1317 if (isset($backup['dropbox'])) {
1318 }
1319
1320 unset($backups[$result_id]);
1321
1322 if (count($backups)) {
1323 $tasks[$task_name]['task_results'] = $backups;
1324 } else {
1325 unset($tasks[$task_name]['task_results']);
1326 }
1327
1328 update_option('mwp_backup_tasks', $tasks);
1329 return true;
1330
1331 }
1332
1333 function cleanup()
1334 {
1335 $tasks = $this->get_backup_settings();
1336 $backup_folder = WP_CONTENT_DIR . '/' . md5('mmb-worker') . '/mwp_backups/';
1337 $files = glob($backup_folder . "*.*");
1338 $deleted = array();
1339 $clone_backup = get_option('mwp_manual_backup');
1340 if(isset($clone_backup['file_path'])){
1341 $clone_backup = $clone_backup['file_path'];
1342 }
1343
1344 if (is_array($files) && count($files)) {
1345 $results = array();
1346 if (count($tasks)) {
1347 foreach ($tasks as $task) {
1348 if (isset($task['task_results']) && count($task['task_results'])) {
1349 foreach ($task['task_results'] as $backup) {
1350 if (isset($backup['server'])) {
1351 $results[] = $backup['server']['file_path'];
1352 }
1353 }
1354 }
1355 }
1356 }
1357
1358 $num_deleted = 0;
1359 foreach ($files as $file) {
1360 if (!in_array($file, $results) && basename($file) != 'index.php' && basename($file) != basename($clone_backup)) {
1361 @unlink($file);
1362 $deleted[] = basename($file);
1363 $num_deleted++;
1364 }
1365 }
1366 }
1367
1368 //Failed db files?
1369 $db_folder = WP_CONTENT_DIR . '/mwp_db/';
1370 $files = glob($db_folder . "*.*");
1371 if (is_array($files) && count($files)) {
1372 foreach ($files as $file) {
1373 @unlink($file);
1374 }
1375 }
1376
1377 return $deleted;
1378 }
1379
1380
1381 function remote_backup_now($args)
1382 {
1383
1384 if (!empty($args))
1385 extract($args);
1386 $tasks = $this->get_backup_settings();
1387 $task = $tasks['Backup Now'];
1388
1389 if (!empty($task)) {
1390 extract($task['task_args']);
1391 }
1392
1393 $results = $task['task_results'];
1394
1395 if (is_array($results) && count($results)) {
1396 $backup_file = $results[count($results) - 1]['server']['file_path'];
1397 }
1398
1399 if ($backup_file && file_exists($backup_file)) {
1400 if ($email) {
1401 $mail_args = array(
1402 'email' => $email_backup,
1403 'task_name' => 'Backup Now',
1404 'file_path' => $backup_file
1405 );
1406
1407
1408
1409 $return = $this->email_backup($mail_args);
1410
1411 //delete from server?
1412 if ($return == true && $del_host_file) {
1413 @unlink($backup_file);
1414
1415 unset($tasks['Backup Now']['task_results'][count($results) - 1]['server']);
1416 update_option('mwp_backup_tasks', $tasks);
1417
1418 }
1419 } else {
1420 //FTP, Amazon S3 or Dropbox
1421 if (isset($account_info['mwp_ftp']) && !empty($account_info['mwp_ftp'])) {
1422 $account_info['mwp_ftp']['backup_file'] = $backup_file;
1423 $return = $this->ftp_backup($account_info['mwp_ftp']);
1424 }
1425
1426 if (isset($account_info['mwp_amazon_s3']) && !empty($account_info['mwp_amazon_s3'])) {
1427 $account_info['mwp_amazon_s3']['backup_file'] = $backup_file;
1428 $return = $this->amazons3_backup($account_info['mwp_amazon_s3']);
1429 }
1430
1431 if (isset($account_info['mwp_dropbox']) && !empty($account_info['mwp_dropbox'])) {
1432 $account_info['mwp_dropbox']['backup_file'] = $backup_file;
1433 $return = $this->dropbox_backup($account_info['mwp_dropbox']);
1434 }
1435
1436 if ($return == true && $del_host_file && !$email_backup) {
1437 @unlink($backup_file);
1438 unset($tasks['Backup Now']['task_results'][count($results) - 1]['server']);
1439
1440 update_option('mwp_backup_tasks', $tasks);
1441 }
1442
1443 }
1444
1445 } else {
1446 $return = array(
1447 'error' => 'Backup file not found on your server. Please try again.'
1448 );
1449 }
1450
1451 return $return;
1452
1453 }
1454
1455 }
1456
1457 ?>