Duplicator – WordPress Migration Plugin - Version 1.3.18

Version Description

Download this release

Release Info

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

Code changes from version 1.3.16 to 1.3.18

classes/package/class.pack.php CHANGED
@@ -238,6 +238,10 @@ class DUP_Package
238
  $report['ARC']['DirCount'] = number_format($dirCount);
239
  $report['ARC']['FileCount'] = number_format($fileCount);
240
  $report['ARC']['FullCount'] = number_format($fullCount);
 
 
 
 
241
  $report['ARC']['FilterDirsAll'] = $this->Archive->FilterDirsAll;
242
  $report['ARC']['FilterFilesAll'] = $this->Archive->FilterFilesAll;
243
  $report['ARC']['FilterExtsAll'] = $this->Archive->FilterExtsAll;
@@ -880,9 +884,8 @@ class DUP_Package
880
  if ($expected_filecount > 500) {
881
  $straight_ratio = (float) $expected_filecount / (float) $this->Archive->file_count;
882
 
883
- $warning_count = $scanReport->ARC->WarnFileCount + $scanReport->ARC->WarnDirCount + $scanReport->ARC->UnreadableFileCount + $scanReport->ARC->UnreadableDirCount;
884
  DUP_LOG::trace("Warn/unread counts) warnfile:{$scanReport->ARC->WarnFileCount} warndir:{$scanReport->ARC->WarnDirCount} unreadfile:{$scanReport->ARC->UnreadableFileCount} unreaddir:{$scanReport->ARC->UnreadableDirCount}");
885
-
886
  $warning_ratio = ((float) ($expected_filecount + $warning_count)) / (float) $this->Archive->file_count;
887
  DUP_LOG::trace("Straight ratio is $straight_ratio and warning ratio is $warning_ratio. # Expected=$expected_filecount # Warning=$warning_count and #Archive File {$this->Archive->file_count}");
888
 
@@ -892,9 +895,9 @@ class DUP_Package
892
  if (($warning_ratio < 0.90) || ($warning_ratio > 1.01)) {
893
  $error_message = sprintf('ERROR: File count in archive vs expected suggests a bad archive (%1$d vs %2$d).', $this->Archive->file_count, $expected_filecount);
894
  $this->BuildProgress->set_failed($error_message);
895
- $this->Status = DUP_PackageStatus::ERROR;
896
  $this->update();
897
-
898
  DUP_Log::error($error_message, '');
899
  return;
900
  }
238
  $report['ARC']['DirCount'] = number_format($dirCount);
239
  $report['ARC']['FileCount'] = number_format($fileCount);
240
  $report['ARC']['FullCount'] = number_format($fullCount);
241
+ $report['ARC']['WarnFileCount'] = count($this->Archive->FilterInfo->Files->Warning);
242
+ $report['ARC']['WarnDirCount'] = count($this->Archive->FilterInfo->Dirs->Warning);
243
+ $report['ARC']['UnreadableDirCount'] = count($this->Archive->FilterInfo->Dirs->Unreadable);
244
+ $report['ARC']['UnreadableFileCount'] = count($this->Archive->FilterInfo->Files->Unreadable);
245
  $report['ARC']['FilterDirsAll'] = $this->Archive->FilterDirsAll;
246
  $report['ARC']['FilterFilesAll'] = $this->Archive->FilterFilesAll;
247
  $report['ARC']['FilterExtsAll'] = $this->Archive->FilterExtsAll;
884
  if ($expected_filecount > 500) {
885
  $straight_ratio = (float) $expected_filecount / (float) $this->Archive->file_count;
886
 
887
+ $warning_count = $scanReport->ARC->WarnFileCount + $scanReport->ARC->WarnDirCount + $scanReport->ARC->UnreadableFileCount + $scanReport->ARC->UnreadableDirCount;
888
  DUP_LOG::trace("Warn/unread counts) warnfile:{$scanReport->ARC->WarnFileCount} warndir:{$scanReport->ARC->WarnDirCount} unreadfile:{$scanReport->ARC->UnreadableFileCount} unreaddir:{$scanReport->ARC->UnreadableDirCount}");
 
889
  $warning_ratio = ((float) ($expected_filecount + $warning_count)) / (float) $this->Archive->file_count;
890
  DUP_LOG::trace("Straight ratio is $straight_ratio and warning ratio is $warning_ratio. # Expected=$expected_filecount # Warning=$warning_count and #Archive File {$this->Archive->file_count}");
891
 
895
  if (($warning_ratio < 0.90) || ($warning_ratio > 1.01)) {
896
  $error_message = sprintf('ERROR: File count in archive vs expected suggests a bad archive (%1$d vs %2$d).', $this->Archive->file_count, $expected_filecount);
897
  $this->BuildProgress->set_failed($error_message);
898
+ $this->Status = DUP_PackageStatus::ERROR;
899
  $this->update();
900
+
901
  DUP_Log::error($error_message, '');
902
  return;
903
  }
ctrls/ctrl.package.php CHANGED
@@ -116,15 +116,13 @@ function duplicator_duparchive_package_build()
116
  $active_package_id = DUP_Settings::Get('active_package_id');
117
 
118
  if ($active_package_id == -1) {
119
-
120
  $package = DUP_Package::getActive();
121
  $package->save('daf');
122
- DUP_Log::TraceObject("saving active package as new id={$package->ID}", package);
123
  DUP_Settings::Set('active_package_id', $package->ID);
124
  DUP_Settings::Save();
125
  } else {
126
-
127
- DUP_Log::TraceObject("getting active package by id {$active_package_id}", package);
128
  $package = DUP_Package::getByID($active_package_id);
129
  }
130
 
116
  $active_package_id = DUP_Settings::Get('active_package_id');
117
 
118
  if ($active_package_id == -1) {
 
119
  $package = DUP_Package::getActive();
120
  $package->save('daf');
121
+ DUP_Log::TraceObject("saving active package as new id={$package->ID}", $package);
122
  DUP_Settings::Set('active_package_id', $package->ID);
123
  DUP_Settings::Save();
124
  } else {
125
+ DUP_Log::TraceObject("getting active package by id {$active_package_id}", $package);
 
126
  $package = DUP_Package::getByID($active_package_id);
127
  }
128
 
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.16');
8
- define('DUPLICATOR_VERSION_BUILD', '2019-07-07_14:00');
9
  define('DUPLICATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
10
  define('DUPLICATOR_SITE_URL', get_site_url());
11
 
4
  //Prevent directly browsing to the file
5
  if (function_exists('plugin_dir_url'))
6
  {
7
+ define('DUPLICATOR_VERSION', '1.3.18');
8
+ define('DUPLICATOR_VERSION_BUILD', '2019-07-13_09:00');
9
  define('DUPLICATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
10
  define('DUPLICATOR_SITE_URL', get_site_url());
11
 
duplicator.php CHANGED
@@ -3,7 +3,7 @@
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.16
7
  Author: Snap Creek
8
  Author URI: http://www.snapcreek.com/duplicator/
9
  Text Domain: duplicator
@@ -163,12 +163,15 @@ if (is_admin() == true)
163
  require_once 'classes/host/class.wpengine.host.php';
164
  }
165
 
166
- $hostName = gethostname();
167
- $goDaddyHostNameSuffix = '.secureserver.net';
168
- $lenGoDaddyHostNameSuffix = strlen($goDaddyHostNameSuffix);
169
- $isGoDaddyHost = apply_filters('duplicator_godaddy_host_check', (false !== $hostName && substr($hostName, - $lenGoDaddyHostNameSuffix) === $goDaddyHostNameSuffix));
170
- if ($isGoDaddyHost) {
171
- require_once 'classes/host/class.godaddy.host.php';
 
 
 
172
  }
173
 
174
  require_once 'classes/class.settings.php';
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.18
7
  Author: Snap Creek
8
  Author URI: http://www.snapcreek.com/duplicator/
9
  Text Domain: duplicator
163
  require_once 'classes/host/class.wpengine.host.php';
164
  }
165
 
166
+ // gethostname() only present in PHP 5.3
167
+ if(version_compare(PHP_VERSION, '5.3.0') >= 0) {
168
+ $hostName = gethostname();
169
+ $goDaddyHostNameSuffix = '.secureserver.net';
170
+ $lenGoDaddyHostNameSuffix = strlen($goDaddyHostNameSuffix);
171
+ $isGoDaddyHost = apply_filters('duplicator_godaddy_host_check', (false !== $hostName && substr($hostName, - $lenGoDaddyHostNameSuffix) === $goDaddyHostNameSuffix));
172
+ if ($isGoDaddyHost) {
173
+ require_once 'classes/host/class.godaddy.host.php';
174
+ }
175
  }
176
 
177
  require_once 'classes/class.settings.php';
installer/dup-installer/classes/class.package.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class used to update and edit web server configuration files
4
+ * for .htaccess, web.config and user.ini
5
+ *
6
+ * Standard: PSR-2
7
+ * @link http://www.php-fig.org/psr/psr-2 Full Documentation
8
+ *
9
+ */
10
+ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
11
+
12
+ /**
13
+ * Package related functions
14
+ *
15
+ */
16
+ final class DUPX_Package
17
+ {
18
+ /**
19
+ *
20
+ * @staticvar string $path
21
+ * @return string
22
+ */
23
+ public static function getWpconfigArkPath()
24
+ {
25
+ static $path = null;
26
+ if (is_null($path)) {
27
+ $path = $GLOBALS['DUPX_AC']->installSiteOverwriteOn ? $GLOBALS['DUPX_ROOT'].'/dup-wp-config-arc__'.$GLOBALS['DUPX_AC']->package_hash.'.txt' : $GLOBALS['DUPX_ROOT'].'/wp-config.php';
28
+ }
29
+ return $path;
30
+ }
31
+
32
+ /**
33
+ *
34
+ * @staticvar string $path
35
+ * @return string
36
+ */
37
+ public static function getHtaccessArkPath()
38
+ {
39
+ static $path = null;
40
+ if (is_null($path)) {
41
+ $path = $GLOBALS['DUPX_ROOT'].'/htaccess.orig';
42
+ }
43
+ return $path;
44
+ }
45
+
46
+ /**
47
+ *
48
+ * @staticvar string $path
49
+ * @return string
50
+ */
51
+ public static function getOrigWpConfigPath()
52
+ {
53
+ static $path = null;
54
+ if (is_null($path)) {
55
+ $path = $GLOBALS['DUPX_INIT'].'/dup-orig-wp-config__'.$GLOBALS['DUPX_AC']->package_hash.'.txt';
56
+ }
57
+ return $path;
58
+ }
59
+
60
+ /**
61
+ *
62
+ * @staticvar string $path
63
+ * @return string
64
+ */
65
+ public static function getOrigHtaccessPath()
66
+ {
67
+ static $path = null;
68
+ if (is_null($path)) {
69
+ $path = $GLOBALS['DUPX_INIT'].'/dup-orig-wp-config__'.$GLOBALS['DUPX_AC']->package_hash.'.txt';
70
+ }
71
+ return $GLOBALS['DUPX_INIT'].'/dup-orig-htaccess__'.$GLOBALS['DUPX_AC']->package_hash.'.txt';
72
+ }
73
+ }
installer/dup-installer/classes/class.s3.func.php CHANGED
@@ -376,83 +376,27 @@ final class DUPX_S3_Funcs
376
 
377
  if (is_null($configTransformer)) {
378
  //@todo: integrate all logic into DUPX_WPConfig::updateVars
379
- if (is_writable($this->getWpconfigArkPath())) {
380
- $configTransformer = new WPConfigTransformer($this->getWpconfigArkPath());
381
  } else {
382
  $err_log = "\nWARNING: Unable to update file permissions and write to dup-wp-config-arc__[HASH].txt. ";
383
  $err_log .= "Check that the wp-config.php is in the archive.zip and check with your host or administrator to enable PHP to write to the wp-config.php file. ";
384
  $err_log .= "If performing a 'Manual Extraction' please be sure to select the 'Manual Archive Extraction' option on step 1 under options.";
385
- chmod($this->getWpconfigArkPath(), 0644) ? DUPX_Log::info("File Permission Update: dup-wp-config-arc__[HASH].txt set to 0644") : DUPX_Log::error("{$err_log}");
386
  }
387
  }
388
 
389
  return $configTransformer;
390
  }
391
 
392
- /**
393
- *
394
- * @staticvar string $path
395
- * @return string
396
- */
397
- public function getWpconfigArkPath()
398
- {
399
- static $path = null;
400
- if (is_null($path)) {
401
- $path = $GLOBALS['DUPX_AC']->installSiteOverwriteOn ? $GLOBALS['DUPX_ROOT'].'/dup-wp-config-arc__'.$GLOBALS['DUPX_AC']->package_hash.'.txt' : $GLOBALS['DUPX_ROOT'].'/wp-config.php';
402
- }
403
- return $path;
404
- }
405
-
406
- /**
407
- *
408
- * @staticvar string $path
409
- * @return string
410
- */
411
- public function getHtaccessArkPath()
412
- {
413
- static $path = null;
414
- if (is_null($path)) {
415
- $path = $GLOBALS['DUPX_ROOT'].'/htaccess.orig';
416
- }
417
- return $path;
418
- }
419
-
420
- /**
421
- *
422
- * @staticvar string $path
423
- * @return string
424
- */
425
- public function getOrigWpConfigPath()
426
- {
427
- static $path = null;
428
- if (is_null($path)) {
429
- $path = $GLOBALS['DUPX_INIT'].'/dup-orig-wp-config__'.$GLOBALS['DUPX_AC']->package_hash.'.txt';
430
- }
431
- return $path;
432
- }
433
-
434
- /**
435
- *
436
- * @staticvar string $path
437
- * @return string
438
- */
439
- public function getOrigHtaccessPath()
440
- {
441
- static $path = null;
442
- if (is_null($path)) {
443
- $path = $GLOBALS['DUPX_INIT'].'/dup-orig-wp-config__'.$GLOBALS['DUPX_AC']->package_hash.'.txt';
444
- }
445
- return $GLOBALS['DUPX_INIT'].'/dup-orig-htaccess__'.$GLOBALS['DUPX_AC']->package_hash.'.txt';
446
- }
447
-
448
  /**
449
  *
450
  * @return string
451
  */
452
  public function copyOriginalConfigFiles()
453
  {
454
- $wpOrigPath = $this->getOrigWpConfigPath();
455
- $wpArkPath = $this->getWpconfigArkPath();
456
 
457
  if (file_exists($wpOrigPath)) {
458
  if (!@unlink($wpOrigPath)) {
@@ -462,17 +406,17 @@ final class DUPX_S3_Funcs
462
 
463
  if (!file_exists($wpArkPath)) {
464
  DUPX_Log::info('WP Config ark file don\' exists');
465
- }
466
-
467
- if (!@copy($wpArkPath, $wpOrigPath)) {
468
- $errors = error_get_last();
469
- DUPX_Log::info("COPY ERROR: ".$errors['type']."\n".$errors['message']);
470
  } else {
471
- echo DUPX_Log::info("Original WP Config file copied", 2);
 
 
 
 
 
472
  }
473
 
474
- $htOrigPath = $this->getOrigHtaccessPath();
475
- $htArkPath = $this->getHtaccessArkPath();
476
 
477
  if (file_exists($htOrigPath)) {
478
  if (!@unlink($htOrigPath)) {
@@ -482,13 +426,13 @@ final class DUPX_S3_Funcs
482
 
483
  if (!file_exists($htArkPath)) {
484
  DUPX_Log::info('htaccess ark file don\' exists');
485
- }
486
-
487
- if (!@copy($htArkPath, $htOrigPath)) {
488
- $errors = error_get_last();
489
- DUPX_Log::info("COPY ERROR: ".$errors['type']."\n".$errors['message']);
490
  } else {
491
- echo DUPX_Log::info("htaccess file copied", 2);
 
 
 
 
 
492
  }
493
  }
494
 
@@ -725,7 +669,7 @@ final class DUPX_S3_Funcs
725
 
726
  $nManager = DUPX_NOTICE_MANAGER::getInstance();
727
  try {
728
- if (file_exists($this->getWpconfigArkPath())) {
729
  $confTransformer = $this->getWpConfigTransformer();
730
 
731
  $mu_newDomain = parse_url($this->getPost('url_new'));
@@ -1043,8 +987,8 @@ LONGMSG;
1043
  $blog_name = mysqli_real_escape_string($this->dbh, $this->post['blogname']);
1044
  $plugin_list = $this->post['plugins'];
1045
 
1046
- if (!in_array('duplicator-pro/duplicator.php', $plugin_list)) {
1047
- $plugin_list[] = 'duplicator-pro/duplicator.php';
1048
  }
1049
  $serial_plugin_list = @serialize($plugin_list);
1050
 
@@ -1060,7 +1004,7 @@ LONGMSG;
1060
  "UPDATE `".mysqli_real_escape_string($this->dbh, $GLOBALS['DUPX_AC']->wp_tableprefix)."options` SET option_value = '".mysqli_real_escape_string($this->dbh, $this->post['siteurl'])."' WHERE option_name = 'siteurl' ");
1061
  mysqli_query($this->dbh,
1062
  "INSERT INTO `".mysqli_real_escape_string($this->dbh, $GLOBALS['DUPX_AC']->wp_tableprefix)."options` (option_value, option_name) VALUES('".mysqli_real_escape_string($this->dbh,
1063
- $this->post['exe_safe_mode'])."','duplicator_pro_exe_safe_mode')");
1064
  //Reset the postguid data
1065
  if ($this->post['postguid']) {
1066
  mysqli_query($this->dbh,
@@ -1078,8 +1022,8 @@ LONGMSG;
1078
  $this->dbConnection();
1079
 
1080
  $nManager = DUPX_NOTICE_MANAGER::getInstance();
1081
- if (file_exists($this->getWpconfigArkPath())) {
1082
- $wpconfig_ark_contents = file_get_contents($this->getWpconfigArkPath());
1083
  $config_vars = array('WPCACHEHOME', 'COOKIE_DOMAIN', 'WP_SITEURL', 'WP_HOME', 'WP_TEMP_DIR');
1084
  $config_found = DUPX_U::getListValues($config_vars, $wpconfig_ark_contents);
1085
 
@@ -1103,10 +1047,10 @@ LONGMSG;
1103
 
1104
  //-- Finally, back up the old wp-config and rename the new one
1105
  $wpconfig_path = "{$GLOBALS['DUPX_ROOT']}/wp-config.php";
1106
- if ($this->getWpconfigArkPath() !== $wpconfig_path) {
1107
- if (copy($this->getWpconfigArkPath(), $wpconfig_path) === false) {
1108
  DUPX_LOG::info(
1109
- 'COPY SOURCE: '.DUPX_LOG::varToString($this->getWpconfigArkPath())."\n".
1110
  "COPY DEST:".DUPX_LOG::varToString($wpconfig_path), DUPX_Log::LV_DEBUG);
1111
  DUPX_Log::error("ERROR: Unable to copy 'dup-wp-config-arc__[HASH].txt' to 'wp-config.php'.\n".
1112
  "Check server permissions for more details see FAQ: https://snapcreek.com/duplicator/docs/faqs-tech/#faq-trouble-055-q");
@@ -1154,9 +1098,6 @@ LONGMSG;
1154
  }
1155
  }
1156
 
1157
- $sql = "INSERT into ".mysqli_real_escape_string($this->dbh, $GLOBALS['DUPX_AC']->wp_tableprefix)."options (option_name, option_value) VALUES ('duplicator_pro_migration', '1');";
1158
- @mysqli_query($this->dbh, $sql);
1159
-
1160
  if (empty($this->report['warnlist'])) {
1161
  DUPX_Log::info("No General Notices Found\n");
1162
  }
@@ -1197,7 +1138,7 @@ LONGMSG;
1197
  {
1198
  $nManager = DUPX_NOTICE_MANAGER::getInstance();
1199
 
1200
- $orig = file_get_contents($this->getOrigHtaccessPath());
1201
  $new = file_get_contents($GLOBALS['DUPX_ROOT'].'/.htaccess');
1202
 
1203
  $lightBoxContent = '<div class="row-cols-2">'.
@@ -1220,7 +1161,7 @@ LONGMSG;
1220
  {
1221
  $nManager = DUPX_NOTICE_MANAGER::getInstance();
1222
 
1223
- if (($orig = file_get_contents($this->getOrigWpConfigPath())) === false) {
1224
  $orig = 'Can read origin wp-config.php file';
1225
  } else {
1226
  $orig = $this->obscureWpConfig($orig);
376
 
377
  if (is_null($configTransformer)) {
378
  //@todo: integrate all logic into DUPX_WPConfig::updateVars
379
+ if (is_writable(DUPX_Package::getWpconfigArkPath())) {
380
+ $configTransformer = new WPConfigTransformer(DUPX_Package::getWpconfigArkPath());
381
  } else {
382
  $err_log = "\nWARNING: Unable to update file permissions and write to dup-wp-config-arc__[HASH].txt. ";
383
  $err_log .= "Check that the wp-config.php is in the archive.zip and check with your host or administrator to enable PHP to write to the wp-config.php file. ";
384
  $err_log .= "If performing a 'Manual Extraction' please be sure to select the 'Manual Archive Extraction' option on step 1 under options.";
385
+ chmod(DUPX_Package::getWpconfigArkPath(), 0644) ? DUPX_Log::info("File Permission Update: dup-wp-config-arc__[HASH].txt set to 0644") : DUPX_Log::error("{$err_log}");
386
  }
387
  }
388
 
389
  return $configTransformer;
390
  }
391
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  /**
393
  *
394
  * @return string
395
  */
396
  public function copyOriginalConfigFiles()
397
  {
398
+ $wpOrigPath = DUPX_Package::getOrigWpConfigPath();
399
+ $wpArkPath = DUPX_Package::getWpconfigArkPath();
400
 
401
  if (file_exists($wpOrigPath)) {
402
  if (!@unlink($wpOrigPath)) {
406
 
407
  if (!file_exists($wpArkPath)) {
408
  DUPX_Log::info('WP Config ark file don\' exists');
 
 
 
 
 
409
  } else {
410
+ if (!@copy($wpArkPath, $wpOrigPath)) {
411
+ $errors = error_get_last();
412
+ DUPX_Log::info("COPY ERROR: ".$errors['type']."\n".$errors['message']);
413
+ } else {
414
+ echo DUPX_Log::info("Original WP Config file copied", 2);
415
+ }
416
  }
417
 
418
+ $htOrigPath = DUPX_Package::getOrigHtaccessPath();
419
+ $htArkPath = DUPX_Package::getHtaccessArkPath();
420
 
421
  if (file_exists($htOrigPath)) {
422
  if (!@unlink($htOrigPath)) {
426
 
427
  if (!file_exists($htArkPath)) {
428
  DUPX_Log::info('htaccess ark file don\' exists');
 
 
 
 
 
429
  } else {
430
+ if (!@copy($htArkPath, $htOrigPath)) {
431
+ $errors = error_get_last();
432
+ DUPX_Log::info("COPY ERROR: ".$errors['type']."\n".$errors['message']);
433
+ } else {
434
+ echo DUPX_Log::info("htaccess file copied", 2);
435
+ }
436
  }
437
  }
438
 
669
 
670
  $nManager = DUPX_NOTICE_MANAGER::getInstance();
671
  try {
672
+ if (file_exists(DUPX_Package::getWpconfigArkPath())) {
673
  $confTransformer = $this->getWpConfigTransformer();
674
 
675
  $mu_newDomain = parse_url($this->getPost('url_new'));
987
  $blog_name = mysqli_real_escape_string($this->dbh, $this->post['blogname']);
988
  $plugin_list = $this->post['plugins'];
989
 
990
+ if (!in_array('duplicator/duplicator.php', $plugin_list)) {
991
+ $plugin_list[] = 'duplicator/duplicator.php';
992
  }
993
  $serial_plugin_list = @serialize($plugin_list);
994
 
1004
  "UPDATE `".mysqli_real_escape_string($this->dbh, $GLOBALS['DUPX_AC']->wp_tableprefix)."options` SET option_value = '".mysqli_real_escape_string($this->dbh, $this->post['siteurl'])."' WHERE option_name = 'siteurl' ");
1005
  mysqli_query($this->dbh,
1006
  "INSERT INTO `".mysqli_real_escape_string($this->dbh, $GLOBALS['DUPX_AC']->wp_tableprefix)."options` (option_value, option_name) VALUES('".mysqli_real_escape_string($this->dbh,
1007
+ $this->post['exe_safe_mode'])."','duplicator_exe_safe_mode')");
1008
  //Reset the postguid data
1009
  if ($this->post['postguid']) {
1010
  mysqli_query($this->dbh,
1022
  $this->dbConnection();
1023
 
1024
  $nManager = DUPX_NOTICE_MANAGER::getInstance();
1025
+ if (file_exists(DUPX_Package::getWpconfigArkPath())) {
1026
+ $wpconfig_ark_contents = file_get_contents(DUPX_Package::getWpconfigArkPath());
1027
  $config_vars = array('WPCACHEHOME', 'COOKIE_DOMAIN', 'WP_SITEURL', 'WP_HOME', 'WP_TEMP_DIR');
1028
  $config_found = DUPX_U::getListValues($config_vars, $wpconfig_ark_contents);
1029
 
1047
 
1048
  //-- Finally, back up the old wp-config and rename the new one
1049
  $wpconfig_path = "{$GLOBALS['DUPX_ROOT']}/wp-config.php";
1050
+ if (DUPX_Package::getWpconfigArkPath() !== $wpconfig_path) {
1051
+ if (copy(DUPX_Package::getWpconfigArkPath(), $wpconfig_path) === false) {
1052
  DUPX_LOG::info(
1053
+ 'COPY SOURCE: '.DUPX_LOG::varToString(DUPX_Package::getWpconfigArkPath())."\n".
1054
  "COPY DEST:".DUPX_LOG::varToString($wpconfig_path), DUPX_Log::LV_DEBUG);
1055
  DUPX_Log::error("ERROR: Unable to copy 'dup-wp-config-arc__[HASH].txt' to 'wp-config.php'.\n".
1056
  "Check server permissions for more details see FAQ: https://snapcreek.com/duplicator/docs/faqs-tech/#faq-trouble-055-q");
1098
  }
1099
  }
1100
 
 
 
 
1101
  if (empty($this->report['warnlist'])) {
1102
  DUPX_Log::info("No General Notices Found\n");
1103
  }
1138
  {
1139
  $nManager = DUPX_NOTICE_MANAGER::getInstance();
1140
 
1141
+ $orig = file_get_contents(DUPX_Package::getOrigHtaccessPath());
1142
  $new = file_get_contents($GLOBALS['DUPX_ROOT'].'/.htaccess');
1143
 
1144
  $lightBoxContent = '<div class="row-cols-2">'.
1161
  {
1162
  $nManager = DUPX_NOTICE_MANAGER::getInstance();
1163
 
1164
+ if (($orig = file_get_contents(DUPX_Package::getOrigWpConfigPath())) === false) {
1165
  $orig = 'Can read origin wp-config.php file';
1166
  } else {
1167
  $orig = $this->obscureWpConfig($orig);
installer/dup-installer/classes/class.view.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
  /**
3
- *
 
4
  * Standard: PSR-2
5
  * @link http://www.php-fig.org/psr/psr-2 Full Documentation
6
  *
@@ -70,4 +71,24 @@ class DUPX_View_Funcs
70
  {
71
  self::helpLink($section, '<i class="fas fa-question-circle fa-sm"></i>');
72
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
1
  <?php
2
  /**
3
+ * This is the class that manages the functions related to the views
4
+ *
5
  * Standard: PSR-2
6
  * @link http://www.php-fig.org/psr/psr-2 Full Documentation
7
  *
71
  {
72
  self::helpLink($section, '<i class="fas fa-question-circle fa-sm"></i>');
73
  }
74
+
75
+ /**
76
+ * Get badge class attr val from status
77
+ *
78
+ * @param string $status
79
+ * @return string html class attribute
80
+ */
81
+ public static function getBadgeClassFromCheckStatus($status)
82
+ {
83
+ switch ($status) {
84
+ case 'Pass':
85
+ return 'status-badge-pass';
86
+ case 'Fail':
87
+ return 'status-badge-fail';
88
+ case 'Warn':
89
+ return 'status-badge-warn';
90
+ default:
91
+ DUPX_Log::error(sprintf("The arcCheck var has the illegal value %s in switch case", DUPX_Log::varToString($status)));
92
+ }
93
+ }
94
  }
installer/dup-installer/classes/utilities/class.u.php CHANGED
@@ -687,7 +687,7 @@ class DUPX_U
687
  * @return string
688
  */
689
  public static function esc_html( $text ) {
690
- $safe_text = self::wp_check_invalid_utf8( $text );
691
  $safe_text = self::_wp_specialchars( $safe_text, ENT_QUOTES );
692
  /**
693
  * Filters a string cleaned and escaped for output in HTML.
@@ -713,7 +713,7 @@ class DUPX_U
713
  * @return string Escaped text.
714
  */
715
  public static function esc_js( $text ) {
716
- $safe_text = self::wp_check_invalid_utf8( $text );
717
  $safe_text = self::_wp_specialchars( $safe_text, ENT_COMPAT );
718
  $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes( $safe_text ) );
719
  $safe_text = str_replace( "\r", '', $safe_text );
@@ -737,7 +737,7 @@ class DUPX_U
737
  * @return string
738
  */
739
  public static function esc_attr( $text ) {
740
- $safe_text = self::wp_check_invalid_utf8( $text );
741
  $safe_text = self::_wp_specialchars( $safe_text, ENT_QUOTES );
742
  /**
743
  * Filters a string cleaned and escaped for output in an HTML attribute.
@@ -926,56 +926,6 @@ class DUPX_U
926
  return strtr( $string, $translation );
927
  }
928
 
929
- /**
930
- * Checks for invalid UTF8 in a string.
931
- *
932
- * @staticvar bool $is_utf8
933
- * @staticvar bool $utf8_pcre
934
- *
935
- * @param string $string The text which is to be checked.
936
- * @param bool $strip Optional. Whether to attempt to strip out invalid UTF8. Default is false.
937
- * @return string The checked text.
938
- */
939
- public static function wp_check_invalid_utf8( $string, $strip = false ) {
940
- $string = (string) $string;
941
-
942
- if ( 0 === strlen( $string ) ) {
943
- return '';
944
- }
945
-
946
- // Store the site charset as a static to avoid multiple calls to get_option()
947
- static $is_utf8 = null;
948
- if ( ! isset( $is_utf8 ) ) {
949
- // $is_utf8 = in_array( get_option( 'blog_charset' ), array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) );
950
- $is_utf8 = true;
951
- }
952
- if ( ! $is_utf8 ) {
953
- return $string;
954
- }
955
-
956
- // Check for support for utf8 in the installed PCRE library once and store the result in a static
957
- static $utf8_pcre = null;
958
- if ( ! isset( $utf8_pcre ) ) {
959
- $utf8_pcre = @preg_match( '/^./u', 'a' );
960
- }
961
- // We can't demand utf8 in the PCRE installation, so just return the string in those cases
962
- if ( !$utf8_pcre ) {
963
- return $string;
964
- }
965
-
966
- // preg_match fails when it encounters invalid UTF8 in $string
967
- if ( 1 === @preg_match( '/^./us', $string ) ) {
968
- return $string;
969
- }
970
-
971
- // Attempt to strip the bad chars if requested (not recommended)
972
- if ( $strip && function_exists( 'iconv' ) ) {
973
- return iconv( 'utf-8', 'utf-8', $string );
974
- }
975
-
976
- return '';
977
- }
978
-
979
  /**
980
  * Perform a deep string replace operation to ensure the values in $search are no longer present
981
  *
@@ -1541,7 +1491,7 @@ class DUPX_U
1541
  * @return string Sanitized string.
1542
  */
1543
  public static function _sanitize_text_fields( $str, $keep_newlines = false ) {
1544
- $filtered = self::wp_check_invalid_utf8( $str );
1545
 
1546
  if ( strpos($filtered, '<') !== false ) {
1547
  $filtered = self::wp_pre_kses_less_than( $filtered );
687
  * @return string
688
  */
689
  public static function esc_html( $text ) {
690
+ $safe_text = DupLiteSnapLibUtil::wp_check_invalid_utf8( $text );
691
  $safe_text = self::_wp_specialchars( $safe_text, ENT_QUOTES );
692
  /**
693
  * Filters a string cleaned and escaped for output in HTML.
713
  * @return string Escaped text.
714
  */
715
  public static function esc_js( $text ) {
716
+ $safe_text = DupLiteSnapLibUtil::wp_check_invalid_utf8( $text );
717
  $safe_text = self::_wp_specialchars( $safe_text, ENT_COMPAT );
718
  $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes( $safe_text ) );
719
  $safe_text = str_replace( "\r", '', $safe_text );
737
  * @return string
738
  */
739
  public static function esc_attr( $text ) {
740
+ $safe_text = DupLiteSnapLibUtil::wp_check_invalid_utf8( $text );
741
  $safe_text = self::_wp_specialchars( $safe_text, ENT_QUOTES );
742
  /**
743
  * Filters a string cleaned and escaped for output in an HTML attribute.
926
  return strtr( $string, $translation );
927
  }
928
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
929
  /**
930
  * Perform a deep string replace operation to ensure the values in $search are no longer present
931
  *
1491
  * @return string Sanitized string.
1492
  */
1493
  public static function _sanitize_text_fields( $str, $keep_newlines = false ) {
1494
+ $filtered = DupLiteSnapLibUtil::wp_check_invalid_utf8( $str );
1495
 
1496
  if ( strpos($filtered, '<') !== false ) {
1497
  $filtered = self::wp_pre_kses_less_than( $filtered );
installer/dup-installer/ctrls/ctrl.s1.php CHANGED
@@ -126,7 +126,9 @@ $log = "\n--------------------------------------\n";
126
  $log .= "ARCHIVE SETUP\n";
127
  $log .= "--------------------------------------\n";
128
  $log .= str_pad('NAME', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($GLOBALS['FW_PACKAGE_NAME'])."\n";
129
- $log .= str_pad('SIZE', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_U::readableByteSize(@filesize($GLOBALS['FW_PACKAGE_PATH']));
 
 
130
  DUPX_Log::info($log."\n", DUPX_Log::LV_DEFAULT, true);
131
 
132
  DUPX_Log::info('PRE-EXTRACT-CHECKS');
@@ -176,7 +178,7 @@ switch ($post_archive_engine) {
176
  DUPX_Log::error(ERR_ZIPARCHIVE);
177
  }
178
 
179
- if (($$extract_filenamesdupInstallerFolder = DUPX_U::findDupInstallerFolder($archive_path)) === false) {
180
  DUPX_Log::info("findDupInstallerFolder error; set no subfolder");
181
  // if not found set not subfolder
182
  $dupInstallerFolder = '';
126
  $log .= "ARCHIVE SETUP\n";
127
  $log .= "--------------------------------------\n";
128
  $log .= str_pad('NAME', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_Log::varToString($GLOBALS['FW_PACKAGE_NAME'])."\n";
129
+ if (file_exists($GLOBALS['FW_PACKAGE_PATH'])) {
130
+ $log .= str_pad('SIZE', $labelPadSize, '_', STR_PAD_RIGHT).': '.DUPX_U::readableByteSize(@filesize($GLOBALS['FW_PACKAGE_PATH']));
131
+ }
132
  DUPX_Log::info($log."\n", DUPX_Log::LV_DEFAULT, true);
133
 
134
  DUPX_Log::info('PRE-EXTRACT-CHECKS');
178
  DUPX_Log::error(ERR_ZIPARCHIVE);
179
  }
180
 
181
+ if (($dupInstallerFolder = DUPX_U::findDupInstallerFolder($archive_path)) === false) {
182
  DUPX_Log::info("findDupInstallerFolder error; set no subfolder");
183
  // if not found set not subfolder
184
  $dupInstallerFolder = '';
installer/dup-installer/main.installer.php CHANGED
@@ -47,6 +47,7 @@ try {
47
  require_once($GLOBALS['DUPX_INIT'].'/classes/class.db.php');
48
  require_once($GLOBALS['DUPX_INIT'].'/classes/class.http.php');
49
  require_once($GLOBALS['DUPX_INIT'].'/classes/class.server.php');
 
50
  require_once($GLOBALS['DUPX_INIT'].'/classes/config/class.conf.srv.php');
51
  require_once($GLOBALS['DUPX_INIT'].'/classes/utilities/class.u.php');
52
  require_once($GLOBALS['DUPX_INIT'].'/classes/class.view.php');
47
  require_once($GLOBALS['DUPX_INIT'].'/classes/class.db.php');
48
  require_once($GLOBALS['DUPX_INIT'].'/classes/class.http.php');
49
  require_once($GLOBALS['DUPX_INIT'].'/classes/class.server.php');
50
+ require_once($GLOBALS['DUPX_INIT'].'/classes/class.package.php');
51
  require_once($GLOBALS['DUPX_INIT'].'/classes/config/class.conf.srv.php');
52
  require_once($GLOBALS['DUPX_INIT'].'/classes/utilities/class.u.php');
53
  require_once($GLOBALS['DUPX_INIT'].'/classes/class.view.php');
installer/dup-installer/views/view.s1.base.php CHANGED
@@ -7,21 +7,22 @@ defined('ABSPATH') || defined('DUPXABSPATH') || exit;
7
 
8
  require_once($GLOBALS['DUPX_INIT'] . '/classes/config/class.archive.config.php');
9
 
10
- //ARCHIVE FILE
11
- $arcCheck = (file_exists($GLOBALS['FW_PACKAGE_PATH'])) ? 'Pass' : 'Fail';
12
- $arcSize = @filesize($GLOBALS['FW_PACKAGE_PATH']);
13
- $arcSize = is_numeric($arcSize) ? $arcSize : 0;
14
-
15
  $root_path = $GLOBALS['DUPX_ROOT'];
16
- $installer_state = DUPX_InstallerState::getInstance();
17
-
18
- if ($GLOBALS['DUPX_AC']->installSiteOverwriteOn) {
19
- $is_wpconfarc_present = file_exists("{$root_path}/dup-wp-config-arc__{$GLOBALS['DUPX_AC']->package_hash}.txt");
20
  } else {
21
- $outer_root_path = dirname($root_path);
22
- $is_wpconfarc_present = file_exists("{$root_path}/wp-config.php") || (@file_exists("{$outer_root_path}/wp-config.php") && !@file_exists("{$outer_root_path}/wp-settings.php"));
 
 
 
23
  }
 
 
24
 
 
25
  $is_overwrite_mode = ($installer_state->mode === DUPX_InstallerMode::OverwriteInstall);
26
  $is_wordpress = DUPX_Server::isWordPress();
27
  $is_dbonly = $GLOBALS['DUPX_AC']->exportOnlyDB;
@@ -75,7 +76,7 @@ if ($GLOBALS['DUPX_AC']->exportOnlyDB) {
75
  }
76
 
77
  $space_free = @disk_free_space($GLOBALS['DUPX_ROOT']);
78
- $archive_size = filesize($GLOBALS['FW_PACKAGE_PATH']);
79
  $notice['100'] = ($space_free && $archive_size > $space_free)
80
  ? 'Warn'
81
  : 'Good';
@@ -165,15 +166,17 @@ ARCHIVE
165
  ==================================== -->
166
  <div class="hdr-sub1 toggle-hdr" data-type="toggle" data-target="#s1-area-archive-file">
167
  <a id="s1-area-archive-file-link"><i class="fa fa-plus-square"></i>Archive</a>
168
- <div class="<?php echo ( $arcCheck == 'Pass') ? 'status-badge-pass' : 'status-badge-fail'; ?>">
169
- <?php echo ($arcCheck == 'Pass') ? 'Pass' : 'Fail'; ?>
 
 
 
170
  </div>
171
  </div>
172
  <div id="s1-area-archive-file" style="display:none" class="hdr-sub1-area">
173
  <div id="tabs">
174
  <ul>
175
  <li><a href="#tabs-1">Server</a></li>
176
- <!--li><a href="#tabs-2">Cloud</a></li-->
177
  </ul>
178
  <div id="tabs-1">
179
 
@@ -204,27 +207,27 @@ ARCHIVE
204
  <tr>
205
  <td style="vertical-align:top">Status:</td>
206
  <td>
207
- <?php if ($arcCheck != 'Fail') : ?>
208
- <span class="dupx-pass">Archive file successfully detected.</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  <?php else : ?>
210
- <div class="s1-archive-failed-msg">
211
- <b class="dupx-fail">Archive File Not Found!</b><br/>
212
- The installer file and the archive are bound together as a package when the archive is built. They must be downloaded together and used
213
- together at install time. The archive file name should <u>NOT</u> be changed when it is downloaded because the file name is strongly bound
214
- to the installer. When downloading the package files make sure both files are from the same package line in the packages view within the
215
- Duplicator WordPress admin.
216
- <br/><br/>
217
-
218
- The full archive file name must be <u>exactly</u> the same as when it was built (character for character), or the installer will not work properly.
219
- To find out the exact archive name that is bound to this installer open the dup_installer/dup-archive_[HASH].txt file with a text editor and search for
220
- the text "package_name":"[HASH]_archive.zip/daf". Check to see what that value is assigned to and that should be the name of the archive file
221
- placed in the same path as this installer.
222
- <br/><br/>
223
-
224
- If the contents of the archive were manually transferred to this location without the archive file then simply create a temp file named the same
225
- archive bound to this installer and place the file in the same directory as the installer.php file. The temp file will not need to contain any data.
226
- Afterward, refresh this page and continue with the install process.
227
- </div>
228
  <?php endif; ?>
229
  </td>
230
  </tr>
@@ -569,41 +572,37 @@ OPTIONS
569
  <td>
570
  <?php
571
  $options = array();
572
- $options[] = '<option '.($is_wpconfarc_present ? '' : 'disabled').' value="manual">Manual Archive Extraction '.($is_wpconfarc_present ? '' : '*').'</option>';
 
573
  if($archive_config->isZipArchive()){
574
- //ZIP-ARCHIVE
575
- if (!$zip_archive_enabled){
576
- $options[] = '<option value="ziparchive" disabled="true">PHP ZipArchive (not detected on server)</option>';
577
- } elseif ($zip_archive_enabled &&!$shell_exec_zip_enabled) {
578
- $options[] = '<option value="ziparchive" selected="true">PHP ZipArchive</option>';
579
- } else {
580
- $options[] = '<option value="ziparchive">PHP ZipArchive</option>';
581
- }
582
- //SHELL-EXEC UNZIP
583
- if (!$shell_exec_zip_enabled){
584
- $options[] = '<option value="shellexec_unzip" disabled="true">Shell Exec Unzip (not detected on server)</option>';
585
- } else {
586
- $options[] = '<option value="shellexec_unzip" selected="true">Shell Exec Unzip</option>';
587
- }
588
- }
589
- else {
590
- $options[] = '<option value="duparchive" selected="true">DupArchive</option>';
591
  }
592
  $num_selections = count($options);
593
  ?>
594
  <select id="archive_engine" name="archive_engine" size="<?php echo DUPX_U::esc_attr($num_selections); ?>">
595
- <?php
596
- foreach($options as $opt) {
597
- echo $opt;
598
- }
599
- ?>
600
  </select><br/>
601
- <?php if(!$is_wpconfarc_present) :?>
602
  <span class="sub-notes">
603
  *Option enabled when archive has been pre-extracted
604
  <a href="https://snapcreek.com/duplicator/docs/faqs-tech/#faq-installer-015-q" target="_blank">[more info]</a>
605
  </span>
606
- <?php endif ?>
607
  </td>
608
  </tr>
609
  <tr>
7
 
8
  require_once($GLOBALS['DUPX_INIT'] . '/classes/config/class.archive.config.php');
9
 
 
 
 
 
 
10
  $root_path = $GLOBALS['DUPX_ROOT'];
11
+ $is_wpconfarc_present = file_exists(DUPX_Package::getWpconfigArkPath());
12
+ //ARCHIVE FILE
13
+ if (file_exists($GLOBALS['FW_PACKAGE_PATH'])) {
14
+ $arcCheck = 'Pass';
15
  } else {
16
+ if ($is_wpconfarc_present) {
17
+ $arcCheck = 'Warn';
18
+ } else {
19
+ $arcCheck = 'Fail';
20
+ }
21
  }
22
+ $arcSize = file_exists($GLOBALS['FW_PACKAGE_PATH']) ? @filesize($GLOBALS['FW_PACKAGE_PATH']) : 0;
23
+ $arcSize = is_numeric($arcSize) ? $arcSize : 0;
24
 
25
+ $installer_state = DUPX_InstallerState::getInstance();
26
  $is_overwrite_mode = ($installer_state->mode === DUPX_InstallerMode::OverwriteInstall);
27
  $is_wordpress = DUPX_Server::isWordPress();
28
  $is_dbonly = $GLOBALS['DUPX_AC']->exportOnlyDB;
76
  }
77
 
78
  $space_free = @disk_free_space($GLOBALS['DUPX_ROOT']);
79
+ $archive_size = file_exists($GLOBALS['FW_PACKAGE_PATH']) ? filesize($GLOBALS['FW_PACKAGE_PATH']) : 0;
80
  $notice['100'] = ($space_free && $archive_size > $space_free)
81
  ? 'Warn'
82
  : 'Good';
166
  ==================================== -->
167
  <div class="hdr-sub1 toggle-hdr" data-type="toggle" data-target="#s1-area-archive-file">
168
  <a id="s1-area-archive-file-link"><i class="fa fa-plus-square"></i>Archive</a>
169
+ <?php
170
+ $badge = DUPX_View_Funcs::getBadgeClassFromCheckStatus($arcCheck);
171
+ ?>
172
+ <div class="<?php echo $badge;?>">
173
+ <?php echo $arcCheck;?>
174
  </div>
175
  </div>
176
  <div id="s1-area-archive-file" style="display:none" class="hdr-sub1-area">
177
  <div id="tabs">
178
  <ul>
179
  <li><a href="#tabs-1">Server</a></li>
 
180
  </ul>
181
  <div id="tabs-1">
182
 
207
  <tr>
208
  <td style="vertical-align:top">Status:</td>
209
  <td>
210
+ <?php if ($arcCheck == 'Fail' || $arcCheck == 'Warn') : ?>
211
+ <span class="dupx-fail" style="font-style:italic">
212
+ <?php
213
+ if ($arcCheck == 'Warn') {
214
+ ?>
215
+ The archive file named above must be the <u>exact</u> name of the archive file placed in the root path (character for character). But you can proceed with choosing Manual Archive Extraction.
216
+ <?php
217
+ } else {
218
+ ?>
219
+ The archive file named above must be the <u>exact</u> name of the archive file placed in the root path (character for character).
220
+ When downloading the package files make sure both files are from the same package line. <br/><br/>
221
+
222
+ If the contents of the archive were manually transferred to this location without the archive file then simply create a temp file named with
223
+ the exact name shown above and place the file in the same directory as the installer.php file. The temp file will not need to contain any data.
224
+ Afterward, refresh this page and continue with the install process.
225
+ <?php
226
+ }
227
+ ?>
228
+ </span>
229
  <?php else : ?>
230
+ <span class="dupx-pass">Archive file successfully detected.</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  <?php endif; ?>
232
  </td>
233
  </tr>
572
  <td>
573
  <?php
574
  $options = array();
575
+ $extra_attr = ($arcCheck == 'Warn' && $is_wpconfarc_present) ? ' selected="selected"' : '';
576
+ $options[] = '<option '.($is_wpconfarc_present ? '' : 'disabled').$extra_attr.' value="manual">Manual Archive Extraction '.($is_wpconfarc_present ? '' : '*').'</option>';
577
  if($archive_config->isZipArchive()){
578
+ //ZIP-ARCHIVE
579
+ $extra_attr = ('Pass' == $arcCheck && $zip_archive_enabled && !$shell_exec_zip_enabled)
580
+ ? ' selected="selected"'
581
+ : '';
582
+ $extra_attr .= ('Pass' != $arcCheck || !$zip_archive_enabled)
583
+ ? ' disabled="disabled"'
584
+ : '';
585
+ $options[] = '<option value="ziparchive"'.$extra_attr.'>PHP ZipArchive</option>';
586
+
587
+ //SHELL-EXEC UNZIP
588
+ $extra_attr = ('Pass' != $arcCheck || !$shell_exec_zip_enabled) ? ' disabled="disabled"' : '';
589
+ $extra_attr .= ('Pass' == $arcCheck && $shell_exec_zip_enabled) ? ' selected="selected"' : '';
590
+ $options[] = '<option value="shellexec_unzip"'.$extra_attr.'>Shell Exec Unzip</option>';
591
+ } else { // DUPARCHIVE
592
+ $extra_attr = ('Pass' == $arcCheck) ? ' selected="selected"' : 'disabled="disabled"';
593
+ $options[] = '<option value="duparchive"'.$extra_attr.'>DupArchive</option>';
 
594
  }
595
  $num_selections = count($options);
596
  ?>
597
  <select id="archive_engine" name="archive_engine" size="<?php echo DUPX_U::esc_attr($num_selections); ?>">
598
+ <?php echo implode('', $options); ?>
 
 
 
 
599
  </select><br/>
600
+ <?php if (!$is_wpconfarc_present):?>
601
  <span class="sub-notes">
602
  *Option enabled when archive has been pre-extracted
603
  <a href="https://snapcreek.com/duplicator/docs/faqs-tech/#faq-installer-015-q" target="_blank">[more info]</a>
604
  </span>
605
+ <?php endif; ?>
606
  </td>
607
  </tr>
608
  <tr>
installer/installer.tpl CHANGED
@@ -183,17 +183,13 @@ class DUPX_Bootstrap
183
  if ($candidate_count >= 1) {
184
  $candidate_html = "<ol>";
185
  foreach($archive_candidates as $archive_candidate) {
186
- $fineDiffObj = new FineDiff($archive_candidate, $archive_filename, FineDiff::$characterGranularity);
187
- $candidate_html .= '<li class="diff-list"> '.$fineDiffObj->renderDiffToHTML().'</li>';
188
  }
189
  $candidate_html .= "</ol>";
190
  }
191
 
192
- $error = "<style>
193
- .diff-list del { color: red; background: #fdd; text-decoration: none; }
194
- .diff-list ins { color: green; background: #dfd; text-decoration: none; }
195
- </style>
196
- <b>Archive not found!</b> The <i>'Required File'</i> below should be present in the <i>'Extraction Path'</i>. "
197
  . "The archive file name must be the <u>exact</u> name of the archive file placed in the extraction path character for character.<br/><br/> "
198
  . "If the file does not have the correct name then rename it to the <i>'Required File'</i> below. When downloading the package files make "
199
  . "sure both files are from the same package line in the packages view. If the archive is not finished downloading please wait for it to complete.<br/><br/>"
@@ -606,7 +602,39 @@ class DUPX_Bootstrap
606
  return $result;
607
  }
608
 
609
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
610
  /**
611
  * Logs a string to the dup-installer-bootlog__[HASH].txt file
612
  *
@@ -1497,486 +1525,6 @@ class DUPX_CSRF {
1497
  }
1498
  }
1499
 
1500
- /**
1501
- * Copyright (c) 2011 Raymond Hill (http://raymondhill.net/blog/?p=441)
1502
- * @copyright Copyright 2011 (c) Raymond Hill (http://raymondhill.net/blog/?p=441)
1503
- * @link http://www.raymondhill.net/finediff/
1504
- * @version 0.6
1505
- * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
1506
- */
1507
- abstract class FineDiffOp
1508
- {
1509
-
1510
- abstract public function getFromLen();
1511
-
1512
- abstract public function getToLen();
1513
-
1514
- abstract public function getOpcode();
1515
- }
1516
-
1517
- class FineDiffDeleteOp extends FineDiffOp
1518
- {
1519
-
1520
- public function __construct($len)
1521
- {
1522
- $this->fromLen = $len;
1523
- }
1524
-
1525
- public function getFromLen()
1526
- {
1527
- return $this->fromLen;
1528
- }
1529
-
1530
- public function getToLen()
1531
- {
1532
- return 0;
1533
- }
1534
-
1535
- public function getOpcode()
1536
- {
1537
- if ($this->fromLen === 1) {
1538
- return 'd';
1539
- }
1540
- return "d{$this->fromLen}";
1541
- }
1542
- }
1543
-
1544
- class FineDiffInsertOp extends FineDiffOp
1545
- {
1546
-
1547
- public function __construct($text)
1548
- {
1549
- $this->text = $text;
1550
- }
1551
-
1552
- public function getFromLen()
1553
- {
1554
- return 0;
1555
- }
1556
-
1557
- public function getToLen()
1558
- {
1559
- return strlen($this->text);
1560
- }
1561
-
1562
- public function getText()
1563
- {
1564
- return $this->text;
1565
- }
1566
-
1567
- public function getOpcode()
1568
- {
1569
- $to_len = strlen($this->text);
1570
- if ($to_len === 1) {
1571
- return "i:{$this->text}";
1572
- }
1573
- return "i{$to_len}:{$this->text}";
1574
- }
1575
- }
1576
-
1577
- class FineDiffReplaceOp extends FineDiffOp
1578
- {
1579
-
1580
- public function __construct($fromLen, $text)
1581
- {
1582
- $this->fromLen = $fromLen;
1583
- $this->text = $text;
1584
- }
1585
-
1586
- public function getFromLen()
1587
- {
1588
- return $this->fromLen;
1589
- }
1590
-
1591
- public function getToLen()
1592
- {
1593
- return strlen($this->text);
1594
- }
1595
-
1596
- public function getText()
1597
- {
1598
- return $this->text;
1599
- }
1600
-
1601
- public function getOpcode()
1602
- {
1603
- if ($this->fromLen === 1) {
1604
- $del_opcode = 'd';
1605
- } else {
1606
- $del_opcode = "d{$this->fromLen}";
1607
- }
1608
- $to_len = strlen($this->text);
1609
- if ($to_len === 1) {
1610
- return "{$del_opcode}i:{$this->text}";
1611
- }
1612
- return "{$del_opcode}i{$to_len}:{$this->text}";
1613
- }
1614
- }
1615
-
1616
- class FineDiffCopyOp extends FineDiffOp
1617
- {
1618
-
1619
- public function __construct($len)
1620
- {
1621
- $this->len = $len;
1622
- }
1623
-
1624
- public function getFromLen()
1625
- {
1626
- return $this->len;
1627
- }
1628
-
1629
- public function getToLen()
1630
- {
1631
- return $this->len;
1632
- }
1633
-
1634
- public function getOpcode()
1635
- {
1636
- if ($this->len === 1) {
1637
- return 'c';
1638
- }
1639
- return "c{$this->len}";
1640
- }
1641
-
1642
- public function increase($size)
1643
- {
1644
- return $this->len += $size;
1645
- }
1646
- }
1647
-
1648
- class FineDiffOps
1649
- {
1650
-
1651
- public function appendOpcode($opcode, $from, $from_offset, $from_len)
1652
- {
1653
- if ($opcode === 'c') {
1654
- $edits[] = new FineDiffCopyOp($from_len);
1655
- } else if ($opcode === 'd') {
1656
- $edits[] = new FineDiffDeleteOp($from_len);
1657
- } else /* if ( $opcode === 'i' ) */ {
1658
- $edits[] = new FineDiffInsertOp(substr($from, $from_offset, $from_len));
1659
- }
1660
- }
1661
-
1662
- public $edits = array();
1663
-
1664
- }
1665
-
1666
- class FineDiff
1667
- {
1668
-
1669
- public function __construct($from_text = '', $to_text = '', $granularityStack = null)
1670
- {
1671
- // setup stack for generic text documents by default
1672
- $this->granularityStack = $granularityStack ? $granularityStack : FineDiff::$characterGranularity;
1673
- $this->edits = array();
1674
- $this->from_text = $from_text;
1675
- $this->doDiff($from_text, $to_text);
1676
- }
1677
-
1678
- public function getOps()
1679
- {
1680
- return $this->edits;
1681
- }
1682
-
1683
- public function renderDiffToHTML()
1684
- {
1685
- $in_offset = 0;
1686
- ob_start();
1687
- foreach ($this->edits as $edit) {
1688
- $n = $edit->getFromLen();
1689
- if ($edit instanceof FineDiffCopyOp) {
1690
- FineDiff::renderDiffToHTMLFromOpcode('c', $this->from_text, $in_offset, $n);
1691
- } else if ($edit instanceof FineDiffDeleteOp) {
1692
- FineDiff::renderDiffToHTMLFromOpcode('d', $this->from_text, $in_offset, $n);
1693
- } else if ($edit instanceof FineDiffInsertOp) {
1694
- FineDiff::renderDiffToHTMLFromOpcode('i', $edit->getText(), 0, $edit->getToLen());
1695
- } else /* if ( $edit instanceof FineDiffReplaceOp ) */ {
1696
- FineDiff::renderDiffToHTMLFromOpcode('d', $this->from_text, $in_offset, $n);
1697
- FineDiff::renderDiffToHTMLFromOpcode('i', $edit->getText(), 0, $edit->getToLen());
1698
- }
1699
- $in_offset += $n;
1700
- }
1701
- return ob_get_clean();
1702
- }
1703
-
1704
- const characterDelimiters = "";
1705
-
1706
- public static $characterGranularity = array(
1707
- FineDiff::characterDelimiters
1708
- );
1709
-
1710
- private function doDiff($from_text, $to_text)
1711
- {
1712
- $this->last_edit = false;
1713
- $this->stackpointer = 0;
1714
- $this->from_text = $from_text;
1715
- $this->from_offset = 0;
1716
- // can't diff without at least one granularity specifier
1717
- if (empty($this->granularityStack)) {
1718
- return;
1719
- }
1720
- $this->_processGranularity($from_text, $to_text);
1721
- }
1722
-
1723
- private function _processGranularity($from_segment, $to_segment)
1724
- {
1725
- $delimiters = $this->granularityStack[$this->stackpointer++];
1726
- $has_next_stage = $this->stackpointer < count($this->granularityStack);
1727
- foreach (FineDiff::doFragmentDiff($from_segment, $to_segment, $delimiters) as $fragment_edit) {
1728
- // increase granularity
1729
- if ($fragment_edit instanceof FineDiffReplaceOp && $has_next_stage) {
1730
- $this->_processGranularity(
1731
- substr($this->from_text, $this->from_offset, $fragment_edit->getFromLen()), $fragment_edit->getText()
1732
- );
1733
- }
1734
- // fuse copy ops whenever possible
1735
- else if ($fragment_edit instanceof FineDiffCopyOp && $this->last_edit instanceof FineDiffCopyOp) {
1736
- $this->edits[count($this->edits) - 1]->increase($fragment_edit->getFromLen());
1737
- $this->from_offset += $fragment_edit->getFromLen();
1738
- } else {
1739
- /* $fragment_edit instanceof FineDiffCopyOp */
1740
- /* $fragment_edit instanceof FineDiffDeleteOp */
1741
- /* $fragment_edit instanceof FineDiffInsertOp */
1742
- $this->edits[] = $this->last_edit = $fragment_edit;
1743
- $this->from_offset += $fragment_edit->getFromLen();
1744
- }
1745
- }
1746
- $this->stackpointer--;
1747
- }
1748
-
1749
- private static function doFragmentDiff($from_text, $to_text, $delimiters)
1750
- {
1751
- // Empty delimiter means character-level diffing.
1752
- // In such case, use code path optimized for character-level
1753
- // diffing.
1754
- if (empty($delimiters)) {
1755
- return FineDiff::doCharDiff($from_text, $to_text);
1756
- }
1757
-
1758
- $result = array();
1759
-
1760
- // fragment-level diffing
1761
- $from_text_len = strlen($from_text);
1762
- $to_text_len = strlen($to_text);
1763
- $from_fragments = FineDiff::extractFragments($from_text, $delimiters);
1764
- $to_fragments = FineDiff::extractFragments($to_text, $delimiters);
1765
-
1766
- $jobs = array(array(0, $from_text_len, 0, $to_text_len));
1767
-
1768
- $cached_array_keys = array();
1769
-
1770
- while ($job = array_pop($jobs)) {
1771
-
1772
- // get the segments which must be diff'ed
1773
- list($from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end) = $job;
1774
-
1775
- // catch easy cases first
1776
- $from_segment_length = $from_segment_end - $from_segment_start;
1777
- $to_segment_length = $to_segment_end - $to_segment_start;
1778
- if (!$from_segment_length || !$to_segment_length) {
1779
- if ($from_segment_length) {
1780
- $result[$from_segment_start * 4] = new FineDiffDeleteOp($from_segment_length);
1781
- } else if ($to_segment_length) {
1782
- $result[$from_segment_start * 4 + 1] = new FineDiffInsertOp(substr($to_text, $to_segment_start, $to_segment_length));
1783
- }
1784
- continue;
1785
- }
1786
-
1787
- // find longest copy operation for the current segments
1788
- $best_copy_length = 0;
1789
-
1790
- $from_base_fragment_index = $from_segment_start;
1791
-
1792
- $cached_array_keys_for_current_segment = array();
1793
-
1794
- while ($from_base_fragment_index < $from_segment_end) {
1795
- $from_base_fragment = $from_fragments[$from_base_fragment_index];
1796
- $from_base_fragment_length = strlen($from_base_fragment);
1797
- // performance boost: cache array keys
1798
- if (!isset($cached_array_keys_for_current_segment[$from_base_fragment])) {
1799
- if (!isset($cached_array_keys[$from_base_fragment])) {
1800
- $to_all_fragment_indices = $cached_array_keys[$from_base_fragment] = array_keys($to_fragments, $from_base_fragment, true);
1801
- } else {
1802
- $to_all_fragment_indices = $cached_array_keys[$from_base_fragment];
1803
- }
1804
- // get only indices which falls within current segment
1805
- if ($to_segment_start > 0 || $to_segment_end < $to_text_len) {
1806
- $to_fragment_indices = array();
1807
- foreach ($to_all_fragment_indices as $to_fragment_index) {
1808
- if ($to_fragment_index < $to_segment_start) {
1809
- continue;
1810
- }
1811
- if ($to_fragment_index >= $to_segment_end) {
1812
- break;
1813
- }
1814
- $to_fragment_indices[] = $to_fragment_index;
1815
- }
1816
- $cached_array_keys_for_current_segment[$from_base_fragment] = $to_fragment_indices;
1817
- } else {
1818
- $to_fragment_indices = $to_all_fragment_indices;
1819
- }
1820
- } else {
1821
- $to_fragment_indices = $cached_array_keys_for_current_segment[$from_base_fragment];
1822
- }
1823
- // iterate through collected indices
1824
- foreach ($to_fragment_indices as $to_base_fragment_index) {
1825
- $fragment_index_offset = $from_base_fragment_length;
1826
- // iterate until no more match
1827
- for (;;) {
1828
- $fragment_from_index = $from_base_fragment_index + $fragment_index_offset;
1829
- if ($fragment_from_index >= $from_segment_end) {
1830
- break;
1831
- }
1832
- $fragment_to_index = $to_base_fragment_index + $fragment_index_offset;
1833
- if ($fragment_to_index >= $to_segment_end) {
1834
- break;
1835
- }
1836
- if ($from_fragments[$fragment_from_index] !== $to_fragments[$fragment_to_index]) {
1837
- break;
1838
- }
1839
- $fragment_length = strlen($from_fragments[$fragment_from_index]);
1840
- $fragment_index_offset += $fragment_length;
1841
- }
1842
- if ($fragment_index_offset > $best_copy_length) {
1843
- $best_copy_length = $fragment_index_offset;
1844
- $best_from_start = $from_base_fragment_index;
1845
- $best_to_start = $to_base_fragment_index;
1846
- }
1847
- }
1848
- $from_base_fragment_index += strlen($from_base_fragment);
1849
- // If match is larger than half segment size, no point trying to find better
1850
- // TODO: Really?
1851
- if ($best_copy_length >= $from_segment_length / 2) {
1852
- break;
1853
- }
1854
- // no point to keep looking if what is left is less than
1855
- // current best match
1856
- if ($from_base_fragment_index + $best_copy_length >= $from_segment_end) {
1857
- break;
1858
- }
1859
- }
1860
-
1861
- if ($best_copy_length) {
1862
- $jobs[] = array($from_segment_start, $best_from_start, $to_segment_start, $best_to_start);
1863
- $result[$best_from_start * 4 + 2] = new FineDiffCopyOp($best_copy_length);
1864
- $jobs[] = array($best_from_start + $best_copy_length, $from_segment_end, $best_to_start + $best_copy_length, $to_segment_end);
1865
- } else {
1866
- $result[$from_segment_start * 4] = new FineDiffReplaceOp($from_segment_length, substr($to_text, $to_segment_start, $to_segment_length));
1867
- }
1868
- }
1869
-
1870
- ksort($result, SORT_NUMERIC);
1871
- return array_values($result);
1872
- }
1873
-
1874
- private static function doCharDiff($from_text, $to_text)
1875
- {
1876
- $result = array();
1877
- $jobs = array(array(0, strlen($from_text), 0, strlen($to_text)));
1878
- while ($job = array_pop($jobs)) {
1879
- // get the segments which must be diff'ed
1880
- list($from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end) = $job;
1881
- $from_segment_len = $from_segment_end - $from_segment_start;
1882
- $to_segment_len = $to_segment_end - $to_segment_start;
1883
-
1884
- // catch easy cases first
1885
- if (!$from_segment_len || !$to_segment_len) {
1886
- if ($from_segment_len) {
1887
- $result[$from_segment_start * 4 + 0] = new FineDiffDeleteOp($from_segment_len);
1888
- } else if ($to_segment_len) {
1889
- $result[$from_segment_start * 4 + 1] = new FineDiffInsertOp(substr($to_text, $to_segment_start, $to_segment_len));
1890
- }
1891
- continue;
1892
- }
1893
- if ($from_segment_len >= $to_segment_len) {
1894
- $copy_len = $to_segment_len;
1895
- while ($copy_len) {
1896
- $to_copy_start = $to_segment_start;
1897
- $to_copy_start_max = $to_segment_end - $copy_len;
1898
- while ($to_copy_start <= $to_copy_start_max) {
1899
- $from_copy_start = strpos(substr($from_text, $from_segment_start, $from_segment_len), substr($to_text, $to_copy_start, $copy_len));
1900
- if ($from_copy_start !== false) {
1901
- $from_copy_start += $from_segment_start;
1902
- break 2;
1903
- }
1904
- $to_copy_start++;
1905
- }
1906
- $copy_len--;
1907
- }
1908
- } else {
1909
- $copy_len = $from_segment_len;
1910
- while ($copy_len) {
1911
- $from_copy_start = $from_segment_start;
1912
- $from_copy_start_max = $from_segment_end - $copy_len;
1913
- while ($from_copy_start <= $from_copy_start_max) {
1914
- $to_copy_start = strpos(substr($to_text, $to_segment_start, $to_segment_len), substr($from_text, $from_copy_start, $copy_len));
1915
- if ($to_copy_start !== false) {
1916
- $to_copy_start += $to_segment_start;
1917
- break 2;
1918
- }
1919
- $from_copy_start++;
1920
- }
1921
- $copy_len--;
1922
- }
1923
- }
1924
- // match found
1925
- if ($copy_len) {
1926
- $jobs[] = array($from_segment_start, $from_copy_start, $to_segment_start, $to_copy_start);
1927
- $result[$from_copy_start * 4 + 2] = new FineDiffCopyOp($copy_len);
1928
- $jobs[] = array($from_copy_start + $copy_len, $from_segment_end, $to_copy_start + $copy_len, $to_segment_end);
1929
- }
1930
- // no match, so delete all, insert all
1931
- else {
1932
- $result[$from_segment_start * 4] = new FineDiffReplaceOp($from_segment_len, substr($to_text, $to_segment_start, $to_segment_len));
1933
- }
1934
- }
1935
- ksort($result, SORT_NUMERIC);
1936
- return array_values($result);
1937
- }
1938
-
1939
- private static function extractFragments($text, $delimiters)
1940
- {
1941
- // special case: split into characters
1942
- if (empty($delimiters)) {
1943
- $chars = str_split($text, 1);
1944
- $chars[strlen($text)] = '';
1945
- return $chars;
1946
- }
1947
- $fragments = array();
1948
- $start = $end = 0;
1949
- for (;;) {
1950
- $end += strcspn($text, $delimiters, $end);
1951
- $end += strspn($text, $delimiters, $end);
1952
- if ($end === $start) {
1953
- break;
1954
- }
1955
- $fragments[$start] = substr($text, $start, $end - $start);
1956
- $start = $end;
1957
- }
1958
- $fragments[$start] = '';
1959
- return $fragments;
1960
- }
1961
-
1962
- private static function renderDiffToHTMLFromOpcode($opcode, $from, $from_offset, $from_len)
1963
- {
1964
- if ($opcode === 'c') {
1965
- echo htmlspecialchars(substr($from, $from_offset, $from_len));
1966
- } else if ($opcode === 'd') {
1967
- $deletion = substr($from, $from_offset, $from_len);
1968
- if (strcspn($deletion, " \n\r") === 0) {
1969
- $deletion = str_replace(array("\n", "\r"), array('\n', '\r'), $deletion);
1970
- }
1971
- echo '<del>', htmlspecialchars($deletion), '</del>';
1972
- } else /* if ( $opcode === 'i' ) */ {
1973
- echo '<ins>', htmlspecialchars(substr($from, $from_offset, $from_len)), '</ins>';
1974
- }
1975
- }
1976
- }
1977
-
1978
- /*** CLASS DEFINITION END ***/
1979
-
1980
  try {
1981
  $boot = new DUPX_Bootstrap();
1982
  $boot_error = $boot->run();
183
  if ($candidate_count >= 1) {
184
  $candidate_html = "<ol>";
185
  foreach($archive_candidates as $archive_candidate) {
186
+ $candidate_html .= '<li class="diff-list"> '.$this->compareStrings($archive_filename, $archive_candidate).'</li>';
 
187
  }
188
  $candidate_html .= "</ol>";
189
  }
190
 
191
+ $error = "<style>.diff-list font { font-weight: bold; }</style>"
192
+ . "<b>Archive not found!</b> The <i>'Required File'</i> below should be present in the <i>'Extraction Path'</i>. "
 
 
 
193
  . "The archive file name must be the <u>exact</u> name of the archive file placed in the extraction path character for character.<br/><br/> "
194
  . "If the file does not have the correct name then rename it to the <i>'Required File'</i> below. When downloading the package files make "
195
  . "sure both files are from the same package line in the packages view. If the archive is not finished downloading please wait for it to complete.<br/><br/>"
602
  return $result;
603
  }
604
 
605
+ /**
606
+ * Compare two strings and return html text which represts diff
607
+ *
608
+ * @param string $oldString
609
+ * @param string $newString
610
+ *
611
+ * @return string Returns html text
612
+ */
613
+ private function compareStrings($oldString, $newString) {
614
+ $ret = '';
615
+ for($i=0; isset($oldString[$i]) || isset($newString[$i]); $i++) {
616
+ if(!isset($oldString[$i])) {
617
+ $ret .= '<font color="red">' . $newString[$i] . '</font>';
618
+ continue;
619
+ }
620
+ for($char=0; isset($oldString[$i]{$char}) || isset($newString[$i]{$char}); $char++) {
621
+
622
+ if(!isset($oldString[$i]{$char})) {
623
+ $ret .= '<font color="red">' . substr($newString[$i], $char) . '</font>';
624
+ break;
625
+ } elseif(!isset($newString[$i]{$char})) {
626
+ break;
627
+ }
628
+
629
+ if(ord($oldString[$i]{$char}) != ord($newString[$i]{$char}))
630
+ $ret .= '<font color="red">' . $newString[$i]{$char} . '</font>';
631
+ else
632
+ $ret .= $newString[$i]{$char};
633
+ }
634
+ }
635
+ return $ret;
636
+ }
637
+
638
  /**
639
  * Logs a string to the dup-installer-bootlog__[HASH].txt file
640
  *
1525
  }
1526
  }
1527
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1528
  try {
1529
  $boot = new DUPX_Bootstrap();
1530
  $boot_error = $boot->run();
lib/dup_archive/daws/daws.php CHANGED
@@ -228,7 +228,9 @@ class DAWS
228
  $retVal->pass = true;
229
  $retVal->status = $this->getStatus($expandState);
230
  } else if ($action == 'cancel') {
231
- DupLiteSnapLibIOU::touch(DAWSConstants::$PROCESS_CANCEL_FILEPATH);
 
 
232
  $retVal->pass = true;
233
  } else {
234
  throw new Exception('Unknown command.');
228
  $retVal->pass = true;
229
  $retVal->status = $this->getStatus($expandState);
230
  } else if ($action == 'cancel') {
231
+ if (!DupLiteSnapLibIOU::touch(DAWSConstants::$PROCESS_CANCEL_FILEPATH)) {
232
+ throw new Exception("Couldn't update time on ".DAWSConstants::$PROCESS_CANCEL_FILEPATH);
233
+ }
234
  $retVal->pass = true;
235
  } else {
236
  throw new Exception('Unknown command.');
lib/fileops/class.fileops.constants.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined("ABSPATH") && !defined("DUPXABSPATH"))
3
+ die("");
4
+ /*
5
+ * To change this license header, choose License Headers in Project Properties.
6
+ * To change this template file, choose Tools | Templates
7
+ * and open the template in the editor.
8
+ */
9
+
10
+ class FileOpsConstants
11
+ {
12
+ public static $FILEOPS_ROOT;
13
+
14
+ public static $DEFAULT_WORKER_TIME = 18;
15
+
16
+ public static $LIB_DIR;
17
+
18
+ public static $PROCESS_LOCK_FILEPATH;
19
+ public static $PROCESS_CANCEL_FILEPATH;
20
+ public static $KEY_FILEPATH;
21
+
22
+ public static $LOG_FILEPATH;
23
+
24
+ public static function init() {
25
+
26
+ self::$FILEOPS_ROOT = dirname(__FILE__);
27
+
28
+ self::$LIB_DIR = self::$FILEOPS_ROOT.'/..';
29
+
30
+ self::$PROCESS_LOCK_FILEPATH = self::$FILEOPS_ROOT.'/fileops_lock.bin';
31
+ self::$PROCESS_CANCEL_FILEPATH = self::$FILEOPS_ROOT.'/fileops_cancel.bin';
32
+ self::$LOG_FILEPATH = dirname(__FILE__).'/fileops.log';
33
+ }
34
+ }
35
+
36
+ FileOpsConstants::init();
lib/fileops/class.fileops.state.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined("ABSPATH") && !defined("DUPXABSPATH"))
3
+ die("");
4
+ /*
5
+ * To change this license header, choose License Headers in Project Properties.
6
+ * To change this template file, choose Tools | Templates
7
+ * and open the template in the editor.
8
+ */
9
+
10
+ class FileOpsState
11
+ {
12
+ public static $instance = null;
13
+
14
+ private $workerTime;
15
+ private $directories;
16
+ private $throttleDelay;
17
+ private $excludedDirectories;
18
+ private $excludedFiles;
19
+ private $working = false;
20
+
21
+ const StateFilename = 'state.json';
22
+
23
+ public static function getInstance($reset = false)
24
+ {
25
+ if ((self::$instance == null) && (!$reset)) {
26
+ $stateFilepath = dirname(__FILE__).'/'.self::StateFilename;
27
+
28
+ self::$instance = new FileOpsState();
29
+
30
+ if (file_exists($stateFilepath)) {
31
+ $stateHandle = DupProSnapLibIOU::fopen($stateFilepath, 'rb');
32
+
33
+ DupProSnapLibIOU::flock($stateHandle, LOCK_EX);
34
+
35
+ $stateString = fread($stateHandle, filesize($stateFilepath));
36
+
37
+ $data = json_decode($stateString);
38
+
39
+ self::$instance->setFromData($data);
40
+
41
+ // self::$instance->fileRenames = (array)(self::$instance->fileRenames);
42
+
43
+ DupProSnapLibIOU::flock($stateHandle, LOCK_UN);
44
+
45
+ DupProSnapLibIOU::fclose($stateHandle);
46
+ } else {
47
+ $reset = true;
48
+ }
49
+ }
50
+
51
+ if ($reset) {
52
+ self::$instance = new FileOpsState();
53
+
54
+ self::$instance->reset();
55
+ }
56
+
57
+ return self::$instance;
58
+ }
59
+
60
+ private function setFromData($data)
61
+ {
62
+ // $this->currentFileHeader = $data->currentFileHeader;
63
+ }
64
+
65
+ public function reset()
66
+ {
67
+ $stateFilepath = dirname(__FILE__).'/'.self::StateFilename;
68
+
69
+ $stateHandle = DupProSnapLibIOU::fopen($stateFilepath, 'w');
70
+
71
+ DupProSnapLibIOU::flock($stateHandle, LOCK_EX);
72
+
73
+ $this->initMembers();
74
+
75
+ DupProSnapLibIOU::fwrite($stateHandle, json_encode($this));
76
+
77
+ DupProSnapLibIOU::fclose($stateHandle);
78
+ }
79
+
80
+ public function save()
81
+ {
82
+ $stateFilepath = dirname(__FILE__).'/'.self::StateFilename;
83
+
84
+ $stateHandle = DupProSnapLibIOU::fopen($stateFilepath, 'w');
85
+
86
+ DupProSnapLibIOU::flock($stateHandle, LOCK_EX);
87
+
88
+ DupArchiveUtil::tlog("saving state");
89
+ DupProSnapLibIOU::fwrite($stateHandle, json_encode($this));
90
+
91
+ DupProSnapLibIOU::fclose($stateHandle);
92
+ }
93
+
94
+ private function initMembers()
95
+ {
96
+ // $this->currentFileHeader = null;
97
+
98
+ }
99
+ }
lib/fileops/class.fileops.u.delete.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined("ABSPATH") && !defined("DUPXABSPATH"))
3
+ die("");
4
+ /*
5
+ * To change this license header, choose License Headers in Project Properties.
6
+ * To change this template file, choose Tools | Templates
7
+ * and open the template in the editor.
8
+ */
9
+
10
+ class FileOpsDeleteConfig
11
+ {
12
+ public $workerTime;
13
+ public $directories;
14
+ public $throttleDelayInUs;
15
+ public $excludedDirectories;
16
+ public $excludedFiles;
17
+ public $fileLock;
18
+
19
+ }
20
+
21
+ class FileOpsDeleteU
22
+ {
23
+
24
+ // Move $directories, $files, $excludedFiles to $destination directory. Throws exception if it can't do something and $exceptionOnFaiure is true
25
+ // $exludedFiles can include * wildcard
26
+ // returns: array with list of failures
27
+ public static function delete($currentDirectory, &$deleteConfig)
28
+ {
29
+ $timedOut = false;
30
+
31
+ if (is_dir($currentDirectory)) {
32
+ $objects = scandir($currentDirectory);
33
+ foreach ($objects as $object) {
34
+ if ($object != "." && $object != "..") {
35
+ if (is_dir($currentDirectory."/".$object)) {
36
+ self::delete($currentDirectory."/".$object, $deleteConfig);
37
+ }
38
+ else {
39
+ @unlink($currentDirectory."/".$object);
40
+ }
41
+ }
42
+ }
43
+ @rmdir($currentDirectory);
44
+ }
45
+ }
46
+ }
lib/fileops/class.fileops.u.move.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined("ABSPATH") && !defined("DUPXABSPATH"))
3
+ die("");
4
+ /*
5
+ * To change this license header, choose License Headers in Project Properties.
6
+ * To change this template file, choose Tools | Templates
7
+ * and open the template in the editor.
8
+ */
9
+
10
+ class FileOpsMoveU
11
+ {
12
+ // Move $directories, $files, $excludedFiles to $destination directory. Throws exception if it can't do something and $exceptionOnFaiure is true
13
+ // $exludedFiles can include * wildcard
14
+ // returns: array with list of failures
15
+ public static function move($directories, $files, $excludedFiles, $destination)
16
+ {
17
+ DupProSnapLibLogger::logObject('directories', $directories);
18
+ DupProSnapLibLogger::logObject('files', $files);
19
+ DupProSnapLibLogger::logObject('excludedFiles', $excludedFiles);
20
+ DupProSnapLibLogger::logObject('destination', $destination);
21
+
22
+ $failures = array();
23
+
24
+
25
+ $directoryFailures = DupProSnapLibIOU::massMove($directories, $destination, null, false);
26
+ DupProSnapLibLogger::log('done directories');
27
+ $fileFailures = DupProSnapLibIOU::massMove($files, $destination, $excludedFiles, false);
28
+ DupProSnapLibLogger::log('done files');
29
+ return array_merge($directoryFailures, $fileFailures);
30
+ }
31
+ }
lib/fileops/fileops.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** Absolute path to the DAWS directory. - necessary for php protection */
3
+ if ( !defined('ABSPATH') )
4
+ define('ABSPATH', dirname(__FILE__) . '/');
5
+ if (DupProSnapLibUtil::wp_is_ini_value_changeable('display_errors'))
6
+ @ini_set('display_errors', 1);
7
+ error_reporting(E_ALL);
8
+ set_error_handler("terminate_missing_variables");
9
+
10
+
11
+ require_once(dirname(__FILE__) . '/class.fileops.constants.php');
12
+ require_once(dirname(__FILE__) . '/class.fileops.u.move.php');
13
+
14
+ require_once(FileOpsConstants::$LIB_DIR . '/snaplib/snaplib.all.php');
15
+
16
+
17
+ class FileOps
18
+ {
19
+ private $lock_handle = null;
20
+
21
+ function __construct()
22
+ {
23
+ date_default_timezone_set('UTC'); // Some machines don’t have this set so just do it here.
24
+
25
+ DupProSnapLibLogger::init(FileOpsConstants::$LOG_FILEPATH);
26
+ }
27
+
28
+ public function processRequest()
29
+ {
30
+ try {
31
+ DupProSnapLibLogger::clearLog();
32
+ /* @var $state FileOpsState */
33
+ DupProSnapLibLogger::log('process request');
34
+ $retVal = new StdClass();
35
+
36
+ $retVal->pass = false;
37
+
38
+
39
+ if (isset($_REQUEST['action'])) {
40
+ //$params = $_REQUEST;
41
+ $params = array();
42
+ DupProSnapLibLogger::logObject('REQUEST', $_REQUEST);
43
+
44
+ foreach($_REQUEST as $key => $value)
45
+ {
46
+ $params[$key] = json_decode($value, true);
47
+ }
48
+
49
+ } else {
50
+ $json = file_get_contents('php://input');
51
+ DupProSnapLibLogger::logObject('json1', $json);
52
+ $params = json_decode($json, true);
53
+ DupProSnapLibLogger::logObject('json2', $json);
54
+ }
55
+
56
+ DupProSnapLibLogger::logObject('params', $params);
57
+ DupProSnapLibLogger::logObject('keys', array_keys($params));
58
+
59
+ $action = $params['action'];
60
+
61
+ if ($action == 'deltree') {
62
+
63
+ DupProSnapLibLogger::log('deltree');
64
+
65
+
66
+
67
+ $config = DeleteConfig();
68
+
69
+ $config->workerTime = DupProSnapLibUtil::GetArrayValue($params, 'worker_time');
70
+ $config->directories = DupProSnapLibUtil::getArrayValue($params, 'directories');
71
+ $config->throttleDelayInUs = DupProSnapLibUtil::getArrayValue($params, 'throttleDelay', false, 0) * 1000000;
72
+ $config->excludedDirectories = DupProSnapLibUtil::getArrayValue($params, 'excluded_directories', false, array());
73
+ $config->excludedFiles = DupProSnapLibUtil::getArrayValue($params, 'excluded_files', false, array());
74
+ $config->fileLock = DupProSnapLibUtil::GetArrayValue($params, 'fileLock');
75
+
76
+ DupProSnapLibLogger::logObject('Config', $config);
77
+
78
+
79
+
80
+ // TODO use appropriate lock type
81
+ DupProSnapLibIOU::flock($this->lock_handle, LOCK_EX);
82
+
83
+ $this->lock_handle = DupProSnapLibIOU::fopen(FileOpsConstants::$PROCESS_LOCK_FILEPATH, 'c+');
84
+
85
+
86
+
87
+
88
+
89
+ DupProSnapLibIOU::flock($this->lock_handle, LOCK_UN);
90
+
91
+ $retVal->pass = true;
92
+ $retVal->status = new stdClass;
93
+ //todo $retVal->status->errors = $moveErrors; // RSR TODO ensure putting right thing in here
94
+
95
+ } else if($action === 'move_files') {
96
+
97
+ $directories = DupProSnapLibUtil::getArrayValue($params, 'directories', false, array());
98
+ $files = DupProSnapLibUtil::getArrayValue($params, 'files', false, array());
99
+ $excludedFiles = DupProSnapLibUtil::getArrayValue($params, 'excluded_files', false, array());
100
+ $destination = DupProSnapLibUtil::getArrayValue($params, 'destination');
101
+
102
+ DupProSnapLibLogger::log('before move');
103
+ $moveErrors = FileOpsMoveU::move($directories, $files, $excludedFiles, $destination);
104
+
105
+ DupProSnapLibLogger::log('after move');
106
+
107
+ $retVal->pass = true;
108
+ $retVal->status = new stdClass();
109
+ $retVal->status->errors = $moveErrors; // RSR TODO ensure putting right thing in here
110
+ }
111
+ else {
112
+
113
+ throw new Exception('Unknown command.');
114
+ }
115
+
116
+ session_write_close();
117
+
118
+ } catch (Exception $ex) {
119
+ $error_message = "Error Encountered:" . $ex->getMessage() . '<br/>' . $ex->getTraceAsString();
120
+
121
+ DupProSnapLibLogger::log($error_message);
122
+
123
+ $retVal->pass = false;
124
+ $retVal->error = $error_message;
125
+ }
126
+
127
+ DupProSnapLibLogger::logObject("before json encode retval", $retVal);
128
+
129
+ $jsonRetVal = json_encode($retVal);
130
+ DupProSnapLibLogger::logObject("json encoded retval", $jsonRetVal);
131
+ echo $jsonRetVal;
132
+ }
133
+ }
134
+
135
+ function generateCallTrace()
136
+ {
137
+ $e = new Exception();
138
+ $trace = explode("\n", $e->getTraceAsString());
139
+ // reverse array to make steps line up chronologically
140
+ $trace = array_reverse($trace);
141
+ array_shift($trace); // remove {main}
142
+ array_pop($trace); // remove call to this method
143
+ $length = count($trace);
144
+ $result = array();
145
+
146
+ for ($i = 0; $i < $length; $i++) {
147
+ $result[] = ($i + 1) . ')' . substr($trace[$i], strpos($trace[$i], ' ')); // replace '#someNum' with '$i)', set the right ordering
148
+ }
149
+
150
+ return "\t" . implode("\n\t", $result);
151
+ }
152
+
153
+ function terminate_missing_variables($errno, $errstr, $errfile, $errline)
154
+ {
155
+ // echo "<br/>ERROR: $errstr $errfile $errline<br/>";
156
+ // if (($errno == E_NOTICE) and ( strstr($errstr, "Undefined variable"))) die("$errstr in $errfile line $errline");
157
+
158
+
159
+ DupProSnapLibLogger::log("ERROR $errno, $errstr, {$errfile}:{$errline}");
160
+ DupProSnapLibLogger::log(generateCallTrace());
161
+ // DaTesterLogging::clearLog();
162
+
163
+ // exit(1);
164
+ //return false; // Let the PHP error handler handle all the rest
165
+ }
166
+
167
+ $fileOps = new FileOps();
168
+
169
+ $fileOps->processRequest();
lib/fileops/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ //silent
lib/snaplib/class.snaplib.u.io.php CHANGED
@@ -152,13 +152,18 @@ if (!class_exists('DupLiteSnapLibIOU', false)) {
152
 
153
  public static function touch($filepath, $time = null)
154
  {
155
- if ($time === null) {
156
- $time = time();
 
 
 
 
157
  }
158
 
159
- if (@touch($filepath, $time) === null) {
160
- throw new Exception("Couldn't update time on {$filepath}");
161
  }
 
162
  }
163
 
164
  public static function rmdir($dirname, $mustExist = false)
152
 
153
  public static function touch($filepath, $time = null)
154
  {
155
+ if (!function_exists('touch')) {
156
+ return false;
157
+ }
158
+
159
+ if (!is_writeable($filepath)) {
160
+ return false;
161
  }
162
 
163
+ if ($time === null) {
164
+ $time = time();
165
  }
166
+ return @touch($filepath, $time);
167
  }
168
 
169
  public static function rmdir($dirname, $mustExist = false)
lib/snaplib/class.snaplib.u.util.php CHANGED
@@ -433,7 +433,6 @@ if (!class_exists('DupLiteSnapLibUtil', false)) {
433
  *
434
  * @since 2.8.0
435
  *
436
- * @staticvar bool $is_utf8
437
  * @staticvar bool $utf8_pcre
438
  *
439
  * @param string $string The text which is to be checked.
@@ -448,15 +447,6 @@ if (!class_exists('DupLiteSnapLibUtil', false)) {
448
  return '';
449
  }
450
 
451
- // Store the site charset as a static to avoid multiple calls to get_option()
452
- static $is_utf8 = null;
453
- if (!isset($is_utf8)) {
454
- $is_utf8 = in_array(get_option('blog_charset'), array('utf8', 'utf-8', 'UTF8', 'UTF-8'));
455
- }
456
- if (!$is_utf8) {
457
- return $string;
458
- }
459
-
460
  // Check for support for utf8 in the installed PCRE library once and store the result in a static
461
  static $utf8_pcre = null;
462
  if (!isset($utf8_pcre)) {
433
  *
434
  * @since 2.8.0
435
  *
 
436
  * @staticvar bool $utf8_pcre
437
  *
438
  * @param string $string The text which is to be checked.
447
  return '';
448
  }
449
 
 
 
 
 
 
 
 
 
 
450
  // Check for support for utf8 in the installed PCRE library once and store the result in a static
451
  static $utf8_pcre = null;
452
  if (!isset($utf8_pcre)) {
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: migration, backup, restore, move, migrate, duplicate, transfer, clone, aut
4
  Requires at least: 4.0
5
  Tested up to: 5.2
6
  Requires PHP: 5.2.17
7
- Stable tag: 1.3.16
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.
4
  Requires at least: 4.0
5
  Tested up to: 5.2
6
  Requires PHP: 5.2.17
7
+ Stable tag: 1.3.18
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.