Backup and Restore WordPress – WPBackItUp Backup Plugin - Version 1.10.7

Version Description

  • UPDATE: Add multi-site support for database backup
  • UPDATE: Add WordPress 4.2 support
  • UPDATE: Enhance backup file validation
  • UPDATE: Add job table to better handle large backup jobs
  • UPDATE: Add logging additional logging to database export.
  • UPDATE: Add logging for is_file to make sure filtering properly.
  • UPDATE: Add logging to backup view to list all files contained in root backup folder.
  • UPDATE: Add logging to plugin meta update
  • FIX: Modify manual db export to write flush file buffer more frequently.
  • FIX: Change backup to use default batch size.
  • FIX: Correct job check error when no jobs available to purge.
Download this release

Release Info

Developer cssimmon
Plugin Icon 128x128 Backup and Restore WordPress – WPBackItUp Backup Plugin
Version 1.10.7
Comparing to
See all releases

Code changes from version 1.10.6 to 1.10.7

lib/includes/class-backup.php CHANGED
@@ -347,14 +347,6 @@ class WPBackItUp_Backup {
347
  }
348
  }
349
  $this->logger->log_info(__METHOD__,'Database Exported successfully');
350
-
351
- // Uncomment when encryption is added
352
- // backup wp.config
353
- // $from_path = get_home_path() .'/wp-config.php';
354
- // $to_path = $this->backup_project_path .'/wp-config.bak';
355
- // $file_system = new WPBackItUp_FileSystem($this->logger);
356
- // $file_system->copy_file($from_path,$to_path);
357
-
358
  return true;
359
  }
360
 
@@ -417,6 +409,261 @@ class WPBackItUp_Backup {
417
  return $plugins_file_list;
418
  }
419
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
  public function get_themes_file_list() {
421
  $this->logger->log_info( __METHOD__, 'Begin' );
422
 
@@ -475,7 +722,7 @@ class WPBackItUp_Backup {
475
  $plugins_folder = basename (WPBACKITUP__PLUGINS_ROOT_PATH);
476
 
477
  //ignore these folders
478
- $wpback_ignore = explode(',',WPBACKITUP__BACKUP_IGNORE_LIST);
479
  $wpcontent_ignore=array($uploads_folder, $themes_folder, $plugins_folder);
480
  $ignore = array_merge($wpback_ignore,$wpcontent_ignore);
481
 
@@ -515,85 +762,281 @@ class WPBackItUp_Backup {
515
  }
516
 
517
 
518
- //BackUp
519
- public function backup_file_list($source_root,$target_root,$suffix,$file_list,$batch_size,$ignore=''){
520
- $this->logger->log_info(__METHOD__,'Begin - Item Count: '. count($file_list));
521
- $this->logger->log_info(__METHOD__,'Items in Backup List: ');
522
- $this->logger->log($file_list);
523
 
524
- if (! is_array($file_list)) {
525
- $this->logger->log_error(__METHOD__,'Array expected in file list:');
526
- $this->logger->log($file_list);
527
- return 'error';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
528
  }
529
 
530
- $zip_file_path = $this->backup_project_path . $this->backup_name .'-'.$suffix .'.tmp';
531
- $zip = new WPBackItUp_Zip($this->logger,$zip_file_path);
532
 
533
- foreach($file_list as $item) {
534
- $this->logger->log_info( __METHOD__, 'File:' . $item );
535
 
536
- //skip it if in ignore
537
- if ( !empty($ignore) && false!== strpos($item,$ignore)) {
538
- $this->logger->log_info( __METHOD__, 'Skip File:' . $item );
539
- array_shift($file_list); //remove from list
540
- continue;
541
- }
542
 
543
- //skip it if folder
544
- if ( is_dir( $item ) ) {
545
- $this->logger->log_info( __METHOD__, 'Skip folder:' . $item );
546
- array_shift( $file_list ); //remove from list
547
- continue;
548
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
549
 
 
550
 
551
- //replace the source path with the target
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552
  $target_item_path = str_replace(rtrim($source_root, '/'),rtrim($target_root,'/'),$item);
 
 
 
 
 
 
 
 
 
 
 
553
 
554
- $this->logger->log_info( __METHOD__, 'Add File:' .$target_item_path );
555
- if ( $zip->add_file($item,$target_item_path)) {
556
- array_shift($file_list);
557
- $this->logger->log_info( __METHOD__, 'File Added:' . $target_item_path );
558
- $this->logger->log_info( __METHOD__, 'Zip file count:' . $zip->get_zip_file_count() . '>=' . $batch_size);
559
 
560
- //If we have added X# of files or hit the size limit then lets close the zip and finish on the next pass
561
- if( $zip->get_zip_file_count()>=$batch_size){
562
 
563
- $zip->close();//close the zip
 
 
 
 
 
 
 
 
 
 
 
 
 
564
 
565
- //check the compressed file size
566
- $compressed_zip_file_size = $zip->get_zip_actual_size();
567
- $this->logger->log_info( __METHOD__, 'Zip Actual Size after close:' . $zip->get_zip_actual_size());
 
 
568
 
569
- //if the zip is too big we need to rename it
570
- $threshold = $zip->get_max_zip_size(.8);
571
- if ($compressed_zip_file_size >= $threshold) {
572
- $this->logger->log_info(__METHOD__,'Zip hit max size threshold:'.$compressed_zip_file_size .'>' .$threshold );
573
- if (! $this->add_zip_suffix($zip_file_path)){
574
- return 'error';
575
- }
576
- }
577
 
578
- $this->logger->log_info(__METHOD__,'End - Item Count:' . count($file_list));
579
- return $file_list;
580
- }
581
- } else {
582
- $this->logger->log_error( __METHOD__, 'File NOT added:' . $target_item_path );
583
- return 'error';
584
- }
585
- }
 
 
 
 
586
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
587
 
588
- //if we get here then close the zip
589
- $zip->close();//close the zip
590
 
591
  //if there are no more files to add then rename the zip
592
- //Check to see if the file exists, it is possible that it does not if only empty folders were contained
593
- if(count($file_list)==0 && file_exists($zip_file_path) ){
594
- $this->logger->log_info( __METHOD__, 'Zip Actual Size after close:' . $zip->get_zip_actual_size());
595
- if (! $this->add_zip_suffix($zip_file_path)){
596
- return 'error';
597
  }
598
  }
599
 
@@ -601,7 +1044,6 @@ class WPBackItUp_Backup {
601
  return $file_list;
602
  }
603
 
604
-
605
  private function strposa($haystack, $needle) {
606
  if(!is_array($needle)) $needle = array($needle);
607
 
@@ -618,14 +1060,14 @@ class WPBackItUp_Backup {
618
  return false;
619
  }
620
 
621
- private function add_zip_suffix($zip_file_path){
622
  $this->logger->log_info(__METHOD__,'Begin');
623
 
624
  $file_extension = pathinfo($zip_file_path, PATHINFO_EXTENSION);
625
  $this->logger->log_info(__METHOD__,'File Extension:'.$file_extension);
626
  if ($file_extension!='zip'){
627
  $file_system = new WPBackItUp_FileSystem($this->logger);
628
- $new_zip_name = str_replace('.' . $file_extension,'-'.time() .'.zip',$zip_file_path);
629
  if ( !$file_system->rename_file($zip_file_path,$new_zip_name)){
630
  $this->logger->log_error(__METHOD__,'Zip could not be renamed.');
631
  return false;
@@ -672,7 +1114,7 @@ class WPBackItUp_Backup {
672
 
673
  //get a list of all the zips
674
  $backup_files_path = array_filter(glob($this->backup_project_path. '*.zip'), 'is_file');
675
- $this->logger->log_error(__METHOD__,'Zip files found:'. var_export($backup_files_path,true));
676
  if (is_array($backup_files_path) && count($backup_files_path)>0){
677
  //get rid of the path.
678
  $backup_files = str_replace($this->backup_project_path,'',$backup_files_path);
347
  }
348
  }
349
  $this->logger->log_info(__METHOD__,'Database Exported successfully');
 
 
 
 
 
 
 
 
350
  return true;
351
  }
352
 
409
  return $plugins_file_list;
410
  }
411
 
412
+ //Search array(needle) for value(haystack) starting in position 1
413
+ function strposa0($haystack, $needle, $offset=0) {
414
+ if(!is_array($needle)) $needle = array($needle);
415
+ foreach($needle as $query) {
416
+ $pos = strpos($haystack, $query, $offset);
417
+ //looking for position 0 - string must start at the beginning
418
+ if($pos === 0) return true; // stop on first true result
419
+ }
420
+ return false;
421
+ }
422
+
423
+
424
+ public function save_inventory_files($batch_insert_size,$job_id,$group_id,$root_path,$exclude=null) {
425
+ $this->logger->log_info( __METHOD__, 'Begin:' .$group_id);
426
+
427
+ //create a separate log file for inventory
428
+ $logger_inventory = new WPBackItUp_Logger(true,null,'debug_inventory_'.$group_id);
429
+ $logger_inventory->log_info( __METHOD__, 'Root Path: ' .$root_path);
430
+ $logger_inventory->log_info( __METHOD__, 'Exclude: ' .var_export($exclude,true));
431
+ $logger_inventory->log_info( __METHOD__, '***');
432
+ try {
433
+ $batch_counter = 0;
434
+ $total_counter=0;
435
+ $directory_iterator=new RecursiveDirectoryIterator($root_path,FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS | RecursiveIteratorIterator::CATCH_GET_CHILD);
436
+ $item_iterator = new RecursiveIteratorIterator($directory_iterator,RecursiveIteratorIterator::SELF_FIRST);
437
+
438
+ $datetime1 = new DateTime('now');
439
+ $sql="";
440
+ while ($item_iterator->valid()) {
441
+ //Skip the item if its in the exclude array
442
+ //This is a string compare starting in position 1
443
+ $file_path = $item_iterator->getSubPathname();
444
+ if ($this->strposa0($file_path, $exclude)===true) {
445
+ $logger_inventory->log_info( __METHOD__, 'Skip: ' .$file_path);
446
+ } else {
447
+ if ( $item_iterator->isFile()) {
448
+ if ($batch_counter>=$batch_insert_size){
449
+ if (! $this->save_inventory_db($sql,$logger_inventory)) {
450
+ return false;
451
+ }
452
+ $sql="";
453
+ $batch_counter=0;
454
+ }
455
+ $total_counter++;
456
+ $batch_counter++;
457
+ $file_size=ceil($item_iterator->getSize()/1024);//round up
458
+ $logger_inventory->log_info( __METHOD__, 'Add File: ' .$batch_counter . ' ' .$file_path);
459
+ $sql.= "(".$job_id .", '" .$group_id."', '" .$file_path ."', ".$file_size ."),";
460
+ }
461
+ }
462
+ $item_iterator->next();
463
+ }
464
+
465
+ if ($batch_counter>0) {
466
+ if (! $this->save_inventory_db($sql,$logger_inventory)) {
467
+ return false;
468
+ }
469
+ }
470
+
471
+ $datetime2 = new DateTime('now');
472
+ $interval = $datetime1->diff($datetime2);
473
+ $this->logger->log_info( __METHOD__, 'File Count/Time: ' .$total_counter . '-' . $interval->format('%s seconds'));
474
+ return true;
475
+
476
+ } catch(Exception $e) {
477
+ $this->logger->log_error( __METHOD__, 'Exception: ' .$e);
478
+ return false;
479
+ }
480
+ }
481
+
482
+
483
+ public function create_job_control($job_id) {
484
+ $this->logger->log_info( __METHOD__, 'Begin' );
485
+
486
+ //create a separate log file for inventory
487
+ $logger_inventory = new WPBackItUp_Logger( true, null, 'debug_inventory_' . $job_id );
488
+ $logger_inventory->log_info( __METHOD__, '***' );
489
+ try {
490
+
491
+ $db = new WPBackItUp_DataAccess();
492
+ return $db->create_job_control($job_id);
493
+
494
+ } catch ( Exception $e ) {
495
+ $this->logger->log_error( __METHOD__, 'Exception: ' . $e );
496
+
497
+ return false;
498
+
499
+ }
500
+ }
501
+
502
+ public function update_job_control_complete($job_id) {
503
+ $this->logger->log_info( __METHOD__, 'Begin' );
504
+
505
+ //create a separate log file for inventory
506
+ $logger_inventory = new WPBackItUp_Logger( true, null, 'debug_inventory_' . $job_id );
507
+ $logger_inventory->log_info( __METHOD__, '***' );
508
+ try {
509
+
510
+ $db = new WPBackItUp_DataAccess();
511
+ return $db->update_job_control_complete($job_id);
512
+
513
+ } catch ( Exception $e ) {
514
+ $this->logger->log_error( __METHOD__, 'Exception: ' . $e );
515
+
516
+ return false;
517
+
518
+ }
519
+ }
520
+
521
+
522
+ /**
523
+ * Save inventory of folder to database
524
+ *
525
+ * @param $batch_insert_size
526
+ * @param $job_id
527
+ * @param $group_id
528
+ * @param $root_path
529
+ * @param null $exclude
530
+ *
531
+ * @return bool
532
+ */
533
+ public function save_folder_inventory($batch_insert_size,$job_id,$group_id,$root_path,$exclude=null) {
534
+ $this->logger->log_info( __METHOD__, 'Begin:' .$group_id);
535
+
536
+ //create a separate log file for inventory
537
+ $logger_inventory = new WPBackItUp_Logger(true,null,'debug_inventory_'.$group_id);
538
+ $logger_inventory->log_info( __METHOD__, 'Root Path: ' .$root_path);
539
+ $logger_inventory->log_info( __METHOD__, 'Exclude: ' .var_export($exclude,true));
540
+ $logger_inventory->log_info( __METHOD__, '***');
541
+ try {
542
+ $batch_counter = 0;
543
+ $total_counter=0;
544
+ $directory_iterator=new RecursiveDirectoryIterator($root_path,FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS | RecursiveIteratorIterator::CATCH_GET_CHILD);
545
+ $item_iterator = new RecursiveIteratorIterator($directory_iterator,RecursiveIteratorIterator::SELF_FIRST);
546
+
547
+ $datetime1 = new DateTime('now');
548
+ $sql="";
549
+ $db = new WPBackItUp_DataAccess();
550
+
551
+ while ($item_iterator->valid()) {
552
+ //Skip the item if its in the exclude array
553
+ //This is a string compare starting in position 1
554
+ $file_path = $item_iterator->getSubPathname();
555
+ if ($this->strposa0($file_path, $exclude)===true) {
556
+ $logger_inventory->log_info( __METHOD__, 'Skip: ' .$file_path);
557
+ } else {
558
+ if ( $item_iterator->isFile()) {
559
+ if ($batch_counter>=$batch_insert_size){
560
+ if (! $db->insert_job_items($sql,$logger_inventory)) {
561
+ return false;
562
+ }
563
+ $sql="";
564
+ $batch_counter=0;
565
+ }
566
+ $total_counter++;
567
+ $batch_counter++;
568
+ $file_size=ceil($item_iterator->getSize()/1024);//round up
569
+ $logger_inventory->log_info( __METHOD__, 'Add File: ' .$batch_counter . ' ' .$file_path);
570
+ $sql.= "(".$job_id .", '" .$group_id."', '" .utf8_encode($file_path) ."', ".$file_size .",now() ),";
571
+ }
572
+ }
573
+ $item_iterator->next();
574
+ }
575
+
576
+ if ($batch_counter>0) {
577
+ if (! $db->insert_job_items($sql,$logger_inventory)) {
578
+ return false;
579
+ }
580
+ }
581
+
582
+ $datetime2 = new DateTime('now');
583
+ $interval = $datetime1->diff($datetime2);
584
+ $this->logger->log_info( __METHOD__, 'File Count/Time: ' .$total_counter . '-' . $interval->format('%s seconds'));
585
+ return true;
586
+
587
+ } catch(Exception $e) {
588
+ $this->logger->log_error( __METHOD__, 'Exception: ' .$e);
589
+ return false;
590
+ }
591
+ }
592
+
593
+ /**
594
+ * Save inventory of array list to database
595
+ *
596
+ * @param $batch_insert_size
597
+ * @param $job_id
598
+ * @param $group_id
599
+ * @param $file_list
600
+ *
601
+ * @return bool
602
+ * @internal param $root_path
603
+ */
604
+ public function save_file_list_inventory($batch_insert_size,$job_id,$group_id,$root_path,$file_list) {
605
+ $this->logger->log_info( __METHOD__, 'Begin:' .var_export($file_list,true));
606
+
607
+ //check is array list
608
+ if (! is_array($file_list)) {
609
+ $this->logger->log_error(__METHOD__,'Array expected in file list:');
610
+ return false;
611
+ }
612
+
613
+ //create a separate log file for inventory
614
+ $logger_inventory = new WPBackItUp_Logger(true,null,'debug_inventory_'.$group_id);
615
+ $logger_inventory->log_info( __METHOD__, '***');
616
+ try {
617
+ $batch_counter = 0;
618
+ $total_counter=0;
619
+
620
+ $datetime1 = new DateTime('now');
621
+ $sql="";
622
+ $db = new WPBackItUp_DataAccess();
623
+ foreach($file_list as $file_path) {
624
+
625
+ //skip if folder
626
+ if ( is_dir( $file_path ) ) {
627
+ $this->logger->log_info( __METHOD__, 'Skip folder:' . $file_path );
628
+ continue;
629
+ }
630
+
631
+
632
+ if ($batch_counter>=$batch_insert_size){
633
+ if (! $db->insert_job_items($sql,$logger_inventory)) {
634
+ return false;
635
+ }
636
+ $sql="";
637
+ $batch_counter=0;
638
+ }
639
+ $total_counter++;
640
+ $batch_counter++;
641
+ $file_size=ceil(filesize($file_path) /1024);//round up
642
+
643
+ //get rid of root path and utf8 encode
644
+ $file_path = utf8_encode(str_replace($root_path,'',$file_path));
645
+
646
+ $logger_inventory->log_info( __METHOD__, 'Add File: ' .$batch_counter . ' ' .$file_path);
647
+ $sql.= "(".$job_id .", '" .$group_id."', '" .$file_path ."', ".$file_size .",now() ),";
648
+ }
649
+
650
+ if ($batch_counter>0) {
651
+ if (! $db->insert_job_items($sql,$logger_inventory)) {
652
+ return false;
653
+ }
654
+ }
655
+
656
+ $datetime2 = new DateTime('now');
657
+ $interval = $datetime1->diff($datetime2);
658
+ $this->logger->log_info( __METHOD__, 'File Count/Time: ' .$total_counter . '-' . $interval->format('%s seconds'));
659
+ return true;
660
+
661
+ } catch(Exception $e) {
662
+ $this->logger->log_error( __METHOD__, 'Exception: ' .$e);
663
+ return false;
664
+ }
665
+ }
666
+
667
  public function get_themes_file_list() {
668
  $this->logger->log_info( __METHOD__, 'Begin' );
669
 
722
  $plugins_folder = basename (WPBACKITUP__PLUGINS_ROOT_PATH);
723
 
724
  //ignore these folders
725
+ $wpback_ignore = explode(',',WPBACKITUP__BACKUP_OTHER_IGNORE_LIST);
726
  $wpcontent_ignore=array($uploads_folder, $themes_folder, $plugins_folder);
727
  $ignore = array_merge($wpback_ignore,$wpcontent_ignore);
728
 
762
  }
763
 
764
 
 
 
 
 
 
765
 
766
+ /**
767
+ *
768
+ * Fetch batch of files from DB and add to zip
769
+ *
770
+ * @param $job_id
771
+ * @param $source_root
772
+ * @param $content_type
773
+ *
774
+ * @return bool|mixed
775
+ */
776
+ public function backup_files($job_id,$source_root,$content_type){
777
+ $this->logger->log_info(__METHOD__,'Begin ');
778
+
779
+ //get files to backup
780
+ $db = new WPBackItUp_DataAccess();
781
+
782
+ switch($content_type)
783
+ {
784
+ case 'themes';
785
+ $target_root='wp-content-themes';
786
+ $batch_size=WPBACKITUP__THEMES_BATCH_SIZE;
787
+ break;
788
+ case 'plugins';
789
+ $target_root='wp-content-plugins';
790
+ $batch_size=WPBACKITUP__PLUGINS_BATCH_SIZE;
791
+ break;
792
+ case 'uploads';
793
+ $target_root='wp-content-uploads';
794
+ $batch_size=WPBACKITUP__UPLOADS_BATCH_SIZE;
795
+ break;
796
+ case 'others';
797
+ $target_root='wp-content-other';
798
+ $batch_size=WPBACKITUP__OTHERS_BATCH_SIZE;
799
+ break;
800
+ // case 'combined';
801
+ // $batch_size=4;
802
+ // break;
803
+ default:
804
+ $this->logger->log_error(__METHOD__,'Content type not recognized:'.$content_type);
805
+ return false;
806
+
807
+ }
808
+
809
+ //If default batch size is not 500 then override defaults
810
+ // $default_batch_size = get_option('wp-backitup_backup_batch_size');
811
+ // if ($default_batch_size!=500){
812
+ // $this->logger->log_info(__METHOD__,'Default batch size overridden:'.$default_batch_size);
813
+ // $batch_size=$default_batch_size;
814
+ // }
815
+
816
+ //get a timestamp for the batch id
817
+ $batch_id=current_time( 'timestamp' );
818
+ $file_list = $db->get_batch_open_tasks($batch_id,$batch_size,$job_id,$content_type);
819
+
820
+ //It is possible that there are no file to backup so return count or false
821
+ if($file_list == false || $file_list==0) return $file_list;
822
+
823
+ $zip_file_path = $this->backup_project_path . $this->backup_name .'-'.$content_type .'.tmp';
824
+ if (! $this->backup_files_to_zip($source_root,$target_root,$file_list,$zip_file_path)){
825
+ return false;
826
+ }
827
+
828
+ //if there are no more files to add then rename the zip
829
+ //Check to see if the file exists, it is possible that it does not if only empty folders were contained
830
+ if(file_exists($zip_file_path) ) {
831
+ if ( ! $this->add_zip_suffix( $batch_id,$zip_file_path ) ) {
832
+ return false;
833
+ }
834
  }
835
 
836
+ //update the batch as done.
837
+ $db->update_batch_complete($job_id,$batch_id);
838
 
839
+ //get count of remaining
840
+ $remaining_count = $db->get_open_task_count($job_id,$content_type);
841
 
842
+ //return count;
843
+ return $remaining_count;
844
+ }
 
 
 
845
 
846
+ /**
847
+ *
848
+ * Validate backup files
849
+ *
850
+ * @param $job_id
851
+ * @param $source_root
852
+ * @param $target_root
853
+ * @param $content_type
854
+ *
855
+ * @return bool|mixed
856
+ */
857
+ public function validate_backup_files($job_id,$content_type){
858
+ $this->logger->log_info(__METHOD__,'Begin: '.$content_type);
859
+
860
+ //get files to backup
861
+ $db = new WPBackItUp_DataAccess();
862
+
863
+ switch($content_type)
864
+ {
865
+ case 'themes';
866
+ $target_root='wp-content-themes';
867
+ break;
868
+ case 'plugins';
869
+ $target_root='wp-content-plugins';
870
+ break;
871
+ case 'uploads';
872
+ $target_root='wp-content-uploads';
873
+ break;
874
+ case 'others';
875
+ $target_root='wp-content-other';
876
+ break;
877
+ //ADD exception when other
878
+ }
879
 
880
+ $file_list = $db->get_completed_tasks($job_id,$content_type);
881
 
882
+ //It is possible that there were no files backed up
883
+ if($file_list == false || $file_list==0) {
884
+ $this->logger->log_info(__METHOD__,'No files found to validate.');
885
+ return true;
886
+ }
887
+
888
+ $current_zip_file=null;
889
+ $zip=null;
890
+ $file_counter=0;
891
+ foreach($file_list as $file) {
892
+ $batch_id = $file->batch_id;
893
+ $item = $target_root .'/' .utf8_decode( $file->item );
894
+
895
+ //get zip path
896
+ $zip_file_path = sprintf('%s-%s-%s.zip',$this->backup_project_path . $this->backup_name, $content_type,$batch_id);
897
+ if ($current_zip_file!=$zip_file_path){
898
+ //$this->logger->log_info( __METHOD__, 'Zip File:' . $zip_file_path );
899
+ if (! file_exists($zip_file_path)){
900
+ $this->logger->log_error( __METHOD__, 'Zip File not found:' . $zip_file_path );
901
+ return false;
902
+ }
903
+ $current_zip_file = $zip_file_path;
904
+ if (null!=$zip) $zip->close();
905
+ $zip = new WPBackItUp_Zip($this->logger,$current_zip_file);
906
+ $this->logger->log_info( __METHOD__, 'Current Zip File:' . $current_zip_file );
907
+ }
908
+
909
+ //validate file exists in zip
910
+ if (false===$zip->validate_file($item)) {
911
+ $this->logger->log_error( __METHOD__, 'File NOT found in zip :' . $item );
912
+ $zip->close();
913
+ return false;
914
+ }
915
+ $file_counter++;
916
+ }
917
+
918
+ $this->logger->log_info( __METHOD__, 'Validation Successful:'.$content_type . '(' .$file_counter .')');
919
+ if (null!=$zip) $zip->close();
920
+ return true;
921
+ }
922
+
923
+ /**
924
+ *
925
+ * Add files in file list to zip file
926
+ *
927
+ *
928
+ * @param $source_root
929
+ * @param $target_root
930
+ * @param $file_list (object collection)
931
+ * @param $zip_file_path
932
+ *
933
+ * @return bool
934
+ */
935
+ private function backup_files_to_zip($source_root,$target_root,$file_list, $zip_file_path){
936
+ $this->logger->log_info(__METHOD__,'Begin ');
937
+
938
+ if (empty($file_list) || !isset($file_list)) {
939
+ $this->logger->log_error(__METHOD__,'File list is not valid:');
940
+ $this->logger->log(var_export($file_list,true));
941
+ return false;
942
+ }
943
+
944
+ $this->logger->log_info(__METHOD__,'Begin - Item Count: '. count($file_list));
945
+ $zip = new WPBackItUp_Zip($this->logger,$zip_file_path);
946
+
947
+ foreach($file_list as $file) {
948
+ $item = $source_root. '/' .utf8_decode($file->item);
949
+ $this->logger->log_info( __METHOD__, 'File:' .$item);
950
+
951
+ //skip it if folder
952
+ if ( is_dir( $item ) ) {
953
+ $this->logger->log_info( __METHOD__, 'Skip folder:' . $item );
954
+ continue;
955
+ }
956
+
957
+ //replace the source path with the target & fix any pathing issues
958
  $target_item_path = str_replace(rtrim($source_root, '/'),rtrim($target_root,'/'),$item);
959
+ $target_item_path= str_replace('//','/',$target_item_path);
960
+ $target_item_path= str_replace('\\','/',$target_item_path);
961
+
962
+ $this->logger->log_info( __METHOD__, 'Add File:' .$target_item_path );
963
+ if ( $zip->add_file($item,$target_item_path)) {
964
+ $this->logger->log_info( __METHOD__, 'File Added:' . $target_item_path );
965
+ } else {
966
+ $this->logger->log_error( __METHOD__, 'File NOT added:' . $target_item_path );
967
+ return false;
968
+ }
969
+ }
970
 
971
+ //if we get here then close the zip
972
+ $zip->close();//close the zip
973
+ $this->logger->log_info(__METHOD__,'End');
974
+ return true;
975
+ }
976
 
 
 
977
 
978
+ /**
979
+ *
980
+ * Backup files in array to list
981
+ *
982
+ * @param $source_root
983
+ * @param $target_root
984
+ * @param $suffix
985
+ * @param $file_list
986
+ * @param $batch_size
987
+ *
988
+ * @return array|bool
989
+ */
990
+ public function backup_file_list($source_root,$target_root,$suffix,$file_list,$batch_size){
991
+ $this->logger->log_info(__METHOD__,'Begin');
992
 
993
+ if (! is_array($file_list)) {
994
+ $this->logger->log_error(__METHOD__,'Array expected in file list:');
995
+ $this->logger->log(var_export($file_list,true));
996
+ return false;
997
+ }
998
 
999
+ $batch_id=current_time( 'timestamp' );
 
 
 
 
 
 
 
1000
 
1001
+ $zip_file_path = $this->backup_project_path . $this->backup_name .'-'.$suffix .'.tmp';
1002
+ $zip = new WPBackItUp_Zip($this->logger,$zip_file_path);
1003
+ foreach($file_list as $item) {
1004
+ $item = utf8_decode($item);
1005
+ $this->logger->log_info( __METHOD__, 'File:' . $item );
1006
+
1007
+ //skip it if folder
1008
+ if ( is_dir( $item ) ) {
1009
+ $this->logger->log_info( __METHOD__, 'Skip folder:' . $item );
1010
+ array_shift( $file_list ); //remove from list
1011
+ continue;
1012
+ }
1013
 
1014
+ //replace the source path with the target
1015
+ $target_item_path = str_replace(rtrim($source_root, '/'),rtrim($target_root,'/'),$item);
1016
+ $this->logger->log_info( __METHOD__, 'Add File:' .$target_item_path );
1017
+ if ( $zip->add_file($item,$target_item_path)) {
1018
+ array_shift($file_list);
1019
+ $this->logger->log_info( __METHOD__, 'File Added:' . $target_item_path );
1020
+ //If we have added X# of files or hit the size limit then lets close the zip and finish on the next pass
1021
+ if( $zip->get_zip_file_count()>=$batch_size){
1022
+ $zip->close();//close the zip
1023
+ $this->logger->log_info(__METHOD__,'End - Item Count:' . count($file_list));
1024
+ return $file_list;
1025
+ }
1026
+ } else {
1027
+ $this->logger->log_error( __METHOD__, 'File NOT added:' . $target_item_path );
1028
+ return false;
1029
+ }
1030
+ }
1031
 
1032
+ //if we get here then close the zip
1033
+ $zip->close();//close the zip
1034
 
1035
  //if there are no more files to add then rename the zip
1036
+ //Check to see if the file exists, it is possible that it does not if only empty folders were contained
1037
+ if(count($file_list)==0 && file_exists($zip_file_path) ){
1038
+ if (! $this->add_zip_suffix($batch_id,$zip_file_path)){
1039
+ return false;
 
1040
  }
1041
  }
1042
 
1044
  return $file_list;
1045
  }
1046
 
 
1047
  private function strposa($haystack, $needle) {
1048
  if(!is_array($needle)) $needle = array($needle);
1049
 
1060
  return false;
1061
  }
1062
 
1063
+ private function add_zip_suffix($batch_id,$zip_file_path){
1064
  $this->logger->log_info(__METHOD__,'Begin');
1065
 
1066
  $file_extension = pathinfo($zip_file_path, PATHINFO_EXTENSION);
1067
  $this->logger->log_info(__METHOD__,'File Extension:'.$file_extension);
1068
  if ($file_extension!='zip'){
1069
  $file_system = new WPBackItUp_FileSystem($this->logger);
1070
+ $new_zip_name = str_replace('.' . $file_extension,'-'.$batch_id .'.zip',$zip_file_path);
1071
  if ( !$file_system->rename_file($zip_file_path,$new_zip_name)){
1072
  $this->logger->log_error(__METHOD__,'Zip could not be renamed.');
1073
  return false;
1114
 
1115
  //get a list of all the zips
1116
  $backup_files_path = array_filter(glob($this->backup_project_path. '*.zip'), 'is_file');
1117
+ $this->logger->log_info(__METHOD__,'Zip files found:'. var_export($backup_files_path,true));
1118
  if (is_array($backup_files_path) && count($backup_files_path)>0){
1119
  //get rid of the path.
1120
  $backup_files = str_replace($this->backup_project_path,'',$backup_files_path);
lib/includes/class-database.php ADDED
@@ -0,0 +1,393 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined ('ABSPATH')) die('No direct access allowed');
2
+
3
+ /**
4
+ * Class for Database access
5
+ *
6
+ * @package WPBackItUp Database Class
7
+ * @copyright Copyright (c) 2015, Chris Simmons
8
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
+ *
10
+ */
11
+
12
+ class WPBackItUp_DataAccess {
13
+
14
+ //Status values
15
+ const BATCH_ACTIVE = 0;
16
+ const BATCH_COMPLETE =1;
17
+ const BATCH_ERROR =-1;
18
+
19
+ //Record Types
20
+ const JOB_CONTROL_RECORD = "J";
21
+ const JOB_ITEM_RECORD ="I";
22
+
23
+ private $logger;
24
+
25
+ /**
26
+ * Class constructor.
27
+ *
28
+ * @access public
29
+ * @param $batch_id
30
+ */
31
+ function __construct() {
32
+ global $wpdb,$table_prefix;
33
+
34
+ try {
35
+ $this->logger = new WPBackItUp_Logger(false,null,'debug_database');
36
+
37
+ //Add tables to WPDB
38
+ $wpdb->wpbackitup_job = $table_prefix . 'wpbackitup_job';
39
+
40
+
41
+ } catch(Exception $e) {
42
+ error_log($e); //Log to debug
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Save Batch of SQL values to inventory table
48
+ * @param $sql_values
49
+ *
50
+ * @return bool
51
+ */
52
+ public function insert_job_items($sql_values) {
53
+ $this->logger->log_info(__METHOD__,'Begin');
54
+ global $wpdb;
55
+
56
+ //Remove slashes
57
+ $sql_values= str_replace('\\', "/", $sql_values );
58
+ //$sql_values= utf8_encode($sql_values);
59
+
60
+ $sql_insert = "INSERT INTO $wpdb->wpbackitup_job
61
+ (job_id, group_id, item, size_kb, create_date)
62
+ VALUES " ;
63
+
64
+ //Get rid of last comma and replace with semicolon
65
+ $sql = $sql_insert . substr_replace($sql_values, ";",-1);
66
+
67
+ //If inserts return false
68
+ $sql_rtn = $this->query($sql);
69
+ if (false=== $sql_rtn || $sql_rtn==0 ) return false;
70
+ else return true;
71
+
72
+ }
73
+
74
+ /**
75
+ * Create job control record
76
+ *
77
+ * @param $job_id
78
+ *
79
+ * @return bool
80
+ */
81
+ public function create_job_control($job_id) {
82
+ $this->logger->log_info(__METHOD__,'Begin');
83
+ global $wpdb;
84
+
85
+ $sql = $wpdb->prepare(
86
+ "INSERT $wpdb->wpbackitup_job
87
+ (job_id, record_type,create_date)
88
+ VALUES(%d,%s,NOW())
89
+ ",$job_id,self::JOB_CONTROL_RECORD);
90
+
91
+ $sql_rtn = $this->query($sql);
92
+ if (false=== $sql_rtn || $sql_rtn==0 ) return false;
93
+ else return true;
94
+
95
+ }
96
+
97
+ /**
98
+ * Update batch status record as successfully completed
99
+ *
100
+ * @param $job_id
101
+ *
102
+ * @return bool
103
+ */
104
+ public function update_job_control_complete($job_id) {
105
+ $this->logger->log_info(__METHOD__,'Begin');
106
+
107
+ return $this->update_job_control_status($job_id,self::BATCH_COMPLETE);
108
+
109
+ }
110
+
111
+ /**
112
+ * Update batch status record
113
+ *
114
+ * @param $job_id
115
+ *
116
+ * @param $status
117
+ *
118
+ * @return bool
119
+ */
120
+ private function update_job_control_status($job_id,$status) {
121
+ $this->logger->log_info(__METHOD__,'Begin');
122
+ global $wpdb;
123
+
124
+ $sql = $wpdb->prepare(
125
+ "UPDATE $wpdb->wpbackitup_job
126
+ set status=%s
127
+ ,update_date=NOW()
128
+ WHERE
129
+ record_type=%s
130
+ && job_id=%d
131
+ ",$status,self::JOB_CONTROL_RECORD,$job_id);
132
+
133
+ //If query errors return false
134
+ $sql_rtn = $this->query($sql);
135
+ if (false=== $sql_rtn || $sql_rtn==0 ) return false;
136
+ else return true;
137
+
138
+ }
139
+
140
+
141
+ /**
142
+ * Fetch batch control records older than date threshhold
143
+ * @param $days
144
+ *
145
+ * @return mixed
146
+ */
147
+ function get_old_batch_control($days){
148
+ global $wpdb;
149
+ $this->logger->log_info(__METHOD__,'Begin');
150
+
151
+ $sql_select = $wpdb->prepare(
152
+ "SELECT * FROM $wpdb->wpbackitup_job
153
+ WHERE
154
+ record_type=%s
155
+ && create_date <= DATE(DATE_SUB(NOW(), INTERVAL %d DAY))
156
+ ",self::JOB_CONTROL_RECORD,$days);
157
+
158
+ return $this->get_rows($sql_select);
159
+ }
160
+
161
+
162
+ /**
163
+ *
164
+ * Get all open task items (status 0 or -1) and mark them with batch id
165
+ *
166
+ * @param $batch_id
167
+ * @param $batch_size
168
+ * @param $job_id
169
+ * @param $group_id
170
+ *
171
+ * @return mixed
172
+ */
173
+ function get_batch_open_tasks($batch_id,$batch_size,$job_id,$group_id){
174
+ global $wpdb;
175
+ $this->logger->log_info(__METHOD__,'Begin');
176
+
177
+ $sql_update = $wpdb->prepare(
178
+ "UPDATE $wpdb->wpbackitup_job
179
+ set batch_id=%d
180
+ ,retry_count=retry_count + 1
181
+ ,update_date=NOW()
182
+ WHERE
183
+ record_type=%s
184
+ && job_id=%d
185
+ && group_id=%s
186
+ && retry_count < 3
187
+ && (status=%d || status=%d)
188
+ LIMIT %d
189
+ ",$batch_id,self::JOB_ITEM_RECORD,$job_id,$group_id,self::BATCH_ACTIVE,self::BATCH_ERROR,$batch_size);
190
+
191
+ //If no updates return false else # updated
192
+ $sql_rtn = $this->query($sql_update);
193
+ if (false=== $sql_rtn || $sql_rtn==0 ) return $sql_rtn;
194
+
195
+ $sql_select = $wpdb->prepare(
196
+ "SELECT * FROM $wpdb->wpbackitup_job
197
+ WHERE
198
+ record_type=%s
199
+ && batch_id=%d
200
+ ORDER BY id
201
+ ",self::JOB_ITEM_RECORD,$batch_id);
202
+
203
+ return $this->get_rows($sql_select);
204
+ }
205
+
206
+ /**
207
+ *
208
+ * Get all completed tasks for a group
209
+ *
210
+ * @param $batch_id
211
+ * @param $job_id
212
+ * @param $group_id
213
+ *
214
+ * @return mixed
215
+ */
216
+ function get_completed_tasks($job_id,$group_id){
217
+ global $wpdb;
218
+ $this->logger->log_info(__METHOD__,'Begin');
219
+
220
+ $sql_select = $wpdb->prepare(
221
+ "SELECT * FROM $wpdb->wpbackitup_job
222
+ WHERE
223
+ record_type=%s
224
+ && job_id=%d
225
+ && group_id=%s
226
+ && status=%d
227
+ ORDER BY id
228
+ ",self::JOB_ITEM_RECORD,$job_id,$group_id,self::BATCH_COMPLETE);
229
+
230
+ return $this->get_rows($sql_select);
231
+ }
232
+
233
+ /**
234
+ *
235
+ * delete all job records by job id
236
+ *
237
+ * @param $job_id
238
+ *
239
+ * @return mixed
240
+ */
241
+ function delete_job_records($job_id){
242
+ global $wpdb;
243
+ $this->logger->log_info(__METHOD__,'Begin');
244
+
245
+ $sql_update = $wpdb->prepare(
246
+ "DELETE FROM $wpdb->wpbackitup_job
247
+ WHERE
248
+ job_id=%d
249
+ ",$job_id);
250
+
251
+ //If no deletes return false else # updated
252
+ $sql_rtn = $this->query($sql_update);
253
+ if (false=== $sql_rtn || $sql_rtn==0 ) return false;
254
+ else return true;
255
+
256
+ }
257
+
258
+ /**
259
+ * Get all open task items (status 0 or -1) and mark them with batch id
260
+ *
261
+ * @param $job_id
262
+ * @param $group_id
263
+ *
264
+ * @return mixed
265
+ */
266
+ function get_open_task_count($job_id,$group_id){
267
+ global $wpdb;
268
+ $this->logger->log_info(__METHOD__,'Begin');
269
+
270
+ $sql = $wpdb->prepare(
271
+ "SELECT count(*) as task_count FROM $wpdb->wpbackitup_job
272
+ WHERE
273
+ record_type=%s
274
+ && job_id=%d
275
+ && group_id=%s
276
+ && retry_count < 3
277
+ && (status=%d || status=%d)
278
+ ",self::JOB_ITEM_RECORD,$job_id,$group_id,self::BATCH_ACTIVE,self::BATCH_ERROR);
279
+
280
+ $row=$this->get_row($sql);
281
+ $this->logger->log_info(__METHOD__,'Results:'.var_export($row,true));
282
+
283
+ return $row->task_count;
284
+ }
285
+
286
+ /**
287
+ * Set Job batch to success
288
+ *
289
+ * @param $job_id
290
+ * @param $batch_id
291
+ *
292
+ * @return bool
293
+ */
294
+ function update_batch_complete($job_id,$batch_id){
295
+ global $wpdb;
296
+ $this->logger->log_info(__METHOD__,'Begin');
297
+
298
+ $sql = $wpdb->prepare(
299
+ "UPDATE $wpdb->wpbackitup_job
300
+ set status=%d
301
+ ,update_date=NOW()
302
+ where
303
+ job_id=%d
304
+ && batch_id=%d;
305
+ ",self::BATCH_COMPLETE,$job_id,$batch_id);
306
+
307
+ $sql_rtn = $this->query($sql);
308
+ if (false=== $sql_rtn || $sql_rtn==0 ) return false;
309
+ else return true;
310
+ }
311
+
312
+ /**
313
+ *
314
+ * PRIVATES
315
+ *
316
+ */
317
+
318
+
319
+ /**
320
+ * Query (Update/Insert Sql statements)
321
+ *
322
+ * @param $sql
323
+ * @return mixed
324
+ *
325
+ */
326
+ private function query($sql){
327
+ global $wpdb;
328
+ $this->logger->log_info(__METHOD__,'Begin');
329
+
330
+ $wpdb_result = $wpdb->query($sql);
331
+ $last_query = $wpdb->last_query;
332
+ $last_error = $wpdb->last_error;
333
+
334
+ $this->logger->log_info(__METHOD__,'Last Query:' .var_export( $last_query,true ) );
335
+ $this->logger->log_info(__METHOD__,'Query Result: ' .($wpdb_result=== FALSE?'Query Error': $wpdb_result));
336
+
337
+ if ($wpdb_result === FALSE && !empty($last_error)) {
338
+ $this->logger->log_error(__METHOD__,'Last Error:' .var_export( $last_error,true ) );
339
+ }
340
+
341
+ return $wpdb_result;
342
+ }
343
+
344
+ /**
345
+ * Get single row
346
+ *
347
+ * @param $sql
348
+ * @return mixed
349
+ */
350
+ private function get_row($sql){
351
+ global $wpdb;
352
+ $this->logger->log_info(__METHOD__,'Begin');
353
+
354
+ $wpdb_result = $wpdb->get_row($sql);
355
+ $last_query = $wpdb->last_query;
356
+ $last_error = $wpdb->last_error;
357
+
358
+ $this->logger->log_info(__METHOD__,'Last Query:' .var_export( $last_query,true ));
359
+ $this->logger->log_info(__METHOD__,'Query Result: ' .($wpdb_result==null?'NULL': $wpdb->num_rows));
360
+
361
+ if (null == $wpdb_result && !empty($last_error)) {
362
+ $this->logger->log_error(__METHOD__,'Last Error:' .var_export( $last_query,true ));
363
+ }
364
+
365
+ return $wpdb_result;
366
+
367
+ }
368
+
369
+ /**
370
+ * Get multiple rows
371
+ *
372
+ * @param $sql
373
+ * @return mixed
374
+ */
375
+ private function get_rows($sql){
376
+ global $wpdb;
377
+ $this->logger->log_info(__METHOD__,'Begin');
378
+
379
+ $wpdb_result = $wpdb->get_results($sql);
380
+ $last_query = $wpdb->last_query;
381
+ $last_error = $wpdb->last_error;
382
+
383
+ $this->logger->log_info(__METHOD__,'Last Query:' .var_export( $last_query,true ));
384
+ $this->logger->log_info(__METHOD__,'Query Result: ' .($wpdb_result==null?'NULL': $wpdb->num_rows));
385
+
386
+ if (null == $wpdb_result && ! empty($last_error)) {
387
+ $this->logger->log_error(__METHOD__,'Last Error:' .var_export( $last_error,true ));
388
+ }
389
+
390
+ return $wpdb_result;
391
+
392
+ }
393
+ }
lib/includes/class-job-v2.php ADDED
@@ -0,0 +1,1040 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined ('ABSPATH')) die('No direct access allowed');
2
+
3
+ /**
4
+ * WP BackItUp - Job Class V2
5
+ *
6
+ * @package WP BackItUp
7
+ * @author Chris Simmons <chris.simmons@wpbackitup.com>
8
+ * @link http://www.wpbackitup.com
9
+ *
10
+ */
11
+
12
+
13
+ //Includes
14
+ if( !class_exists( 'WPBackItUp_Utility' ) ) {
15
+ include_once 'class-utility.php';
16
+ }
17
+
18
+ if( !class_exists( 'WPBackItUp_Mutex' ) ) {
19
+ include_once 'class-mutex.php';
20
+ }
21
+
22
+ if( !class_exists( 'WPBackItUp_DataAccess' ) ) {
23
+ include_once 'class-database.php';
24
+ }
25
+
26
+
27
+
28
+ class WPBackItUp_Job_v2 {
29
+
30
+ const JOB_TITLE='wpbackitup_job';
31
+
32
+ //Status values
33
+ const ERROR = 'error';
34
+ const ACTIVE ='active';
35
+ const COMPLETE ='complete';
36
+ const CANCELLED='cancelled';
37
+ const QUEUED = 'queued';
38
+ const RESUME = 'resume';
39
+
40
+ private $logger;
41
+ private $job_id; //post ID
42
+ private $instance_id;
43
+ private $allocated_task;
44
+
45
+ private $job_start_time;
46
+ private $job_end_time;
47
+
48
+ private $lockFile;
49
+ private $lockFilePath;
50
+ private $locked;
51
+ private $mutex;
52
+
53
+ private $job_info; //getter
54
+
55
+ public $job_status;
56
+ public $backup_id;
57
+
58
+ private function __construct($job) {
59
+ try {
60
+ $this->logger = new WPBackItUp_Logger(false,null,'debug_job');
61
+
62
+ //Load of the class properties from the post object(see wp_post)
63
+ $this->job_id=$job->ID;
64
+ $this->instance_id=time();
65
+ $this->job_status=$job->post_status;
66
+ $this->backup_id=$job->post_name;
67
+
68
+ //empty array if no job info
69
+ $this->job_info = get_post_meta($this->job_id,'job_info',true);
70
+
71
+ //Deserialize content
72
+ $content = $job->post_content;
73
+ if (!empty($content)){
74
+ $job_info =maybe_unserialize($content);
75
+ if (is_array($job_info)){
76
+ $this->job_start_time=$job_info['start_time'];
77
+ }
78
+ }
79
+
80
+ } catch(Exception $e) {
81
+ error_log($e); //Log to debug
82
+ }
83
+ }
84
+
85
+ function __destruct() {
86
+ $this->logger->log_info( __METHOD__,'Begin');
87
+ $this->release_lock();
88
+ }
89
+
90
+ /**
91
+ * Get lock if possible
92
+ *
93
+ * @param $lock_name
94
+ *
95
+ * @return bool
96
+ *
97
+ */
98
+ public function get_lock ($lock_name){
99
+ $this->logger->log_info( __METHOD__,'Begin:'.$lock_name);
100
+
101
+ try {
102
+ $lock_file_path = WPBACKITUP__PLUGIN_PATH .'/logs';
103
+ $this->mutex = new WPBackItUp_Mutex($lock_name,$lock_file_path);
104
+ if ($this->mutex->lock(false)) {
105
+ $this->logger->log_info( __METHOD__,'Process LOCK acquired');
106
+ $this->locked=true;
107
+ } else {
108
+ //This is not an error, just means another process has it allocated
109
+ $this->logger->log_info( __METHOD__,'Process LOCK Failed');
110
+ $this->locked=false;
111
+ }
112
+
113
+ return $this->locked;
114
+
115
+ } catch(Exception $e) {
116
+ $this->logger->log_error( __METHOD__,'Process Lock error: ' .$e);
117
+ $this->locked=false;
118
+ return $this->locked;
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Release lock
124
+ *
125
+ * @return bool
126
+ */
127
+ public function release_lock (){
128
+ $this->logger->log_info( __METHOD__,'Begin');
129
+
130
+ try{
131
+
132
+ if (null!=$this->mutex) {
133
+ $this->mutex->releaseLock();
134
+ $this->mutex = null;
135
+ }
136
+
137
+ $this->logger->log_info( __METHOD__,'Lock released');
138
+ $this->locked=false;
139
+ }catch(Exception $e) {
140
+ $this->logger->log_error( __METHOD__,'Process UNLOCK error: ' .$e);
141
+ }
142
+ }
143
+
144
+ public function is_job_complete() {
145
+ $this->logger->log_info( __METHOD__, 'Begin' );
146
+
147
+ $tasks = get_post_meta( $this->job_id);
148
+ foreach($tasks as $key=>$value) {
149
+ //Is this a task of job meta data
150
+ if (substr($key, 0, 4)!='task') continue;
151
+
152
+ $task = get_post_meta($this->job_id,$key);
153
+
154
+ //Get Task Properties
155
+ // $task_id = $task[0]['task_id'];
156
+ $task_status = $task[0]['task_status'];
157
+ // $task_allocated_id = $task[0]['task_allocated_id'];
158
+ // $task_last_updated = $task[0]['task_last_updated'];
159
+
160
+ if (self::QUEUED==$task_status || self::ACTIVE==$task_status){
161
+ $this->logger->log_info( __METHOD__, 'Active or Queued Task found:' . $key );
162
+ return false;
163
+ }
164
+ }
165
+
166
+ //No active or queued tasks were found
167
+ $this->logger->log_info( __METHOD__, 'End - No Active or Queued Tasks found' );
168
+ return true;
169
+
170
+ }
171
+ //What is the next task in the stack
172
+ public function get_next_task(){
173
+ $this->logger->log_info(__METHOD__,'Begin');
174
+
175
+ $this->allocated_task=null; //Set the current task to null;
176
+
177
+ //Get the tasks -- DO I NEED TO SORT?
178
+ $tasks = get_post_meta($this->job_id);
179
+
180
+ //Enumerate the tasks
181
+ foreach ($tasks as $key => $value) {
182
+
183
+ //Is this a task of job meta data
184
+ if (substr($key, 0, 4)!='task') continue;
185
+
186
+ $task = get_post_meta($this->job_id,$key);
187
+
188
+ //Get Task Properties
189
+ $task_id = $task[0]['task_id'];
190
+ $task_status = $task[0]['task_status'];
191
+ $task_allocated_id = $task[0]['task_allocated_id'];
192
+ $task_last_updated = $task[0]['task_last_updated'];
193
+ $task_retry_count = $task[0]['task_retry_count'];
194
+
195
+ //if next task in stack is queued then its time to get to work
196
+ switch ($task_status) {
197
+
198
+ case self::QUEUED:
199
+ //Try allocate task
200
+ $queued_task = $this->allocate_task($this->job_id, $key,$task_id);
201
+
202
+ //If task was allocated then update the job status to active
203
+ if (false!==$queued_task){
204
+ $this->set_job_status_active();
205
+
206
+ //return task
207
+ $rtn_task = new WPBackItUp_Task($this->job_id,$key,$queued_task[0]);
208
+
209
+ // $rtn_task = new stdClass;
210
+ // $rtn_task->id = $queued_task[0]['task_id'];
211
+ // $rtn_task->status = $task[0]['task_status'];
212
+ return $rtn_task;
213
+
214
+ } else{
215
+ //couldnt allocate task
216
+ return false;
217
+ }
218
+
219
+ case self::RESUME:
220
+
221
+ $rtn_task = new WPBackItUp_Task($this->job_id,$key,$task[0]);
222
+
223
+ //return task
224
+ // $rtn_task = new stdClass;
225
+ // $rtn_task->id = $task_id;
226
+ // $rtn_task->status = $task_status;
227
+ return $rtn_task;
228
+
229
+ case self::ACTIVE:
230
+ //Error if >= 3 minutes since the last update
231
+ if (time()>=$task_last_updated+WPBACKITUP__TASK_TIMEOUT_SECONDS){
232
+ $this->update_task_status($this->job_id, $key,$task_id,self::ERROR);
233
+
234
+ //Update job to error also
235
+ $this->set_job_status_error();
236
+
237
+ $task[0]['task_status']=self::ERROR;
238
+ $rtn_task = new WPBackItUp_Task($this->job_id,$key,$task[0]);
239
+
240
+ //return task
241
+ // $rtn_task = new stdClass;
242
+ // $rtn_task->id = $task_id;
243
+ // $rtn_task->status = self::ERROR;
244
+ return $rtn_task;
245
+
246
+ }else {
247
+
248
+ $this->logger->log_info( __METHOD__, 'Job:' . $key . ' is still active' );
249
+ //if its been less than 3 minutes then wait
250
+ return false;
251
+ }
252
+
253
+ case self::CANCELLED:
254
+ case self::COMPLETE:
255
+ //Do nothing - get the next task
256
+ break;
257
+
258
+ case self::ERROR:
259
+ //Job should already be error but update if not
260
+ //Update job to error also
261
+ $this->set_job_status_error();
262
+
263
+ //return task
264
+ $task[0]['task_status']=self::ERROR;
265
+ $rtn_task = new WPBackItUp_Task($this->job_id,$key,$task[0]);
266
+
267
+ // $rtn_task = new stdClass;
268
+ // $rtn_task->id = $task_id;
269
+ // $rtn_task->status = self::ERROR;
270
+ return $rtn_task;
271
+ }
272
+ }
273
+
274
+ //If no more tasks then job must be done
275
+ $this->set_job_status_complete();
276
+
277
+ $this->logger->log_info(__METHOD__,'End - no tasks to allocate');
278
+ return false; //no tasks to allocate now but job should be complete next time
279
+ }
280
+
281
+ public function peek_current_task(){
282
+ $this->logger->log_info(__METHOD__,'Begin');
283
+
284
+ //$this->allocated_task=null; //Set the current task to null;
285
+
286
+ //Get the tasks -- DO I NEED TO SORT?
287
+ $tasks = get_post_meta($this->job_id);
288
+
289
+ //Enumerate the tasks
290
+ foreach ($tasks as $key => $value) {
291
+
292
+ //Is this a task of job meta data
293
+ if (substr($key, 0, 4)!='task') continue;
294
+
295
+ $task_info = get_post_meta($this->job_id,$key);
296
+
297
+ //Get Task Properties
298
+ $task = new WPBackItUp_Task($this->job_id,$key,$task_info[0]);
299
+ // $task=new stdClass();
300
+ // $task->id=$task_info[0]['task_id'];
301
+ // $task->status=$task_info[0]['task_status'];
302
+ // $task->last_updated=$task_info[0]['task_last_updated'];
303
+
304
+ //Find the current task in stack
305
+ switch ($task->getStatus()) {
306
+ case self::QUEUED:
307
+ case self::RESUME:
308
+ case self::ACTIVE:
309
+ case self::ERROR: //retry task
310
+ return $task;
311
+
312
+ case self::CANCELLED:
313
+ case self::COMPLETE:
314
+ //Do nothing - get the next task
315
+ break;
316
+ }
317
+ }
318
+
319
+ $this->logger->log_info(__METHOD__,'End - no tasks to allocate');
320
+ return false; //nothing active
321
+ }
322
+
323
+
324
+ /**
325
+ * Allocate the task to this job - will set task status to active
326
+ *
327
+ * @param $job_id
328
+ * @param $key
329
+ * @param $task_id
330
+ *
331
+ * @return bool
332
+ */
333
+ private function allocate_task($job_id, $key,$task_id){
334
+ $this->logger->log_info(__METHOD__,'Begin');
335
+
336
+ //Allocate the task to this process
337
+ $process_uid = uniqid();
338
+ $this->update_task_status($job_id, $key,$task_id,self::ACTIVE,$process_uid);
339
+
340
+ //Get updated task and make sure uid is good
341
+ $updated_task = get_post_meta( $this->job_id, $key);
342
+ $updated_task_allocated_id = $updated_task[0]['task_allocated_id'];
343
+ if ($process_uid==$updated_task_allocated_id) {
344
+ $this->allocated_task=$updated_task; // set the jobs allocated task
345
+
346
+ $this->logger->log_info(__METHOD__,'End - Task allocated');
347
+ return $updated_task;
348
+ }else{
349
+ $this->allocated_task=null;
350
+ $this->logger->log_info(__METHOD__,'End - Task was not allocated');
351
+ return false;
352
+ }
353
+ }
354
+
355
+ /**
356
+ * Set the allocated task status to queued
357
+ */
358
+ public function set_task_queued(){
359
+ $this->logger->log_info(__METHOD__,'Begin');
360
+
361
+ $this->logger->log_info(__METHOD__, 'Task Info:');
362
+ $this->logger->log($this->allocated_task);
363
+
364
+ //Get allocated task Properties
365
+ $task_id = $this->allocated_task[0]['task_id'];
366
+ $this->update_task_status($this->job_id, $task_id,$task_id,self::QUEUED);
367
+
368
+ $this->logger->log_info(__METHOD__,'End');
369
+ }
370
+
371
+ /**
372
+ * Set the allocated task status to queued by id
373
+ *
374
+ * @param $task_id
375
+ */
376
+ public function set_task_queued_by_id($task_id){
377
+ $this->logger->log_info(__METHOD__,'Begin');
378
+
379
+ $this->logger->log_info(__METHOD__, 'Task Info:');
380
+ $this->logger->log($task_id);
381
+
382
+ $this->update_task_status($this->job_id, $task_id,$task_id,self::QUEUED);
383
+
384
+ $this->logger->log_info(__METHOD__,'End');
385
+ }
386
+
387
+ /**
388
+ * Set the task status by id
389
+ *
390
+ * @param $task_id
391
+ * @param $status
392
+ */
393
+ public function set_task_status_by_id($task_id, $status){
394
+ $this->logger->log_info(__METHOD__,'Begin');
395
+
396
+ $this->logger->log_info(__METHOD__, 'Task Info:');
397
+ $this->logger->log($task_id);
398
+
399
+ $this->update_task_status($this->job_id, $task_id,$task_id,$status);
400
+
401
+ $this->logger->log_info(__METHOD__,'End');
402
+ }
403
+
404
+ /**
405
+ * Set the allocated task status to complete
406
+ */
407
+ public function set_task_complete(){
408
+ $this->logger->log_info(__METHOD__,'Begin');
409
+
410
+ $this->logger->log_info(__METHOD__, 'Task Info:');
411
+ $this->logger->log($this->allocated_task);
412
+
413
+ //Get allocated task Properties
414
+ $task_id = $this->allocated_task[0]['task_id'];
415
+ $this->update_task_status($this->job_id, $task_id,$task_id,self::COMPLETE);
416
+
417
+
418
+ //Check if this was the last task
419
+ if ($this->is_job_complete()){
420
+ $this->set_job_status_complete();
421
+ }
422
+
423
+ $this->logger->log_info(__METHOD__,'End');
424
+ }
425
+
426
+
427
+ /**
428
+ * Set the allocated task status to error
429
+ */
430
+ public function set_task_error($error_code){
431
+ $this->logger->log_info(__METHOD__,'Begin');
432
+
433
+ $this->logger->log_info(__METHOD__, 'Task Info:');
434
+ $this->logger->log($this->allocated_task);
435
+
436
+ //Get allocated task Properties
437
+ $task_id = $this->allocated_task[0]['task_id'];
438
+ $this->update_task_status($this->job_id, $task_id,$task_id,self::ERROR,'',$error_code);
439
+
440
+ $this->set_job_status_error();
441
+
442
+ $this->logger->log_info(__METHOD__,'End');
443
+ }
444
+
445
+
446
+ private function update_task_status($job_id,$task_name,$task_id, $task_status, $task_allocated_id='', $task_error_code=''){
447
+ $this->logger->log_info(__METHOD__,'Begin');
448
+
449
+ $meta_value = array(
450
+ 'task_id' => $task_id,
451
+ 'task_status' => $task_status,
452
+ 'task_allocated_id' => $task_allocated_id,
453
+ 'task_error_code' => $task_error_code,
454
+ 'task_last_updated' => time()
455
+ );
456
+
457
+ $this->logger->log_info(__METHOD__,'End - Task Updated:' .$job_id .'-'. $task_name .'-'. $task_status);
458
+ return update_post_meta( $job_id, $task_name, $meta_value );
459
+ }
460
+
461
+ // private function update_task_retry_count($job_id,$task_name,$task_id, $task_allocated_id='', $task_error_code=''){
462
+ // $this->logger->log_info(__METHOD__,'Begin');
463
+ //
464
+ // $meta_value = array(
465
+ // 'task_id' => $task_id,
466
+ // 'task_status' => $task_status,
467
+ // 'task_allocated_id' => $task_allocated_id,
468
+ // 'task_error_code' => $task_error_code,
469
+ // 'task_last_updated' => time()
470
+ // );
471
+ //
472
+ // $this->logger->log_info(__METHOD__,'End - Task Updated:' .$job_id .'-'. $task_name .'-'. $task_status);
473
+ // return update_post_meta( $job_id, $task_name, $meta_value );
474
+ // }
475
+
476
+
477
+ public function update_job_meta($meta_name,$meta_value){
478
+ $this->logger->log_info(__METHOD__,'Begin - Update job meta:' .$this->job_id .'-'. $meta_name);
479
+
480
+ //Encode the array values
481
+ if (is_array($meta_value)){
482
+ array_walk_recursive($meta_value, 'WPBackItUp_Utility::encode_items');
483
+ }
484
+
485
+ return update_post_meta( $this->job_id, $meta_name,$this->wpb_slash($meta_value));
486
+ }
487
+
488
+ /**
489
+ * Add slashes to a string or array of strings.
490
+ *
491
+ * This should be used when preparing data for core API that expects slashed data.
492
+ * This should not be used to escape data going directly into an SQL query.
493
+ *
494
+ * @since 3.6.0
495
+ *
496
+ * @param string|array $value String or array of strings to slash.
497
+ * @return string|array Slashed $value
498
+ */
499
+ private function wpb_slash( $value ) {
500
+ //only use on strings and arrays
501
+ if(! is_array($value) && ! is_string($value)){
502
+ return $value;
503
+ }
504
+
505
+ //only available 3.6 or later
506
+ if (function_exists('wp_slash')) return wp_slash($value);
507
+
508
+ if ( is_array( $value ) ) {
509
+ foreach ( $value as $k => $v ) {
510
+ if ( is_array( $v ) ) {
511
+ $value[$k] = $this->wpb_slash( $v );
512
+ } else {
513
+ $value[ $k ] = addslashes( $v );
514
+ }
515
+ }
516
+ } else {
517
+ $value = addslashes( $value );
518
+ }
519
+
520
+ return $value;
521
+ }
522
+
523
+ /**
524
+ * Remove slashes from a string or array of strings.
525
+ *
526
+ * This should be used to remove slashes from data passed to core API that
527
+ * expects data to be unslashed.
528
+ *
529
+ * @since 3.6.0
530
+ *
531
+ * @param string|array $value String or array of strings to unslash.
532
+ * @return string|array Unslashed $value
533
+ */
534
+ function wpb_unslash( $value ) {
535
+ return stripslashes_deep( $value );
536
+ }
537
+
538
+ public function get_job_meta($meta_name){
539
+ $this->logger->log_info(__METHOD__,'Begin:' .$this->job_id .'-'. $meta_name);
540
+
541
+ $job_meta = get_post_meta($this->job_id,$meta_name,true);
542
+
543
+ //Decode the array values
544
+ if (is_array($job_meta)){
545
+ array_walk_recursive($job_meta, 'WPBackItUp_Utility::decode_items');
546
+ }
547
+
548
+ return $job_meta;
549
+
550
+ }
551
+
552
+ /**
553
+ * Set job status to active
554
+ */
555
+ public function set_job_status_active( ) {
556
+ $status=self::ACTIVE;
557
+ if ($this->update_job_status($status)){
558
+ $this->job_status = $status;
559
+ }
560
+
561
+ //Set job end Time
562
+ $this->set_job_start_time();
563
+ }
564
+
565
+ /**
566
+ * Set job status to error
567
+ */
568
+ public function set_job_status_error( ) {
569
+ $status=self::ERROR;
570
+ if ($this->update_job_status($status)){
571
+ $this->job_status = $status;
572
+ }
573
+
574
+ //Set job end Time
575
+ $this->set_job_end_time();
576
+ }
577
+
578
+ /**
579
+ * Set job status to complete
580
+ */
581
+ public function set_job_status_complete( ) {
582
+ $status=self::COMPLETE;
583
+
584
+ if ($this->update_job_status($status)){
585
+ $this->job_status = $status;
586
+ }
587
+
588
+ //Set job end Time
589
+ $this->set_job_end_time();
590
+ }
591
+
592
+ /**
593
+ * Set job status to cancelled
594
+ */
595
+ public function set_job_status_cancelled( ) {
596
+ $status=self::CANCELLED;
597
+
598
+ if ($this->update_job_status($status)){
599
+ $this->job_status = $status;
600
+ }
601
+
602
+ //Set job end Time
603
+ $this->set_job_end_time();
604
+ }
605
+
606
+
607
+ /**
608
+ * Update job status
609
+ *
610
+ * @param $status
611
+ *
612
+ * @return bool
613
+ */
614
+ private function update_job_status($status) {
615
+ $this->logger->log_info(__METHOD__,'Begin');
616
+
617
+ $job = array(
618
+ 'ID' => $this->job_id,
619
+ 'post_status' => $status
620
+ );
621
+
622
+ // update the job
623
+ $job_id = wp_update_post($job );
624
+
625
+ if (0!=$job_id) {
626
+ $this->logger->log_info(__METHOD__,'End - Backup Job status set to:' .$job_id .'-' . $status );
627
+ return true;
628
+ } else{
629
+ $this->logger->log_error(__METHOD__,'End - Backup Job status NOT set.');
630
+ return false;
631
+ }
632
+
633
+ }
634
+
635
+ /**
636
+ * Set job start time
637
+ *
638
+ * @return bool
639
+ */
640
+ private function set_job_start_time() {
641
+ $this->logger->log_info(__METHOD__,'Begin');
642
+
643
+ $this->job_start_time= time();
644
+ $job_info = array(
645
+ 'start_time' => $this->job_start_time,
646
+ );
647
+
648
+ $job = array(
649
+ 'ID' => $this->job_id,
650
+ 'post_content' => serialize($job_info)
651
+ );
652
+
653
+ // update the job info
654
+ $job_id = wp_update_post($job );
655
+
656
+ if (0!=$job_id) {
657
+ $this->logger->log_info(__METHOD__,'End - Backup Job start time set');
658
+ return true;
659
+ } else{
660
+ $this->logger->log_error(__METHOD__,'End - Backup Job start time NOT set.');
661
+ return false;
662
+ }
663
+
664
+ }
665
+
666
+ /**
667
+ * Set job end time
668
+ *
669
+ * @return bool
670
+ */
671
+ private function set_job_end_time() {
672
+ $this->logger->log_info(__METHOD__,'Begin');
673
+
674
+ $this->job_end_time=time();
675
+ $job_info = array(
676
+ 'start_time' => $this->job_start_time,
677
+ 'end_time' => $this->job_end_time,
678
+ );
679
+
680
+ $job = array(
681
+ 'ID' => $this->job_id,
682
+ 'post_content' => serialize($job_info)
683
+ );
684
+
685
+ // update the job info
686
+ $job_id = wp_update_post($job );
687
+
688
+ if (0!=$job_id) {
689
+ $this->logger->log_info(__METHOD__,'End - Backup Job end time set');
690
+ return true;
691
+ } else{
692
+ $this->logger->log_error(__METHOD__,'End - Backup Job end time NOT set.');
693
+ return false;
694
+ }
695
+
696
+ }
697
+
698
+ /**---------STATICS---------***/
699
+
700
+ /**
701
+ * Is there at least 1 job queued or active?
702
+ *
703
+ * @param $job_name
704
+ *
705
+ * @return bool
706
+ */
707
+ public static function is_job_queued($job_name) {
708
+ $logger = new WPBackItUp_Logger(false,null,'debug_job');
709
+ $logger->log_info(__METHOD__,'Begin - Check Job Queue:' . $job_name);
710
+
711
+ //Get top 1
712
+ $args = array(
713
+ 'posts_per_page' => 1,
714
+ 'post_type' => $job_name,
715
+ 'post_status' => array(self::QUEUED,self::ACTIVE),
716
+ 'orderby' => 'post_date',
717
+ 'order' => 'ASC',
718
+ 'suppress_filters' => true
719
+ );
720
+ $jobs = get_posts( $args );
721
+ $logger->log($jobs);
722
+
723
+ if (is_array($jobs) && count($jobs)>0) {
724
+ $logger->log_info(__METHOD__,'Jobs found:' . count($jobs) );
725
+ return true;
726
+ }
727
+
728
+ $logger->log_info(__METHOD__,'No jobs found:' . $job_name);
729
+ $logger->log_info(__METHOD__,'End');
730
+ return false;
731
+ }
732
+
733
+ /**
734
+ * get completed jobs
735
+ * - complete, cancelled, error
736
+ *
737
+ * @param $job_name
738
+ //* @param int $count
739
+ *
740
+ * @return bool
741
+ */
742
+ public static function get_completed_jobs($job_name) {
743
+ $logger = new WPBackItUp_Logger(false,null,'debug_job');
744
+ $logger->log_info(__METHOD__,'Begin');
745
+
746
+ $args = array(
747
+ 'posts_per_page' => -1,
748
+ 'post_type' => $job_name,
749
+ 'post_status' => array(self::COMPLETE,self::CANCELLED,self::ERROR),
750
+ 'orderby' => 'post_date',
751
+ 'order' => 'DESC',
752
+ 'suppress_filters' => true
753
+ );
754
+ $jobs = get_posts( $args );
755
+ $logger->log_info(__METHOD__,'Jobs found:' . count($jobs));
756
+
757
+ if (is_array($jobs) && count($jobs)>0) {
758
+ return $jobs;
759
+ }
760
+
761
+ $logger->log_info(__METHOD__,'No jobs found:' . $job_name);
762
+ $logger->log_info(__METHOD__,'End');
763
+ return false;
764
+ }
765
+
766
+ /**
767
+ * Cancel all queued or active jobs by job_name
768
+ *
769
+ * @param $job_name
770
+ *
771
+ * @return bool
772
+ */
773
+ public static function cancel_all_jobs($job_name) {
774
+ $logger = new WPBackItUp_Logger(false,null,'debug_job');
775
+ $logger->log_info(__METHOD__,'Begin - Cancel all jobs:'.$job_name);
776
+
777
+ while (self::is_job_queued($job_name)){
778
+ $job = self::get_current_job($job_name);
779
+ if (false!== $job) {
780
+ $job->set_job_status_cancelled();
781
+ $logger->log_info(__METHOD__,'Job Cancelled:' . $job->get_job_id());
782
+ }
783
+ }
784
+
785
+ $logger->log_info(__METHOD__,'End - All jobs cancelled');
786
+ }
787
+
788
+ /**
789
+ * purge completed jobs
790
+ * - complete, cancelled, error
791
+ *
792
+ * @param $job_name *
793
+ *
794
+ * @param int $dont_purge - dont purge this many
795
+ *
796
+ * @return int
797
+ * @internal param int $count
798
+ */
799
+ public static function purge_completed_jobs($job_name,$dont_purge=10) {
800
+ $logger = new WPBackItUp_Logger(false,null,'debug_job');
801
+ $logger->log_info(__METHOD__,'Begin - Purge Jobs.');
802
+
803
+ $jobs_purged=0;
804
+ $jobs = self::get_completed_jobs($job_name);
805
+ if ($jobs){
806
+ $job_count = count($jobs);
807
+
808
+ //if ALL delete them all
809
+ if ($dont_purge=='ALL'){
810
+ $start=0;
811
+ }else{
812
+ $start=$dont_purge;
813
+ }
814
+
815
+ $purge_count=$job_count-$dont_purge;
816
+ $logger->log_info(__METHOD__,'Jobs to be purged:' .$purge_count);
817
+ //Leave the last n and purge the remaining
818
+ for ($i = $start; $i < $job_count; $i++) {
819
+ $job= $jobs[$i];
820
+ $logger->log_info(__METHOD__,'Delete Job:'.$i .':' .$job->ID .':' .$job->post_name .':' .$job->post_type .":" .$job->post_title .':' .$job->post_date);
821
+
822
+ //delete job records
823
+ $job_id=$job->post_name;
824
+ $db = new WPBackItUp_DataAccess();
825
+
826
+ if ($db->delete_job_records($job_id)){
827
+ $logger->log_error(__METHOD__,'Job records purged.');
828
+ }else {
829
+ $logger->log_error(__METHOD__,'Job records NOT purged.');
830
+ }
831
+
832
+ wp_delete_post( $job->ID, true );
833
+ $jobs_purged+=1;
834
+ }
835
+ }
836
+ $logger->log_info(__METHOD__,'End - job purge complete:' .$jobs_purged);
837
+ return $jobs_purged;
838
+ }
839
+
840
+ /**
841
+ * Gets the queued or active job on top of the stack
842
+ * - set status to active
843
+ *
844
+ * @param $job_name
845
+ *
846
+ * @return bool|WPBackItUp_Job
847
+ */
848
+ public static function get_current_job($job_name) {
849
+ $logger = new WPBackItUp_Logger(false,null,'debug_job');
850
+ $logger->log_info(__METHOD__,'Begin - Job Name: ' .$job_name);
851
+
852
+ //Get backup on top
853
+ $args = array(
854
+ 'posts_per_page' => 1,
855
+ 'post_type' => $job_name,
856
+ 'post_status' => array(self::QUEUED,self::ACTIVE),
857
+ 'orderby' => 'post_date',
858
+ 'order' => 'ASC',
859
+ );
860
+ $jobs = get_posts( $args );
861
+ $logger->log($jobs);
862
+
863
+ if (is_array($jobs) && count($jobs)>0) {
864
+ $logger->log_info(__METHOD__,'Job found:' . count($jobs));
865
+
866
+ $backup_job = new WPBackItUp_Job_v2($jobs[0]);
867
+ if (self::QUEUED==$backup_job->job_status){
868
+ $backup_job->set_job_status_active();
869
+ }
870
+ return $backup_job;
871
+ }
872
+
873
+ $logger->log_info(__METHOD__,'No jobs found.');
874
+ $logger->log_info(__METHOD__,'End');
875
+ return false;
876
+ }
877
+
878
+ /**
879
+ * Gets a job by id
880
+ *
881
+ * @param $id
882
+ *
883
+ * @return bool|WPBackItUp_Job
884
+ */
885
+ public static function get_job_by_id($id) {
886
+ $logger = new WPBackItUp_Logger(false,null,'debug_job');
887
+ $logger->log_info(__METHOD__,'Begin');
888
+
889
+ $job = get_post( $id, 'OBJECT');
890
+ $logger->log($job);
891
+
892
+ if (null!=$job) {
893
+ $logger->log_info(__METHOD__,'Job found:' .$id);
894
+ return new WPBackItUp_Job_v2($job);
895
+ }
896
+
897
+ $logger->log_info(__METHOD__,'No job found with id.' . $id);
898
+ $logger->log_info(__METHOD__,'End');
899
+ return false;
900
+ }
901
+
902
+ /**
903
+ * Queue a job
904
+ *
905
+ * @param $job_name
906
+ *
907
+ * @param $tasks
908
+ *
909
+ * @param null $job_info
910
+ *
911
+ * @return bool|WPBackItUp_Job
912
+ */
913
+ public static function queue_job($job_name,$tasks,$job_info=null){
914
+ $logger = new WPBackItUp_Logger(false,null,'debug_job');
915
+ $logger->log_info(__METHOD__,'Begin - Job:'. $job_name);
916
+
917
+ $new_job = array(
918
+ 'post_title' => self::JOB_TITLE,
919
+ 'post_name' => time(),
920
+ 'post_status' => self::QUEUED,
921
+ 'post_type' => $job_name
922
+ );
923
+
924
+ // Insert the post into the database
925
+ $job_id = wp_insert_post($new_job );
926
+ $logger->log_info(__METHOD__,'Job Created:' .$job_id);
927
+
928
+ //Add job info is available
929
+ if (null!= $job_info){
930
+ update_post_meta($job_id, 'job_info',$job_info);
931
+ }
932
+
933
+ //add the tasks
934
+ if ( false === self::create_tasks( $job_id,$tasks ) ) {
935
+ $logger->log_info( __METHOD__, 'Job tasks not Created - deleting job:' . $job_id );
936
+ wp_delete_post( $job_id, true );
937
+ return false;
938
+ }
939
+
940
+ $logger->log_info(__METHOD__,'End');
941
+ return self::get_job_by_id($job_id);
942
+ }
943
+
944
+ /**
945
+ * Create all the tasks for a job
946
+ *
947
+ * @param $job_id
948
+ *
949
+ * @param $tasks
950
+ *
951
+ * @return bool
952
+ */
953
+ private static function create_tasks($job_id, $tasks){
954
+ $logger = new WPBackItUp_Logger(false,null,'debug_job');
955
+ $logger->log_info(__METHOD__,'Begin');
956
+
957
+ //Create the job tasks
958
+ $last_updated_time=time();
959
+ foreach ($tasks as $key => $value){
960
+ $task_name = $value;
961
+ $task_data = array(
962
+ 'task_id' => $task_name,
963
+ 'task_status' => self::QUEUED,
964
+ 'task_allocated_id'=>'',
965
+ 'task_last_updated'=>$last_updated_time
966
+ );
967
+ $task_created = update_post_meta( $job_id, $task_name, $task_data );
968
+
969
+ if (false===$task_created){
970
+ $logger->log_error( __METHOD__, 'Tasks NOT created');
971
+ return false;
972
+ }
973
+ $logger->log_info( __METHOD__, 'task created:' . $task_created .':'. $task_name);
974
+ }
975
+
976
+ $logger->log_info(__METHOD__,'End');
977
+ return true;
978
+
979
+ }
980
+
981
+ /**
982
+ * @return mixed
983
+ */
984
+ public function get_job_start_time() {
985
+ return $this->job_start_time;
986
+ }
987
+
988
+ /**
989
+ * @return mixed
990
+ */
991
+ public function get_job_end_time() {
992
+ return $this->job_end_time;
993
+ }
994
+
995
+ /**
996
+ * Get Job status
997
+ * @return mixed
998
+ */
999
+ public function get_job_status() {
1000
+ return $this->job_status;
1001
+ }
1002
+
1003
+ /**
1004
+ * Get job id
1005
+ * @return mixed
1006
+ */
1007
+ public function get_job_id() {
1008
+ return $this->job_id;
1009
+ }
1010
+
1011
+ /**
1012
+ * @return int
1013
+ */
1014
+ public function getInstanceId() {
1015
+ return $this->instance_id;
1016
+ }
1017
+
1018
+ /**
1019
+ * Get job info
1020
+
1021
+ * @param null $key
1022
+ *
1023
+ * @return array returns array if key not passed and value if key passed
1024
+ * If key doesnt exists then null will be returned
1025
+ */
1026
+ public function getJobInfo($key=null) {
1027
+ $job_info = $this->job_info;
1028
+
1029
+ if (null!=$key ){
1030
+ if (array_key_exists($key,$job_info) ){
1031
+ return $job_info[$key];
1032
+ }else{
1033
+ return null;
1034
+ }
1035
+ }else{
1036
+ return $job_info;
1037
+ }
1038
+ }
1039
+ }
1040
+
lib/includes/class-job.php CHANGED
@@ -19,8 +19,16 @@ class WPBackItUp_Job {
19
 
20
  const JOB_TITLE='wpbackitup_job';
21
 
 
 
 
 
 
 
 
22
  private $logger;
23
  private $job_id;
 
24
  private $allocated_task;
25
 
26
  public $job_status;
@@ -29,6 +37,10 @@ class WPBackItUp_Job {
29
  private $job_start_time;
30
  private $job_end_time;
31
 
 
 
 
 
32
  static private $backup_tasks = array(
33
  1=>'task_preparing',
34
  2=>'task_backup_db' ,
@@ -55,12 +67,20 @@ class WPBackItUp_Job {
55
  1=>'task_scheduled_cleanup'
56
  );
57
 
 
 
 
 
 
 
 
58
  function __construct($job) {
59
  try {
60
  $this->logger = new WPBackItUp_Logger(false,null,'debug_job');
61
 
62
  //Load of the class properties from the post object(see wp_post)
63
  $this->job_id=$job->ID;
 
64
  $this->job_status=$job->post_status;
65
  $this->backup_id=$job->post_name;
66
 
@@ -79,7 +99,58 @@ class WPBackItUp_Job {
79
  }
80
 
81
  function __destruct() {
 
 
 
 
 
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  }
84
 
85
  public function is_job_complete() {
@@ -137,6 +208,11 @@ class WPBackItUp_Job {
137
  case "queued":
138
  //Try allocate task
139
  $queued_task = $this->allocate_task($this->job_id, $key,$task_id);
 
 
 
 
 
140
  return $queued_task[0]['task_id'];
141
 
142
  case "active":
@@ -171,7 +247,7 @@ class WPBackItUp_Job {
171
  $this->set_job_status_complete();
172
 
173
  $this->logger->log_info(__METHOD__,'End - no tasks to allocate');
174
- return false; //no tasks to allocate
175
  }
176
 
177
  /**
@@ -302,6 +378,11 @@ class WPBackItUp_Job {
302
  * @return string|array Slashed $value
303
  */
304
  private function wpb_slash( $value ) {
 
 
 
 
 
305
  //only available 3.6 or later
306
  if (function_exists('wp_slash')) return wp_slash($value);
307
 
@@ -310,7 +391,7 @@ class WPBackItUp_Job {
310
  if ( is_array( $v ) ) {
311
  $value[$k] = $this->wpb_slash( $v );
312
  } else {
313
- $value[$k] = addslashes( $v );
314
  }
315
  }
316
  } else {
@@ -331,8 +412,7 @@ class WPBackItUp_Job {
331
  * @param string|array $value String or array of strings to unslash.
332
  * @return string|array Unslashed $value
333
  */
334
- function wpb_
335
- ( $value ) {
336
  return stripslashes_deep( $value );
337
  }
338
 
@@ -354,7 +434,7 @@ class WPBackItUp_Job {
354
  * Set job status to active
355
  */
356
  public function set_job_status_active( ) {
357
- $status='active';
358
  if ($this->update_job_status($status)){
359
  $this->job_status = $status;
360
  }
@@ -367,7 +447,7 @@ class WPBackItUp_Job {
367
  * Set job status to error
368
  */
369
  public function set_job_status_error( ) {
370
- $status='error';
371
  if ($this->update_job_status($status)){
372
  $this->job_status = $status;
373
  }
@@ -380,7 +460,7 @@ class WPBackItUp_Job {
380
  * Set job status to complete
381
  */
382
  public function set_job_status_complete( ) {
383
- $status='complete';
384
 
385
  if ($this->update_job_status($status)){
386
  $this->job_status = $status;
@@ -394,7 +474,7 @@ class WPBackItUp_Job {
394
  * Set job status to cancelled
395
  */
396
  public function set_job_status_cancelled( ) {
397
- $status='cancelled';
398
 
399
  if ($this->update_job_status($status)){
400
  $this->job_status = $status;
@@ -586,7 +666,7 @@ class WPBackItUp_Job {
586
  $backup_job = self::get_job('backup');
587
  if (false!== $backup_job) {
588
  $backup_job->set_job_status_cancelled();
589
- $logger->log_info(__METHOD__,'Backup job Cancelled:' . $backup_job->job_id);
590
  }
591
  }
592
 
@@ -594,7 +674,7 @@ class WPBackItUp_Job {
594
  $cleanup_job = self::get_job('cleanup');
595
  if (false!== $cleanup_job) {
596
  $cleanup_job->set_job_status_cancelled();
597
- $logger->log_info(__METHOD__,'Cleanup job Cancelled:' . $cleanup_job->job_id);
598
  }
599
  }
600
 
@@ -650,7 +730,7 @@ class WPBackItUp_Job {
650
  $logger->log_info(__METHOD__,'Job found:' . count($jobs));
651
 
652
  $backup_job = new WPBackItUp_Job($jobs[0]);
653
- if ('queued'==$backup_job->job_status){
654
  $backup_job->set_job_status_active();
655
  }
656
  return $backup_job;
@@ -737,6 +817,15 @@ class WPBackItUp_Job {
737
  }
738
  break;
739
 
 
 
 
 
 
 
 
 
 
740
  default://Job type not defined
741
  $logger->log_info( __METHOD__, 'Job type not defined - deleting job:' . $job_name );
742
  wp_delete_post( $job_id, true );
@@ -805,5 +894,20 @@ class WPBackItUp_Job {
805
  public function get_job_status() {
806
  return $this->job_status;
807
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
808
  }
809
 
19
 
20
  const JOB_TITLE='wpbackitup_job';
21
 
22
+ //job Status values
23
+ const ERROR = 'error';
24
+ const ACTIVE ='Active';
25
+ const COMPLETE ='complete';
26
+ const CANCELLED='cancelled';
27
+ const QUEUED = 'queued';
28
+
29
  private $logger;
30
  private $job_id;
31
+ private $instance_id;
32
  private $allocated_task;
33
 
34
  public $job_status;
37
  private $job_start_time;
38
  private $job_end_time;
39
 
40
+ private $lockFile;
41
+ private $lockFilePath;
42
+ private $locked;
43
+
44
  static private $backup_tasks = array(
45
  1=>'task_preparing',
46
  2=>'task_backup_db' ,
67
  1=>'task_scheduled_cleanup'
68
  );
69
 
70
+ static private $cloud_upload_tasks = array(
71
+ 1=>'task_validate_cloud_credentials',
72
+ 2=>'task_upload_files_to_cloud',
73
+ 3=>'task_update_backup_status'
74
+ );
75
+
76
+
77
  function __construct($job) {
78
  try {
79
  $this->logger = new WPBackItUp_Logger(false,null,'debug_job');
80
 
81
  //Load of the class properties from the post object(see wp_post)
82
  $this->job_id=$job->ID;
83
+ $this->instance_id=time();
84
  $this->job_status=$job->post_status;
85
  $this->backup_id=$job->post_name;
86
 
99
  }
100
 
101
  function __destruct() {
102
+ $this->logger->log_info( __METHOD__,'Begin');
103
+ if ($this->locked) {
104
+ $this->release_lock();
105
+ }
106
+ }
107
 
108
+ /**
109
+ * Get lock of possible
110
+ *
111
+ * @param $lock_file_path
112
+ *
113
+ * @return bool
114
+ */
115
+ public function get_lock ($lock_file_path){
116
+ $this->logger->log_info( __METHOD__,'Begin:'.$lock_file_path);
117
+
118
+ $this->$lock_file_path = $lock_file_path;
119
+ try {
120
+ $this->lockFile = fopen($this->$lock_file_path ,"w"); // open it for WRITING ("w")
121
+ if (flock( $this->lockFile, LOCK_EX | LOCK_NB)) {
122
+ $this->logger->log_info( __METHOD__,'Process LOCK acquired');
123
+ $this->locked=true;
124
+ } else {
125
+ //This is not an error, just means another process has it allocated
126
+ $this->logger->log_info( __METHOD__,'Process LOCK Failed');
127
+ $this->locked=false;
128
+ }
129
+
130
+ return $this->locked;
131
+
132
+ } catch(Exception $e) {
133
+ $this->logger->log_error( __METHOD__,'Process Lock error: ' .$e);
134
+ $this->locked=false;
135
+ return $this->locked;
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Release lock
141
+ *
142
+ * @return bool
143
+ */
144
+ public function release_lock (){
145
+ $this->logger->log_info( __METHOD__,'Begin');
146
+
147
+ try{
148
+ flock($this->lockFile, LOCK_UN); // unlock the file
149
+ $this->logger->log_info( __METHOD__,'Lock released');
150
+ $this->locked=false;
151
+ }catch(Exception $e) {
152
+ $this->logger->log_error( __METHOD__,'Process UNLOCK error: ' .$e);
153
+ }
154
  }
155
 
156
  public function is_job_complete() {
208
  case "queued":
209
  //Try allocate task
210
  $queued_task = $this->allocate_task($this->job_id, $key,$task_id);
211
+
212
+ //If task was allocated then update the job status to active
213
+ if (false!==$queued_task){
214
+ $this->set_job_status_active();
215
+ }
216
  return $queued_task[0]['task_id'];
217
 
218
  case "active":
247
  $this->set_job_status_complete();
248
 
249
  $this->logger->log_info(__METHOD__,'End - no tasks to allocate');
250
+ return false; //no tasks to allocate now but job should be complete next time
251
  }
252
 
253
  /**
378
  * @return string|array Slashed $value
379
  */
380
  private function wpb_slash( $value ) {
381
+ //only use on strings and arrays
382
+ if(! is_array($value) && ! is_string($value)){
383
+ return $value;
384
+ }
385
+
386
  //only available 3.6 or later
387
  if (function_exists('wp_slash')) return wp_slash($value);
388
 
391
  if ( is_array( $v ) ) {
392
  $value[$k] = $this->wpb_slash( $v );
393
  } else {
394
+ $value[ $k ] = addslashes( $v );
395
  }
396
  }
397
  } else {
412
  * @param string|array $value String or array of strings to unslash.
413
  * @return string|array Unslashed $value
414
  */
415
+ function wpb_unslash( $value ) {
 
416
  return stripslashes_deep( $value );
417
  }
418
 
434
  * Set job status to active
435
  */
436
  public function set_job_status_active( ) {
437
+ $status=self::ACTIVE;
438
  if ($this->update_job_status($status)){
439
  $this->job_status = $status;
440
  }
447
  * Set job status to error
448
  */
449
  public function set_job_status_error( ) {
450
+ $status=self::ERROR;
451
  if ($this->update_job_status($status)){
452
  $this->job_status = $status;
453
  }
460
  * Set job status to complete
461
  */
462
  public function set_job_status_complete( ) {
463
+ $status=self::COMPLETE;
464
 
465
  if ($this->update_job_status($status)){
466
  $this->job_status = $status;
474
  * Set job status to cancelled
475
  */
476
  public function set_job_status_cancelled( ) {
477
+ $status=self::CANCELLED;
478
 
479
  if ($this->update_job_status($status)){
480
  $this->job_status = $status;
666
  $backup_job = self::get_job('backup');
667
  if (false!== $backup_job) {
668
  $backup_job->set_job_status_cancelled();
669
+ $logger->log_info(__METHOD__,'Backup job Cancelled:' . $backup_job->get_job_id());
670
  }
671
  }
672
 
674
  $cleanup_job = self::get_job('cleanup');
675
  if (false!== $cleanup_job) {
676
  $cleanup_job->set_job_status_cancelled();
677
+ $logger->log_info(__METHOD__,'Cleanup job Cancelled:' . $cleanup_job->get_job_id());
678
  }
679
  }
680
 
730
  $logger->log_info(__METHOD__,'Job found:' . count($jobs));
731
 
732
  $backup_job = new WPBackItUp_Job($jobs[0]);
733
+ if (self::QUEUED==$backup_job->job_status){
734
  $backup_job->set_job_status_active();
735
  }
736
  return $backup_job;
817
  }
818
  break;
819
 
820
+ case "cloud_upload":
821
+ //add the tasks
822
+ if ( false === self::create_tasks( $job_id,self::$cloud_upload_tasks ) ) {
823
+ $logger->log_info( __METHOD__, 'Cloud upload tasks not Created - deleting job:' . $job_id );
824
+ wp_delete_post( $job_id, true );
825
+ return false;
826
+ }
827
+ break;
828
+
829
  default://Job type not defined
830
  $logger->log_info( __METHOD__, 'Job type not defined - deleting job:' . $job_name );
831
  wp_delete_post( $job_id, true );
894
  public function get_job_status() {
895
  return $this->job_status;
896
  }
897
+
898
+ /**
899
+ * Get job id
900
+ * @return mixed
901
+ */
902
+ public function get_job_id() {
903
+ return $this->job_id;
904
+ }
905
+
906
+ /**
907
+ * @return int
908
+ */
909
+ public function getInstanceId() {
910
+ return $this->instance_id;
911
+ }
912
  }
913
 
lib/includes/class-logger.php CHANGED
@@ -216,4 +216,22 @@ class WPBackItUp_Logger {
216
  print $e;
217
  }
218
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  }
216
  print $e;
217
  }
218
  }
219
+
220
+ function log_memory_info(){
221
+ try{
222
+
223
+ $memory_usage = memory_get_usage();
224
+ $memory_peak_usage = memory_get_peak_usage();
225
+ $memory_limit=ini_get('memory_limit');
226
+
227
+ $this->log("\n**MEMORY USAGE INFO**");
228
+ $this->log('Memory in use: ' . $memory_usage . ' ('. $memory_usage/1024/1024 .' Mb)');
229
+ $this->log('Peak usage: ' . $memory_peak_usage . ' ('. $memory_peak_usage/1024/1024 .' Mb)');
230
+ $this->log('Memory limit: ' . $memory_limit . ' ('. $memory_limit/1024/1024 .' Mb)');
231
+ $this->log("\n**END MEMORY USAGE INFO**");
232
+ } catch(Exception $e) {
233
+ //Dont do anything
234
+ //print $e;
235
+ }
236
+ }
237
  }
lib/includes/class-mutex.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBackItUp_Mutex {
4
+ var $writeablePath = '';
5
+ var $lockName = '';
6
+ var $fileHandle = null;
7
+
8
+ public function __construct($lockName, $writeablePath = null){
9
+ $this->lockName = preg_replace('/[^a-zA-Z0-9]/', '', $lockName);
10
+ if($writeablePath == null){
11
+ $this->writeablePath = $this->findWriteablePath();
12
+ } else {
13
+ $this->writeablePath = $writeablePath;
14
+ }
15
+ }
16
+
17
+ function __destruct() {
18
+ if (null!=$this->fileHandle){
19
+ $this->releaseLock();
20
+ }
21
+ }
22
+
23
+ public function lock($wait = false, $maxTime = 10){
24
+ $locked = false;
25
+ $timeAsleep = 0;
26
+ do{
27
+ $locked = $this->attemptLock();
28
+ if(!$locked && $wait){
29
+ sleep(1);
30
+ $timeAsleep +=1;
31
+ }
32
+ } while(!$locked && $wait && $timeAsleep <= $maxTime);
33
+
34
+ return $locked;
35
+ }
36
+
37
+ private function attemptLock(){
38
+ if (PHP_OS == 'WINNT'){
39
+ $lockFilePath = $this->getLockFilePath();
40
+ if(file_exists($lockFilePath)){
41
+ $unlinked = @unlink($lockFilePath);
42
+ if(!$unlinked) return false;
43
+
44
+ }
45
+ }
46
+
47
+ $fileHandle = $this->getFileHandle();
48
+ if(!$fileHandle){
49
+ return false;
50
+ } else {
51
+ return true;
52
+ }
53
+ }
54
+
55
+ public function getFileHandle(){
56
+ if(!$this->fileHandle){
57
+ $this->fileHandle = @fopen($this->getLockFilePath(), 'a+');
58
+ if($this->fileHandle){
59
+ if (PHP_OS == 'WINNT'){
60
+ fwrite($this->fileHandle, "A");
61
+ if(flock($this->fileHandle, LOCK_SH)){
62
+ rewind($this->fileHandle);
63
+ $contents = fread($this->fileHandle, 2);
64
+ if($contents != 'A'){
65
+ flock($this->fileHandle, LOCK_UN);
66
+ fclose($this->fileHandle);
67
+ $this->fileHandle = null;
68
+ return false;
69
+ }
70
+ } else {
71
+ fclose($this->fileHandle);
72
+ return false;
73
+ }
74
+ } else {
75
+ if(flock($this->fileHandle, LOCK_EX | LOCK_NB)){
76
+
77
+ } else {
78
+ fclose($this->fileHandle);
79
+ return false;
80
+ }
81
+ }
82
+
83
+ }
84
+ }
85
+ return $this->fileHandle;
86
+ }
87
+
88
+ public function releaseLock(){
89
+ flock($this->fileHandle, LOCK_UN);
90
+ $success = fclose($this->getFileHandle());
91
+ unlink($this->getLockFilePath());
92
+ $this->fileHandle = null;
93
+ return $success;
94
+ }
95
+
96
+ public function getLockFilePath(){
97
+ return $this->writeablePath . DIRECTORY_SEPARATOR . $this->lockName . '.lock';
98
+ }
99
+
100
+ public function isLocked(){
101
+ $lock = $this->attemptLock();
102
+
103
+ if($lock){
104
+ $this->releaseLock();
105
+ return false;
106
+ }else{
107
+ return true;
108
+ }
109
+ }
110
+
111
+ public function findWriteablePath(){
112
+ $foundPath = false;
113
+
114
+ //First try the temp directory...
115
+ $path = $this->getTempDirPath();
116
+ $fileName = $path . DIRECTORY_SEPARATOR . 'test_file';
117
+ if($fileHandle = fopen($fileName, "w")){
118
+ fclose($fileHandle);
119
+ $foundPath = true;
120
+ }
121
+
122
+
123
+ //Now try the current directory
124
+ if(!$foundPath){
125
+ $path = '.';
126
+ if($fileHandle = fopen($path . DIRECTORY_SEPARATOR . 'test_file', "w")){
127
+ fclose($fileHandle);
128
+ $this->writeablePath = $path;
129
+ }
130
+ }
131
+
132
+ if(!$foundPath){
133
+ throw new Exception("Cannot establish lock on temporary file.");
134
+ }
135
+
136
+ return $path;
137
+ }
138
+
139
+ public function getTempDirPath(){
140
+ $fileName = tempnam("/tmp", "MUT");
141
+ $path = dirname($fileName);
142
+ if ($path == '/') $path = '/tmp';
143
+ return $path;
144
+ }
145
+ }
lib/includes/class-restore.php CHANGED
@@ -897,6 +897,19 @@ class WPBackItUp_Restore {
897
  return true;
898
  }
899
 
 
 
 
 
 
 
 
 
 
 
 
 
 
900
  function update_permalinks(){
901
  global $wp_rewrite;
902
  $this->logger->log_info(__METHOD__,'Begin');
897
  return true;
898
  }
899
 
900
+ function update_license_key($table_prefix, $license_key){
901
+ $this->logger->log_info(__METHOD__,'Begin');
902
+
903
+ $sql = "UPDATE ". $table_prefix ."options SET option_value='" .$license_key ."' WHERE option_name='wp-backitup_license_key'";
904
+ $dbc = new WPBackItUp_SQL($this->logger);
905
+ if (!$dbc->run_sql_command($sql)){
906
+ $this->logger->log(__METHOD__,'License Key database update failed..');
907
+ return false;
908
+ }
909
+ $this->logger->log_info(__METHOD__,'End - License Key updated in database:'.$license_key);
910
+ return true;
911
+ }
912
+
913
  function update_permalinks(){
914
  global $wp_rewrite;
915
  $this->logger->log_info(__METHOD__,'Begin');
lib/includes/class-sql.php CHANGED
@@ -31,77 +31,97 @@ class WPBackItUp_SQL {
31
  }
32
 
33
  public function mysqldump_export($sql_file_path,$with_mysqlpath=false) {
 
 
34
 
35
- $this->logger->log('(SQL.mysqldump_export) Export Database to: ' .$sql_file_path);
 
 
 
 
36
 
37
- $db_name = DB_NAME;
38
- $db_user = DB_USER;
39
- $db_pass = DB_PASSWORD;
40
- $db_host = $this->get_hostonly(DB_HOST);
41
- $db_port = $this->get_portonly(DB_HOST);
42
-
43
- //This is to ensure that exec() is enabled on the server
44
- if(exec('echo EXEC') == 'EXEC') {
45
- try {
46
- $mysql_path='';
47
- if ($with_mysqlpath) {
48
- $mysql_path = $this->get_mysql_path();
49
- if ($mysql_path===false) return false;
50
- }
51
 
52
- $process = $mysql_path .'mysqldump';
53
- $command = $process
54
- . ' --host=' . $db_host;
55
-
56
- //Check for port
57
- if (false!==$db_port){
58
- $command .=' --port=' . $db_port;
59
- }
60
-
61
- $command .=
62
- ' --user=' . $db_user
63
- . ' --password=' . $db_pass
64
- .=' ' . $db_name
65
- . ' > "' . $sql_file_path .'"';
66
-
67
- if (WPBACKITUP__DEBUG) {
68
- $this->logger->log('(SQL.db_SQLDump)Execute command:' . $command);
69
- }
 
 
 
 
 
 
 
70
 
71
- exec($command,$output,$rtn_var);
72
- $this->logger->log('(SQL.mysqldump_export)Execute output:');
73
- $this->logger->log($output);
74
- $this->logger->log('Return Value:' .$rtn_var);
75
-
76
- //0 is success
77
- if ($rtn_var>0){
78
- $this->logger->log('(SQL.mysqldump_export) EXPORT FAILED return Value:' .$rtn_var);
79
- return false;
80
- }
81
-
82
- //Did the export work
83
- clearstatcache();
84
- if (!file_exists($sql_file_path) || filesize($sql_file_path)<=0) {
85
- $this->logger->log('(SQL.mysqldump_export) EXPORT FAILED: Dump was empty or missing.');
86
- return false;
87
- }
88
- } catch(Exception $e) {
89
- $this->logger->log('(SQL.mysqldump_export) EXPORT FAILED Exception: ' .$e);
90
- return false;
91
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  }
93
- else
94
- {
95
- $this->logger->log('(SQL.mysqldump_export) EXPORT FAILED Exec() disabled.');
96
- return false;
97
- }
 
98
 
99
- $this->logger->log('(SQL.mysqldump_export) SQL Dump SUCCESS.');
100
- return true;
101
  }
102
 
103
 
104
  public function manual_export($sql_file_path) {
 
105
  $this->logger->log_info(__METHOD__,'Manually Create SQL Backup File:'.$sql_file_path);
106
 
107
  $mysqli = $this->connection;
@@ -112,6 +132,14 @@ class WPBackItUp_SQL {
112
  return false;
113
  }
114
 
 
 
 
 
 
 
 
 
115
  // Script Header Information
116
  $return = '';
117
  $return .= "-- ------------------------------------------------------\n";
@@ -133,10 +161,16 @@ class WPBackItUp_SQL {
133
  $return .= '/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;' ."\n" ;
134
  $return .= '/*!40101 SET NAMES utf8 */;' ."\n" ;
135
 
 
 
136
  $tables = array() ;
137
 
138
- // Exploring what tables this database has
139
- $result = $mysqli->query('SHOW TABLES' ) ;
 
 
 
 
140
 
141
  // Cycle through "$result" and put content into an array
142
  while ($row = $result->fetch_row()) {
@@ -147,6 +181,11 @@ class WPBackItUp_SQL {
147
  foreach($tables as $table) {
148
  $this->logger->log($table);
149
 
 
 
 
 
 
150
  // Get content of each table
151
  $result = $mysqli->query('SELECT * FROM '. $table) ;
152
 
@@ -154,10 +193,10 @@ class WPBackItUp_SQL {
154
  $num_fields = $mysqli->field_count ;
155
 
156
  // Add table information
157
- $return .= "--\n" ;
158
  $return .= '-- Table structure for table `' . $table . '`' . "\n" ;
159
  $return .= "--\n" ;
160
- $return.= 'DROP TABLE IF EXISTS `'.$table.'`;' . "\n" ;
161
 
162
  // Get the table-shema
163
  $shema = $mysqli->query('SHOW CREATE TABLE '.$table) ;
@@ -166,12 +205,14 @@ class WPBackItUp_SQL {
166
  $tableshema = $shema->fetch_row() ;
167
 
168
  // Append table-shema into code
169
- $return.= $tableshema[1].";" . "\n\n" ;
170
-
 
 
171
  // Cycle through each table-row
172
  while($rowdata = $result->fetch_row()) {
173
 
174
- $return.= 'INSERT INTO '.$table.' VALUES(';
175
  for($j=0; $j<$num_fields; $j++){
176
  $rowdata[$j] = addslashes($rowdata[$j]);
177
  $rowdata[$j] = str_replace("\n","\\n",$rowdata[$j]);
@@ -189,8 +230,12 @@ class WPBackItUp_SQL {
189
  if ($j<($num_fields-1)) { $return.= ','; }
190
  }
191
  $return.= ");\n";
192
- }
193
- $return .= "\n\n" ;
 
 
 
 
194
  }
195
 
196
  $return .= 'SET FOREIGN_KEY_CHECKS = 1 ; ' . "\n" ;
@@ -198,9 +243,10 @@ class WPBackItUp_SQL {
198
  $return .= 'SET AUTOCOMMIT = 1 ; ' . "\n" ;
199
 
200
  //save file
201
- $handle = fopen($sql_file_path,'w+');
202
  fwrite($handle,$return);
203
  fclose($handle);
 
204
  clearstatcache();
205
 
206
  //Did the export work
@@ -258,7 +304,8 @@ class WPBackItUp_SQL {
258
  . ' --execute="SOURCE ' . $sql_file .'"';
259
 
260
  if (WPBACKITUP__DEBUG) {
261
- $this->logger->log( '(SQL.db_run_sql)Execute command:' . $command );
 
262
  }
263
 
264
  //$output = shell_exec($command);
31
  }
32
 
33
  public function mysqldump_export($sql_file_path,$with_mysqlpath=false) {
34
+ global $wpdb;
35
+ $this->logger->log('(SQL.mysqldump_export) Export Database to: ' .$sql_file_path);
36
 
37
+ $db_name = DB_NAME;
38
+ $db_user = DB_USER;
39
+ $db_pass = DB_PASSWORD;
40
+ $db_host = $this->get_hostonly(DB_HOST);
41
+ $db_port = $this->get_portonly(DB_HOST);
42
 
43
+ //This is to ensure that exec() is enabled on the server
44
+ if(exec('echo EXEC') == 'EXEC') {
45
+ try {
46
+ $mysql_path='';
47
+ if ($with_mysqlpath) {
48
+ $mysql_path = $this->get_mysql_path();
49
+ if ($mysql_path===false) return false;
50
+ }
 
 
 
 
 
 
51
 
52
+ $process = $mysql_path .'mysqldump';
53
+ $command = $process
54
+ . ' --host=' . $db_host;
55
+
56
+ //Check for port
57
+ if (false!==$db_port){
58
+ $command .=' --port=' . $db_port;
59
+ }
60
+
61
+ //If multi-site install then just backup the tables for current install.
62
+ $tables='';
63
+ if (is_multisite()){
64
+ $sql = sprintf('SHOW TABLES like \'%s%%\' ',$wpdb->prefix);
65
+ $this->logger->log('tables:' . $sql);
66
+ $mysqli = $this->connection;
67
+ $result = $mysqli->query($sql);
68
+ // Cycle through "$result" and put content into an array
69
+ while ($row = $result->fetch_row()) {
70
+ $tables_list[] = $row[0] ;
71
+ }
72
+
73
+ if (is_array($tables_list)){
74
+ $tables = implode( " ", $tables_list);
75
+ }
76
+ }
77
 
78
+ $command .=
79
+ ' --user=' . $db_user
80
+ . ' --password=' . $db_pass
81
+ . ' ' . $db_name
82
+ . ' ' . $tables
83
+ . ' > "' . $sql_file_path .'"';
84
+
85
+ if (WPBACKITUP__DEBUG) {
86
+ $masked_command = str_replace(array($db_user,$db_pass),'XXXXXX',$command);
87
+ $this->logger->log('(SQL.db_SQLDump)Execute command:' . $masked_command);
 
 
 
 
 
 
 
 
 
 
88
  }
89
+
90
+ exec($command,$output,$rtn_var);
91
+ $this->logger->log('(SQL.mysqldump_export)Execute output:');
92
+ $this->logger->log($output);
93
+ $this->logger->log('Return Value:' .$rtn_var);
94
+
95
+ //0 is success
96
+ if ($rtn_var>0){
97
+ $this->logger->log('(SQL.mysqldump_export) EXPORT FAILED return Value:' .$rtn_var);
98
+ return false;
99
+ }
100
+
101
+ //Did the export work
102
+ clearstatcache();
103
+ if (!file_exists($sql_file_path) || filesize($sql_file_path)<=0) {
104
+ $this->logger->log('(SQL.mysqldump_export) EXPORT FAILED: Dump was empty or missing.');
105
+ return false;
106
+ }
107
+ } catch(Exception $e) {
108
+ $this->logger->log('(SQL.mysqldump_export) EXPORT FAILED Exception: ' .$e);
109
+ return false;
110
  }
111
+ }
112
+ else
113
+ {
114
+ $this->logger->log('(SQL.mysqldump_export) EXPORT FAILED Exec() disabled.');
115
+ return false;
116
+ }
117
 
118
+ $this->logger->log('(SQL.mysqldump_export) SQL Dump SUCCESS.');
119
+ return true;
120
  }
121
 
122
 
123
  public function manual_export($sql_file_path) {
124
+ global $wpdb;
125
  $this->logger->log_info(__METHOD__,'Manually Create SQL Backup File:'.$sql_file_path);
126
 
127
  $mysqli = $this->connection;
132
  return false;
133
  }
134
 
135
+ //open the SQL file
136
+ $handle = fopen($sql_file_path,'w+');
137
+ if (false===$handle) {
138
+ $this->logger->log_error(__METHOD__,'File could not be opened.');
139
+ return false;
140
+ }
141
+
142
+
143
  // Script Header Information
144
  $return = '';
145
  $return .= "-- ------------------------------------------------------\n";
161
  $return .= '/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;' ."\n" ;
162
  $return .= '/*!40101 SET NAMES utf8 */;' ."\n" ;
163
 
164
+ fwrite($handle,$return); //Write to file
165
+
166
  $tables = array() ;
167
 
168
+ //If multisite install then just backup the tables for current install.
169
+ $sql = 'SHOW TABLES';
170
+ if (is_multisite()){
171
+ $sql .= sprintf(' like \'%s%%\' ',$wpdb->prefix);
172
+ }
173
+ $result = $mysqli->query($sql);
174
 
175
  // Cycle through "$result" and put content into an array
176
  while ($row = $result->fetch_row()) {
181
  foreach($tables as $table) {
182
  $this->logger->log($table);
183
 
184
+ // //if multi site install then
185
+ // if (is_multisite()){
186
+ //
187
+ // }
188
+
189
  // Get content of each table
190
  $result = $mysqli->query('SELECT * FROM '. $table) ;
191
 
193
  $num_fields = $mysqli->field_count ;
194
 
195
  // Add table information
196
+ $return = "--\n" ;
197
  $return .= '-- Table structure for table `' . $table . '`' . "\n" ;
198
  $return .= "--\n" ;
199
+ $return .= 'DROP TABLE IF EXISTS `'.$table.'`;' . "\n" ;
200
 
201
  // Get the table-shema
202
  $shema = $mysqli->query('SHOW CREATE TABLE '.$table) ;
205
  $tableshema = $shema->fetch_row() ;
206
 
207
  // Append table-shema into code
208
+ $return.= $tableshema[1].";" . "\n\n" ;
209
+
210
+ fwrite($handle,$return); //Write to file
211
+
212
  // Cycle through each table-row
213
  while($rowdata = $result->fetch_row()) {
214
 
215
+ $return = 'INSERT INTO '.$table.' VALUES(';
216
  for($j=0; $j<$num_fields; $j++){
217
  $rowdata[$j] = addslashes($rowdata[$j]);
218
  $rowdata[$j] = str_replace("\n","\\n",$rowdata[$j]);
230
  if ($j<($num_fields-1)) { $return.= ','; }
231
  }
232
  $return.= ");\n";
233
+
234
+ fwrite($handle,$return); //Write to file
235
+ }
236
+
237
+ $return= "\n\n" ;
238
+ fwrite($handle,$return); //Write to file
239
  }
240
 
241
  $return .= 'SET FOREIGN_KEY_CHECKS = 1 ; ' . "\n" ;
243
  $return .= 'SET AUTOCOMMIT = 1 ; ' . "\n" ;
244
 
245
  //save file
246
+ //$handle = fopen($sql_file_path,'w+');
247
  fwrite($handle,$return);
248
  fclose($handle);
249
+
250
  clearstatcache();
251
 
252
  //Did the export work
304
  . ' --execute="SOURCE ' . $sql_file .'"';
305
 
306
  if (WPBACKITUP__DEBUG) {
307
+ $masked_command = str_replace(array($db_user,$db_pass),'XXXXXX',$command);
308
+ $this->logger->log( '(SQL.db_run_sql)Execute command:' . $masked_command );
309
  }
310
 
311
  //$output = shell_exec($command);
lib/includes/class-task.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined ('ABSPATH')) die('No direct access allowed');
2
+
3
+
4
+ class WPBackItUp_Task {
5
+
6
+ //Task Status values
7
+ const ERROR = 'error';
8
+ const ACTIVE ='active';
9
+ const COMPLETE ='complete';
10
+ const CANCELLED='cancelled';
11
+ const QUEUED = 'queued';
12
+ const RESUME = 'resume';
13
+
14
+
15
+ private $logger;
16
+
17
+ private $job_id;
18
+ private $name; //task name
19
+
20
+ private $id;
21
+ private $status;
22
+
23
+ private $allocated_id=null;
24
+ private $error_code=null;
25
+ private $last_updated=null;
26
+ private $retry_count=0;
27
+
28
+ public function __construct($job_id,$task_name,$task_info) {
29
+
30
+ if (empty($job_id) ||
31
+ empty($task_name) ||
32
+ empty($task_info['task_id']) ||
33
+ empty($task_info['task_status'])){
34
+
35
+ throw new exception('Cant create task object, missing parameter in constructor.' );
36
+ }
37
+
38
+ $this->logger = new WPBackItUp_Logger(false,null,'debug_restore_tasks');
39
+
40
+ //Task Key Info
41
+ $this->job_id=$job_id;
42
+ $this->name=$task_name;
43
+ $this->id = $task_info['task_id'];
44
+ $this->status = $task_info['task_status'];
45
+
46
+ if (! empty($task_info['task_allocated_id'])){
47
+ $this->allocated_id = $task_info['task_allocated_id'];
48
+ }
49
+
50
+ if (! empty($task_info['task_last_updated'])) {
51
+ $this->last_updated = $task_info['task_last_updated'];
52
+ }
53
+
54
+ if (! empty($task_info['task_retry_count'])) {
55
+ $this->retry_count = $task_info['task_retry_count'];
56
+ }
57
+ }
58
+
59
+ function __destruct() {
60
+
61
+ }
62
+
63
+
64
+ /**
65
+ * Increment the task retry count
66
+ */
67
+ public function increment_retry_count(){
68
+ $this->logger->log_info(__METHOD__,'Begin');
69
+
70
+ $this->retry_count++;
71
+ return $this->save();
72
+ }
73
+
74
+ /**
75
+ * Save the task info to the
76
+ *
77
+ * @return mixed
78
+ * Returns Returns true on success and false on failure.
79
+ * NOTE: If the meta_value(Task Info) passed to this function is the same as the value that is already in the database, this function returns false.
80
+ *
81
+ */
82
+ private function save(){
83
+ $this->logger->log_info(__METHOD__,'Begin');
84
+
85
+ $meta_value = array(
86
+ 'task_id' => $this->id,
87
+ 'task_status' => $this->status,
88
+ 'task_allocated_id' => $this->allocated_id,
89
+ 'task_error_code' => $this->error_code,
90
+ 'task_retry_count' => $this->retry_count,
91
+ 'task_last_updated' => time()
92
+ );
93
+ $this->logger->log_info(__METHOD__,'Task Info:' .var_export($meta_value,true));
94
+
95
+ $rtn_status =update_post_meta( $this->job_id, $this->name, $meta_value );
96
+ $this->logger->log_info(__METHOD__,'Task Saved:' .$rtn_status);
97
+ return $rtn_status;
98
+ }
99
+
100
+
101
+ /**
102
+ * @return mixed
103
+ */
104
+ public function getId() {
105
+ return $this->id;
106
+ }
107
+
108
+ /**
109
+ * @return mixed
110
+ */
111
+ public function getStatus() {
112
+ return $this->status;
113
+ }
114
+
115
+ /**
116
+ * @return mixed
117
+ */
118
+ public function getAllocatedId() {
119
+ return $this->allocated_id;
120
+ }
121
+
122
+ /**
123
+ * @return mixed
124
+ */
125
+ public function getLastUpdated() {
126
+ return $this->last_updated;
127
+ }
128
+
129
+ /**
130
+ * @return int
131
+ */
132
+ public function getRetryCount() {
133
+ return $this->retry_count;
134
+ }
135
+
136
+
137
+ }
138
+
139
+
140
+
lib/includes/class-utility.php CHANGED
@@ -53,6 +53,42 @@ class WPBackItUp_Utility {
53
 
54
  }
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  //Function for PHP version 5.2
57
  //Diff Approximation only
58
  function date_diff_days($date1,$date2 ){
@@ -84,6 +120,12 @@ class WPBackItUp_Utility {
84
 
85
  public static function encode_items(&$item, $key)
86
  {
 
 
 
 
 
 
87
  $item = utf8_encode($item);
88
  }
89
 
@@ -91,5 +133,37 @@ class WPBackItUp_Utility {
91
  {
92
  $item = utf8_decode($item);
93
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
95
 
53
 
54
  }
55
 
56
+ function send_email_v2($to,$subject,$message,$attachments=array(),$from_name=null,$from_email=null,$reply_email=null)
57
+ {
58
+ try {
59
+
60
+ if($to) {
61
+
62
+ if (empty($from_name)){
63
+ $from_name = 'WP BackItUp';
64
+ }
65
+
66
+ if (empty($from_email)){
67
+ $from_email = get_bloginfo( 'admin_email' );
68
+ }
69
+
70
+ $headers[] = 'Content-type: text/html';
71
+ $headers[] = 'From: '.$from_name .' <'. $from_email .'>';
72
+
73
+ if (null!=$reply_email) {
74
+ $headers[] = 'Reply-To: ' .$from_name .' <'. $reply_email .'>';
75
+ }
76
+
77
+ wp_mail($to, $subject, nl2br($message), $headers,$attachments);
78
+
79
+ $this->logger->log('(send_email)Headers:' .var_export($headers,true));
80
+ $this->logger->log('(send_email)EMail Sent from:' .$from_email);
81
+ $this->logger->log('(send_email)EMail Sent to:' .$to);
82
+ }
83
+
84
+ } catch(Exception $e) {
85
+ //Dont do anything
86
+ $this->logger->log('(send_email)Send Email Exception:'.$e);
87
+ }
88
+
89
+ }
90
+
91
+
92
  //Function for PHP version 5.2
93
  //Diff Approximation only
94
  function date_diff_days($date1,$date2 ){
120
 
121
  public static function encode_items(&$item, $key)
122
  {
123
+ //If not string convert to one.
124
+ //If this happens it could be an error on backup job.
125
+ if (!is_string($item)){
126
+ $item = var_export($item,true);
127
+ }
128
+
129
  $item = utf8_encode($item);
130
  }
131
 
133
  {
134
  $item = utf8_decode($item);
135
  }
136
+
137
+
138
+ /**
139
+ * Compare major and minor versions
140
+ *
141
+ * @param $version1
142
+ * @param $version2
143
+ *
144
+ * @return bool
145
+ */
146
+ public static function version_compare($version1, $version2) {
147
+ //Check major and minor versions only
148
+
149
+ $version1_array = explode('.', $version1);
150
+ $version2_array = explode('.', $version2);
151
+
152
+ if (! empty($version1_array[0]) && isset ($version1_array[0]) &&
153
+ ! empty($version2_array[0]) && isset ($version2_array[0]) &&
154
+ ! empty($version1_array[1]) && isset ($version1_array[1]) &&
155
+ ! empty($version2_array[1]) && isset ($version2_array[1]) ){
156
+
157
+ //If major or minor version is different
158
+ if ($version1_array[0] == $version2_array[0] &&
159
+ $version1_array[1] == $version2_array[1] ) {
160
+ return true;
161
+ }
162
+
163
+ }
164
+
165
+ return false;
166
+ }
167
+
168
  }
169
 
lib/includes/class-wpbackitup-admin.php CHANGED
@@ -16,6 +16,8 @@ class WPBackitup_Admin {
16
  public $friendly_name = WPBACKITUP__FRIENDLY_NAME;
17
  public $version = WPBACKITUP__VERSION;
18
 
 
 
19
  private static $instance = false;
20
 
21
  //Use Getters
@@ -80,7 +82,7 @@ class WPBackitup_Admin {
80
  * Instantiation construction
81
  *
82
  */
83
- private function __construct() {
84
  /**
85
  * Make this plugin available for translation.
86
  * Translations can be added to the /languages/ directory.
@@ -110,6 +112,9 @@ class WPBackitup_Admin {
110
  //Load all the resources
111
  add_action( 'admin_enqueue_scripts', array( &$this, 'load_resources' ) );
112
 
 
 
 
113
  //Load the backup action
114
  add_action('wp_ajax_wp-backitup_backup', array( &$this, 'ajax_queue_backup' ));
115
 
@@ -326,7 +331,7 @@ class WPBackitup_Admin {
326
  }
327
 
328
  public function initialize(){
329
- do_action( 'wpbackitup_check_license');
330
  }
331
 
332
  public function wpbackitup_queue_scheduled_jobs(){
@@ -597,6 +602,9 @@ class WPBackitup_Admin {
597
  * Return the restore status and try run tasks
598
  */
599
  public function ajax_get_restore_status() {
 
 
 
600
  // Check permissions
601
  if (! self::is_authorized()) exit('Access denied.');
602
 
@@ -606,19 +614,25 @@ class WPBackitup_Admin {
606
 
607
  //Check permissions
608
  if ( current_user_can( 'manage_options' ) ) {
609
- //echo('RUNNING BACKUP');
610
-
611
- $process_id = uniqid();
612
 
613
  $event_logger->log_info(__METHOD__ .'(' .$process_id .')', 'Begin');
614
-
615
- //Try Run Next Backup Tasks
616
- $event_logger->log_info(__METHOD__.'(' .$process_id .')','Try Run restore task');
617
-
618
  $this->backup_type='manual';
619
- include_once( WPBACKITUP__PLUGIN_PATH.'/lib/includes/job_restore.php' );
620
 
621
- $event_logger->log_info(__METHOD__.'(' .$process_id .')','End Try Run Backup Task');
 
 
 
 
 
 
 
 
 
 
 
 
622
 
623
  //return status
624
  $log = WPBACKITUP__PLUGIN_PATH .'/logs/restore_status.log';
@@ -629,7 +643,8 @@ class WPBackitup_Admin {
629
  }
630
  }
631
 
632
- exit;
 
633
  }
634
 
635
  public function plupload_action() {
@@ -900,11 +915,11 @@ class WPBackitup_Admin {
900
  // set_transient('error-support-body', __('Please enter your problem description', $this->namespace), 60);
901
  // }
902
 
903
- $include_logs=false;
904
- if(!empty($_POST['support_include_logs']))
905
- {
906
- $include_logs=true;
907
- }
908
 
909
  //Send if no errors
910
  if (!$error){
@@ -939,8 +954,12 @@ class WPBackitup_Admin {
939
 
940
  }
941
 
 
942
  $utility = new WPBackItUp_Utility($logger);
943
  $support_to_address = WPBACKITUP__SUPPORT_EMAIL;
 
 
 
944
  $support_from_email=$_POST['support_email'];
945
  $support_subject = '[#' .trim($_POST['support_ticket_id']) .']';
946
 
@@ -949,9 +968,7 @@ class WPBackitup_Admin {
949
 
950
  $support_body=$site_info . '<br/><br/><b>Customer Comments:</b><br/><br/>' . $_POST['support_body'];
951
 
952
-
953
- $utility->send_email($support_to_address,$support_subject,$support_body,$logs_attachment,$support_from_email);
954
-
955
  // get rid of the transients
956
  foreach( $_POST as $key => $val ){
957
  delete_transient($key);
@@ -1417,7 +1434,7 @@ class WPBackitup_Admin {
1417
  */
1418
  private function update_license_options($license)
1419
  {
1420
- $logger = new WPBackItUp_Logger(true,null,'debug_activation');
1421
  $logger->log('Update License Options:' .$license);
1422
 
1423
  $license=trim($license);
@@ -1472,7 +1489,9 @@ class WPBackitup_Admin {
1472
 
1473
  if ( is_wp_error( $response ) ){
1474
  $logger->log_error(__METHOD__,$response->get_error_message());
1475
- return false; //Exit and don't update
 
 
1476
  }else{
1477
  $logger->log_info(__METHOD__,'No request errors.');
1478
  }
@@ -1652,7 +1671,7 @@ class WPBackitup_Admin {
1652
 
1653
 
1654
  /**
1655
- * Activation action
1656
  */
1657
  public static function activate() {
1658
  try{
@@ -1682,26 +1701,8 @@ class WPBackitup_Admin {
1682
  exit ('WP BackItUp was not able to create the required backup and restore folders.');
1683
  }
1684
 
1685
- //Need to reset the batch size for this release
1686
- $batch_size = get_option('wp-backitup_backup_batch_size');
1687
- if ($batch_size<100){
1688
- delete_option('wp-backitup_backup_batch_size');
1689
- }
1690
-
1691
- //Migrate old properties - can be removed in a few releases
1692
- $old_lite_name = get_option('wp-backitup_lite_registration_first_name');
1693
- if ($old_lite_name) {
1694
- update_option('wp-backitup_license_customer_name','test');
1695
- delete_option('wp-backitup_lite_registration_first_name');
1696
- }
1697
-
1698
- $old_lite_email = get_option('wp-backitup_lite_registration_email');
1699
- if ($old_lite_email) {
1700
- update_option('wp-backitup_license_customer_email',$old_lite_email);
1701
- delete_option('wp-backitup_lite_registration_email');
1702
- }
1703
- //--END Migrate
1704
-
1705
 
1706
  do_action( 'wpbackitup_check_license',true);
1707
 
@@ -1710,6 +1711,24 @@ class WPBackitup_Admin {
1710
  }
1711
  }
1712
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1713
  /**
1714
  * Deactivation action
1715
  */
16
  public $friendly_name = WPBACKITUP__FRIENDLY_NAME;
17
  public $version = WPBACKITUP__VERSION;
18
 
19
+ const DB_VERSION = 1;
20
+
21
  private static $instance = false;
22
 
23
  //Use Getters
82
  * Instantiation construction
83
  *
84
  */
85
+ public function __construct() {
86
  /**
87
  * Make this plugin available for translation.
88
  * Translations can be added to the /languages/ directory.
112
  //Load all the resources
113
  add_action( 'admin_enqueue_scripts', array( &$this, 'load_resources' ) );
114
 
115
+ //Update
116
+ add_action( 'plugins_loaded', array( $this, 'maybe_update' ), 1 );
117
+
118
  //Load the backup action
119
  add_action('wp_ajax_wp-backitup_backup', array( &$this, 'ajax_queue_backup' ));
120
 
331
  }
332
 
333
  public function initialize(){
334
+
335
  }
336
 
337
  public function wpbackitup_queue_scheduled_jobs(){
602
  * Return the restore status and try run tasks
603
  */
604
  public function ajax_get_restore_status() {
605
+ //@session_start();
606
+ @session_write_close();
607
+
608
  // Check permissions
609
  if (! self::is_authorized()) exit('Access denied.');
610
 
614
 
615
  //Check permissions
616
  if ( current_user_can( 'manage_options' ) ) {
617
+ global $restore_job,$process_id;
618
+ $process_id = uniqid();
 
619
 
620
  $event_logger->log_info(__METHOD__ .'(' .$process_id .')', 'Begin');
 
 
 
 
621
  $this->backup_type='manual';
 
622
 
623
+ //Is there a restore job available and is it already running
624
+ $restore_job = WPBackItUp_Job_v2::get_current_job('restore');
625
+ if (false!==$restore_job && $restore_job->get_lock('restore-lock')) {
626
+ $event_logger->log_info(__METHOD__.'(' .$process_id .')','Job Lock Acquired.');
627
+
628
+ //Try Run Next Backup Tasks
629
+ $event_logger->log_info(__METHOD__.'(' .$process_id .')','Try Run restore task');
630
+ include_once( WPBACKITUP__PLUGIN_PATH.'/lib/includes/job_restore.php' );
631
+ $restore_job->release_lock();
632
+ $event_logger->log_info(__METHOD__.'(' .$process_id .')','End Try Run Backup Task');
633
+ }else{
634
+ $event_logger->log_info(__METHOD__.'(' .$process_id .')','Job Lock NOT Acquired.');
635
+ }
636
 
637
  //return status
638
  $log = WPBACKITUP__PLUGIN_PATH .'/logs/restore_status.log';
643
  }
644
  }
645
 
646
+ $event_logger->log_info(__METHOD__ .'(' .$process_id .')', 'End');
647
+ exit(0);
648
  }
649
 
650
  public function plupload_action() {
915
  // set_transient('error-support-body', __('Please enter your problem description', $this->namespace), 60);
916
  // }
917
 
918
+ $include_logs=true; //always send logs
919
+ // if(!empty($_POST['support_include_logs']))
920
+ // {
921
+ // $include_logs=true;
922
+ // }
923
 
924
  //Send if no errors
925
  if (!$error){
954
 
955
  }
956
 
957
+ //Get registration name
958
  $utility = new WPBackItUp_Utility($logger);
959
  $support_to_address = WPBACKITUP__SUPPORT_EMAIL;
960
+
961
+ //If we force registration then this will always be here.
962
+ $from_name=$this->license_customer_name();
963
  $support_from_email=$_POST['support_email'];
964
  $support_subject = '[#' .trim($_POST['support_ticket_id']) .']';
965
 
968
 
969
  $support_body=$site_info . '<br/><br/><b>Customer Comments:</b><br/><br/>' . $_POST['support_body'];
970
 
971
+ $utility->send_email_v2($support_to_address,$support_subject,$support_body,$logs_attachment,$from_name,$support_from_email,$support_from_email);
 
 
972
  // get rid of the transients
973
  foreach( $_POST as $key => $val ){
974
  delete_transient($key);
1434
  */
1435
  private function update_license_options($license)
1436
  {
1437
+ $logger = new WPBackItUp_Logger(false,null,'debug_activation');
1438
  $logger->log('Update License Options:' .$license);
1439
 
1440
  $license=trim($license);
1489
 
1490
  if ( is_wp_error( $response ) ){
1491
  $logger->log_error(__METHOD__,$response->get_error_message());
1492
+ //update license last checked date and
1493
+ $this->set_option('license_last_check_date', $data['license_last_check_date']);
1494
+ return false; //Exit and don't update license
1495
  }else{
1496
  $logger->log_info(__METHOD__,'No request errors.');
1497
  }
1671
 
1672
 
1673
  /**
1674
+ * Activation action - will run ONLY on activation
1675
  */
1676
  public static function activate() {
1677
  try{
1701
  exit ('WP BackItUp was not able to create the required backup and restore folders.');
1702
  }
1703
 
1704
+ //Run database update routines
1705
+ self::maybe_update();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1706
 
1707
  do_action( 'wpbackitup_check_license',true);
1708
 
1711
  }
1712
  }
1713
 
1714
+
1715
+ //Run on plugins loaded
1716
+ public static function maybe_update() {
1717
+
1718
+ //if the plugin version is less than current, run the update
1719
+ if ( get_option( 'wp-backitup_major_version',0 ) < WPBACKITUP__MAJOR_VERSION ) {
1720
+ require_once( WPBACKITUP__PLUGIN_PATH .'/lib/includes/update_plugin.php' );
1721
+ wpbackitup_update_plugin();
1722
+ }
1723
+
1724
+ //if the DB version is less than current, run the update
1725
+ if ( get_option( 'wp-backitup_db_version',0 ) < self::DB_VERSION ) {
1726
+ require_once(WPBACKITUP__PLUGIN_PATH .'/lib/includes/update_database.php' );
1727
+ wpbackitup_update_database();
1728
+ }
1729
+
1730
+ }
1731
+
1732
  /**
1733
  * Deactivation action
1734
  */
lib/includes/job_backup.php CHANGED
@@ -43,6 +43,10 @@ if( !class_exists( 'WPBackItUp_Job' ) ) {
43
  include_once 'class-job.php';
44
  }
45
 
 
 
 
 
46
  /*** Globals ***/
47
  global $WPBackitup;
48
 
@@ -213,8 +217,6 @@ if ($backup_error) {
213
  end_backup( 2109, false );
214
  break;
215
 
216
-
217
-
218
  // case "task_cleanup_current": //Dont end backup on this error
219
  // set_status( 'cleanup', $active, true );
220
  // write_warning_status( '2106' );
@@ -260,10 +262,6 @@ if ('task_preparing'==$current_task) {
260
  //*** END Check Dependencies ***
261
 
262
 
263
- //This is handled in the cleanup jobs now
264
- //Cleanup any backups that didnt finish normally
265
- //$wp_backup->cleanup_unfinished_backups();
266
-
267
  //Make sure wpbackitup_backups exists
268
  if (! $wp_backup->backup_root_folder_exists() ){
269
  $backup_job->set_task_error('101');
@@ -288,30 +286,74 @@ if ('task_preparing'==$current_task) {
288
  end_backup(102,false);
289
  }
290
 
291
- //Generate the list of files to be backed up and update the tasks info
292
-
293
- $plugins_file_list = $wp_backup->get_plugins_file_list();
294
- $backup_job->update_job_meta('backup_plugins_filelist',$plugins_file_list);
295
- $backup_job->update_job_meta('backup_plugins_filelist_remaining',$plugins_file_list);
296
- $plugins_file_list=null;
297
-
298
- $themes_file_list = $wp_backup->get_themes_file_list();
299
- $backup_job->update_job_meta('backup_themes_filelist',$themes_file_list);
300
- $backup_job->update_job_meta('backup_themes_filelist_remaining',$themes_file_list);
301
- $themes_file_list=null;
302
-
303
- //some folders excluded
304
- $uploads_file_list = $wp_backup->get_uploads_file_list();
305
- $backup_job->update_job_meta('backup_uploads_filelist',$uploads_file_list);
306
- $backup_job->update_job_meta('backup_uploads_filelist_remaining',$uploads_file_list);
307
- $uploads_file_list=null;
308
-
309
- //some folders excluded
310
- $others_file_list = $wp_backup->get_other_file_list();
311
- $backup_job->update_job_meta('backup_others_filelist',$others_file_list);
312
- $backup_job->update_job_meta('backup_others_filelist_remaining',$others_file_list);
313
- $others_file_list=null;
314
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
 
316
  set_status('preparing',$complete,false);
317
  $backup_job->set_task_complete();
@@ -320,14 +362,15 @@ if ('task_preparing'==$current_task) {
320
  return;
321
  }
322
 
323
-
324
  //Backup the database
325
  if ('task_backup_db'==$current_task) {
326
  $logger->log( '**BEGIN SQL EXPORT**' );
327
  write_response_processing( "Create database export" );
328
  set_status( 'backupdb', $active, true );
329
 
330
- if ( ! $wp_backup->export_database() ) {
 
 
331
  $backup_job->set_task_error('104');
332
 
333
  write_fatal_error_status( '104' );
@@ -335,6 +378,8 @@ if ('task_backup_db'==$current_task) {
335
  end_backup( 104, false );
336
  }
337
 
 
 
338
  set_status('backupdb',$complete,false);
339
  $backup_job->set_task_complete();
340
 
@@ -343,6 +388,8 @@ if ('task_backup_db'==$current_task) {
343
 
344
  }
345
 
 
 
346
  //Extract the site info
347
  if ('task_backup_siteinfo'==$current_task) {
348
  $logger->log( '**SITE INFO**' );
@@ -352,12 +399,12 @@ if ('task_backup_siteinfo'==$current_task) {
352
  if ( $wp_backup->create_siteinfo_file() ) {
353
 
354
  //Add site Info and SQL data to main zip
355
- $site_data_suffix='main';
356
  $source_site_data_root = $wp_backup->backup_project_path;
357
  $target_site_data_root = 'site-data';
358
 
359
- $site_data_files = array_filter(glob($wp_backup->backup_project_path. '*.{txt,sql}',GLOB_BRACE), 'is_file');
360
- $site_data_complete = $wp_backup->backup_file_list( $source_site_data_root, $target_site_data_root, $site_data_suffix, $site_data_files, WPBACKITUP__PLUGINS_BATCH_SIZE );
361
  if ( $site_data_complete == 'error' ) {
362
  $backup_job->set_task_error('105');
363
 
@@ -391,14 +438,9 @@ if ('task_backup_themes'==$current_task) {
391
  write_response_processing( "Backup themes " );
392
  set_status( 'backup_themes', $active, true );
393
 
394
- $source_themes_root = WPBACKITUP__THEMES_ROOT_PATH;
395
- $target_theme_root = 'wp-content-themes';
396
- $themes_suffix='themes';
397
- $themes_file_list = $backup_job->get_job_meta('backup_themes_filelist_remaining');
398
- $themes_file_list_count= count($themes_file_list);
399
-
400
- $themes_remaining_files = $wp_backup->backup_file_list($source_themes_root,$target_theme_root,$themes_suffix,$themes_file_list,WPBACKITUP__THEMES_BATCH_SIZE);
401
- if ($themes_remaining_files=='error') {
402
  //ERROR
403
  $logger->log_error(__METHOD__,'Error backing up themes.');
404
  $backup_job->set_task_error('120');
@@ -406,14 +448,6 @@ if ('task_backup_themes'==$current_task) {
406
  //cleanup_on_failure( $wp_backup->backup_project_path );
407
  end_backup( 120, false );
408
  }else{
409
- //update the file list with remaining files
410
- $backup_job->update_job_meta('backup_themes_filelist_remaining',$themes_remaining_files);
411
-
412
- $themes_remaining_files_count= count($themes_remaining_files);
413
- $themes_batch_count = $themes_file_list_count-$themes_remaining_files_count;
414
- $logger->log('Backed up in this batch:' .$themes_batch_count);
415
-
416
- $logger->log('Themes remaining:' .$themes_remaining_files_count);
417
  if ($themes_remaining_files_count>0){
418
  //CONTINUE
419
  $logger->log_info(__METHOD__,'Continue backing up themes.');
@@ -431,20 +465,16 @@ if ('task_backup_themes'==$current_task) {
431
  return;
432
  }
433
 
 
434
  //Backup the plugins
435
  if ('task_backup_plugins'==$current_task) {
436
  $logger->log( '**BACKUP PLUGINS TASK**' );
437
  write_response_processing( "Backup plugins " );
438
  set_status( 'backup_plugins', $active, true );
439
 
440
- $source_plugins_root = WPBACKITUP__PLUGINS_ROOT_PATH;
441
- $target_plugins_root = 'wp-content-plugins';
442
- $plugins_suffix='plugins';
443
- $plugins_file_list = $backup_job->get_job_meta('backup_plugins_filelist_remaining');
444
- $plugins_file_list_count= count($plugins_file_list);
445
-
446
- $plugins_remaining_files = $wp_backup->backup_file_list($source_plugins_root,$target_plugins_root,$plugins_suffix,$plugins_file_list,WPBACKITUP__PLUGINS_BATCH_SIZE);
447
- if ($plugins_remaining_files=='error') {
448
  //ERROR
449
  $logger->log('Error backing up plugins.');
450
 
@@ -453,14 +483,6 @@ if ('task_backup_plugins'==$current_task) {
453
  //cleanup_on_failure( $wp_backup->backup_project_path );
454
  end_backup( 121, false );
455
  } else {
456
- //update the file list with remaining files
457
- $backup_job->update_job_meta('backup_plugins_filelist_remaining',$plugins_remaining_files);
458
-
459
- $plugins_remaining_files_count= count($plugins_remaining_files);
460
- $plugins_batch_count = $plugins_file_list_count-$plugins_remaining_files_count;
461
- $logger->log('Backed up in this batch:' .$plugins_batch_count);
462
-
463
- $logger->log('Plugins remaining:' .$plugins_remaining_files_count);
464
  if ($plugins_remaining_files_count>0){
465
  //CONTINUE
466
  $logger->log('Continue backing up plugins.');
@@ -477,7 +499,6 @@ if ('task_backup_plugins'==$current_task) {
477
  return;
478
  }
479
 
480
-
481
  //Backup the uploads
482
  if ('task_backup_uploads'==$current_task) {
483
  $logger->log( '**BACKUP UPLOADS TASK**' );
@@ -486,31 +507,17 @@ if ('task_backup_uploads'==$current_task) {
486
 
487
  $upload_array = wp_upload_dir();
488
  $source_uploads_root = $upload_array['basedir'];
489
- $target_uploads_root = 'wp-content-uploads';
490
- $uploads_suffix = 'uploads';
491
-
492
- $uploads_file_list = $backup_job->get_job_meta( 'backup_uploads_filelist_remaining' );
493
- $uploads_file_list_count = count( $uploads_file_list );
494
-
495
- $batch_size = $WPBackitup->backup_batch_size();
496
 
497
  //exclude zip files from backup
498
- $uploads_remaining_files = $wp_backup->backup_file_list( $source_uploads_root, $target_uploads_root, $uploads_suffix, $uploads_file_list,$batch_size,'.zip' );
499
- if ( $uploads_remaining_files == 'error' ) {
 
500
  //ERROR
501
  $logger->log( 'Error backing up uploads.' );
502
  $backup_job->set_task_error( '122' );
503
  write_fatal_error_status( '122' );
504
- //cleanup_on_failure( $wp_backup->backup_project_path );
505
  end_backup( 122, false );
506
  } else {
507
- //update the file list with remaining files
508
- $backup_job->update_job_meta( 'backup_uploads_filelist_remaining',$uploads_remaining_files);
509
-
510
- $uploads_remaining_files_count = count( $uploads_remaining_files );
511
- $uploads_batch_count = $uploads_file_list_count - $uploads_remaining_files_count;
512
- $logger->log( 'Backed up in this batch:' . $uploads_batch_count );
513
- $logger->log( 'Remaining Uploads:' . $uploads_remaining_files_count );
514
  if ( $uploads_remaining_files_count > 0 ) {
515
  //CONTINUE
516
  $logger->log( 'Continue backing up uploads.' );
@@ -534,18 +541,9 @@ if ('task_backup_other'==$current_task) {
534
  write_response_processing( "Backup other files " );
535
  set_status( 'backup_other', $active, true );
536
 
537
- $source_others_root = WPBACKITUP__CONTENT_PATH;
538
- $target_others_root = 'wp-content-other';
539
- $others_suffix = 'others';
540
-
541
- $others_file_list = $backup_job->get_job_meta( 'backup_others_filelist_remaining' );
542
- $others_file_list_count = count( $others_file_list );
543
-
544
- $batch_size = $WPBackitup->backup_batch_size();
545
-
546
- //exclude zip files from backup
547
- $others_remaining_files = $wp_backup->backup_file_list( $source_others_root, $target_others_root, $others_suffix, $others_file_list, $batch_size,'.zip' );
548
- if ( $others_remaining_files == 'error' ) {
549
  //ERROR
550
  $logger->log( 'Error backing up others.' );
551
  $backup_job->set_task_error( '123' );
@@ -554,13 +552,6 @@ if ('task_backup_other'==$current_task) {
554
  //cleanup_on_failure( $wp_backup->backup_project_path );
555
  end_backup( 123, false );
556
  } else {
557
- //update the file list with remaining files
558
- $backup_job->update_job_meta( 'backup_others_filelist_remaining', $others_remaining_files );
559
-
560
- $others_remaining_files_count = count( $others_remaining_files );
561
- $others_batch_count = $others_file_list_count - $others_remaining_files_count;
562
- $logger->log( 'Backed up in this batch:' . $others_batch_count );
563
- $logger->log( 'Remaining Others:' . $others_remaining_files_count );
564
  if ( $others_remaining_files_count > 0 ) {
565
  //CONTINUE
566
  $logger->log( 'Continue backing up others.' );
@@ -579,6 +570,7 @@ if ('task_backup_other'==$current_task) {
579
  return;
580
  }
581
 
 
582
  //ENCRYPT CONTENT TASK
583
  //wp-config.php
584
  //db backup
@@ -591,15 +583,28 @@ if ('task_validate_backup'==$current_task) {
591
  write_response_processing( "Validating Backup " );
592
  set_status( 'validate_backup', $active, true );
593
 
594
- if ($WPBackitup->logging()){
595
- //$wp_backup->validate_backup(); --HOW DO I DO THIS
596
- }
597
-
598
- sleep(5);//temp UI only
 
 
 
 
 
 
 
 
 
 
 
 
 
599
 
600
- set_status( 'validate_backup', $complete, false );
601
- $backup_job->set_task_complete();
602
- $logger->log('**END VALIDATE CONTENT**');
603
 
604
  return;
605
  }
@@ -633,6 +638,13 @@ if ('task_finalize_backup'==$current_task) {
633
  end_backup( 109, false );
634
  }
635
 
 
 
 
 
 
 
 
636
  set_status( 'finalize_backup', $complete, false );
637
  $backup_job->set_task_complete();
638
 
@@ -640,28 +652,16 @@ if ('task_finalize_backup'==$current_task) {
640
 
641
  }
642
 
 
643
  //If we get this far we have a finalized backup so change the path
644
  $wp_backup->set_final_backup_path();
645
 
646
- //Cleanup work folders - handled in cleanup jobs now
647
- //if ('task_cleanup_current'==$current_task) {
648
- // $logger->log( '**CLEANUP**' );
649
- //
650
- // write_response_processing( "Cleanup after Backup " );
651
- // set_status( 'cleanup', $active, true );
652
- //
653
- // //Check retention limits and cleanup
654
- // $wp_backup->purge_old_files();
655
- //
656
- // set_status( 'cleanup', $complete, false );
657
- // $backup_job->set_task_complete();
658
- //
659
- // $logger->log( '**END CLEANUP**' );
660
- //}
661
 
662
  if ($backup_job->get_job_status()=='complete') {
663
  //SUCCESS- End Job!
664
 
 
 
665
  //write response file first to make sure it is there
666
  write_response_file_success();
667
  set_status_success();
@@ -1008,6 +1008,8 @@ function get_error_message($error_code){
1008
  '123'=> '(123) Unable to backup your miscellaneous files. Please try again',
1009
  '125'=> '(125) Unable to compress your backup because there is no zip utility available. Please contact support',
1010
  '126'=> '(126) Unable to validate your backup. Please try again',
 
 
1011
 
1012
  '2101' =>'(2101) Unable to create a new directory for backup. Please check your CHMOD settings of your wp-backitup backup directory',
1013
  '2102'=> '(2102) Cannot create backup directory. Please check the CHMOD settings of your wp-backitup plugin directory',
@@ -1025,6 +1027,8 @@ function get_error_message($error_code){
1025
  '2123'=> '(2123) Unable to backup your miscellaneous files. Please try again',
1026
  '2125'=> '(2125) Unable to compress your backup because there is no zip utility available. Please contact support',
1027
  '2126'=> '(2126) Unable to validate your backup. Please try again',
 
 
1028
  );
1029
 
1030
  $error_message = '(999) Unexpected error';
@@ -1036,4 +1040,20 @@ function get_error_message($error_code){
1036
  }
1037
 
1038
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1039
 
43
  include_once 'class-job.php';
44
  }
45
 
46
+ if( !class_exists( 'WPBackItUp_DataAccess' ) ) {
47
+ include_once 'class-database.php';
48
+ }
49
+
50
  /*** Globals ***/
51
  global $WPBackitup;
52
 
217
  end_backup( 2109, false );
218
  break;
219
 
 
 
220
  // case "task_cleanup_current": //Dont end backup on this error
221
  // set_status( 'cleanup', $active, true );
222
  // write_warning_status( '2106' );
262
  //*** END Check Dependencies ***
263
 
264
 
 
 
 
 
265
  //Make sure wpbackitup_backups exists
266
  if (! $wp_backup->backup_root_folder_exists() ){
267
  $backup_job->set_task_error('101');
286
  end_backup(102,false);
287
  }
288
 
289
+ // ** Generate the list of files to be backed up **
290
+
291
+ //Create a job control record
292
+ if ( ! $wp_backup->create_job_control($backup_job->backup_id)){
293
+ $logger->log_error( __METHOD__, 'Cant create batch record');
294
+ $backup_job->set_task_error('128');
295
+
296
+ write_fatal_error_status('128');
297
+ end_backup(128,false);
298
+ };
299
+
300
+ $plugin_exclude = WPBACKITUP__BACKUP_GLOBAL_IGNORE_LIST;
301
+ if (! $wp_backup->save_folder_inventory(WPBACKITUP__SQL_BULK_INSERT_SIZE,$backup_job->backup_id,'plugins',WPBACKITUP__PLUGINS_ROOT_PATH,$plugin_exclude)){
302
+ $logger->log_error( __METHOD__, 'Plugins Inventory Error.');
303
+ $backup_job->set_task_error('127');
304
+
305
+ write_fatal_error_status('127');
306
+ end_backup(127,false);
307
+ };
308
+
309
+ $theme_exclude = WPBACKITUP__BACKUP_GLOBAL_IGNORE_LIST;
310
+ if (! $wp_backup->save_folder_inventory(WPBACKITUP__SQL_BULK_INSERT_SIZE,$backup_job->backup_id,'themes',WPBACKITUP__THEMES_ROOT_PATH,$theme_exclude)){
311
+ $logger->log_error( __METHOD__, 'Themes Inventory Error.');
312
+ $backup_job->set_task_error('127');
313
+
314
+ write_fatal_error_status('127');
315
+ end_backup(127,false);
316
+ };
317
+
318
+ $upload_exclude = WPBACKITUP__BACKUP_GLOBAL_IGNORE_LIST;
319
+ $upload_array = wp_upload_dir();
320
+ $uploads_root_path = $upload_array['basedir'];
321
+ if (! $wp_backup->save_folder_inventory(WPBACKITUP__SQL_BULK_INSERT_SIZE,$backup_job->backup_id,'uploads',$uploads_root_path,$upload_exclude)){
322
+ $logger->log_error( __METHOD__, 'Uploads Inventory Error.');
323
+ $backup_job->set_task_error('127');
324
+
325
+ write_fatal_error_status('127');
326
+ end_backup(127,false);
327
+ };
328
+
329
+ $global_exclude = explode(',', WPBACKITUP__BACKUP_GLOBAL_IGNORE_LIST);
330
+ $other_exclude = array_merge (
331
+ $global_exclude,
332
+ array(
333
+ "plugins",
334
+ "themes",
335
+ "uploads",
336
+ "wpbackitup_backups",
337
+ "wpbackitup_restore",
338
+ "backup",
339
+ "w3tc-config",
340
+ "updraft",
341
+ "wp-clone",
342
+ "backwpup",
343
+ "backupwordpress",
344
+ "cache",
345
+ "backupcreator",
346
+ "backupbuddy",
347
+ "wptouch-data",
348
+ ));
349
+
350
+ if (! $wp_backup->save_folder_inventory(WPBACKITUP__SQL_BULK_INSERT_SIZE,$backup_job->backup_id,'others',WPBACKITUP__CONTENT_PATH,$other_exclude)){
351
+ $logger->log_error( __METHOD__, 'Other Inventory Error.');
352
+ $backup_job->set_task_error('127');
353
+
354
+ write_fatal_error_status('127');
355
+ end_backup(127,false);
356
+ };
357
 
358
  set_status('preparing',$complete,false);
359
  $backup_job->set_task_complete();
362
  return;
363
  }
364
 
 
365
  //Backup the database
366
  if ('task_backup_db'==$current_task) {
367
  $logger->log( '**BEGIN SQL EXPORT**' );
368
  write_response_processing( "Create database export" );
369
  set_status( 'backupdb', $active, true );
370
 
371
+ $export_database = $wp_backup->export_database();
372
+ $logger->log( 'Export Database return:' .var_export($export_database,true));
373
+ if ( ! $export_database ) {
374
  $backup_job->set_task_error('104');
375
 
376
  write_fatal_error_status( '104' );
378
  end_backup( 104, false );
379
  }
380
 
381
+ $logger->log( 'Database Export complete.');
382
+
383
  set_status('backupdb',$complete,false);
384
  $backup_job->set_task_complete();
385
 
388
 
389
  }
390
 
391
+
392
+
393
  //Extract the site info
394
  if ('task_backup_siteinfo'==$current_task) {
395
  $logger->log( '**SITE INFO**' );
399
  if ( $wp_backup->create_siteinfo_file() ) {
400
 
401
  //Add site Info and SQL data to main zip
402
+ $suffix='main';
403
  $source_site_data_root = $wp_backup->backup_project_path;
404
  $target_site_data_root = 'site-data';
405
 
406
+ $site_data_files = get_fileonly_list($wp_backup->backup_project_path, '*.{txt,sql}');
407
+ $site_data_complete = $wp_backup->backup_file_list( $source_site_data_root, $target_site_data_root, $suffix, $site_data_files, WPBACKITUP__OTHERS_BATCH_SIZE );
408
  if ( $site_data_complete == 'error' ) {
409
  $backup_job->set_task_error('105');
410
 
438
  write_response_processing( "Backup themes " );
439
  set_status( 'backup_themes', $active, true );
440
 
441
+ $themes_remaining_files_count = $wp_backup->backup_files($backup_job->backup_id,WPBACKITUP__THEMES_ROOT_PATH,'themes');
442
+ $logger->log('Themes remaining:' .$themes_remaining_files_count);
443
+ if ($themes_remaining_files_count===false) {
 
 
 
 
 
444
  //ERROR
445
  $logger->log_error(__METHOD__,'Error backing up themes.');
446
  $backup_job->set_task_error('120');
448
  //cleanup_on_failure( $wp_backup->backup_project_path );
449
  end_backup( 120, false );
450
  }else{
 
 
 
 
 
 
 
 
451
  if ($themes_remaining_files_count>0){
452
  //CONTINUE
453
  $logger->log_info(__METHOD__,'Continue backing up themes.');
465
  return;
466
  }
467
 
468
+
469
  //Backup the plugins
470
  if ('task_backup_plugins'==$current_task) {
471
  $logger->log( '**BACKUP PLUGINS TASK**' );
472
  write_response_processing( "Backup plugins " );
473
  set_status( 'backup_plugins', $active, true );
474
 
475
+ $plugins_remaining_files_count = $wp_backup->backup_files($backup_job->backup_id,WPBACKITUP__PLUGINS_ROOT_PATH,'plugins');
476
+ $logger->log('Plugins remaining:' .$plugins_remaining_files_count);
477
+ if ($plugins_remaining_files_count===false) {
 
 
 
 
 
478
  //ERROR
479
  $logger->log('Error backing up plugins.');
480
 
483
  //cleanup_on_failure( $wp_backup->backup_project_path );
484
  end_backup( 121, false );
485
  } else {
 
 
 
 
 
 
 
 
486
  if ($plugins_remaining_files_count>0){
487
  //CONTINUE
488
  $logger->log('Continue backing up plugins.');
499
  return;
500
  }
501
 
 
502
  //Backup the uploads
503
  if ('task_backup_uploads'==$current_task) {
504
  $logger->log( '**BACKUP UPLOADS TASK**' );
507
 
508
  $upload_array = wp_upload_dir();
509
  $source_uploads_root = $upload_array['basedir'];
 
 
 
 
 
 
 
510
 
511
  //exclude zip files from backup
512
+ $uploads_remaining_files_count = $wp_backup->backup_files($backup_job->backup_id,$source_uploads_root,'uploads');
513
+ $logger->log('Uploads remaining:' .$uploads_remaining_files_count);
514
+ if ( $uploads_remaining_files_count ===false) {
515
  //ERROR
516
  $logger->log( 'Error backing up uploads.' );
517
  $backup_job->set_task_error( '122' );
518
  write_fatal_error_status( '122' );
 
519
  end_backup( 122, false );
520
  } else {
 
 
 
 
 
 
 
521
  if ( $uploads_remaining_files_count > 0 ) {
522
  //CONTINUE
523
  $logger->log( 'Continue backing up uploads.' );
541
  write_response_processing( "Backup other files " );
542
  set_status( 'backup_other', $active, true );
543
 
544
+ $others_remaining_files_count = $wp_backup->backup_files($backup_job->backup_id,WPBACKITUP__CONTENT_PATH,'others');
545
+ $logger->log('Others remaining:' .$others_remaining_files_count);
546
+ if ( $others_remaining_files_count ===false) {
 
 
 
 
 
 
 
 
 
547
  //ERROR
548
  $logger->log( 'Error backing up others.' );
549
  $backup_job->set_task_error( '123' );
552
  //cleanup_on_failure( $wp_backup->backup_project_path );
553
  end_backup( 123, false );
554
  } else {
 
 
 
 
 
 
 
555
  if ( $others_remaining_files_count > 0 ) {
556
  //CONTINUE
557
  $logger->log( 'Continue backing up others.' );
570
  return;
571
  }
572
 
573
+
574
  //ENCRYPT CONTENT TASK
575
  //wp-config.php
576
  //db backup
583
  write_response_processing( "Validating Backup " );
584
  set_status( 'validate_backup', $active, true );
585
 
586
+ $validate_plugins= $wp_backup->validate_backup_files($backup_job->backup_id,'plugins');
587
+ $validate_themes = $wp_backup->validate_backup_files($backup_job->backup_id,'themes');
588
+ $validate_uploads = $wp_backup->validate_backup_files($backup_job->backup_id,'uploads');
589
+ $validate_others = $wp_backup->validate_backup_files($backup_job->backup_id,'others');
590
+
591
+ if ( $validate_plugins ===false
592
+ || $validate_themes===false
593
+ || $validate_uploads===false
594
+ || $validate_others===false) {
595
+ //ERROR
596
+ $logger->log_error(__METHOD__ ,'Content Validation ERROR.' );
597
+ $backup_job->set_task_error( '126' );
598
+
599
+ write_fatal_error_status( '126' );
600
+ end_backup( 123, false );
601
+ } else {
602
+ set_status( 'validate_backup', $complete, false );
603
+ $backup_job->set_task_complete();
604
 
605
+ $logger->log_info(__METHOD__,'Content Validated Successfully!' );
606
+ $logger->log( '**END VALIDATE CONTENT**' );
607
+ }
608
 
609
  return;
610
  }
638
  end_backup( 109, false );
639
  }
640
 
641
+ //Take an inventory of the zip files created
642
+ $zip_files = get_fileonly_list($wp_backup->backup_project_path, '*.{zip}');
643
+ $wp_backup->save_file_list_inventory(WPBACKITUP__SQL_BULK_INSERT_SIZE,$backup_job->backup_id,'backups',$wp_backup->backup_project_path,$zip_files);
644
+
645
+ //Combine the zip files into one file
646
+ // $zip_remaining_files_count = $wp_backup->backup_files( $backup_job->backup_id, $wp_backup->backup_project_path, 'backup-files', 'combined' );
647
+
648
  set_status( 'finalize_backup', $complete, false );
649
  $backup_job->set_task_complete();
650
 
652
 
653
  }
654
 
655
+
656
  //If we get this far we have a finalized backup so change the path
657
  $wp_backup->set_final_backup_path();
658
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
659
 
660
  if ($backup_job->get_job_status()=='complete') {
661
  //SUCCESS- End Job!
662
 
663
+ $wp_backup->update_job_control_complete($backup_job->backup_id);
664
+
665
  //write response file first to make sure it is there
666
  write_response_file_success();
667
  set_status_success();
1008
  '123'=> '(123) Unable to backup your miscellaneous files. Please try again',
1009
  '125'=> '(125) Unable to compress your backup because there is no zip utility available. Please contact support',
1010
  '126'=> '(126) Unable to validate your backup. Please try again',
1011
+ '127'=> '(127) Unable to create inventory of files to backup. Please try again',
1012
+ '128'=> '(128) Unable to create job control record. Please try again',
1013
 
1014
  '2101' =>'(2101) Unable to create a new directory for backup. Please check your CHMOD settings of your wp-backitup backup directory',
1015
  '2102'=> '(2102) Cannot create backup directory. Please check the CHMOD settings of your wp-backitup plugin directory',
1027
  '2123'=> '(2123) Unable to backup your miscellaneous files. Please try again',
1028
  '2125'=> '(2125) Unable to compress your backup because there is no zip utility available. Please contact support',
1029
  '2126'=> '(2126) Unable to validate your backup. Please try again',
1030
+ '2127'=> '(2127) Unable to create inventory of files to backup. Please try again',
1031
+ '2128'=> '(2128) Unable to create job control record. Please try again',
1032
  );
1033
 
1034
  $error_message = '(999) Unexpected error';
1040
  }
1041
 
1042
 
1043
+ function get_fileonly_list($path,$pattern){
1044
+ global $logger;
1045
+ $logger->log_info(__METHOD__,"Begin:" .$path);
1046
+ $logger->log_info(__METHOD__,"Pattern:" .$pattern);//'*.{txt,sql}'
1047
+
1048
+ $all_files = glob($path. $pattern,GLOB_BRACE);
1049
+ $logger->log_info(__METHOD__,"All Files:" .var_export($all_files,true));
1050
+
1051
+ $filtered_array =array_filter($all_files, 'is_file'); //not sure i need this...
1052
+ $logger->log_info(__METHOD__,"Filtered Files:" .var_export($filtered_array,true));
1053
+
1054
+ return $filtered_array;
1055
+
1056
+
1057
+ }
1058
+
1059
 
lib/includes/job_cleanup.php CHANGED
@@ -148,6 +148,9 @@ if ('task_scheduled_cleanup'==$current_task) {
148
  $logger->log('***BEGIN JOB***');
149
  $logger->log_sysinfo();
150
 
 
 
 
151
  $logger->log('Scheduled Cleanup requested');
152
 
153
  $logger->log( '**CLEAN UNFINISHED BACKUPS**' );
@@ -193,10 +196,10 @@ if ('task_scheduled_cleanup'==$current_task) {
193
  $logger->log( '**END SECURE FOLDERS**' );
194
 
195
  $logger->log( '**CLEANUP OLD JOBS**' );
196
- $backup_job_purge_count = WPBackItUp_Job::purge_old_jobs('backup',25);
197
  $logger->log( 'Backup job records purged:' .$backup_job_purge_count );
198
 
199
- $cleanup_job_purge_count = WPBackItUp_Job::purge_old_jobs('cleanup',25);
200
  $logger->log( 'Cleanup job records purged:' .$cleanup_job_purge_count );
201
  $logger->log( '**END CLEANUP OLD JOBS**' );
202
 
148
  $logger->log('***BEGIN JOB***');
149
  $logger->log_sysinfo();
150
 
151
+ $logger->log('Check License');
152
+ do_action( 'wpbackitup_check_license');
153
+
154
  $logger->log('Scheduled Cleanup requested');
155
 
156
  $logger->log( '**CLEAN UNFINISHED BACKUPS**' );
196
  $logger->log( '**END SECURE FOLDERS**' );
197
 
198
  $logger->log( '**CLEANUP OLD JOBS**' );
199
+ $backup_job_purge_count = WPBackItUp_Job_v2::purge_completed_jobs('backup');
200
  $logger->log( 'Backup job records purged:' .$backup_job_purge_count );
201
 
202
+ $cleanup_job_purge_count = WPBackItUp_Job_v2::purge_completed_jobs('cleanup');
203
  $logger->log( 'Cleanup job records purged:' .$cleanup_job_purge_count );
204
  $logger->log( '**END CLEANUP OLD JOBS**' );
205
 
lib/includes/job_restore.php CHANGED
@@ -12,10 +12,6 @@
12
 
13
  /*** Includes ***/
14
 
15
- if( !class_exists( 'WPBackItUp_Backup' ) ) {
16
- include_once 'class-backup.php';
17
- }
18
-
19
  if( !class_exists( 'WPBackItUp_Restore' ) ) {
20
  include_once 'class-restore.php';
21
  }
@@ -36,11 +32,10 @@ if( !class_exists( 'WPBackItUp_SQL' ) ) {
36
  include_once 'class-sql.php';
37
  }
38
 
39
- if( !class_exists( 'WPBackItUp_Job' ) ) {
40
- include_once 'class-job.php';
41
  }
42
 
43
-
44
  /*** Globals ***/
45
  global $WPBackitup;
46
  global $table_prefix; //this is from wp-config
@@ -70,7 +65,6 @@ $status_array = array(
70
  'restore_database'=>$inactive,
71
  'update_user'=>$inactive,
72
  'update_site_info'=>$inactive,
73
- 'activate_plugins'=>$inactive,
74
  'update_permalinks'=>$inactive,
75
  );
76
 
@@ -79,58 +73,46 @@ $status_array = array(
79
  //**************************//
80
 
81
  $logger_tasks = new WPBackItUp_Logger(false,null,'debug_restore_tasks');
82
- $process_id = uniqid();
83
-
84
- //Is restore running
85
- if ( ! WPBackItUp_Backup::start()) {
86
- $logger_tasks->log_info(__METHOD__,'Restore job cant acquire job lock.');
87
- return; // do nothing.
88
- }else{
89
- $logger_tasks->log_info(__METHOD__,'Restore job lock acquired.');
90
- }
91
-
92
 
93
  //**************************//
94
  // Task Handling //
95
  //**************************//
96
- global $restore_job;
97
- $restore_job=null;
98
  $current_task= null;
99
 
100
  $restore_error=false;
101
- $restore_job = WPBackItUp_Job::get_job('restore');
102
  $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','Check for available job');
103
  if ($restore_job){
104
 
105
  //Get the next task in the stack
106
- $next_task = $restore_job->get_next_task();
107
- if (false!==$next_task){
108
- $restore_id=$restore_job->backup_id;
109
- $current_task=$next_task;
110
-
111
- //If task contains error then timeout has occurred
112
- if (strpos($current_task,'error') !== false){
113
- $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','Restore Error Found:' .$current_task);
 
114
  $restore_error=true;
115
  }
116
 
117
- $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','Available Task Found:' . $current_task);
118
 
119
  }else{
120
  $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','No available tasks found.');
121
- WPBackItUp_Backup::end(); //release lock
122
  return;
123
  }
124
  }else {
125
  $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','No job available.');
126
 
127
  //wp_clear_scheduled_hook( 'wpbackitup_run_restore_tasks');
128
- WPBackItUp_Backup::end(); //release lock
129
  return;
130
  }
131
 
132
  //Should only get here when there is a task to run
133
- $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','Run Restore task:' .$current_task);
134
 
135
 
136
  //*****************//
@@ -138,7 +120,7 @@ $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','Run Restore task:' .$c
138
  //*****************//
139
 
140
  //Get the job name
141
- $job_log_name = get_job_log_name($restore_job->backup_id);
142
 
143
  global $logger;
144
  $logger = new WPBackItUp_Logger(false,null,$job_log_name,true);
@@ -159,53 +141,52 @@ if( empty($user_id)) {
159
  }
160
 
161
  global $wp_restore; //Eventually everything will be migrated to this class
162
- $wp_restore = new WPBackItUp_Restore($logger,$backup_name,$restore_job->backup_id);
163
 
164
  //*************************//
165
  //*** RESTORE TASKS ***//
166
  //*************************//
167
  //An error has occurred on the previous tasks
168
  if ($restore_error) {
169
- $error_task = substr( $current_task, 6 );
170
 
171
  //Check for error type
172
- switch ( $error_task ) {
173
  case "task_preparing":
174
- fatal_error( 'preparing', '2001', 'Task ended in error:'.$error_task );
175
  break;
176
 
177
  case "task_unzip_backup_set":
178
- fatal_error( 'unzipping', '2002', 'Task ended in error:'.$error_task );
179
  break;
180
 
181
  case "task_validate_backup":
182
- fatal_error( 'validation', '2003', 'Task ended in error:'.$error_task );
183
  break;
184
 
185
  case "task_create_checkpoint":
186
- fatal_error( 'restore_point', '2004', 'Task ended in error:'.$error_task );
187
  break;
188
 
189
  case "task_stage_wpcontent":
190
- fatal_error( 'stage_wpcontent', '2005', 'Task ended in error:'.$error_task );
191
  break;
192
 
193
  case "task_restore_wpcontent":
194
- fatal_error( 'restore_wpcontent', '2006', 'Task ended in error:'.$error_task );
195
  break;
196
 
197
  case "task_restore_database":
198
- fatal_error( 'restore_database', '2007', 'Task ended in error:'.$error_task );
199
  break;
200
 
201
  default:
202
- fatal_error( 'unknown', '2999', 'Task ended in error:'.$error_task );
203
  break;
204
  }
205
  }
206
 
207
  //Cleanup Task
208
- if ('task_preparing'==$current_task) {
209
  $logger->log('***BEGIN RESTORE***');
210
  $logger->log_sysinfo();
211
 
@@ -214,6 +195,9 @@ if ('task_preparing'==$current_task) {
214
 
215
  $logger->log('**PREPARING FOR RESTORE**');
216
 
 
 
 
217
  if (! $this->license_active()){
218
  fatal_error($task,'225','Restore is not available because license is not active.');
219
  }
@@ -300,7 +284,7 @@ if ('task_preparing'==$current_task) {
300
  return;
301
  }
302
 
303
- if ('task_unzip_backup_set'==$current_task) {
304
 
305
  $logger->log( '**UNZIP BACKUP**' );
306
 
@@ -337,7 +321,7 @@ if ('task_unzip_backup_set'==$current_task) {
337
  }
338
 
339
  //Validate the backup folder
340
- if ('task_validate_backup'==$current_task) {
341
  $logger->log_info(__METHOD__, '**VALIDATE BACKUP**' );
342
 
343
  $task = 'validation';
@@ -386,30 +370,22 @@ if ('task_validate_backup'==$current_task) {
386
  }
387
 
388
  //Check wordpress version
389
- if ( get_bloginfo( 'version') != $site_info['restore_wp_version'] ) {
 
 
 
 
 
390
  fatal_error($task,'226','Backup was created using different version of wordpress');
391
  }
392
 
393
 
394
- //Check wpbackitup version
395
- //Only major versions differences should fail
396
- //1.9.2.8 and 1.9.2.9 are ok
397
- //1.9.2 and 1.10 are NOT
398
- //Even minor numbers are final releases
399
- //Odd minor numbers are pre-releases
400
  $restore_wpbackitup_version = $site_info['restore_wpbackitup_version'];
401
- $restore_wpbackitup_version = explode('.', $restore_wpbackitup_version);
402
- $current_wpbackitup_version = explode('.', WPBACKITUP__VERSION);
403
-
404
- $logger->log_info(__METHOD__,'Backup Created with WP BackItUp Version :');
405
- $logger->log($restore_wpbackitup_version);
406
-
407
- if (! empty($restore_wpbackitup_version[0]) && isset ($restore_wpbackitup_version[0])){ //Check version if not old backup - this should be removed in a few releases
408
- //If major version is different
409
- if ($restore_wpbackitup_version[0] != $current_wpbackitup_version[0] ||
410
- $restore_wpbackitup_version[1] != $current_wpbackitup_version[1] ) {
411
- fatal_error($task,'227','Backup was created using different version of WP BackItUp');
412
- }
413
  }
414
  $logger->log( '*END VALIDATE SITEDATA FILE*' );
415
 
@@ -436,7 +412,7 @@ if ('task_validate_backup'==$current_task) {
436
 
437
 
438
  //Create the DB restore point
439
- if ('task_create_checkpoint'==$current_task) {
440
 
441
  $logger->log('**CREATE RESTORE POINT**');
442
  $task = 'restore_point';
@@ -455,7 +431,7 @@ if ('task_create_checkpoint'==$current_task) {
455
 
456
 
457
  //Stage WP content folders
458
- if ('task_stage_wpcontent'==$current_task) {
459
 
460
  $logger->log('*STAGE WP-CONTENT*');
461
  $task = 'stage_wpcontent';
@@ -510,7 +486,7 @@ if ('task_stage_wpcontent'==$current_task) {
510
 
511
 
512
  //Rename the staged folders to current
513
- if ('task_restore_wpcontent'==$current_task) {
514
 
515
  $logger->log('**RESTORE WPCONTENT**');
516
  $task ='restore_wpcontent';
@@ -542,12 +518,15 @@ if ('task_restore_wpcontent'==$current_task) {
542
  }
543
 
544
  //restore the DB
545
- if ('task_restore_database'==$current_task) {
546
 
547
  $logger->log('**RESTORE DATABASE**');
548
  $task ='restore_database';
549
  start_status($task);
550
 
 
 
 
551
  $current_siteurl= $restore_job->get_job_meta('current_siteurl');
552
  $current_homeurl= $restore_job->get_job_meta('current_homeurl');
553
 
@@ -576,7 +555,9 @@ if ('task_restore_database'==$current_task) {
576
  //update the session cookie
577
  wp_set_auth_cookie( $user_id, true);
578
 
579
- WPBackItUp_Job::cancel_all_jobs(); //Cancel any jobs that were in the restored DB
 
 
580
 
581
  start_status('update_user');
582
  //Restored DB so current user may not be there.
@@ -597,15 +578,15 @@ if ('task_restore_database'==$current_task) {
597
  }
598
  end_status('update_site_info');
599
 
600
- //DONT NEED TO UPDATE TASKS - DB RESTORED
601
 
602
- $logger->log('*ACTIVATE PLUGINS*');
603
- start_status('activate_plugins');
604
- $wp_restore->activate_plugins();
605
- end_status('activate_plugins');
606
- $logger->log('*END ACTIVATE PLUGINS*');
607
 
608
 
 
 
 
609
  start_status('update_permalinks');
610
  if (! $wp_restore->update_permalinks()){
611
  //dont do anything
@@ -627,11 +608,8 @@ if ('task_restore_database'==$current_task) {
627
  $logger->log('Restore completed successfully');
628
  $logger->log('***END RESTORE***');
629
 
630
- echo('Restore has completed successfully.');
631
  end_restore(null,true);
632
 
633
- exit;
634
-
635
  /******************/
636
  /*** Functions ***/
637
  /******************/
@@ -795,27 +773,23 @@ function set_status_success(){
795
  }
796
 
797
  function end_restore($err=null, $success=null){
798
- global $WPBackitup, $wp_restore, $logger;
799
 
800
  if (true===$success) $logger->log("Restore completed: SUCCESS");
801
  if (false===$success) $logger->log("Restore completed: ERROR");
802
 
803
  $logger->log("*** END RESTORE ***");
804
 
805
- //Zip up all the logs
806
- // $zip_file_path =$wp_restore->zip_logs();
807
-
808
- //Email the log
809
- // $notification_email = $WPBackitup->get_option('notification_email');
810
- // $logs_attachment = array( $zip_file_path );
811
- // $wp_restore->send_notification_email($err, $success,$logs_attachment,$notification_email);
812
-
813
- //Release the lock
814
- WPBackItUp_Backup::end();
815
 
816
  //Close the logger
817
  $logger->close_file();
 
 
 
 
 
 
 
818
 
819
- echo('Restore has completed');
820
  exit(0);
821
  }
12
 
13
  /*** Includes ***/
14
 
 
 
 
 
15
  if( !class_exists( 'WPBackItUp_Restore' ) ) {
16
  include_once 'class-restore.php';
17
  }
32
  include_once 'class-sql.php';
33
  }
34
 
35
+ if( !class_exists( 'WPBackItUp_Task' ) ) {
36
+ include_once 'class-task.php';
37
  }
38
 
 
39
  /*** Globals ***/
40
  global $WPBackitup;
41
  global $table_prefix; //this is from wp-config
65
  'restore_database'=>$inactive,
66
  'update_user'=>$inactive,
67
  'update_site_info'=>$inactive,
 
68
  'update_permalinks'=>$inactive,
69
  );
70
 
73
  //**************************//
74
 
75
  $logger_tasks = new WPBackItUp_Logger(false,null,'debug_restore_tasks');
 
 
 
 
 
 
 
 
 
 
76
 
77
  //**************************//
78
  // Task Handling //
79
  //**************************//
 
 
80
  $current_task= null;
81
 
82
  $restore_error=false;
 
83
  $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','Check for available job');
84
  if ($restore_job){
85
 
86
  //Get the next task in the stack
87
+ $current_task = $restore_job->get_next_task();
88
+ $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','TASK Info:'.var_export($current_task,true));
89
+ if (null!= $current_task && false!==$current_task){
90
+ $restore_id=$restore_job->get_job_id();
91
+ $current_task->increment_retry_count();
92
+
93
+ //Was there an error on the previous task
94
+ if (WPBackItUp_Job_v2::ERROR==$current_task->getStatus()){
95
+ $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','Restore Error Found:' .$current_task->getId());
96
  $restore_error=true;
97
  }
98
 
99
+ $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','Available Task Found:' . $current_task->getId());
100
 
101
  }else{
102
  $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','No available tasks found.');
103
+ //WPBackItUp_Backup::end(); //release lock
104
  return;
105
  }
106
  }else {
107
  $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','No job available.');
108
 
109
  //wp_clear_scheduled_hook( 'wpbackitup_run_restore_tasks');
110
+ //WPBackItUp_Backup::end(); //release lock
111
  return;
112
  }
113
 
114
  //Should only get here when there is a task to run
115
+ $logger_tasks->log_info(__METHOD__.'(' .$process_id .')','Run Restore task:' .$current_task->getId());
116
 
117
 
118
  //*****************//
120
  //*****************//
121
 
122
  //Get the job name
123
+ $job_log_name = get_job_log_name($restore_job->get_job_id());
124
 
125
  global $logger;
126
  $logger = new WPBackItUp_Logger(false,null,$job_log_name,true);
141
  }
142
 
143
  global $wp_restore; //Eventually everything will be migrated to this class
144
+ $wp_restore = new WPBackItUp_Restore($logger,$backup_name,$restore_job->get_job_id());
145
 
146
  //*************************//
147
  //*** RESTORE TASKS ***//
148
  //*************************//
149
  //An error has occurred on the previous tasks
150
  if ($restore_error) {
 
151
 
152
  //Check for error type
153
+ switch ( $current_task->getId() ) {
154
  case "task_preparing":
155
+ fatal_error( 'preparing', '2001', 'Task ended in error:'.$current_task->getId() );
156
  break;
157
 
158
  case "task_unzip_backup_set":
159
+ fatal_error( 'unzipping', '2002', 'Task ended in error:'.$current_task->getId());
160
  break;
161
 
162
  case "task_validate_backup":
163
+ fatal_error( 'validation', '2003', 'Task ended in error:'.$current_task->getId() );
164
  break;
165
 
166
  case "task_create_checkpoint":
167
+ fatal_error( 'restore_point', '2004', 'Task ended in error:'.$current_task->getId() );
168
  break;
169
 
170
  case "task_stage_wpcontent":
171
+ fatal_error( 'stage_wpcontent', '2005', 'Task ended in error:'.$current_task->getId() );
172
  break;
173
 
174
  case "task_restore_wpcontent":
175
+ fatal_error( 'restore_wpcontent', '2006', 'Task ended in error:'.$current_task->getId() );
176
  break;
177
 
178
  case "task_restore_database":
179
+ fatal_error( 'restore_database', '2007', 'Task ended in error:'.$current_task->getId() );
180
  break;
181
 
182
  default:
183
+ fatal_error( 'unknown', '2999', 'Task ended in error:'.$current_task->getId() );
184
  break;
185
  }
186
  }
187
 
188
  //Cleanup Task
189
+ if ('task_preparing'==$current_task->getId()) {
190
  $logger->log('***BEGIN RESTORE***');
191
  $logger->log_sysinfo();
192
 
195
 
196
  $logger->log('**PREPARING FOR RESTORE**');
197
 
198
+ //ONLY check license here and prevent restore from starting. If
199
+ //IF license check fails in later steps could be because DB was restored and no license on backup
200
+ //which is a valid condition.
201
  if (! $this->license_active()){
202
  fatal_error($task,'225','Restore is not available because license is not active.');
203
  }
284
  return;
285
  }
286
 
287
+ if ('task_unzip_backup_set'==$current_task->getId()) {
288
 
289
  $logger->log( '**UNZIP BACKUP**' );
290
 
321
  }
322
 
323
  //Validate the backup folder
324
+ if ('task_validate_backup'==$current_task->getId()) {
325
  $logger->log_info(__METHOD__, '**VALIDATE BACKUP**' );
326
 
327
  $task = 'validation';
370
  }
371
 
372
  //Check wordpress version
373
+ $site_wordpress_version = get_bloginfo('version');
374
+ $backup_wordpress_version = $site_info['restore_wp_version'];
375
+ $logger->log_info(__METHOD__, 'Site Wordpress Version:' . $site_wordpress_version);
376
+ $logger->log_info(__METHOD__, 'Backup Wordpress Version:' . $backup_wordpress_version);
377
+ if ( ! WPBackItUp_Utility::version_compare($site_wordpress_version, $backup_wordpress_version )) {
378
+ $logger->log( '*VALIDATE SITEDATA FILE*' );
379
  fatal_error($task,'226','Backup was created using different version of wordpress');
380
  }
381
 
382
 
 
 
 
 
 
 
383
  $restore_wpbackitup_version = $site_info['restore_wpbackitup_version'];
384
+ $current_wpbackitup_version = WPBACKITUP__VERSION;
385
+ $logger->log_info(__METHOD__, 'WP BackItUp current Version:' . $current_wpbackitup_version);
386
+ $logger->log_info(__METHOD__, 'WP BackItUp backup Version:' . $restore_wpbackitup_version);
387
+ if (! WPBackItUp_Utility::version_compare($restore_wpbackitup_version, $current_wpbackitup_version )){
388
+ fatal_error($task,'227','Backup was created using different version of WP BackItUp');
 
 
 
 
 
 
 
389
  }
390
  $logger->log( '*END VALIDATE SITEDATA FILE*' );
391
 
412
 
413
 
414
  //Create the DB restore point
415
+ if ('task_create_checkpoint'==$current_task->getId()) {
416
 
417
  $logger->log('**CREATE RESTORE POINT**');
418
  $task = 'restore_point';
431
 
432
 
433
  //Stage WP content folders
434
+ if ('task_stage_wpcontent'==$current_task->getId()) {
435
 
436
  $logger->log('*STAGE WP-CONTENT*');
437
  $task = 'stage_wpcontent';
486
 
487
 
488
  //Rename the staged folders to current
489
+ if ('task_restore_wpcontent'==$current_task->getId()) {
490
 
491
  $logger->log('**RESTORE WPCONTENT**');
492
  $task ='restore_wpcontent';
518
  }
519
 
520
  //restore the DB
521
+ if ('task_restore_database'==$current_task->getId()) {
522
 
523
  $logger->log('**RESTORE DATABASE**');
524
  $task ='restore_database';
525
  start_status($task);
526
 
527
+ //grab the license before the database is restored
528
+ $license_key = $this->license_key();
529
+
530
  $current_siteurl= $restore_job->get_job_meta('current_siteurl');
531
  $current_homeurl= $restore_job->get_job_meta('current_homeurl');
532
 
555
  //update the session cookie
556
  wp_set_auth_cookie( $user_id, true);
557
 
558
+ //Cancel any jobs that were in the restored DB
559
+ WPBackItUp_Job_v2::cancel_all_jobs('backup');
560
+ WPBackItUp_Job_v2::cancel_all_jobs('cleanup');
561
 
562
  start_status('update_user');
563
  //Restored DB so current user may not be there.
578
  }
579
  end_status('update_site_info');
580
 
 
581
 
582
+ //Update the license information in the DB just in case it wasn't there on DB restore
583
+ //Dont need to call activation, will happen on its own
584
+ $wp_restore->update_license_key($table_prefix, $license_key);
 
 
585
 
586
 
587
+ //DONT NEED TO UPDATE TASKS - DB RESTORED
588
+ //DONT need to activate plugins, they will be active in restored DB
589
+
590
  start_status('update_permalinks');
591
  if (! $wp_restore->update_permalinks()){
592
  //dont do anything
608
  $logger->log('Restore completed successfully');
609
  $logger->log('***END RESTORE***');
610
 
 
611
  end_restore(null,true);
612
 
 
 
613
  /******************/
614
  /*** Functions ***/
615
  /******************/
773
  }
774
 
775
  function end_restore($err=null, $success=null){
776
+ global $restore_job, $logger;
777
 
778
  if (true===$success) $logger->log("Restore completed: SUCCESS");
779
  if (false===$success) $logger->log("Restore completed: ERROR");
780
 
781
  $logger->log("*** END RESTORE ***");
782
 
 
 
 
 
 
 
 
 
 
 
783
 
784
  //Close the logger
785
  $logger->close_file();
786
+ $restore_job->release_lock();
787
+
788
+ //response back the status file since this method will end processing
789
+ $log = WPBACKITUP__PLUGIN_PATH .'/logs/restore_status.log';
790
+ if(file_exists($log) ) {
791
+ readfile($log);
792
+ }
793
 
 
794
  exit(0);
795
  }
lib/includes/update_database.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined ('ABSPATH')) die('No direct access allowed');
2
+
3
+
4
+ /**
5
+ * Run the incremental updates one by one.
6
+ *
7
+ * For example, if the current DB version is 3, and the target DB version is 6,
8
+ * this function will execute update routines if they exist:
9
+ * - wpbackitup_update_routine_4()
10
+ * - wpbackitup_routine_5()
11
+ * - wpbackitup_update_routine_6()
12
+ *
13
+ */
14
+ function wpbackitup_update_database() {
15
+ // no PHP timeout for running updates
16
+ set_time_limit( 0 );
17
+
18
+ // this is the current database schema version number
19
+ $current_db_ver = get_option( 'wp-backitup_db_version',0 );
20
+
21
+ // this is the target version that we need to reach
22
+ $target_db_ver = WPBackitup_Admin::DB_VERSION;
23
+
24
+ // run update routines one by one until the current version number
25
+ // reaches the target version number
26
+ while ( $current_db_ver < $target_db_ver ) {
27
+
28
+ error_log( 'Run Update database routines');
29
+ error_log( 'Current DB version:'.$current_db_ver );
30
+ error_log( 'Target DB version:'.$target_db_ver );
31
+
32
+ // increment the current db_ver by one
33
+ $current_db_ver ++;
34
+
35
+ // each db version will require a separate update function
36
+ // for example, for db_ver 3, the function name should be solis_update_routine_3
37
+ $func = "wpbackitup_update_database_routine_{$current_db_ver}";
38
+ if ( function_exists( $func ) ) {
39
+ error_log( 'Run:' .$func);
40
+ call_user_func( $func );
41
+ error_log( 'Run complete:' .$func);
42
+ }
43
+
44
+ // update the option in the database, so that this process can always
45
+ // pick up where it left off
46
+ update_option( 'wp-backitup_db_version', $current_db_ver );
47
+ }
48
+ }
49
+
50
+
51
+ /**
52
+ * DB version 0 to 1 update
53
+ *
54
+ */
55
+ function wpbackitup_update_database_routine_1(){
56
+ global $wpdb;
57
+
58
+ $charset_collate = $wpdb->get_charset_collate();
59
+ $table_name = $wpdb->prefix . "wpbackitup_job";
60
+
61
+ $sql = "CREATE TABLE $table_name (
62
+ id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
63
+ job_id bigint(20) NOT NULL,
64
+ batch_id bigint(20) DEFAULT NULL,
65
+ group_id varchar(15) DEFAULT NULL,
66
+ item longtext,
67
+ size_kb bigint(20) DEFAULT NULL,
68
+ retry_count int(11) NOT NULL DEFAULT '0',
69
+ status int(11) NOT NULL DEFAULT '0',
70
+ create_date datetime DEFAULT NULL,
71
+ update_date datetime DEFAULT NULL,
72
+ record_type varchar(1) NOT NULL DEFAULT 'I',
73
+ PRIMARY KEY (id)
74
+ ) $charset_collate;";
75
+
76
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
77
+ dbDelta( $sql );
78
+ }
lib/includes/update_plugin.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined ('ABSPATH')) die('No direct access allowed');
2
+
3
+
4
+ /**
5
+ * Run the incremental updates one by one.
6
+ *
7
+ * For example, if the current DB version is 3, and the target DB version is 6,
8
+ * this function will execute update routines if they exist:
9
+ * - wpbackitup_update_routine_4()
10
+ * - wpbackitup_routine_5()
11
+ * - wpbackitup_update_routine_6()
12
+ *
13
+ */
14
+ function wpbackitup_update_plugin() {
15
+ // no PHP timeout for running updates
16
+ set_time_limit( 0 );
17
+
18
+ // this is the current database schema version number
19
+ $current_plugin_major_ver = get_option( 'wp-backitup_major_version',0 );
20
+
21
+ // this is the target version that we need to reach
22
+ $target_plugin_major_ver = WPBACKITUP__MAJOR_VERSION;
23
+
24
+ //Major updates require routine
25
+
26
+ // run update routines one by one until the current version number
27
+ // reaches the target version number
28
+ while ( $current_plugin_major_ver < $target_plugin_major_ver ) {
29
+
30
+ error_log( 'Run Update plugin routines');
31
+ error_log( 'Current Plugin Major Version:'.$current_plugin_major_ver );
32
+ error_log( 'Target Plugin Major Version:'.$target_plugin_major_ver );
33
+
34
+ // increment the current db_ver by one
35
+ $current_plugin_major_ver ++;
36
+
37
+ // each version will require a separate update function
38
+ // for example, for ver 3, the function name should be solis_update_routine_3
39
+ $func = "wpbackitup_update_plugin_routine_{$current_plugin_major_ver}";
40
+ if ( function_exists( $func ) ) {
41
+ error_log( 'Run:' .$func);
42
+ call_user_func( $func );
43
+ error_log( 'Run complete:' .$func);
44
+ }
45
+
46
+ // update the option in the database, so that this process can always
47
+ // pick up where it left off
48
+ update_option( 'wp-backitup_major_version', $current_plugin_major_ver );
49
+ }
50
+
51
+ }
52
+
53
+
54
+ /**
55
+ * Plugin update 0 to 1
56
+ */
57
+ function wpbackitup_update_plugin_routine_1(){
58
+
59
+ //Need to reset the batch size for this release
60
+ $batch_size = get_option('wp-backitup_backup_batch_size');
61
+ if ($batch_size<100){
62
+ delete_option('wp-backitup_backup_batch_size');
63
+ }
64
+
65
+ //Migrate old properties - can be removed in a few releases
66
+ $old_lite_name = get_option('wp-backitup_lite_registration_first_name');
67
+ if ($old_lite_name) {
68
+ update_option('wp-backitup_license_customer_name',$old_lite_name);
69
+ delete_option('wp-backitup_lite_registration_first_name');
70
+ }
71
+
72
+ $old_lite_email = get_option('wp-backitup_lite_registration_email');
73
+ if ($old_lite_email) {
74
+ update_option('wp-backitup_license_customer_email',$old_lite_email);
75
+ delete_option('wp-backitup_lite_registration_email');
76
+ }
77
+ }
78
+
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === WP Backitup ===
2
- Contributors: cssimmon,jcpeden
3
  Donate link: http://www.wpbackitup.com
4
  Tags: backup, back up, backups, backup wordpress, backup database, backup plugin, backup and restore, database, database backup, database restore, db, db backup, db restore, download database, full backup, mysql backup, restore, restore database,restore wordpress, restore wordpress backup,restoring wordpress, website backup, wordpress backup, wordpress restore, plugin, backup buddy
5
  Requires at least: 3.8.0
6
- Tested up to: 4.1.1
7
- Stable tag: 1.10.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -151,6 +151,19 @@ Our online documentation and full list of FAQs can be found at [www.wpbackitup.c
151
 
152
 
153
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  = 1.10.6 =
155
  * FEATURE:Add job data to cleanup routine
156
  * FIX: Add wp-cron task on schedule check to fix issue with sheduled backups not running.
1
  === WP Backitup ===
2
+ Contributors: cssimmon,jcpeden,wpbackitup
3
  Donate link: http://www.wpbackitup.com
4
  Tags: backup, back up, backups, backup wordpress, backup database, backup plugin, backup and restore, database, database backup, database restore, db, db backup, db restore, download database, full backup, mysql backup, restore, restore database,restore wordpress, restore wordpress backup,restoring wordpress, website backup, wordpress backup, wordpress restore, plugin, backup buddy
5
  Requires at least: 3.8.0
6
+ Tested up to: 4.2.2
7
+ Stable tag: 1.10.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
151
 
152
 
153
  == Changelog ==
154
+ = 1.10.7 =
155
+ * UPDATE: Add multi-site support for database backup
156
+ * UPDATE: Add WordPress 4.2 support
157
+ * UPDATE: Enhance backup file validation
158
+ * UPDATE: Add job table to better handle large backup jobs
159
+ * UPDATE: Add logging additional logging to database export.
160
+ * UPDATE: Add logging for is_file to make sure filtering properly.
161
+ * UPDATE: Add logging to backup view to list all files contained in root backup folder.
162
+ * UPDATE: Add logging to plugin meta update
163
+ * FIX: Modify manual db export to write flush file buffer more frequently.
164
+ * FIX: Change backup to use default batch size.
165
+ * FIX: Correct job check error when no jobs available to purge.
166
+
167
  = 1.10.6 =
168
  * FEATURE:Add job data to cleanup routine
169
  * FIX: Add wp-cron task on schedule check to fix issue with sheduled backups not running.
views/backup.php CHANGED
@@ -8,6 +8,8 @@
8
  * @link http://www.wpbackitup.com
9
  *
10
  */
 
 
11
 
12
  $page_title = $this->friendly_name . ' Dashboard';
13
  $namespace = $this->namespace;
@@ -16,8 +18,11 @@
16
  $backup_folder_root = WPBACKITUP__BACKUP_PATH;
17
  $logs_folder_root = WPBACKITUP__PLUGIN_PATH .'/logs';
18
 
19
- //Get license info
20
- $version = $this->version;
 
 
 
21
  $license_key = $this->license_key();
22
  $license_active = $this->license_active();
23
 
@@ -63,62 +68,68 @@
63
  //Get Zip File List
64
  $file_list = glob($backup_folder_root . "/*.{zip,log}",GLOB_BRACE);
65
  //If there are zip files then move them into their own folders
66
- foreach($file_list as $file) {
67
 
68
- //remove the suffix
69
- $file_name = substr(basename($file),0,-4);
70
 
71
- //strip off the suffix IF one exists
72
- $folder_name = $file_name;
73
- if ( ( $str_pos = strpos( $folder_name, '-main-' ) ) !== false ) {
74
- $suffix = substr( $folder_name, $str_pos );
75
- $folder_name = str_replace( $suffix, '', $folder_name );
76
- }
77
 
78
- if ( ( $str_pos = strpos( $folder_name, '-others-' ) ) !== false ) {
79
- $suffix = substr( $folder_name, $str_pos );
80
- $folder_name = str_replace( $suffix, '', $folder_name );
81
- }
82
 
83
- if ( ( $str_pos = strpos( $folder_name, '-plugins-' ) ) !== false ) {
84
- $suffix = substr( $folder_name, $str_pos );
85
- $folder_name = str_replace( $suffix, '', $folder_name );
86
- }
 
 
87
 
88
- if ( ( $str_pos = strpos( $folder_name, '-themes-' ) ) !== false ) {
89
- $suffix = substr( $folder_name, $str_pos );
90
- $folder_name = str_replace( $suffix, '', $folder_name );
91
- }
92
 
93
- if ( ( $str_pos = strpos( $folder_name, '-uploads-' ) ) !== false ) {
94
- $suffix = substr( $folder_name, $str_pos );
95
- $folder_name = str_replace( $suffix, '', $folder_name );
96
- }
97
 
98
- //Does folder exist
99
- $backup_archive_folder = $backup_dir . '/' . $folder_name;
100
- if ( ! is_dir( $backup_archive_folder ) ) {
101
- if (mkdir( $backup_archive_folder, 0755 )){
102
- //print_r( "Folder Create.." );
103
- }else{
104
- //print_r( "Create Failed.." );
105
  }
106
- }
107
 
108
- //make sure it exists before you move it
109
- if ( is_dir( $backup_archive_folder ) ) {
110
- //move the file to the archive folder
111
- $target_file = $backup_archive_folder ."/" . basename($file);
112
- if (rename ($file,$target_file)){
113
- //print_r( "File Moved.." );
114
- } else{
115
- //print_r( "Move Failed.." );
116
  }
117
 
118
- } else {
119
- //print_r( "NO FOLDER" );
120
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
 
122
  }
123
 
124
  $backup_list = $this->get_backup_list();
8
  * @link http://www.wpbackitup.com
9
  *
10
  */
11
+ //Check the license
12
+ do_action( 'wpbackitup_check_license');
13
 
14
  $page_title = $this->friendly_name . ' Dashboard';
15
  $namespace = $this->namespace;
18
  $backup_folder_root = WPBACKITUP__BACKUP_PATH;
19
  $logs_folder_root = WPBACKITUP__PLUGIN_PATH .'/logs';
20
 
21
+ $logger = new WPBackItUp_Logger(false,null,'debug_backup_view');
22
+
23
+ //Get license info - trim off build version if 0
24
+ $version = rtrim ($this->version,'.0');
25
+
26
  $license_key = $this->license_key();
27
  $license_active = $this->license_active();
28
 
68
  //Get Zip File List
69
  $file_list = glob($backup_folder_root . "/*.{zip,log}",GLOB_BRACE);
70
  //If there are zip files then move them into their own folders
 
71
 
72
+ $logger->log_info(__METHOD__,'Files in backup folder: ' .var_export($file_list,true));
73
+ $logger->log_info(__METHOD__,'Last Error: ' .var_export(error_get_last(),true));
74
 
75
+ if (null != $file_list) {
76
+ foreach ( $file_list as $file ) {
 
 
 
 
77
 
78
+ //remove the suffix
79
+ $file_name = substr( basename( $file ), 0, - 4 );
 
 
80
 
81
+ //strip off the suffix IF one exists
82
+ $folder_name = $file_name;
83
+ if ( ( $str_pos = strpos( $folder_name, '-main-' ) ) !== false ) {
84
+ $suffix = substr( $folder_name, $str_pos );
85
+ $folder_name = str_replace( $suffix, '', $folder_name );
86
+ }
87
 
88
+ if ( ( $str_pos = strpos( $folder_name, '-others-' ) ) !== false ) {
89
+ $suffix = substr( $folder_name, $str_pos );
90
+ $folder_name = str_replace( $suffix, '', $folder_name );
91
+ }
92
 
93
+ if ( ( $str_pos = strpos( $folder_name, '-plugins-' ) ) !== false ) {
94
+ $suffix = substr( $folder_name, $str_pos );
95
+ $folder_name = str_replace( $suffix, '', $folder_name );
96
+ }
97
 
98
+ if ( ( $str_pos = strpos( $folder_name, '-themes-' ) ) !== false ) {
99
+ $suffix = substr( $folder_name, $str_pos );
100
+ $folder_name = str_replace( $suffix, '', $folder_name );
 
 
 
 
101
  }
 
102
 
103
+ if ( ( $str_pos = strpos( $folder_name, '-uploads-' ) ) !== false ) {
104
+ $suffix = substr( $folder_name, $str_pos );
105
+ $folder_name = str_replace( $suffix, '', $folder_name );
 
 
 
 
 
106
  }
107
 
108
+ //Does folder exist
109
+ $backup_archive_folder = $backup_dir . '/' . $folder_name;
110
+ if ( ! is_dir( $backup_archive_folder ) ) {
111
+ if ( mkdir( $backup_archive_folder, 0755 ) ) {
112
+ //print_r( "Folder Create.." );
113
+ } else {
114
+ //print_r( "Create Failed.." );
115
+ }
116
+ }
117
+
118
+ //make sure it exists before you move it
119
+ if ( is_dir( $backup_archive_folder ) ) {
120
+ //move the file to the archive folder
121
+ $target_file = $backup_archive_folder . "/" . basename( $file );
122
+ if ( rename( $file, $target_file ) ) {
123
+ //print_r( "File Moved.." );
124
+ } else {
125
+ //print_r( "Move Failed.." );
126
+ }
127
+
128
+ } else {
129
+ //print_r( "NO FOLDER" );
130
+ }
131
 
132
+ }
133
  }
134
 
135
  $backup_list = $this->get_backup_list();
views/restore.php CHANGED
@@ -9,6 +9,9 @@
9
  *
10
  */
11
 
 
 
 
12
  $page_title = $this->friendly_name . ' Restore';
13
  $namespace = $this->namespace;
14
 
@@ -223,7 +226,7 @@ if (!$restore_folder_exists) {
223
  <li class="restore_database"><?php _e('Restoring database', $namespace); ?>...<span class='status-icon'><img class="restore_database-icon" src="<?php echo WPBACKITUP__PLUGIN_URL . "/images/loader.gif"; ?>" height="16" width="16" /></span><span class='status'><?php _e('Done', $namespace); ?></span><span class='fail error'><?php _e('Failed', $namespace); ?></span></li>
224
  <li class="update_user"><?php _e('Updating current user info', $namespace); ?>...<span class='status-icon'><img class="update_user-icon" src="<?php echo WPBACKITUP__PLUGIN_URL . "/images/loader.gif"; ?>" height="16" width="16" /></span><span class='status'><?php _e('Done', $namespace); ?></span><span class='fail error'><?php _e('Failed', $namespace); ?></span></li>
225
  <li class="update_site_info"><?php _e('Updating site URL', $namespace); ?>...<span class='status-icon'><img class="update_site_info-icon" src="<?php echo WPBACKITUP__PLUGIN_URL . "/images/loader.gif"; ?>" height="16" width="16" /></span><span class='status'><?php _e('Done', $namespace); ?></span><span class='fail error'><?php _e('Failed', $namespace); ?></span></li>
226
- <li class="activate_plugins"><?php _e('Activating plugins', $namespace); ?>...<span class='status-icon'><img class="activate_plugins-icon" src="<?php echo WPBACKITUP__PLUGIN_URL . "/images/loader.gif"; ?>" height="16" width="16" /></span><span class='status'><?php _e('Done', $namespace); ?></span><span class='fail error'><?php _e('Failed', $namespace); ?></span></li>
227
  <li class="update_permalinks"><?php _e('Updating permalinks', $namespace); ?>...<span class='status-icon'><img class="update_permalinks-icon" src="<?php echo WPBACKITUP__PLUGIN_URL . "/images/loader.gif"; ?>" height="16" width="16" /></span><span class='status'><?php _e('Done', $namespace); ?></span><span class='fail error'><?php _e('Failed', $namespace); ?></span></li>
228
  </ul>
229
  <p>
9
  *
10
  */
11
 
12
+ //Check the license
13
+ do_action( 'wpbackitup_check_license');
14
+
15
  $page_title = $this->friendly_name . ' Restore';
16
  $namespace = $this->namespace;
17
 
226
  <li class="restore_database"><?php _e('Restoring database', $namespace); ?>...<span class='status-icon'><img class="restore_database-icon" src="<?php echo WPBACKITUP__PLUGIN_URL . "/images/loader.gif"; ?>" height="16" width="16" /></span><span class='status'><?php _e('Done', $namespace); ?></span><span class='fail error'><?php _e('Failed', $namespace); ?></span></li>
227
  <li class="update_user"><?php _e('Updating current user info', $namespace); ?>...<span class='status-icon'><img class="update_user-icon" src="<?php echo WPBACKITUP__PLUGIN_URL . "/images/loader.gif"; ?>" height="16" width="16" /></span><span class='status'><?php _e('Done', $namespace); ?></span><span class='fail error'><?php _e('Failed', $namespace); ?></span></li>
228
  <li class="update_site_info"><?php _e('Updating site URL', $namespace); ?>...<span class='status-icon'><img class="update_site_info-icon" src="<?php echo WPBACKITUP__PLUGIN_URL . "/images/loader.gif"; ?>" height="16" width="16" /></span><span class='status'><?php _e('Done', $namespace); ?></span><span class='fail error'><?php _e('Failed', $namespace); ?></span></li>
229
+ <!-- <li class="activate_plugins">--><?php //_e('Activating plugins', $namespace); ?><!--...<span class='status-icon'><img class="activate_plugins-icon" src="--><?php //echo WPBACKITUP__PLUGIN_URL . "/images/loader.gif"; ?><!--" height="16" width="16" /></span><span class='status'>--><?php //_e('Done', $namespace); ?><!--</span><span class='fail error'>--><?php //_e('Failed', $namespace); ?><!--</span></li>-->
230
  <li class="update_permalinks"><?php _e('Updating permalinks', $namespace); ?>...<span class='status-icon'><img class="update_permalinks-icon" src="<?php echo WPBACKITUP__PLUGIN_URL . "/images/loader.gif"; ?>" height="16" width="16" /></span><span class='status'><?php _e('Done', $namespace); ?></span><span class='fail error'><?php _e('Failed', $namespace); ?></span></li>
231
  </ul>
232
  <p>
views/settings.php CHANGED
@@ -9,6 +9,9 @@
9
  *
10
  */
11
 
 
 
 
12
  $page_title = $this->friendly_name . ' Settings';
13
  $namespace = $this->namespace;
14
 
9
  *
10
  */
11
 
12
+ //Check the license
13
+ do_action( 'wpbackitup_check_license');
14
+
15
  $page_title = $this->friendly_name . ' Settings';
16
  $namespace = $this->namespace;
17
 
views/support.php CHANGED
@@ -9,6 +9,9 @@
9
  *
10
  */
11
 
 
 
 
12
  $page_title = $this->friendly_name . ' Support';
13
  $namespace = $this->namespace;
14
 
@@ -16,11 +19,15 @@
16
  $is_lite_registered = $this->is_lite_registered();
17
 
18
  $support_email =$this->support_email();
 
 
 
19
 
 
20
  $disabled='';
21
- // if (!$license_active && !$is_lite_registered){
22
- // $disabled='disabled';
23
- // }
24
 
25
  ?>
26
  <?php if (!empty($_GET["s"]) && '1' == $_GET["s"]) : ?>
@@ -72,12 +79,17 @@
72
  ?>
73
 
74
  </p>
75
- <input <?php echo($disabled) ; ?> type="checkbox" name="support_include_logs" id="support_include_logs" value="1" checked> <label for="support_include_logs">send logs</label><br>
76
 
77
  <div class="submit"><input <?php echo($disabled) ; ?> type="submit" name="send_ticket" class="button-primary" value="<?php _e("Send", $namespace) ?>" />
78
- <?php if (!$license_active) : ?>
79
- * Premium customers receive priority support.
 
80
  <?php endif; ?>
 
 
 
 
81
  </div>
82
 
83
  <?php
9
  *
10
  */
11
 
12
+ //Check the license
13
+ do_action( 'wpbackitup_check_license');
14
+
15
  $page_title = $this->friendly_name . ' Support';
16
  $namespace = $this->namespace;
17
 
19
  $is_lite_registered = $this->is_lite_registered();
20
 
21
  $support_email =$this->support_email();
22
+ if (empty($support_email)){
23
+ $support_email =$this->license_customer_email();
24
+ }
25
 
26
+ //Force registration for support
27
  $disabled='';
28
+ if (!$license_active && !$is_lite_registered){
29
+ $disabled='disabled';
30
+ }
31
 
32
  ?>
33
  <?php if (!empty($_GET["s"]) && '1' == $_GET["s"]) : ?>
79
  ?>
80
 
81
  </p>
82
+ <!-- <input <?php echo($disabled) ; ?> type="checkbox" name="support_include_logs" id="support_include_logs" value="1" checked> <label for="support_include_logs">send logs</label><br>-->
83
 
84
  <div class="submit"><input <?php echo($disabled) ; ?> type="submit" name="send_ticket" class="button-primary" value="<?php _e("Send", $namespace) ?>" />
85
+
86
+ <?php if (!$license_active && !$is_lite_registered) : ?>
87
+ <span style="color:red">* Please register your version of WP BackItUp for access to support.</span>
88
  <?php endif; ?>
89
+
90
+ <?php if (!$license_active && $is_lite_registered) : ?>
91
+ * Premium customers receive priority support.
92
+ <?php endif; ?>
93
  </div>
94
 
95
  <?php
wp-backitup.php CHANGED
@@ -13,7 +13,7 @@
13
  Plugin Name: WP Backitup
14
  Plugin URI: http://www.wpbackitup.com
15
  Description: Backup your content, settings, themes, plugins and media in just a few simple clicks.
16
- Version: 1.10.6
17
  Author: Chris Simmons
18
  Author URI: http://www.wpbackitup.com
19
  License: GPL3
@@ -35,7 +35,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
35
  */
36
 
37
  define( 'WPBACKITUP__NAMESPACE', 'wp-backitup' );
38
- define( 'WPBACKITUP__VERSION', '1.10.6');
 
 
 
 
39
  define( 'WPBACKITUP__DEBUG', false );
40
  define( 'WPBACKITUP__MINIMUM_WP_VERSION', '3.0' );
41
  define( 'WPBACKITUP__ITEM_NAME', 'WP Backitup' );
@@ -66,22 +70,27 @@ define( 'WPBACKITUP__THEMES_FOLDER',basename(get_theme_root()));
66
  define( 'WPBACKITUP__SQL_DBBACKUP_FILENAME', 'db-backup.sql');
67
 
68
  define( 'WPBACKITUP__BACKUP_IGNORE_LIST', WPBACKITUP__BACKUP_FOLDER .',' .WPBACKITUP__RESTORE_FOLDER .',updraft*,wp-clone*,backwpup*,backupwordpress*,cache,backupcreator*,backupbuddy*');
 
 
 
69
  define( 'WPBACKITUP__TASK_TIMEOUT_SECONDS', 300);//300 = 5 minutes
70
  define( 'WPBACKITUP__SCRIPT_TIMEOUT_SECONDS', 900);//900 = 15 minutes
71
 
72
  define( 'WPBACKITUP__BACKUP_RETAINED_DAYS', 5);//5 days
73
  define( 'WPBACKITUP__SUPPORT_EMAIL', 'wpbackitupcomsupport@wpbackitup.freshdesk.com');
74
 
 
75
  define( 'WPBACKITUP__ZIP_MAX_FILE_SIZE', 524288000); //524288000; # 500Mb
76
  define( 'WPBACKITUP__THEMES_BATCH_SIZE', 5000); //~100kb each = 5000*100 = 500000 kb = 500 mb
77
  define( 'WPBACKITUP__PLUGINS_BATCH_SIZE', 5000); //~100kb each = 5000*100 = 500000 kb = 500 mb
78
  define( 'WPBACKITUP__OTHERS_BATCH_SIZE', 500); //~100kb each = 5000*100 = 500000 kb = 500 mb
79
  define( 'WPBACKITUP__UPLOADS_BATCH_SIZE', 500); //anyones guess here
80
 
 
 
81
  register_activation_hook( __FILE__, array( 'WPBackitup_Admin', 'activate' ) );
82
  register_deactivation_hook( __FILE__, array( 'WPBackitup_Admin', 'deactivate' ) );
83
 
84
-
85
  function wpbackitup_modify_cron_schedules($schedules) {
86
  $schedules['weekly'] = array('interval' => 604800, 'display' => 'Once Weekly');
87
  $schedules['monthly'] = array('interval' => 2592000, 'display' => 'Once Monthly');
@@ -144,6 +153,13 @@ if (!is_admin()
144
  require_once( WPBACKITUP__PLUGIN_PATH .'/lib/includes/class-wpbackitup-admin.php' );
145
  require_once( WPBACKITUP__PLUGIN_PATH .'/lib/includes/class-logger.php' );
146
 
 
 
 
 
 
147
  global $WPBackitup;
148
  $WPBackitup = WPBackitup_Admin::get_instance();
149
  $WPBackitup->initialize();
 
 
13
  Plugin Name: WP Backitup
14
  Plugin URI: http://www.wpbackitup.com
15
  Description: Backup your content, settings, themes, plugins and media in just a few simple clicks.
16
+ Version: 1.10.7
17
  Author: Chris Simmons
18
  Author URI: http://www.wpbackitup.com
19
  License: GPL3
35
  */
36
 
37
  define( 'WPBACKITUP__NAMESPACE', 'wp-backitup' );
38
+ define( 'WPBACKITUP__MAJOR_VERSION', 1);
39
+ define( 'WPBACKITUP__MINOR_VERSION', 10);
40
+ define( 'WPBACKITUP__MAINTENANCE_VERSION', 7);
41
+ define( 'WPBACKITUP__BUILD_VERSION', 0);
42
+ define( 'WPBACKITUP__VERSION',sprintf("%d.%d.%d.%d", WPBACKITUP__MAJOR_VERSION, WPBACKITUP__MINOR_VERSION,WPBACKITUP__MAINTENANCE_VERSION,WPBACKITUP__BUILD_VERSION));
43
  define( 'WPBACKITUP__DEBUG', false );
44
  define( 'WPBACKITUP__MINIMUM_WP_VERSION', '3.0' );
45
  define( 'WPBACKITUP__ITEM_NAME', 'WP Backitup' );
70
  define( 'WPBACKITUP__SQL_DBBACKUP_FILENAME', 'db-backup.sql');
71
 
72
  define( 'WPBACKITUP__BACKUP_IGNORE_LIST', WPBACKITUP__BACKUP_FOLDER .',' .WPBACKITUP__RESTORE_FOLDER .',updraft*,wp-clone*,backwpup*,backupwordpress*,cache,backupcreator*,backupbuddy*');
73
+ define( 'WPBACKITUP__BACKUP_GLOBAL_IGNORE_LIST','.htaccess');//comma seperated list with no spaces after comma
74
+
75
+ define( 'WPBACKITUP__BACKUP_OTHER_IGNORE_LIST', WPBACKITUP__BACKUP_FOLDER .',' .WPBACKITUP__RESTORE_FOLDER .',updraft*,wp-clone*,backwpup*,backupwordpress*,cache,backupcreator*,backupbuddy*,wptouch-data*,backups*');
76
  define( 'WPBACKITUP__TASK_TIMEOUT_SECONDS', 300);//300 = 5 minutes
77
  define( 'WPBACKITUP__SCRIPT_TIMEOUT_SECONDS', 900);//900 = 15 minutes
78
 
79
  define( 'WPBACKITUP__BACKUP_RETAINED_DAYS', 5);//5 days
80
  define( 'WPBACKITUP__SUPPORT_EMAIL', 'wpbackitupcomsupport@wpbackitup.freshdesk.com');
81
 
82
+ define( 'WPBACKITUP__SQL_BULK_INSERT_SIZE', 1000);
83
  define( 'WPBACKITUP__ZIP_MAX_FILE_SIZE', 524288000); //524288000; # 500Mb
84
  define( 'WPBACKITUP__THEMES_BATCH_SIZE', 5000); //~100kb each = 5000*100 = 500000 kb = 500 mb
85
  define( 'WPBACKITUP__PLUGINS_BATCH_SIZE', 5000); //~100kb each = 5000*100 = 500000 kb = 500 mb
86
  define( 'WPBACKITUP__OTHERS_BATCH_SIZE', 500); //~100kb each = 5000*100 = 500000 kb = 500 mb
87
  define( 'WPBACKITUP__UPLOADS_BATCH_SIZE', 500); //anyones guess here
88
 
89
+
90
+ //activation hooks
91
  register_activation_hook( __FILE__, array( 'WPBackitup_Admin', 'activate' ) );
92
  register_deactivation_hook( __FILE__, array( 'WPBackitup_Admin', 'deactivate' ) );
93
 
 
94
  function wpbackitup_modify_cron_schedules($schedules) {
95
  $schedules['weekly'] = array('interval' => 604800, 'display' => 'Once Weekly');
96
  $schedules['monthly'] = array('interval' => 2592000, 'display' => 'Once Monthly');
153
  require_once( WPBACKITUP__PLUGIN_PATH .'/lib/includes/class-wpbackitup-admin.php' );
154
  require_once( WPBACKITUP__PLUGIN_PATH .'/lib/includes/class-logger.php' );
155
 
156
+ //Shared Classes
157
+ if( !class_exists('WPBackItUp_Job_v2') ) {
158
+ include_once(WPBACKITUP__PLUGIN_PATH .'/lib/includes/class-job-v2.php');
159
+ }
160
+
161
  global $WPBackitup;
162
  $WPBackitup = WPBackitup_Admin::get_instance();
163
  $WPBackitup->initialize();
164
+
165
+