Migration, Backup, Staging – WPvivid - Version 0.9.19

Version Description

  • Added a php memory limit option to settings, you can use it to temporarily increase php memory limit when encountering a memory exhausted error in backup process.
  • Fixed: Backup does not exist error that occurred in some cases when downloading the backup to local.
  • Fixed: Backup error that occurred when the wp-content/plugins folder on a web server was moved or renamed.
  • Fixed: Restore error that occurred in some cases when restoring a backup to a different domain.
  • Enhanced the clean backup cache option in settings.
  • Optimized backup process.
Download this release

Release Info

Developer wpvivid
Plugin Icon 128x128 Migration, Backup, Staging – WPvivid
Version 0.9.19
Comparing to
See all releases

Code changes from version 0.9.18 to 0.9.19

admin/partials/wpvivid-settings-page-display.php CHANGED
@@ -38,6 +38,9 @@ function wpvivid_general_settings()
38
  $wpvivid_domain_include = '';
39
  }
40
  }
 
 
 
41
  global $wpvivid_pulgin;
42
  $out_of_date=$wpvivid_pulgin->_get_out_of_date_info();
43
  ?>
@@ -60,6 +63,11 @@ function wpvivid_general_settings()
60
  <input type="text" placeholder="600" option="setting" name="max_execution_time" id="wpvivid_option_timeout" class="all-options" value="<?php esc_attr_e($general_setting['options']['wpvivid_common_setting']['max_execution_time'], 'wpvivid'); ?>" onkeyup="value=value.replace(/\D/g,'')" />Seconds
61
  <div><p><?php _e( 'The time-out is not your server PHP time-out. With the execution time exhausted, our plugin will shut the process of backup down. If the progress of backup encounters a time-out, that means you have a medium or large sized website, please try to scale the value bigger. ', 'wpvivid' ); ?></p></div>
62
  </div>
 
 
 
 
 
63
  <div>
64
  <select option="setting" name="max_backup_count" id="wpvivid_max_backup_count">
65
  <?php
@@ -162,7 +170,7 @@ function wpvivid_compressing()
162
  <label>
163
  <input type="radio" option="setting" name="no_compress" value="1" <?php esc_attr_e($wpvivid_setting_no_compress, 'wpvivid'); ?> />
164
  <span><?php _e( 'Only Archive without compressing', 'wpvivid' ); ?></span>
165
- <span><?php _e( 'It will cause a lower CPU Usage and is recommended in a web hosting/ shared hosting environment.', 'wpvivid' ); ?>
166
  </label><br>
167
  <label>
168
  <input type="radio" option="setting" name="no_compress" value="0" <?php esc_attr_e($wpvivid_setting_compress, 'wpvivid'); ?> />
38
  $wpvivid_domain_include = '';
39
  }
40
  }
41
+ if(!isset($general_setting['options']['wpvivid_common_setting']['memory_limit'])){
42
+ $general_setting['options']['wpvivid_common_setting']['memory_limit']=WPVIVID_MEMORY_LIMIT;
43
+ }
44
  global $wpvivid_pulgin;
45
  $out_of_date=$wpvivid_pulgin->_get_out_of_date_info();
46
  ?>
63
  <input type="text" placeholder="600" option="setting" name="max_execution_time" id="wpvivid_option_timeout" class="all-options" value="<?php esc_attr_e($general_setting['options']['wpvivid_common_setting']['max_execution_time'], 'wpvivid'); ?>" onkeyup="value=value.replace(/\D/g,'')" />Seconds
64
  <div><p><?php _e( 'The time-out is not your server PHP time-out. With the execution time exhausted, our plugin will shut the process of backup down. If the progress of backup encounters a time-out, that means you have a medium or large sized website, please try to scale the value bigger. ', 'wpvivid' ); ?></p></div>
65
  </div>
66
+ <div><strong><?php _e('PHP memory limit', 'wpvivid'); ?></strong></div>
67
+ <div class="schedule-tab-block setting-page-content">
68
+ <input type="text" placeholder="256" option="setting" name="memory_limit" class="all-options" value="<?php esc_attr_e(str_replace('M', '', $general_setting['options']['wpvivid_common_setting']['memory_limit']), 'wpvivid'); ?>" onkeyup="value=value.replace(/\D/g,'')" />MB
69
+ <div><p><?php _e('Adjust this value to apply for a temporary PHP memory limit for WPvivid backup plugin to run a backup. We set this value to 256M by default. Increase the value if you encounter a memory exhausted error. Note: some web hosting providers may not support this.', 'wpvivid'); ?></p></div>
70
+ </div>
71
  <div>
72
  <select option="setting" name="max_backup_count" id="wpvivid_max_backup_count">
73
  <?php
170
  <label>
171
  <input type="radio" option="setting" name="no_compress" value="1" <?php esc_attr_e($wpvivid_setting_no_compress, 'wpvivid'); ?> />
172
  <span><?php _e( 'Only Archive without compressing', 'wpvivid' ); ?></span>
173
+ <span><?php _e( 'It will cause a lower CPU Usage and is recommended in a web hosting/ shared hosting environment.', 'wpvivid' ); ?></span>
174
  </label><br>
175
  <label>
176
  <input type="radio" option="setting" name="no_compress" value="0" <?php esc_attr_e($wpvivid_setting_compress, 'wpvivid'); ?> />
includes/class-wpvivid-backup-database.php CHANGED
@@ -80,6 +80,7 @@ class WPvivid_Backup_Database
80
  $backup_file =$data['sql_file_name'];
81
 
82
  $privileges = array();
 
83
  require_once 'class-wpvivid-mysqldump.php';
84
  if(class_exists('PDO'))
85
  {
80
  $backup_file =$data['sql_file_name'];
81
 
82
  $privileges = array();
83
+ require_once 'class-wpvivid-mysqldump-method.php';
84
  require_once 'class-wpvivid-mysqldump.php';
85
  if(class_exists('PDO'))
86
  {
includes/class-wpvivid-backup.php CHANGED
@@ -240,8 +240,8 @@ class WPvivid_Backup_Task
240
  {
241
  $backup_data['root_path']=WP_CONTENT_DIR;
242
  $backup_data['prefix']=$this->get_prefix().'_backup_plugin';
243
- $backup_data['files_root']=$this->transfer_path(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.'plugins');
244
- $exclude_regex[]='#^'.preg_quote($this -> transfer_path(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.'plugins'.DIRECTORY_SEPARATOR.'wpvivid-backuprestore'), '/').'#';
245
  $backup_data['exclude_regex']=$exclude_regex;
246
  $backup_data['include_regex']=array();
247
  }
@@ -285,7 +285,9 @@ class WPvivid_Backup_Task
285
  $backup_data['json_info']['wp_core']=1;
286
  $include_regex[]='#^'.preg_quote($this -> transfer_path(get_home_path().DIRECTORY_SEPARATOR.'wp-admin'), '/').'#';
287
  $include_regex[]='#^'.preg_quote($this->transfer_path(get_home_path().DIRECTORY_SEPARATOR.'wp-includes'), '/').'#';
288
- $backup_data['exclude_regex']=array();
 
 
289
  $backup_data['include_regex']=$include_regex;
290
  }
291
  else if($backup==WPVIVID_BACKUP_TYPE_MERGE)
@@ -460,7 +462,8 @@ class WPvivid_Backup_Task
460
  public function getFileLoop(&$files,$path,$exclude_regex=array(),$include_regex=array(),$exclude_file_size=array(),$include_dir = true)
461
  {
462
  $count = 0;
463
- if(is_dir($path)) {
 
464
  $handler = opendir($path);
465
  while (($filename = readdir($handler)) !== false) {
466
  if ($filename != "." && $filename != "..") {
@@ -897,7 +900,7 @@ class WPvivid_Backup_Item
897
  return $ret;
898
  }
899
 
900
- public function get_file_md5($file_name)
901
  {
902
  $zip=new WPvivid_ZipClass();
903
  $json=$zip->get_json_data($file_name);
@@ -922,7 +925,7 @@ class WPvivid_Backup_Item
922
  return '';
923
  }
924
  }
925
- }
926
 
927
  public function get_local_path()
928
  {
@@ -1364,6 +1367,7 @@ class WPvivid_Backup
1364
  WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'backup', $next_backup['key'],1,'Backing up '.$next_backup['key'].' finished.',$result);
1365
  $this->task->update_backup_result($next_backup,$result);
1366
  $wpvivid_pulgin->check_cancel_backup($task_id);
 
1367
  $next_backup=$this->task->get_need_backup();
1368
  }
1369
 
240
  {
241
  $backup_data['root_path']=WP_CONTENT_DIR;
242
  $backup_data['prefix']=$this->get_prefix().'_backup_plugin';
243
+ $backup_data['files_root']=$this->transfer_path(WP_PLUGIN_DIR);
244
+ $exclude_regex[]='#^'.preg_quote($this -> transfer_path(WP_PLUGIN_DIR.DIRECTORY_SEPARATOR.'wpvivid-backuprestore'), '/').'#';
245
  $backup_data['exclude_regex']=$exclude_regex;
246
  $backup_data['include_regex']=array();
247
  }
285
  $backup_data['json_info']['wp_core']=1;
286
  $include_regex[]='#^'.preg_quote($this -> transfer_path(get_home_path().DIRECTORY_SEPARATOR.'wp-admin'), '/').'#';
287
  $include_regex[]='#^'.preg_quote($this->transfer_path(get_home_path().DIRECTORY_SEPARATOR.'wp-includes'), '/').'#';
288
+ $exclude_regex[]='#^'.preg_quote($this->transfer_path(get_home_path().DIRECTORY_SEPARATOR), '/').'pclzip-.*\.tmp#';
289
+ $exclude_regex[]='#^'.preg_quote($this->transfer_path(get_home_path().DIRECTORY_SEPARATOR), '/').'pclzip-.*\.gz#';
290
+ $backup_data['exclude_regex']=$exclude_regex;
291
  $backup_data['include_regex']=$include_regex;
292
  }
293
  else if($backup==WPVIVID_BACKUP_TYPE_MERGE)
462
  public function getFileLoop(&$files,$path,$exclude_regex=array(),$include_regex=array(),$exclude_file_size=array(),$include_dir = true)
463
  {
464
  $count = 0;
465
+ if(is_dir($path))
466
+ {
467
  $handler = opendir($path);
468
  while (($filename = readdir($handler)) !== false) {
469
  if ($filename != "." && $filename != "..") {
900
  return $ret;
901
  }
902
 
903
+ /*public function get_file_md5($file_name)
904
  {
905
  $zip=new WPvivid_ZipClass();
906
  $json=$zip->get_json_data($file_name);
925
  return '';
926
  }
927
  }
928
+ }*/
929
 
930
  public function get_local_path()
931
  {
1367
  WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'backup', $next_backup['key'],1,'Backing up '.$next_backup['key'].' finished.',$result);
1368
  $this->task->update_backup_result($next_backup,$result);
1369
  $wpvivid_pulgin->check_cancel_backup($task_id);
1370
+ unset($next_backup);
1371
  $next_backup=$this->task->get_need_backup();
1372
  }
1373
 
includes/class-wpvivid-downloader.php CHANGED
@@ -60,9 +60,12 @@ class WPvivid_downloader
60
  return false;
61
  }
62
  $download_option='';
63
- if(isset($backup['backup']['files'])){
64
- foreach ($backup['backup']['files'] as $file){
65
- if ($file['file_name'] == $download_info['file_name']) {
 
 
 
66
  $download_option = 'all';
67
  $files[] = $file;
68
  break;
@@ -92,7 +95,10 @@ class WPvivid_downloader
92
  }
93
 
94
  if(empty($files))
 
95
  return false;
 
 
96
 
97
  $local_path=WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$backup['local']['path'].DIRECTORY_SEPARATOR;
98
  $need_download_files=array();
60
  return false;
61
  }
62
  $download_option='';
63
+ if(isset($backup['backup']['files']))
64
+ {
65
+ foreach ($backup['backup']['files'] as $file)
66
+ {
67
+ if ($file['file_name'] == $download_info['file_name'])
68
+ {
69
  $download_option = 'all';
70
  $files[] = $file;
71
  break;
95
  }
96
 
97
  if(empty($files))
98
+ {
99
  return false;
100
+ }
101
+
102
 
103
  $local_path=WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$backup['local']['path'].DIRECTORY_SEPARATOR;
104
  $need_download_files=array();
includes/class-wpvivid-mysqldump-method.php ADDED
@@ -0,0 +1,1501 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Enum with all available compression methods
5
+ *
6
+ */
7
+
8
+ abstract class CompressMethod
9
+ {
10
+ public static $enums = array(
11
+ "None",
12
+ "Gzip",
13
+ "Bzip2"
14
+ );
15
+
16
+ /**
17
+ * @param string $c
18
+ * @return boolean
19
+ */
20
+ public static function isValid($c)
21
+ {
22
+ return in_array($c, self::$enums);
23
+ }
24
+ }
25
+
26
+ abstract class CompressManagerFactory
27
+ {
28
+ /**
29
+ * @param string $c
30
+ * @return CompressBzip2|CompressGzip|CompressNone
31
+ */
32
+ public static function create($c)
33
+ {
34
+ $c = ucfirst(strtolower($c));
35
+ if (! CompressMethod::isValid($c)) {
36
+ throw new Exception("Compression method ($c) is not defined yet");
37
+ }
38
+
39
+ $method = __NAMESPACE__ . "\\" . "Compress" . $c;
40
+
41
+ return new $method;
42
+ }
43
+ }
44
+
45
+ class CompressBzip2 extends CompressManagerFactory
46
+ {
47
+ private $fileHandler = null;
48
+
49
+ public function __construct()
50
+ {
51
+ if (! function_exists("bzopen")) {
52
+ throw new Exception("Compression is enabled, but bzip2 lib is not installed or configured properly");
53
+ }
54
+ }
55
+
56
+ /**
57
+ * @param string $filename
58
+ */
59
+ public function open($filename)
60
+ {
61
+ $this->fileHandler = bzopen($filename, "w");
62
+ if (false === $this->fileHandler) {
63
+ throw new Exception("Output file is not writable");
64
+ }
65
+
66
+ return true;
67
+ }
68
+
69
+ public function write($str)
70
+ {
71
+ if (false === ($bytesWritten = bzwrite($this->fileHandler, $str))) {
72
+ throw new Exception("Writting to file failed! Probably, there is no more free space left?");
73
+ }
74
+ return $bytesWritten;
75
+ }
76
+
77
+ public function close()
78
+ {
79
+ return bzclose($this->fileHandler);
80
+ }
81
+ }
82
+
83
+ class CompressGzip extends CompressManagerFactory
84
+ {
85
+ private $fileHandler = null;
86
+
87
+ public function __construct()
88
+ {
89
+ if (! function_exists("gzopen")) {
90
+ throw new Exception("Compression is enabled, but gzip lib is not installed or configured properly");
91
+ }
92
+ }
93
+
94
+ /**
95
+ * @param string $filename
96
+ */
97
+ public function open($filename)
98
+ {
99
+ $this->fileHandler = gzopen($filename, "wb");
100
+ if (false === $this->fileHandler) {
101
+ throw new Exception("Output file is not writable");
102
+ }
103
+
104
+ return true;
105
+ }
106
+
107
+ public function write($str)
108
+ {
109
+ if (false === ($bytesWritten = gzwrite($this->fileHandler, $str))) {
110
+ throw new Exception("Writting to file failed! Probably, there is no more free space left?");
111
+ }
112
+ return $bytesWritten;
113
+ }
114
+
115
+ public function close()
116
+ {
117
+ return gzclose($this->fileHandler);
118
+ }
119
+ }
120
+
121
+ class CompressNone extends CompressManagerFactory
122
+ {
123
+ private $fileHandler = null;
124
+
125
+ /**
126
+ * @param string $filename
127
+ */
128
+ public function open($filename)
129
+ {
130
+ $this->fileHandler = fopen($filename, "wb");
131
+ if (false === $this->fileHandler) {
132
+ throw new Exception("Output file is not writable");
133
+ }
134
+
135
+ return true;
136
+ }
137
+
138
+ public function write($str)
139
+ {
140
+ if (false === ($bytesWritten = fwrite($this->fileHandler, $str))) {
141
+ throw new Exception("Writting to file failed! Probably, there is no more free space left?");
142
+ }
143
+ return $bytesWritten;
144
+ }
145
+
146
+ public function close()
147
+ {
148
+ return fclose($this->fileHandler);
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Enum with all available TypeAdapter implementations
154
+ *
155
+ */
156
+ abstract class TypeAdapter
157
+ {
158
+ public static $enums = array(
159
+ "Sqlite",
160
+ "Mysql",
161
+ "Wpdb"
162
+ );
163
+
164
+ /**
165
+ * @param string $c
166
+ * @return boolean
167
+ */
168
+ public static function isValid($c)
169
+ {
170
+ return in_array($c, self::$enums);
171
+ }
172
+ }
173
+
174
+ /**
175
+ * TypeAdapter Factory
176
+ *
177
+ */
178
+ abstract class TypeAdapterFactory
179
+ {
180
+ /**
181
+ * @param string $c Type of database factory to create (Mysql, Sqlite,...)
182
+ * @param PDO $dbHandler
183
+ */
184
+ public static function create($c, $dbHandler = null)
185
+ {
186
+ $c = ucfirst(strtolower($c));
187
+ if (! TypeAdapter::isValid($c)) {
188
+ throw new Exception("Database type support for ($c) not yet available");
189
+ }
190
+ $method = __NAMESPACE__ . "\\" . "TypeAdapter" . $c;
191
+ return new $method($dbHandler);
192
+ }
193
+
194
+ /**
195
+ * function databases Add sql to create and use database
196
+ * @todo make it do something with sqlite
197
+ */
198
+ public function databases()
199
+ {
200
+ return "";
201
+ }
202
+
203
+ public function show_create_table($tableName)
204
+ {
205
+ return "SELECT tbl_name as 'Table', sql as 'Create Table' " .
206
+ "FROM sqlite_master " .
207
+ "WHERE type='table' AND tbl_name='$tableName'";
208
+ }
209
+
210
+ /**
211
+ * function create_table Get table creation code from database
212
+ * @todo make it do something with sqlite
213
+ */
214
+ public function create_table($row, $dumpSettings)
215
+ {
216
+ return "";
217
+ }
218
+
219
+ public function show_create_view($viewName)
220
+ {
221
+ return "SELECT tbl_name as 'View', sql as 'Create View' " .
222
+ "FROM sqlite_master " .
223
+ "WHERE type='view' AND tbl_name='$viewName'";
224
+ }
225
+
226
+ /**
227
+ * function create_view Get view creation code from database
228
+ * @todo make it do something with sqlite
229
+ */
230
+ public function create_view($row)
231
+ {
232
+ return "";
233
+ }
234
+
235
+ /**
236
+ * function show_create_trigger Get trigger creation code from database
237
+ * @todo make it do something with sqlite
238
+ */
239
+ public function show_create_trigger($triggerName)
240
+ {
241
+ return "";
242
+ }
243
+
244
+ /**
245
+ * function create_trigger Modify trigger code, add delimiters, etc
246
+ * @todo make it do something with sqlite
247
+ */
248
+ public function create_trigger($triggerName)
249
+ {
250
+ return "";
251
+ }
252
+
253
+ /**
254
+ * function create_procedure Modify procedure code, add delimiters, etc
255
+ * @todo make it do something with sqlite
256
+ */
257
+ public function create_procedure($procedureName, $dumpSettings)
258
+ {
259
+ return "";
260
+ }
261
+
262
+ public function show_tables()
263
+ {
264
+ return "SELECT tbl_name FROM sqlite_master WHERE type='table'";
265
+ }
266
+
267
+ public function show_views()
268
+ {
269
+ return "SELECT tbl_name FROM sqlite_master WHERE type='view'";
270
+ }
271
+
272
+ public function show_triggers()
273
+ {
274
+ return "SELECT name FROM sqlite_master WHERE type='trigger'";
275
+ }
276
+
277
+ public function show_columns()
278
+ {
279
+ if (func_num_args() != 1) {
280
+ return "";
281
+ }
282
+
283
+ $args = func_get_args();
284
+
285
+ return "pragma table_info(${args[0]})";
286
+ }
287
+
288
+ public function show_procedures()
289
+ {
290
+ return "";
291
+ }
292
+
293
+ public function show_events()
294
+ {
295
+ return "";
296
+ }
297
+
298
+ public function setup_transaction()
299
+ {
300
+ return "";
301
+ }
302
+
303
+ public function start_transaction()
304
+ {
305
+ return "BEGIN EXCLUSIVE";
306
+ }
307
+
308
+ public function commit_transaction()
309
+ {
310
+ return "COMMIT";
311
+ }
312
+
313
+ public function lock_table()
314
+ {
315
+ return "";
316
+ }
317
+
318
+ public function unlock_table()
319
+ {
320
+ return "";
321
+ }
322
+
323
+ public function start_add_lock_table()
324
+ {
325
+ return PHP_EOL;
326
+ }
327
+
328
+ public function end_add_lock_table()
329
+ {
330
+ return PHP_EOL;
331
+ }
332
+
333
+ public function start_add_disable_keys()
334
+ {
335
+ return PHP_EOL;
336
+ }
337
+
338
+ public function end_add_disable_keys()
339
+ {
340
+ return PHP_EOL;
341
+ }
342
+
343
+ public function start_disable_foreign_keys_check()
344
+ {
345
+ return PHP_EOL;
346
+ }
347
+
348
+ public function end_disable_foreign_keys_check()
349
+ {
350
+ return PHP_EOL;
351
+ }
352
+
353
+ public function add_drop_database()
354
+ {
355
+ return PHP_EOL;
356
+ }
357
+
358
+ public function add_drop_trigger()
359
+ {
360
+ return PHP_EOL;
361
+ }
362
+
363
+ public function drop_table()
364
+ {
365
+ return PHP_EOL;
366
+ }
367
+
368
+ public function drop_view()
369
+ {
370
+ return PHP_EOL;
371
+ }
372
+
373
+ /**
374
+ * Decode column metadata and fill info structure.
375
+ * type, is_numeric and is_blob will always be available.
376
+ *
377
+ * @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
378
+ * @return array
379
+ */
380
+ public function parseColumnType($colType)
381
+ {
382
+ return array();
383
+ }
384
+
385
+ public function backup_parameters()
386
+ {
387
+ return PHP_EOL;
388
+ }
389
+
390
+ public function restore_parameters()
391
+ {
392
+ return PHP_EOL;
393
+ }
394
+ }
395
+
396
+ class TypeAdapterPgsql extends TypeAdapterFactory
397
+ {
398
+ }
399
+
400
+ class TypeAdapterDblib extends TypeAdapterFactory
401
+ {
402
+ }
403
+
404
+ class TypeAdapterSqlite extends TypeAdapterFactory
405
+ {
406
+ }
407
+
408
+ class TypeAdapterMysql extends TypeAdapterFactory
409
+ {
410
+
411
+ private $dbHandler = null;
412
+
413
+ private $dsn;
414
+ private $user;
415
+ private $pass;
416
+ private $pdoSettings;
417
+ private $reconnect_count;
418
+
419
+ // Numerical Mysql types
420
+ public $mysqlTypes = array(
421
+ 'numerical' => array(
422
+ 'bit',
423
+ 'tinyint',
424
+ 'smallint',
425
+ 'mediumint',
426
+ 'int',
427
+ 'integer',
428
+ 'bigint',
429
+ 'real',
430
+ 'double',
431
+ 'float',
432
+ 'decimal',
433
+ 'numeric'
434
+ ),
435
+ 'blob' => array(
436
+ 'tinyblob',
437
+ 'blob',
438
+ 'mediumblob',
439
+ 'longblob',
440
+ 'binary',
441
+ 'varbinary',
442
+ 'bit',
443
+ 'geometry', /* http://bugs.mysql.com/bug.php?id=43544 */
444
+ 'point',
445
+ 'linestring',
446
+ 'polygon',
447
+ 'multipoint',
448
+ 'multilinestring',
449
+ 'multipolygon',
450
+ 'geometrycollection',
451
+ )
452
+ );
453
+
454
+ public function __construct ($dbHandler)
455
+ {
456
+ $this->dbHandler = $dbHandler;
457
+ $this->dsn='';
458
+ $this->user='';
459
+ $this->pass='';
460
+ $this->pdoSettings=array();
461
+ $this->reconnect_count=0;
462
+ }
463
+
464
+ public function set_connect_info($dsn,$user,$pass,$pdoSetting)
465
+ {
466
+ $this->dsn=$dsn;
467
+ $this->user=$user;
468
+ $this->pass=$pass;
469
+ $this->pdoSettings=$pdoSetting;
470
+ }
471
+
472
+ public function databases()
473
+ {
474
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
475
+ $args = func_get_args();
476
+ $databaseName = $args[0];
477
+
478
+ $resultSet = $this->query("SHOW VARIABLES LIKE 'character_set_database';");
479
+ $characterSet = $resultSet->fetchColumn(1);
480
+ $resultSet->closeCursor();
481
+
482
+ $resultSet = $this->query("SHOW VARIABLES LIKE 'collation_database';");
483
+ $collationDb = $resultSet->fetchColumn(1);
484
+ $resultSet->closeCursor();
485
+ $ret = "";
486
+
487
+ $ret .= "CREATE DATABASE /*!32312 IF NOT EXISTS*/ `${databaseName}`".
488
+ " /*!40100 DEFAULT CHARACTER SET ${characterSet} " .
489
+ " COLLATE ${collationDb} */;" . PHP_EOL . PHP_EOL .
490
+ "USE `${databaseName}`;" . PHP_EOL . PHP_EOL;
491
+
492
+ return $ret;
493
+ }
494
+
495
+ public function show_create_table($tableName)
496
+ {
497
+ return "SHOW CREATE TABLE `$tableName`";
498
+ }
499
+
500
+ public function show_create_view($viewName)
501
+ {
502
+ return "SHOW CREATE VIEW `$viewName`";
503
+ }
504
+
505
+ public function show_create_trigger($triggerName)
506
+ {
507
+ return "SHOW CREATE TRIGGER `$triggerName`";
508
+ }
509
+
510
+ public function show_create_procedure($procedureName)
511
+ {
512
+ return "SHOW CREATE PROCEDURE `$procedureName`";
513
+ }
514
+
515
+ public function show_create_event($eventName)
516
+ {
517
+ return "SHOW CREATE EVENT `$eventName`";
518
+ }
519
+
520
+ public function create_table( $row, $dumpSettings )
521
+ {
522
+
523
+ if ( !isset($row['Create Table']) ) {
524
+ throw new Exception("Error getting table code, unknown output");
525
+ }
526
+
527
+ $createTable = str_replace('\'0000-00-00 00:00:00\'','\'1970-01-01 00:00:00\'',$row['Create Table']);
528
+
529
+ if ( $dumpSettings['reset-auto-increment'] ) {
530
+ $match = "/AUTO_INCREMENT=[0-9]+/s";
531
+ $replace = "";
532
+ $createTable = preg_replace($match, $replace, $createTable);
533
+ }
534
+
535
+ $ret = "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
536
+ "/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
537
+ $createTable . ";" . PHP_EOL .
538
+ "/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL .
539
+ PHP_EOL;
540
+ return $ret;
541
+ }
542
+
543
+ public function create_view($row)
544
+ {
545
+ $ret = "";
546
+ if (!isset($row['Create View'])) {
547
+ throw new Exception("Error getting view structure, unknown output");
548
+ }
549
+
550
+ $triggerStmt = $row['Create View'];
551
+
552
+ $triggerStmtReplaced1 = str_replace(
553
+ "CREATE ALGORITHM",
554
+ "/*!50001 CREATE ALGORITHM",
555
+ $triggerStmt
556
+ );
557
+ $triggerStmtReplaced2 = str_replace(
558
+ " DEFINER=",
559
+ " */" . PHP_EOL . "/*!50013 DEFINER=",
560
+ $triggerStmtReplaced1
561
+ );
562
+ $triggerStmtReplaced3 = str_replace(
563
+ " VIEW ",
564
+ " */" . PHP_EOL . "/*!50001 VIEW ",
565
+ $triggerStmtReplaced2
566
+ );
567
+ if (false === $triggerStmtReplaced1 ||
568
+ false === $triggerStmtReplaced2 ||
569
+ false === $triggerStmtReplaced3) {
570
+ $triggerStmtReplaced = $triggerStmt;
571
+ } else {
572
+ $triggerStmtReplaced = $triggerStmtReplaced3 . " */;";
573
+ }
574
+
575
+ $ret .= $triggerStmtReplaced . PHP_EOL . PHP_EOL;
576
+ return $ret;
577
+ }
578
+
579
+ public function create_trigger($row)
580
+ {
581
+ $ret = "";
582
+ if (!isset($row['SQL Original Statement'])) {
583
+ throw new Exception("Error getting trigger code, unknown output");
584
+ }
585
+
586
+ $triggerStmt = $row['SQL Original Statement'];
587
+ $triggerStmtReplaced = str_replace(
588
+ "CREATE DEFINER",
589
+ "/*!50003 CREATE*/ /*!50017 DEFINER",
590
+ $triggerStmt
591
+ );
592
+ $triggerStmtReplaced = str_replace(
593
+ " TRIGGER",
594
+ "*/ /*!50003 TRIGGER",
595
+ $triggerStmtReplaced
596
+ );
597
+ if ( false === $triggerStmtReplaced ) {
598
+ $triggerStmtReplaced = $triggerStmt . " /* ";
599
+ }
600
+
601
+ $ret .= "DELIMITER ;;" . PHP_EOL .
602
+ $triggerStmtReplaced . " */ ;;" . PHP_EOL .
603
+ "DELIMITER ;" . PHP_EOL . PHP_EOL;
604
+ return $ret;
605
+ }
606
+
607
+ public function create_procedure($row, $dumpSettings)
608
+ {
609
+ $ret = "";
610
+ if (!isset($row['Create Procedure'])) {
611
+ throw new Exception("Error getting procedure code, unknown output. " .
612
+ "Please check 'https://bugs.mysql.com/bug.php?id=14564'");
613
+ }
614
+ $procedureStmt = $row['Create Procedure'];
615
+
616
+ $ret .= "/*!50003 DROP PROCEDURE IF EXISTS `" .
617
+ $row['Procedure'] . "` */;" . PHP_EOL .
618
+ "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
619
+ "/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
620
+ "DELIMITER ;;" . PHP_EOL .
621
+ $procedureStmt . " ;;" . PHP_EOL .
622
+ "DELIMITER ;" . PHP_EOL .
623
+ "/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL . PHP_EOL;
624
+
625
+ return $ret;
626
+ }
627
+
628
+ public function create_event($row)
629
+ {
630
+ $ret = "";
631
+ if ( !isset($row['Create Event']) ) {
632
+ throw new Exception("Error getting event code, unknown output. " .
633
+ "Please check 'http://stackoverflow.com/questions/10853826/mysql-5-5-create-event-gives-syntax-error'");
634
+ }
635
+ $eventName = $row['Event'];
636
+ $eventStmt = $row['Create Event'];
637
+ $sqlMode = $row['sql_mode'];
638
+
639
+ $eventStmtReplaced = str_replace(
640
+ "CREATE DEFINER",
641
+ "/*!50106 CREATE*/ /*!50117 DEFINER",
642
+ $eventStmt
643
+ );
644
+ $eventStmtReplaced = str_replace(
645
+ " EVENT ",
646
+ "*/ /*!50106 EVENT ",
647
+ $eventStmtReplaced
648
+ );
649
+
650
+ if ( false === $eventStmtReplaced ) {
651
+ $eventStmtReplaced = $eventStmt . " /* ";
652
+ }
653
+
654
+ $ret .= "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;" . PHP_EOL .
655
+ "/*!50106 DROP EVENT IF EXISTS `" . $eventName . "` */;" . PHP_EOL .
656
+ "DELIMITER ;;" . PHP_EOL .
657
+ "/*!50003 SET @saved_cs_client = @@character_set_client */ ;;" . PHP_EOL .
658
+ "/*!50003 SET @saved_cs_results = @@character_set_results */ ;;" . PHP_EOL .
659
+ "/*!50003 SET @saved_col_connection = @@collation_connection */ ;;" . PHP_EOL .
660
+ "/*!50003 SET character_set_client = utf8 */ ;;" . PHP_EOL .
661
+ "/*!50003 SET character_set_results = utf8 */ ;;" . PHP_EOL .
662
+ "/*!50003 SET collation_connection = utf8_general_ci */ ;;" . PHP_EOL .
663
+ "/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;" . PHP_EOL .
664
+ "/*!50003 SET sql_mode = '" . $sqlMode . "' */ ;;" . PHP_EOL .
665
+ "/*!50003 SET @saved_time_zone = @@time_zone */ ;;" . PHP_EOL .
666
+ "/*!50003 SET time_zone = 'SYSTEM' */ ;;" . PHP_EOL .
667
+ $eventStmtReplaced . " */ ;;" . PHP_EOL .
668
+ "/*!50003 SET time_zone = @saved_time_zone */ ;;" . PHP_EOL .
669
+ "/*!50003 SET sql_mode = @saved_sql_mode */ ;;" . PHP_EOL .
670
+ "/*!50003 SET character_set_client = @saved_cs_client */ ;;" . PHP_EOL .
671
+ "/*!50003 SET character_set_results = @saved_cs_results */ ;;" . PHP_EOL .
672
+ "/*!50003 SET collation_connection = @saved_col_connection */ ;;" . PHP_EOL .
673
+ "DELIMITER ;" . PHP_EOL .
674
+ "/*!50106 SET TIME_ZONE= @save_time_zone */ ;" . PHP_EOL . PHP_EOL;
675
+ // Commented because we are doing this in restore_parameters()
676
+ // "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL . PHP_EOL;
677
+
678
+ return $ret;
679
+ }
680
+
681
+ public function show_tables()
682
+ {
683
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
684
+ $args = func_get_args();
685
+ return "SELECT TABLE_NAME AS tbl_name " .
686
+ "FROM INFORMATION_SCHEMA.TABLES " .
687
+ "WHERE TABLE_TYPE='BASE TABLE' AND TABLE_SCHEMA='${args[0]}'";
688
+ }
689
+
690
+ public function show_views()
691
+ {
692
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
693
+ $args = func_get_args();
694
+ return "SELECT TABLE_NAME AS tbl_name " .
695
+ "FROM INFORMATION_SCHEMA.TABLES " .
696
+ "WHERE TABLE_TYPE='VIEW' AND TABLE_SCHEMA='${args[0]}'";
697
+ }
698
+
699
+ public function show_triggers()
700
+ {
701
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
702
+ $args = func_get_args();
703
+ return "SHOW TRIGGERS FROM `${args[0]}`;";
704
+ }
705
+
706
+ public function show_columns()
707
+ {
708
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
709
+ $args = func_get_args();
710
+ return "SHOW COLUMNS FROM `${args[0]}`;";
711
+ }
712
+
713
+ public function show_procedures()
714
+ {
715
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
716
+ $args = func_get_args();
717
+ return "SELECT SPECIFIC_NAME AS procedure_name " .
718
+ "FROM INFORMATION_SCHEMA.ROUTINES " .
719
+ "WHERE ROUTINE_TYPE='PROCEDURE' AND ROUTINE_SCHEMA='${args[0]}'";
720
+ }
721
+
722
+ /**
723
+ * Get query string to ask for names of events from current database.
724
+ *
725
+ * @param string Name of database
726
+ * @return string
727
+ */
728
+ public function show_events()
729
+ {
730
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
731
+ $args = func_get_args();
732
+ return "SELECT EVENT_NAME AS event_name " .
733
+ "FROM INFORMATION_SCHEMA.EVENTS " .
734
+ "WHERE EVENT_SCHEMA='${args[0]}'";
735
+ }
736
+
737
+ public function setup_transaction()
738
+ {
739
+ return "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";
740
+ }
741
+
742
+ public function start_transaction()
743
+ {
744
+ return "START TRANSACTION";
745
+ }
746
+
747
+ public function commit_transaction()
748
+ {
749
+ return "COMMIT";
750
+ }
751
+
752
+ public function lock_table()
753
+ {
754
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
755
+ $args = func_get_args();
756
+ return $this->dbHandler->exec("LOCK TABLES `${args[0]}` READ LOCAL");
757
+
758
+ }
759
+
760
+ public function unlock_table()
761
+ {
762
+ return $this->dbHandler->exec("UNLOCK TABLES");
763
+ }
764
+
765
+ public function start_add_lock_table()
766
+ {
767
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
768
+ $args = func_get_args();
769
+ return "LOCK TABLES `${args[0]}` WRITE;" . PHP_EOL;
770
+ }
771
+
772
+ public function end_add_lock_table()
773
+ {
774
+ return "UNLOCK TABLES;" . PHP_EOL;
775
+ }
776
+
777
+ public function start_add_disable_keys()
778
+ {
779
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
780
+ $args = func_get_args();
781
+ return "/*!40000 ALTER TABLE `${args[0]}` DISABLE KEYS */;" .
782
+ PHP_EOL;
783
+ }
784
+
785
+ public function end_add_disable_keys()
786
+ {
787
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
788
+ $args = func_get_args();
789
+ return "/*!40000 ALTER TABLE `${args[0]}` ENABLE KEYS */;" .
790
+ PHP_EOL;
791
+ }
792
+
793
+ public function start_disable_autocommit()
794
+ {
795
+ return "SET autocommit=0;" . PHP_EOL;
796
+ }
797
+
798
+ public function end_disable_autocommit()
799
+ {
800
+ return "COMMIT;" . PHP_EOL;
801
+ }
802
+
803
+ public function add_drop_database()
804
+ {
805
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
806
+ $args = func_get_args();
807
+ return "/*!40000 DROP DATABASE IF EXISTS `${args[0]}`*/;" .
808
+ PHP_EOL . PHP_EOL;
809
+ }
810
+
811
+ public function add_drop_trigger()
812
+ {
813
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
814
+ $args = func_get_args();
815
+ return "DROP TRIGGER IF EXISTS `${args[0]}`;" . PHP_EOL;
816
+ }
817
+
818
+ public function drop_table()
819
+ {
820
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
821
+ $args = func_get_args();
822
+ return "DROP TABLE IF EXISTS `${args[0]}`;" . PHP_EOL;
823
+ }
824
+
825
+ public function drop_view()
826
+ {
827
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
828
+ $args = func_get_args();
829
+ return "DROP TABLE IF EXISTS `${args[0]}`;" . PHP_EOL .
830
+ "/*!50001 DROP VIEW IF EXISTS `${args[0]}`*/;" . PHP_EOL;
831
+ }
832
+
833
+ public function getDatabaseHeader()
834
+ {
835
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
836
+ $args = func_get_args();
837
+ return "--" . PHP_EOL .
838
+ "-- Current Database: `${args[0]}`" . PHP_EOL .
839
+ "--" . PHP_EOL . PHP_EOL;
840
+ }
841
+
842
+ /**
843
+ * Decode column metadata and fill info structure.
844
+ * type, is_numeric and is_blob will always be available.
845
+ *
846
+ * @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
847
+ * @return array
848
+ */
849
+ public function parseColumnType($colType)
850
+ {
851
+ $colInfo = array();
852
+ $colParts = explode(" ", $colType['Type']);
853
+
854
+ if($fparen = strpos($colParts[0], "("))
855
+ {
856
+ $colInfo['type'] = substr($colParts[0], 0, $fparen);
857
+ $colInfo['length'] = str_replace(")", "", substr($colParts[0], $fparen+1));
858
+ $colInfo['attributes'] = isset($colParts[1]) ? $colParts[1] : NULL;
859
+ }
860
+ else
861
+ {
862
+ $colInfo['type'] = $colParts[0];
863
+ }
864
+ $colInfo['is_numeric'] = in_array($colInfo['type'], $this->mysqlTypes['numerical']);
865
+ $colInfo['is_blob'] = in_array($colInfo['type'], $this->mysqlTypes['blob']);
866
+ // for virtual 'Extra' -> "STORED GENERATED"
867
+ $colInfo['is_virtual'] = strpos($colType['Extra'], "STORED GENERATED") === false ? false : true;
868
+
869
+ return $colInfo;
870
+ }
871
+
872
+ public function backup_parameters()
873
+ {
874
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
875
+ $args = func_get_args();
876
+ $dumpSettings = $args[0];
877
+ $ret = "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" . PHP_EOL .
878
+ "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" . PHP_EOL .
879
+ "/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" . PHP_EOL .
880
+ "/*!40101 SET NAMES " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL;
881
+
882
+ if (false === $dumpSettings['skip-tz-utc']) {
883
+ $ret .= "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;" . PHP_EOL .
884
+ "/*!40103 SET TIME_ZONE='+00:00' */;" . PHP_EOL;
885
+ }
886
+
887
+ $ret .= "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;" . PHP_EOL .
888
+ "/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;" . PHP_EOL .
889
+ "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;" . PHP_EOL .
890
+ "/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;" . PHP_EOL .PHP_EOL;
891
+
892
+ return $ret;
893
+ }
894
+
895
+ public function restore_parameters()
896
+ {
897
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
898
+ $args = func_get_args();
899
+ $dumpSettings = $args[0];
900
+ $ret = "";
901
+
902
+ if (false === $dumpSettings['skip-tz-utc']) {
903
+ $ret .= "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL;
904
+ }
905
+
906
+ $ret .= "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;" . PHP_EOL .
907
+ "/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;" . PHP_EOL .
908
+ "/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;" . PHP_EOL .
909
+ "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;" . PHP_EOL .
910
+ "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;" . PHP_EOL .
911
+ "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;" . PHP_EOL .
912
+ "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;" . PHP_EOL . PHP_EOL;
913
+
914
+ return $ret;
915
+ }
916
+
917
+ /**
918
+ * Check number of parameters passed to function, useful when inheriting.
919
+ * Raise exception if unexpected.
920
+ *
921
+ * @param integer $num_args
922
+ * @param integer $expected_num_args
923
+ * @param string $method_name
924
+ */
925
+ private function check_parameters($num_args, $expected_num_args, $method_name)
926
+ {
927
+ if ( $num_args != $expected_num_args ) {
928
+ throw new Exception("Unexpected parameter passed to $method_name");
929
+ }
930
+ return;
931
+ }
932
+
933
+ public function query($string)
934
+ {
935
+ $ret= $this->dbHandler->query($string);
936
+
937
+ if($ret===false)
938
+ {
939
+ $info=$this->dbHandler->errorInfo();
940
+ if($info[1] == 2006)
941
+ {
942
+ if($this->reconnect_count>3)
943
+ {
944
+ throw new Exception("MySQL server has gone away. Too many reconnect.");
945
+ }
946
+ $this->reconnect();
947
+ $this->reconnect_count++;
948
+ $ret= $this->dbHandler->query($string);
949
+ }
950
+ }
951
+ return $ret;
952
+ }
953
+
954
+ public function exec($string)
955
+ {
956
+ $ret=$this->dbHandler->exec($string);
957
+
958
+ if($ret===false)
959
+ {
960
+ $info=$this->dbHandler->errorInfo();
961
+ if($info[1] == 2006)
962
+ {
963
+ if($this->reconnect_count>3)
964
+ {
965
+ throw new Exception("MySQL server has gone away. Too many reconnect.");
966
+ }
967
+ $this->reconnect();
968
+ $this->reconnect_count++;
969
+ $ret= $this->dbHandler->exec($string);
970
+ }
971
+ }
972
+ return $ret;
973
+ }
974
+
975
+ public function reconnect()
976
+ {
977
+ $this->dbHandler = @new PDO(
978
+ $this->dsn,
979
+ $this->user,
980
+ $this->pass,
981
+ $this->pdoSettings
982
+ );
983
+ }
984
+ }
985
+
986
+ class TypeAdapterWpdb extends TypeAdapterFactory
987
+ {
988
+
989
+ private $dbHandler = null;
990
+
991
+ // Numerical Mysql types
992
+ public $mysqlTypes = array(
993
+ 'numerical' => array(
994
+ 'bit',
995
+ 'tinyint',
996
+ 'smallint',
997
+ 'mediumint',
998
+ 'int',
999
+ 'integer',
1000
+ 'bigint',
1001
+ 'real',
1002
+ 'double',
1003
+ 'float',
1004
+ 'decimal',
1005
+ 'numeric'
1006
+ ),
1007
+ 'blob' => array(
1008
+ 'tinyblob',
1009
+ 'blob',
1010
+ 'mediumblob',
1011
+ 'longblob',
1012
+ 'binary',
1013
+ 'varbinary',
1014
+ 'bit',
1015
+ 'geometry', /* http://bugs.mysql.com/bug.php?id=43544 */
1016
+ 'point',
1017
+ 'linestring',
1018
+ 'polygon',
1019
+ 'multipoint',
1020
+ 'multilinestring',
1021
+ 'multipolygon',
1022
+ 'geometrycollection',
1023
+ )
1024
+ );
1025
+
1026
+ public function __construct ($dbHandler)
1027
+ {
1028
+ $this->dbHandler = $dbHandler;
1029
+ }
1030
+
1031
+ public function databases()
1032
+ {
1033
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1034
+ $args = func_get_args();
1035
+ $databaseName = $args[0];
1036
+
1037
+ $resultSet = $this->query("SHOW VARIABLES LIKE 'character_set_database';");
1038
+ $characterSet = $resultSet->fetchColumn(1);
1039
+ $resultSet->closeCursor();
1040
+
1041
+ $resultSet = $this->query("SHOW VARIABLES LIKE 'collation_database';");
1042
+ $collationDb = $resultSet->fetchColumn(1);
1043
+ $resultSet->closeCursor();
1044
+ $ret = "";
1045
+
1046
+ $ret .= "CREATE DATABASE /*!32312 IF NOT EXISTS*/ `${databaseName}`".
1047
+ " /*!40100 DEFAULT CHARACTER SET ${characterSet} " .
1048
+ " COLLATE ${collationDb} */;" . PHP_EOL . PHP_EOL .
1049
+ "USE `${databaseName}`;" . PHP_EOL . PHP_EOL;
1050
+
1051
+ return $ret;
1052
+ }
1053
+
1054
+ public function show_create_table($tableName)
1055
+ {
1056
+ return "SHOW CREATE TABLE `$tableName`";
1057
+ }
1058
+
1059
+ public function show_create_view($viewName)
1060
+ {
1061
+ return "SHOW CREATE VIEW `$viewName`";
1062
+ }
1063
+
1064
+ public function show_create_trigger($triggerName)
1065
+ {
1066
+ return "SHOW CREATE TRIGGER `$triggerName`";
1067
+ }
1068
+
1069
+ public function show_create_procedure($procedureName)
1070
+ {
1071
+ return "SHOW CREATE PROCEDURE `$procedureName`";
1072
+ }
1073
+
1074
+ public function show_create_event($eventName)
1075
+ {
1076
+ return "SHOW CREATE EVENT `$eventName`";
1077
+ }
1078
+
1079
+ public function create_table( $row, $dumpSettings )
1080
+ {
1081
+
1082
+ if ( !isset($row['Create Table']) ) {
1083
+ throw new Exception("Error getting table code, unknown output");
1084
+ }
1085
+
1086
+ $createTable = str_replace('\'0000-00-00 00:00:00\'','\'1970-01-01 00:00:00\'',$row['Create Table']);
1087
+
1088
+ if ( $dumpSettings['reset-auto-increment'] ) {
1089
+ $match = "/AUTO_INCREMENT=[0-9]+/s";
1090
+ $replace = "";
1091
+ $createTable = preg_replace($match, $replace, $createTable);
1092
+ }
1093
+
1094
+ $ret = "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
1095
+ "/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
1096
+ $createTable . ";" . PHP_EOL .
1097
+ "/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL .
1098
+ PHP_EOL;
1099
+ return $ret;
1100
+ }
1101
+
1102
+ public function create_view($row)
1103
+ {
1104
+ $ret = "";
1105
+ if (!isset($row['Create View'])) {
1106
+ throw new Exception("Error getting view structure, unknown output");
1107
+ }
1108
+
1109
+ $triggerStmt = $row['Create View'];
1110
+
1111
+ $triggerStmtReplaced1 = str_replace(
1112
+ "CREATE ALGORITHM",
1113
+ "/*!50001 CREATE ALGORITHM",
1114
+ $triggerStmt
1115
+ );
1116
+ $triggerStmtReplaced2 = str_replace(
1117
+ " DEFINER=",
1118
+ " */" . PHP_EOL . "/*!50013 DEFINER=",
1119
+ $triggerStmtReplaced1
1120
+ );
1121
+ $triggerStmtReplaced3 = str_replace(
1122
+ " VIEW ",
1123
+ " */" . PHP_EOL . "/*!50001 VIEW ",
1124
+ $triggerStmtReplaced2
1125
+ );
1126
+ if (false === $triggerStmtReplaced1 ||
1127
+ false === $triggerStmtReplaced2 ||
1128
+ false === $triggerStmtReplaced3) {
1129
+ $triggerStmtReplaced = $triggerStmt;
1130
+ } else {
1131
+ $triggerStmtReplaced = $triggerStmtReplaced3 . " */;";
1132
+ }
1133
+
1134
+ $ret .= $triggerStmtReplaced . PHP_EOL . PHP_EOL;
1135
+ return $ret;
1136
+ }
1137
+
1138
+ public function create_trigger($row)
1139
+ {
1140
+ $ret = "";
1141
+ if (!isset($row['SQL Original Statement'])) {
1142
+ throw new Exception("Error getting trigger code, unknown output");
1143
+ }
1144
+
1145
+ $triggerStmt = $row['SQL Original Statement'];
1146
+ $triggerStmtReplaced = str_replace(
1147
+ "CREATE DEFINER",
1148
+ "/*!50003 CREATE*/ /*!50017 DEFINER",
1149
+ $triggerStmt
1150
+ );
1151
+ $triggerStmtReplaced = str_replace(
1152
+ " TRIGGER",
1153
+ "*/ /*!50003 TRIGGER",
1154
+ $triggerStmtReplaced
1155
+ );
1156
+ if ( false === $triggerStmtReplaced ) {
1157
+ $triggerStmtReplaced = $triggerStmt . " /* ";
1158
+ }
1159
+
1160
+ $ret .= "DELIMITER ;;" . PHP_EOL .
1161
+ $triggerStmtReplaced . " */ ;;" . PHP_EOL .
1162
+ "DELIMITER ;" . PHP_EOL . PHP_EOL;
1163
+ return $ret;
1164
+ }
1165
+
1166
+ public function create_procedure($row, $dumpSettings)
1167
+ {
1168
+ $ret = "";
1169
+ if (!isset($row['Create Procedure'])) {
1170
+ throw new Exception("Error getting procedure code, unknown output. " .
1171
+ "Please check 'https://bugs.mysql.com/bug.php?id=14564'");
1172
+ }
1173
+ $procedureStmt = $row['Create Procedure'];
1174
+
1175
+ $ret .= "/*!50003 DROP PROCEDURE IF EXISTS `" .
1176
+ $row['Procedure'] . "` */;" . PHP_EOL .
1177
+ "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
1178
+ "/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
1179
+ "DELIMITER ;;" . PHP_EOL .
1180
+ $procedureStmt . " ;;" . PHP_EOL .
1181
+ "DELIMITER ;" . PHP_EOL .
1182
+ "/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL . PHP_EOL;
1183
+
1184
+ return $ret;
1185
+ }
1186
+
1187
+ public function create_event($row)
1188
+ {
1189
+ $ret = "";
1190
+ if ( !isset($row['Create Event']) ) {
1191
+ throw new Exception("Error getting event code, unknown output. " .
1192
+ "Please check 'http://stackoverflow.com/questions/10853826/mysql-5-5-create-event-gives-syntax-error'");
1193
+ }
1194
+ $eventName = $row['Event'];
1195
+ $eventStmt = $row['Create Event'];
1196
+ $sqlMode = $row['sql_mode'];
1197
+
1198
+ $eventStmtReplaced = str_replace(
1199
+ "CREATE DEFINER",
1200
+ "/*!50106 CREATE*/ /*!50117 DEFINER",
1201
+ $eventStmt
1202
+ );
1203
+ $eventStmtReplaced = str_replace(
1204
+ " EVENT ",
1205
+ "*/ /*!50106 EVENT ",
1206
+ $eventStmtReplaced
1207
+ );
1208
+
1209
+ if ( false === $eventStmtReplaced ) {
1210
+ $eventStmtReplaced = $eventStmt . " /* ";
1211
+ }
1212
+
1213
+ $ret .= "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;" . PHP_EOL .
1214
+ "/*!50106 DROP EVENT IF EXISTS `" . $eventName . "` */;" . PHP_EOL .
1215
+ "DELIMITER ;;" . PHP_EOL .
1216
+ "/*!50003 SET @saved_cs_client = @@character_set_client */ ;;" . PHP_EOL .
1217
+ "/*!50003 SET @saved_cs_results = @@character_set_results */ ;;" . PHP_EOL .
1218
+ "/*!50003 SET @saved_col_connection = @@collation_connection */ ;;" . PHP_EOL .
1219
+ "/*!50003 SET character_set_client = utf8 */ ;;" . PHP_EOL .
1220
+ "/*!50003 SET character_set_results = utf8 */ ;;" . PHP_EOL .
1221
+ "/*!50003 SET collation_connection = utf8_general_ci */ ;;" . PHP_EOL .
1222
+ "/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;" . PHP_EOL .
1223
+ "/*!50003 SET sql_mode = '" . $sqlMode . "' */ ;;" . PHP_EOL .
1224
+ "/*!50003 SET @saved_time_zone = @@time_zone */ ;;" . PHP_EOL .
1225
+ "/*!50003 SET time_zone = 'SYSTEM' */ ;;" . PHP_EOL .
1226
+ $eventStmtReplaced . " */ ;;" . PHP_EOL .
1227
+ "/*!50003 SET time_zone = @saved_time_zone */ ;;" . PHP_EOL .
1228
+ "/*!50003 SET sql_mode = @saved_sql_mode */ ;;" . PHP_EOL .
1229
+ "/*!50003 SET character_set_client = @saved_cs_client */ ;;" . PHP_EOL .
1230
+ "/*!50003 SET character_set_results = @saved_cs_results */ ;;" . PHP_EOL .
1231
+ "/*!50003 SET collation_connection = @saved_col_connection */ ;;" . PHP_EOL .
1232
+ "DELIMITER ;" . PHP_EOL .
1233
+ "/*!50106 SET TIME_ZONE= @save_time_zone */ ;" . PHP_EOL . PHP_EOL;
1234
+ // Commented because we are doing this in restore_parameters()
1235
+ // "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL . PHP_EOL;
1236
+
1237
+ return $ret;
1238
+ }
1239
+
1240
+ public function show_tables()
1241
+ {
1242
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1243
+ $args = func_get_args();
1244
+ return "SELECT TABLE_NAME AS tbl_name " .
1245
+ "FROM INFORMATION_SCHEMA.TABLES " .
1246
+ "WHERE TABLE_TYPE='BASE TABLE' AND TABLE_SCHEMA='${args[0]}'";
1247
+ }
1248
+
1249
+ public function show_views()
1250
+ {
1251
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1252
+ $args = func_get_args();
1253
+ return "SELECT TABLE_NAME AS tbl_name " .
1254
+ "FROM INFORMATION_SCHEMA.TABLES " .
1255
+ "WHERE TABLE_TYPE='VIEW' AND TABLE_SCHEMA='${args[0]}'";
1256
+ }
1257
+
1258
+ public function show_triggers()
1259
+ {
1260
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1261
+ $args = func_get_args();
1262
+ return "SHOW TRIGGERS FROM `${args[0]}`;";
1263
+ }
1264
+
1265
+ public function show_columns()
1266
+ {
1267
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1268
+ $args = func_get_args();
1269
+ return "SHOW COLUMNS FROM `${args[0]}`;";
1270
+ }
1271
+
1272
+ public function show_procedures()
1273
+ {
1274
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1275
+ $args = func_get_args();
1276
+ return "SELECT SPECIFIC_NAME AS procedure_name " .
1277
+ "FROM INFORMATION_SCHEMA.ROUTINES " .
1278
+ "WHERE ROUTINE_TYPE='PROCEDURE' AND ROUTINE_SCHEMA='${args[0]}'";
1279
+ }
1280
+
1281
+ /**
1282
+ * Get query string to ask for names of events from current database.
1283
+ *
1284
+ * @param string Name of database
1285
+ * @return string
1286
+ */
1287
+ public function show_events()
1288
+ {
1289
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1290
+ $args = func_get_args();
1291
+ return "SELECT EVENT_NAME AS event_name " .
1292
+ "FROM INFORMATION_SCHEMA.EVENTS " .
1293
+ "WHERE EVENT_SCHEMA='${args[0]}'";
1294
+ }
1295
+
1296
+ public function setup_transaction()
1297
+ {
1298
+ return "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";
1299
+ }
1300
+
1301
+ public function start_transaction()
1302
+ {
1303
+ return "START TRANSACTION";
1304
+ }
1305
+
1306
+ public function commit_transaction()
1307
+ {
1308
+ return "COMMIT";
1309
+ }
1310
+
1311
+ public function lock_table()
1312
+ {
1313
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1314
+ $args = func_get_args();
1315
+ return $this->dbHandler->get_results("LOCK TABLES `${args[0]}` READ LOCAL",ARRAY_A);
1316
+
1317
+ }
1318
+
1319
+ public function unlock_table()
1320
+ {
1321
+ return $this->dbHandler->get_results("UNLOCK TABLES",ARRAY_A);
1322
+ }
1323
+
1324
+ public function start_add_lock_table()
1325
+ {
1326
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1327
+ $args = func_get_args();
1328
+ return "LOCK TABLES `${args[0]}` WRITE;" . PHP_EOL;
1329
+ }
1330
+
1331
+ public function end_add_lock_table()
1332
+ {
1333
+ return "UNLOCK TABLES;" . PHP_EOL;
1334
+ }
1335
+
1336
+ public function start_add_disable_keys()
1337
+ {
1338
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1339
+ $args = func_get_args();
1340
+ return "/*!40000 ALTER TABLE `${args[0]}` DISABLE KEYS */;" .
1341
+ PHP_EOL;
1342
+ }
1343
+
1344
+ public function end_add_disable_keys()
1345
+ {
1346
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1347
+ $args = func_get_args();
1348
+ return "/*!40000 ALTER TABLE `${args[0]}` ENABLE KEYS */;" .
1349
+ PHP_EOL;
1350
+ }
1351
+
1352
+ public function start_disable_autocommit()
1353
+ {
1354
+ return "SET autocommit=0;" . PHP_EOL;
1355
+ }
1356
+
1357
+ public function end_disable_autocommit()
1358
+ {
1359
+ return "COMMIT;" . PHP_EOL;
1360
+ }
1361
+
1362
+ public function add_drop_database()
1363
+ {
1364
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1365
+ $args = func_get_args();
1366
+ return "/*!40000 DROP DATABASE IF EXISTS `${args[0]}`*/;" .
1367
+ PHP_EOL . PHP_EOL;
1368
+ }
1369
+
1370
+ public function add_drop_trigger()
1371
+ {
1372
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1373
+ $args = func_get_args();
1374
+ return "DROP TRIGGER IF EXISTS `${args[0]}`;" . PHP_EOL;
1375
+ }
1376
+
1377
+ public function drop_table()
1378
+ {
1379
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1380
+ $args = func_get_args();
1381
+ return "DROP TABLE IF EXISTS `${args[0]}`;" . PHP_EOL;
1382
+ }
1383
+
1384
+ public function drop_view()
1385
+ {
1386
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1387
+ $args = func_get_args();
1388
+ return "DROP TABLE IF EXISTS `${args[0]}`;" . PHP_EOL .
1389
+ "/*!50001 DROP VIEW IF EXISTS `${args[0]}`*/;" . PHP_EOL;
1390
+ }
1391
+
1392
+ public function getDatabaseHeader()
1393
+ {
1394
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1395
+ $args = func_get_args();
1396
+ return "--" . PHP_EOL .
1397
+ "-- Current Database: `${args[0]}`" . PHP_EOL .
1398
+ "--" . PHP_EOL . PHP_EOL;
1399
+ }
1400
+
1401
+ /**
1402
+ * Decode column metadata and fill info structure.
1403
+ * type, is_numeric and is_blob will always be available.
1404
+ *
1405
+ * @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
1406
+ * @return array
1407
+ */
1408
+ public function parseColumnType($colType)
1409
+ {
1410
+ $colInfo = array();
1411
+ $colParts = explode(" ", $colType['Type']);
1412
+
1413
+ if($fparen = strpos($colParts[0], "("))
1414
+ {
1415
+ $colInfo['type'] = substr($colParts[0], 0, $fparen);
1416
+ $colInfo['length'] = str_replace(")", "", substr($colParts[0], $fparen+1));
1417
+ $colInfo['attributes'] = isset($colParts[1]) ? $colParts[1] : NULL;
1418
+ }
1419
+ else
1420
+ {
1421
+ $colInfo['type'] = $colParts[0];
1422
+ }
1423
+ $colInfo['is_numeric'] = in_array($colInfo['type'], $this->mysqlTypes['numerical']);
1424
+ $colInfo['is_blob'] = in_array($colInfo['type'], $this->mysqlTypes['blob']);
1425
+ // for virtual 'Extra' -> "STORED GENERATED"
1426
+ $colInfo['is_virtual'] = strpos($colType['Extra'], "STORED GENERATED") === false ? false : true;
1427
+
1428
+ return $colInfo;
1429
+ }
1430
+
1431
+ public function backup_parameters()
1432
+ {
1433
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1434
+ $args = func_get_args();
1435
+ $dumpSettings = $args[0];
1436
+ $ret = "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" . PHP_EOL .
1437
+ "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" . PHP_EOL .
1438
+ "/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" . PHP_EOL .
1439
+ "/*!40101 SET NAMES " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL;
1440
+
1441
+ if (false === $dumpSettings['skip-tz-utc']) {
1442
+ $ret .= "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;" . PHP_EOL .
1443
+ "/*!40103 SET TIME_ZONE='+00:00' */;" . PHP_EOL;
1444
+ }
1445
+
1446
+ $ret .= "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;" . PHP_EOL .
1447
+ "/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;" . PHP_EOL .
1448
+ "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;" . PHP_EOL .
1449
+ "/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;" . PHP_EOL .PHP_EOL;
1450
+
1451
+ return $ret;
1452
+ }
1453
+
1454
+ public function restore_parameters()
1455
+ {
1456
+ $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1457
+ $args = func_get_args();
1458
+ $dumpSettings = $args[0];
1459
+ $ret = "";
1460
+
1461
+ if (false === $dumpSettings['skip-tz-utc']) {
1462
+ $ret .= "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL;
1463
+ }
1464
+
1465
+ $ret .= "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;" . PHP_EOL .
1466
+ "/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;" . PHP_EOL .
1467
+ "/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;" . PHP_EOL .
1468
+ "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;" . PHP_EOL .
1469
+ "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;" . PHP_EOL .
1470
+ "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;" . PHP_EOL .
1471
+ "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;" . PHP_EOL . PHP_EOL;
1472
+
1473
+ return $ret;
1474
+ }
1475
+
1476
+ /**
1477
+ * Check number of parameters passed to function, useful when inheriting.
1478
+ * Raise exception if unexpected.
1479
+ *
1480
+ * @param integer $num_args
1481
+ * @param integer $expected_num_args
1482
+ * @param string $method_name
1483
+ */
1484
+ private function check_parameters($num_args, $expected_num_args, $method_name)
1485
+ {
1486
+ if ( $num_args != $expected_num_args ) {
1487
+ throw new Exception("Unexpected parameter passed to $method_name");
1488
+ }
1489
+ return;
1490
+ }
1491
+
1492
+ public function query($string)
1493
+ {
1494
+ return $this->dbHandler->get_results($string, ARRAY_A);
1495
+ }
1496
+
1497
+ public function exec($string)
1498
+ {
1499
+ return $this->dbHandler->get_results($string, ARRAY_A);
1500
+ }
1501
+ }
includes/class-wpvivid-mysqldump-wpdb.php ADDED
@@ -0,0 +1,765 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Created by PhpStorm.
4
+ * User: alienware`x
5
+ * Date: 2019/5/23
6
+ * Time: 16:42
7
+ */
8
+
9
+ class WPvivid_Mysqldump_wpdb
10
+ {
11
+ // Same as mysqldump
12
+ const MAXLINESIZE = 1000000;
13
+
14
+ // Available compression methods as constants
15
+ const GZIP = 'Gzip';
16
+ const BZIP2 = 'Bzip2';
17
+ const NONE = 'None';
18
+
19
+ // Available connection strings
20
+ const UTF8 = 'utf8';
21
+ const UTF8MB4 = 'utf8mb4';
22
+
23
+ /**
24
+ * Database username
25
+ * @var string
26
+ */
27
+ public $user;
28
+ /**
29
+ * Database password
30
+ * @var string
31
+ */
32
+ public $pass;
33
+ /**
34
+ * Connection string for PDO
35
+ * @var string
36
+ */
37
+ public $dsn;
38
+ /**
39
+ * Destination filename, defaults to stdout
40
+ * @var string
41
+ */
42
+ public $fileName = 'php://output';
43
+
44
+ // Internal stuff
45
+ private $tables = array();
46
+ private $views = array();
47
+ private $triggers = array();
48
+ private $procedures = array();
49
+ private $events = array();
50
+ private $dbHandler = null;
51
+ private $dbType;
52
+ private $compressManager;
53
+ private $typeAdapter;
54
+ private $dumpSettings = array();
55
+ private $pdoSettings = array();
56
+ private $version;
57
+ private $tableColumnTypes = array();
58
+ public $log=false;
59
+ public $task_id='';
60
+ /**
61
+ * database name, parsed from dsn
62
+ * @var string
63
+ */
64
+ private $dbName;
65
+ /**
66
+ * host name, parsed from dsn
67
+ * @var string
68
+ */
69
+ private $host;
70
+ /**
71
+ * dsn string parsed as an array
72
+ * @var array
73
+ */
74
+ private $dsnArray = array();
75
+ private $privileges = array();
76
+
77
+ public $last_query_string='';
78
+
79
+ /**
80
+ * Constructor of Mysqldump. Note that in the case of an SQLite database
81
+ * connection, the filename must be in the $db parameter.
82
+ *
83
+ * @param string $dsn PDO DSN connection string
84
+ * @param string $user SQL account username
85
+ * @param string $pass SQL account password
86
+ * @param array $dumpSettings SQL database settings
87
+ * @param array $pdoSettings PDO configured attributes
88
+ */
89
+ public function __construct($dumpSettings = array())
90
+ {
91
+ $dumpSettingsDefault = array(
92
+ 'include-tables' => array(),
93
+ 'exclude-tables' => array(),
94
+ 'compress' => WPvivid_Mysqldump_wpdb::NONE,
95
+ 'init_commands' => array(),
96
+ 'no-data' => array(),
97
+ 'reset-auto-increment' => false,
98
+ 'add-drop-database' => false,
99
+ 'add-drop-table' => false,
100
+ 'add-drop-trigger' => true,
101
+ 'add-locks' => true,
102
+ 'complete-insert' => false,
103
+ 'databases' => false,
104
+ 'default-character-set' => WPvivid_Mysqldump_wpdb::UTF8,
105
+ 'disable-keys' => true,
106
+ 'extended-insert' => true,
107
+ 'events' => false,
108
+ 'hex-blob' => true, /* faster than escaped content */
109
+ 'net_buffer_length' => self::MAXLINESIZE,
110
+ 'no-autocommit' => true,
111
+ 'no-create-info' => false,
112
+ 'lock-tables' => true,
113
+ 'routines' => false,
114
+ 'single-transaction' => true,
115
+ 'skip-triggers' => false,
116
+ 'skip-tz-utc' => false,
117
+ 'skip-comments' => false,
118
+ 'skip-dump-date' => false,
119
+ 'where' => '',
120
+ /* deprecated */
121
+ 'disable-foreign-keys-check' => true
122
+ );
123
+
124
+ $this->dumpSettings = self::array_replace_recursive($dumpSettingsDefault, $dumpSettings);
125
+
126
+ $this->dumpSettings['init_commands'][] = "SET NAMES " . $this->dumpSettings['default-character-set'];
127
+
128
+ if (false === $this->dumpSettings['skip-tz-utc']) {
129
+ $this->dumpSettings['init_commands'][] = "SET TIME_ZONE='+00:00'";
130
+ }
131
+
132
+ $diff = array_diff(array_keys($this->dumpSettings), array_keys($dumpSettingsDefault));
133
+ if (count($diff)>0) {
134
+ throw new Exception("Unexpected value in dumpSettings: (" . implode(",", $diff) . ")");
135
+ }
136
+
137
+ if ( !is_array($this->dumpSettings['include-tables']) ||
138
+ !is_array($this->dumpSettings['exclude-tables']) ) {
139
+ throw new Exception("Include-tables and exclude-tables should be arrays");
140
+ }
141
+
142
+ // Dump the same views as tables, mimic mysqldump behaviour
143
+ $this->dumpSettings['include-views'] = $this->dumpSettings['include-tables'];
144
+
145
+ // Create a new compressManager to manage compressed output
146
+ $this->compressManager = CompressManagerFactory::create($this->dumpSettings['compress']);
147
+ }
148
+
149
+ public function set_privilege($privileges)
150
+ {
151
+ $this -> privileges = $privileges;
152
+ }
153
+
154
+ /**
155
+ * Custom array_replace_recursive to be used if PHP < 5.3
156
+ * Replaces elements from passed arrays into the first array recursively
157
+ *
158
+ * @param array $array1 The array in which elements are replaced
159
+ * @param array $array2 The array from which elements will be extracted
160
+ *
161
+ * @return array Returns an array, or NULL if an error occurs.
162
+ */
163
+ public static function array_replace_recursive($array1, $array2)
164
+ {
165
+ if (function_exists('array_replace_recursive')) {
166
+ return array_replace_recursive($array1, $array2);
167
+ }
168
+
169
+ foreach ($array2 as $key => $value) {
170
+ if (is_array($value)) {
171
+ $array1[$key] = self::array_replace_recursive($array1[$key], $value);
172
+ } else {
173
+ $array1[$key] = $value;
174
+ }
175
+ }
176
+ return $array1;
177
+ }
178
+
179
+ /**
180
+ * Main call
181
+ *
182
+ * @param string $filename Name of file to write sql dump to
183
+ * @return null
184
+ */
185
+ public function start($filename = '')
186
+ {
187
+ // Output file can be redefined here
188
+ if (!empty($filename)) {
189
+ $this->fileName = $filename;
190
+ }
191
+
192
+ // Connect to database
193
+ $this->connect();
194
+
195
+ // Create output file
196
+ $this->compressManager->open($this->fileName);
197
+
198
+ // Write some basic info to output file
199
+ $this->compressManager->write($this->getDumpFileHeader());
200
+
201
+ $this->compressManager->write('/* # site_url: '.site_url().' */;'.PHP_EOL);
202
+ $this->compressManager->write('/* # home_url: '.home_url().' */;'.PHP_EOL);
203
+ $this->compressManager->write('/* # content_url: '.content_url().' */;'.PHP_EOL);
204
+ $upload_dir = wp_upload_dir();
205
+ $this->compressManager->write('/* # upload_url: '.$upload_dir['baseurl'].' */;'.PHP_EOL);
206
+ global $wpdb;
207
+ if (is_multisite() && !defined('MULTISITE'))
208
+ {
209
+ $prefix = $wpdb->base_prefix;
210
+ } else {
211
+ $prefix = $wpdb->get_blog_prefix(0);
212
+ }
213
+ $this->compressManager->write('/* # table_prefix: '.$prefix.' */;'.PHP_EOL.PHP_EOL.PHP_EOL);
214
+
215
+ // Store server settings and use sanner defaults to dump
216
+ $this->compressManager->write(
217
+ $this->typeAdapter->backup_parameters($this->dumpSettings)
218
+ );
219
+
220
+ // Get table, view and trigger structures from database
221
+ $this->getDatabaseStructure();
222
+
223
+ // If there still are some tables/views in include-tables array,
224
+ // that means that some tables or views weren't found.
225
+ // Give proper error and exit.
226
+ // This check will be removed once include-tables supports regexps
227
+ if (0 < count($this->dumpSettings['include-tables']))
228
+ {
229
+ $name = implode(",", $this->dumpSettings['include-tables']);
230
+ throw new Exception("Table (" . $name . ") not found in database");
231
+ }
232
+
233
+ $this->exportTables();
234
+
235
+ // Restore saved parameters
236
+ $this->compressManager->write(
237
+ $this->typeAdapter->restore_parameters($this->dumpSettings)
238
+ );
239
+ // Write some stats to output file
240
+ $this->compressManager->write($this->getDumpFileFooter());
241
+ // Close output file
242
+ $this->compressManager->close();
243
+ }
244
+
245
+ /**
246
+ * Reads table and views names from database.
247
+ * Fills $this->tables array so they will be dumped later.
248
+ *
249
+ * @return null
250
+ */
251
+ private function getDatabaseStructure()
252
+ {
253
+ // Listing all tables from database
254
+ if (empty($this->dumpSettings['include-tables']))
255
+ {
256
+ // include all tables for now, blacklisting happens later
257
+
258
+ $rows=$this->query($this->typeAdapter->show_tables($this->dbName));
259
+
260
+ foreach ($rows as $row)
261
+ {
262
+ array_push($this->tables, current($row));
263
+ }
264
+ } else {
265
+ // include only the tables mentioned in include-tables
266
+ $rows=$this->query($this->typeAdapter->show_tables($this->dbName));
267
+ foreach ($rows as $row)
268
+ {
269
+ if (in_array(current($row), $this->dumpSettings['include-tables'], true))
270
+ {
271
+ array_push($this->tables, current($row));
272
+ $elem = array_search(
273
+ current($row),
274
+ $this->dumpSettings['include-tables']
275
+ );
276
+ unset($this->dumpSettings['include-tables'][$elem]);
277
+ }
278
+ }
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Returns header for dump file
284
+ *
285
+ * @return string
286
+ */
287
+ private function getDumpFileHeader()
288
+ {
289
+ $header = '';
290
+ if ( !$this->dumpSettings['skip-comments'] ) {
291
+ // Some info about software, source and time
292
+ $header = "-- mysqldump-php https://github.com/ifsnop/mysqldump-php" . PHP_EOL .
293
+ "--" . PHP_EOL .
294
+ "-- Host: {$this->host}\tDatabase: {$this->dbName}" . PHP_EOL .
295
+ "-- ------------------------------------------------------" . PHP_EOL;
296
+
297
+ if ( !empty($this->version) ) {
298
+ $header .= "-- Server version \t" . $this->version . PHP_EOL;
299
+ }
300
+
301
+ if ( !$this->dumpSettings['skip-dump-date'] ) {
302
+ $header .= "-- Date: " . date('r') . PHP_EOL . PHP_EOL;
303
+ }
304
+ }
305
+ return $header;
306
+ }
307
+
308
+ private function connect()
309
+ {
310
+ // Connecting with PDO
311
+ global $wpdb;
312
+
313
+ $this->host=DB_HOST;
314
+ $this->dbName=DB_NAME;
315
+ $this->version=$wpdb->db_version();
316
+
317
+ $this->dbType='wpdb';
318
+ $this->dbHandler=$wpdb;
319
+
320
+ $this->typeAdapter = TypeAdapterFactory::create($this->dbType, $this->dbHandler);
321
+ }
322
+
323
+ public function query($query_string)
324
+ {
325
+ $this->last_query_string=$query_string;
326
+ return $this->typeAdapter->query($query_string);
327
+ }
328
+
329
+ /**
330
+ * Returns footer for dump file
331
+ *
332
+ * @return string
333
+ */
334
+ private function getDumpFileFooter()
335
+ {
336
+ $footer = '';
337
+ if (!$this->dumpSettings['skip-comments']) {
338
+ $footer .= '-- Dump completed';
339
+ if (!$this->dumpSettings['skip-dump-date']) {
340
+ $footer .= ' on: ' . date('r');
341
+ }
342
+ $footer .= PHP_EOL;
343
+ }
344
+
345
+ return $footer;
346
+ }
347
+
348
+ /**
349
+ * Compare if $table name matches with a definition inside $arr
350
+ * @param $table string
351
+ * @param $arr array with strings or patterns
352
+ * @return bool
353
+ */
354
+ private function matches($table, $arr) {
355
+ $match = false;
356
+
357
+ foreach ($arr as $pattern) {
358
+ if ( '/' != $pattern[0] ) {
359
+ continue;
360
+ }
361
+ if ( 1 == preg_match($pattern, $table) ) {
362
+ $match = true;
363
+ }
364
+ }
365
+
366
+ return in_array($table, $arr) || $match;
367
+ }
368
+
369
+ /**
370
+ * Exports all the tables selected from database
371
+ *
372
+ * @return null
373
+ */
374
+ private function exportTables()
375
+ {
376
+ // Exporting tables one by one
377
+ $i=0;
378
+ $i_step=0;
379
+ if($this->task_id!=='')
380
+ {
381
+ $options_name[]='backup_options';
382
+ $options_name[]='ismerge';
383
+ $options=WPvivid_taskmanager::get_task_options($this->task_id,$options_name);
384
+ if($options['ismerge'])
385
+ {
386
+ if(isset($options['backup_options']['backup']['backup_type'])) {
387
+ $i_step = intval(1 / (sizeof($options['backup_options']['backup']['backup_type']) + 1) * 100);
388
+ }
389
+ else{
390
+ $i_step = intval(1 / (sizeof($options['backup_options']['backup']) + 1) * 100);
391
+ }
392
+ }
393
+ else
394
+ {
395
+ if(isset($options['backup_options']['backup']['backup_type'])) {
396
+ $i_step = intval(1 / sizeof($options['backup_options']['backup']['backup_type']) * 100);
397
+ }
398
+ else{
399
+ $i_step = intval(1 / sizeof($options['backup_options']['backup']) * 100);
400
+ }
401
+ }
402
+ }
403
+
404
+ foreach ($this->tables as $table)
405
+ {
406
+ if ( $this->matches($table, $this->dumpSettings['exclude-tables']) )
407
+ {
408
+ continue;
409
+ }
410
+
411
+ if($this->task_id!=='')
412
+ {
413
+ $message='Preparing to dump table '.$table;
414
+ global $wpvivid_pulgin;
415
+ $wpvivid_pulgin->wpvivid_log->WriteLog($message,'notice');
416
+ WPvivid_taskmanager::update_backup_sub_task_progress($this->task_id,'backup',WPVIVID_BACKUP_TYPE_DB,0,$message);
417
+ }
418
+
419
+ $this->getTableStructure($table);
420
+ if ( false === $this->dumpSettings['no-data'] ) { // don't break compatibility with old trigger
421
+ $this->listValues($table);
422
+ } else if ( true === $this->dumpSettings['no-data']
423
+ || $this->matches($table, $this->dumpSettings['no-data']) ) {
424
+ continue;
425
+ } else {
426
+ $this->listValues($table);
427
+ }
428
+ $i++;
429
+ if($this->task_id!=='')
430
+ {
431
+ $i_progress=intval($i/sizeof($this->tables)*$i_step);
432
+ WPvivid_taskmanager::update_backup_main_task_progress($this->task_id,'backup',$i_progress,0);
433
+ }
434
+ }
435
+ return ;
436
+ }
437
+
438
+ /**
439
+ * Table structure extractor
440
+ *
441
+ * @todo move specific mysql code to typeAdapter
442
+ * @param string $tableName Name of table to export
443
+ * @return null
444
+ */
445
+ private function getTableStructure($tableName)
446
+ {
447
+ if (!$this->dumpSettings['no-create-info']) {
448
+ $ret = '';
449
+ if (!$this->dumpSettings['skip-comments']) {
450
+ $ret = "--" . PHP_EOL .
451
+ "-- Table structure for table `$tableName`" . PHP_EOL .
452
+ "--" . PHP_EOL . PHP_EOL;
453
+ }
454
+ $stmt = $this->typeAdapter->show_create_table($tableName);
455
+
456
+ foreach ($this->query($stmt) as $r) {
457
+
458
+ $this->compressManager->write($ret);
459
+ if ($this->dumpSettings['add-drop-table']) {
460
+ $this->compressManager->write(
461
+ $this->typeAdapter->drop_table($tableName)
462
+ );
463
+ }
464
+
465
+ $this->compressManager->write(
466
+ $this->typeAdapter->create_table($r, $this->dumpSettings)
467
+ );
468
+ break;
469
+ }
470
+ }
471
+ $this->tableColumnTypes[$tableName] = $this->getTableColumnTypes($tableName);
472
+ return;
473
+ }
474
+
475
+ /**
476
+ * Store column types to create data dumps and for Stand-In tables
477
+ *
478
+ * @param string $tableName Name of table to export
479
+ * @return array type column types detailed
480
+ */
481
+
482
+ private function getTableColumnTypes($tableName)
483
+ {
484
+ $columnTypes = array();
485
+ $columns = $this->query(
486
+ $this->typeAdapter->show_columns($tableName)
487
+ );
488
+
489
+ foreach($columns as $key => $col) {
490
+ $types = $this->typeAdapter->parseColumnType($col);
491
+ $columnTypes[$col['Field']] = array(
492
+ 'is_numeric'=> $types['is_numeric'],
493
+ 'is_blob' => $types['is_blob'],
494
+ 'type' => $types['type'],
495
+ 'type_sql' => $col['Type'],
496
+ 'is_virtual' => $types['is_virtual']
497
+ );
498
+ }
499
+
500
+ return $columnTypes;
501
+ }
502
+
503
+ /**
504
+ * Table rows extractor
505
+ *
506
+ * @param string $tableName Name of table to export
507
+ *
508
+ * @return null
509
+ */
510
+ private function listValues($tableName)
511
+ {
512
+ $this->prepareListValues($tableName);
513
+
514
+ $onlyOnce = true;
515
+ $lineSize = 0;
516
+
517
+ $colStmt = $this->getColumnStmt($tableName);
518
+
519
+ global $wpdb;
520
+ $prefix=$wpdb->base_prefix;
521
+
522
+ if(substr($tableName, strlen($prefix))=='options')
523
+ {
524
+ $stmt = "SELECT " . implode(",", $colStmt) . " FROM `$tableName` WHERE option_name !='wpvivid_task_list'";
525
+ }
526
+ else
527
+ {
528
+ $stmt = "SELECT " . implode(",", $colStmt) . " FROM `$tableName`";
529
+ }
530
+
531
+
532
+
533
+ if ($this->dumpSettings['where']) {
534
+ $stmt .= " WHERE {$this->dumpSettings['where']}";
535
+ }
536
+
537
+ $resultSet = $this->query($stmt);
538
+
539
+ $i=0;
540
+ $i_check_cancel=0;
541
+ $count=0;
542
+ foreach ($resultSet as $row)
543
+ {
544
+ $i++;
545
+ $vals = $this->escape($tableName, $row);
546
+
547
+ foreach($vals as $key => $value){
548
+ if($value === '\'0000-00-00 00:00:00\'')
549
+ $vals[$key] = '\'1970-01-01 00:00:00\'';
550
+ }
551
+
552
+ if ($onlyOnce || !$this->dumpSettings['extended-insert'])
553
+ {
554
+
555
+ if ($this->dumpSettings['complete-insert'])
556
+ {
557
+ $lineSize += $this->compressManager->write(
558
+ "INSERT INTO `$tableName` (" .
559
+ implode(", ", $colStmt) .
560
+ ") VALUES (" . implode(",", $vals) . ")"
561
+ );
562
+ } else {
563
+ $lineSize += $this->compressManager->write(
564
+ "INSERT INTO `$tableName` VALUES (" . implode(",", $vals) . ")"
565
+ );
566
+ }
567
+ $onlyOnce = false;
568
+ } else {
569
+ $lineSize += $this->compressManager->write(",(" . implode(",", $vals) . ")");
570
+ }
571
+ if (($lineSize > $this->dumpSettings['net_buffer_length']) ||
572
+ !$this->dumpSettings['extended-insert']) {
573
+ $onlyOnce = true;
574
+ $lineSize = $this->compressManager->write(";" . PHP_EOL);
575
+ }
576
+
577
+ if($i>=200000)
578
+ {
579
+ $count+=$i;
580
+ $i=0;
581
+ if($this->task_id!=='')
582
+ {
583
+ $i_check_cancel++;
584
+ if($i_check_cancel>5)
585
+ {
586
+ $i_check_cancel=0;
587
+ global $wpvivid_pulgin;
588
+ $wpvivid_pulgin->check_cancel_backup($this->task_id);
589
+ }
590
+ $message='Dumping table '.$tableName.', rows dumped: '.$count.' rows.';
591
+ WPvivid_taskmanager::update_backup_sub_task_progress($this->task_id,'backup',WPVIVID_BACKUP_TYPE_DB,0,$message);
592
+ }
593
+ }
594
+ }
595
+ unset($resultSet);
596
+
597
+ if (!$onlyOnce) {
598
+ $this->compressManager->write(";" . PHP_EOL);
599
+ }
600
+
601
+
602
+
603
+ $this->endListValues($tableName);
604
+ }
605
+
606
+ /**
607
+ * Table rows extractor, append information prior to dump
608
+ *
609
+ * @param string $tableName Name of table to export
610
+ *
611
+ * @return null
612
+ */
613
+ function prepareListValues($tableName)
614
+ {
615
+ if (!$this->dumpSettings['skip-comments']) {
616
+ $this->compressManager->write(
617
+ "--" . PHP_EOL .
618
+ "-- Dumping data for table `$tableName`" . PHP_EOL .
619
+ "--" . PHP_EOL . PHP_EOL
620
+ );
621
+ }
622
+
623
+ if ($this->dumpSettings['single-transaction']) {
624
+ $this->typeAdapter->exec($this->typeAdapter->setup_transaction());
625
+ $this->typeAdapter->exec($this->typeAdapter->start_transaction());
626
+ }
627
+
628
+ if ($this->dumpSettings['lock-tables']) {
629
+ if($this -> privileges['LOCK TABLES'] == 0){
630
+ global $wpvivid_pulgin;
631
+ $wpvivid_pulgin->wpvivid_log->WriteLog('The lack of LOCK TABLES privilege, the backup will skip lock_tables() to continue.','notice');
632
+ }else{
633
+ $this->typeAdapter->lock_table($tableName);
634
+ }
635
+ }
636
+
637
+ if ($this->dumpSettings['add-locks']) {
638
+ $this->compressManager->write(
639
+ $this->typeAdapter->start_add_lock_table($tableName)
640
+ );
641
+ }
642
+
643
+ if ($this->dumpSettings['disable-keys']) {
644
+ $this->compressManager->write(
645
+ $this->typeAdapter->start_add_disable_keys($tableName)
646
+ );
647
+ }
648
+
649
+ // Disable autocommit for faster reload
650
+ if ($this->dumpSettings['no-autocommit']) {
651
+ $this->compressManager->write(
652
+ $this->typeAdapter->start_disable_autocommit()
653
+ );
654
+ }
655
+
656
+ return;
657
+ }
658
+
659
+ /**
660
+ * Build SQL List of all columns on current table
661
+ *
662
+ * @param string $tableName Name of table to get columns
663
+ *
664
+ * @return string SQL sentence with columns
665
+ */
666
+ function getColumnStmt($tableName)
667
+ {
668
+ $colStmt = array();
669
+ foreach($this->tableColumnTypes[$tableName] as $colName => $colType) {
670
+ if ($colType['type'] == 'bit' && $this->dumpSettings['hex-blob']) {
671
+ $colStmt[] = "LPAD(HEX(`${colName}`),2,'0') AS `${colName}`";
672
+ } else if ($colType['is_blob'] && $this->dumpSettings['hex-blob']) {
673
+ $colStmt[] = "HEX(`${colName}`) AS `${colName}`";
674
+ } else if ($colType['is_virtual']) {
675
+ $this->dumpSettings['complete-insert'] = true;
676
+ continue;
677
+ } else {
678
+ $colStmt[] = "`${colName}`";
679
+ }
680
+ }
681
+
682
+ return $colStmt;
683
+ }
684
+
685
+ /**
686
+ * Escape values with quotes when needed
687
+ *
688
+ * @param string $tableName Name of table which contains rows
689
+ * @param array $row Associative array of column names and values to be quoted
690
+ *
691
+ * @return string
692
+ */
693
+ private function escape($tableName, $row)
694
+ {
695
+ $ret = array();
696
+ $columnTypes = $this->tableColumnTypes[$tableName];
697
+
698
+ foreach ($row as $colName => $colValue) {
699
+ if (is_null($colValue)) {
700
+ $ret[] = "NULL";
701
+ } elseif ($this->dumpSettings['hex-blob'] && $columnTypes[$colName]['is_blob']) {
702
+ if ($columnTypes[$colName]['type'] == 'bit' || !empty($colValue)) {
703
+ $ret[] = "0x${colValue}";
704
+ } else {
705
+ $ret[] = "''";
706
+ }
707
+ } elseif ($columnTypes[$colName]['is_numeric']) {
708
+ $ret[] = $colValue;
709
+ } else {
710
+ $ret[] = $this->quote($colValue);
711
+ }
712
+ }
713
+ return $ret;
714
+ }
715
+
716
+ public function quote($value)
717
+ {
718
+ $search = array("\x00", "\x0a", "\x0d", "\x1a");
719
+ $replace = array('\0', '\n', '\r', '\Z');
720
+ $value=str_replace('\\', '\\\\', $value);
721
+ $value=str_replace('\'', '\\\'', $value);
722
+ $value= "'" . str_replace($search, $replace, $value) . "'";
723
+ return $value;
724
+ }
725
+ /**
726
+ * Table rows extractor, close locks and commits after dump
727
+ *
728
+ * @param string $tableName Name of table to export
729
+ *
730
+ * @return null
731
+ */
732
+ function endListValues($tableName)
733
+ {
734
+ if ($this->dumpSettings['disable-keys']) {
735
+ $this->compressManager->write(
736
+ $this->typeAdapter->end_add_disable_keys($tableName)
737
+ );
738
+ }
739
+
740
+ if ($this->dumpSettings['add-locks']) {
741
+ $this->compressManager->write(
742
+ $this->typeAdapter->end_add_lock_table($tableName)
743
+ );
744
+ }
745
+
746
+ if ($this->dumpSettings['single-transaction']) {
747
+ $this->typeAdapter->exec($this->typeAdapter->commit_transaction());
748
+ }
749
+
750
+ if ($this->dumpSettings['lock-tables']) {
751
+ $this->typeAdapter->unlock_table($tableName);
752
+ }
753
+
754
+ // Commit to enable autocommit
755
+ if ($this->dumpSettings['no-autocommit']) {
756
+ $this->compressManager->write(
757
+ $this->typeAdapter->end_disable_autocommit()
758
+ );
759
+ }
760
+
761
+ $this->compressManager->write(PHP_EOL);
762
+
763
+ return;
764
+ }
765
+ }
includes/class-wpvivid-mysqldump.php CHANGED
@@ -314,6 +314,10 @@ class WPvivid_Mysqldump
314
 
315
  $this->dbHandler->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL);
316
  $this->typeAdapter = TypeAdapterFactory::create($this->dbType, $this->dbHandler);
 
 
 
 
317
  }
318
 
319
  /**
@@ -1098,8 +1102,8 @@ class WPvivid_Mysqldump
1098
  }
1099
 
1100
  if ($this->dumpSettings['single-transaction']) {
1101
- $this->dbHandler->exec($this->typeAdapter->setup_transaction());
1102
- $this->dbHandler->exec($this->typeAdapter->start_transaction());
1103
  }
1104
 
1105
  if ($this->dumpSettings['lock-tables']) {
@@ -1155,7 +1159,7 @@ class WPvivid_Mysqldump
1155
  }
1156
 
1157
  if ($this->dumpSettings['single-transaction']) {
1158
- $this->dbHandler->exec($this->typeAdapter->commit_transaction());
1159
  }
1160
 
1161
  if ($this->dumpSettings['lock-tables']) {
@@ -1203,916 +1207,14 @@ class WPvivid_Mysqldump
1203
  public function query($query_string)
1204
  {
1205
  $this->last_query_string=$query_string;
1206
- return $this->dbHandler->query($query_string);
1207
- }
1208
- }
1209
-
1210
- /**
1211
- * Enum with all available compression methods
1212
- *
1213
- */
1214
- abstract class CompressMethod
1215
- {
1216
- public static $enums = array(
1217
- "None",
1218
- "Gzip",
1219
- "Bzip2"
1220
- );
1221
-
1222
- /**
1223
- * @param string $c
1224
- * @return boolean
1225
- */
1226
- public static function isValid($c)
1227
- {
1228
- return in_array($c, self::$enums);
1229
- }
1230
- }
1231
-
1232
- abstract class CompressManagerFactory
1233
- {
1234
- /**
1235
- * @param string $c
1236
- * @return CompressBzip2|CompressGzip|CompressNone
1237
- */
1238
- public static function create($c)
1239
- {
1240
- $c = ucfirst(strtolower($c));
1241
- if (! CompressMethod::isValid($c)) {
1242
- throw new Exception("Compression method ($c) is not defined yet");
1243
- }
1244
-
1245
- $method = __NAMESPACE__ . "\\" . "Compress" . $c;
1246
-
1247
- return new $method;
1248
- }
1249
- }
1250
-
1251
- class CompressBzip2 extends CompressManagerFactory
1252
- {
1253
- private $fileHandler = null;
1254
-
1255
- public function __construct()
1256
- {
1257
- if (! function_exists("bzopen")) {
1258
- throw new Exception("Compression is enabled, but bzip2 lib is not installed or configured properly");
1259
- }
1260
- }
1261
-
1262
- /**
1263
- * @param string $filename
1264
- */
1265
- public function open($filename)
1266
- {
1267
- $this->fileHandler = bzopen($filename, "w");
1268
- if (false === $this->fileHandler) {
1269
- throw new Exception("Output file is not writable");
1270
- }
1271
-
1272
- return true;
1273
- }
1274
-
1275
- public function write($str)
1276
- {
1277
- if (false === ($bytesWritten = bzwrite($this->fileHandler, $str))) {
1278
- throw new Exception("Writting to file failed! Probably, there is no more free space left?");
1279
- }
1280
- return $bytesWritten;
1281
- }
1282
-
1283
- public function close()
1284
- {
1285
- return bzclose($this->fileHandler);
1286
- }
1287
- }
1288
-
1289
- class CompressGzip extends CompressManagerFactory
1290
- {
1291
- private $fileHandler = null;
1292
-
1293
- public function __construct()
1294
- {
1295
- if (! function_exists("gzopen")) {
1296
- throw new Exception("Compression is enabled, but gzip lib is not installed or configured properly");
1297
- }
1298
  }
1299
 
1300
- /**
1301
- * @param string $filename
1302
- */
1303
- public function open($filename)
1304
- {
1305
- $this->fileHandler = gzopen($filename, "wb");
1306
- if (false === $this->fileHandler) {
1307
- throw new Exception("Output file is not writable");
1308
- }
1309
-
1310
- return true;
1311
- }
1312
-
1313
- public function write($str)
1314
- {
1315
- if (false === ($bytesWritten = gzwrite($this->fileHandler, $str))) {
1316
- throw new Exception("Writting to file failed! Probably, there is no more free space left?");
1317
- }
1318
- return $bytesWritten;
1319
- }
1320
-
1321
- public function close()
1322
- {
1323
- return gzclose($this->fileHandler);
1324
- }
1325
- }
1326
-
1327
- class CompressNone extends CompressManagerFactory
1328
- {
1329
- private $fileHandler = null;
1330
-
1331
- /**
1332
- * @param string $filename
1333
- */
1334
- public function open($filename)
1335
- {
1336
- $this->fileHandler = fopen($filename, "wb");
1337
- if (false === $this->fileHandler) {
1338
- throw new Exception("Output file is not writable");
1339
- }
1340
-
1341
- return true;
1342
- }
1343
-
1344
- public function write($str)
1345
  {
1346
- if (false === ($bytesWritten = fwrite($this->fileHandler, $str))) {
1347
- throw new Exception("Writting to file failed! Probably, there is no more free space left?");
1348
- }
1349
- return $bytesWritten;
1350
- }
1351
-
1352
- public function close()
1353
- {
1354
- return fclose($this->fileHandler);
1355
- }
1356
- }
1357
-
1358
- /**
1359
- * Enum with all available TypeAdapter implementations
1360
- *
1361
- */
1362
- abstract class TypeAdapter
1363
- {
1364
- public static $enums = array(
1365
- "Sqlite",
1366
- "Mysql"
1367
- );
1368
-
1369
- /**
1370
- * @param string $c
1371
- * @return boolean
1372
- */
1373
- public static function isValid($c)
1374
- {
1375
- return in_array($c, self::$enums);
1376
- }
1377
- }
1378
-
1379
- /**
1380
- * TypeAdapter Factory
1381
- *
1382
- */
1383
- abstract class TypeAdapterFactory
1384
- {
1385
- /**
1386
- * @param string $c Type of database factory to create (Mysql, Sqlite,...)
1387
- * @param PDO $dbHandler
1388
- */
1389
- public static function create($c, $dbHandler = null)
1390
- {
1391
- $c = ucfirst(strtolower($c));
1392
- if (! TypeAdapter::isValid($c)) {
1393
- throw new Exception("Database type support for ($c) not yet available");
1394
- }
1395
- $method = __NAMESPACE__ . "\\" . "TypeAdapter" . $c;
1396
- return new $method($dbHandler);
1397
- }
1398
-
1399
- /**
1400
- * function databases Add sql to create and use database
1401
- * @todo make it do something with sqlite
1402
- */
1403
- public function databases()
1404
- {
1405
- return "";
1406
- }
1407
-
1408
- public function show_create_table($tableName)
1409
- {
1410
- return "SELECT tbl_name as 'Table', sql as 'Create Table' " .
1411
- "FROM sqlite_master " .
1412
- "WHERE type='table' AND tbl_name='$tableName'";
1413
- }
1414
-
1415
- /**
1416
- * function create_table Get table creation code from database
1417
- * @todo make it do something with sqlite
1418
- */
1419
- public function create_table($row, $dumpSettings)
1420
- {
1421
- return "";
1422
- }
1423
-
1424
- public function show_create_view($viewName)
1425
- {
1426
- return "SELECT tbl_name as 'View', sql as 'Create View' " .
1427
- "FROM sqlite_master " .
1428
- "WHERE type='view' AND tbl_name='$viewName'";
1429
- }
1430
-
1431
- /**
1432
- * function create_view Get view creation code from database
1433
- * @todo make it do something with sqlite
1434
- */
1435
- public function create_view($row)
1436
- {
1437
- return "";
1438
- }
1439
-
1440
- /**
1441
- * function show_create_trigger Get trigger creation code from database
1442
- * @todo make it do something with sqlite
1443
- */
1444
- public function show_create_trigger($triggerName)
1445
- {
1446
- return "";
1447
- }
1448
-
1449
- /**
1450
- * function create_trigger Modify trigger code, add delimiters, etc
1451
- * @todo make it do something with sqlite
1452
- */
1453
- public function create_trigger($triggerName)
1454
- {
1455
- return "";
1456
- }
1457
-
1458
- /**
1459
- * function create_procedure Modify procedure code, add delimiters, etc
1460
- * @todo make it do something with sqlite
1461
- */
1462
- public function create_procedure($procedureName, $dumpSettings)
1463
- {
1464
- return "";
1465
- }
1466
-
1467
- public function show_tables()
1468
- {
1469
- return "SELECT tbl_name FROM sqlite_master WHERE type='table'";
1470
- }
1471
-
1472
- public function show_views()
1473
- {
1474
- return "SELECT tbl_name FROM sqlite_master WHERE type='view'";
1475
- }
1476
-
1477
- public function show_triggers()
1478
- {
1479
- return "SELECT name FROM sqlite_master WHERE type='trigger'";
1480
- }
1481
-
1482
- public function show_columns()
1483
- {
1484
- if (func_num_args() != 1) {
1485
- return "";
1486
- }
1487
-
1488
- $args = func_get_args();
1489
-
1490
- return "pragma table_info(${args[0]})";
1491
- }
1492
-
1493
- public function show_procedures()
1494
- {
1495
- return "";
1496
- }
1497
-
1498
- public function show_events()
1499
- {
1500
- return "";
1501
- }
1502
-
1503
- public function setup_transaction()
1504
- {
1505
- return "";
1506
- }
1507
-
1508
- public function start_transaction()
1509
- {
1510
- return "BEGIN EXCLUSIVE";
1511
- }
1512
-
1513
- public function commit_transaction()
1514
- {
1515
- return "COMMIT";
1516
- }
1517
-
1518
- public function lock_table()
1519
- {
1520
- return "";
1521
- }
1522
-
1523
- public function unlock_table()
1524
- {
1525
- return "";
1526
- }
1527
-
1528
- public function start_add_lock_table()
1529
- {
1530
- return PHP_EOL;
1531
- }
1532
-
1533
- public function end_add_lock_table()
1534
- {
1535
- return PHP_EOL;
1536
- }
1537
-
1538
- public function start_add_disable_keys()
1539
- {
1540
- return PHP_EOL;
1541
- }
1542
-
1543
- public function end_add_disable_keys()
1544
- {
1545
- return PHP_EOL;
1546
- }
1547
-
1548
- public function start_disable_foreign_keys_check()
1549
- {
1550
- return PHP_EOL;
1551
- }
1552
-
1553
- public function end_disable_foreign_keys_check()
1554
- {
1555
- return PHP_EOL;
1556
- }
1557
-
1558
- public function add_drop_database()
1559
- {
1560
- return PHP_EOL;
1561
- }
1562
-
1563
- public function add_drop_trigger()
1564
- {
1565
- return PHP_EOL;
1566
- }
1567
-
1568
- public function drop_table()
1569
- {
1570
- return PHP_EOL;
1571
- }
1572
-
1573
- public function drop_view()
1574
- {
1575
- return PHP_EOL;
1576
- }
1577
-
1578
- /**
1579
- * Decode column metadata and fill info structure.
1580
- * type, is_numeric and is_blob will always be available.
1581
- *
1582
- * @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
1583
- * @return array
1584
- */
1585
- public function parseColumnType($colType)
1586
- {
1587
- return array();
1588
- }
1589
-
1590
- public function backup_parameters()
1591
- {
1592
- return PHP_EOL;
1593
- }
1594
-
1595
- public function restore_parameters()
1596
- {
1597
- return PHP_EOL;
1598
  }
1599
  }
1600
 
1601
- class TypeAdapterPgsql extends TypeAdapterFactory
1602
- {
1603
- }
1604
-
1605
- class TypeAdapterDblib extends TypeAdapterFactory
1606
- {
1607
- }
1608
-
1609
- class TypeAdapterSqlite extends TypeAdapterFactory
1610
- {
1611
- }
1612
-
1613
- class TypeAdapterMysql extends TypeAdapterFactory
1614
- {
1615
-
1616
- private $dbHandler = null;
1617
-
1618
- // Numerical Mysql types
1619
- public $mysqlTypes = array(
1620
- 'numerical' => array(
1621
- 'bit',
1622
- 'tinyint',
1623
- 'smallint',
1624
- 'mediumint',
1625
- 'int',
1626
- 'integer',
1627
- 'bigint',
1628
- 'real',
1629
- 'double',
1630
- 'float',
1631
- 'decimal',
1632
- 'numeric'
1633
- ),
1634
- 'blob' => array(
1635
- 'tinyblob',
1636
- 'blob',
1637
- 'mediumblob',
1638
- 'longblob',
1639
- 'binary',
1640
- 'varbinary',
1641
- 'bit',
1642
- 'geometry', /* http://bugs.mysql.com/bug.php?id=43544 */
1643
- 'point',
1644
- 'linestring',
1645
- 'polygon',
1646
- 'multipoint',
1647
- 'multilinestring',
1648
- 'multipolygon',
1649
- 'geometrycollection',
1650
- )
1651
- );
1652
-
1653
- public function __construct ($dbHandler)
1654
- {
1655
- $this->dbHandler = $dbHandler;
1656
- }
1657
-
1658
- public function databases()
1659
- {
1660
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1661
- $args = func_get_args();
1662
- $databaseName = $args[0];
1663
-
1664
- $resultSet = $this->query("SHOW VARIABLES LIKE 'character_set_database';");
1665
- $characterSet = $resultSet->fetchColumn(1);
1666
- $resultSet->closeCursor();
1667
-
1668
- $resultSet = $this->query("SHOW VARIABLES LIKE 'collation_database';");
1669
- $collationDb = $resultSet->fetchColumn(1);
1670
- $resultSet->closeCursor();
1671
- $ret = "";
1672
-
1673
- $ret .= "CREATE DATABASE /*!32312 IF NOT EXISTS*/ `${databaseName}`".
1674
- " /*!40100 DEFAULT CHARACTER SET ${characterSet} " .
1675
- " COLLATE ${collationDb} */;" . PHP_EOL . PHP_EOL .
1676
- "USE `${databaseName}`;" . PHP_EOL . PHP_EOL;
1677
-
1678
- return $ret;
1679
- }
1680
-
1681
- public function show_create_table($tableName)
1682
- {
1683
- return "SHOW CREATE TABLE `$tableName`";
1684
- }
1685
-
1686
- public function show_create_view($viewName)
1687
- {
1688
- return "SHOW CREATE VIEW `$viewName`";
1689
- }
1690
-
1691
- public function show_create_trigger($triggerName)
1692
- {
1693
- return "SHOW CREATE TRIGGER `$triggerName`";
1694
- }
1695
-
1696
- public function show_create_procedure($procedureName)
1697
- {
1698
- return "SHOW CREATE PROCEDURE `$procedureName`";
1699
- }
1700
-
1701
- public function show_create_event($eventName)
1702
- {
1703
- return "SHOW CREATE EVENT `$eventName`";
1704
- }
1705
-
1706
- public function create_table( $row, $dumpSettings )
1707
- {
1708
-
1709
- if ( !isset($row['Create Table']) ) {
1710
- throw new Exception("Error getting table code, unknown output");
1711
- }
1712
-
1713
- $createTable = str_replace('\'0000-00-00 00:00:00\'','\'1970-01-01 00:00:00\'',$row['Create Table']);
1714
-
1715
- if ( $dumpSettings['reset-auto-increment'] ) {
1716
- $match = "/AUTO_INCREMENT=[0-9]+/s";
1717
- $replace = "";
1718
- $createTable = preg_replace($match, $replace, $createTable);
1719
- }
1720
-
1721
- $ret = "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
1722
- "/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
1723
- $createTable . ";" . PHP_EOL .
1724
- "/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL .
1725
- PHP_EOL;
1726
- return $ret;
1727
- }
1728
-
1729
- public function create_view($row)
1730
- {
1731
- $ret = "";
1732
- if (!isset($row['Create View'])) {
1733
- throw new Exception("Error getting view structure, unknown output");
1734
- }
1735
-
1736
- $triggerStmt = $row['Create View'];
1737
-
1738
- $triggerStmtReplaced1 = str_replace(
1739
- "CREATE ALGORITHM",
1740
- "/*!50001 CREATE ALGORITHM",
1741
- $triggerStmt
1742
- );
1743
- $triggerStmtReplaced2 = str_replace(
1744
- " DEFINER=",
1745
- " */" . PHP_EOL . "/*!50013 DEFINER=",
1746
- $triggerStmtReplaced1
1747
- );
1748
- $triggerStmtReplaced3 = str_replace(
1749
- " VIEW ",
1750
- " */" . PHP_EOL . "/*!50001 VIEW ",
1751
- $triggerStmtReplaced2
1752
- );
1753
- if (false === $triggerStmtReplaced1 ||
1754
- false === $triggerStmtReplaced2 ||
1755
- false === $triggerStmtReplaced3) {
1756
- $triggerStmtReplaced = $triggerStmt;
1757
- } else {
1758
- $triggerStmtReplaced = $triggerStmtReplaced3 . " */;";
1759
- }
1760
-
1761
- $ret .= $triggerStmtReplaced . PHP_EOL . PHP_EOL;
1762
- return $ret;
1763
- }
1764
-
1765
- public function create_trigger($row)
1766
- {
1767
- $ret = "";
1768
- if (!isset($row['SQL Original Statement'])) {
1769
- throw new Exception("Error getting trigger code, unknown output");
1770
- }
1771
-
1772
- $triggerStmt = $row['SQL Original Statement'];
1773
- $triggerStmtReplaced = str_replace(
1774
- "CREATE DEFINER",
1775
- "/*!50003 CREATE*/ /*!50017 DEFINER",
1776
- $triggerStmt
1777
- );
1778
- $triggerStmtReplaced = str_replace(
1779
- " TRIGGER",
1780
- "*/ /*!50003 TRIGGER",
1781
- $triggerStmtReplaced
1782
- );
1783
- if ( false === $triggerStmtReplaced ) {
1784
- $triggerStmtReplaced = $triggerStmt . " /* ";
1785
- }
1786
-
1787
- $ret .= "DELIMITER ;;" . PHP_EOL .
1788
- $triggerStmtReplaced . " */ ;;" . PHP_EOL .
1789
- "DELIMITER ;" . PHP_EOL . PHP_EOL;
1790
- return $ret;
1791
- }
1792
-
1793
- public function create_procedure($row, $dumpSettings)
1794
- {
1795
- $ret = "";
1796
- if (!isset($row['Create Procedure'])) {
1797
- throw new Exception("Error getting procedure code, unknown output. " .
1798
- "Please check 'https://bugs.mysql.com/bug.php?id=14564'");
1799
- }
1800
- $procedureStmt = $row['Create Procedure'];
1801
-
1802
- $ret .= "/*!50003 DROP PROCEDURE IF EXISTS `" .
1803
- $row['Procedure'] . "` */;" . PHP_EOL .
1804
- "/*!40101 SET @saved_cs_client = @@character_set_client */;" . PHP_EOL .
1805
- "/*!40101 SET character_set_client = " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL .
1806
- "DELIMITER ;;" . PHP_EOL .
1807
- $procedureStmt . " ;;" . PHP_EOL .
1808
- "DELIMITER ;" . PHP_EOL .
1809
- "/*!40101 SET character_set_client = @saved_cs_client */;" . PHP_EOL . PHP_EOL;
1810
-
1811
- return $ret;
1812
- }
1813
-
1814
- public function create_event($row)
1815
- {
1816
- $ret = "";
1817
- if ( !isset($row['Create Event']) ) {
1818
- throw new Exception("Error getting event code, unknown output. " .
1819
- "Please check 'http://stackoverflow.com/questions/10853826/mysql-5-5-create-event-gives-syntax-error'");
1820
- }
1821
- $eventName = $row['Event'];
1822
- $eventStmt = $row['Create Event'];
1823
- $sqlMode = $row['sql_mode'];
1824
-
1825
- $eventStmtReplaced = str_replace(
1826
- "CREATE DEFINER",
1827
- "/*!50106 CREATE*/ /*!50117 DEFINER",
1828
- $eventStmt
1829
- );
1830
- $eventStmtReplaced = str_replace(
1831
- " EVENT ",
1832
- "*/ /*!50106 EVENT ",
1833
- $eventStmtReplaced
1834
- );
1835
-
1836
- if ( false === $eventStmtReplaced ) {
1837
- $eventStmtReplaced = $eventStmt . " /* ";
1838
- }
1839
-
1840
- $ret .= "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;" . PHP_EOL .
1841
- "/*!50106 DROP EVENT IF EXISTS `" . $eventName . "` */;" . PHP_EOL .
1842
- "DELIMITER ;;" . PHP_EOL .
1843
- "/*!50003 SET @saved_cs_client = @@character_set_client */ ;;" . PHP_EOL .
1844
- "/*!50003 SET @saved_cs_results = @@character_set_results */ ;;" . PHP_EOL .
1845
- "/*!50003 SET @saved_col_connection = @@collation_connection */ ;;" . PHP_EOL .
1846
- "/*!50003 SET character_set_client = utf8 */ ;;" . PHP_EOL .
1847
- "/*!50003 SET character_set_results = utf8 */ ;;" . PHP_EOL .
1848
- "/*!50003 SET collation_connection = utf8_general_ci */ ;;" . PHP_EOL .
1849
- "/*!50003 SET @saved_sql_mode = @@sql_mode */ ;;" . PHP_EOL .
1850
- "/*!50003 SET sql_mode = '" . $sqlMode . "' */ ;;" . PHP_EOL .
1851
- "/*!50003 SET @saved_time_zone = @@time_zone */ ;;" . PHP_EOL .
1852
- "/*!50003 SET time_zone = 'SYSTEM' */ ;;" . PHP_EOL .
1853
- $eventStmtReplaced . " */ ;;" . PHP_EOL .
1854
- "/*!50003 SET time_zone = @saved_time_zone */ ;;" . PHP_EOL .
1855
- "/*!50003 SET sql_mode = @saved_sql_mode */ ;;" . PHP_EOL .
1856
- "/*!50003 SET character_set_client = @saved_cs_client */ ;;" . PHP_EOL .
1857
- "/*!50003 SET character_set_results = @saved_cs_results */ ;;" . PHP_EOL .
1858
- "/*!50003 SET collation_connection = @saved_col_connection */ ;;" . PHP_EOL .
1859
- "DELIMITER ;" . PHP_EOL .
1860
- "/*!50106 SET TIME_ZONE= @save_time_zone */ ;" . PHP_EOL . PHP_EOL;
1861
- // Commented because we are doing this in restore_parameters()
1862
- // "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL . PHP_EOL;
1863
-
1864
- return $ret;
1865
- }
1866
-
1867
- public function show_tables()
1868
- {
1869
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1870
- $args = func_get_args();
1871
- return "SELECT TABLE_NAME AS tbl_name " .
1872
- "FROM INFORMATION_SCHEMA.TABLES " .
1873
- "WHERE TABLE_TYPE='BASE TABLE' AND TABLE_SCHEMA='${args[0]}'";
1874
- }
1875
-
1876
- public function show_views()
1877
- {
1878
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1879
- $args = func_get_args();
1880
- return "SELECT TABLE_NAME AS tbl_name " .
1881
- "FROM INFORMATION_SCHEMA.TABLES " .
1882
- "WHERE TABLE_TYPE='VIEW' AND TABLE_SCHEMA='${args[0]}'";
1883
- }
1884
-
1885
- public function show_triggers()
1886
- {
1887
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1888
- $args = func_get_args();
1889
- return "SHOW TRIGGERS FROM `${args[0]}`;";
1890
- }
1891
-
1892
- public function show_columns()
1893
- {
1894
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1895
- $args = func_get_args();
1896
- return "SHOW COLUMNS FROM `${args[0]}`;";
1897
- }
1898
-
1899
- public function show_procedures()
1900
- {
1901
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1902
- $args = func_get_args();
1903
- return "SELECT SPECIFIC_NAME AS procedure_name " .
1904
- "FROM INFORMATION_SCHEMA.ROUTINES " .
1905
- "WHERE ROUTINE_TYPE='PROCEDURE' AND ROUTINE_SCHEMA='${args[0]}'";
1906
- }
1907
-
1908
- /**
1909
- * Get query string to ask for names of events from current database.
1910
- *
1911
- * @param string Name of database
1912
- * @return string
1913
- */
1914
- public function show_events()
1915
- {
1916
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1917
- $args = func_get_args();
1918
- return "SELECT EVENT_NAME AS event_name " .
1919
- "FROM INFORMATION_SCHEMA.EVENTS " .
1920
- "WHERE EVENT_SCHEMA='${args[0]}'";
1921
- }
1922
-
1923
- public function setup_transaction()
1924
- {
1925
- return "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";
1926
- }
1927
-
1928
- public function start_transaction()
1929
- {
1930
- return "START TRANSACTION";
1931
- }
1932
-
1933
- public function commit_transaction()
1934
- {
1935
- return "COMMIT";
1936
- }
1937
-
1938
- public function lock_table()
1939
- {
1940
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1941
- $args = func_get_args();
1942
- return $this->dbHandler->exec("LOCK TABLES `${args[0]}` READ LOCAL");
1943
-
1944
- }
1945
-
1946
- public function unlock_table()
1947
- {
1948
- return $this->dbHandler->exec("UNLOCK TABLES");
1949
- }
1950
-
1951
- public function start_add_lock_table()
1952
- {
1953
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1954
- $args = func_get_args();
1955
- return "LOCK TABLES `${args[0]}` WRITE;" . PHP_EOL;
1956
- }
1957
-
1958
- public function end_add_lock_table()
1959
- {
1960
- return "UNLOCK TABLES;" . PHP_EOL;
1961
- }
1962
-
1963
- public function start_add_disable_keys()
1964
- {
1965
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1966
- $args = func_get_args();
1967
- return "/*!40000 ALTER TABLE `${args[0]}` DISABLE KEYS */;" .
1968
- PHP_EOL;
1969
- }
1970
 
1971
- public function end_add_disable_keys()
1972
- {
1973
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1974
- $args = func_get_args();
1975
- return "/*!40000 ALTER TABLE `${args[0]}` ENABLE KEYS */;" .
1976
- PHP_EOL;
1977
- }
1978
-
1979
- public function start_disable_autocommit()
1980
- {
1981
- return "SET autocommit=0;" . PHP_EOL;
1982
- }
1983
-
1984
- public function end_disable_autocommit()
1985
- {
1986
- return "COMMIT;" . PHP_EOL;
1987
- }
1988
-
1989
- public function add_drop_database()
1990
- {
1991
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
1992
- $args = func_get_args();
1993
- return "/*!40000 DROP DATABASE IF EXISTS `${args[0]}`*/;" .
1994
- PHP_EOL . PHP_EOL;
1995
- }
1996
-
1997
- public function add_drop_trigger()
1998
- {
1999
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
2000
- $args = func_get_args();
2001
- return "DROP TRIGGER IF EXISTS `${args[0]}`;" . PHP_EOL;
2002
- }
2003
-
2004
- public function drop_table()
2005
- {
2006
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
2007
- $args = func_get_args();
2008
- return "DROP TABLE IF EXISTS `${args[0]}`;" . PHP_EOL;
2009
- }
2010
-
2011
- public function drop_view()
2012
- {
2013
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
2014
- $args = func_get_args();
2015
- return "DROP TABLE IF EXISTS `${args[0]}`;" . PHP_EOL .
2016
- "/*!50001 DROP VIEW IF EXISTS `${args[0]}`*/;" . PHP_EOL;
2017
- }
2018
-
2019
- public function getDatabaseHeader()
2020
- {
2021
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
2022
- $args = func_get_args();
2023
- return "--" . PHP_EOL .
2024
- "-- Current Database: `${args[0]}`" . PHP_EOL .
2025
- "--" . PHP_EOL . PHP_EOL;
2026
- }
2027
-
2028
- /**
2029
- * Decode column metadata and fill info structure.
2030
- * type, is_numeric and is_blob will always be available.
2031
- *
2032
- * @param array $colType Array returned from "SHOW COLUMNS FROM tableName"
2033
- * @return array
2034
- */
2035
- public function parseColumnType($colType)
2036
- {
2037
- $colInfo = array();
2038
- $colParts = explode(" ", $colType['Type']);
2039
-
2040
- if($fparen = strpos($colParts[0], "("))
2041
- {
2042
- $colInfo['type'] = substr($colParts[0], 0, $fparen);
2043
- $colInfo['length'] = str_replace(")", "", substr($colParts[0], $fparen+1));
2044
- $colInfo['attributes'] = isset($colParts[1]) ? $colParts[1] : NULL;
2045
- }
2046
- else
2047
- {
2048
- $colInfo['type'] = $colParts[0];
2049
- }
2050
- $colInfo['is_numeric'] = in_array($colInfo['type'], $this->mysqlTypes['numerical']);
2051
- $colInfo['is_blob'] = in_array($colInfo['type'], $this->mysqlTypes['blob']);
2052
- // for virtual 'Extra' -> "STORED GENERATED"
2053
- $colInfo['is_virtual'] = strpos($colType['Extra'], "STORED GENERATED") === false ? false : true;
2054
-
2055
- return $colInfo;
2056
- }
2057
-
2058
- public function backup_parameters()
2059
- {
2060
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
2061
- $args = func_get_args();
2062
- $dumpSettings = $args[0];
2063
- $ret = "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" . PHP_EOL .
2064
- "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" . PHP_EOL .
2065
- "/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" . PHP_EOL .
2066
- "/*!40101 SET NAMES " . $dumpSettings['default-character-set'] . " */;" . PHP_EOL;
2067
-
2068
- if (false === $dumpSettings['skip-tz-utc']) {
2069
- $ret .= "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;" . PHP_EOL .
2070
- "/*!40103 SET TIME_ZONE='+00:00' */;" . PHP_EOL;
2071
- }
2072
-
2073
- $ret .= "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;" . PHP_EOL .
2074
- "/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;" . PHP_EOL .
2075
- "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;" . PHP_EOL .
2076
- "/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;" . PHP_EOL .PHP_EOL;
2077
-
2078
- return $ret;
2079
- }
2080
-
2081
- public function restore_parameters()
2082
- {
2083
- $this->check_parameters(func_num_args(), $expected_num_args = 1, __METHOD__);
2084
- $args = func_get_args();
2085
- $dumpSettings = $args[0];
2086
- $ret = "";
2087
-
2088
- if (false === $dumpSettings['skip-tz-utc']) {
2089
- $ret .= "/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;" . PHP_EOL;
2090
- }
2091
-
2092
- $ret .= "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;" . PHP_EOL .
2093
- "/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;" . PHP_EOL .
2094
- "/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;" . PHP_EOL .
2095
- "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;" . PHP_EOL .
2096
- "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;" . PHP_EOL .
2097
- "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;" . PHP_EOL .
2098
- "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;" . PHP_EOL . PHP_EOL;
2099
-
2100
- return $ret;
2101
- }
2102
-
2103
- /**
2104
- * Check number of parameters passed to function, useful when inheriting.
2105
- * Raise exception if unexpected.
2106
- *
2107
- * @param integer $num_args
2108
- * @param integer $expected_num_args
2109
- * @param string $method_name
2110
- */
2111
- private function check_parameters($num_args, $expected_num_args, $method_name)
2112
- {
2113
- if ( $num_args != $expected_num_args ) {
2114
- throw new Exception("Unexpected parameter passed to $method_name");
2115
- }
2116
- return;
2117
- }
2118
- }
314
 
315
  $this->dbHandler->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL);
316
  $this->typeAdapter = TypeAdapterFactory::create($this->dbType, $this->dbHandler);
317
+ if($this->dbType=='mysql'||$this->dbType=='pgsql'||$this->dbType=='dblib')
318
+ {
319
+ $this->typeAdapter->set_connect_info($this->dsn, $this->user, $this->pass, $this->pdoSettings);
320
+ }
321
  }
322
 
323
  /**
1102
  }
1103
 
1104
  if ($this->dumpSettings['single-transaction']) {
1105
+ $this->exec($this->typeAdapter->setup_transaction());
1106
+ $this->exec($this->typeAdapter->start_transaction());
1107
  }
1108
 
1109
  if ($this->dumpSettings['lock-tables']) {
1159
  }
1160
 
1161
  if ($this->dumpSettings['single-transaction']) {
1162
+ $this->exec($this->typeAdapter->commit_transaction());
1163
  }
1164
 
1165
  if ($this->dumpSettings['lock-tables']) {
1207
  public function query($query_string)
1208
  {
1209
  $this->last_query_string=$query_string;
1210
+ return $this->typeAdapter->query($query_string);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1211
  }
1212
 
1213
+ private function exec($query_string)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1214
  {
1215
+ $this->last_query_string=$query_string;
1216
+ return $this->typeAdapter->query($query_string);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1217
  }
1218
  }
1219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-wpvivid-restore-database.php CHANGED
@@ -839,6 +839,17 @@ class WPvivid_RestoreDB
839
  {
840
  return $old_string;
841
  }
 
 
 
 
 
 
 
 
 
 
 
842
  if($this->old_site_url!=$this->new_site_url)
843
  {
844
  $old_string=str_replace($this->old_site_url,$this->new_site_url,$old_string);
@@ -887,6 +898,52 @@ class WPvivid_RestoreDB
887
  return $old_string;
888
  }
889
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
890
  public function skip_tables($skip_table,$table_name)
891
  {
892
  $skip_tables[]='adrotate_stats';
@@ -957,7 +1014,7 @@ class WPvivid_RestoreDB
957
  return $skip_rows;
958
  }
959
 
960
- private function check_max_allow_packet()
961
  {
962
  //$max_allow_packet
963
  global $wpvivid_pulgin;
@@ -1003,7 +1060,7 @@ class WPvivid_RestoreDB
1003
  if(is_array($max_allowed_packet)&&isset($max_allowed_packet[0])&&isset($max_allowed_packet[0][0]))
1004
  {
1005
  if($max_allowed_packet[0][0]<16777216){
1006
- $max_all_packet_warning = 'max_allow_packet = '.$max_allowed_packet[0][0].' is too small. The recommended value is 16M or higher. Too small value could lead to a failure when importing a larger database.';
1007
  }
1008
  }
1009
  }
839
  {
840
  return $old_string;
841
  }
842
+
843
+ if($this->old_site_url!=$this->new_site_url)
844
+ {
845
+ $remove_http_link=$this->get_remove_http_link($this->old_site_url);
846
+ $new_remove_http_link=$this->get_remove_http_link($this->new_site_url);
847
+ if(strpos($new_remove_http_link,$remove_http_link)!==false)
848
+ {
849
+ return $this->replace_string_ex($old_string);
850
+ }
851
+ }
852
+
853
  if($this->old_site_url!=$this->new_site_url)
854
  {
855
  $old_string=str_replace($this->old_site_url,$this->new_site_url,$old_string);
898
  return $old_string;
899
  }
900
 
901
+ private function replace_string_ex($old_string)
902
+ {
903
+ if(!is_string($old_string))
904
+ {
905
+ return $old_string;
906
+ }
907
+
908
+ if($this->old_site_url!=$this->new_site_url)
909
+ {
910
+ $remove_http_link=$this->get_remove_http_link($this->old_site_url);
911
+ if($remove_http_link!==false)
912
+ {
913
+ $new_remove_http_link=$this->get_remove_http_link($this->new_site_url);
914
+ $old_string=str_replace($remove_http_link,$new_remove_http_link,$old_string);
915
+ }
916
+
917
+ $new_mix_link=$this->get_mix_link($this->new_site_url);
918
+ if($new_mix_link!==false)
919
+ {
920
+ $old_string=str_replace($new_mix_link,$this->new_site_url,$old_string);
921
+ }
922
+ if(substr($this->replacing_table, strlen($this->new_prefix))=='posts'||substr($this->replacing_table, strlen($this->new_prefix))=='postmeta'||substr($this->replacing_table, strlen($this->new_prefix))=='options')
923
+ {
924
+ $remove_http_link=$this->get_remove_http_link_ex($this->old_site_url);
925
+ if($remove_http_link!==false)
926
+ {
927
+ $new_remove_http_link=$this->get_remove_http_link_ex($this->new_site_url);
928
+ $old_string=str_replace($remove_http_link,$new_remove_http_link,$old_string);
929
+ }
930
+ }
931
+ }
932
+
933
+ if($this->old_home_url!=$this->new_home_url&&$this->old_home_url!=$this->old_site_url)
934
+ {
935
+ $old_string=str_replace($this->old_home_url,$this->new_home_url,$old_string);
936
+
937
+ $new_mix_link=$this->get_mix_link($this->new_home_url);
938
+ if($new_mix_link!==false)
939
+ {
940
+ $old_string=str_replace($new_mix_link,$this->new_home_url,$old_string);
941
+ }
942
+ }
943
+
944
+ return $old_string;
945
+ }
946
+
947
  public function skip_tables($skip_table,$table_name)
948
  {
949
  $skip_tables[]='adrotate_stats';
1014
  return $skip_rows;
1015
  }
1016
 
1017
+ private function check_max_allow_packet()
1018
  {
1019
  //$max_allow_packet
1020
  global $wpvivid_pulgin;
1060
  if(is_array($max_allowed_packet)&&isset($max_allowed_packet[0])&&isset($max_allowed_packet[0][0]))
1061
  {
1062
  if($max_allowed_packet[0][0]<16777216){
1063
+ $max_all_packet_warning = 'max_allow_packet = '.size_format($max_allowed_packet[0][0]).' is too small. The recommended value is 16M or higher. Too small value could lead to a failure when importing a larger database.';
1064
  }
1065
  }
1066
  }
includes/class-wpvivid-restore-site.php CHANGED
@@ -206,13 +206,15 @@ class WPvivid_RestoreSite
206
  {
207
  if($filename != "." && $filename != "..")
208
  {
209
- if(is_dir($path.DIRECTORY_SEPARATOR.$filename)){
 
210
  @mkdir(str_replace($replace_path,$temp_path,$path.DIRECTORY_SEPARATOR.$filename));
211
  $result = $this->_restore_copy_loop($path.DIRECTORY_SEPARATOR.$filename,$temp_path,$replace_path);
212
  if($result['result'] != WPVIVID_SUCCESS)
213
  break;
214
  }else{
215
- if(file_exists($path.DIRECTORY_SEPARATOR.$filename)){
 
216
  if(!copy($path.DIRECTORY_SEPARATOR.$filename,str_replace($replace_path,$temp_path,$path.DIRECTORY_SEPARATOR.$filename))){
217
  $result = array('result'=>'failed','error'=>'Copying '.$path.DIRECTORY_SEPARATOR.$filename.' into '.$temp_path.DIRECTORY_SEPARATOR.$filename.' failed. The file may be occupied, or the folder may not be granted a permission to write. Please try again.');
218
  break;
206
  {
207
  if($filename != "." && $filename != "..")
208
  {
209
+ if(is_dir($path.DIRECTORY_SEPARATOR.$filename))
210
+ {
211
  @mkdir(str_replace($replace_path,$temp_path,$path.DIRECTORY_SEPARATOR.$filename));
212
  $result = $this->_restore_copy_loop($path.DIRECTORY_SEPARATOR.$filename,$temp_path,$replace_path);
213
  if($result['result'] != WPVIVID_SUCCESS)
214
  break;
215
  }else{
216
+ if(file_exists($path.DIRECTORY_SEPARATOR.$filename))
217
+ {
218
  if(!copy($path.DIRECTORY_SEPARATOR.$filename,str_replace($replace_path,$temp_path,$path.DIRECTORY_SEPARATOR.$filename))){
219
  $result = array('result'=>'failed','error'=>'Copying '.$path.DIRECTORY_SEPARATOR.$filename.' into '.$temp_path.DIRECTORY_SEPARATOR.$filename.' failed. The file may be occupied, or the folder may not be granted a permission to write. Please try again.');
220
  break;
includes/class-wpvivid-setting.php CHANGED
@@ -124,6 +124,7 @@ class WPvivid_Setting
124
  $common_option['domain_include']=WPVIVID_DEFAULT_DOMAIN_INCLUDE;
125
  $common_option['estimate_backup']=WPVIVID_DEFAULT_ESTIMATE_BACKUP;
126
  $common_option['max_resume_count']=WPVIVID_RESUME_RETRY_TIMES;
 
127
  self::update_option('wpvivid_common_setting',$common_option);
128
  return $common_option;
129
  }
124
  $common_option['domain_include']=WPVIVID_DEFAULT_DOMAIN_INCLUDE;
125
  $common_option['estimate_backup']=WPVIVID_DEFAULT_ESTIMATE_BACKUP;
126
  $common_option['max_resume_count']=WPVIVID_RESUME_RETRY_TIMES;
127
+ $common_option['memory_limit']=WPVIVID_MEMORY_LIMIT;
128
  self::update_option('wpvivid_common_setting',$common_option);
129
  return $common_option;
130
  }
includes/class-wpvivid-tools.php CHANGED
@@ -46,6 +46,31 @@ class WPvivid_tools
46
  {
47
  WPvivid_tools::deldir($path.DIRECTORY_SEPARATOR.$filename,'',true);
48
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
  @closedir($handler);
51
  }
46
  {
47
  WPvivid_tools::deldir($path.DIRECTORY_SEPARATOR.$filename,'',true);
48
  }
49
+ if(is_dir($path.DIRECTORY_SEPARATOR.$filename) && preg_match('#temp-'.$task_id.'#',$filename))
50
+ {
51
+ WPvivid_tools::deldir($path.DIRECTORY_SEPARATOR.$filename,'',true);
52
+ }
53
+ }
54
+ @closedir($handler);
55
+ }
56
+
57
+ public static function clean_junk_cache(){
58
+ $home_url_prefix=get_home_url();
59
+ $parse = parse_url($home_url_prefix);
60
+ $tmppath=str_replace('/','_',$parse['path']);
61
+ $home_url_prefix = $parse['host'].$tmppath;
62
+ $path = WP_CONTENT_DIR.DIRECTORY_SEPARATOR.WPvivid_Setting::get_backupdir();
63
+ $handler=opendir($path);
64
+ while(($filename=readdir($handler))!==false)
65
+ {
66
+ if(is_dir($path.DIRECTORY_SEPARATOR.$filename) && preg_match('#temp-'.$home_url_prefix.'_'.'#',$filename))
67
+ {
68
+ WPvivid_tools::deldir($path.DIRECTORY_SEPARATOR.$filename,'',true);
69
+ }
70
+ if(is_dir($path.DIRECTORY_SEPARATOR.$filename) && preg_match('#temp-'.'#',$filename))
71
+ {
72
+ WPvivid_tools::deldir($path.DIRECTORY_SEPARATOR.$filename,'',true);
73
+ }
74
  }
75
  @closedir($handler);
76
  }
includes/class-wpvivid-zipclass.php CHANGED
@@ -6,9 +6,11 @@ if (!defined('WPVIVID_PLUGIN_DIR')){
6
  if(!defined('WPVIVID_COMPRESS_ZIPCLASS')){
7
  define('WPVIVID_COMPRESS_ZIPCLASS','zipclass');
8
  }
 
9
  define('WPVIVID_ZIPCLASS_JSONFILE_NAME','wpvivid_zipclass.json');
10
  require_once WPVIVID_PLUGIN_DIR . '/includes/class-wpvivid-compress-default.php';
11
- class WPvivid_ZipClass extends Wpvivid_Compress_Default{
 
12
  public $last_error = '';
13
  public $path_filter=array();
14
 
@@ -189,17 +191,19 @@ class WPvivid_ZipClass extends Wpvivid_Compress_Default{
189
 
190
  private function _zip($name,$files,$options,$json_info=false)
191
  {
 
 
192
  if(file_exists($name))
193
  @unlink($name);
194
  $archive = new PclZip($name);
195
 
196
  if(isset($options['compress']['no_compress']))
197
  {
198
- $no_compress=1;
199
  }
200
  else
201
  {
202
- $no_compress=0;
203
  }
204
 
205
  if(isset($options['compress']['use_temp_file']))
@@ -228,8 +232,21 @@ class WPvivid_ZipClass extends Wpvivid_Compress_Default{
228
  {
229
  $replace_path=WP_CONTENT_DIR.DIRECTORY_SEPARATOR.WPvivid_Setting::get_backupdir();
230
  }
231
- global $wpvivid_pulgin;
 
 
 
 
 
 
 
 
 
 
 
 
232
  $wpvivid_pulgin->wpvivid_log->WriteLog('Prepare to zip files. Is compress: '.$no_compress,'notice');
 
233
  if($no_compress)
234
  {
235
  if($use_temp_file==1)
@@ -273,24 +290,7 @@ class WPvivid_ZipClass extends Wpvivid_Compress_Default{
273
  return array('result'=>WPVIVID_FAILED,'error'=>$archive->errorInfo(true));
274
  }
275
 
276
- if($json_info!==false)
277
- {
278
- $json_info['md5']=md5_file($name);
279
-
280
- $temp_path = dirname($name).DIRECTORY_SEPARATOR.'wpvivid_package_info.json';
281
-
282
- if(file_exists($temp_path))
283
- {
284
- @unlink($temp_path);
285
- }
286
-
287
- file_put_contents($temp_path,print_r(json_encode($json_info),true));
288
- $wpvivid_pulgin->wpvivid_log->WriteLog('Adding zip files, filename: '.basename($name).', filesize: '.size_format(filesize($name),2),'notice');
289
- $archive -> add($temp_path,PCLZIP_OPT_REMOVE_PATH,dirname($temp_path));
290
- $wpvivid_pulgin->wpvivid_log->WriteLog('Adding zip files completed.','notice');
291
- @unlink($temp_path);
292
- }
293
-
294
  $file_data = array();
295
  $file_data['file_name'] = basename($name);
296
  $file_data['size'] = filesize($name);
@@ -386,7 +386,9 @@ function wpvivid_function_per_add_callback($p_event, &$p_header)
386
 
387
  function wpvivid_function_pre_extract_callback($p_event, &$p_header)
388
  {
389
- if(strpos($p_header['filename'],'wp-content/plugins/wpvivid-backuprestore')!==false)
 
 
390
  {
391
  return 0;
392
  }
6
  if(!defined('WPVIVID_COMPRESS_ZIPCLASS')){
7
  define('WPVIVID_COMPRESS_ZIPCLASS','zipclass');
8
  }
9
+
10
  define('WPVIVID_ZIPCLASS_JSONFILE_NAME','wpvivid_zipclass.json');
11
  require_once WPVIVID_PLUGIN_DIR . '/includes/class-wpvivid-compress-default.php';
12
+ class WPvivid_ZipClass extends Wpvivid_Compress_Default
13
+ {
14
  public $last_error = '';
15
  public $path_filter=array();
16
 
191
 
192
  private function _zip($name,$files,$options,$json_info=false)
193
  {
194
+ global $wpvivid_pulgin;
195
+
196
  if(file_exists($name))
197
  @unlink($name);
198
  $archive = new PclZip($name);
199
 
200
  if(isset($options['compress']['no_compress']))
201
  {
202
+ $no_compress=$options['compress']['no_compress'];
203
  }
204
  else
205
  {
206
+ $no_compress=1;
207
  }
208
 
209
  if(isset($options['compress']['use_temp_file']))
232
  {
233
  $replace_path=WP_CONTENT_DIR.DIRECTORY_SEPARATOR.WPvivid_Setting::get_backupdir();
234
  }
235
+
236
+ if($json_info!==false)
237
+ {
238
+ $temp_path = dirname($name).DIRECTORY_SEPARATOR.'wpvivid_package_info.json';
239
+ if(file_exists($temp_path))
240
+ {
241
+ @unlink($temp_path);
242
+ }
243
+ file_put_contents($temp_path,print_r(json_encode($json_info),true));
244
+ $archive -> add($temp_path,PCLZIP_OPT_REMOVE_PATH,dirname($temp_path));
245
+ @unlink($temp_path);
246
+ }
247
+
248
  $wpvivid_pulgin->wpvivid_log->WriteLog('Prepare to zip files. Is compress: '.$no_compress,'notice');
249
+
250
  if($no_compress)
251
  {
252
  if($use_temp_file==1)
290
  return array('result'=>WPVIVID_FAILED,'error'=>$archive->errorInfo(true));
291
  }
292
 
293
+ $wpvivid_pulgin->wpvivid_log->WriteLog('Adding zip files completed.'.basename($name).', filesize: '.size_format(filesize($name),2),'notice');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
  $file_data = array();
295
  $file_data['file_name'] = basename($name);
296
  $file_data['size'] = filesize($name);
386
 
387
  function wpvivid_function_pre_extract_callback($p_event, &$p_header)
388
  {
389
+ $plugins = substr(WP_PLUGIN_DIR, strpos(WP_PLUGIN_DIR, 'wp-content/'));
390
+
391
+ if(strpos($p_header['filename'],$plugins.DIRECTORY_SEPARATOR.'wpvivid-backuprestore')!==false)
392
  {
393
  return 0;
394
  }
includes/class-wpvivid.php CHANGED
@@ -950,6 +950,14 @@ class WPvivid {
950
  {
951
  //register shutdown function to catch php fatal error such as script time out and memory limit
952
 
 
 
 
 
 
 
 
 
953
  $this->end_shutdown_function=false;
954
  register_shutdown_function(array($this,'deal_shutdown_error'),$task_id);
955
  @ignore_user_abort(true);
@@ -1181,7 +1189,7 @@ class WPvivid {
1181
  if($this->end_shutdown_function===false)
1182
  {
1183
  $last_error = error_get_last();
1184
- if (!empty($last_error) && !in_array($last_error['type'], array(E_NOTICE), true))
1185
  {
1186
  $error = $last_error;
1187
  } else {
@@ -1219,7 +1227,7 @@ class WPvivid {
1219
  }
1220
  $time_spend = time() - $status['timeout'];
1221
  $time_start = time() - $status['start_time'];
1222
- $time_min=min($limit, 300);
1223
  if ($time_spend >= $limit)
1224
  {
1225
  //time out
@@ -1910,8 +1918,8 @@ class WPvivid {
1910
  }
1911
  $download_info=array();
1912
  $download_info['backup_id']=sanitize_key($_POST['backup_id']);
1913
- $download_info['file_name']=sanitize_file_name($_POST['file_name']);
1914
-
1915
  set_time_limit(600);
1916
  if (session_id())
1917
  session_write_close();
@@ -2283,7 +2291,8 @@ class WPvivid {
2283
  }
2284
  $download_info=array();
2285
  $download_info['backup_id']=sanitize_key($_POST['backup_id']);
2286
- $download_info['file_name']=sanitize_file_name($_POST['file_name']);
 
2287
 
2288
  $files=array();
2289
  $backup=WPvivid_Backuplist::get_backuplist_by_key($download_info['backup_id']);
@@ -2358,7 +2367,8 @@ class WPvivid {
2358
 
2359
  if(!empty($_REQUEST['file_name'])&&is_string($_REQUEST['file_name']))
2360
  {
2361
- $file_name=sanitize_file_name($_REQUEST['file_name']);
 
2362
  }
2363
  else
2364
  {
@@ -2925,15 +2935,15 @@ class WPvivid {
2925
  $memory_limit = ini_get('memory_limit');
2926
  $unit = substr($memory_limit, -1);
2927
  if($unit == 'K'){
2928
- $memory_limit = intval($memory_limit) * 1024;
2929
  }
2930
  else if($unit == 'M'){
2931
- $memory_limit = intval($memory_limit) * 1024 * 1024;
2932
  }
2933
  else if($unit == 'G'){
2934
- $memory_limit = intval($memory_limit) * 1024 * 1024 * 1024;
2935
  }
2936
- if($memory_limit<256 * 1024 * 1024){
2937
  $ret['memory_limit_warning']='memory_limit = '.$memory_limit.' is too small. The recommended value is 256M or higher. Too small value could result in a failure of website restore.';
2938
  }
2939
  else{
@@ -3019,7 +3029,8 @@ class WPvivid {
3019
  set_time_limit(600);
3020
 
3021
  $backup_id = sanitize_key($_POST['backup_id']);
3022
- $file_name=sanitize_file_name($_POST['file_name']);
 
3023
 
3024
  $file['file_name']=$file_name;
3025
  $file['size']=$_POST['size'];
@@ -3924,6 +3935,7 @@ class WPvivid {
3924
  {
3925
  $backup_id_list=WPvivid_Backuplist::get_has_remote_backuplist();
3926
  $this->delete_local_backup($backup_id_list);
 
3927
  }
3928
 
3929
  if($options['junk_files']=='1')
@@ -4250,6 +4262,7 @@ class WPvivid {
4250
  $setting_data['wpvivid_common_setting']['domain_include'] = $setting['domain_include'];
4251
  $setting_data['wpvivid_common_setting']['estimate_backup'] = $setting['estimate_backup'];
4252
  $setting_data['wpvivid_common_setting']['max_resume_count'] = $setting['max_resume_count'];
 
4253
  return $setting_data;
4254
  }
4255
 
950
  {
951
  //register shutdown function to catch php fatal error such as script time out and memory limit
952
 
953
+ $common_setting = WPvivid_Setting::get_option('wpvivid_common_setting');
954
+ if(isset($common_setting['memory_limit']) && !empty($common_setting['memory_limit'])){
955
+ $memory_limit = $common_setting['memory_limit'];
956
+ }
957
+ else{
958
+ $memory_limit = WPVIVID_MEMORY_LIMIT;
959
+ }
960
+ @ini_set('memory_limit', $memory_limit);
961
  $this->end_shutdown_function=false;
962
  register_shutdown_function(array($this,'deal_shutdown_error'),$task_id);
963
  @ignore_user_abort(true);
1189
  if($this->end_shutdown_function===false)
1190
  {
1191
  $last_error = error_get_last();
1192
+ if (!empty($last_error) && !in_array($last_error['type'], array(E_NOTICE,E_WARNING), true))
1193
  {
1194
  $error = $last_error;
1195
  } else {
1227
  }
1228
  $time_spend = time() - $status['timeout'];
1229
  $time_start = time() - $status['start_time'];
1230
+ $time_min=min($limit, 180);
1231
  if ($time_spend >= $limit)
1232
  {
1233
  //time out
1918
  }
1919
  $download_info=array();
1920
  $download_info['backup_id']=sanitize_key($_POST['backup_id']);
1921
+ //$download_info['file_name']=sanitize_file_name($_POST['file_name']);
1922
+ $download_info['file_name']=$_POST['file_name'];
1923
  set_time_limit(600);
1924
  if (session_id())
1925
  session_write_close();
2291
  }
2292
  $download_info=array();
2293
  $download_info['backup_id']=sanitize_key($_POST['backup_id']);
2294
+ //$download_info['file_name']=sanitize_file_name($_POST['file_name']);
2295
+ $download_info['file_name']=$_POST['file_name'];
2296
 
2297
  $files=array();
2298
  $backup=WPvivid_Backuplist::get_backuplist_by_key($download_info['backup_id']);
2367
 
2368
  if(!empty($_REQUEST['file_name'])&&is_string($_REQUEST['file_name']))
2369
  {
2370
+ //$file_name=sanitize_file_name($_REQUEST['file_name']);
2371
+ $file_name=$_REQUEST['file_name'];
2372
  }
2373
  else
2374
  {
2935
  $memory_limit = ini_get('memory_limit');
2936
  $unit = substr($memory_limit, -1);
2937
  if($unit == 'K'){
2938
+ $memory_limit_tmp = intval($memory_limit) * 1024;
2939
  }
2940
  else if($unit == 'M'){
2941
+ $memory_limit_tmp = intval($memory_limit) * 1024 * 1024;
2942
  }
2943
  else if($unit == 'G'){
2944
+ $memory_limit_tmp = intval($memory_limit) * 1024 * 1024 * 1024;
2945
  }
2946
+ if($memory_limit_tmp<256 * 1024 * 1024){
2947
  $ret['memory_limit_warning']='memory_limit = '.$memory_limit.' is too small. The recommended value is 256M or higher. Too small value could result in a failure of website restore.';
2948
  }
2949
  else{
3029
  set_time_limit(600);
3030
 
3031
  $backup_id = sanitize_key($_POST['backup_id']);
3032
+ //$file_name=sanitize_file_name($_POST['file_name']);
3033
+ $file_name=$_POST['file_name'];
3034
 
3035
  $file['file_name']=$file_name;
3036
  $file['size']=$_POST['size'];
3935
  {
3936
  $backup_id_list=WPvivid_Backuplist::get_has_remote_backuplist();
3937
  $this->delete_local_backup($backup_id_list);
3938
+ WPvivid_tools::clean_junk_cache();
3939
  }
3940
 
3941
  if($options['junk_files']=='1')
4262
  $setting_data['wpvivid_common_setting']['domain_include'] = $setting['domain_include'];
4263
  $setting_data['wpvivid_common_setting']['estimate_backup'] = $setting['estimate_backup'];
4264
  $setting_data['wpvivid_common_setting']['max_resume_count'] = $setting['max_resume_count'];
4265
+ $setting_data['wpvivid_common_setting']['memory_limit'] = $setting['memory_limit'].'M';
4266
  return $setting_data;
4267
  }
4268
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: transfer, move, duplicate, clone, backup, migrate, restore, auto backup, c
4
  Requires at least: 4.5
5
  Tested up to: 5.2
6
  Requires PHP: 5.3
7
- Stable tag: 0.9.18
8
  License: GPLv3 or later
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.en.html
10
 
@@ -110,10 +110,12 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
110
  2. Backup list
111
  3. Dashboard
112
  4. Configure remote storage
 
 
113
 
114
  == Frequently Asked Questions ==
115
  = What does WPvivid Backup plugin do? =
116
- As its name says, it enables you to easily transfer a WordPress site to a new domain, to perform manual and scheduled backups of your WordPress site, to back up to cloud storage and restore backups directly from the site’s admin dashboard.
117
  = Does the plugin also transfer my site? Is it a free feature? =
118
  Yes, we have added website transfer feature since version 0.9.14.
119
  Yes, it's a completely free feature.
@@ -144,6 +146,13 @@ Please try to contact your web hosting provider for changing PHP memory limit, o
144
  Feel free to let us know how we can help using the [support forum](https://wordpress.org/support/plugin/wpvivid-backuprestore) for the plugin on WordPress.org or our [contact form](https://wpvivid.com/contact-us). You can also reach us with a direct message on [Twitter](https://twitter.com/WPvividcom).
145
 
146
  == Changelog ==
 
 
 
 
 
 
 
147
  = 0.9.18 =
148
  - Optimized migration process, improved compatibility for migration. Old keys will be expired after you update to the new version.
149
  - Added an option to retry the backup operation when encountering a timeout error.
4
  Requires at least: 4.5
5
  Tested up to: 5.2
6
  Requires PHP: 5.3
7
+ Stable tag: 0.9.19
8
  License: GPLv3 or later
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.en.html
10
 
110
  2. Backup list
111
  3. Dashboard
112
  4. Configure remote storage
113
+ 5. Transfer a WordPress site to a new domain
114
+ 6. Upload a backup to restore or transfer
115
 
116
  == Frequently Asked Questions ==
117
  = What does WPvivid Backup plugin do? =
118
+ As its name says, it is an all in one free WP backup plugin that enables you to easily transfer a WordPress site to a new domain, to perform manual and scheduled backups of your WordPress site, to back up to cloud storage and restore backups directly from your site’s admin dashboard.
119
  = Does the plugin also transfer my site? Is it a free feature? =
120
  Yes, we have added website transfer feature since version 0.9.14.
121
  Yes, it's a completely free feature.
146
  Feel free to let us know how we can help using the [support forum](https://wordpress.org/support/plugin/wpvivid-backuprestore) for the plugin on WordPress.org or our [contact form](https://wpvivid.com/contact-us). You can also reach us with a direct message on [Twitter](https://twitter.com/WPvividcom).
147
 
148
  == Changelog ==
149
+ = 0.9.19 =
150
+ - Added a php memory limit option to settings, you can use it to temporarily increase php memory limit when encountering a memory exhausted error in backup process.
151
+ - Fixed: Backup does not exist error that occurred in some cases when downloading the backup to local.
152
+ - Fixed: Backup error that occurred when the wp-content/plugins folder on a web server was moved or renamed.
153
+ - Fixed: Restore error that occurred in some cases when restoring a backup to a different domain.
154
+ - Enhanced the clean backup cache option in settings.
155
+ - Optimized backup process.
156
  = 0.9.18 =
157
  - Optimized migration process, improved compatibility for migration. Old keys will be expired after you update to the new version.
158
  - Added an option to retry the backup operation when encountering a timeout error.
wpvivid-backuprestore.php CHANGED
@@ -7,7 +7,7 @@
7
  * @wordpress-plugin
8
  * Plugin Name: WPvivid Backup Plugin
9
  * Description: Transfer site to a new domain. Off-site backup schedule, transfer backups to leading remote storage (dropbox, onedrive, google drive etc). All in one.
10
- * Version: 0.9.18
11
  * Author: WPvivid Team
12
  * Author URI: https://wpvivid.com
13
  * License: GPL-3.0+
@@ -21,7 +21,7 @@ if ( ! defined( 'WPINC' ) ) {
21
  die;
22
  }
23
 
24
- define( 'WPVIVID_PLUGIN_VERSION', '0.9.18' );
25
  //
26
  define('WPVIVID_RESTORE_INIT','init');
27
  define('WPVIVID_RESTORE_READY','ready');
@@ -38,8 +38,9 @@ define('WPVIVID_PLUGIN_URL',plugins_url('',__FILE__));
38
  define('WPVIVID_PLUGIN_DIR',dirname(__FILE__));
39
  //We set a long enough default execution time (10 min) to ensure that the backup process can be completed.
40
  define('WPVIVID_MAX_EXECUTION_TIME',900);
 
41
  //If the server uses fastcgi then default execution time should be set to 2 min for more efficient.
42
- define('WPVIVID_MAX_EXECUTION_TIME_FCGI',120);
43
  //Default number of reserved backups
44
  define('WPVIVID_MAX_BACKUP_COUNT',7);
45
  define('WPVIVID_DEFAULT_BACKUP_COUNT',3);
7
  * @wordpress-plugin
8
  * Plugin Name: WPvivid Backup Plugin
9
  * Description: Transfer site to a new domain. Off-site backup schedule, transfer backups to leading remote storage (dropbox, onedrive, google drive etc). All in one.
10
+ * Version: 0.9.19
11
  * Author: WPvivid Team
12
  * Author URI: https://wpvivid.com
13
  * License: GPL-3.0+
21
  die;
22
  }
23
 
24
+ define( 'WPVIVID_PLUGIN_VERSION', '0.9.19' );
25
  //
26
  define('WPVIVID_RESTORE_INIT','init');
27
  define('WPVIVID_RESTORE_READY','ready');
38
  define('WPVIVID_PLUGIN_DIR',dirname(__FILE__));
39
  //We set a long enough default execution time (10 min) to ensure that the backup process can be completed.
40
  define('WPVIVID_MAX_EXECUTION_TIME',900);
41
+ define('WPVIVID_MEMORY_LIMIT','256M');
42
  //If the server uses fastcgi then default execution time should be set to 2 min for more efficient.
43
+ define('WPVIVID_MAX_EXECUTION_TIME_FCGI',180);
44
  //Default number of reserved backups
45
  define('WPVIVID_MAX_BACKUP_COUNT',7);
46
  define('WPVIVID_DEFAULT_BACKUP_COUNT',3);