Duplicator – WordPress Migration Plugin - Version 1.3.26

Version Description

Download this release

Release Info

Developer cory@lamle.org
Plugin Icon 128x128 Duplicator – WordPress Migration Plugin
Version 1.3.26
Comparing to
See all releases

Code changes from version 1.3.24 to 1.3.26

Files changed (43) hide show
  1. assets/css/style.css +127 -0
  2. assets/img/logo.png +0 -0
  3. assets/js/global-admin-script.js +16 -0
  4. assets/js/javascript.php +20 -1
  5. classes/class.db.php +54 -75
  6. classes/class.server.php +9 -8
  7. classes/package/class.pack.archive.php +23 -21
  8. classes/package/class.pack.database.php +127 -107
  9. classes/package/class.pack.installer.php +35 -10
  10. classes/package/class.pack.php +2 -19
  11. classes/ui/class.ui.notice.php +51 -0
  12. classes/utilities/class.u.php +2 -2
  13. ctrls/class.web.services.php +39 -0
  14. ctrls/ctrl.package.php +130 -114
  15. ctrls/ctrl.tools.php +2 -2
  16. define.php +6 -5
  17. duplicator.php +30 -6
  18. helper.php +65 -0
  19. installer/dup-installer/classes/class.http.php +1 -1
  20. installer/dup-installer/classes/class.package.php +1 -1
  21. installer/dup-installer/classes/config/class.conf.srv.php +10 -10
  22. installer/dup-installer/classes/utilities/class.u.php +19 -16
  23. installer/dup-installer/main.installer.php +1 -1
  24. installer/dup-installer/views/view.help.php +4 -4
  25. installer/dup-installer/views/view.init1.php +1 -1
  26. installer/dup-installer/views/view.s1.base.php +3 -7
  27. installer/dup-installer/views/view.s2.base.php +2 -2
  28. installer/dup-installer/views/view.s3.php +2 -2
  29. installer/dup-installer/views/view.s4.php +1 -1
  30. installer/installer.tpl +6 -6
  31. lib/forceutf8/Encoding.php +4 -4
  32. readme.txt +3 -3
  33. uninstall.php +3 -0
  34. views/packages/details/detail.php +2 -2
  35. views/packages/main/s1.setup1.php +5 -3
  36. views/packages/main/s1.setup2.php +2 -2
  37. views/packages/main/s2.scan1.php +1 -1
  38. views/packages/main/s2.scan3.php +3 -3
  39. views/packages/main/s3.build.php +8 -1
  40. views/settings/packages.php +1 -1
  41. views/tools/diagnostics/inc.settings.php +8 -4
  42. views/tools/diagnostics/inc.validator.php +1 -1
  43. views/tools/diagnostics/information.php +4 -3
assets/css/style.css CHANGED
@@ -75,3 +75,130 @@ div.cleanup-notice b.title {color: green;font-size: 20px;}
75
  /*SCREEN TABS*/
76
  div.dup-screen-hlp-info {line-height:26px; padding:10px 0 10px 0}
77
  #screen-meta-links .button { font-size:13px !important; height:auto !important;font-weight: normal; padding: 3px 6px 3px 16px !important;min-width:72px !important}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  /*SCREEN TABS*/
76
  div.dup-screen-hlp-info {line-height:26px; padding:10px 0 10px 0}
77
  #screen-meta-links .button { font-size:13px !important; height:auto !important;font-weight: normal; padding: 3px 6px 3px 16px !important;min-width:72px !important}
78
+
79
+ /*= Duplicator Message
80
+ ---------------------------------------*/
81
+ .notice.duplicator-message {
82
+ border: none;
83
+ padding: 20px;
84
+ }
85
+
86
+ .notice.duplicator-message .duplicator-message-inner {
87
+ display: -webkit-box;
88
+ display: -webkit-flex;
89
+ display: -ms-flexbox;
90
+ display: flex;
91
+ -webkit-box-align: center;
92
+ -webkit-align-items: center;
93
+ -ms-flex-align: center;
94
+ align-items: center;
95
+ }
96
+
97
+ .notice.duplicator-message .duplicator-message-icon {
98
+ font-size: 20px;
99
+ }
100
+
101
+ .notice.duplicator-message .duplicator-message-content {
102
+ padding: 0 20px;
103
+ }
104
+
105
+ .notice.duplicator-message p {
106
+ padding: 0;
107
+ margin: 0;
108
+ }
109
+
110
+ .notice.duplicator-message h3 {
111
+ margin: 0 0 5px;
112
+ }
113
+
114
+ .notice.duplicator-message .duplicator-message-action {
115
+ text-align: center;
116
+ display: -webkit-box;
117
+ display: -webkit-flex;
118
+ display: -ms-flexbox;
119
+ display: flex;
120
+ -webkit-box-orient: vertical;
121
+ -webkit-box-direction: normal;
122
+ -webkit-flex-direction: column;
123
+ -ms-flex-direction: column;
124
+ flex-direction: column;
125
+ margin-left: auto;
126
+ }
127
+
128
+ .notice.duplicator-message .duplicator-message-action .duplicator-button {
129
+ background-color: #D30C5C;
130
+ color: #fff;
131
+ border-color: #7c1337;
132
+ -webkit-box-shadow: 0 1px 0 #7c1337;
133
+ box-shadow: 0 1px 0 #7c1337;
134
+ padding: 5px 30px;
135
+ height: auto;
136
+ line-height: 20px;
137
+ text-transform: capitalize;
138
+ }
139
+
140
+ .notice.duplicator-message .duplicator-message-action .duplicator-button i {
141
+ margin-right: 5px;
142
+ }
143
+
144
+ .notice.duplicator-message .duplicator-message-action .duplicator-button:hover {
145
+ background-color: #a0124a;
146
+ }
147
+
148
+ .notice.duplicator-message .duplicator-message-action .duplicator-button:active {
149
+ -webkit-box-shadow: inset 0 1px 0 #7c1337;
150
+ box-shadow: inset 0 1px 0 #7c1337;
151
+ -webkit-transform: translateY(1px);
152
+ -ms-transform: translateY(1px);
153
+ transform: translateY(1px);
154
+ }
155
+
156
+ .notice.duplicator-message .duplicator-message-action .duplicator-link {
157
+ padding-top: 5px;
158
+ }
159
+
160
+ .notice.duplicator-message .duplicator-message-actions {
161
+ margin-top: 10px;
162
+ }
163
+
164
+ .notice.duplicator-message .duplicator-message-actions .button.button-primary {
165
+ margin-right: 5px;
166
+ }
167
+
168
+ .notice.duplicator-message-announcement {
169
+ border-color: #D30C5C;
170
+ }
171
+
172
+ .notice.duplicator-message-announcement a {
173
+ color: #D30C5C;
174
+ }
175
+
176
+ @media (min-width: 1200px) {
177
+ .duplicator-message-action {
178
+ padding-right: 10px;
179
+ }
180
+ }
181
+
182
+ @media (max-width: 600px) {
183
+ .notice.duplicator-message {
184
+ padding: 20px;
185
+ }
186
+ .notice.duplicator-message .duplicator-message-inner {
187
+ display: block;
188
+ text-align: center;
189
+ }
190
+ .notice.duplicator-message .duplicator-message-inner .duplicator-message-icon,
191
+ .notice.duplicator-message .duplicator-message-inner .duplicator-message-content,
192
+ .notice.duplicator-message .duplicator-message-inner .duplicator-message-action {
193
+ display: block;
194
+ }
195
+ .notice.duplicator-message .duplicator-message-inner .duplicator-message-action {
196
+ text-align: center;
197
+ }
198
+ .notice.duplicator-message .duplicator-message-inner .duplicator-message-icon {
199
+ width: auto;
200
+ }
201
+ .notice.duplicator-message .duplicator-message-inner .duplicator-message-content {
202
+ padding: 10px 0;
203
+ }
204
+ }
assets/img/logo.png ADDED
Binary file
assets/js/global-admin-script.js ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function($) {
2
+ $('div.notice.duplicator-message-dismissed, .duplicator-message .notice-dismiss').on('click', function (event) {
3
+ event.preventDefault();
4
+ $.post(ajaxurl, {
5
+ action: 'duplicator_set_admin_notice_viewed',
6
+ notice_id: $(this).closest('.duplicator-message-dismissed').data('notice_id')
7
+ });
8
+ var $wrapperElm = $(this).closest('.duplicator-message-dismissed');
9
+ $wrapperElm.fadeTo(100, 0, function () {
10
+ $wrapperElm.slideUp(100, function () {
11
+ $wrapperElm.remove();
12
+ });
13
+ });
14
+ });
15
+ });
16
+
assets/js/javascript.php CHANGED
@@ -323,5 +323,24 @@ jQuery(document).ready(function($)
323
  //Prevent notice boxes from flashing as its re-positioned in DOM
324
  $('div.dup-wpnotice-box').show(300);
325
 
326
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  </script>
323
  //Prevent notice boxes from flashing as its re-positioned in DOM
324
  $('div.dup-wpnotice-box').show(300);
325
 
326
+ });
327
+
328
+ jQuery(document).ready(function($) {
329
+ $('.duplicator-message .notice-dismiss, .duplicator-message .duplicator-notice-dismiss, .duplicator-message .duplicator-notice-rate-now').on('click', function (event) {
330
+ if ('button button-primary duplicator-notice-rate-now' !== $(event.target).attr('class')) {
331
+ event.preventDefault();
332
+ }
333
+ $.post(ajaxurl, {
334
+ action: 'duplicator_set_admin_notice_viewed',
335
+ notice_id: $(this).closest('.duplicator-message-dismissed').data('notice_id')
336
+ });
337
+ var $wrapperElm = $(this).closest('.duplicator-message-dismissed');
338
+ $wrapperElm.fadeTo(100, 0, function () {
339
+ $wrapperElm.slideUp(100, function () {
340
+ $wrapperElm.remove();
341
+ });
342
+ });
343
+ });
344
+ });
345
+
346
  </script>
classes/class.db.php CHANGED
@@ -113,82 +113,61 @@ class DUP_DB extends wpdb
113
  }
114
 
115
  /**
116
- * Returns the mysqldump path if the server is enabled to execute it otherwise false
117
- *
118
- * @return boolean|string
119
- */
120
- public static function getMySqlDumpPath()
121
- {
122
- //Is shell_exec possible
123
- if (!DUP_Util::hasShellExec()) {
124
- return false;
125
- }
126
-
127
- $custom_mysqldump_path = DUP_Settings::Get('package_mysqldump_path');
128
- $custom_mysqldump_path = (strlen($custom_mysqldump_path)) ? $custom_mysqldump_path : '';
129
-
130
- //Common Windows Paths
131
- if (DUP_Util::isWindows()) {
132
- $paths = array(
133
- $custom_mysqldump_path,
134
- self::getWindowsMySqlDumpRealPath(),
135
- 'C:/xampp/mysql/bin/mysqldump.exe',
136
- 'C:/Program Files/xampp/mysql/bin/mysqldump',
137
- 'C:/Program Files/MySQL/MySQL Server 6.0/bin/mysqldump',
138
- 'C:/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump',
139
- 'C:/Program Files/MySQL/MySQL Server 5.4/bin/mysqldump'
140
- );
141
-
142
- //Common Linux Paths
143
- } else {
144
- $path1 = '';
145
- $path2 = '';
146
- $mysqldump = `which mysqldump`;
147
- if (DUP_Util::isExecutable($mysqldump)) {
148
- $path1 = (!empty($mysqldump)) ? $mysqldump : '';
149
- }
150
-
151
- $mysqldump = dirname(`which mysql`)."/mysqldump";
152
- if (DUP_Util::isExecutable($mysqldump)) {
153
- $path2 = (!empty($mysqldump)) ? $mysqldump : '';
154
- }
155
-
156
- $paths = array(
157
- $custom_mysqldump_path,
158
- $path1,
159
- $path2,
160
- '/usr/local/bin/mysqldump',
161
- '/usr/local/mysql/bin/mysqldump',
162
- '/usr/mysql/bin/mysqldump',
163
- '/usr/bin/mysqldump',
164
- '/opt/local/lib/mysql6/bin/mysqldump',
165
- '/opt/local/lib/mysql5/bin/mysqldump'
166
- );
167
- }
168
-
169
- //Try to find a path that works. With open_basedir enabled, the file_exists may not work on some systems
170
- //So we fallback and try to use exec as a last resort
171
- $exec_available = function_exists('exec');
172
- foreach ($paths as $path) {
173
- if (@file_exists($path)) {
174
- if (DUP_Util::isExecutable($path)) {
175
- return $path;
176
- }
177
- } elseif ($exec_available) {
178
- $out = array();
179
- $rc = -1;
180
- $cmd = $path.' --help';
181
- @exec($cmd, $out, $rc);
182
- if ($rc === 0) {
183
- return $path;
184
- }
185
- }
186
- }
187
-
188
- return false;
189
- }
190
 
191
- /**
192
  * Returns all collation types that are assigned to the tables in
193
  * the current database. Each element in the array is unique
194
  *
113
  }
114
 
115
  /**
116
+ * Returns the mysqldump path if the server is enabled to execute it otherwise false
117
+ *
118
+ * @return boolean|string
119
+ */
120
+ public static function getMySqlDumpPath()
121
+ {
122
+ //Is shell_exec possible
123
+ if (!DUP_Util::hasShellExec()) {
124
+ return false;
125
+ }
126
+
127
+ $custom_mysqldump_path = DUP_Settings::Get('package_mysqldump_path');
128
+ $custom_mysqldump_path = (strlen($custom_mysqldump_path)) ? $custom_mysqldump_path : '';
129
+
130
+ //Common Windows Paths
131
+ if (DUP_Util::isWindows()) {
132
+ $paths = array(
133
+ $custom_mysqldump_path,
134
+ 'mysqldump.exe',
135
+ self::getWindowsMySqlDumpRealPath(),
136
+ 'C:/xampp/mysql/bin/mysqldump.exe',
137
+ 'C:/Program Files/xampp/mysql/bin/mysqldump',
138
+ 'C:/Program Files/MySQL/MySQL Server 6.0/bin/mysqldump',
139
+ 'C:/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump',
140
+ 'C:/Program Files/MySQL/MySQL Server 5.4/bin/mysqldump'
141
+ );
142
+
143
+ //Common Linux Paths
144
+ } else {
145
+ $paths = array(
146
+ $custom_mysqldump_path,
147
+ 'mysqldump',
148
+ '/usr/local/bin/mysqldump',
149
+ '/usr/local/mysql/bin/mysqldump',
150
+ '/usr/mysql/bin/mysqldump',
151
+ '/usr/bin/mysqldump',
152
+ '/opt/local/lib/mysql6/bin/mysqldump',
153
+ '/opt/local/lib/mysql5/bin/mysqldump'
154
+ );
155
+ }
156
+
157
+ foreach ($paths as $path) {
158
+ $out = array();
159
+ $rc = -1;
160
+ $cmd = $path.' --version';
161
+ @exec($cmd, $out, $rc);
162
+ if ($rc === 0) {
163
+ return $path;
164
+ }
165
+ }
166
+
167
+ return false;
168
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
+ /**
171
  * Returns all collation types that are assigned to the tables in
172
  * the current database. Each element in the array is unique
173
  *
classes/class.server.php CHANGED
@@ -72,8 +72,9 @@ class DUP_Server
72
  $dup_tests['PHP']['ALL'] = !in_array('Fail', $dup_tests['PHP']) ? 'Pass' : 'Fail';
73
 
74
  //REQUIRED PATHS
75
- $handle_test = @opendir(DUPLICATOR_WPROOTPATH);
76
- $dup_tests['IO']['WPROOT'] = is_writeable(DUPLICATOR_WPROOTPATH) && $handle_test ? 'Pass' : 'Warn';
 
77
  @closedir($handle_test);
78
 
79
  $dup_tests['IO']['SSDIR'] = (file_exists(DUPLICATOR_SSDIR_PATH) && is_writeable(DUPLICATOR_SSDIR_PATH)) ? 'Pass' : 'Fail';
@@ -133,7 +134,7 @@ class DUP_Server
133
 
134
  //Core Files
135
  $files = array();
136
- $files['wp-config.php'] = file_exists(DUP_Util::safePath(DUPLICATOR_WPROOTPATH.'/wp-config.php'));
137
 
138
  /** searching wp-config in working word press is not worthy
139
  * if this script is executing that means wp-config.php exists :)
@@ -202,15 +203,15 @@ class DUP_Server
202
  public static function getInstallerFiles()
203
  {
204
  // alphanumeric 7 time, then -(dash), then 8 digits
205
-
206
  $retArr = array(
207
  basename(DUPLICATOR_INSTALLER_DIRECTORY).' '.esc_html__('(directory)', 'duplicator') => DUPLICATOR_INSTALLER_DIRECTORY,
208
- DUPLICATOR_INSTALL_PHP => DUPLICATOR_WPROOTPATH.DUPLICATOR_INSTALL_PHP,
209
- DUPLICATOR_INSTALL_BAK => DUPLICATOR_WPROOTPATH.DUPLICATOR_INSTALL_BAK,
210
- 'dup-installer-bootlog__[HASH].txt' => DUPLICATOR_WPROOTPATH.'dup-installer-bootlog__'.DUPLICATOR_INSTALLER_HASH_PATTERN.'.txt',
211
  );
212
  if (DUPLICATOR_INSTALL_SITE_OVERWRITE_ON) {
213
- $retArr['dup-wp-config-arc__[HASH].txt'] = DUPLICATOR_WPROOTPATH.'dup-wp-config-arc__'.DUPLICATOR_INSTALLER_HASH_PATTERN.'.txt';
214
  }
215
  return $retArr;
216
  }
72
  $dup_tests['PHP']['ALL'] = !in_array('Fail', $dup_tests['PHP']) ? 'Pass' : 'Fail';
73
 
74
  //REQUIRED PATHS
75
+ $abs_path = duplicator_get_abs_path();
76
+ $handle_test = @opendir($abs_path);
77
+ $dup_tests['IO']['WPROOT'] = is_writeable($abs_path) && $handle_test ? 'Pass' : 'Warn';
78
  @closedir($handle_test);
79
 
80
  $dup_tests['IO']['SSDIR'] = (file_exists(DUPLICATOR_SSDIR_PATH) && is_writeable(DUPLICATOR_SSDIR_PATH)) ? 'Pass' : 'Fail';
134
 
135
  //Core Files
136
  $files = array();
137
+ $files['wp-config.php'] = file_exists(duplicator_get_abs_path().'/wp-config.php');
138
 
139
  /** searching wp-config in working word press is not worthy
140
  * if this script is executing that means wp-config.php exists :)
203
  public static function getInstallerFiles()
204
  {
205
  // alphanumeric 7 time, then -(dash), then 8 digits
206
+ $abs_path = duplicator_get_abs_path();
207
  $retArr = array(
208
  basename(DUPLICATOR_INSTALLER_DIRECTORY).' '.esc_html__('(directory)', 'duplicator') => DUPLICATOR_INSTALLER_DIRECTORY,
209
+ DUPLICATOR_INSTALL_PHP => $abs_path . '/' .DUPLICATOR_INSTALL_PHP,
210
+ DUPLICATOR_INSTALL_BAK => $abs_path . '/' .DUPLICATOR_INSTALL_BAK,
211
+ 'dup-installer-bootlog__[HASH].txt' => $abs_path.'/dup-installer-bootlog__'.DUPLICATOR_INSTALLER_HASH_PATTERN.'.txt',
212
  );
213
  if (DUPLICATOR_INSTALL_SITE_OVERWRITE_ON) {
214
+ $retArr['dup-wp-config-arc__[HASH].txt'] = $abs_path.'/dup-wp-config-arc__'.DUPLICATOR_INSTALLER_HASH_PATTERN.'.txt';
215
  }
216
  return $retArr;
217
  }
classes/package/class.pack.archive.php CHANGED
@@ -61,15 +61,15 @@ class DUP_Archive
61
  $this->ExportOnlyDB = false;
62
  $this->FilterInfo = new DUP_Archive_Filter_Info();
63
 
64
- $rootPath = DUP_Util::safePath(rtrim(DUPLICATOR_WPROOTPATH, '//'));
65
 
66
- $this->wpCorePaths[] = DUP_Util::safePath("{$rootPath}/wp-admin");
67
  $this->wpCorePaths[] = DUP_Util::safePath(WP_CONTENT_DIR."/uploads");
68
  $this->wpCorePaths[] = DUP_Util::safePath(WP_CONTENT_DIR."/languages");
69
  $this->wpCorePaths[] = DUP_Util::safePath(get_theme_root());
70
- $this->wpCorePaths[] = DUP_Util::safePath("{$rootPath}/wp-includes");
71
 
72
- $this->wpCoreExactPaths[] = DUP_Util::safePath("{$rootPath}");
73
  $this->wpCoreExactPaths[] = DUP_Util::safePath(WP_CONTENT_DIR);
74
  }
75
 
@@ -165,8 +165,7 @@ class DUP_Archive
165
  public function getScannerData()
166
  {
167
  $this->createFilterInfo();
168
- $rootPath = DUP_Util::safePath(rtrim(DUPLICATOR_WPROOTPATH, '//'));
169
- $rootPath = (trim($rootPath) == '') ? '/' : $rootPath;
170
 
171
  $this->RecursiveLinks = array();
172
  //If the root directory is a filter then skip it all
@@ -302,7 +301,7 @@ class DUP_Archive
302
 
303
  //FILTER: CORE ITMES
304
  //Filters Duplicator free packages & All pro local directories
305
- $wp_root = rtrim(DUPLICATOR_WPROOTPATH, '/');
306
  $upload_dir = wp_upload_dir();
307
  $upload_dir = isset($upload_dir['basedir']) ? basename($upload_dir['basedir']) : 'uploads';
308
  $wp_content = str_replace("\\", "/", WP_CONTENT_DIR);
@@ -310,6 +309,7 @@ class DUP_Archive
310
  $this->FilterInfo->Dirs->Core = array(
311
  //WP-ROOT
312
  $wp_root.'/wp-snapshots',
 
313
  //WP-CONTENT
314
  $wp_content.'/backups-dup-pro',
315
  $wp_content.'/ai1wm-backups',
@@ -371,9 +371,10 @@ class DUP_Archive
371
  $this->FilterExtsAll = array_merge($this->FilterInfo->Exts->Instance, $this->FilterInfo->Exts->Core);
372
  $this->FilterFilesAll = array_merge($this->FilterInfo->Files->Instance, $this->FilterInfo->Files->Global);
373
 
374
- $this->FilterFilesAll[] = DUPLICATOR_WPROOTPATH.'.htaccess';
375
- $this->FilterFilesAll[] = DUPLICATOR_WPROOTPATH.'web.config';
376
- $this->FilterFilesAll[] = DUPLICATOR_WPROOTPATH.'wp-config.php';
 
377
  $this->tmpFilterDirsAll = $this->FilterDirsAll;
378
 
379
  //PHP 5 on windows decode patch
@@ -429,7 +430,7 @@ class DUP_Archive
429
  //Check for other WordPress installs
430
  if ($name === 'wp-admin') {
431
  $parent_dir = realpath(dirname($this->Dirs[$key]));
432
- if ($parent_dir != realpath(DUPLICATOR_WPROOTPATH)) {
433
  if (file_exists("$parent_dir/wp-includes")) {
434
  if (file_exists("$parent_dir/wp-config.php")) {
435
  // Ensure we aren't adding any critical directories
@@ -649,7 +650,7 @@ class DUP_Archive
649
  $this->FilterInfo->TreeSize[] = array(
650
  'size' => DUP_Util::byteSize($sum, 0),
651
  'dir' => $dir,
652
- 'sdir' => str_replace(DUPLICATOR_WPROOTPATH, '/', $dir),
653
  'iscore' => $iscore,
654
  'files' => $files
655
  );
@@ -679,7 +680,7 @@ class DUP_Archive
679
 
680
  $this->FilterInfo->TreeWarning[] = array(
681
  'dir' => $dir,
682
- 'sdir' => str_replace(DUPLICATOR_WPROOTPATH, '/', $dir),
683
  'iscore' => $iscore,
684
  'count' => count($files),
685
  'files' => $files);
@@ -713,7 +714,7 @@ class DUP_Archive
713
 
714
  $this->FilterInfo->TreeWarning[] = array(
715
  'dir' => $dir,
716
- 'sdir' => str_replace(DUPLICATOR_WPROOTPATH, '/', $dir),
717
  'iscore' => $iscore,
718
  'count' => 0);
719
  }
@@ -729,10 +730,11 @@ class DUP_Archive
729
  public function getWPConfigFilePath()
730
  {
731
  $wpconfig_filepath = '';
732
- if (file_exists(DUPLICATOR_WPROOTPATH.'wp-config.php')) {
733
- $wpconfig_filepath = DUPLICATOR_WPROOTPATH.'wp-config.php';
734
- } elseif (@file_exists(dirname(DUPLICATOR_WPROOTPATH).'/wp-config.php') && !@file_exists(dirname(DUPLICATOR_WPROOTPATH).'/wp-settings.php')) {
735
- $wpconfig_filepath = dirname(DUPLICATOR_WPROOTPATH).'/wp-config.php';
 
736
  }
737
  return $wpconfig_filepath;
738
  }
@@ -770,7 +772,7 @@ class DUP_Archive
770
  $newWPContentDirPath = empty($basePath) ? 'wp-content/' : $basePath.'wp-content/';
771
  $emptyDir = ltrim(str_replace($wpContentDirNormalizePath, $newWPContentDirPath, $dir), '/');
772
  } else {
773
- $emptyDir = ltrim(str_replace($compressDir, $basePath, $dir), '/');
774
  }
775
  return $emptyDir;
776
  }
@@ -785,8 +787,8 @@ class DUP_Archive
785
  if ($isOuterWPContentDir && 0 === strpos($file, $wpContentDirNormalizePath)) {
786
  $newWPContentDirPath = empty($basePath) ? 'wp-content/' : $basePath.'wp-content/';
787
  $localFileName = ltrim(str_replace($wpContentDirNormalizePath, $newWPContentDirPath, $file), '/');
788
- } else {
789
- $localFileName = ltrim(str_replace($compressDir, $basePath, $file), '/');
790
  }
791
  return $localFileName;
792
  }
61
  $this->ExportOnlyDB = false;
62
  $this->FilterInfo = new DUP_Archive_Filter_Info();
63
 
64
+ $homePath = duplicator_get_home_path();
65
 
66
+ $this->wpCorePaths[] = DUP_Util::safePath("{$homePath}/wp-admin");
67
  $this->wpCorePaths[] = DUP_Util::safePath(WP_CONTENT_DIR."/uploads");
68
  $this->wpCorePaths[] = DUP_Util::safePath(WP_CONTENT_DIR."/languages");
69
  $this->wpCorePaths[] = DUP_Util::safePath(get_theme_root());
70
+ $this->wpCorePaths[] = DUP_Util::safePath("{$homePath}/wp-includes");
71
 
72
+ $this->wpCoreExactPaths[] = DUP_Util::safePath("{$homePath}");
73
  $this->wpCoreExactPaths[] = DUP_Util::safePath(WP_CONTENT_DIR);
74
  }
75
 
165
  public function getScannerData()
166
  {
167
  $this->createFilterInfo();
168
+ $rootPath = duplicator_get_abs_path();
 
169
 
170
  $this->RecursiveLinks = array();
171
  //If the root directory is a filter then skip it all
301
 
302
  //FILTER: CORE ITMES
303
  //Filters Duplicator free packages & All pro local directories
304
+ $wp_root = duplicator_get_abs_path();
305
  $upload_dir = wp_upload_dir();
306
  $upload_dir = isset($upload_dir['basedir']) ? basename($upload_dir['basedir']) : 'uploads';
307
  $wp_content = str_replace("\\", "/", WP_CONTENT_DIR);
309
  $this->FilterInfo->Dirs->Core = array(
310
  //WP-ROOT
311
  $wp_root.'/wp-snapshots',
312
+ $wp_root.'/.opcache',
313
  //WP-CONTENT
314
  $wp_content.'/backups-dup-pro',
315
  $wp_content.'/ai1wm-backups',
371
  $this->FilterExtsAll = array_merge($this->FilterInfo->Exts->Instance, $this->FilterInfo->Exts->Core);
372
  $this->FilterFilesAll = array_merge($this->FilterInfo->Files->Instance, $this->FilterInfo->Files->Global);
373
 
374
+ $abs_path = duplicator_get_abs_path();
375
+ $this->FilterFilesAll[] = $abs_path.'/.htaccess';
376
+ $this->FilterFilesAll[] = $abs_path.'/web.config';
377
+ $this->FilterFilesAll[] = $abs_path.'/wp-config.php';
378
  $this->tmpFilterDirsAll = $this->FilterDirsAll;
379
 
380
  //PHP 5 on windows decode patch
430
  //Check for other WordPress installs
431
  if ($name === 'wp-admin') {
432
  $parent_dir = realpath(dirname($this->Dirs[$key]));
433
+ if ($parent_dir != realpath(duplicator_get_abs_path())) {
434
  if (file_exists("$parent_dir/wp-includes")) {
435
  if (file_exists("$parent_dir/wp-config.php")) {
436
  // Ensure we aren't adding any critical directories
650
  $this->FilterInfo->TreeSize[] = array(
651
  'size' => DUP_Util::byteSize($sum, 0),
652
  'dir' => $dir,
653
+ 'sdir' => str_replace(duplicator_get_abs_path(), '/', $dir),
654
  'iscore' => $iscore,
655
  'files' => $files
656
  );
680
 
681
  $this->FilterInfo->TreeWarning[] = array(
682
  'dir' => $dir,
683
+ 'sdir' => str_replace(duplicator_get_abs_path(), '/', $dir),
684
  'iscore' => $iscore,
685
  'count' => count($files),
686
  'files' => $files);
714
 
715
  $this->FilterInfo->TreeWarning[] = array(
716
  'dir' => $dir,
717
+ 'sdir' => str_replace(duplicator_get_abs_path(), '/', $dir),
718
  'iscore' => $iscore,
719
  'count' => 0);
720
  }
730
  public function getWPConfigFilePath()
731
  {
732
  $wpconfig_filepath = '';
733
+ $abs_path = duplicator_get_abs_path();
734
+ if (file_exists($abs_path.'/wp-config.php')) {
735
+ $wpconfig_filepath = $abs_path.'/wp-config.php';
736
+ } elseif (@file_exists(dirname($abs_path).'/wp-config.php') && !@file_exists(dirname($abs_path).'/wp-settings.php')) {
737
+ $wpconfig_filepath = dirname($abs_path).'/wp-config.php';
738
  }
739
  return $wpconfig_filepath;
740
  }
772
  $newWPContentDirPath = empty($basePath) ? 'wp-content/' : $basePath.'wp-content/';
773
  $emptyDir = ltrim(str_replace($wpContentDirNormalizePath, $newWPContentDirPath, $dir), '/');
774
  } else {
775
+ $emptyDir = ltrim($basePath.preg_replace('/^'.preg_quote($compressDir, '/').'(.*)/m', '$1', $dir), '/');
776
  }
777
  return $emptyDir;
778
  }
787
  if ($isOuterWPContentDir && 0 === strpos($file, $wpContentDirNormalizePath)) {
788
  $newWPContentDirPath = empty($basePath) ? 'wp-content/' : $basePath.'wp-content/';
789
  $localFileName = ltrim(str_replace($wpContentDirNormalizePath, $newWPContentDirPath, $file), '/');
790
+ } else {
791
+ $localFileName = ltrim($basePath.preg_replace('/^'.preg_quote($compressDir, '/').'(.*)/m', '$1', $file), '/');
792
  }
793
  return $localFileName;
794
  }
classes/package/class.pack.database.php CHANGED
@@ -1,7 +1,8 @@
1
  <?php
2
  defined('ABSPATH') || defined('DUPXABSPATH') || exit;
3
  // Exit if accessed directly
4
- if (! defined('DUPLICATOR_VERSION')) exit;
 
5
 
6
  /**
7
  * Class for gathering system information about a database
@@ -12,6 +13,7 @@ if (! defined('DUPLICATOR_VERSION')) exit;
12
  */
13
  class DUP_DatabaseInfo
14
  {
 
15
  /**
16
  * The SQL file was built with mysqldump or PHP
17
  */
@@ -98,13 +100,14 @@ class DUP_DatabaseInfo
98
  //CONSTRUCTOR
99
  function __construct()
100
  {
101
- $this->collationList = array();
102
  $this->tableWiseRowCounts = array();
103
  }
104
  }
105
 
106
  class DUP_Database
107
  {
 
108
  //PUBLIC
109
  public $Type = 'MySQL';
110
  public $Size;
@@ -115,7 +118,7 @@ class DUP_Database
115
  public $Name;
116
  public $Compatible;
117
  public $Comments;
118
-
119
  /**
120
  *
121
  * @var DUP_DatabaseInfo
@@ -133,12 +136,12 @@ class DUP_Database
133
  */
134
  function __construct($package)
135
  {
136
- $this->Package = $package;
137
- $this->EOFMarker = "";
138
- $package_zip_flush = DUP_Settings::Get('package_zip_flush');
139
- $this->networkFlush = empty($package_zip_flush) ? false : $package_zip_flush;
140
- $this->info = new DUP_DatabaseInfo();
141
- $this->info->varLowerCaseTables = DUP_Util::isWindows() ? 1 : 0;
142
  }
143
 
144
  /**
@@ -148,12 +151,12 @@ class DUP_Database
148
  *
149
  * @return null
150
  */
151
- public function build($package, $errorBehavior = Dup_ErrorBehavior::Quit)
152
  {
153
  try {
154
 
155
  $this->Package = $package;
156
- do_action('duplicator_lite_build_database_before_start' , $package);
157
 
158
  $time_start = DUP_Util::getMicrotime();
159
  $this->Package->setStatus(DUP_PackageStatus::DBSTART);
@@ -164,7 +167,7 @@ class DUP_Database
164
 
165
  $mysqlDumpPath = DUP_DB::getMySqlDumpPath();
166
  $mode = DUP_DB::getBuildMode();
167
- $reserved_db_filepath = DUPLICATOR_WPROOTPATH.'database.sql';
168
 
169
  $log = "\n********************************************************************************\n";
170
  $log .= "DATABASE:\n";
@@ -177,7 +180,7 @@ class DUP_Database
177
  DUP_Log::Info($log);
178
  $log = null;
179
 
180
- do_action('duplicator_lite_build_database_start' , $package);
181
 
182
  switch ($mode) {
183
  case 'MYSQLDUMP':
@@ -197,25 +200,25 @@ class DUP_Database
197
  DUP_Log::Info("SQL FILE SIZE: ".DUP_Util::byteSize($sql_file_size)." ({$sql_file_size})");
198
 
199
  if ($sql_file_size < 1350) {
200
- $error_message = "SQL file size too low.";
201
  $package->BuildProgress->set_failed($error_message);
202
  $package->Status = DUP_PackageStatus::ERROR;
203
  $package->Update();
204
  DUP_Log::Error($error_message, "File does not look complete. Check permission on file and parent directory at [{$this->dbStorePath}]", $errorBehavior);
205
- do_action('duplicator_lite_build_database_fail' , $package);
206
-
207
  } else {
208
- do_action('duplicator_lite_build_database_completed' , $package);
209
  }
210
 
211
  DUP_Log::Info("SQL FILE TIME: ".date("Y-m-d H:i:s"));
212
  DUP_Log::Info("SQL RUNTIME: {$time_sum}");
213
 
214
  $this->Size = @filesize($this->dbStorePath);
215
-
216
  $this->Package->setStatus(DUP_PackageStatus::DBDONE);
217
- } catch (Exception $e) {
218
- do_action('duplicator_lite_build_database_fail' , $package);
 
219
  DUP_Log::Error("Runtime error in DUP_Database::Build", "Exception: {$e}", $errorBehavior);
220
  }
221
  }
@@ -230,7 +233,7 @@ class DUP_Database
230
  global $wpdb;
231
 
232
  $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : array();
233
- $tblBaseCount = 0;
234
  $tblCount = 0;
235
 
236
  $tables = $wpdb->get_results("SHOW TABLE STATUS", ARRAY_A);
@@ -265,12 +268,12 @@ class DUP_Database
265
  $size = ($table["Data_length"] + $table["Index_length"]);
266
  $rows = empty($table["Rows"]) ? '0' : $table["Rows"];
267
 
268
- $info['Size'] += $size;
269
- $info['Rows'] += ($table["Rows"]);
270
  $info['TableList'][$name]['Case'] = preg_match('/[A-Z]/', $name) ? 1 : 0;
271
  $info['TableList'][$name]['Rows'] = number_format($rows);
272
  $info['TableList'][$name]['Size'] = DUP_Util::byteSize($size);
273
- $info['TableList'][$name]['USize'] = $size;
274
  $tblCount++;
275
 
276
  //Table Uppercase
@@ -310,26 +313,27 @@ class DUP_Database
310
  $info['TableCount'] = $tblCount;
311
 
312
  $this->setInfoObj();
313
- $this->info->isTablesUpperCase = $tblCaseFound;
314
- $this->info->tablesBaseCount = $tblBaseCount;
315
- $this->info->tablesFinalCount = $tblCount;
316
- $this->info->tablesRowCount = $info['Rows'];
317
- $this->info->tablesSizeOnDisk = $info['Size'];
318
 
319
  return $info;
320
  }
321
 
322
- public function setInfoObj() {
 
323
  global $wpdb;
324
  $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : array();
325
 
326
- $this->info->buildMode = DUP_DB::getBuildMode();
327
- $this->info->version = DUP_DB::getVersion();
328
- $this->info->versionComment = DUP_DB::getVariable('version_comment');
329
- $this->info->varLowerCaseTables = DUP_DB::getVariable('lower_case_table_names');
330
- $this->info->name = $wpdb->dbname;
331
- $this->info->isNameUpperCase = preg_match('/[A-Z]/', $wpdb->dbname) ? 1 : 0;
332
- $this->info->collationList = DUP_DB::getTableCollationList($filterTables);
333
  }
334
 
335
  /**
@@ -338,7 +342,8 @@ class DUP_Database
338
  * @param object $package The reference to the current package being built *
339
  * @return void
340
  */
341
- public function validateTableWiseRowCounts() {
 
342
  foreach ($this->Package->Database->info->tableWiseRowCounts as $rewriteTableAs => $rowCount) {
343
  $newRowCount = $GLOBALS['wpdb']->get_var("SELECT Count(*) FROM `{$rewriteTableAs}`");
344
  if ($rowCount != $newRowCount) {
@@ -382,8 +387,8 @@ class DUP_Database
382
  }
383
 
384
  //Filter tables
385
- $res = $wpdb->get_results('SHOW FULL TABLES', ARRAY_N);
386
- $tables = array();
387
  $baseTables = array();
388
  foreach ($res as $row) {
389
  if (DUP_Util::isTableExists($row[0])) {
@@ -398,8 +403,8 @@ class DUP_Database
398
 
399
  foreach ($tables as $table) {
400
  if (in_array($table, $baseTables)) {
401
- $row_count = $GLOBALS['wpdb']->get_var("SELECT Count(*) FROM `{$table}`");
402
- $rewrite_table_as = $this->rewriteTableNameAs($table);
403
  $this->Package->Database->info->tableWiseRowCounts[$rewrite_table_as] = $row_count;
404
  }
405
  }
@@ -421,7 +426,7 @@ class DUP_Database
421
  $cmd .= ' -h '.escapeshellarg($host);
422
  $cmd .= (!empty($port) && is_numeric($port) ) ?
423
  ' -P '.$port : '';
424
-
425
  $isPopenEnabled = DUP_Shell_U::isPopenEnabled();
426
 
427
  if (!$isPopenEnabled) {
@@ -430,11 +435,11 @@ class DUP_Database
430
 
431
  $cmd .= ' '.escapeshellarg(DB_NAME);
432
  $cmd .= ' 2>&1';
433
-
434
  if ($isPopenEnabled) {
435
  $needToRewrite = false;
436
- foreach ($tables as $tableName) {
437
- $rewriteTableAs = $this->rewriteTableNameAs($tableName);
438
  if ($tableName != $rewriteTableAs) {
439
  $needToRewrite = true;
440
  break;
@@ -443,10 +448,10 @@ class DUP_Database
443
 
444
  if ($needToRewrite) {
445
  $findReplaceTableNames = array(); // orignal table name => rewrite table name
446
-
447
- foreach ($tables as $tableName) {
448
- $rewriteTableAs = $this->rewriteTableNameAs($tableName);
449
- if ($tableName != $rewriteTableAs) {
450
  $findReplaceTableNames[$tableName] = $rewriteTableAs;
451
  }
452
  }
@@ -454,16 +459,17 @@ class DUP_Database
454
 
455
  $firstLine = '';
456
  DUP_LOG::trace("Executing mysql dump command by popen: $cmd");
457
- $handle = popen($cmd, "r");
458
  if ($handle) {
459
- $sql_header = "/* DUPLICATOR-LITE (MYSQL-DUMP BUILD MODE) MYSQL SCRIPT CREATED ON : ".@date("Y-m-d H:i:s")." */\n\n";
460
  file_put_contents($this->dbStorePath, $sql_header, FILE_APPEND);
461
  while (!feof($handle)) {
462
  $line = fgets($handle); //get ony one line
463
  if ($line) {
464
  if (empty($firstLine)) {
465
  $firstLine = $line;
466
- if (false !== stripos($line, 'Using a password on the command line interface can be insecure')) continue;
 
467
  }
468
 
469
  if ($needToRewrite) {
@@ -473,19 +479,19 @@ class DUP_Database
473
  $tableName = $matches[1];
474
  if (isset($findReplaceTableNames[$tableName])) {
475
  $rewriteTableAs = $findReplaceTableNames[$tableName];
476
- $line = str_replace('CREATE TABLE `'.$tableName.'`', 'CREATE TABLE `'.$rewriteTableAs.'`', $line, $replaceCount);
477
  }
478
  } elseif (preg_match('/INSERT INTO `(.*?)`/', $line, $matches)) {
479
  $tableName = $matches[1];
480
  if (isset($findReplaceTableNames[$tableName])) {
481
  $rewriteTableAs = $findReplaceTableNames[$tableName];
482
- $line = str_replace('INSERT INTO `'.$tableName.'`', 'INSERT INTO `'.$rewriteTableAs.'`', $line, $replaceCount);
483
  }
484
  } elseif (preg_match('/LOCK TABLES `(.*?)`/', $line, $matches)) {
485
  $tableName = $matches[1];
486
  if (isset($findReplaceTableNames[$tableName])) {
487
  $rewriteTableAs = $findReplaceTableNames[$tableName];
488
- $line = str_replace('LOCK TABLES `'.$tableName.'`', 'LOCK TABLES `'.$rewriteTableAs.'`', $line, $replaceCount);
489
  }
490
  }
491
  }
@@ -494,18 +500,19 @@ class DUP_Database
494
  $output = "Ran from {$exePath}";
495
  }
496
  }
497
- $ret = pclose($handle);
498
  } else {
499
  $output = '';
500
  }
501
-
502
  // Password bug > 5.6 (@see http://bugs.mysql.com/bug.php?id=66546)
503
  if (empty($output) && trim($firstLine) === 'Warning: Using a password on the command line interface can be insecure.') {
504
  $output = '';
505
  }
506
  } else {
507
  DUP_LOG::trace("Executing mysql dump command $cmd");
508
- $output = shell_exec($cmd);
 
509
 
510
  // Password bug > 5.6 (@see http://bugs.mysql.com/bug.php?id=66546)
511
  if (trim($output) === 'Warning: Using a password on the command line interface can be insecure.') {
@@ -526,7 +533,20 @@ class DUP_Database
526
  $sql_footer = "\n\n/* Duplicator WordPress Timestamp: ".date("Y-m-d H:i:s")."*/\n";
527
  $sql_footer .= "/* ".DUPLICATOR_DB_EOF_MARKER." */\n";
528
  file_put_contents($this->dbStorePath, $sql_footer, FILE_APPEND);
529
- return ($output) ? false : true;
 
 
 
 
 
 
 
 
 
 
 
 
 
530
  }
531
 
532
  /**
@@ -537,18 +557,18 @@ class DUP_Database
537
  private function phpDump($package)
538
  {
539
  global $wpdb;
540
-
541
  $wpdb->query("SET session wait_timeout = ".DUPLICATOR_DB_MAX_TIME);
542
  if (($handle = fopen($this->dbStorePath, 'w+')) == false) {
543
- DUP_Log::error('[PHP DUMP] ERROR Can\'t open sbStorePath "'.$this->dbStorePath.'"', Dup_ErrorBehavior::Quit);
544
  }
545
- $tables = $wpdb->get_col("SHOW FULL TABLES WHERE Table_Type != 'VIEW'");
546
-
547
  $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : null;
548
  $tblAllCount = count($tables);
549
  //$tblFilterOn = ($this->FilterOn) ? 'ON' : 'OFF';
550
  $qryLimit = DUP_Settings::Get('package_phpdump_qrylimit');
551
-
552
  if (is_array($filterTables) && $this->FilterOn) {
553
  foreach ($tables as $key => $val) {
554
  if (in_array($tables[$key], $filterTables)) {
@@ -558,72 +578,73 @@ class DUP_Database
558
  }
559
  $tblCreateCount = count($tables);
560
  $tblFilterCount = $tblAllCount - $tblCreateCount;
561
-
562
  DUP_Log::Info("TABLES: total:{$tblAllCount} | filtered:{$tblFilterCount} | create:{$tblCreateCount}");
563
  DUP_Log::Info("FILTERED: [{$this->FilterTables}]");
564
-
565
  //Added 'NO_AUTO_VALUE_ON_ZERO' at plugin version 1.2.12 to fix :
566
  //**ERROR** database error write 'Invalid default value for for older mysql versions
567
- $sql_header = "/* DUPLICATOR-LITE (PHP BUILD MODE) MYSQL SCRIPT CREATED ON : ".@date("Y-m-d H:i:s")." */\n\n";
568
  $sql_header .= "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;\n\n";
569
  $sql_header .= "SET FOREIGN_KEY_CHECKS = 0;\n\n";
570
  fwrite($handle, $sql_header);
571
-
572
  //BUILD CREATES:
573
  //All creates must be created before inserts do to foreign key constraints
574
  foreach ($tables as $table) {
575
- $rewrite_table_as = $this->rewriteTableNameAs($table);
576
- $create = $wpdb->get_row("SHOW CREATE TABLE `{$table}`", ARRAY_N);
577
- $count = 1;
578
  $create_table_query = str_replace($table, $rewrite_table_as, $create[1], $count);
579
  @fwrite($handle, "{$create_table_query};\n\n");
580
  }
581
-
582
- $procedures = $wpdb->get_col("SHOW PROCEDURE STATUS WHERE `Db` = '{$wpdb->dbname}'",1);
583
- if(count($procedures)){
584
- foreach ($procedures as $procedure){
585
  @fwrite($handle, "DELIMITER ;;\n");
586
  $create = $wpdb->get_row("SHOW CREATE PROCEDURE `{$procedure}`", ARRAY_N);
587
  @fwrite($handle, "{$create[2]} ;;\n");
588
  @fwrite($handle, "DELIMITER ;\n\n");
589
  }
590
  }
591
-
592
  $views = $wpdb->get_col("SHOW FULL TABLES WHERE Table_Type = 'VIEW'");
593
- if(count($views)){
594
- foreach ($views as $view){
595
  $create = $wpdb->get_row("SHOW CREATE VIEW `{$view}`", ARRAY_N);
596
  @fwrite($handle, "{$create[1]};\n\n");
597
  }
598
  }
599
-
600
- $table_count = count($tables);
601
  $table_number = 0;
602
-
603
  //BUILD INSERTS:
604
  //Create Insert in 100 row increments to better handle memory
605
  foreach ($tables as $table) {
606
-
607
  $table_number++;
608
- if($table_number % 2 == 0) {
609
  $this->Package->Status = DupLiteSnapLibUtil::getWorkPercent(DUP_PackageStatus::DBSTART, DUP_PackageStatus::DBDONE, $table_count, $table_number);
610
  $this->Package->update();
611
  }
612
-
613
- $row_count = $wpdb->get_var("SELECT Count(*) FROM `{$table}`");
614
  $rewrite_table_as = $this->rewriteTableNameAs($table);
 
615
  $this->Package->Database->info->tableWiseRowCounts[$rewrite_table_as] = $row_count;
616
-
617
  if ($row_count > $qryLimit) {
618
  $row_count = ceil($row_count / $qryLimit);
619
  } else if ($row_count > 0) {
620
  $row_count = 1;
621
  }
622
-
623
  if ($row_count >= 1) {
624
  fwrite($handle, "\n/* INSERT TABLE DATA: {$table} */\n");
625
  }
626
-
627
  for ($i = 0; $i < $row_count; $i++) {
628
  $sql = "";
629
  $limit = $i * $qryLimit;
@@ -631,30 +652,28 @@ class DUP_Database
631
  $rows = $wpdb->get_results($query, ARRAY_A);
632
 
633
  $select_last_error = $wpdb->last_error;
634
- if ('' !== $select_last_error) {
635
- $fix = esc_html__('Please contact your DataBase administrator to fix the error.', 'duplicator');
636
- $errorMessage = $select_last_error.' '.$fix.'.';
637
  $package->BuildProgress->set_failed($errorMessage);
638
  $package->BuildProgress->failed = true;
639
- $package->failed = true;
640
- $package->Status = DUP_PackageStatus::ERROR;
641
- $package->Update();
642
- DUP_Log::error($select_last_error, $fix, Dup_ErrorBehavior::Quit);
643
  return;
644
  }
645
 
646
  if (is_array($rows)) {
647
  foreach ($rows as $row) {
648
- $sql .= "INSERT INTO `{$rewrite_table_as}` VALUES(";
649
  $num_values = count($row);
650
  $num_counter = 1;
651
  foreach ($row as $value) {
652
  if (is_null($value) || !isset($value)) {
653
  ($num_values == $num_counter) ? $sql .= 'NULL' : $sql .= 'NULL, ';
654
  } else {
655
- ($num_values == $num_counter)
656
- ? $sql .= '"' . DUP_DB::escSQL($value, true) . '"'
657
- : $sql .= '"' . DUP_DB::escSQL($value, true) . '", ';
658
  }
659
  $num_counter++;
660
  }
@@ -663,7 +682,7 @@ class DUP_Database
663
  fwrite($handle, $sql);
664
  }
665
  }
666
-
667
  //Flush buffer if enabled
668
  if ($this->networkFlush) {
669
  DUP_Util::fcgiFlush();
@@ -671,7 +690,7 @@ class DUP_Database
671
  $sql = null;
672
  $rows = null;
673
  }
674
-
675
  $sql_footer = "\nSET FOREIGN_KEY_CHECKS = 1; \n\n";
676
  $sql_footer .= "/* Duplicator WordPress Timestamp: ".date("Y-m-d H:i:s")."*/\n";
677
  $sql_footer .= "/* ".DUPLICATOR_DB_EOF_MARKER." */\n";
@@ -681,12 +700,12 @@ class DUP_Database
681
  }
682
 
683
  private function rewriteTableNameAs($table)
684
- {
685
  $table_prefix = $this->getTablePrefix();
686
  if (!isset($this->sameNameTableExists)) {
687
  global $wpdb;
688
  $this->sameNameTableExists = false;
689
- $all_tables = $wpdb->get_col("SHOW FULL TABLES WHERE Table_Type != 'VIEW'");
690
  foreach ($all_tables as $table_name) {
691
  if (strtolower($table_name) != $table_name && in_array(strtolower($table_name), $all_tables)) {
692
  $this->sameNameTableExists = true;
@@ -695,15 +714,16 @@ class DUP_Database
695
  }
696
  }
697
  if (false === $this->sameNameTableExists && 0 === stripos($table, $table_prefix) && 0 !== strpos($table, $table_prefix)) {
698
- $post_fix = substr($table, strlen($table_prefix));
699
  $rewrite_table_name = $table_prefix.$post_fix;
700
  } else {
701
  $rewrite_table_name = $table;
702
  }
703
  return $rewrite_table_name;
704
  }
705
-
706
- private function getTablePrefix() {
 
707
  global $wpdb;
708
  $table_prefix = (is_multisite() && !defined('MULTISITE')) ? $wpdb->base_prefix : $wpdb->get_blog_prefix(0);
709
  return $table_prefix;
1
  <?php
2
  defined('ABSPATH') || defined('DUPXABSPATH') || exit;
3
  // Exit if accessed directly
4
+ if (!defined('DUPLICATOR_VERSION'))
5
+ exit;
6
 
7
  /**
8
  * Class for gathering system information about a database
13
  */
14
  class DUP_DatabaseInfo
15
  {
16
+
17
  /**
18
  * The SQL file was built with mysqldump or PHP
19
  */
100
  //CONSTRUCTOR
101
  function __construct()
102
  {
103
+ $this->collationList = array();
104
  $this->tableWiseRowCounts = array();
105
  }
106
  }
107
 
108
  class DUP_Database
109
  {
110
+
111
  //PUBLIC
112
  public $Type = 'MySQL';
113
  public $Size;
118
  public $Name;
119
  public $Compatible;
120
  public $Comments;
121
+
122
  /**
123
  *
124
  * @var DUP_DatabaseInfo
136
  */
137
  function __construct($package)
138
  {
139
+ $this->Package = $package;
140
+ $this->EOFMarker = "";
141
+ $package_zip_flush = DUP_Settings::Get('package_zip_flush');
142
+ $this->networkFlush = empty($package_zip_flush) ? false : $package_zip_flush;
143
+ $this->info = new DUP_DatabaseInfo();
144
+ $this->info->varLowerCaseTables = DUP_Util::isWindows() ? 1 : 0;
145
  }
146
 
147
  /**
151
  *
152
  * @return null
153
  */
154
+ public function build($package, $errorBehavior = Dup_ErrorBehavior::ThrowException)
155
  {
156
  try {
157
 
158
  $this->Package = $package;
159
+ do_action('duplicator_lite_build_database_before_start', $package);
160
 
161
  $time_start = DUP_Util::getMicrotime();
162
  $this->Package->setStatus(DUP_PackageStatus::DBSTART);
167
 
168
  $mysqlDumpPath = DUP_DB::getMySqlDumpPath();
169
  $mode = DUP_DB::getBuildMode();
170
+ $reserved_db_filepath = duplicator_get_abs_path().'/database.sql';
171
 
172
  $log = "\n********************************************************************************\n";
173
  $log .= "DATABASE:\n";
180
  DUP_Log::Info($log);
181
  $log = null;
182
 
183
+ do_action('duplicator_lite_build_database_start', $package);
184
 
185
  switch ($mode) {
186
  case 'MYSQLDUMP':
200
  DUP_Log::Info("SQL FILE SIZE: ".DUP_Util::byteSize($sql_file_size)." ({$sql_file_size})");
201
 
202
  if ($sql_file_size < 1350) {
203
+ $error_message = "SQL file size too low.";
204
  $package->BuildProgress->set_failed($error_message);
205
  $package->Status = DUP_PackageStatus::ERROR;
206
  $package->Update();
207
  DUP_Log::Error($error_message, "File does not look complete. Check permission on file and parent directory at [{$this->dbStorePath}]", $errorBehavior);
208
+ do_action('duplicator_lite_build_database_fail', $package);
 
209
  } else {
210
+ do_action('duplicator_lite_build_database_completed', $package);
211
  }
212
 
213
  DUP_Log::Info("SQL FILE TIME: ".date("Y-m-d H:i:s"));
214
  DUP_Log::Info("SQL RUNTIME: {$time_sum}");
215
 
216
  $this->Size = @filesize($this->dbStorePath);
217
+
218
  $this->Package->setStatus(DUP_PackageStatus::DBDONE);
219
+ }
220
+ catch (Exception $e) {
221
+ do_action('duplicator_lite_build_database_fail', $package);
222
  DUP_Log::Error("Runtime error in DUP_Database::Build", "Exception: {$e}", $errorBehavior);
223
  }
224
  }
233
  global $wpdb;
234
 
235
  $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : array();
236
+ $tblBaseCount = 0;
237
  $tblCount = 0;
238
 
239
  $tables = $wpdb->get_results("SHOW TABLE STATUS", ARRAY_A);
268
  $size = ($table["Data_length"] + $table["Index_length"]);
269
  $rows = empty($table["Rows"]) ? '0' : $table["Rows"];
270
 
271
+ $info['Size'] += $size;
272
+ $info['Rows'] += ($table["Rows"]);
273
  $info['TableList'][$name]['Case'] = preg_match('/[A-Z]/', $name) ? 1 : 0;
274
  $info['TableList'][$name]['Rows'] = number_format($rows);
275
  $info['TableList'][$name]['Size'] = DUP_Util::byteSize($size);
276
+ $info['TableList'][$name]['USize'] = $size;
277
  $tblCount++;
278
 
279
  //Table Uppercase
313
  $info['TableCount'] = $tblCount;
314
 
315
  $this->setInfoObj();
316
+ $this->info->isTablesUpperCase = $tblCaseFound;
317
+ $this->info->tablesBaseCount = $tblBaseCount;
318
+ $this->info->tablesFinalCount = $tblCount;
319
+ $this->info->tablesRowCount = $info['Rows'];
320
+ $this->info->tablesSizeOnDisk = $info['Size'];
321
 
322
  return $info;
323
  }
324
 
325
+ public function setInfoObj()
326
+ {
327
  global $wpdb;
328
  $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : array();
329
 
330
+ $this->info->buildMode = DUP_DB::getBuildMode();
331
+ $this->info->version = DUP_DB::getVersion();
332
+ $this->info->versionComment = DUP_DB::getVariable('version_comment');
333
+ $this->info->varLowerCaseTables = DUP_DB::getVariable('lower_case_table_names');
334
+ $this->info->name = $wpdb->dbname;
335
+ $this->info->isNameUpperCase = preg_match('/[A-Z]/', $wpdb->dbname) ? 1 : 0;
336
+ $this->info->collationList = DUP_DB::getTableCollationList($filterTables);
337
  }
338
 
339
  /**
342
  * @param object $package The reference to the current package being built *
343
  * @return void
344
  */
345
+ public function validateTableWiseRowCounts()
346
+ {
347
  foreach ($this->Package->Database->info->tableWiseRowCounts as $rewriteTableAs => $rowCount) {
348
  $newRowCount = $GLOBALS['wpdb']->get_var("SELECT Count(*) FROM `{$rewriteTableAs}`");
349
  if ($rowCount != $newRowCount) {
387
  }
388
 
389
  //Filter tables
390
+ $res = $wpdb->get_results('SHOW FULL TABLES', ARRAY_N);
391
+ $tables = array();
392
  $baseTables = array();
393
  foreach ($res as $row) {
394
  if (DUP_Util::isTableExists($row[0])) {
403
 
404
  foreach ($tables as $table) {
405
  if (in_array($table, $baseTables)) {
406
+ $row_count = $GLOBALS['wpdb']->get_var("SELECT Count(*) FROM `{$table}`");
407
+ $rewrite_table_as = $this->rewriteTableNameAs($table);
408
  $this->Package->Database->info->tableWiseRowCounts[$rewrite_table_as] = $row_count;
409
  }
410
  }
426
  $cmd .= ' -h '.escapeshellarg($host);
427
  $cmd .= (!empty($port) && is_numeric($port) ) ?
428
  ' -P '.$port : '';
429
+
430
  $isPopenEnabled = DUP_Shell_U::isPopenEnabled();
431
 
432
  if (!$isPopenEnabled) {
435
 
436
  $cmd .= ' '.escapeshellarg(DB_NAME);
437
  $cmd .= ' 2>&1';
438
+
439
  if ($isPopenEnabled) {
440
  $needToRewrite = false;
441
+ foreach ($tables as $tableName) {
442
+ $rewriteTableAs = $this->rewriteTableNameAs($tableName);
443
  if ($tableName != $rewriteTableAs) {
444
  $needToRewrite = true;
445
  break;
448
 
449
  if ($needToRewrite) {
450
  $findReplaceTableNames = array(); // orignal table name => rewrite table name
451
+
452
+ foreach ($tables as $tableName) {
453
+ $rewriteTableAs = $this->rewriteTableNameAs($tableName);
454
+ if ($tableName != $rewriteTableAs) {
455
  $findReplaceTableNames[$tableName] = $rewriteTableAs;
456
  }
457
  }
459
 
460
  $firstLine = '';
461
  DUP_LOG::trace("Executing mysql dump command by popen: $cmd");
462
+ $handle = popen($cmd, "r");
463
  if ($handle) {
464
+ $sql_header = "/* DUPLICATOR-LITE (MYSQL-DUMP BUILD MODE) MYSQL SCRIPT CREATED ON : ".@date("Y-m-d H:i:s")." */\n\n";
465
  file_put_contents($this->dbStorePath, $sql_header, FILE_APPEND);
466
  while (!feof($handle)) {
467
  $line = fgets($handle); //get ony one line
468
  if ($line) {
469
  if (empty($firstLine)) {
470
  $firstLine = $line;
471
+ if (false !== stripos($line, 'Using a password on the command line interface can be insecure'))
472
+ continue;
473
  }
474
 
475
  if ($needToRewrite) {
479
  $tableName = $matches[1];
480
  if (isset($findReplaceTableNames[$tableName])) {
481
  $rewriteTableAs = $findReplaceTableNames[$tableName];
482
+ $line = str_replace('CREATE TABLE `'.$tableName.'`', 'CREATE TABLE `'.$rewriteTableAs.'`', $line, $replaceCount);
483
  }
484
  } elseif (preg_match('/INSERT INTO `(.*?)`/', $line, $matches)) {
485
  $tableName = $matches[1];
486
  if (isset($findReplaceTableNames[$tableName])) {
487
  $rewriteTableAs = $findReplaceTableNames[$tableName];
488
+ $line = str_replace('INSERT INTO `'.$tableName.'`', 'INSERT INTO `'.$rewriteTableAs.'`', $line, $replaceCount);
489
  }
490
  } elseif (preg_match('/LOCK TABLES `(.*?)`/', $line, $matches)) {
491
  $tableName = $matches[1];
492
  if (isset($findReplaceTableNames[$tableName])) {
493
  $rewriteTableAs = $findReplaceTableNames[$tableName];
494
+ $line = str_replace('LOCK TABLES `'.$tableName.'`', 'LOCK TABLES `'.$rewriteTableAs.'`', $line, $replaceCount);
495
  }
496
  }
497
  }
500
  $output = "Ran from {$exePath}";
501
  }
502
  }
503
+ $mysqlResult = pclose($handle);
504
  } else {
505
  $output = '';
506
  }
507
+
508
  // Password bug > 5.6 (@see http://bugs.mysql.com/bug.php?id=66546)
509
  if (empty($output) && trim($firstLine) === 'Warning: Using a password on the command line interface can be insecure.') {
510
  $output = '';
511
  }
512
  } else {
513
  DUP_LOG::trace("Executing mysql dump command $cmd");
514
+ exec($cmd, $output, $mysqlResult);
515
+ $output = implode("\n", $output);
516
 
517
  // Password bug > 5.6 (@see http://bugs.mysql.com/bug.php?id=66546)
518
  if (trim($output) === 'Warning: Using a password on the command line interface can be insecure.') {
533
  $sql_footer = "\n\n/* Duplicator WordPress Timestamp: ".date("Y-m-d H:i:s")."*/\n";
534
  $sql_footer .= "/* ".DUPLICATOR_DB_EOF_MARKER." */\n";
535
  file_put_contents($this->dbStorePath, $sql_footer, FILE_APPEND);
536
+ if ($mysqlResult !== 0) {
537
+ /**
538
+ * -1 error command shell
539
+ * mysqldump return
540
+ * 0 - Success
541
+ * 1 - Warning
542
+ * 2 - Exception
543
+ */
544
+ DUP_Log::Info('MYSQL DUMP ERROR '.print_r($mysqlResult, true));
545
+ DUP_Log::error(__('Shell mysql dump error', 'duplicator'), __('change Mysql dump engine in PHP mode', 'duplicator'), Dup_ErrorBehavior::ThrowException);
546
+ return false;
547
+ }
548
+
549
+ return true;
550
  }
551
 
552
  /**
557
  private function phpDump($package)
558
  {
559
  global $wpdb;
560
+
561
  $wpdb->query("SET session wait_timeout = ".DUPLICATOR_DB_MAX_TIME);
562
  if (($handle = fopen($this->dbStorePath, 'w+')) == false) {
563
+ DUP_Log::error('[PHP DUMP] ERROR Can\'t open sbStorePath "'.$this->dbStorePath.'"', Dup_ErrorBehavior::ThrowException);
564
  }
565
+ $tables = $wpdb->get_col("SHOW FULL TABLES WHERE Table_Type != 'VIEW'");
566
+
567
  $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : null;
568
  $tblAllCount = count($tables);
569
  //$tblFilterOn = ($this->FilterOn) ? 'ON' : 'OFF';
570
  $qryLimit = DUP_Settings::Get('package_phpdump_qrylimit');
571
+
572
  if (is_array($filterTables) && $this->FilterOn) {
573
  foreach ($tables as $key => $val) {
574
  if (in_array($tables[$key], $filterTables)) {
578
  }
579
  $tblCreateCount = count($tables);
580
  $tblFilterCount = $tblAllCount - $tblCreateCount;
581
+
582
  DUP_Log::Info("TABLES: total:{$tblAllCount} | filtered:{$tblFilterCount} | create:{$tblCreateCount}");
583
  DUP_Log::Info("FILTERED: [{$this->FilterTables}]");
584
+
585
  //Added 'NO_AUTO_VALUE_ON_ZERO' at plugin version 1.2.12 to fix :
586
  //**ERROR** database error write 'Invalid default value for for older mysql versions
587
+ $sql_header = "/* DUPLICATOR-LITE (PHP BUILD MODE) MYSQL SCRIPT CREATED ON : ".@date("Y-m-d H:i:s")." */\n\n";
588
  $sql_header .= "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;\n\n";
589
  $sql_header .= "SET FOREIGN_KEY_CHECKS = 0;\n\n";
590
  fwrite($handle, $sql_header);
591
+
592
  //BUILD CREATES:
593
  //All creates must be created before inserts do to foreign key constraints
594
  foreach ($tables as $table) {
595
+ $rewrite_table_as = $this->rewriteTableNameAs($table);
596
+ $create = $wpdb->get_row("SHOW CREATE TABLE `{$table}`", ARRAY_N);
597
+ $count = 1;
598
  $create_table_query = str_replace($table, $rewrite_table_as, $create[1], $count);
599
  @fwrite($handle, "{$create_table_query};\n\n");
600
  }
601
+
602
+ $procedures = $wpdb->get_col("SHOW PROCEDURE STATUS WHERE `Db` = '{$wpdb->dbname}'", 1);
603
+ if (count($procedures)) {
604
+ foreach ($procedures as $procedure) {
605
  @fwrite($handle, "DELIMITER ;;\n");
606
  $create = $wpdb->get_row("SHOW CREATE PROCEDURE `{$procedure}`", ARRAY_N);
607
  @fwrite($handle, "{$create[2]} ;;\n");
608
  @fwrite($handle, "DELIMITER ;\n\n");
609
  }
610
  }
611
+
612
  $views = $wpdb->get_col("SHOW FULL TABLES WHERE Table_Type = 'VIEW'");
613
+ if (count($views)) {
614
+ foreach ($views as $view) {
615
  $create = $wpdb->get_row("SHOW CREATE VIEW `{$view}`", ARRAY_N);
616
  @fwrite($handle, "{$create[1]};\n\n");
617
  }
618
  }
619
+
620
+ $table_count = count($tables);
621
  $table_number = 0;
622
+
623
  //BUILD INSERTS:
624
  //Create Insert in 100 row increments to better handle memory
625
  foreach ($tables as $table) {
626
+
627
  $table_number++;
628
+ if ($table_number % 2 == 0) {
629
  $this->Package->Status = DupLiteSnapLibUtil::getWorkPercent(DUP_PackageStatus::DBSTART, DUP_PackageStatus::DBDONE, $table_count, $table_number);
630
  $this->Package->update();
631
  }
632
+
633
+ $row_count = $wpdb->get_var("SELECT Count(*) FROM `{$table}`");
634
  $rewrite_table_as = $this->rewriteTableNameAs($table);
635
+
636
  $this->Package->Database->info->tableWiseRowCounts[$rewrite_table_as] = $row_count;
637
+
638
  if ($row_count > $qryLimit) {
639
  $row_count = ceil($row_count / $qryLimit);
640
  } else if ($row_count > 0) {
641
  $row_count = 1;
642
  }
643
+
644
  if ($row_count >= 1) {
645
  fwrite($handle, "\n/* INSERT TABLE DATA: {$table} */\n");
646
  }
647
+
648
  for ($i = 0; $i < $row_count; $i++) {
649
  $sql = "";
650
  $limit = $i * $qryLimit;
652
  $rows = $wpdb->get_results($query, ARRAY_A);
653
 
654
  $select_last_error = $wpdb->last_error;
655
+ if ('' !== $select_last_error) {
656
+ $fix = esc_html__('Please contact your DataBase administrator to fix the error.', 'duplicator');
657
+ $errorMessage = $select_last_error.' '.$fix.'.';
658
  $package->BuildProgress->set_failed($errorMessage);
659
  $package->BuildProgress->failed = true;
660
+ $package->failed = true;
661
+ $package->Status = DUP_PackageStatus::ERROR;
662
+ $package->Update();
663
+ DUP_Log::error($select_last_error, $fix, Dup_ErrorBehavior::ThrowException);
664
  return;
665
  }
666
 
667
  if (is_array($rows)) {
668
  foreach ($rows as $row) {
669
+ $sql .= "INSERT INTO `{$rewrite_table_as}` VALUES(";
670
  $num_values = count($row);
671
  $num_counter = 1;
672
  foreach ($row as $value) {
673
  if (is_null($value) || !isset($value)) {
674
  ($num_values == $num_counter) ? $sql .= 'NULL' : $sql .= 'NULL, ';
675
  } else {
676
+ ($num_values == $num_counter) ? $sql .= '"'.DUP_DB::escSQL($value, true).'"' : $sql .= '"'.DUP_DB::escSQL($value, true).'", ';
 
 
677
  }
678
  $num_counter++;
679
  }
682
  fwrite($handle, $sql);
683
  }
684
  }
685
+
686
  //Flush buffer if enabled
687
  if ($this->networkFlush) {
688
  DUP_Util::fcgiFlush();
690
  $sql = null;
691
  $rows = null;
692
  }
693
+
694
  $sql_footer = "\nSET FOREIGN_KEY_CHECKS = 1; \n\n";
695
  $sql_footer .= "/* Duplicator WordPress Timestamp: ".date("Y-m-d H:i:s")."*/\n";
696
  $sql_footer .= "/* ".DUPLICATOR_DB_EOF_MARKER." */\n";
700
  }
701
 
702
  private function rewriteTableNameAs($table)
703
+ {
704
  $table_prefix = $this->getTablePrefix();
705
  if (!isset($this->sameNameTableExists)) {
706
  global $wpdb;
707
  $this->sameNameTableExists = false;
708
+ $all_tables = $wpdb->get_col("SHOW FULL TABLES WHERE Table_Type != 'VIEW'");
709
  foreach ($all_tables as $table_name) {
710
  if (strtolower($table_name) != $table_name && in_array(strtolower($table_name), $all_tables)) {
711
  $this->sameNameTableExists = true;
714
  }
715
  }
716
  if (false === $this->sameNameTableExists && 0 === stripos($table, $table_prefix) && 0 !== strpos($table, $table_prefix)) {
717
+ $post_fix = substr($table, strlen($table_prefix));
718
  $rewrite_table_name = $table_prefix.$post_fix;
719
  } else {
720
  $rewrite_table_name = $table;
721
  }
722
  return $rewrite_table_name;
723
  }
724
+
725
+ private function getTablePrefix()
726
+ {
727
  global $wpdb;
728
  $table_prefix = (is_multisite() && !defined('MULTISITE')) ? $wpdb->base_prefix : $wpdb->get_blog_prefix(0);
729
  return $table_prefix;
classes/package/class.pack.installer.php CHANGED
@@ -145,9 +145,11 @@ class DUP_Installer
145
  $ac->package_notes = $this->Package->Notes;
146
  $ac->url_old = get_option('siteurl');
147
  $ac->opts_delete = DupLiteSnapJsonU::wp_json_encode_pprint($GLOBALS['DUPLICATOR_OPTS_DELETE']);
148
- $ac->blogname = esc_html(get_option('blogname'));
149
- $ac->wproot = DUPLICATOR_WPROOTPATH;
150
- $ac->relative_content_dir = str_replace(ABSPATH, '', WP_CONTENT_DIR);
 
 
151
  $ac->exportOnlyDB = $this->Package->Archive->ExportOnlyDB;
152
  $ac->installSiteOverwriteOn = DUPLICATOR_INSTALL_SITE_OVERWRITE_ON;
153
  $ac->wplogin_url = wp_login_url();
@@ -163,7 +165,7 @@ class DUP_Installer
163
  $ac->wp_tableprefix = $wpdb->base_prefix;
164
 
165
  $ac->mu_mode = DUP_MU::getMode();
166
- $ac->is_outer_root_wp_config_file = (!file_exists(DUPLICATOR_WPROOTPATH.'wp-config.php')) ? true : false;
167
  $ac->is_outer_root_wp_content_dir = $this->Package->Archive->isOuterWPContentDir();
168
 
169
  $json = DupLiteSnapJsonU::wp_json_encode_pprint($ac);
@@ -245,8 +247,8 @@ class DUP_Installer
245
 
246
  try {
247
  DUP_Log::Info("add_extra_files_using_da1");
248
- $htaccess_filepath = DUPLICATOR_WPROOTPATH.'.htaccess';
249
- $webconf_filepath = DUPLICATOR_WPROOTPATH.'web.config';
250
 
251
  $logger = new DUP_DupArchive_Logger();
252
 
@@ -257,8 +259,9 @@ class DUP_Installer
257
  $this->numFilesAdded++;
258
 
259
  if (file_exists($htaccess_filepath)) {
 
260
  try {
261
- DupArchiveEngine::addRelativeFileToArchiveST($archive_filepath, $htaccess_filepath, DUPLICATOR_HTACCESS_ORIG_FILENAME);
262
  $this->numFilesAdded++;
263
  } catch (Exception $ex) {
264
  // Non critical so bury exception
@@ -345,8 +348,8 @@ class DUP_Installer
345
 
346
  private function add_extra_files_using_ziparchive($installer_filepath, $scan_filepath, $sql_filepath, $zip_filepath, $archive_config_filepath, $wpconfig_filepath)
347
  {
348
- $htaccess_filepath = DUPLICATOR_WPROOTPATH.'.htaccess';
349
- $webconfig_filepath = DUPLICATOR_WPROOTPATH.'web.config';
350
 
351
  $success = false;
352
  $zipArchive = new ZipArchive();
@@ -355,7 +358,8 @@ class DUP_Installer
355
  DUP_Log::Info("Successfully opened zip $zip_filepath");
356
 
357
  if (file_exists($htaccess_filepath)) {
358
- DUP_Zip_U::addFileToZipArchive($zipArchive, $htaccess_filepath, DUPLICATOR_HTACCESS_ORIG_FILENAME, true);
 
359
  }
360
 
361
  if (file_exists($webconfig_filepath)) {
@@ -439,6 +443,27 @@ class DUP_Installer
439
  return $success;
440
  }
441
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
442
  /**
443
  * Get wp-config.php file path along with name in archive file
444
  */
145
  $ac->package_notes = $this->Package->Notes;
146
  $ac->url_old = get_option('siteurl');
147
  $ac->opts_delete = DupLiteSnapJsonU::wp_json_encode_pprint($GLOBALS['DUPLICATOR_OPTS_DELETE']);
148
+ $ac->blogname = esc_html(get_option('blogname'));
149
+
150
+ $abs_path = duplicator_get_abs_path();
151
+ $ac->wproot = $abs_path;
152
+ $ac->relative_content_dir = str_replace($abs_path, '', WP_CONTENT_DIR);
153
  $ac->exportOnlyDB = $this->Package->Archive->ExportOnlyDB;
154
  $ac->installSiteOverwriteOn = DUPLICATOR_INSTALL_SITE_OVERWRITE_ON;
155
  $ac->wplogin_url = wp_login_url();
165
  $ac->wp_tableprefix = $wpdb->base_prefix;
166
 
167
  $ac->mu_mode = DUP_MU::getMode();
168
+ $ac->is_outer_root_wp_config_file = (!file_exists($abs_path . '/wp-config.php')) ? true : false;
169
  $ac->is_outer_root_wp_content_dir = $this->Package->Archive->isOuterWPContentDir();
170
 
171
  $json = DupLiteSnapJsonU::wp_json_encode_pprint($ac);
247
 
248
  try {
249
  DUP_Log::Info("add_extra_files_using_da1");
250
+ $htaccess_filepath = $this->getHtaccessFilePath();
251
+ $webconf_filepath = duplicator_get_abs_path() . '/web.config';
252
 
253
  $logger = new DUP_DupArchive_Logger();
254
 
259
  $this->numFilesAdded++;
260
 
261
  if (file_exists($htaccess_filepath)) {
262
+ $htaccess_ark_file_path = $this->getHtaccessArkFilePath();
263
  try {
264
+ DupArchiveEngine::addRelativeFileToArchiveST($archive_filepath, $htaccess_filepath, $htaccess_ark_file_path);
265
  $this->numFilesAdded++;
266
  } catch (Exception $ex) {
267
  // Non critical so bury exception
348
 
349
  private function add_extra_files_using_ziparchive($installer_filepath, $scan_filepath, $sql_filepath, $zip_filepath, $archive_config_filepath, $wpconfig_filepath)
350
  {
351
+ $htaccess_filepath = $this->getHtaccessFilePath();
352
+ $webconfig_filepath = duplicator_get_abs_path() . '/web.config';
353
 
354
  $success = false;
355
  $zipArchive = new ZipArchive();
358
  DUP_Log::Info("Successfully opened zip $zip_filepath");
359
 
360
  if (file_exists($htaccess_filepath)) {
361
+ $htaccess_ark_file_path = $this->getHtaccessArkFilePath();
362
+ DUP_Zip_U::addFileToZipArchive($zipArchive, $htaccess_filepath, $htaccess_ark_file_path, true);
363
  }
364
 
365
  if (file_exists($webconfig_filepath)) {
443
  return $success;
444
  }
445
 
446
+ /**
447
+ * Get .htaccess file path
448
+ *
449
+ * @return string
450
+ */
451
+ private function getHtaccessFilePath() {
452
+ return duplicator_get_abs_path().'/.htaccess';
453
+ }
454
+
455
+ /**
456
+ * Get .htaccss in archive file
457
+ *
458
+ * @return string
459
+ */
460
+ private function getHtaccessArkFilePath()
461
+ {
462
+ $packageHash = $this->Package->getPackageHash();
463
+ $htaccessArkFilePath = '.htaccess__'.$packageHash;
464
+ return $htaccessArkFilePath;
465
+ }
466
+
467
  /**
468
  * Get wp-config.php file path along with name in archive file
469
  */
classes/package/class.pack.php CHANGED
@@ -1230,7 +1230,7 @@ class DUP_Package
1230
  //START BUILD
1231
  //PHPs serialze method will return the object, but the ID above is not passed
1232
  //for one reason or another so passing the object back in seems to do the trick
1233
- $this->Database->build($this);
1234
  $this->Database->validateTableWiseRowCounts();
1235
  $this->Archive->build($this);
1236
  $this->Installer->build($this);
@@ -1244,23 +1244,6 @@ class DUP_Package
1244
  $zipSizeRead = DUP_Util::byteSize($this->Archive->Size);
1245
  $exeSizeRead = DUP_Util::byteSize($this->Installer->Size);
1246
 
1247
- /*
1248
- DUP_Log::Info("SQL File: {$dbSizeRead}");
1249
- DUP_Log::Info("Installer File: {$exeSizeRead}");
1250
- DUP_Log::Info("Archive File: {$zipSizeRead} ");
1251
-
1252
- if (!($this->Archive->Size && $this->Database->Size && $this->Installer->Size)) {
1253
- DUP_Log::Error("A required file contains zero bytes.", "Archive Size: {$zipSizeRead} | SQL Size: {$dbSizeRead} | Installer Size: {$exeSizeRead}");
1254
- }
1255
-
1256
- //Validate SQL files completed
1257
- $sql_tmp_path = DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP.'/'.$this->Database->File);
1258
- $sql_complete_txt = DUP_Util::tailFile($sql_tmp_path, 3);
1259
- if (!strstr($sql_complete_txt, 'DUPLICATOR_MYSQLDUMP_EOF')) {
1260
- DUP_Log::Error("ERROR: SQL file not complete. The end of file marker was not found. Please try to re-create the package.");
1261
- }*/
1262
-
1263
-
1264
  $timerEnd = DUP_Util::getMicrotime();
1265
  $timerSum = DUP_Util::elapsedTime($timerEnd, $timerStart);
1266
 
@@ -1359,7 +1342,7 @@ class DUP_Package
1359
 
1360
  $this->Notes = sanitize_textarea_field($post['package-notes']);
1361
  //ARCHIVE
1362
- $this->Archive->PackDir = rtrim(DUPLICATOR_WPROOTPATH, '/');
1363
  $this->Archive->Format = 'ZIP';
1364
  $this->Archive->FilterOn = isset($post['filter-on']) ? 1 : 0;
1365
  $this->Archive->ExportOnlyDB = isset($post['export-onlydb']) ? 1 : 0;
1230
  //START BUILD
1231
  //PHPs serialze method will return the object, but the ID above is not passed
1232
  //for one reason or another so passing the object back in seems to do the trick
1233
+ $this->Database->build($this, Dup_ErrorBehavior::ThrowException);
1234
  $this->Database->validateTableWiseRowCounts();
1235
  $this->Archive->build($this);
1236
  $this->Installer->build($this);
1244
  $zipSizeRead = DUP_Util::byteSize($this->Archive->Size);
1245
  $exeSizeRead = DUP_Util::byteSize($this->Installer->Size);
1246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1247
  $timerEnd = DUP_Util::getMicrotime();
1248
  $timerSum = DUP_Util::elapsedTime($timerEnd, $timerStart);
1249
 
1342
 
1343
  $this->Notes = sanitize_textarea_field($post['package-notes']);
1344
  //ARCHIVE
1345
+ $this->Archive->PackDir = duplicator_get_abs_path();
1346
  $this->Archive->Format = 'ZIP';
1347
  $this->Archive->FilterOn = isset($post['filter-on']) ? 1 : 0;
1348
  $this->Archive->ExportOnlyDB = isset($post['export-onlydb']) ? 1 : 0;
classes/ui/class.ui.notice.php CHANGED
@@ -130,4 +130,55 @@ class DUP_UI_Notice
130
  }
131
  }
132
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  }
130
  }
131
  }
132
  }
133
+
134
+ /**
135
+ * Shows feedback notices after certain no. of packages successfully created
136
+ */
137
+ public static function showFeedBackNotice() {
138
+ $notice_id = 'rate_us_feedback';
139
+
140
+ if (!current_user_can('manage_options')) {
141
+ return;
142
+ }
143
+
144
+ $notices = get_user_meta(get_current_user_id(), DUPLICATOR_ADMIN_NOTICES_USER_META_KEY, true);
145
+
146
+ $duplicator_pages = array(
147
+ 'toplevel_page_duplicator',
148
+ 'duplicator_page_duplicator-tools',
149
+ 'duplicator_page_duplicator-settings',
150
+ 'duplicator_page_duplicator-gopro',
151
+ );
152
+
153
+ if (!in_array(get_current_screen()->id, $duplicator_pages) || (isset($notices[$notice_id]) && 'true' === $notices[$notice_id])) {
154
+ return;
155
+ }
156
+
157
+ $packagesCount = $GLOBALS['wpdb']->get_var('SELECT count(id) FROM '.DUP_Util::getTablePrefix().'duplicator_packages WHERE status=100');
158
+
159
+ if ($packagesCount < DUPLICATOR_FEEDBACK_NOTICE_SHOW_AFTER_NO_PACKAGE) {
160
+ return;
161
+ }
162
+
163
+ $dismiss_url = add_query_arg(array(
164
+ 'action' => 'duplicator_set_admin_notice_viewed',
165
+ 'notice_id' => esc_attr($notice_id),
166
+ ), admin_url('admin-post.php'));
167
+ ?>
168
+ <div class="notice updated duplicator-message duplicator-message-dismissed" data-notice_id="<?php echo esc_attr( $notice_id); ?>">
169
+ <div class="duplicator-message-inner">
170
+ <div class="duplicator-message-icon">
171
+ <img src="<?php echo esc_url(DUPLICATOR_PLUGIN_URL."assets/img/logo.png"); ?>" style="text-align:top; margin:0; height:60px; width:60px;" alt="Duplicator">
172
+ </div>
173
+ <div class="duplicator-message-content">
174
+ <p><strong><?php echo __( 'Congrats!', 'duplicator' ); ?></strong> <?php printf(esc_html__('You created over %d packages with Duplicator. Great job! If you can spare a minute, please help us by leaving a five star review on WordPress.org.', 'duplicator'), DUPLICATOR_FEEDBACK_NOTICE_SHOW_AFTER_NO_PACKAGE); ?></p>
175
+ <p class="duplicator-message-actions">
176
+ <a href="https://wordpress.org/support/plugin/duplicator/reviews/?filter=5/#new-post" target="_blank" class="button button-primary duplicator-notice-rate-now"><?php esc_html_e("Sure! I'd love to help", 'duplicator' ); ?></a>
177
+ <a href="<?php echo esc_url_raw($dismiss_url); ?>" class="button duplicator-notice-dismiss"><?php esc_html_e('Hide Notification', 'duplicator'); ?></a>
178
+ </p>
179
+ </div>
180
+ </div>
181
+ </div>
182
+ <?php
183
+ }
184
  }
classes/utilities/class.u.php CHANGED
@@ -413,7 +413,7 @@ class DUP_Util
413
  */
414
  public static function hasShellExec()
415
  {
416
- $cmds = array('shell_exec', 'escapeshellarg', 'escapeshellcmd', 'extension_loaded');
417
 
418
  //Function disabled at server level
419
  if (array_intersect($cmds, array_map('trim', explode(',', @ini_get('disable_functions'))))) return false;
@@ -556,7 +556,7 @@ class DUP_Util
556
  */
557
  public static function initSnapshotDirectory()
558
  {
559
- $path_wproot = DUP_Util::safePath(DUPLICATOR_WPROOTPATH);
560
  $path_ssdir = DUP_Util::safePath(DUPLICATOR_SSDIR_PATH);
561
  $path_plugin = DUP_Util::safePath(DUPLICATOR_PLUGIN_PATH);
562
 
413
  */
414
  public static function hasShellExec()
415
  {
416
+ $cmds = array('shell_exec', 'escapeshellarg', 'escapeshellcmd', 'extension_loaded', 'exec');
417
 
418
  //Function disabled at server level
419
  if (array_intersect($cmds, array_map('trim', explode(',', @ini_get('disable_functions'))))) return false;
556
  */
557
  public static function initSnapshotDirectory()
558
  {
559
+ $path_wproot = duplicator_get_abs_path();
560
  $path_ssdir = DUP_Util::safePath(DUPLICATOR_SSDIR_PATH);
561
  $path_plugin = DUP_Util::safePath(DUPLICATOR_PLUGIN_PATH);
562
 
ctrls/class.web.services.php CHANGED
@@ -10,6 +10,8 @@ class DUP_Web_Services
10
  public static function init()
11
  {
12
  add_action('wp_ajax_duplicator_reset_all_settings', array(__CLASS__, 'ajax_reset_all'));
 
 
13
  }
14
 
15
  /**
@@ -79,4 +81,41 @@ class DUP_Web_Services
79
  wp_send_json_success($result);
80
  }
81
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  }
10
  public static function init()
11
  {
12
  add_action('wp_ajax_duplicator_reset_all_settings', array(__CLASS__, 'ajax_reset_all'));
13
+ add_action('wp_ajax_duplicator_download', array(__CLASS__, 'duplicator_download'));
14
+ add_action('wp_ajax_nopriv_duplicator_download', array(__CLASS__, 'duplicator_download'));
15
  }
16
 
17
  /**
81
  wp_send_json_success($result);
82
  }
83
  }
84
+
85
+ public static function duplicator_download() {
86
+ $file = sanitize_text_field($_GET['file']);
87
+ $filepath = DUPLICATOR_SSDIR_PATH.'/'.$file;
88
+ // Process download
89
+ if(file_exists($filepath)) {
90
+ // Clean output buffer
91
+ if (ob_get_level() !== 0 && @ob_end_clean() === FALSE) {
92
+ @ob_clean();
93
+ }
94
+
95
+ header('Content-Description: File Transfer');
96
+ header('Content-Type: application/octet-stream');
97
+ header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
98
+ header('Expires: 0');
99
+ header('Cache-Control: must-revalidate');
100
+ header('Pragma: public');
101
+ header('Content-Length: ' . filesize($filepath));
102
+ flush(); // Flush system output buffer
103
+
104
+ try {
105
+ $fp = @fopen($filepath, 'r');
106
+ if (false === $fp) {
107
+ throw new Exception('Fail to open the file '.$filepath);
108
+ }
109
+ while (!feof($fp) && ($data = fread($fp, DUPLICATOR_BUFFER_READ_WRITE_SIZE)) !== FALSE) {
110
+ echo $data;
111
+ }
112
+ @fclose($fp);
113
+ } catch (Exception $e) {
114
+ readfile($filepath);
115
+ }
116
+ exit;
117
+ } else {
118
+ wp_die('Invalid installer file name!!');
119
+ }
120
+ }
121
  }
ctrls/ctrl.package.php CHANGED
@@ -1,7 +1,8 @@
1
  <?php
2
  defined('ABSPATH') || defined('DUPXABSPATH') || exit;
3
  // Exit if accessed directly
4
- if (! defined('DUPLICATOR_VERSION')) exit;
 
5
 
6
  require_once(DUPLICATOR_PLUGIN_PATH.'/ctrls/ctrl.base.php');
7
  require_once(DUPLICATOR_PLUGIN_PATH.'/classes/utilities/class.u.scancheck.php');
@@ -17,7 +18,8 @@ require_once(DUPLICATOR_PLUGIN_PATH.'/classes/package/duparchive/class.pack.arch
17
  *
18
  * @return void
19
  */
20
- function duplicator_package_scan_shutdown() {
 
21
  $logMessage = DUP_Handler::getVarLog();
22
  if (!empty($logMessage)) {
23
  echo nl2br($logMessage);
@@ -74,35 +76,53 @@ function duplicator_package_build()
74
 
75
  header('Content-Type: application/json');
76
 
77
- @set_time_limit(0);
78
- $errLevel = error_reporting();
79
- error_reporting(E_ERROR);
80
- DUP_Util::initSnapshotDirectory();
81
 
82
- $Package = DUP_Package::getActive();
83
- $Package->save('zip');
 
 
 
84
 
85
- DUP_Settings::Set('active_package_id', $Package->ID);
86
- DUP_Settings::Save();
87
 
88
- if (!is_readable(DUPLICATOR_SSDIR_PATH_TMP."/{$Package->ScanFile}")) {
89
- die("The scan result file was not found. Please run the scan step before building the package.");
90
- }
91
 
92
- $Package->runZipBuild();
 
 
93
 
94
- //JSON:Debug Response
95
- //Pass = 1, Warn = 2, Fail = 3
96
- $json = array();
97
- $json['status'] = 1;
98
- $json['package'] = $Package;
99
- $json['runtime'] = $Package->Runtime;
100
- $json['exeSize'] = $Package->ExeSize;
101
- $json['archiveSize'] = $Package->ZipSize;
102
- $json_response = DupLiteSnapJsonU::wp_json_encode($json);
103
-
104
- //Simulate a Host Build Interrupt
105
- //die(0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
  error_reporting($errLevel);
108
  die($json_response);
@@ -117,7 +137,7 @@ function duplicator_duparchive_package_build()
117
  {
118
  DUP_Handler::init_error_handler();
119
  DUP_Log::Info('[CTRL DUP ARCIVE] CALL TO '.__FUNCTION__);
120
-
121
  check_ajax_referer('duplicator_duparchive_package_build', 'nonce');
122
  DUP_Util::hasCapability('export');
123
  header('Content-Type: application/json');
@@ -157,14 +177,14 @@ function duplicator_duparchive_package_build()
157
  die("There is no active package.");
158
  }
159
 
160
- if($package->Status == DUP_PackageStatus::ERROR) {
161
  $package->setStatus(DUP_PackageStatus::ERROR);
162
  $hasCompleted = true;
163
  } else {
164
  try {
165
  $hasCompleted = $package->runDupArchiveBuild();
166
  }
167
- catch(Exception $ex) {
168
  DUP_Log::Info('[CTRL DUP ARCIVE] ERROR: caught exception');
169
  Dup_Log::Error('[CTRL DUP ARCIVE] Caught exception', $ex->getMessage(), Dup_ErrorBehavior::LogOnly);
170
  DUP_Log::Info('[CTRL DUP ARCIVE] ERROR: after log');
@@ -173,7 +193,7 @@ function duplicator_duparchive_package_build()
173
  }
174
  }
175
 
176
- $json = array();
177
  $json['failures'] = array_merge($package->BuildProgress->build_failures, $package->BuildProgress->validation_failures);
178
  if (!empty($json['failures'])) {
179
  DUP_Log::Info('[CTRL DUP ARCIVE] FAILURES', $json['failures']);
@@ -184,11 +204,11 @@ function duplicator_duparchive_package_build()
184
  if ($hasCompleted) {
185
  DUP_Log::Info('[CTRL DUP ARCIVE] COMPLETED PACKAGE STATUS: '.$package->Status);
186
 
187
- if($package->Status == DUP_PackageStatus::ERROR) {
188
  DUP_Log::Info('[CTRL DUP ARCIVE] ERROR');
189
- $error_message = __('Error building DupArchive package') . '<br/>';
190
 
191
- foreach($json['failures'] as $failure) {
192
  $error_message .= implode(',', $failure->description);
193
  }
194
 
@@ -198,7 +218,7 @@ function duplicator_duparchive_package_build()
198
  $json['status'] = 3;
199
  } else {
200
  Dup_Log::Info("sending back success status");
201
- $json['status'] = 1;
202
  }
203
 
204
  Dup_Log::Trace('#### json package');
@@ -230,27 +250,27 @@ function duplicator_package_delete()
230
  {
231
  DUP_Handler::init_error_handler();
232
  check_ajax_referer('duplicator_package_delete', 'nonce');
233
- DUP_Util::hasCapability('export');
234
-
235
- function _unlinkFile($file) {
236
- if (! file_exists($file)) {
237
- return;
238
- }
239
- if (! @unlink($file)) {
240
- @chmod($file, 0644);
241
- @unlink($file);
242
- }
243
- }
244
 
 
 
 
 
 
 
 
 
 
 
245
  try {
246
  global $wpdb;
247
- $json = array();
248
- $post = stripslashes_deep($_POST);
249
  $tablePrefix = DUP_Util::getTablePrefix();
250
- $tblName = $tablePrefix.'duplicator_packages';
251
- $postIDs = isset($post['duplicator_delid']) ? sanitize_text_field($post['duplicator_delid']) : null;
252
- $list = explode(",", $postIDs);
253
- $delCount = 0;
254
 
255
  if ($postIDs != null) {
256
 
@@ -275,20 +295,20 @@ function duplicator_package_delete()
275
  _unlinkFile($globSnapshotFile);
276
  }
277
  // _unlinkFile(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH."/{$nameHash}.log"));
278
-
279
  //Unfinished Zip files
280
  /*
281
- $tmpZip = DUPLICATOR_SSDIR_PATH_TMP."/{$nameHash}_archive.zip.*";
282
- if ($tmpZip !== false) {
283
- array_map('unlink', glob($tmpZip));
284
- }
285
- */
286
  $delCount++;
287
  }
288
  }
289
  }
290
  }
291
- } catch (Exception $e) {
 
292
  $json['error'] = "{$e}";
293
  die(DupLiteSnapJsonU::wp_json_encode($json));
294
  }
@@ -314,7 +334,7 @@ function duplicator_active_package_info()
314
  DUP_Util::hasCapability('export', DUP_Util::SECURE_ISSUE_THROW);
315
 
316
  if (!check_ajax_referer('duplicator_active_package_info', 'nonce', false)) {
317
- throw new Exception(__('An unathorized security request was made to this page. Please try again!','duplicator'));
318
  }
319
 
320
  global $wpdb;
@@ -323,26 +343,27 @@ function duplicator_active_package_info()
323
  $result = array(
324
  'active_package' => array(
325
  'present' => false,
326
- 'status' => 0,
327
- 'size' => 0
328
  ),
329
- 'html' => '',
330
- 'message' => ''
331
  );
332
 
333
  $result['active_package']['present'] = DUP_Package::is_active_package_present();
334
 
335
  if ($result['active_package']['present']) {
336
- $id = DUP_Settings::Get('active_package_id');
337
  $package = DUP_Package::getByID($id);
338
  if (is_null($package)) {
339
- throw new Exception(__('Active package object error','duplicator'));
340
  }
341
- $result['active_package']['status'] = $package->Status;
342
- $result['active_package']['size'] = $package->getArchiveSize();
343
  $result['active_package']['size_format'] = DUP_Util::byteSize($package->getArchiveSize());
344
  }
345
- } catch (Exception $e) {
 
346
  $error = true;
347
  $result['message'] = $e->getMessage();
348
  }
@@ -393,21 +414,17 @@ class DUP_CTRL_Package extends DUP_CTRL_Base
393
  $package = DUP_Package::getActive();
394
 
395
  //DIRS
396
- $dir_filters = ($package->Archive->FilterOn)
397
- ? $package->Archive->FilterDirs.';'.sanitize_text_field($post['dir_paths'])
398
- : sanitize_text_field($post['dir_paths']);
399
  $dir_filters = $package->Archive->parseDirectoryFilter($dir_filters);
400
  $changed = $package->Archive->saveActiveItem($package, 'FilterDirs', $dir_filters);
401
 
402
  //FILES
403
- $file_filters = ($package->Archive->FilterOn)
404
- ? $package->Archive->FilterFiles.';'.sanitize_text_field($post['file_paths'])
405
- : sanitize_text_field($post['file_paths']);
406
  $file_filters = $package->Archive->parseFileFilter($file_filters);
407
  $changed = $package->Archive->saveActiveItem($package, 'FilterFiles', $file_filters);
408
 
409
  if (!$package->Archive->FilterOn && !empty($package->Archive->FilterExts)) {
410
- $changed = $package->Archive->saveActiveItem($package, 'FilterExts', '');
411
  }
412
 
413
  $changed = $package->Archive->saveActiveItem($package, 'FilterOn', 1);
@@ -422,7 +439,8 @@ class DUP_CTRL_Package extends DUP_CTRL_Base
422
  //RETURN RESULT
423
  $test = ($changed) ? DUP_CTRL_Status::SUCCESS : DUP_CTRL_Status::FAILED;
424
  $result->process($payload, $test);
425
- } catch (Exception $exc) {
 
426
  $result->processError($exc);
427
  }
428
  }
@@ -439,7 +457,7 @@ class DUP_CTRL_Package extends DUP_CTRL_Base
439
  {
440
  DUP_Handler::init_error_handler();
441
 
442
- check_ajax_referer('DUP_CTRL_Package_getPackageFile', 'nonce' );
443
  DUP_Util::hasCapability('export');
444
  $params = $this->postParamMerge($post);
445
 
@@ -459,8 +477,8 @@ class DUP_CTRL_Package extends DUP_CTRL_Base
459
  if ($isBinary) {
460
  @session_write_close();
461
  // @ob_flush();
462
- //flush seems to cause issues on some PHP version where the download prompt
463
- //is no longer called but the contents of the installer are dumped to the browser.
464
  //@flush();
465
 
466
  header("Pragma: public");
@@ -479,18 +497,18 @@ class DUP_CTRL_Package extends DUP_CTRL_Base
479
  $fileName = basename($filePath);
480
  }
481
 
482
- header("Content-Type: application/octet-stream");
483
- header("Content-Disposition: attachment; filename=\"{$fileName}\";");
484
 
485
  DUP_LOG::trace("streaming $filePath");
486
 
487
- while(!feof($fp)) {
488
- $buffer = fread($fp, 2048);
489
- print $buffer;
490
- }
491
 
492
  fclose($fp);
493
- exit;
494
  } else {
495
  header("Content-Type: text/plain");
496
  header("Content-Disposition: attachment; filename=\"error.txt\";");
@@ -521,7 +539,8 @@ class DUP_CTRL_Package extends DUP_CTRL_Base
521
  echo esc_html($message);
522
  }
523
  }
524
- } catch (Exception $exc) {
 
525
  $result->processError($exc);
526
  }
527
  }
@@ -529,43 +548,40 @@ class DUP_CTRL_Package extends DUP_CTRL_Base
529
  /**
530
  * Get active package status
531
  *
532
- * <code>
533
- * //JavaScript Ajax Request
534
- * Duplicator.Package.getActivePackageStatus()
535
- * </code>
536
  */
537
- public function getActivePackageStatus($post)
538
- {
539
  DUP_Handler::init_error_handler();
540
-
541
  check_ajax_referer('DUP_CTRL_Package_getActivePackageStatus', 'nonce');
542
  DUP_Util::hasCapability('export');
543
 
544
- $post = $this->postParamMerge($post);
545
- $result = new DUP_CTRL_Result($this);
546
 
547
- try
548
- {
549
- //CONTROLLER LOGIC
550
- $post = stripslashes_deep($_POST);
551
  $active_package_id = DUP_Settings::Get('active_package_id');
552
- $package = DUP_Package::getByID($active_package_id);
553
- $payload = array();
554
 
555
- if($package != null) {
556
- $test = DUP_CTRL_Status::SUCCESS;
557
- $payload['status'] = $package->Status;
558
  } else {
559
  $test = DUP_CTRL_Status::FAILED;
560
  }
561
 
562
- //RETURN RESULT
563
- return $result->process($payload, $test);
564
- }
565
- catch (Exception $exc)
566
- {
567
- $result->processError($exc);
568
- }
569
  }
570
-
571
- }
1
  <?php
2
  defined('ABSPATH') || defined('DUPXABSPATH') || exit;
3
  // Exit if accessed directly
4
+ if (!defined('DUPLICATOR_VERSION'))
5
+ exit;
6
 
7
  require_once(DUPLICATOR_PLUGIN_PATH.'/ctrls/ctrl.base.php');
8
  require_once(DUPLICATOR_PLUGIN_PATH.'/classes/utilities/class.u.scancheck.php');
18
  *
19
  * @return void
20
  */
21
+ function duplicator_package_scan_shutdown()
22
+ {
23
  $logMessage = DUP_Handler::getVarLog();
24
  if (!empty($logMessage)) {
25
  echo nl2br($logMessage);
76
 
77
  header('Content-Type: application/json');
78
 
79
+ $Package = null;
 
 
 
80
 
81
+ try {
82
+ @set_time_limit(0);
83
+ $errLevel = error_reporting();
84
+ error_reporting(E_ERROR);
85
+ DUP_Util::initSnapshotDirectory();
86
 
87
+ $Package = DUP_Package::getActive();
88
+ $Package->save('zip');
89
 
90
+ DUP_Settings::Set('active_package_id', $Package->ID);
91
+ DUP_Settings::Save();
 
92
 
93
+ if (!is_readable(DUPLICATOR_SSDIR_PATH_TMP."/{$Package->ScanFile}")) {
94
+ die("The scan result file was not found. Please run the scan step before building the package.");
95
+ }
96
 
97
+ $Package->runZipBuild();
98
+
99
+ //JSON:Debug Response
100
+ //Pass = 1, Warn = 2, Fail = 3
101
+ $json = array();
102
+ $json['status'] = 1;
103
+ $json['error'] = '';
104
+ $json['package'] = $Package;
105
+ $json['runtime'] = $Package->Runtime;
106
+ $json['exeSize'] = $Package->ExeSize;
107
+ $json['archiveSize'] = $Package->ZipSize;
108
+
109
+ //Simulate a Host Build Interrupt
110
+ //die(0);
111
+ }
112
+ catch (Exception $e) {
113
+ $Package->setStatus(DUP_PackageStatus::ERROR);
114
+
115
+ //JSON:Debug Response
116
+ //Pass = 1, Warn = 2, Fail = 3
117
+ $json = array();
118
+ $json['status'] = 3;
119
+ $json['error'] = $e->getMessage();
120
+ $json['package'] = $Package;
121
+ $json['runtime'] = null;
122
+ $json['exeSize'] = null;
123
+ $json['archiveSize'] = null;
124
+ }
125
+ $json_response = DupLiteSnapJsonU::wp_json_encode($json);
126
 
127
  error_reporting($errLevel);
128
  die($json_response);
137
  {
138
  DUP_Handler::init_error_handler();
139
  DUP_Log::Info('[CTRL DUP ARCIVE] CALL TO '.__FUNCTION__);
140
+
141
  check_ajax_referer('duplicator_duparchive_package_build', 'nonce');
142
  DUP_Util::hasCapability('export');
143
  header('Content-Type: application/json');
177
  die("There is no active package.");
178
  }
179
 
180
+ if ($package->Status == DUP_PackageStatus::ERROR) {
181
  $package->setStatus(DUP_PackageStatus::ERROR);
182
  $hasCompleted = true;
183
  } else {
184
  try {
185
  $hasCompleted = $package->runDupArchiveBuild();
186
  }
187
+ catch (Exception $ex) {
188
  DUP_Log::Info('[CTRL DUP ARCIVE] ERROR: caught exception');
189
  Dup_Log::Error('[CTRL DUP ARCIVE] Caught exception', $ex->getMessage(), Dup_ErrorBehavior::LogOnly);
190
  DUP_Log::Info('[CTRL DUP ARCIVE] ERROR: after log');
193
  }
194
  }
195
 
196
+ $json = array();
197
  $json['failures'] = array_merge($package->BuildProgress->build_failures, $package->BuildProgress->validation_failures);
198
  if (!empty($json['failures'])) {
199
  DUP_Log::Info('[CTRL DUP ARCIVE] FAILURES', $json['failures']);
204
  if ($hasCompleted) {
205
  DUP_Log::Info('[CTRL DUP ARCIVE] COMPLETED PACKAGE STATUS: '.$package->Status);
206
 
207
+ if ($package->Status == DUP_PackageStatus::ERROR) {
208
  DUP_Log::Info('[CTRL DUP ARCIVE] ERROR');
209
+ $error_message = __('Error building DupArchive package').'<br/>';
210
 
211
+ foreach ($json['failures'] as $failure) {
212
  $error_message .= implode(',', $failure->description);
213
  }
214
 
218
  $json['status'] = 3;
219
  } else {
220
  Dup_Log::Info("sending back success status");
221
+ $json['status'] = 1;
222
  }
223
 
224
  Dup_Log::Trace('#### json package');
250
  {
251
  DUP_Handler::init_error_handler();
252
  check_ajax_referer('duplicator_package_delete', 'nonce');
253
+ DUP_Util::hasCapability('export');
 
 
 
 
 
 
 
 
 
 
254
 
255
+ function _unlinkFile($file)
256
+ {
257
+ if (!file_exists($file)) {
258
+ return;
259
+ }
260
+ if (!@unlink($file)) {
261
+ @chmod($file, 0644);
262
+ @unlink($file);
263
+ }
264
+ }
265
  try {
266
  global $wpdb;
267
+ $json = array();
268
+ $post = stripslashes_deep($_POST);
269
  $tablePrefix = DUP_Util::getTablePrefix();
270
+ $tblName = $tablePrefix.'duplicator_packages';
271
+ $postIDs = isset($post['duplicator_delid']) ? sanitize_text_field($post['duplicator_delid']) : null;
272
+ $list = explode(",", $postIDs);
273
+ $delCount = 0;
274
 
275
  if ($postIDs != null) {
276
 
295
  _unlinkFile($globSnapshotFile);
296
  }
297
  // _unlinkFile(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH."/{$nameHash}.log"));
 
298
  //Unfinished Zip files
299
  /*
300
+ $tmpZip = DUPLICATOR_SSDIR_PATH_TMP."/{$nameHash}_archive.zip.*";
301
+ if ($tmpZip !== false) {
302
+ array_map('unlink', glob($tmpZip));
303
+ }
304
+ */
305
  $delCount++;
306
  }
307
  }
308
  }
309
  }
310
+ }
311
+ catch (Exception $e) {
312
  $json['error'] = "{$e}";
313
  die(DupLiteSnapJsonU::wp_json_encode($json));
314
  }
334
  DUP_Util::hasCapability('export', DUP_Util::SECURE_ISSUE_THROW);
335
 
336
  if (!check_ajax_referer('duplicator_active_package_info', 'nonce', false)) {
337
+ throw new Exception(__('An unathorized security request was made to this page. Please try again!', 'duplicator'));
338
  }
339
 
340
  global $wpdb;
343
  $result = array(
344
  'active_package' => array(
345
  'present' => false,
346
+ 'status' => 0,
347
+ 'size' => 0
348
  ),
349
+ 'html' => '',
350
+ 'message' => ''
351
  );
352
 
353
  $result['active_package']['present'] = DUP_Package::is_active_package_present();
354
 
355
  if ($result['active_package']['present']) {
356
+ $id = DUP_Settings::Get('active_package_id');
357
  $package = DUP_Package::getByID($id);
358
  if (is_null($package)) {
359
+ throw new Exception(__('Active package object error', 'duplicator'));
360
  }
361
+ $result['active_package']['status'] = $package->Status;
362
+ $result['active_package']['size'] = $package->getArchiveSize();
363
  $result['active_package']['size_format'] = DUP_Util::byteSize($package->getArchiveSize());
364
  }
365
+ }
366
+ catch (Exception $e) {
367
  $error = true;
368
  $result['message'] = $e->getMessage();
369
  }
414
  $package = DUP_Package::getActive();
415
 
416
  //DIRS
417
+ $dir_filters = ($package->Archive->FilterOn) ? $package->Archive->FilterDirs.';'.sanitize_text_field($post['dir_paths']) : sanitize_text_field($post['dir_paths']);
 
 
418
  $dir_filters = $package->Archive->parseDirectoryFilter($dir_filters);
419
  $changed = $package->Archive->saveActiveItem($package, 'FilterDirs', $dir_filters);
420
 
421
  //FILES
422
+ $file_filters = ($package->Archive->FilterOn) ? $package->Archive->FilterFiles.';'.sanitize_text_field($post['file_paths']) : sanitize_text_field($post['file_paths']);
 
 
423
  $file_filters = $package->Archive->parseFileFilter($file_filters);
424
  $changed = $package->Archive->saveActiveItem($package, 'FilterFiles', $file_filters);
425
 
426
  if (!$package->Archive->FilterOn && !empty($package->Archive->FilterExts)) {
427
+ $changed = $package->Archive->saveActiveItem($package, 'FilterExts', '');
428
  }
429
 
430
  $changed = $package->Archive->saveActiveItem($package, 'FilterOn', 1);
439
  //RETURN RESULT
440
  $test = ($changed) ? DUP_CTRL_Status::SUCCESS : DUP_CTRL_Status::FAILED;
441
  $result->process($payload, $test);
442
+ }
443
+ catch (Exception $exc) {
444
  $result->processError($exc);
445
  }
446
  }
457
  {
458
  DUP_Handler::init_error_handler();
459
 
460
+ check_ajax_referer('DUP_CTRL_Package_getPackageFile', 'nonce');
461
  DUP_Util::hasCapability('export');
462
  $params = $this->postParamMerge($post);
463
 
477
  if ($isBinary) {
478
  @session_write_close();
479
  // @ob_flush();
480
+ //flush seems to cause issues on some PHP version where the download prompt
481
+ //is no longer called but the contents of the installer are dumped to the browser.
482
  //@flush();
483
 
484
  header("Pragma: public");
497
  $fileName = basename($filePath);
498
  }
499
 
500
+ header("Content-Type: application/octet-stream");
501
+ header("Content-Disposition: attachment; filename=\"{$fileName}\";");
502
 
503
  DUP_LOG::trace("streaming $filePath");
504
 
505
+ while (!feof($fp)) {
506
+ $buffer = fread($fp, 2048);
507
+ print $buffer;
508
+ }
509
 
510
  fclose($fp);
511
+ exit;
512
  } else {
513
  header("Content-Type: text/plain");
514
  header("Content-Disposition: attachment; filename=\"error.txt\";");
539
  echo esc_html($message);
540
  }
541
  }
542
+ }
543
+ catch (Exception $exc) {
544
  $result->processError($exc);
545
  }
546
  }
548
  /**
549
  * Get active package status
550
  *
551
+ * <code>
552
+ * //JavaScript Ajax Request
553
+ * Duplicator.Package.getActivePackageStatus()
554
+ * </code>
555
  */
556
+ public function getActivePackageStatus($post)
557
+ {
558
  DUP_Handler::init_error_handler();
559
+
560
  check_ajax_referer('DUP_CTRL_Package_getActivePackageStatus', 'nonce');
561
  DUP_Util::hasCapability('export');
562
 
563
+ $post = $this->postParamMerge($post);
564
+ $result = new DUP_CTRL_Result($this);
565
 
566
+ try {
567
+ //CONTROLLER LOGIC
568
+ $post = stripslashes_deep($_POST);
 
569
  $active_package_id = DUP_Settings::Get('active_package_id');
570
+ $package = DUP_Package::getByID($active_package_id);
571
+ $payload = array();
572
 
573
+ if ($package != null) {
574
+ $test = DUP_CTRL_Status::SUCCESS;
575
+ $payload['status'] = $package->Status;
576
  } else {
577
  $test = DUP_CTRL_Status::FAILED;
578
  }
579
 
580
+ //RETURN RESULT
581
+ return $result->process($payload, $test);
582
+ }
583
+ catch (Exception $exc) {
584
+ $result->processError($exc);
585
+ }
 
586
  }
587
+ }
 
ctrls/ctrl.tools.php CHANGED
@@ -24,7 +24,7 @@ class DUP_CTRL_Tools extends DUP_CTRL_Base
24
  /**
25
  * Calls the ScanValidator and returns a JSON result
26
  *
27
- * @param string $_POST['scan-path'] The path to start scanning from, defaults to DUPLICATOR_WPROOTPATH
28
  * @param bool $_POST['scan-recursive'] Recursivly search the path
29
  *
30
  * @notes: Testing = /wp-admin/admin-ajax.php?action=DUP_CTRL_Tools_runScanValidator
@@ -43,7 +43,7 @@ class DUP_CTRL_Tools extends DUP_CTRL_Base
43
  try
44
  {
45
  //CONTROLLER LOGIC
46
- $path = isset($post['scan-path']) ? sanitize_text_field($post['scan-path']) : DUPLICATOR_WPROOTPATH;
47
  if (!is_dir($path)) {
48
  throw new Exception("Invalid directory provided '{$path}'!");
49
  }
24
  /**
25
  * Calls the ScanValidator and returns a JSON result
26
  *
27
+ * @param string $_POST['scan-path'] The path to start scanning from, defaults to duplicator_get_abs_path()
28
  * @param bool $_POST['scan-recursive'] Recursivly search the path
29
  *
30
  * @notes: Testing = /wp-admin/admin-ajax.php?action=DUP_CTRL_Tools_runScanValidator
43
  try
44
  {
45
  //CONTROLLER LOGIC
46
+ $path = isset($post['scan-path']) ? sanitize_text_field($post['scan-path']) : duplicator_get_abs_path();
47
  if (!is_dir($path)) {
48
  throw new Exception("Invalid directory provided '{$path}'!");
49
  }
define.php CHANGED
@@ -4,8 +4,8 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
4
  //Prevent directly browsing to the file
5
  if (function_exists('plugin_dir_url'))
6
  {
7
- define('DUPLICATOR_VERSION', '1.3.24');
8
- define('DUPLICATOR_VERSION_BUILD', '2019-11-13_07:45');
9
  define('DUPLICATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
10
  define('DUPLICATOR_SITE_URL', get_site_url());
11
 
@@ -24,7 +24,7 @@ if (function_exists('plugin_dir_url'))
24
 
25
  define('DUPLICATOR_PLUGIN_PATH', str_replace("\\", "/", plugin_dir_path(__FILE__)));
26
  define('DUPLICATOR_SSDIR_NAME', 'wp-snapshots');
27
- define('DUPLICATOR_SSDIR_PATH', str_replace("\\", "/", DUPLICATOR_WPROOTPATH . DUPLICATOR_SSDIR_NAME));
28
  define('DUPLICATOR_SSDIR_PATH_TMP', DUPLICATOR_SSDIR_PATH . '/tmp');
29
  define("DUPLICATOR_SSDIR_PATH_INSTALLER", DUPLICATOR_SSDIR_PATH . '/installer');
30
  define('DUPLICATOR_SSDIR_URL', DUPLICATOR_SITE_URL . "/" . DUPLICATOR_SSDIR_NAME);
@@ -52,13 +52,14 @@ if (function_exists('plugin_dir_url'))
52
 
53
  define('DUPLICATOR_TEMP_CLEANUP_SECONDS', 900); // 15 min = How many seconds to keep temp files around when delete is requested
54
  define('DUPLICATOR_MAX_BUILD_RETRIES', 10); // Max times to try a part of progressive build work
55
- define('DUPLICATOR_HTACCESS_ORIG_FILENAME', 'htaccess.orig');
56
  define('DUPLICATOR_WEBCONFIG_ORIG_FILENAME', 'web.config.orig');
57
- define("DUPLICATOR_INSTALLER_DIRECTORY", DUPLICATOR_WPROOTPATH . 'dup-installer');
58
  define('DUPLICATOR_MAX_LOG_SIZE', 400000); // The higher this is the more overhead
59
  define('DUPLICATOR_ZIP_ARCHIVE_ADD_FROM_STR', false);
60
  define('DUPLICATOR_DEACTIVATION_FEEDBACK', false);
61
  define("DUPLICATOR_BUFFER_READ_WRITE_SIZE", 4377);
 
 
62
 
63
  $GLOBALS['DUPLICATOR_SERVER_LIST'] = array('Apache','LiteSpeed', 'Nginx', 'Lighttpd', 'IIS', 'WebServerX', 'uWSGI');
64
  $GLOBALS['DUPLICATOR_OPTS_DELETE'] = array('duplicator_ui_view_state', 'duplicator_package_active', 'duplicator_settings');
4
  //Prevent directly browsing to the file
5
  if (function_exists('plugin_dir_url'))
6
  {
7
+ define('DUPLICATOR_VERSION', '1.3.26');
8
+ define('DUPLICATOR_VERSION_BUILD', '2020-02-07_13:50');
9
  define('DUPLICATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
10
  define('DUPLICATOR_SITE_URL', get_site_url());
11
 
24
 
25
  define('DUPLICATOR_PLUGIN_PATH', str_replace("\\", "/", plugin_dir_path(__FILE__)));
26
  define('DUPLICATOR_SSDIR_NAME', 'wp-snapshots');
27
+ define('DUPLICATOR_SSDIR_PATH', duplicator_get_abs_path() . '/' . DUPLICATOR_SSDIR_NAME);
28
  define('DUPLICATOR_SSDIR_PATH_TMP', DUPLICATOR_SSDIR_PATH . '/tmp');
29
  define("DUPLICATOR_SSDIR_PATH_INSTALLER", DUPLICATOR_SSDIR_PATH . '/installer');
30
  define('DUPLICATOR_SSDIR_URL', DUPLICATOR_SITE_URL . "/" . DUPLICATOR_SSDIR_NAME);
52
 
53
  define('DUPLICATOR_TEMP_CLEANUP_SECONDS', 900); // 15 min = How many seconds to keep temp files around when delete is requested
54
  define('DUPLICATOR_MAX_BUILD_RETRIES', 10); // Max times to try a part of progressive build work
 
55
  define('DUPLICATOR_WEBCONFIG_ORIG_FILENAME', 'web.config.orig');
56
+ define("DUPLICATOR_INSTALLER_DIRECTORY", duplicator_get_abs_path() . '/dup-installer');
57
  define('DUPLICATOR_MAX_LOG_SIZE', 400000); // The higher this is the more overhead
58
  define('DUPLICATOR_ZIP_ARCHIVE_ADD_FROM_STR', false);
59
  define('DUPLICATOR_DEACTIVATION_FEEDBACK', false);
60
  define("DUPLICATOR_BUFFER_READ_WRITE_SIZE", 4377);
61
+ define("DUPLICATOR_ADMIN_NOTICES_USER_META_KEY", 'duplicator_admin_notices');
62
+ define("DUPLICATOR_FEEDBACK_NOTICE_SHOW_AFTER_NO_PACKAGE", 5);
63
 
64
  $GLOBALS['DUPLICATOR_SERVER_LIST'] = array('Apache','LiteSpeed', 'Nginx', 'Lighttpd', 'IIS', 'WebServerX', 'uWSGI');
65
  $GLOBALS['DUPLICATOR_OPTS_DELETE'] = array('duplicator_ui_view_state', 'duplicator_package_active', 'duplicator_settings');
duplicator.php CHANGED
@@ -3,13 +3,13 @@
3
  Plugin Name: Duplicator
4
  Plugin URI: https://snapcreek.com/duplicator/duplicator-free/
5
  Description: Migrate and backup a copy of your WordPress files and database. Duplicate and move a site from one location to another quickly.
6
- Version: 1.3.24
7
  Author: Snap Creek
8
  Author URI: http://www.snapcreek.com/duplicator/
9
  Text Domain: duplicator
10
  License: GPLv2 or later
11
 
12
- Copyright 2011-2017 SnapCreek LLC
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License, version 2, as
@@ -24,9 +24,6 @@
24
  along with this program; if not, write to the Free Software
25
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
 
27
- SOURCE CONTRIBUTORS:
28
- David Coveney of Interconnect IT Ltd
29
- https://github.com/interconnectit/Search-Replace-DB/
30
  ================================================================================ */
31
  defined('ABSPATH') || defined('DUPXABSPATH') || exit;
32
  if ( !defined('DUPXABSPATH') ) {
@@ -36,6 +33,7 @@ if ( !defined('DUPXABSPATH') ) {
36
  if (!defined('ABSPATH')) {
37
  exit; // Exit if accessed directly.
38
  }
 
39
  require_once("define.php");
40
 
41
  if (!function_exists('sanitize_textarea_field')) {
@@ -274,7 +272,8 @@ if (is_admin() == true)
274
  PRIMARY KEY (id),
275
  KEY hash (hash))";
276
 
277
- require_once(DUPLICATOR_WPROOTPATH . 'wp-admin/includes/upgrade.php');
 
278
  @dbDelta($sql);
279
 
280
  DupLiteSnapLibIOU::chmod(DUPLICATOR_SSDIR_PATH, 'u+rwx,go+rx');
@@ -331,6 +330,7 @@ if (is_admin() == true)
331
  add_action('admin_enqueue_scripts', 'duplicator_admin_enqueue_scripts' );
332
  add_action('admin_notices', array('DUP_UI_Notice', 'showReservedFilesNotice'));
333
  add_action('admin_notices', array('DUP_UI_Notice', 'installAutoDeactivatePlugins'));
 
334
 
335
  //CTRL ACTIONS
336
  DUP_Web_Services::init();
@@ -339,6 +339,7 @@ if (is_admin() == true)
339
  add_action('wp_ajax_duplicator_package_build', 'duplicator_package_build');
340
  add_action('wp_ajax_duplicator_package_delete', 'duplicator_package_delete');
341
  add_action('wp_ajax_duplicator_duparchive_package_build', 'duplicator_duparchive_package_build');
 
342
 
343
  $GLOBALS['CTRLS_DUP_CTRL_UI'] = new DUP_CTRL_UI();
344
  $GLOBALS['CTRLS_DUP_CTRL_Tools'] = new DUP_CTRL_Tools();
@@ -616,4 +617,27 @@ if (is_admin() == true)
616
  }
617
  }
618
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
619
  }
3
  Plugin Name: Duplicator
4
  Plugin URI: https://snapcreek.com/duplicator/duplicator-free/
5
  Description: Migrate and backup a copy of your WordPress files and database. Duplicate and move a site from one location to another quickly.
6
+ Version: 1.3.26
7
  Author: Snap Creek
8
  Author URI: http://www.snapcreek.com/duplicator/
9
  Text Domain: duplicator
10
  License: GPLv2 or later
11
 
12
+ Copyright 2011-2020 SnapCreek LLC
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License, version 2, as
24
  along with this program; if not, write to the Free Software
25
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
 
 
 
 
27
  ================================================================================ */
28
  defined('ABSPATH') || defined('DUPXABSPATH') || exit;
29
  if ( !defined('DUPXABSPATH') ) {
33
  if (!defined('ABSPATH')) {
34
  exit; // Exit if accessed directly.
35
  }
36
+ require_once("helper.php");
37
  require_once("define.php");
38
 
39
  if (!function_exists('sanitize_textarea_field')) {
272
  PRIMARY KEY (id),
273
  KEY hash (hash))";
274
 
275
+ $abs_path = duplicator_get_abs_path();
276
+ require_once($abs_path . '/wp-admin/includes/upgrade.php');
277
  @dbDelta($sql);
278
 
279
  DupLiteSnapLibIOU::chmod(DUPLICATOR_SSDIR_PATH, 'u+rwx,go+rx');
330
  add_action('admin_enqueue_scripts', 'duplicator_admin_enqueue_scripts' );
331
  add_action('admin_notices', array('DUP_UI_Notice', 'showReservedFilesNotice'));
332
  add_action('admin_notices', array('DUP_UI_Notice', 'installAutoDeactivatePlugins'));
333
+ add_action('admin_notices', array('DUP_UI_Notice', 'showFeedBackNotice'));
334
 
335
  //CTRL ACTIONS
336
  DUP_Web_Services::init();
339
  add_action('wp_ajax_duplicator_package_build', 'duplicator_package_build');
340
  add_action('wp_ajax_duplicator_package_delete', 'duplicator_package_delete');
341
  add_action('wp_ajax_duplicator_duparchive_package_build', 'duplicator_duparchive_package_build');
342
+ add_action('wp_ajax_duplicator_set_admin_notice_viewed', 'duplicator_set_admin_notice_viewed');
343
 
344
  $GLOBALS['CTRLS_DUP_CTRL_UI'] = new DUP_CTRL_UI();
345
  $GLOBALS['CTRLS_DUP_CTRL_Tools'] = new DUP_CTRL_Tools();
617
  }
618
  }
619
  }
620
+
621
+ if (!function_exists('duplicator_set_admin_notice_viewed')) {
622
+ function duplicator_set_admin_notice_viewed() {
623
+ if ( empty( $_REQUEST['notice_id'] ) ) {
624
+ wp_die();
625
+ }
626
+
627
+ $notices = get_user_meta(get_current_user_id(), DUPLICATOR_ADMIN_NOTICES_USER_META_KEY, true);
628
+ if ( empty( $notices ) ) {
629
+ $notices = array();
630
+ }
631
+
632
+ $notices[ $_REQUEST['notice_id'] ] = 'true';
633
+ update_user_meta( get_current_user_id(), DUPLICATOR_ADMIN_NOTICES_USER_META_KEY, $notices);
634
+
635
+ if ( ! wp_doing_ajax() ) {
636
+ wp_safe_redirect( admin_url() );
637
+ die;
638
+ }
639
+
640
+ wp_die();
641
+ }
642
+ }
643
  }
helper.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined('ABSPATH') || exit;
3
+
4
+ if (!function_exists('duplicator_cloned_get_home_path')) {
5
+ /**
6
+ * Cloned function of the get_home_path(). It is same code except two lines of code
7
+ * Get the absolute filesystem path to the root of the WordPress installation
8
+ *
9
+ * @return string Full filesystem path to the root of the WordPress installation
10
+ */
11
+ function duplicator_cloned_get_home_path()
12
+ {
13
+ $home = set_url_scheme(get_option('home'), 'http');
14
+ $siteurl = set_url_scheme(get_option('siteurl'), 'http');
15
+
16
+ // below two lines
17
+ // extra added by snapcreek
18
+ // when home is www. path and siteurl is non-www , the duplicator_get_home_psth() was returning empty value
19
+ $home = str_ireplace('://www.', '://', $home);
20
+ $siteurl = str_ireplace('://www.', '://', $siteurl);
21
+
22
+ if (!empty($home) && 0 !== strcasecmp($home, $siteurl) && $home !== $siteurl) {
23
+ $wp_path_rel_to_home = str_ireplace($home, '', $siteurl); /* $siteurl - $home */
24
+ $pos = strripos(str_replace('\\', '/', $_SERVER['SCRIPT_FILENAME']), trailingslashit($wp_path_rel_to_home));
25
+ $home_path = substr($_SERVER['SCRIPT_FILENAME'], 0, $pos);
26
+ $home_path = trailingslashit($home_path);
27
+ } else {
28
+ $home_path = ABSPATH;
29
+ }
30
+ return str_replace('\\', '/', $home_path);
31
+ }
32
+ }
33
+
34
+ if (!function_exists('duplicator_get_home_path')) {
35
+ function duplicator_get_home_path() {
36
+ static $homePath = null;
37
+ if (is_null($homePath)) {
38
+ if (!function_exists('get_home_path')) {
39
+ require_once(ABSPATH.'wp-admin/includes/file.php');
40
+ }
41
+ $homePath = wp_normalize_path(duplicator_cloned_get_home_path());
42
+ if ($homePath == '//' || $homePath == '') {
43
+ $homePath = '/';
44
+ } else {
45
+ $homePath = rtrim($homePath, '/');
46
+ }
47
+ }
48
+ return $homePath;
49
+ }
50
+ }
51
+
52
+ if (!function_exists('duplicator_get_abs_path')) {
53
+ function duplicator_get_abs_path() {
54
+ static $absPath = null;
55
+ if (is_null($absPath)) {
56
+ $absPath = wp_normalize_path(ABSPATH);
57
+ if ($absPath == '//' || $absPath == '') {
58
+ $absPath = '/';
59
+ } else {
60
+ $absPath = rtrim($absPath, '/');
61
+ }
62
+ }
63
+ return $absPath;
64
+ }
65
+ }
installer/dup-installer/classes/class.http.php CHANGED
@@ -18,7 +18,7 @@ class DUPX_HTTP
18
  $html = "<form id='".DUPX_U::esc_attr($id)."' method='post' action='".DUPX_U::esc_url($url)."'>\n";
19
  foreach ($data as $name => $value)
20
  {
21
- $html .= "<input type='hidden' name='".DUPX_U::esc_attr($name)."' value='".DUPX_U::esc_attr($value)."' />\n";
22
  }
23
  $html .= "</form>\n";
24
  $html .= "<script>$(document).ready(function() { $('#{$id}').submit(); });</script>";
18
  $html = "<form id='".DUPX_U::esc_attr($id)."' method='post' action='".DUPX_U::esc_url($url)."'>\n";
19
  foreach ($data as $name => $value)
20
  {
21
+ $html .= "<input type='hidden' name='".DUPX_U::esc_attr($name)."' value='".DUPX_U::esc_attr($value)."' autocomplete=\"off\" />\n";
22
  }
23
  $html .= "</form>\n";
24
  $html .= "<script>$(document).ready(function() { $('#{$id}').submit(); });</script>";
installer/dup-installer/classes/class.package.php CHANGED
@@ -38,7 +38,7 @@ final class DUPX_Package
38
  {
39
  static $path = null;
40
  if (is_null($path)) {
41
- $path = $GLOBALS['DUPX_ROOT'].'/htaccess.orig';
42
  }
43
  return $path;
44
  }
38
  {
39
  static $path = null;
40
  if (is_null($path)) {
41
+ $path = $GLOBALS['DUPX_ROOT'].'/.htaccess__'.$GLOBALS['DUPX_AC']->package_hash;
42
  }
43
  return $path;
44
  }
installer/dup-installer/classes/config/class.conf.srv.php CHANGED
@@ -44,7 +44,7 @@ class DUPX_ServerConfig
44
  self::$timeStamp = date("Y-m-d H:i:s");
45
  self::$rootPath = "{$GLOBALS['DUPX_ROOT']}";
46
  self::$confFileApache = "{$GLOBALS['DUPX_ROOT']}/.htaccess";
47
- self::$confFileApacheOrig = "{$GLOBALS['DUPX_ROOT']}/htaccess.orig";
48
  self::$confFileIIS = "{$GLOBALS['DUPX_ROOT']}/web.config";
49
  self::$confFileIISOrig = "{$GLOBALS['DUPX_ROOT']}/web.config.orig";
50
  self::$confFileWordFence = "{$GLOBALS['DUPX_ROOT']}/.user.ini";
@@ -96,7 +96,7 @@ class DUPX_ServerConfig
96
  }
97
 
98
  /**
99
- * Copies the code in htaccess.orig and web.config.orig
100
  * to .htaccess and web.config
101
  *
102
  * @return void
@@ -105,16 +105,16 @@ class DUPX_ServerConfig
105
  {
106
  //APACHE
107
  if(rename(self::$confFileApacheOrig, self::$confFileApache)){
108
- DUPX_Log::info("\n- PASS: The orginal htaccess.orig was renamed");
109
  } else {
110
- DUPX_Log::info("\n- WARN: The orginal htaccess.orig was NOT renamed");
111
  }
112
 
113
  //IIS
114
  if(rename(self::$confFileIISOrig, self::$confFileIIS)){
115
- DUPX_Log::info("\n- PASS: The orginal htaccess.orig was renamed");
116
  } else {
117
- DUPX_Log::info("\n- WARN: The orginal htaccess.orig was NOT renamed");
118
  }
119
  }
120
 
@@ -162,7 +162,7 @@ class DUPX_ServerConfig
162
  $newdata = parse_url(self::$newSiteURL);
163
  $newpath = DUPX_U::addSlash(isset($newdata['path']) ? $newdata['path'] : "");
164
  $update_msg = "#This Apache config file was created by Duplicator Installer on {$timestamp}.\n";
165
- $update_msg .= "#The original can be found in archived file with the name htaccess.orig\n";
166
 
167
  $tmp_htaccess = <<<HTACCESS
168
  {$update_msg}
@@ -346,7 +346,7 @@ HTACCESS;
346
  }
347
 
348
  /**
349
- * Copies the code in htaccess.orig to .htaccess
350
  *
351
  * @param $path The root path to the location of the server config files
352
  * @param $new_htaccess_name New name of htaccess (either .htaccess or a backup name)
@@ -357,7 +357,7 @@ HTACCESS;
357
  {
358
  $status = false;
359
 
360
- if (!@rename($path.'/htaccess.orig', $path.'/'.$new_htaccess_name)) {
361
  $status = true;
362
  }
363
 
@@ -382,7 +382,7 @@ HTACCESS;
382
  $newdata = parse_url($post_url_new);
383
  $newpath = DUPX_U::addSlash(isset($newdata['path']) ? $newdata['path'] : "");
384
  $update_msg = "# This file was updated by Duplicator Pro on {$timestamp}.\n";
385
- $update_msg .= (file_exists("{$path}/.htaccess")) ? "# See htaccess.orig for the .htaccess original file." : "";
386
  $update_msg .= self::getOldHtaccessAddhandlerLine($path);
387
 
388
 
44
  self::$timeStamp = date("Y-m-d H:i:s");
45
  self::$rootPath = "{$GLOBALS['DUPX_ROOT']}";
46
  self::$confFileApache = "{$GLOBALS['DUPX_ROOT']}/.htaccess";
47
+ self::$confFileApacheOrig = "{$GLOBALS['DUPX_ROOT']}/.htaccess__".$GLOBALS['DUPX_AC']->package_hash;
48
  self::$confFileIIS = "{$GLOBALS['DUPX_ROOT']}/web.config";
49
  self::$confFileIISOrig = "{$GLOBALS['DUPX_ROOT']}/web.config.orig";
50
  self::$confFileWordFence = "{$GLOBALS['DUPX_ROOT']}/.user.ini";
96
  }
97
 
98
  /**
99
+ * Copies the code in .htaccess__[HASH] and web.config.orig
100
  * to .htaccess and web.config
101
  *
102
  * @return void
105
  {
106
  //APACHE
107
  if(rename(self::$confFileApacheOrig, self::$confFileApache)){
108
+ DUPX_Log::info("\n- PASS: The orginal .htaccess__[HASH] was renamed");
109
  } else {
110
+ DUPX_Log::info("\n- WARN: The orginal .htaccess__[HASH] was NOT renamed");
111
  }
112
 
113
  //IIS
114
  if(rename(self::$confFileIISOrig, self::$confFileIIS)){
115
+ DUPX_Log::info("\n- PASS: The orginal .htaccess__[HASH] was renamed");
116
  } else {
117
+ DUPX_Log::info("\n- WARN: The orginal .htaccess__[HASH] was NOT renamed");
118
  }
119
  }
120
 
162
  $newdata = parse_url(self::$newSiteURL);
163
  $newpath = DUPX_U::addSlash(isset($newdata['path']) ? $newdata['path'] : "");
164
  $update_msg = "#This Apache config file was created by Duplicator Installer on {$timestamp}.\n";
165
+ $update_msg .= "#The original can be found in archived file with the name .htaccess__[HASH]\n";
166
 
167
  $tmp_htaccess = <<<HTACCESS
168
  {$update_msg}
346
  }
347
 
348
  /**
349
+ * Copies the code in .htaccess__[HASH] to .htaccess
350
  *
351
  * @param $path The root path to the location of the server config files
352
  * @param $new_htaccess_name New name of htaccess (either .htaccess or a backup name)
357
  {
358
  $status = false;
359
 
360
+ if (!@rename($path.'/.htaccess__'.$GLOBALS['DUPX_AC']->package_hash, $path.'/'.$new_htaccess_name)) {
361
  $status = true;
362
  }
363
 
382
  $newdata = parse_url($post_url_new);
383
  $newpath = DUPX_U::addSlash(isset($newdata['path']) ? $newdata['path'] : "");
384
  $update_msg = "# This file was updated by Duplicator Pro on {$timestamp}.\n";
385
+ $update_msg .= (file_exists("{$path}/.htaccess")) ? "# See .htaccess__[HASH] for the .htaccess original file." : "";
386
  $update_msg .= self::getOldHtaccessAddhandlerLine($path);
387
 
388
 
installer/dup-installer/classes/utilities/class.u.php CHANGED
@@ -1663,25 +1663,28 @@ class DUPX_U
1663
 
1664
  return $wrapper . $path;
1665
  }
 
 
 
 
 
 
 
 
 
 
 
 
1666
 
1667
- /**
1668
- * Test if a given path is a stream URL
1669
- *
1670
- * @param string $path The resource path or URL.
1671
- * @return bool True if the path is a stream URL.
1672
- */
1673
- public static function wp_is_stream( $path ) {
1674
- if ( false === strpos( $path, '://' ) ) {
1675
- // $path isn't a stream
1676
- return false;
1677
- }
1678
 
1679
- $wrappers = stream_get_wrappers();
1680
- $wrappers = array_map( 'preg_quote', $wrappers );
1681
- $wrappers_re = '(' . join( '|', $wrappers ) . ')';
1682
 
1683
- return preg_match( "!^$wrappers_re://!", $path ) === 1;
1684
- }
1685
 
1686
  /**
1687
  * Check if string is base64 encoded
1663
 
1664
  return $wrapper . $path;
1665
  }
1666
+
1667
+ /**
1668
+ * Test if a given path is a stream URL
1669
+ *
1670
+ * from wordpress function wp_is_stream
1671
+ *
1672
+ * @param string $path The resource path or URL.
1673
+ * @return bool True if the path is a stream URL.
1674
+ */
1675
+ function wp_is_stream($path)
1676
+ {
1677
+ $scheme_separator = strpos($path, '://');
1678
 
1679
+ if (false === $scheme_separator) {
1680
+ // $path isn't a stream
1681
+ return false;
1682
+ }
 
 
 
 
 
 
 
1683
 
1684
+ $stream = substr($path, 0, $scheme_separator);
 
 
1685
 
1686
+ return in_array($stream, stream_get_wrappers(), true);
1687
+ }
1688
 
1689
  /**
1690
  * Check if string is base64 encoded
installer/dup-installer/main.installer.php CHANGED
@@ -453,7 +453,7 @@ $(document).ready(function ()
453
 
454
 
455
  <?php if ($GLOBALS['DUPX_DEBUG']) :?>
456
- <form id="form-debug" method="post" action="?debug=1">
457
  <input id="debug-view" type="hidden" name="view" />
458
  <br/><hr size="1" />
459
  DEBUG MODE ON
453
 
454
 
455
  <?php if ($GLOBALS['DUPX_DEBUG']) :?>
456
+ <form id="form-debug" method="post" action="?debug=1" autocomplete="off" >
457
  <input id="debug-view" type="hidden" name="view" />
458
  <br/><hr size="1" />
459
  DEBUG MODE ON
installer/dup-installer/views/view.help.php CHANGED
@@ -218,19 +218,19 @@ $expandClass = $sectionId == $open_section ? 'open' : 'close';
218
  present will be removed.
219
  <br/><br/>
220
 
221
- <b>Restore Original:</b> This option simply renames the htaccess.orig or web.config.orig files to .htaccess or web.config. The *.orig files come from the original
222
  web server where the package was built. Please note this option will cause issues with the install process if the configuration files are not properly setup to
223
  handle the new server environment. This is an advanced option and should only be used if you know how to properly configure your web servers configuration.
224
  <br/><br/>
225
 
226
  <b>Ignore All:</b> This option simply does nothing. No files are backed up, nothing is renamed or created. This advanced option assumes you already have your
227
- config files setup and know how they should behave in the new environment. When the package is build it will always create a htaccess.orig or web.config.orig.
228
  Since these files are already in the archive file they will show up when the archive is extracted.
229
  <br/><br/>
230
 
231
  <b>Additional Notes:</b>
232
  Inside the archive.zip will be a copy of the original .htaccess (Apache) or the web.config (IIS) files that were setup with your packaged site. They are both
233
- renamed to htaccess.orig and web.config.orig. When using either 'Create New' or 'Restore Original' any existing config files will be backed up with a .bak extension.
234
  <i>None of these changes are made until Step 3 is completed, to avoid any issues the .htaccess might cause during the install</i>
235
  <br/><br/>
236
  </td>
@@ -642,7 +642,7 @@ $expandClass = $sectionId == $open_section ? 'open' : 'close';
642
  <br/><br/>
643
 
644
  <b>Web server configuration files:</b><br/>
645
- For Apache web server the root .htaccess file was copied to htaccess.orig. A new stripped down .htaccess file was created to help simplify access issues. For IIS web server the web.config file was copied to web.config.orig, however no new web.config file was created. If you have not altered this file manually then resaving your permalinks and resaving your plugins should resolve most all changes that were made to the root web configuration file. If your still experiencing issues then open the .orig file and do a compare to see what changes need to be made. <br/><br/><b>Plugin Notes:</b><br/> It's impossible to know how all 3rd party plugins function. The Duplicator attempts to fix the new install URL for settings stored in the WordPress options table. Please validate that all plugins retained there settings after installing. If you experience issues try to bulk deactivate all plugins then bulk reactivate them on your new duplicated site. If you run into issues were a plugin does not retain its data then try to resave the plugins settings.
646
  <br/><br/>
647
 
648
  <b>Cache Systems:</b><br/>
218
  present will be removed.
219
  <br/><br/>
220
 
221
+ <b>Restore Original:</b> This option simply renames the .htaccess__[HASH] or web.config.orig files to .htaccess or web.config. The *.orig files come from the original
222
  web server where the package was built. Please note this option will cause issues with the install process if the configuration files are not properly setup to
223
  handle the new server environment. This is an advanced option and should only be used if you know how to properly configure your web servers configuration.
224
  <br/><br/>
225
 
226
  <b>Ignore All:</b> This option simply does nothing. No files are backed up, nothing is renamed or created. This advanced option assumes you already have your
227
+ config files setup and know how they should behave in the new environment. When the package is build it will always create a .htaccess__[HASH] or web.config.orig.
228
  Since these files are already in the archive file they will show up when the archive is extracted.
229
  <br/><br/>
230
 
231
  <b>Additional Notes:</b>
232
  Inside the archive.zip will be a copy of the original .htaccess (Apache) or the web.config (IIS) files that were setup with your packaged site. They are both
233
+ renamed to .htaccess__[HASH] and web.config.orig. When using either 'Create New' or 'Restore Original' any existing config files will be backed up with a .bak extension.
234
  <i>None of these changes are made until Step 3 is completed, to avoid any issues the .htaccess might cause during the install</i>
235
  <br/><br/>
236
  </td>
642
  <br/><br/>
643
 
644
  <b>Web server configuration files:</b><br/>
645
+ For Apache web server the root .htaccess file was copied to .htaccess__[HASH]. A new stripped down .htaccess file was created to help simplify access issues. For IIS web server the web.config file was copied to web.config.orig, however no new web.config file was created. If you have not altered this file manually then resaving your permalinks and resaving your plugins should resolve most all changes that were made to the root web configuration file. If your still experiencing issues then open the .orig file and do a compare to see what changes need to be made. <br/><br/><b>Plugin Notes:</b><br/> It's impossible to know how all 3rd party plugins function. The Duplicator attempts to fix the new install URL for settings stored in the WordPress options table. Please validate that all plugins retained there settings after installing. If you experience issues try to bulk deactivate all plugins then bulk reactivate them on your new duplicated site. If you run into issues were a plugin does not retain its data then try to resave the plugins settings.
646
  <br/><br/>
647
 
648
  <b>Cache Systems:</b><br/>
installer/dup-installer/views/view.init1.php CHANGED
@@ -43,7 +43,7 @@ if ($_POST['secure-try'] && ! $pass_check) {
43
 
44
  <!-- =========================================
45
  VIEW: STEP 0 - PASSWORD -->
46
- <form method="post" id="i1-pass-form" class="content-form" data-parsley-validate="">
47
  <input type="hidden" name="view" value="secure" />
48
  <input type="hidden" name="csrf_token" value="<?php echo DUPX_CSRF::generate('secure'); ?>">
49
  <input type="hidden" name="secure-try" value="1" />
43
 
44
  <!-- =========================================
45
  VIEW: STEP 0 - PASSWORD -->
46
+ <form method="post" id="i1-pass-form" class="content-form" data-parsley-validate="" autocomplete="off" >
47
  <input type="hidden" name="view" value="secure" />
48
  <input type="hidden" name="csrf_token" value="<?php echo DUPX_CSRF::generate('secure'); ?>">
49
  <input type="hidden" name="secure-try" value="1" />
installer/dup-installer/views/view.s1.base.php CHANGED
@@ -95,7 +95,7 @@ $zip_archive_enabled = class_exists('ZipArchive') ? 'Enabled' : 'Not Enabled';
95
  $archive_config = DUPX_ArchiveConfig::getInstance();
96
  ?>
97
 
98
- <form id="s1-input-form" method="post" class="content-form">
99
  <input type="hidden" name="view" value="step1" />
100
  <input type="hidden" name="csrf_token" value="<?php echo DUPX_CSRF::generate('step1'); ?>">
101
  <input type="hidden" name="ctrl_action" value="ctrl-step1" />
@@ -713,7 +713,7 @@ OPTIONS
713
  <!-- =========================================
714
  VIEW: STEP 1 - DB QUICK TEST
715
  ========================================= -->
716
- <form id="s1-dbtest-form" method="post" target="_blank">
717
  <input type="hidden" name="dbonlytest" value="1" />
718
  <input type="hidden" name="view" value="step2" />
719
  <input type="hidden" name="csrf_token" value="<?php echo DUPX_CSRF::generate('step2'); ?>">
@@ -727,7 +727,7 @@ VIEW: STEP 1 - DB QUICK TEST
727
  VIEW: STEP 1 - AJAX RESULT
728
  Auto Posts to view.step2.php
729
  ========================================= -->
730
- <form id='s1-result-form' method="post" class="content-form" style="display:none">
731
 
732
  <div class="dupx-logfile-link"><?php DUPX_View_Funcs::installerLogLink(); ?></div>
733
  <div class="hdr-main">
@@ -1068,10 +1068,6 @@ DUPX.kickOffDupArchiveExtract = function ()
1068
  request.throttle_delay = DUPX.throttleDelay;
1069
  request.filtered_directories = ['dup-installer'];
1070
 
1071
- if(!DUPX.areConfigFilesPreserved()) {
1072
- request.file_renames = {".htaccess":"htaccess.orig"};
1073
- }
1074
-
1075
  var requestString = JSON.stringify(request);
1076
 
1077
  if (!isClientSideKickoff) {
95
  $archive_config = DUPX_ArchiveConfig::getInstance();
96
  ?>
97
 
98
+ <form id="s1-input-form" method="post" class="content-form" autocomplete="off">
99
  <input type="hidden" name="view" value="step1" />
100
  <input type="hidden" name="csrf_token" value="<?php echo DUPX_CSRF::generate('step1'); ?>">
101
  <input type="hidden" name="ctrl_action" value="ctrl-step1" />
713
  <!-- =========================================
714
  VIEW: STEP 1 - DB QUICK TEST
715
  ========================================= -->
716
+ <form id="s1-dbtest-form" method="post" target="_blank" autocomplete="off">
717
  <input type="hidden" name="dbonlytest" value="1" />
718
  <input type="hidden" name="view" value="step2" />
719
  <input type="hidden" name="csrf_token" value="<?php echo DUPX_CSRF::generate('step2'); ?>">
727
  VIEW: STEP 1 - AJAX RESULT
728
  Auto Posts to view.step2.php
729
  ========================================= -->
730
+ <form id='s1-result-form' method="post" class="content-form" style="display:none" autocomplete="off">
731
 
732
  <div class="dupx-logfile-link"><?php DUPX_View_Funcs::installerLogLink(); ?></div>
733
  <div class="hdr-main">
1068
  request.throttle_delay = DUPX.throttleDelay;
1069
  request.filtered_directories = ['dup-installer'];
1070
 
 
 
 
 
1071
  var requestString = JSON.stringify(request);
1072
 
1073
  if (!isClientSideKickoff) {
installer/dup-installer/views/view.s2.base.php CHANGED
@@ -22,7 +22,7 @@ if (isset($_POST['logging'])) {
22
  $cpnl_supported = DUPX_U::$on_php_53_plus ? true : false;
23
  ?>
24
 
25
- <form id='s2-input-form' method="post" class="content-form" data-parsley-validate="true" data-parsley-excluded="input[type=hidden], [disabled], :hidden">
26
 
27
  <?php if ($is_dbtest_mode) : ?>
28
  <div class="hdr-main">Database Validation </div>
@@ -103,7 +103,7 @@ $cpnl_supported = DUPX_U::$on_php_53_plus ? true : false;
103
  <!-- =========================================
104
  VIEW: STEP 2 - AJAX RESULT
105
  Auto Posts to view.step3.php -->
106
- <form id='s2-result-form' method="post" class="content-form" style="display:none">
107
 
108
  <div class="dupx-logfile-link"><?php DUPX_View_Funcs::installerLogLink(); ?></div>
109
  <div class="hdr-main">
22
  $cpnl_supported = DUPX_U::$on_php_53_plus ? true : false;
23
  ?>
24
 
25
+ <form id='s2-input-form' method="post" class="content-form" autocomplete="off" data-parsley-validate="true" data-parsley-excluded="input[type=hidden], [disabled], :hidden">
26
 
27
  <?php if ($is_dbtest_mode) : ?>
28
  <div class="hdr-main">Database Validation </div>
103
  <!-- =========================================
104
  VIEW: STEP 2 - AJAX RESULT
105
  Auto Posts to view.step3.php -->
106
+ <form id='s2-result-form' method="post" class="content-form" style="display:none" autocomplete="off">
107
 
108
  <div class="dupx-logfile-link"><?php DUPX_View_Funcs::installerLogLink(); ?></div>
109
  <div class="hdr-main">
installer/dup-installer/views/view.s3.php CHANGED
@@ -62,7 +62,7 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
62
 
63
  <!-- =========================================
64
  VIEW: STEP 3- INPUT -->
65
- <form id='s3-input-form' method="post" class="content-form">
66
 
67
  <div class="logfile-link">
68
  <?php DUPX_View_Funcs::installerLogLink(); ?>
@@ -371,7 +371,7 @@ VIEW: STEP 3- INPUT -->
371
 
372
  <!-- =========================================
373
  VIEW: STEP 3 - AJAX RESULT -->
374
- <form id='s3-result-form' method="post" class="content-form" style="display:none">
375
 
376
  <div class="logfile-link"><?php DUPX_View_Funcs::installerLogLink(); ?></div>
377
  <div class="hdr-main">
62
 
63
  <!-- =========================================
64
  VIEW: STEP 3- INPUT -->
65
+ <form id='s3-input-form' method="post" class="content-form" autocomplete="off">
66
 
67
  <div class="logfile-link">
68
  <?php DUPX_View_Funcs::installerLogLink(); ?>
371
 
372
  <!-- =========================================
373
  VIEW: STEP 3 - AJAX RESULT -->
374
+ <form id='s3-result-form' method="post" class="content-form" style="display:none" autocomplete="off">
375
 
376
  <div class="logfile-link"><?php DUPX_View_Funcs::installerLogLink(); ?></div>
377
  <div class="hdr-main">
installer/dup-installer/views/view.s4.php CHANGED
@@ -67,7 +67,7 @@ if ($json_decode == NULL || $json_decode == FALSE) {
67
 
68
  <!-- =========================================
69
  VIEW: STEP 4- INPUT -->
70
- <form id='s4-input-form' method="post" class="content-form" style="line-height:20px">
71
  <input type="hidden" name="url_new" id="url_new" value="<?php echo DUPX_U::esc_attr($url_new_rtrim); ?>" />
72
  <div class="logfile-link"><?php DUPX_View_Funcs::installerLogLink(); ?></div>
73
 
67
 
68
  <!-- =========================================
69
  VIEW: STEP 4- INPUT -->
70
+ <form id='s4-input-form' method="post" class="content-form" style="line-height:20px" autocomplete="off">
71
  <input type="hidden" name="url_new" id="url_new" value="<?php echo DUPX_U::esc_attr($url_new_rtrim); ?>" />
72
  <div class="logfile-link"><?php DUPX_View_Funcs::installerLogLink(); ?></div>
73
 
installer/installer.tpl CHANGED
@@ -620,19 +620,19 @@ class DUPX_Bootstrap
620
  $ret .= '<font color="red">' . $newString[$i] . '</font>';
621
  continue;
622
  }
623
- for($char=0; isset($oldString[$i]{$char}) || isset($newString[$i]{$char}); $char++) {
624
 
625
- if(!isset($oldString[$i]{$char})) {
626
  $ret .= '<font color="red">' . substr($newString[$i], $char) . '</font>';
627
  break;
628
- } elseif(!isset($newString[$i]{$char})) {
629
  break;
630
  }
631
 
632
- if(ord($oldString[$i]{$char}) != ord($newString[$i]{$char}))
633
- $ret .= '<font color="red">' . $newString[$i]{$char} . '</font>';
634
  else
635
- $ret .= $newString[$i]{$char};
636
  }
637
  }
638
  return $ret;
620
  $ret .= '<font color="red">' . $newString[$i] . '</font>';
621
  continue;
622
  }
623
+ for($char=0; isset($oldString[$i][$char]) || isset($newString[$i][$char]); $char++) {
624
 
625
+ if(!isset($oldString[$i][$char])) {
626
  $ret .= '<font color="red">' . substr($newString[$i], $char) . '</font>';
627
  break;
628
+ } elseif(!isset($newString[$i][$char])) {
629
  break;
630
  }
631
 
632
+ if(ord($oldString[$i][$char]) != ord($newString[$i][$char]))
633
+ $ret .= '<font color="red">' . $newString[$i][$char] . '</font>';
634
  else
635
+ $ret .= $newString[$i][$char];
636
  }
637
  }
638
  return $ret;
lib/forceutf8/Encoding.php CHANGED
@@ -192,11 +192,11 @@ if (!class_exists('DUP_Encoding'))
192
 
193
  $buf = "";
194
  for($i = 0; $i < $max; $i++){
195
- $c1 = $text{$i};
196
  if($c1>="\xc0"){ //Should be converted to UTF8, if it's not UTF8 already
197
- $c2 = $i+1 >= $max? "\x00" : $text{$i+1};
198
- $c3 = $i+2 >= $max? "\x00" : $text{$i+2};
199
- $c4 = $i+3 >= $max? "\x00" : $text{$i+3};
200
  if($c1 >= "\xc0" & $c1 <= "\xdf"){ //looks like 2 bytes UTF8
201
  if($c2 >= "\x80" && $c2 <= "\xbf"){ //yeah, almost sure it's UTF8 already
202
  $buf .= $c1 . $c2;
192
 
193
  $buf = "";
194
  for($i = 0; $i < $max; $i++){
195
+ $c1 = $text[$i];
196
  if($c1>="\xc0"){ //Should be converted to UTF8, if it's not UTF8 already
197
+ $c2 = $i+1 >= $max? "\x00" : $text[$i+1];
198
+ $c3 = $i+2 >= $max? "\x00" : $text[$i+2];
199
+ $c4 = $i+3 >= $max? "\x00" : $text[$i+3];
200
  if($c1 >= "\xc0" & $c1 <= "\xdf"){ //looks like 2 bytes UTF8
201
  if($c2 >= "\x80" && $c2 <= "\xbf"){ //yeah, almost sure it's UTF8 already
202
  $buf .= $c1 . $c2;
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Duplicator - WordPress Migration Plugin ===
2
  Contributors: corylamleorg, bobriley
3
- Tags: migration, backup, restore, move, migrate, duplicate, transfer, clone, automate, copy site
4
  Requires at least: 4.0
5
  Tested up to: 5.3
6
  Requires PHP: 5.2.17
7
- Stable tag: 1.3.24
8
  License: GPLv2
9
 
10
  WordPress migration and backups are much easier with Duplicator! Clone, backup, move and transfer an entire site from one location to another.
@@ -19,7 +19,7 @@ For complete details visit [snapcreek.com](https://snapcreek.com/duplicator/?utm
19
  http://www.youtube.com/watch?v=oc73jtvHWYQ
20
 
21
  = Overview =
22
- Duplicator enables you to:
23
 
24
  * Move, migrate or clone a WordPress site between domains or hosts with **zero downtime**
25
  * Pull down a live site to localhost for development
1
  === Duplicator - WordPress Migration Plugin ===
2
  Contributors: corylamleorg, bobriley
3
+ Tags: migration, backup, duplicate, move, migrate, restore, transfer, clone, automate, copy site, migrator
4
  Requires at least: 4.0
5
  Tested up to: 5.3
6
  Requires PHP: 5.2.17
7
+ Stable tag: 1.3.26
8
  License: GPLv2
9
 
10
  WordPress migration and backups are much easier with Duplicator! Clone, backup, move and transfer an entire site from one location to another.
19
  http://www.youtube.com/watch?v=oc73jtvHWYQ
20
 
21
  = Overview =
22
+ Duplicator is the most powerful migrator available. It enables you to:
23
 
24
  * Move, migrate or clone a WordPress site between domains or hosts with **zero downtime**
25
  * Pull down a live site to localhost for development
uninstall.php CHANGED
@@ -7,6 +7,7 @@
7
  if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
8
  exit;
9
  }
 
10
  require_once 'define.php';
11
  require_once 'classes/class.settings.php';
12
  require_once 'classes/utilities/class.u.php';
@@ -17,6 +18,8 @@ DUP_Settings::init();
17
  $table_name = $wpdb->prefix . "duplicator_packages";
18
  $wpdb->query("DROP TABLE IF EXISTS `{$table_name}`");
19
 
 
 
20
  delete_option('duplicator_version_plugin');
21
  delete_option('duplicator_usage_id');
22
 
7
  if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
8
  exit;
9
  }
10
+ require_once 'helper.php';
11
  require_once 'define.php';
12
  require_once 'classes/class.settings.php';
13
  require_once 'classes/utilities/class.u.php';
18
  $table_name = $wpdb->prefix . "duplicator_packages";
19
  $wpdb->query("DROP TABLE IF EXISTS `{$table_name}`");
20
 
21
+ $wpdb->query("DELETE FROM ".$wpdb->usermeta." WHERE meta_key='".DUPLICATOR_ADMIN_NOTICES_USER_META_KEY."'");
22
+
23
  delete_option('duplicator_version_plugin');
24
  delete_option('duplicator_usage_id');
25
 
views/packages/details/detail.php CHANGED
@@ -8,7 +8,7 @@ $ui_css_install = (isset($view_state['dup-package-dtl-install-panel']) && $view_
8
 
9
  $format = strtolower($package->Archive->Format);
10
 
11
- $base_url = admin_url('admin.php');
12
  $link_sql = add_query_arg(
13
  array(
14
  'action' => 'duplicator_download',
@@ -155,7 +155,7 @@ GENERAL -->
155
  <table class="dup-sub-list">
156
  <tr>
157
  <td><?php esc_html_e('Archive', 'duplicator') ?>: </td>
158
- <td><a href="<?php echo esc_url($link_archive); ?>" target="_blank"><?php echo esc_html($package->Archive->File); ?></a></td>
159
  </tr>
160
  <tr>
161
  <td><?php esc_html_e('Installer', 'duplicator') ?>: </td>
8
 
9
  $format = strtolower($package->Archive->Format);
10
 
11
+ $base_url = admin_url('admin-ajax.php');
12
  $link_sql = add_query_arg(
13
  array(
14
  'action' => 'duplicator_download',
155
  <table class="dup-sub-list">
156
  <tr>
157
  <td><?php esc_html_e('Archive', 'duplicator') ?>: </td>
158
+ <td><a href="<?php echo esc_url($link_archive); ?>"><?php echo esc_html($package->Archive->File); ?></a></td>
159
  </tr>
160
  <tr>
161
  <td><?php esc_html_e('Installer', 'duplicator') ?>: </td>
views/packages/main/s1.setup1.php CHANGED
@@ -168,14 +168,16 @@ SYSTEM REQUIREMENTS -->
168
  </div>
169
  <div class="dup-sys-info dup-info-box">
170
  <?php
 
 
171
  printf("<b>%s</b> &nbsp; [%s] <br/>", $dup_tests['IO']['SSDIR'], DUPLICATOR_SSDIR_PATH);
172
  printf("<b>%s</b> &nbsp; [%s] <br/>", $dup_tests['IO']['SSTMP'], DUPLICATOR_SSDIR_PATH_TMP);
173
- printf("<b>%s</b> &nbsp; [%s] <br/>", $dup_tests['IO']['WPROOT'], DUPLICATOR_WPROOTPATH);
174
  ?>
175
  <div style="font-size:11px; padding-top: 3px">
176
  <?php
177
  if ($dup_tests['IO']['WPROOT'] == 'Warn') {
178
- echo sprintf(__('If the root WordPress path is not writable by PHP on some systems this can cause issues.', 'duplicator'), DUPLICATOR_WPROOTPATH);
179
  echo '<br/>';
180
  }
181
  esc_html_e("If Duplicator does not have enough permissions then you will need to manually create the paths above. &nbsp; ", 'duplicator');
@@ -226,7 +228,7 @@ SYSTEM REQUIREMENTS -->
226
  $duplicator_nonce = wp_create_nonce('duplicator_cleanup_page');
227
  ?>
228
  <form method="post" action="admin.php?page=duplicator-tools&tab=diagnostics&section=info&action=installer&_wpnonce=<?php echo esc_js($duplicator_nonce); ?>">
229
- <b><?php esc_html_e('WordPress Root Path:', 'duplicator'); ?></b> <?php echo esc_html(DUPLICATOR_WPROOTPATH); ?><br/>
230
  <?php esc_html_e("A reserved file(s) was found in the WordPress root directory. Reserved file names include [{$dup_intaller_files}]. To archive your data correctly please remove any of these files from your WordPress root directory. Then try creating your package again.", 'duplicator'); ?>
231
  <br/><input type='submit' class='button button-small' value='<?php esc_attr_e('Remove Files Now', 'duplicator') ?>' style='font-size:10px; margin-top:5px;' />
232
  </form>
168
  </div>
169
  <div class="dup-sys-info dup-info-box">
170
  <?php
171
+ $abs_path = duplicator_get_abs_path();
172
+
173
  printf("<b>%s</b> &nbsp; [%s] <br/>", $dup_tests['IO']['SSDIR'], DUPLICATOR_SSDIR_PATH);
174
  printf("<b>%s</b> &nbsp; [%s] <br/>", $dup_tests['IO']['SSTMP'], DUPLICATOR_SSDIR_PATH_TMP);
175
+ printf("<b>%s</b> &nbsp; [%s] <br/>", $dup_tests['IO']['WPROOT'], $abs_path);
176
  ?>
177
  <div style="font-size:11px; padding-top: 3px">
178
  <?php
179
  if ($dup_tests['IO']['WPROOT'] == 'Warn') {
180
+ echo sprintf(__('If the root WordPress path is not writable by PHP on some systems this can cause issues.', 'duplicator'), $abs_path);
181
  echo '<br/>';
182
  }
183
  esc_html_e("If Duplicator does not have enough permissions then you will need to manually create the paths above. &nbsp; ", 'duplicator');
228
  $duplicator_nonce = wp_create_nonce('duplicator_cleanup_page');
229
  ?>
230
  <form method="post" action="admin.php?page=duplicator-tools&tab=diagnostics&section=info&action=installer&_wpnonce=<?php echo esc_js($duplicator_nonce); ?>">
231
+ <b><?php esc_html_e('WordPress Root Path:', 'duplicator'); ?></b> <?php echo esc_html(duplicator_get_abs_path()); ?><br/>
232
  <?php esc_html_e("A reserved file(s) was found in the WordPress root directory. Reserved file names include [{$dup_intaller_files}]. To archive your data correctly please remove any of these files from your WordPress root directory. Then try creating your package again.", 'duplicator'); ?>
233
  <br/><input type='submit' class='button button-small' value='<?php esc_attr_e('Remove Files Now', 'duplicator') ?>' style='font-size:10px; margin-top:5px;' />
234
  </form>
views/packages/main/s1.setup2.php CHANGED
@@ -189,7 +189,7 @@ ARCHIVE -->
189
  ?>
190
  </label>
191
  <div class='dup-quick-links'>
192
- <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo rtrim(DUPLICATOR_WPROOTPATH, '/'); ?>')">[<?php esc_html_e("root path", 'duplicator') ?>]</a>
193
  <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo rtrim($upload_dir, '/'); ?>')">[<?php esc_html_e("wp-uploads", 'duplicator') ?>]</a>
194
  <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo DUP_Util::safePath(WP_CONTENT_DIR); ?>/cache')">[<?php esc_html_e("cache", 'duplicator') ?>]</a>
195
  <a href="javascript:void(0)" onclick="jQuery('#filter-dirs').val('')"><?php esc_html_e("(clear)", 'duplicator') ?></a>
@@ -211,7 +211,7 @@ ARCHIVE -->
211
  ?>
212
  </label>
213
  <div class='dup-quick-links'>
214
- <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludeFilePath('<?php echo rtrim(DUPLICATOR_WPROOTPATH, '/'); ?>')"><?php esc_html_e("(file path)", 'duplicator') ?></a>
215
  <a href="javascript:void(0)" onclick="jQuery('#filter-files').val('')"><?php esc_html_e("(clear)", 'duplicator') ?></a>
216
  </div>
217
  <textarea name="filter-files" id="filter-files" placeholder="/full_path/exclude_file_1.ext;/full_path/exclude_file2.ext"><?php echo str_replace(";", ";\n", esc_textarea($Package->Archive->FilterFiles)) ?></textarea>
189
  ?>
190
  </label>
191
  <div class='dup-quick-links'>
192
+ <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo duplicator_get_abs_path(); ?>')">[<?php esc_html_e("root path", 'duplicator') ?>]</a>
193
  <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo rtrim($upload_dir, '/'); ?>')">[<?php esc_html_e("wp-uploads", 'duplicator') ?>]</a>
194
  <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo DUP_Util::safePath(WP_CONTENT_DIR); ?>/cache')">[<?php esc_html_e("cache", 'duplicator') ?>]</a>
195
  <a href="javascript:void(0)" onclick="jQuery('#filter-dirs').val('')"><?php esc_html_e("(clear)", 'duplicator') ?></a>
211
  ?>
212
  </label>
213
  <div class='dup-quick-links'>
214
+ <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludeFilePath('<?php echo duplicator_get_abs_path(); ?>')"><?php esc_html_e("(file path)", 'duplicator') ?></a>
215
  <a href="javascript:void(0)" onclick="jQuery('#filter-files').val('')"><?php esc_html_e("(clear)", 'duplicator') ?></a>
216
  </div>
217
  <textarea name="filter-files" id="filter-files" placeholder="/full_path/exclude_file_1.ext;/full_path/exclude_file2.ext"><?php echo str_replace(";", ";\n", esc_textarea($Package->Archive->FilterFiles)) ?></textarea>
views/packages/main/s2.scan1.php CHANGED
@@ -420,7 +420,7 @@ jQuery(document).ready(function($)
420
  html_msg += '<li><?php esc_html_e("- On some budget hosts scanning over 30k files can lead to timeout/gateway issues. Consider scanning only your main WordPress site and avoid trying to backup other external directories.", 'duplicator') ?></li>';
421
  html_msg += '<li><?php esc_html_e("- Symbolic link recursion can cause timeouts. Ask your server admin if any are present in the scan path. If they are add the full path as a filter and try running the scan again.", 'duplicator') ?></li>';
422
  html_msg += '</ul>';
423
- $('#dup-msg-error-response-status').html('Scan Path Error [<?php echo rtrim(DUPLICATOR_WPROOTPATH, '/'); ?>]');
424
  $('#dup-msg-error-response-text').html(html_msg);
425
  $('#dup-msg-error').show(200);
426
  }
420
  html_msg += '<li><?php esc_html_e("- On some budget hosts scanning over 30k files can lead to timeout/gateway issues. Consider scanning only your main WordPress site and avoid trying to backup other external directories.", 'duplicator') ?></li>';
421
  html_msg += '<li><?php esc_html_e("- Symbolic link recursion can cause timeouts. Ask your server admin if any are present in the scan path. If they are add the full path as a filter and try running the scan again.", 'duplicator') ?></li>';
422
  html_msg += '</ul>';
423
+ $('#dup-msg-error-response-status').html('Scan Path Error [<?php echo duplicator_get_abs_path(); ?>]');
424
  $('#dup-msg-error-response-text').html(html_msg);
425
  $('#dup-msg-error').show(200);
426
  }
views/packages/main/s2.scan3.php CHANGED
@@ -4,7 +4,7 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
4
  /* @var $Package DUP_Package */
5
  function _duplicatorGetRootPath() {
6
  $txt = __('Root Path', 'duplicator');
7
- $root = rtrim(DUPLICATOR_WPROOTPATH, '//');
8
  $sroot = strlen($root) > 50 ? substr($root, 0, 50) . '...' : $root;
9
  echo "<div title='{$root}' class='divider'><i class='fa fa-folder-open'></i> {$sroot}</div>";
10
  }
@@ -616,7 +616,7 @@ DIALOG: Scan Results -->
616
  <small><?php echo ($Package->Archive->FilterOn) ? __('Enabled', 'duplicator') : __('Disabled', 'duplicator') ;?></small>
617
  </h2>
618
  <div class="filter-area">
619
- <b><i class="fa fa-folder-open"></i> <?php echo rtrim(DUPLICATOR_WPROOTPATH, "//");?></b>
620
 
621
  <script id="hb-filter-file-list" type="text/x-handlebars-template">
622
  <div class="file-info">
@@ -711,7 +711,7 @@ jQuery(document).ready(function($)
711
  {
712
 
713
  Handlebars.registerHelper('stripWPRoot', function(path) {
714
- return path.replace('<?php echo rtrim(DUPLICATOR_WPROOTPATH, "//") ?>', '');
715
  });
716
 
717
  //Uncheck file names if directory is checked
4
  /* @var $Package DUP_Package */
5
  function _duplicatorGetRootPath() {
6
  $txt = __('Root Path', 'duplicator');
7
+ $root = duplicator_get_abs_path();
8
  $sroot = strlen($root) > 50 ? substr($root, 0, 50) . '...' : $root;
9
  echo "<div title='{$root}' class='divider'><i class='fa fa-folder-open'></i> {$sroot}</div>";
10
  }
616
  <small><?php echo ($Package->Archive->FilterOn) ? __('Enabled', 'duplicator') : __('Disabled', 'duplicator') ;?></small>
617
  </h2>
618
  <div class="filter-area">
619
+ <b><i class="fa fa-folder-open"></i> <?php echo duplicator_get_abs_path();?></b>
620
 
621
  <script id="hb-filter-file-list" type="text/x-handlebars-template">
622
  <div class="file-info">
711
  {
712
 
713
  Handlebars.registerHelper('stripWPRoot', function(path) {
714
+ return path.replace('<?php echo duplicator_get_abs_path(); ?>');
715
  });
716
 
717
  //Uncheck file names if directory is checked
views/packages/main/s3.build.php CHANGED
@@ -422,7 +422,14 @@ jQuery(document).ready(function ($)
422
  console.log(xHr);
423
  return false;
424
  }
425
- Duplicator.Pack.WireDownloadLinks(data);
 
 
 
 
 
 
 
426
  },
427
  error: function (xHr) {
428
  $('#dup-progress-bar-area').hide();
422
  console.log(xHr);
423
  return false;
424
  }
425
+
426
+ if ((data != null) && (typeof (data) != 'undefined') && data.status == 1) {
427
+ Duplicator.Pack.WireDownloadLinks(data);
428
+ } else {
429
+ var message = (typeof (data.error) != 'undefined' && data.error.length) ? data.error : 'Error processing package';
430
+ Duplicator.Pack.DupArchiveProcessingFailed(message);
431
+ }
432
+
433
  },
434
  error: function (xHr) {
435
  $('#dup-progress-bar-area').hide();
views/settings/packages.php CHANGED
@@ -95,7 +95,7 @@ $archive_build_mode = DUP_Settings::Get('archive_build_mode')
95
  <?php if (!$is_shellexec_on) : ?>
96
  <p class="description" style="width:550px; margin:5px 0 0 20px">
97
  <?php
98
- _e("This server does not support the PHP shell_exec function which is required for mysqldump to run. ", 'duplicator');
99
  _e("Please contact the host or server administrator to enable this feature.", 'duplicator');
100
  ?>
101
  <br/>
95
  <?php if (!$is_shellexec_on) : ?>
96
  <p class="description" style="width:550px; margin:5px 0 0 20px">
97
  <?php
98
+ _e("This server does not support the PHP shell_exec or exec function which is required for mysqldump to run. ", 'duplicator');
99
  _e("Please contact the host or server administrator to enable this feature.", 'duplicator');
100
  ?>
101
  <br/>
views/tools/diagnostics/inc.settings.php CHANGED
@@ -5,8 +5,9 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
5
  $dbvar_maxtime = is_null($dbvar_maxtime) ? __("unknow", 'duplicator') : $dbvar_maxtime;
6
  $dbvar_maxpacks = is_null($dbvar_maxpacks) ? __("unknow", 'duplicator') : $dbvar_maxpacks;
7
 
8
- $space = @disk_total_space(DUPLICATOR_WPROOTPATH);
9
- $space_free = @disk_free_space(DUPLICATOR_WPROOTPATH);
 
10
  $perc = @round((100/$space)*$space_free,2);
11
  $mysqldumpPath = DUP_DB::getMySqlDumpPath();
12
  $mysqlDumpSupport = ($mysqldumpPath) ? $mysqldumpPath : 'Path Not Found';
@@ -51,13 +52,16 @@ SERVER SETTINGS -->
51
  <td><?php esc_html_e("Web Server", 'duplicator'); ?></td>
52
  <td><?php echo esc_html($_SERVER['SERVER_SOFTWARE']); ?></td>
53
  </tr>
 
 
 
54
  <tr>
55
  <td><?php esc_html_e("Root Path", 'duplicator'); ?></td>
56
- <td><?php echo esc_html(DUPLICATOR_WPROOTPATH) ?></td>
57
  </tr>
58
  <tr>
59
  <td><?php esc_html_e("ABSPATH", 'duplicator'); ?></td>
60
- <td><?php echo esc_html(ABSPATH); ?></td>
61
  </tr>
62
  <tr>
63
  <td><?php esc_html_e("Plugins Path", 'duplicator'); ?></td>
5
  $dbvar_maxtime = is_null($dbvar_maxtime) ? __("unknow", 'duplicator') : $dbvar_maxtime;
6
  $dbvar_maxpacks = is_null($dbvar_maxpacks) ? __("unknow", 'duplicator') : $dbvar_maxpacks;
7
 
8
+ $abs_path = duplicator_get_abs_path();
9
+ $space = @disk_total_space($abs_path);
10
+ $space_free = @disk_free_space($abs_path);
11
  $perc = @round((100/$space)*$space_free,2);
12
  $mysqldumpPath = DUP_DB::getMySqlDumpPath();
13
  $mysqlDumpSupport = ($mysqldumpPath) ? $mysqldumpPath : 'Path Not Found';
52
  <td><?php esc_html_e("Web Server", 'duplicator'); ?></td>
53
  <td><?php echo esc_html($_SERVER['SERVER_SOFTWARE']); ?></td>
54
  </tr>
55
+ <?php
56
+ $abs_path = duplicator_get_abs_path();
57
+ ?>
58
  <tr>
59
  <td><?php esc_html_e("Root Path", 'duplicator'); ?></td>
60
+ <td><?php echo esc_html($abs_path); ?></td>
61
  </tr>
62
  <tr>
63
  <td><?php esc_html_e("ABSPATH", 'duplicator'); ?></td>
64
+ <td><?php echo esc_html($abs_path); ?></td>
65
  </tr>
66
  <tr>
67
  <td><?php esc_html_e("Plugins Path", 'duplicator'); ?></td>
views/tools/diagnostics/inc.validator.php CHANGED
@@ -44,7 +44,7 @@ SCAN VALIDATOR -->
44
  </button>
45
 
46
  <script id="hb-template" type="text/x-handlebars-template">
47
- <b>Scan Path:</b> <?php echo esc_html(DUPLICATOR_WPROOTPATH); ?> <br/>
48
  <b>Scan Results</b><br/>
49
  <table>
50
  <tr>
44
  </button>
45
 
46
  <script id="hb-template" type="text/x-handlebars-template">
47
+ <b>Scan Path:</b> <?php echo esc_html(duplicator_get_abs_path()); ?> <br/>
48
  <b>Scan Results</b><br/>
49
  <table>
50
  <tr>
views/tools/diagnostics/information.php CHANGED
@@ -6,22 +6,23 @@ require_once(DUPLICATOR_PLUGIN_PATH . '/classes/class.io.php');
6
 
7
  $installer_files = DUP_Server::getInstallerFiles();
8
  $package_name = (isset($_GET['package'])) ? esc_html($_GET['package']) : '';
 
9
 
10
  // For auto detect archive file name logic
11
  if (empty($package_name)) {
12
- $installer_file_path = DUPLICATOR_WPROOTPATH . 'installer.php';
13
  if (file_exists($installer_file_path)) {
14
  $installer_file_data = file_get_contents($installer_file_path);
15
  if (preg_match("/const ARCHIVE_FILENAME = '(.*?)';/", $installer_file_data, $match)) {
16
  $temp_archive_file = esc_html($match[1]);
17
- $temp_archive_file_path = DUPLICATOR_WPROOTPATH . $temp_archive_file;
18
  if (file_exists($temp_archive_file_path)) {
19
  $package_name = $temp_archive_file;
20
  }
21
  }
22
  }
23
  }
24
- $package_path = empty($package_name) ? '' : DUPLICATOR_WPROOTPATH.$package_name;
25
  $txt_found = __('File Found: Unable to remove', 'duplicator');
26
  $txt_removed = __('Removed', 'duplicator');
27
  $nonce = wp_create_nonce('duplicator_cleanup_page');
6
 
7
  $installer_files = DUP_Server::getInstallerFiles();
8
  $package_name = (isset($_GET['package'])) ? esc_html($_GET['package']) : '';
9
+ $abs_path = duplicator_get_abs_path();
10
 
11
  // For auto detect archive file name logic
12
  if (empty($package_name)) {
13
+ $installer_file_path = $abs_path . '/' . 'installer.php';
14
  if (file_exists($installer_file_path)) {
15
  $installer_file_data = file_get_contents($installer_file_path);
16
  if (preg_match("/const ARCHIVE_FILENAME = '(.*?)';/", $installer_file_data, $match)) {
17
  $temp_archive_file = esc_html($match[1]);
18
+ $temp_archive_file_path = $abs_path . '/' . $temp_archive_file;
19
  if (file_exists($temp_archive_file_path)) {
20
  $package_name = $temp_archive_file;
21
  }
22
  }
23
  }
24
  }
25
+ $package_path = empty($package_name) ? '' : $abs_path . '/' . $package_name;
26
  $txt_found = __('File Found: Unable to remove', 'duplicator');
27
  $txt_removed = __('Removed', 'duplicator');
28
  $nonce = wp_create_nonce('duplicator_cleanup_page');