Duplicator – WordPress Migration Plugin - Version 1.1.34

Version Description

Download this release

Release Info

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

Code changes from version 1.1.32 to 1.1.34

Files changed (80) hide show
  1. assets/img/paypal.png +0 -0
  2. assets/img/perks_bluehost.png +0 -0
  3. assets/img/perks_ethemes.png +0 -0
  4. assets/img/perks_inmotion.png +0 -0
  5. assets/img/perks_managewp.png +0 -0
  6. assets/img/perks_maxcdn.png +0 -0
  7. assets/img/perks_ninjaforms.png +0 -0
  8. assets/img/perks_optinmonster.png +0 -0
  9. classes/{logging.php → class.logging.php} +2 -2
  10. classes/{settings.php → class.settings.php} +0 -0
  11. classes/package.archive.php +0 -316
  12. classes/package.archive.zip.php +0 -181
  13. classes/package.database.php +0 -416
  14. classes/package.installer.php +0 -203
  15. classes/package.php +0 -547
  16. classes/package/class.pack.archive.filters.php +80 -0
  17. classes/package/class.pack.archive.php +274 -0
  18. classes/package/class.pack.archive.zip.php +159 -0
  19. classes/package/class.pack.database.php +375 -0
  20. classes/package/class.pack.installer.php +214 -0
  21. classes/package/class.pack.php +622 -0
  22. classes/scan.validator.php +0 -93
  23. classes/server.php +0 -200
  24. classes/ui.php +0 -92
  25. classes/ui/class.dialog.php +0 -165
  26. classes/ui/class.ui.dialog.php +200 -0
  27. classes/ui/class.ui.notice.php +51 -0
  28. classes/ui/class.ui.viewstate.php +72 -0
  29. classes/ui/ui.php +0 -92
  30. classes/utilities/class.db.php +117 -0
  31. classes/utilities/class.scan.check.php +146 -0
  32. classes/utilities/class.server.php +204 -0
  33. classes/utilities/class.util.php +481 -0
  34. classes/utility.php +0 -393
  35. ctrls/ctrl.base.php +2 -2
  36. ctrls/ctrl.package.php +27 -28
  37. ctrls/ctrl.tools.php +9 -6
  38. ctrls/ctrl.ui.php +4 -4
  39. debug/main.php +1 -1
  40. define.php +1 -1
  41. duplicator.php +21 -37
  42. installer/build/ajax.step1.php +114 -94
  43. installer/build/ajax.step2.php +27 -27
  44. installer/build/assets/inc.css.php +1 -1
  45. installer/build/classes/class.conf.srv.php +0 -77
  46. installer/build/classes/class.conf.wp.php +0 -113
  47. installer/build/classes/class.engine.php +441 -0
  48. installer/build/classes/class.logging.php +29 -10
  49. installer/build/classes/class.serializer.php +0 -452
  50. installer/build/classes/class.utils.php +0 -376
  51. installer/build/classes/config/class.conf.srv.php +87 -0
  52. installer/build/classes/config/class.conf.wp.php +122 -0
  53. installer/build/classes/util/class.db.php +194 -0
  54. installer/build/classes/util/class.utils.php +312 -0
  55. installer/build/main.installer.php +5 -2
  56. installer/build/view.step2.php +2 -2
  57. readme.txt +1 -1
  58. uninstall.php +4 -4
  59. views/help/about.php +1 -1
  60. views/help/gopro.php +1 -1
  61. views/help/help.php +1 -1
  62. views/help/perks.php +0 -183
  63. views/packages/controller.php +1 -1
  64. views/packages/details/controller.php +2 -2
  65. views/packages/details/detail.php +6 -4
  66. views/packages/main/controller.php +1 -1
  67. views/packages/main/new1.inc.form.php +6 -6
  68. views/packages/main/new1.setup.php +8 -9
  69. views/packages/main/new2.scan.php +12 -14
  70. views/packages/main/new3.build.php +1 -2
  71. views/packages/main/packages.php +17 -17
  72. views/settings/controller.php +1 -1
  73. views/settings/general.php +4 -4
  74. views/tools/cleanup.php +8 -8
  75. views/tools/controller.php +2 -2
  76. views/tools/diagnostics/inc.data.php +5 -5
  77. views/tools/diagnostics/inc.settings.php +16 -12
  78. views/tools/diagnostics/inc.validator.php +10 -10
  79. views/tools/diagnostics/main.php +1 -1
  80. views/tools/logging.php +1 -1
assets/img/paypal.png DELETED
Binary file
assets/img/perks_bluehost.png DELETED
Binary file
assets/img/perks_ethemes.png DELETED
Binary file
assets/img/perks_inmotion.png DELETED
Binary file
assets/img/perks_managewp.png DELETED
Binary file
assets/img/perks_maxcdn.png DELETED
Binary file
assets/img/perks_ninjaforms.png DELETED
Binary file
assets/img/perks_optinmonster.png DELETED
Binary file
classes/{logging.php → class.logging.php} RENAMED
@@ -34,12 +34,12 @@ class DUP_Log {
34
  * @param string $msg The message to log
35
  *
36
  * REPLACE TO DEBUG: Memory consuption as script runs
37
- * $results = DUP_Util::ByteSize(memory_get_peak_usage(true)) . "\t" . $msg;
38
  * @fwrite(self::$logFileHandle, "{$results} \n");
39
  */
40
  static public function Info($msg) {
41
  @fwrite(self::$logFileHandle, "{$msg} \n");
42
- //$results = DUP_Util::ByteSize(memory_get_usage(true)) . "\t" . $msg;
43
  //@fwrite(self::$logFileHandle, "{$results} \n");
44
  }
45
 
34
  * @param string $msg The message to log
35
  *
36
  * REPLACE TO DEBUG: Memory consuption as script runs
37
+ * $results = DUP_Util::byteSize(memory_get_peak_usage(true)) . "\t" . $msg;
38
  * @fwrite(self::$logFileHandle, "{$results} \n");
39
  */
40
  static public function Info($msg) {
41
  @fwrite(self::$logFileHandle, "{$msg} \n");
42
+ //$results = DUP_Util::byteSize(memory_get_usage(true)) . "\t" . $msg;
43
  //@fwrite(self::$logFileHandle, "{$results} \n");
44
  }
45
 
classes/{settings.php → class.settings.php} RENAMED
File without changes
classes/package.archive.php DELETED
@@ -1,316 +0,0 @@
1
- <?php
2
- if ( ! defined( 'DUPLICATOR_VERSION' ) ) exit; // Exit if accessed directly
3
-
4
- require_once (DUPLICATOR_PLUGIN_PATH . 'classes/package.archive.zip.php');
5
- require_once (DUPLICATOR_PLUGIN_PATH . 'lib/forceutf8/Encoding.php');
6
-
7
- /**
8
- * The base class for all filter types Directories/Files/Extentions
9
- */
10
- class DUP_Archive_Filter_Scope_Base
11
- {
12
- //All internal storage items that duplicator decides to filter
13
- public $Core = array();
14
-
15
- //Items when creating a package or template that a user decides to filter
16
- public $Instance = array();
17
- }
18
-
19
- /**
20
- * The filter types that belong to directories
21
- */
22
- class DUP_Archive_Filter_Scope_Directory extends DUP_Archive_Filter_Scope_Base
23
- {
24
- //Items that are not readable
25
- public $Warning = array();
26
-
27
- //Items that are not readable
28
- public $Unreadable = array();
29
- }
30
-
31
- /**
32
- * The filter types that belong to files
33
- */
34
- class DUP_Archive_Filter_Scope_File extends DUP_Archive_Filter_Scope_Directory
35
- {
36
- //Items that are too large
37
- public $Size = array();
38
- }
39
-
40
- /**
41
- * The filter information object which store all information about the filtered
42
- * data that is gathered to the execution of a scan process
43
- */
44
- class DUP_Archive_Filter_Info
45
- {
46
- //Contains all folder filter info
47
- public $Dirs = array();
48
-
49
- //Contains all file filter info
50
- public $Files = array();
51
-
52
- //Contains all extensions filter info
53
- public $Exts = array();
54
-
55
- public $UDirCount = 0;
56
- public $UFileCount = 0;
57
- public $UExtCount = 0;
58
-
59
- public function __construct()
60
- {
61
- $this->Dirs = new DUP_Archive_Filter_Scope_Directory();
62
- $this->Files = new DUP_Archive_Filter_Scope_File();
63
- $this->Exts = new DUP_Archive_Filter_Scope_Base();
64
- }
65
- }
66
-
67
-
68
- class DUP_Archive
69
- {
70
- //PUBLIC
71
- public $FilterDirs;
72
- public $FilterExts;
73
- public $FilterDirsAll = array();
74
- public $FilterExtsAll = array();
75
- public $FilterOn;
76
- public $File;
77
- public $Format;
78
- public $PackDir;
79
- public $Size = 0;
80
- public $Dirs = array();
81
- public $Files = array();
82
- public $FilterInfo;
83
-
84
- //PROTECTED
85
- protected $Package;
86
-
87
- public function __construct($package)
88
- {
89
- $this->Package = $package;
90
- $this->FilterOn = false;
91
- $this->FilterInfo = new DUP_Archive_Filter_Info();
92
- }
93
-
94
- public function Build($package)
95
- {
96
- try
97
- {
98
- $this->Package = $package;
99
- if (!isset($this->PackDir) && ! is_dir($this->PackDir)) throw new Exception("The 'PackDir' property must be a valid diretory.");
100
- if (!isset($this->File)) throw new Exception("A 'File' property must be set.");
101
-
102
- $this->Package->SetStatus(DUP_PackageStatus::ARCSTART);
103
- switch ($this->Format)
104
- {
105
- case 'TAR': break;
106
- case 'TAR-GZIP': break;
107
- default:
108
- if (class_exists(ZipArchive))
109
- {
110
- $this->Format = 'ZIP';
111
- DUP_Zip::Create($this);
112
- }
113
- break;
114
- }
115
-
116
- $storePath = "{$this->Package->StorePath}/{$this->File}";
117
- $this->Size = @filesize($storePath);
118
- $this->Package->SetStatus(DUP_PackageStatus::ARCDONE);
119
-
120
- }
121
- catch (Exception $e)
122
- {
123
- echo 'Caught exception: ', $e->getMessage(), "\n";
124
- }
125
- }
126
-
127
- public function GetFilterDirAsArray()
128
- {
129
- return array_map('DUP_Util::SafePath', explode(";", $this->FilterDirs, -1));
130
- }
131
-
132
- public function GetFilterExtsAsArray()
133
- {
134
- return explode(";", $this->FilterExts, -1);
135
- }
136
-
137
- /**
138
- * Get the directory size recursively, but don't calc the snapshot directory, exclusion diretories
139
- * @link http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx Windows filename restrictions
140
- */
141
- public function Stats()
142
- {
143
- $this->createFilterInfo();
144
- $this->getDirs();
145
- $this->getFiles();
146
- return $this;
147
- }
148
-
149
- //Build Filter Data
150
- private function createFilterInfo()
151
- {
152
- //FILTER: INSTANCE ITEMS
153
- //Add the items generated at create time
154
- if ($this->FilterOn)
155
- {
156
- $this->FilterInfo->Dirs->Instance = array_map('DUP_Util::SafePath', explode(";", $this->FilterDirs, -1));
157
- $this->FilterInfo->Exts->Instance = explode(";", $this->FilterExts, -1);
158
- }
159
-
160
- //FILTER: CORE ITMES
161
- //Filters Duplicator free packages & All pro local directories
162
- $this->FilterInfo->Dirs->Core[] = DUPLICATOR_SSDIR_PATH;
163
-
164
- $this->FilterDirsAll = array_merge($this->FilterInfo->Dirs->Instance,
165
- $this->FilterInfo->Dirs->Core);
166
-
167
- $this->FilterExtsAll = array_merge($this->FilterInfo->Exts->Instance,
168
- $this->FilterInfo->Exts->Core);
169
- }
170
-
171
-
172
- //Get All Directories then filter
173
- private function getDirs()
174
- {
175
-
176
- $rootPath = DUP_Util::SafePath(rtrim(DUPLICATOR_WPROOTPATH, '//' ));
177
- $this->Dirs = array();
178
-
179
- //If the root directory is a filter then we will only need the root files
180
- if (in_array($this->PackDir, $this->FilterDirsAll))
181
- {
182
- $this->Dirs[] = $this->PackDir;
183
- }
184
- else
185
- {
186
- $this->Dirs = $this->dirsToArray($rootPath, $this->FilterDirsAll);
187
- $this->Dirs[] = $this->PackDir;
188
- }
189
-
190
- //Filter Directories
191
- //Invalid test contains checks for: characters over 250, invlaid characters,
192
- //empty string and directories ending with period (Windows incompatable)
193
- foreach ($this->Dirs as $key => $val)
194
- {
195
- //WARNING: Find OS items that may have issues
196
- // was commented out in pro
197
- $name = basename($val);
198
-
199
- $warn_test = strlen($val) > 250
200
- || preg_match('/(\/|\*|\?|\>|\<|\:|\\|\|)/', $name)
201
- || trim($name) == ""
202
- || (strrpos($name, '.') == strlen($name) - 1 && substr($name, -1) == '.')
203
- || preg_match('/[^\x20-\x7f]/', $name);
204
- if ($warn_test)
205
- {
206
- $this->FilterInfo->Dirs->Warning[] = DUP_Encoding::toUTF8($val);
207
- }
208
-
209
- //UNREADABLE: Directory is unreadable flag it
210
- if (! is_readable($this->Dirs[$key]))
211
- {
212
- unset($this->Dirs[$key]);
213
- $this->FilterInfo->Dirs->Unreadable[] = $val;
214
- $this->FilterDirsAll[] = $val;
215
- }
216
- }
217
- }
218
-
219
- //Get all files and filter out error prone subsets
220
- private function getFiles()
221
- {
222
- foreach ($this->Dirs as $key => $val)
223
- {
224
- $files = DUP_Util::ListFiles($val);
225
- foreach ($files as $filePath)
226
- {
227
- $fileName = basename($filePath);
228
- if (!is_dir($filePath))
229
- {
230
- if (!in_array(@pathinfo($filePath, PATHINFO_EXTENSION), $this->FilterExtsAll))
231
- {
232
- //Unreadable
233
- if (!is_readable($filePath))
234
- {
235
- $this->FilterInfo->Files->Unreadable[] = $filePath;
236
- continue;
237
- }
238
-
239
- $fileSize = @filesize($filePath);
240
- $fileSize = empty($fileSize) ? 0 : $fileSize;
241
- $invalid_test = strlen($filePath) > 250 ||
242
- preg_match('/(\/|\*|\?|\>|\<|\:|\\|\|)/', $fileName) ||
243
- trim($fileName) == "";
244
-
245
- if ($invalid_test || preg_match('/[^\x20-\x7f]/', $fileName))
246
- {
247
- $filePath = DUP_Encoding::toUTF8($filePath);
248
- $this->FilterInfo->Files->Warning[] = $filePath;
249
- }
250
- $this->Size += $fileSize;
251
- $this->Files[] = $filePath;
252
-
253
-
254
- if ($fileSize > DUPLICATOR_SCAN_WARNFILESIZE)
255
- {
256
- $this->FilterInfo->Files->Size[] = $filePath . ' [' . DUP_Util::ByteSize($fileSize) . ']';
257
- }
258
- }
259
- }
260
- }
261
- }
262
- }
263
-
264
- //Recursive function to get all Directories in a wp install
265
- //Older PHP logic which is more stable on older version of PHP
266
- //NOTE RecursiveIteratorIterator is problematic on some systems issues include:
267
- // - error 'too many files open' for recursion
268
- // - $file->getExtension() is not reliable as it silently fails at least in php 5.2.9
269
- // - issues with when a file has a permission such as 705 and trying to get info (had to fallback to pathinfo)
270
- // - basic conclusion wait on the SPL libs untill after php 5.4 is a requiremnt
271
- // - since we are in a tight recursive loop lets remove the utiltiy call DUP_Util::SafePath("{$path}/{$file}") and
272
- // squeeze out as much performance as we possible can
273
-
274
- private function dirsToArray($path, $filterDirsAll)
275
- {
276
- $items = array();
277
- $handle = @opendir($path);
278
- if ($handle)
279
- {
280
- while (($file = readdir($handle)) !== false)
281
- {
282
- if ($file != '.' && $file != '..')
283
- {
284
- $fullPath = str_replace("\\", '/', "{$path}/{$file}");
285
-
286
- if (is_dir($fullPath))
287
- {
288
- $addDir = true;
289
-
290
- //Remove path filter directories
291
- foreach ($filterDirsAll as $filterDir)
292
- {
293
- $trimmedFilterDir = rtrim($filterDir, '/');
294
-
295
- if ($fullPath == $trimmedFilterDir || strstr($fullPath, $trimmedFilterDir . '/'))
296
- {
297
- $addDir = false;
298
- break;
299
- }
300
- }
301
-
302
- if($addDir)
303
- {
304
- $items = array_merge($items, $this->dirsToArray($fullPath, $filterDirsAll));
305
- $items[] = $fullPath;
306
- }
307
- }
308
- }
309
- }
310
- closedir($handle);
311
- }
312
-
313
- return $items;
314
- }
315
- }
316
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/package.archive.zip.php DELETED
@@ -1,181 +0,0 @@
1
- <?php
2
- if ( ! defined( 'DUPLICATOR_VERSION' ) ) exit; // Exit if accessed directly
3
- require_once (DUPLICATOR_PLUGIN_PATH . 'classes/package.archive.php');
4
-
5
- /**
6
- * DUP_ZIP
7
- * Creates a zip file using the built in PHP ZipArchive class
8
- */
9
- class DUP_Zip extends DUP_Archive
10
- {
11
- //PRIVATE
12
- private static $compressDir;
13
- private static $countDirs = 0;
14
- private static $countFiles = 0;
15
- private static $sqlPath;
16
- private static $zipPath;
17
- private static $zipFileSize;
18
- private static $zipArchive;
19
-
20
- private static $limitItems = 0;
21
- private static $networkFlush = false;
22
- private static $scanReport;
23
-
24
- /**
25
- * CREATE
26
- * Creates the zip file and adds the SQL file to the archive */
27
- static public function Create(DUP_Archive $archive)
28
- {
29
- try
30
- {
31
- $timerAllStart = DUP_Util::GetMicrotime();
32
- $package_zip_flush = DUP_Settings::Get('package_zip_flush');
33
-
34
- self::$compressDir = rtrim(DUP_Util::SafePath($archive->PackDir), '/');
35
- self::$sqlPath = DUP_Util::SafePath("{$archive->Package->StorePath}/{$archive->Package->Database->File}");
36
- self::$zipPath = DUP_Util::SafePath("{$archive->Package->StorePath}/{$archive->File}");
37
- self::$zipArchive = new ZipArchive();
38
- self::$networkFlush = empty($package_zip_flush) ? false : $package_zip_flush;
39
-
40
- $filterDirs = empty($archive->FilterDirs) ? 'not set' : $archive->FilterDirs;
41
- $filterExts = empty($archive->FilterExts) ? 'not set' : $archive->FilterExts;
42
- $filterOn = ($archive->FilterOn) ? 'ON' : 'OFF';
43
- $filterDirsFormat = rtrim(str_replace(';', "\n ", $filterDirs));
44
- $lastDirSuccess = self::$compressDir;
45
-
46
- //LOAD SCAN REPORT
47
- $json = file_get_contents(DUPLICATOR_SSDIR_PATH_TMP . "/{$archive->Package->NameHash}_scan.json");
48
- self::$scanReport = json_decode($json);
49
-
50
- DUP_Log::Info("\n********************************************************************************");
51
- DUP_Log::Info("ARCHIVE (ZIP):");
52
- DUP_Log::Info("********************************************************************************");
53
- $isZipOpen = (self::$zipArchive->open(self::$zipPath, ZIPARCHIVE::CREATE) === TRUE);
54
- if (! $isZipOpen){
55
- DUP_Log::Error("Cannot open zip file with PHP ZipArchive.", "Path location [" . self::$zipPath . "]");
56
- }
57
- DUP_Log::Info("ARCHIVE DIR: " . self::$compressDir);
58
- DUP_Log::Info("ARCHIVE FILE: " . basename(self::$zipPath));
59
- DUP_Log::Info("FILTERS: *{$filterOn}*");
60
- DUP_Log::Info("DIRS: {$filterDirsFormat}");
61
- DUP_Log::Info("EXTS: {$filterExts}");
62
-
63
- DUP_Log::Info("----------------------------------------");
64
- DUP_Log::Info("COMPRESSING");
65
- DUP_Log::Info("SIZE:\t" . self::$scanReport->ARC->Size);
66
- DUP_Log::Info("STATS:\tDirs " . self::$scanReport->ARC->DirCount . " | Files " . self::$scanReport->ARC->FileCount);
67
-
68
- //ADD SQL
69
- $isSQLInZip = self::$zipArchive->addFile(self::$sqlPath, "database.sql");
70
- if ($isSQLInZip) {
71
- DUP_Log::Info("SQL ADDED: " . basename(self::$sqlPath));
72
- } else {
73
- DUP_Log::Error("Unable to add database.sql to archive.", "SQL File Path [" . self::$sqlath . "]");
74
- }
75
- self::$zipArchive->close();
76
- self::$zipArchive->open(self::$zipPath, ZipArchive::CREATE);
77
-
78
- //ZIP DIRECTORIES
79
- $info = '';
80
- foreach(self::$scanReport->ARC->Dirs as $dir)
81
- {
82
- if (is_readable($dir) && self::$zipArchive->addEmptyDir(ltrim(str_replace(self::$compressDir, '', $dir), '/')))
83
- {
84
- self::$countDirs++;
85
- $lastDirSuccess = $dir;
86
- }
87
- else
88
- {
89
- //Don't warn when dirtory is the root path
90
- if (strcmp($dir, rtrim(self::$compressDir, '/')) != 0) {
91
- $dir_path = strlen($dir) ? "[{$dir}]" : "[Read Error] - last successful read was: [{$lastDirSuccess}]";
92
- $info .= "DIR: {$dir_path}\n";
93
- }
94
- }
95
- }
96
-
97
- //LOG Unreadable DIR info
98
- if (strlen($info))
99
- {
100
- DUP_Log::Info("\nWARNING: Unable to zip directories:");
101
- DUP_Log::Info($info);
102
- }
103
-
104
-
105
-
106
- /* ZIP FILES: Network Flush
107
- * This allows the process to not timeout on fcgi
108
- * setups that need a response every X seconds */
109
- $info = '';
110
- if (self::$networkFlush)
111
- {
112
- foreach(self::$scanReport->ARC->Files as $file)
113
- {
114
- if (is_readable($file) && self::$zipArchive->addFile($file, ltrim(str_replace(self::$compressDir, '', $file), '/')))
115
- {
116
- self::$limitItems++;
117
- self::$countFiles++;
118
- }
119
- else
120
- {
121
- $info .= "FILE: [{$file}]\n";
122
- }
123
- //Trigger a flush to the web server after so many files have been loaded.
124
- if(self::$limitItems > DUPLICATOR_ZIP_FLUSH_TRIGGER)
125
- {
126
- $sumItems = (self::$countDirs + self::$countFiles);
127
- self::$zipArchive->close();
128
- self::$zipArchive->open(self::$zipPath);
129
- self::$limitItems = 0;
130
- DUP_Util::FcgiFlush();
131
- DUP_Log::Info("Items archived [{$sumItems}] flushing response.");
132
- }
133
- }
134
- }
135
- //Normal
136
- else
137
- {
138
- foreach(self::$scanReport->ARC->Files as $file)
139
- {
140
- if (is_readable($file) && self::$zipArchive->addFile($file, ltrim(str_replace(self::$compressDir, '', $file), '/'))) {
141
- self::$countFiles++;
142
- } else {
143
- $info .= "FILE: [{$file}]\n";
144
- }
145
- }
146
- }
147
-
148
- //LOG Unreadable FILE info
149
- if (strlen($info))
150
- {
151
- DUP_Log::Info("\nWARNING: Unable to zip files:");
152
- DUP_Log::Info($info);
153
- unset($info);
154
- }
155
-
156
- DUP_Log::Info(print_r(self::$zipArchive, true));
157
-
158
- //--------------------------------
159
- //LOG FINAL RESULTS
160
- DUP_Util::FcgiFlush();
161
- $zipCloseResult = self::$zipArchive->close();
162
- ($zipCloseResult)
163
- ? DUP_Log::Info("COMPRESSION RESULT: '{$zipCloseResult}'")
164
- : DUP_Log::Error("ZipArchive close failure.", "This hosted server may have a disk quota limit.\nCheck to make sure this archive file can be stored.");
165
-
166
- $timerAllEnd = DUP_Util::GetMicrotime();
167
- $timerAllSum = DUP_Util::ElapsedTime($timerAllEnd, $timerAllStart);
168
-
169
-
170
- self::$zipFileSize = @filesize(self::$zipPath);
171
- DUP_Log::Info("COMPRESSED SIZE: " . DUP_Util::ByteSize(self::$zipFileSize));
172
- DUP_Log::Info("ARCHIVE RUNTIME: {$timerAllSum}");
173
- DUP_Log::Info("MEMORY STACK: " . DUP_Server::GetPHPMemory());
174
- }
175
- catch (Exception $e) {
176
- DUP_Log::Error("Runtime error in package.archive.zip.php constructor.", "Exception: {$e}");
177
- }
178
- }
179
-
180
- }
181
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/package.database.php DELETED
@@ -1,416 +0,0 @@
1
- <?php
2
- if ( ! defined( 'DUPLICATOR_VERSION' ) ) exit; // Exit if accessed directly
3
-
4
- class DUP_Database {
5
-
6
- //PUBLIC
7
- public $Type = 'MySQL';
8
- public $Size;
9
- public $File;
10
- public $Path;
11
- public $FilterTables;
12
- public $FilterOn;
13
- public $Name;
14
- public $Compatible;
15
-
16
- //PROTECTED
17
- protected $Package;
18
-
19
- //PRIVATE
20
- private $dbStorePath;
21
- private $EOFMarker;
22
- private $networkFlush;
23
-
24
- //CONSTRUCTOR
25
- function __construct($package) {
26
- $this->Package = $package;
27
- $this->EOFMarker = "";
28
- $package_zip_flush = DUP_Settings::Get('package_zip_flush');
29
- $this->networkFlush = empty($package_zip_flush) ? false : $package_zip_flush;
30
- }
31
-
32
- public function Build($package) {
33
- try {
34
-
35
- $this->Package = $package;
36
-
37
- $time_start = DUP_Util::GetMicrotime();
38
- $this->Package->SetStatus(DUP_PackageStatus::DBSTART);
39
- $this->dbStorePath = "{$this->Package->StorePath}/{$this->File}";
40
-
41
- $package_mysqldump = DUP_Settings::Get('package_mysqldump');
42
- $package_phpdump_qrylimit = DUP_Settings::Get('package_phpdump_qrylimit');
43
-
44
- $mysqlDumpPath = self::GetMySqlDumpPath();
45
- $mode = ($mysqlDumpPath && $package_mysqldump) ? 'MYSQLDUMP' : 'PHP';
46
- $reserved_db_filepath = DUPLICATOR_WPROOTPATH . 'database.sql';
47
-
48
-
49
- $log = "\n********************************************************************************\n";
50
- $log .= "DATABASE:\n";
51
- $log .= "********************************************************************************\n";
52
- $log .= "BUILD MODE: {$mode}";
53
- $log .= ($mode == 'PHP') ? "(query limit - {$package_phpdump_qrylimit})\n" : "\n";
54
- $log .= "MYSQLTIMEOUT: " . DUPLICATOR_DB_MAX_TIME . "\n";
55
- $log .= "MYSQLDUMP: ";
56
- $log .= ($mysqlDumpPath) ? "Is Supported" : "Not Supported";
57
- DUP_Log::Info($log);
58
- $log = null;
59
-
60
- //Reserved file found
61
- if (file_exists($reserved_db_filepath)) {
62
- DUP_Log::Error("Reserverd SQL file detected",
63
- "The file database.sql was found at [{$reserved_db_filepath}].\n"
64
- . "\tPlease remove/rename this file to continue with the package creation.");
65
- }
66
-
67
- switch ($mode) {
68
- case 'MYSQLDUMP': $this->mysqlDump($mysqlDumpPath); break;
69
- case 'PHP' : $this->phpDump(); break;
70
- }
71
-
72
- DUP_Log::Info("SQL CREATED: {$this->File}");
73
- $time_end = DUP_Util::GetMicrotime();
74
- $time_sum = DUP_Util::ElapsedTime($time_end, $time_start);
75
-
76
- //File below 10k will be incomplete
77
- $sql_file_size = filesize($this->dbStorePath);
78
- DUP_Log::Info("SQL FILE SIZE: " . DUP_Util::ByteSize($sql_file_size) . " ({$sql_file_size})");
79
- if ($sql_file_size < 10000) {
80
- DUP_Log::Error("SQL file size too low.", "File does not look complete. Check permission on file and parent directory at [{$this->dbStorePath}]");
81
- }
82
-
83
- DUP_Log::Info("SQL FILE TIME: " . date("Y-m-d H:i:s"));
84
- DUP_Log::Info("SQL RUNTIME: {$time_sum}");
85
-
86
- $this->Size = @filesize($this->dbStorePath);
87
- $this->Package->SetStatus(DUP_PackageStatus::DBDONE);
88
-
89
- } catch (Exception $e) {
90
- DUP_Log::Error("Runtime error in DUP_Database::Build","Exception: {$e}");
91
- }
92
- }
93
-
94
- /**
95
- * Get the database stats
96
- */
97
- public function Stats() {
98
-
99
- global $wpdb;
100
- $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : null;
101
- $tblCount = 0;
102
-
103
- $tables = $wpdb->get_results("SHOW TABLE STATUS", ARRAY_A);
104
- $info = array();
105
- $info['Status']['Success'] = is_null($tables) ? false : true;
106
- //DB_Case for the database name is never checked on
107
- $info['Status']['DB_Case'] = 'Good';
108
- $info['Status']['DB_Rows'] = 'Good';
109
- $info['Status']['DB_Size'] = 'Good';
110
- $info['Status']['TBL_Case'] = 'Good';
111
- $info['Status']['TBL_Rows'] = 'Good';
112
- $info['Status']['TBL_Size'] = 'Good';
113
-
114
- $info['Size'] = 0;
115
- $info['Rows'] = 0;
116
- $info['TableCount'] = 0;
117
- $info['TableList'] = array();
118
- $tblCaseFound = 0;
119
- $tblRowsFound = 0;
120
- $tblSizeFound = 0;
121
-
122
- //Grab Table Stats
123
- foreach ($tables as $table)
124
- {
125
- $name = $table["Name"];
126
- if ($this->FilterOn && is_array($filterTables))
127
- {
128
- if (in_array($name, $filterTables)) {
129
- continue;
130
- }
131
- }
132
-
133
- $size = ($table["Data_length"] + $table["Index_length"]);
134
- $rows = empty($table["Rows"]) ? '0' : $table["Rows"];
135
-
136
- $info['Size'] += $size;
137
- $info['Rows'] += ($table["Rows"]);
138
- $info['TableList'][$name]['Case'] = preg_match('/[A-Z]/', $name) ? 1 : 0;
139
- $info['TableList'][$name]['Rows'] = number_format($rows);
140
- $info['TableList'][$name]['Size'] = DUP_Util::ByteSize($size);
141
- $tblCount++;
142
-
143
- //Table Uppercase
144
- if ($info['TableList'][$name]['Case']) {
145
- if (! $tblCaseFound) {
146
- $tblCaseFound = 1;
147
- }
148
- }
149
-
150
- //Table Row Count
151
- if ($rows > DUPLICATOR_SCAN_DB_TBL_ROWS) {
152
- if (! $tblRowsFound) {
153
- $tblRowsFound = 1;
154
- }
155
- }
156
-
157
- //Table Size
158
- if ($size > DUPLICATOR_SCAN_DB_TBL_SIZE) {
159
- if (! $tblSizeFound) {
160
- $tblSizeFound = 1;
161
- }
162
- }
163
- }
164
-
165
- $info['Status']['DB_Case'] = preg_match('/[A-Z]/', $wpdb->dbname) ? 'Warn' : 'Good';
166
- $info['Status']['DB_Rows'] = ($info['Rows'] > DUPLICATOR_SCAN_DB_ALL_ROWS) ? 'Warn' : 'Good';
167
- $info['Status']['DB_Size'] = ($info['Size'] > DUPLICATOR_SCAN_DB_ALL_SIZE) ? 'Warn' : 'Good';
168
-
169
-
170
- $info['Status']['TBL_Case'] = ($tblCaseFound) ? 'Warn' : 'Good';
171
- $info['Status']['TBL_Rows'] = ($tblRowsFound) ? 'Warn' : 'Good';
172
- $info['Status']['TBL_Size'] = ($tblSizeFound) ? 'Warn' : 'Good';
173
-
174
- $info['Size'] = DUP_Util::ByteSize($info['Size']) or "unknown";
175
- $info['Rows'] = number_format($info['Rows']) or "unknown";
176
- $info['TableList'] = $info['TableList'] or "unknown";
177
- $info['TableCount'] = $tblCount;
178
-
179
- return $info;
180
- }
181
-
182
- /**
183
- * Returns the mysqldump path if the server is enabled to execute it
184
- * @return boolean|string
185
- */
186
- public static function GetMySqlDumpPath() {
187
-
188
- //Is shell_exec possible
189
- if (! DUP_Util::IsShellExecAvailable()) {
190
- return false;
191
- }
192
-
193
- $custom_mysqldump_path = DUP_Settings::Get('package_mysqldump_path');
194
- $custom_mysqldump_path = (strlen($custom_mysqldump_path)) ? $custom_mysqldump_path : '';
195
-
196
- //Common Windows Paths
197
- if (DUP_Util::IsOSWindows()) {
198
- $paths = array(
199
- $custom_mysqldump_path,
200
- 'C:/xampp/mysql/bin/mysqldump.exe',
201
- 'C:/Program Files/xampp/mysql/bin/mysqldump',
202
- 'C:/Program Files/MySQL/MySQL Server 6.0/bin/mysqldump',
203
- 'C:/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump',
204
- 'C:/Program Files/MySQL/MySQL Server 5.4/bin/mysqldump',
205
- 'C:/Program Files/MySQL/MySQL Server 5.1/bin/mysqldump',
206
- 'C:/Program Files/MySQL/MySQL Server 5.0/bin/mysqldump',
207
- );
208
-
209
- //Common Linux Paths
210
- } else {
211
- $path1 = '';
212
- $path2 = '';
213
- $mysqldump = `which mysqldump`;
214
- if (@is_executable($mysqldump))
215
- $path1 = (!empty($mysqldump)) ? $mysqldump : '';
216
-
217
- $mysqldump = dirname(`which mysql`) . "/mysqldump";
218
- if (@is_executable($mysqldump))
219
- $path2 = (!empty($mysqldump)) ? $mysqldump : '';
220
-
221
- $paths = array(
222
- $custom_mysqldump_path,
223
- $path1,
224
- $path2,
225
- '/usr/local/bin/mysqldump',
226
- '/usr/local/mysql/bin/mysqldump',
227
- '/usr/mysql/bin/mysqldump',
228
- '/usr/bin/mysqldump',
229
- '/opt/local/lib/mysql6/bin/mysqldump',
230
- '/opt/local/lib/mysql5/bin/mysqldump',
231
- '/opt/local/lib/mysql4/bin/mysqldump',
232
- );
233
- }
234
-
235
- // Find the one which works
236
- foreach ( $paths as $path ) {
237
- if ( @is_executable($path))
238
- return $path;
239
- }
240
-
241
- return false;
242
- }
243
-
244
-
245
- private function mysqlDump($exePath) {
246
-
247
- global $wpdb;
248
-
249
- $host = explode(':', DB_HOST);
250
- $host = reset($host);
251
- $port = strpos(DB_HOST, ':') ? end(explode( ':', DB_HOST ) ) : '';
252
- $name = DB_NAME;
253
- $mysqlcompat_on = isset($this->Compatible) && strlen($this->Compatible);
254
-
255
- //Build command
256
- $cmd = escapeshellarg($exePath);
257
- $cmd .= ' --no-create-db';
258
- $cmd .= ' --single-transaction';
259
- $cmd .= ' --hex-blob';
260
- $cmd .= ' --skip-add-drop-table';
261
-
262
- //Compatibility mode
263
- if ($mysqlcompat_on) {
264
- DUP_Log::Info("COMPATIBLE: [{$this->Compatible}]");
265
- $cmd .= " --compatible={$this->Compatible}";
266
- }
267
-
268
- //Filter tables
269
- $tables = $wpdb->get_col('SHOW TABLES');
270
- $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : null;
271
- $tblAllCount = count($tables);
272
- $tblFilterOn = ($this->FilterOn) ? 'ON' : 'OFF';
273
-
274
- if (is_array($filterTables) && $this->FilterOn) {
275
- foreach ($tables as $key => $val) {
276
- if (in_array($tables[$key], $filterTables)) {
277
- $cmd .= " --ignore-table={$name}.{$tables[$key]} ";
278
- unset($tables[$key]);
279
- }
280
- }
281
- }
282
-
283
- $cmd .= ' -u ' . escapeshellarg(DB_USER);
284
- $cmd .= (DB_PASSWORD) ?
285
- ' -p' . escapeshellarg(DB_PASSWORD) : '';
286
- $cmd .= ' -h ' . escapeshellarg($host);
287
- $cmd .= ( ! empty($port) && is_numeric($port) ) ?
288
- ' -P ' . $port : '';
289
- $cmd .= ' -r ' . escapeshellarg($this->dbStorePath);
290
- $cmd .= ' ' . escapeshellarg(DB_NAME);
291
- $cmd .= ' 2>&1';
292
-
293
- $output = shell_exec($cmd);
294
-
295
- // Password bug > 5.6 (@see http://bugs.mysql.com/bug.php?id=66546)
296
- if ( trim( $output ) === 'Warning: Using a password on the command line interface can be insecure.' ) {
297
- $output = '';
298
- }
299
- $output = (strlen($output)) ? $output : "Ran from {$exePath}";
300
-
301
- $tblCreateCount = count($tables);
302
- $tblFilterCount = $tblAllCount - $tblCreateCount;
303
-
304
- //DEBUG
305
- //DUP_Log::Info("COMMAND: {$cmd}");
306
- DUP_Log::Info("FILTERED: [{$this->FilterTables}]");
307
- DUP_Log::Info("RESPONSE: {$output}");
308
- DUP_Log::Info("TABLES: total:{$tblAllCount} | filtered:{$tblFilterCount} | create:{$tblCreateCount}");
309
-
310
- $sql_footer = "\n\n/* Duplicator WordPress Timestamp: " . date("Y-m-d H:i:s") . "*/\n";
311
- $sql_footer .= "/* " . DUPLICATOR_DB_EOF_MARKER . " */\n";
312
- file_put_contents($this->dbStorePath, $sql_footer, FILE_APPEND);
313
-
314
- return ($output) ? false : true;
315
- }
316
-
317
-
318
- private function phpDump() {
319
-
320
- global $wpdb;
321
-
322
- $wpdb->query("SET session wait_timeout = " . DUPLICATOR_DB_MAX_TIME);
323
- $handle = fopen($this->dbStorePath, 'w+');
324
- $tables = $wpdb->get_col('SHOW TABLES');
325
-
326
- $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : null;
327
- $tblAllCount = count($tables);
328
- $tblFilterOn = ($this->FilterOn) ? 'ON' : 'OFF';
329
- $qryLimit = DUP_Settings::Get('package_phpdump_qrylimit');
330
-
331
- if (is_array($filterTables) && $this->FilterOn) {
332
- foreach ($tables as $key => $val) {
333
- if (in_array($tables[$key], $filterTables)) {
334
- unset($tables[$key]);
335
- }
336
- }
337
- }
338
- $tblCreateCount = count($tables);
339
- $tblFilterCount = $tblAllCount - $tblCreateCount;
340
-
341
- DUP_Log::Info("TABLES: total:{$tblAllCount} | filtered:{$tblFilterCount} | create:{$tblCreateCount}");
342
- DUP_Log::Info("FILTERED: [{$this->FilterTables}]");
343
-
344
- $sql_header = "/* DUPLICATOR MYSQL SCRIPT CREATED ON : " . @date("Y-m-d H:i:s") . " */\n\n";
345
- $sql_header .= "SET FOREIGN_KEY_CHECKS = 0;\n\n";
346
- fwrite($handle, $sql_header);
347
-
348
- //BUILD CREATES:
349
- //All creates must be created before inserts do to foreign key constraints
350
- foreach ($tables as $table) {
351
- //$sql_del = ($GLOBALS['duplicator_opts']['dbadd_drop']) ? "DROP TABLE IF EXISTS {$table};\n\n" : "";
352
- //@fwrite($handle, $sql_del);
353
- $create = $wpdb->get_row("SHOW CREATE TABLE `{$table}`", ARRAY_N);
354
- @fwrite($handle, "{$create[1]};\n\n");
355
- }
356
-
357
- //BUILD INSERTS:
358
- //Create Insert in 100 row increments to better handle memory
359
- foreach ($tables as $table) {
360
-
361
- $row_count = $wpdb->get_var("SELECT Count(*) FROM `{$table}`");
362
- //DUP_Log::Info("{$table} ({$row_count})");
363
-
364
- if ($row_count > $qryLimit) {
365
- $row_count = ceil($row_count / $qryLimit);
366
- } else if ($row_count > 0) {
367
- $row_count = 1;
368
- }
369
-
370
- if ($row_count >= 1) {
371
- fwrite($handle, "\n/* INSERT TABLE DATA: {$table} */\n");
372
- }
373
-
374
- for ($i = 0; $i < $row_count; $i++) {
375
- $sql = "";
376
- $limit = $i * $qryLimit;
377
- $query = "SELECT * FROM `{$table}` LIMIT {$limit}, {$qryLimit}";
378
- $rows = $wpdb->get_results($query, ARRAY_A);
379
- if (is_array($rows)) {
380
- foreach ($rows as $row) {
381
- $sql .= "INSERT INTO `{$table}` VALUES(";
382
- $num_values = count($row);
383
- $num_counter = 1;
384
- foreach ($row as $value) {
385
- if ( is_null( $value ) || ! isset( $value ) ) {
386
- ($num_values == $num_counter) ? $sql .= 'NULL' : $sql .= 'NULL, ';
387
- } else {
388
- ($num_values == $num_counter)
389
- ? $sql .= '"' . @esc_sql($value) . '"'
390
- : $sql .= '"' . @esc_sql($value) . '", ';
391
- }
392
- $num_counter++;
393
- }
394
- $sql .= ");\n";
395
- }
396
- fwrite($handle, $sql);
397
- }
398
- }
399
-
400
- //Flush buffer if enabled
401
- if ($this->networkFlush) {
402
- DUP_Util::FcgiFlush();
403
- }
404
- $sql = null;
405
- $rows = null;
406
- }
407
-
408
- $sql_footer = "\nSET FOREIGN_KEY_CHECKS = 1; \n\n";
409
- $sql_footer .= "/* Duplicator WordPress Timestamp: " . date("Y-m-d H:i:s") . "*/\n";
410
- $sql_footer .= "/* " . DUPLICATOR_DB_EOF_MARKER . " */\n";
411
- fwrite($handle, $sql_footer);
412
- $wpdb->flush();
413
- fclose($handle);
414
- }
415
- }
416
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/package.installer.php DELETED
@@ -1,203 +0,0 @@
1
- <?php
2
-
3
- if ( ! defined( 'DUPLICATOR_VERSION' ) ) exit; // Exit if accessed directly
4
-
5
- class DUP_Installer {
6
-
7
- //PUBLIC
8
- public $File;
9
- public $Size = 0;
10
- public $OptsDBHost;
11
- public $OptsDBPort;
12
- public $OptsDBName;
13
- public $OptsDBUser;
14
- public $OptsSSLAdmin;
15
- public $OptsSSLLogin;
16
- public $OptsCacheWP;
17
- public $OptsCachePath;
18
- public $OptsURLNew;
19
-
20
- //PROTECTED
21
- protected $Package;
22
-
23
- //CONSTRUCTOR
24
- function __construct($package) {
25
- $this->Package = $package;
26
- }
27
-
28
- public function Build($package) {
29
-
30
- $this->Package = $package;
31
-
32
- DUP_Log::Info("\n********************************************************************************");
33
- DUP_Log::Info("MAKE INSTALLER:");
34
- DUP_Log::Info("********************************************************************************");
35
- DUP_Log::Info("Build Start");
36
-
37
- $template_uniqid = uniqid('') . '_' . time();
38
- $template_path = DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH_TMP . "/installer.template_{$template_uniqid}.php");
39
- $main_path = DUP_Util::SafePath(DUPLICATOR_PLUGIN_PATH . 'installer/build/main.installer.php');
40
- @chmod($template_path, 0777);
41
- @chmod($main_path, 0777);
42
-
43
- @touch($template_path);
44
- $main_data = file_get_contents("{$main_path}");
45
- $template_result = file_put_contents($template_path, $main_data);
46
- if ($main_data === false || $template_result == false) {
47
- $err_info ="These files may have permission issues. Please validate that PHP has read/write access.\n";
48
- $err_info .= "Main Installer: '{$main_path}' \nTemplate Installer: '$template_path'";
49
- DUP_Log::Error("Install builder failed to generate files.", "{$err_info}");
50
- }
51
-
52
- $embeded_files = array(
53
- "assets/inc.libs.css.php" => "@@INC.LIBS.CSS.PHP@@",
54
- "assets/inc.css.php" => "@@INC.CSS.PHP@@",
55
- "assets/inc.libs.js.php" => "@@INC.LIBS.JS.PHP@@",
56
- "assets/inc.js.php" => "@@INC.JS.PHP@@",
57
- "classes/class.logging.php" => "@@CLASS.LOGGING.PHP@@",
58
- "classes/class.utils.php" => "@@CLASS.UTILS.PHP@@",
59
- "classes/class.conf.wp.php" => "@@CLASS.CONF.WP.PHP@@",
60
- "classes/class.conf.srv.php" => "@@CLASS.CONF.SRV.PHP@@",
61
- "classes/class.serializer.php" => "@@CLASS.SERIALIZER.PHP@@",
62
- "ajax.step1.php" => "@@AJAX.STEP1.PHP@@",
63
- "ajax.step2.php" => "@@AJAX.STEP2.PHP@@",
64
- "view.step1.php" => "@@VIEW.STEP1.PHP@@",
65
- "view.step2.php" => "@@VIEW.STEP2.PHP@@",
66
- "view.step3.php" => "@@VIEW.STEP3.PHP@@",
67
- "view.help.php" => "@@VIEW.HELP.PHP@@",);
68
-
69
- foreach ($embeded_files as $name => $token) {
70
- $file_path = DUPLICATOR_PLUGIN_PATH . "installer/build/{$name}";
71
- @chmod($file_path, 0777);
72
-
73
- $search_data = @file_get_contents($template_path);
74
- $insert_data = @file_get_contents($file_path);
75
- file_put_contents($template_path, str_replace("${token}", "{$insert_data}", $search_data));
76
- if ($search_data === false || $insert_data == false) {
77
- DUP_Log::Error("Installer generation failed at {$token}.");
78
- }
79
- @chmod($file_path, 0644);
80
- }
81
-
82
- @chmod($template_path, 0644);
83
- @chmod($main_path, 0644);
84
-
85
- DUP_Log::Info("Build Finished");
86
- $this->createFromTemplate($template_path);
87
- $storePath = "{$this->Package->StorePath}/{$this->File}";
88
- $this->Size = @filesize($storePath);
89
- $this->addBackup();
90
-
91
- }
92
-
93
-
94
- /**
95
- * createZipBackup
96
- * Puts an installer zip file in the archive for backup purposes.
97
- */
98
- private function addBackup() {
99
-
100
- $zipPath = DUP_Util::SafePath("{$this->Package->StorePath}/{$this->Package->Archive->File}");
101
- $installer = DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH_TMP) . "/{$this->Package->NameHash}_installer.php";
102
-
103
- $zipArchive = new ZipArchive();
104
- if ($zipArchive->open($zipPath, ZIPARCHIVE::CREATE) === TRUE) {
105
- if ($zipArchive->addFile($installer, "installer-backup.php")) {
106
- DUP_Log::Info("Added to archive");
107
- } else {
108
- DUP_Log::Info("Unable to add installer-backup.php to archive.", "Installer File Path [{$installer}]");
109
- }
110
- $zipArchive->close();
111
- }
112
- }
113
-
114
- /**
115
- * createFromTemplate
116
- * Generates the final installer file from the template file
117
- */
118
- private function createFromTemplate($template) {
119
-
120
- global $wpdb;
121
-
122
- DUP_Log::Info("Preping for use");
123
- $installer = DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH_TMP) . "/{$this->Package->NameHash}_installer.php";
124
-
125
- //Option values to delete at install time
126
- $deleteOpts = $GLOBALS['DUPLICATOR_OPTS_DELETE'];
127
-
128
- $replace_items = Array(
129
- //COMPARE VALUES
130
- "fwrite_created" => $this->Package->Created,
131
- "fwrite_version_dup" => DUPLICATOR_VERSION,
132
- "fwrite_version_wp" => $this->Package->VersionWP,
133
- "fwrite_version_db" => $this->Package->VersionDB,
134
- "fwrite_version_php" => $this->Package->VersionPHP,
135
- "fwrite_version_os" => $this->Package->VersionOS,
136
- //GENERAL
137
- "fwrite_url_old" => get_option('siteurl'),
138
- "fwrite_package_name" => "{$this->Package->NameHash}_archive.zip",
139
- "fwrite_package_notes" => $this->Package->Notes,
140
- "fwrite_secure_name" => $this->Package->NameHash,
141
- "fwrite_url_new" => $this->Package->Installer->OptsURLNew,
142
- "fwrite_dbhost" => $this->Package->Installer->OptsDBHost,
143
- "fwrite_dbport" => $this->Package->Installer->OptsDBPort,
144
- "fwrite_dbname" => $this->Package->Installer->OptsDBName,
145
- "fwrite_dbuser" => $this->Package->Installer->OptsDBUser,
146
- "fwrite_dbpass" => '',
147
- "fwrite_ssl_admin" => $this->Package->Installer->OptsSSLAdmin,
148
- "fwrite_ssl_login" => $this->Package->Installer->OptsSSLLogin,
149
- "fwrite_cache_wp" => $this->Package->Installer->OptsCacheWP,
150
- "fwrite_cache_path" => $this->Package->Installer->OptsCachePath,
151
- "fwrite_wp_tableprefix" => $wpdb->prefix,
152
- "fwrite_opts_delete" => json_encode($deleteOpts),
153
- "fwrite_blogname" => esc_html(get_option('blogname')),
154
- "fwrite_wproot" => DUPLICATOR_WPROOTPATH,
155
- "fwrite_duplicator_version" => DUPLICATOR_VERSION);
156
-
157
- if (file_exists($template) && is_readable($template)) {
158
- $err_msg = "ERROR: Unable to read/write installer. \nERROR INFO: Check permission/owner on file and parent folder.\nInstaller File = <{$installer}>";
159
- $install_str = $this->parseTemplate($template, $replace_items);
160
- (empty($install_str))
161
- ? DUP_Log::Error("{$err_msg}" , "DUP_Installer::createFromTemplate => file-empty-read")
162
- : DUP_Log::Info("Template parsed with new data");
163
-
164
- //INSTALLER FILE
165
- $fp = (!file_exists($installer)) ? fopen($installer, 'x+') : fopen($installer, 'w');
166
- if (! $fp || ! fwrite($fp, $install_str, strlen($install_str))) {
167
- DUP_Log::Error("{$err_msg}", "DUP_Installer::createFromTemplate => file-write-error");
168
- }
169
-
170
- @fclose($fp);
171
- } else {
172
- DUP_Log::Error("Installer Template missing or unreadable.", "Template [{$template}]");
173
- }
174
- @unlink($template);
175
- DUP_Log::Info("Complete [{$installer}]");
176
- }
177
-
178
- /**
179
- * parseTemplate
180
- * Tokenize a file based on an array key
181
- *
182
- * @param string $filename The filename to tokenize
183
- * @param array $data The array of key value items to tokenize
184
- */
185
- private function parseTemplate($filename, $data) {
186
- $q = file_get_contents($filename);
187
- foreach ($data as $key => $value) {
188
- //NOTE: Use var_export as it's probably best and most "thorough" way to
189
- //make sure the values are set correctly in the template. But in the template,
190
- //need to make things properly formatted so that when real syntax errors
191
- //exist they are easy to spot. So the values will be surrounded by quotes
192
-
193
- $find = array ("'%{$key}%'", "\"%{$key}%\"");
194
- $q = str_replace($find, var_export($value, true), $q);
195
- //now, account for places that do not surround with quotes... these
196
- //places do NOT need to use var_export as they are not inside strings
197
- $q = str_replace('%' . $key . '%', $value, $q);
198
- }
199
- return $q;
200
- }
201
-
202
- }
203
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/package.php DELETED
@@ -1,547 +0,0 @@
1
- <?php
2
- if ( ! defined( 'DUPLICATOR_VERSION' ) ) exit; // Exit if accessed directly
3
-
4
- require_once (DUPLICATOR_PLUGIN_PATH . 'classes/package.archive.php');
5
- require_once (DUPLICATOR_PLUGIN_PATH . 'classes/package.installer.php');
6
- require_once (DUPLICATOR_PLUGIN_PATH . 'classes/package.database.php');
7
- require_once (DUPLICATOR_PLUGIN_PATH . 'classes/utility.php');
8
-
9
- final class DUP_PackageStatus {
10
- private function __construct() {}
11
- const START = 10;
12
- const DBSTART = 20;
13
- const DBDONE = 30;
14
- const ARCSTART = 40;
15
- const ARCDONE = 50;
16
- const COMPLETE = 100;
17
- }
18
-
19
- final class DUP_PackageType {
20
- private function __construct() {}
21
- const MANUAL = 0;
22
- const SCHEDULED = 1;
23
- }
24
-
25
- /**
26
- * Class used to store and process all Package logic
27
- * @package Dupicator\classes
28
- */
29
- class DUP_Package {
30
-
31
- const OPT_ACTIVE = 'duplicator_package_active';
32
-
33
- //Properties
34
- public $Created;
35
- public $Version;
36
- public $VersionWP;
37
- public $VersionDB;
38
- public $VersionPHP;
39
- public $VersionOS;
40
-
41
- public $ID;
42
- public $Name;
43
- public $Hash;
44
- public $NameHash;
45
- public $Type;
46
- public $Notes;
47
- public $StorePath;
48
- public $StoreURL;
49
- public $ScanFile;
50
- public $Runtime;
51
- public $ExeSize;
52
- public $ZipSize;
53
- public $Status;
54
- public $WPUser;
55
- //Objects
56
- public $Archive;
57
- public $Installer;
58
- public $Database;
59
-
60
- /**
61
- * Manages the Package Process
62
- */
63
- function __construct() {
64
-
65
- $this->ID = null;
66
- $this->Version = DUPLICATOR_VERSION;
67
-
68
- $this->Type = DUP_PackageType::MANUAL;
69
- $this->Name = self::GetDefaultName();
70
- $this->Notes = null;
71
- $this->StoreURL = DUP_Util::SSDirURL();
72
- $this->StorePath = DUPLICATOR_SSDIR_PATH_TMP;
73
- $this->Database = new DUP_Database($this);
74
- $this->Archive = new DUP_Archive($this);
75
- $this->Installer = new DUP_Installer($this);
76
-
77
- }
78
-
79
- /**
80
- * Generates a scan report
81
- * @return array of scan results
82
- *
83
- * @notes: Testing = /wp-admin/admin-ajax.php?action=duplicator_package_scan
84
- */
85
- public function Scan() {
86
-
87
- $timerStart = DUP_Util::GetMicrotime();
88
- $report = array();
89
- $this->ScanFile = "{$this->NameHash}_scan.json";
90
-
91
- $report['RPT']['ScanTime'] = "0";
92
- $report['RPT']['ScanFile'] = $this->ScanFile;
93
-
94
- //SERVER
95
- $srv = DUP_Server::GetChecks();
96
- $report['SRV'] = $srv['SRV'];
97
-
98
- //FILES
99
- $this->Archive->Stats();
100
- $dirCount = count($this->Archive->Dirs);
101
- $fileCount = count($this->Archive->Files);
102
- $fullCount = $dirCount + $fileCount;
103
-
104
- $report['ARC']['Size'] = DUP_Util::ByteSize($this->Archive->Size) or "unknown";
105
- $report['ARC']['DirCount'] = number_format($dirCount);
106
- $report['ARC']['FileCount'] = number_format($fileCount);
107
- $report['ARC']['FullCount'] = number_format($fullCount);
108
-
109
- $report['ARC']['FilterInfo']['Dirs'] = $this->Archive->FilterInfo->Dirs;
110
- $report['ARC']['FilterInfo']['Files'] = $this->Archive->FilterInfo->Files;
111
- $report['ARC']['FilterInfo']['Exts'] = $this->Archive->FilterInfo->Exts;
112
-
113
- $report['ARC']['Status']['Size'] = ($this->Archive->Size > DUPLICATOR_SCAN_SITE) ? 'Warn' : 'Good';
114
- $report['ARC']['Status']['Names'] = (count($this->Archive->FilterInfo->Files->Warning) + count($this->Archive->FilterInfo->Dirs->Warning)) ? 'Warn' : 'Good';
115
- $report['ARC']['Status']['Big'] = count($this->Archive->FilterInfo->Files->Size) ? 'Warn' : 'Good';
116
-
117
- $report['ARC']['Dirs'] = $this->Archive->Dirs;
118
- $report['ARC']['Files'] = $this->Archive->Files;
119
-
120
- //DATABASE
121
- $db = $this->Database->Stats();
122
- $report['DB'] = $db;
123
-
124
- $warnings = array($report['SRV']['WEB']['ALL'],
125
- $report['SRV']['PHP']['ALL'],
126
- $report['SRV']['WP']['ALL'],
127
- $report['ARC']['Status']['Size'],
128
- $report['ARC']['Status']['Names'],
129
- $report['ARC']['Status']['Big'],
130
- $db['Status']['Size'],
131
- $db['Status']['Rows'],
132
- $db['Status']['Case']);
133
-
134
- //array_count_values will throw a warning message if it has null values,
135
- //so lets replace all nulls with empty string
136
- foreach ($warnings as $i => $value) {
137
- if (is_null($value)) {
138
- $warnings[$i] = '';
139
- }
140
- }
141
- $warn_counts = is_array($warnings) ? array_count_values($warnings) : 0;
142
- $report['RPT']['Warnings'] = $warn_counts['Warn'];
143
- $report['RPT']['Success'] = $warn_counts['Good'];
144
- $report['RPT']['ScanTime'] = DUP_Util::ElapsedTime(DUP_Util::GetMicrotime(), $timerStart);
145
- $fp = fopen(DUPLICATOR_SSDIR_PATH_TMP . "/{$this->ScanFile}", 'w');
146
- fwrite($fp, json_encode($report));
147
- fclose($fp);
148
-
149
- return $report;
150
- }
151
-
152
- /**
153
- * Starts the package build process
154
- * @return DUP_Package
155
- */
156
- public function Build() {
157
-
158
- global $wp_version;
159
- global $wpdb;
160
- global $current_user;
161
-
162
- $timerStart = DUP_Util::GetMicrotime();
163
-
164
- $this->Archive->File = "{$this->NameHash}_archive.zip";
165
- $this->Installer->File = "{$this->NameHash}_installer.php";
166
- $this->Database->File = "{$this->NameHash}_database.sql";
167
- $this->WPUser = isset($current_user->user_login) ? $current_user->user_login : 'unknown';
168
-
169
- //START LOGGING
170
- DUP_Log::Open($this->NameHash);
171
- $php_max_time = @ini_get("max_execution_time");
172
- $php_max_memory = @ini_set('memory_limit', DUPLICATOR_PHP_MAX_MEMORY);
173
- $php_max_time = ($php_max_time == 0) ? "(0) no time limit imposed" : "[{$php_max_time}] not allowed";
174
- $php_max_memory = ($php_max_memory === false) ? "Unabled to set php memory_limit" : DUPLICATOR_PHP_MAX_MEMORY . " ({$php_max_memory} default)";
175
-
176
- $info = "********************************************************************************\n";
177
- $info .= "DUPLICATOR-LITE PACKAGE-LOG: " . @date("Y-m-d H:i:s") . "\n";
178
- $info .= "NOTICE: Do NOT post to public sites or forums \n";
179
- $info .= "********************************************************************************\n";
180
- $info .= "VERSION:\t" . DUPLICATOR_VERSION . "\n";
181
- $info .= "WORDPRESS:\t{$wp_version}\n";
182
- $info .= "PHP INFO:\t" . phpversion() . ' | ' . 'SAPI: ' . php_sapi_name() . "\n";
183
- $info .= "SERVER:\t\t{$_SERVER['SERVER_SOFTWARE']} \n";
184
- $info .= "PHP TIME LIMIT: {$php_max_time} \n";
185
- $info .= "PHP MAX MEMORY: {$php_max_memory} \n";
186
- $info .= "MEMORY STACK: " . DUP_Server::GetPHPMemory();
187
- DUP_Log::Info($info);
188
- $info = null;
189
-
190
- //CREATE DB RECORD
191
- $packageObj = serialize($this);
192
- if (! $packageObj) {
193
- DUP_Log::Error("Unable to serialize pacakge object while building record.");
194
- }
195
-
196
- $this->ID = $this->FindHashKey($this->Hash);
197
-
198
- if ($this->ID != 0){
199
- $this->SetStatus(DUP_PackageStatus::START);
200
- } else {
201
- $results = $wpdb->insert($wpdb->prefix . "duplicator_packages", array(
202
- 'name' => $this->Name,
203
- 'hash' => $this->Hash,
204
- 'status' => DUP_PackageStatus::START,
205
- 'created' => current_time('mysql', get_option('gmt_offset', 1)),
206
- 'owner' => isset($current_user->user_login) ? $current_user->user_login : 'unknown',
207
- 'package' => $packageObj)
208
- );
209
- if ($results === false) {
210
-
211
- $wpdb->print_error();
212
- DUP_Log::Error("Duplicator is unable to insert a package record into the database table.", "'{$wpdb->last_error}'");
213
- }
214
- $this->ID = $wpdb->insert_id;
215
- }
216
-
217
- //START BUILD
218
- //PHPs serialze method will return the object, but the ID above is not passed
219
- //for one reason or another so passing the object back in seems to do the trick
220
- $this->Database->Build($this);
221
- $this->Archive->Build($this);
222
- $this->Installer->Build($this);
223
-
224
-
225
- //INTEGRITY CHECKS
226
- DUP_Log::Info("\n********************************************************************************");
227
- DUP_Log::Info("INTEGRITY CHECKS:");
228
- DUP_Log::Info("********************************************************************************");
229
- $dbSizeRead = DUP_Util::ByteSize($this->Database->Size);
230
- $zipSizeRead = DUP_Util::ByteSize($this->Archive->Size);
231
- $exeSizeRead = DUP_Util::ByteSize($this->Installer->Size);
232
-
233
- DUP_Log::Info("SQL File: {$dbSizeRead}");
234
- DUP_Log::Info("Installer File: {$exeSizeRead}");
235
- DUP_Log::Info("Archive File: {$zipSizeRead} ");
236
-
237
- if ( !($this->Archive->Size && $this->Database->Size && $this->Installer->Size)) {
238
- DUP_Log::Error("A required file contains zero bytes.", "Archive Size: {$zipSizeRead} | SQL Size: {$dbSizeRead} | Installer Size: {$exeSizeRead}");
239
- }
240
-
241
- //Validate SQL files completed
242
- $sql_tmp_path = DUP_UTIL::SafePath(DUPLICATOR_SSDIR_PATH_TMP . '/'. $this->Database->File);
243
- $sql_complete_txt = DUP_Util::TailFile($sql_tmp_path, 3);
244
- if (! strstr($sql_complete_txt, 'DUPLICATOR_MYSQLDUMP_EOF')) {
245
- DUP_Log::Error("ERROR: SQL file not complete. The end of file marker was not found. Please try to re-create the package.");
246
- }
247
-
248
- $timerEnd = DUP_Util::GetMicrotime();
249
- $timerSum = DUP_Util::ElapsedTime($timerEnd, $timerStart);
250
-
251
- $this->Runtime = $timerSum;
252
- $this->ExeSize = $exeSizeRead;
253
- $this->ZipSize = $zipSizeRead;
254
-
255
- $this->buildCleanup();
256
-
257
- //FINAL REPORT
258
- $info = "\n********************************************************************************\n";
259
- $info .= "RECORD ID:[{$this->ID}]\n";
260
- $info .= "TOTAL PROCESS RUNTIME: {$timerSum}\n";
261
- $info .= "PEAK PHP MEMORY USED: " . DUP_Server::GetPHPMemory(true) . "\n";
262
- $info .= "DONE PROCESSING => {$this->Name} " . @date("Y-m-d H:i:s") . "\n";
263
-
264
- DUP_Log::Info($info);
265
- DUP_Log::Close();
266
-
267
- $this->SetStatus(DUP_PackageStatus::COMPLETE);
268
- return $this;
269
- }
270
-
271
- /**
272
- * Saves the active options associted with the active(latest) package.
273
- * @param $_POST $post The Post server object
274
- * @see DUP_Package::GetActive
275
- * @return void */
276
- public function SaveActive($post = null)
277
- {
278
- global $wp_version;
279
-
280
- if (isset($post)) {
281
- $post = stripslashes_deep($post);
282
-
283
- $name_chars = array(".", "-");
284
- $name = ( isset($post['package-name']) && ! empty($post['package-name'])) ? $post['package-name'] : self::GetDefaultName();
285
- $name = substr(sanitize_file_name($name), 0 , 40);
286
- $name = str_replace($name_chars, '', $name);
287
-
288
- $filter_dirs = isset($post['filter-dirs']) ? $this->parseDirectoryFilter($post['filter-dirs']) : '';
289
- $filter_exts = isset($post['filter-exts']) ? $this->parseExtensionFilter($post['filter-exts']) : '';
290
- $tablelist = isset($post['dbtables']) ? implode(',', $post['dbtables']) : '';
291
- $compatlist = isset($post['dbcompat']) ? implode(',', $post['dbcompat']) : '';
292
- $dbversion = preg_replace('/[^0-9.].*/', '', DUP_Util::MysqlVariableValue('version'));
293
- $dbversion = is_null($dbversion) ? '- unknown -' : $dbversion;
294
-
295
- //PACKAGE
296
- $this->Created = date("Y-m-d H:i:s");
297
- $this->Version = DUPLICATOR_VERSION;
298
- $this->VersionOS = defined('PHP_OS') ? PHP_OS : 'unknown';
299
- $this->VersionWP = $wp_version;
300
- $this->VersionPHP = phpversion();
301
- $this->VersionDB = $dbversion;
302
- $this->Name = $name;
303
- $this->Hash = $this->MakeHash();
304
- $this->NameHash = "{$this->Name}_{$this->Hash}";;
305
- $this->Notes = esc_html($post['package-notes']);
306
- //ARCHIVE
307
- $this->Archive->PackDir = rtrim(DUPLICATOR_WPROOTPATH, '/');
308
- $this->Archive->Format = 'ZIP';
309
- $this->Archive->FilterOn = isset($post['filter-on']) ? 1 : 0;
310
- $this->Archive->FilterDirs = esc_html($filter_dirs);
311
- $this->Archive->FilterExts = str_replace(array('.' ,' '), "", esc_html($filter_exts));
312
- //INSTALLER
313
- $this->Installer->OptsDBHost = esc_html($post['dbhost']);
314
- $this->Installer->OptsDBPort = esc_html($post['dbport']);
315
- $this->Installer->OptsDBName = esc_html($post['dbname']);
316
- $this->Installer->OptsDBUser = esc_html($post['dbuser']);
317
- $this->Installer->OptsSSLAdmin = isset($post['ssl-admin']) ? 1 : 0;
318
- $this->Installer->OptsSSLLogin = isset($post['ssl-login']) ? 1 : 0;
319
- $this->Installer->OptsCacheWP = isset($post['cache-wp']) ? 1 : 0;
320
- $this->Installer->OptsCachePath = isset($post['cache-path']) ? 1 : 0;
321
- $this->Installer->OptsURLNew = esc_html($post['url-new']);
322
- //DATABASE
323
- $this->Database->FilterOn = isset($post['dbfilter-on']) ? 1 : 0;
324
- $this->Database->FilterTables = esc_html($tablelist);
325
- $this->Database->Compatible = $compatlist;
326
-
327
- update_option(self::OPT_ACTIVE, $this);
328
- }
329
- }
330
-
331
- /**
332
- * Save any property of this class through reflection
333
- * @param $property A valid public property in this class
334
- * @param $value The value for the new dynamic property
335
- * @return void */
336
- public function SaveActiveItem($property, $value) {
337
- $package = self::GetActive();
338
-
339
- $reflectionClass = new ReflectionClass($package);
340
- $reflectionClass->getProperty($property)->setValue($package, $value);
341
- update_option(self::OPT_ACTIVE, $package);
342
- }
343
-
344
- /**
345
- * Sets the status to log the state of the build
346
- * @param $status The status level for where the package is
347
- * @return void */
348
- public function SetStatus($status) {
349
- global $wpdb;
350
-
351
- $packageObj = serialize($this);
352
-
353
- if (! isset($status)) {
354
- DUP_Log::Error("Package SetStatus did not receive a proper code.");
355
- }
356
-
357
- if (! $packageObj) {
358
- DUP_Log::Error("Package SetStatus was unable to serialize package object while updating record.");
359
- }
360
-
361
- $wpdb->flush();
362
- $table = $wpdb->prefix . "duplicator_packages";
363
- $sql = "UPDATE `{$table}` SET status = {$status}, package = '{$packageObj}' WHERE ID = {$this->ID}";
364
- $wpdb->query($sql);
365
- }
366
-
367
- /**
368
- * Does a hash already exisit
369
- * @return int Returns 0 if no has is found, if found returns the table ID
370
- */
371
- public function FindHashKey($hash) {
372
-
373
- global $wpdb;
374
-
375
- $table = $wpdb->prefix . "duplicator_packages";
376
- $qry = $wpdb->get_row("SELECT ID, hash FROM `{$table}` WHERE hash = '{$hash}'" );
377
- if ( strlen($qry->hash) == 0) {
378
- return 0;
379
- } else {
380
- return $qry->ID;
381
- }
382
-
383
- }
384
-
385
- /**
386
- * Makes the hashkey for the package files
387
- * @return string A unique hashkey */
388
- public function MakeHash() {
389
- return uniqid() . mt_rand(1000, 9999) . date("ymdHis");
390
- }
391
-
392
- /**
393
- * Gets the active package. The active package is defined as the package that was lasted saved.
394
- * Do to cache issues with the built in WP function get_option moved call to a direct DB call.
395
- * @see DUP_Package::SaveActive
396
- * @return DUP_Package
397
- */
398
- public static function GetActive() {
399
-
400
- global $wpdb;
401
- $obj = new DUP_Package();
402
- $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM `{$wpdb->options}` WHERE option_name = %s LIMIT 1", self::OPT_ACTIVE ) );
403
- if (is_object($row)) {
404
- $obj = @unserialize($row->option_value);
405
- }
406
- //Incase unserilaize fails
407
- $obj = (is_object($obj)) ? $obj : new DUP_Package();
408
- return $obj;
409
- }
410
-
411
- /**
412
- * Gets the Package by ID
413
- * @see DUP_Package::GetByID
414
- * @return DUP_Package
415
- */
416
- public static function GetByID($id) {
417
-
418
- global $wpdb;
419
- $obj = new DUP_Package();
420
-
421
- $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}duplicator_packages` WHERE ID = %s", $id ) );
422
- if (is_object($row)) {
423
- $obj = @unserialize($row->package);
424
- $obj->Status = $row->status;
425
- }
426
- //Incase unserilaize fails
427
- $obj = (is_object($obj)) ? $obj : null;
428
- return $obj;
429
- }
430
-
431
- /**
432
- * Creates a default name
433
- * @return string A default packagename
434
- */
435
- public static function GetDefaultName() {
436
- //Remove specail_chars from final result
437
- $special_chars = array(".", "-");
438
- $name = date('Ymd') . '_' . sanitize_title(get_bloginfo( 'name', 'display' ));
439
- $name = substr(sanitize_file_name($name), 0 , 40);
440
- $name = str_replace($special_chars, '', $name);
441
- return $name;
442
-
443
- }
444
-
445
- /**
446
- * Cleanup all tmp files
447
- * @param all empty all contents
448
- * @return void
449
- */
450
- public static function TmpCleanup($all = false) {
451
-
452
- //Delete all files now
453
- if ($all){
454
- $dir = DUPLICATOR_SSDIR_PATH_TMP . "/*";
455
- foreach (glob($dir) as $file) {
456
- unlink($file);
457
- }
458
- }
459
- //Remove scan files that are 24 hours old
460
- else {
461
- $dir = DUPLICATOR_SSDIR_PATH_TMP . "/*_scan.json";
462
- foreach (glob($dir) as $file) {
463
- if (filemtime($file) <= time() - 86400) {
464
- unlink($file);
465
- }
466
- }
467
- }
468
- }
469
-
470
- /**
471
- * Provides various date formats
472
- *
473
- * @param $date The date to format
474
- * @param $format Various date formats to apply
475
- *
476
- * @return a formated date
477
- */
478
- public static function FormatCreatedDate($date, $format = 1)
479
- {
480
- $date = new DateTime($date);
481
- switch ($format)
482
- {
483
- //YEAR
484
- case 1: return $date->format('Y-m-d H:i'); break;
485
- case 2: return $date->format('Y-m-d H:i:s'); break;
486
- case 3: return $date->format('y-m-d H:i'); break;
487
- case 4: return $date->format('y-m-d H:i:s'); break;
488
- //MONTH
489
- case 5: return $date->format('m-d-Y H:i'); break;
490
- case 6: return $date->format('m-d-Y H:i:s'); break;
491
- case 7: return $date->format('m-d-y H:i'); break;
492
- case 8: return $date->format('m-d-y H:i:s'); break;
493
- //DAY
494
- case 9: return $date->format('d-m-Y H:i'); break;
495
- case 10: return $date->format('d-m-Y H:i:s'); break;
496
- case 11: return $date->format('d-m-y H:i'); break;
497
- case 12: return $date->format('d-m-y H:i:s'); break;
498
- }
499
- }
500
-
501
- private function buildCleanup() {
502
-
503
- $files = DUP_Util::ListFiles(DUPLICATOR_SSDIR_PATH_TMP);
504
- $newPath = DUPLICATOR_SSDIR_PATH;
505
-
506
- if (function_exists('rename')) {
507
- foreach($files as $file){
508
- $name = basename($file);
509
- if (strstr($name, $this->NameHash)) {
510
- rename($file,"{$newPath}/{$name}");
511
- }
512
- }
513
- } else {
514
- foreach($files as $file){
515
- $name = basename($file);
516
- if (strstr($name, $this->NameHash)) {
517
- copy($file,"{$newPath}/{$name}");
518
- unlink($file);
519
- }
520
- }
521
- }
522
- }
523
-
524
- private function parseDirectoryFilter($dirs = "") {
525
- $dirs = str_replace(array("\n", "\t", "\r"), '', $dirs);
526
- $filter_dirs = "";
527
- $dir_array = array_unique(explode(";", $dirs));
528
- foreach ($dir_array as $val) {
529
- if (strlen($val) >= 2) {
530
- $filter_dirs .= DUP_Util::SafePath(trim(rtrim($val, "/\\"))) . ";";
531
- }
532
- }
533
- return $filter_dirs;
534
- }
535
-
536
- private function parseExtensionFilter($extensions = "") {
537
- $filter_exts = "";
538
- if (strlen($extensions) >= 1 && $extensions != ";") {
539
- $filter_exts = str_replace(array(' ', '.'), '', $extensions);
540
- $filter_exts = str_replace(",", ";", $filter_exts);
541
- $filter_exts = DUP_Util::StringAppend($extensions, ";");
542
- }
543
- return $filter_exts;
544
- }
545
-
546
- }
547
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/package/class.pack.archive.filters.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The base class for all filter types Directories/Files/Extentions
4
+ *
5
+ * @package Duplicator
6
+ * @subpackage classes/package
7
+ * @since 1.1.0
8
+ *
9
+ */
10
+ class DUP_Archive_Filter_Scope_Base
11
+ {
12
+ //All internal storage items that duplicator decides to filter
13
+ public $Core = array();
14
+ //Items when creating a package or template that a user decides to filter
15
+ public $Instance = array();
16
+ }
17
+
18
+ /**
19
+ * The filter types that belong to directories
20
+ *
21
+ * @package Duplicator
22
+ * @subpackage classes/package
23
+ * @since 1.1.0
24
+ *
25
+ */
26
+ class DUP_Archive_Filter_Scope_Directory extends DUP_Archive_Filter_Scope_Base
27
+ {
28
+ //Items that are not readable
29
+ public $Warning = array();
30
+ //Items that are not readable
31
+ public $Unreadable = array();
32
+ }
33
+
34
+ /**
35
+ * The filter types that belong to files
36
+ *
37
+ * @package Duplicator
38
+ * @subpackage classes/package
39
+ * @since 1.1.0
40
+ *
41
+ */
42
+ class DUP_Archive_Filter_Scope_File extends DUP_Archive_Filter_Scope_Directory
43
+ {
44
+ //Items that are too large
45
+ public $Size = array();
46
+
47
+ }
48
+
49
+ /**
50
+ * The filter information object which store all information about the filtered
51
+ * data that is gathered to the execution of a scan process
52
+ *
53
+ * @package Duplicator
54
+ * @subpackage classes/package
55
+ * @since 1.1.0
56
+ *
57
+ */
58
+ class DUP_Archive_Filter_Info
59
+ {
60
+ //Contains all folder filter info
61
+ public $Dirs = array();
62
+ //Contains all file filter info
63
+ public $Files = array();
64
+ //Contains all extensions filter info
65
+ public $Exts = array();
66
+ public $UDirCount = 0;
67
+ public $UFileCount = 0;
68
+ public $UExtCount = 0;
69
+
70
+ /**
71
+ * Init this object
72
+ */
73
+ public function __construct()
74
+ {
75
+ $this->Dirs = new DUP_Archive_Filter_Scope_Directory();
76
+ $this->Files = new DUP_Archive_Filter_Scope_File();
77
+ $this->Exts = new DUP_Archive_Filter_Scope_Base();
78
+ }
79
+ }
80
+
classes/package/class.pack.archive.php ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('DUPLICATOR_VERSION')) exit; // Exit if accessed directly
3
+
4
+ require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/class.pack.archive.filters.php');
5
+ require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/class.pack.archive.zip.php');
6
+ require_once (DUPLICATOR_PLUGIN_PATH.'lib/forceutf8/Encoding.php');
7
+
8
+ /**
9
+ * Used to create the archive file
10
+ *
11
+ * @package Duplicator
12
+ * @subpackage classes/package
13
+ * @copyright (c) 2017, Snapcreek LLC
14
+ * @since 1.1.0
15
+ *
16
+ */
17
+ class DUP_Archive
18
+ {
19
+ //PUBLIC
20
+ public $FilterDirs;
21
+ public $FilterExts;
22
+ public $FilterDirsAll = array();
23
+ public $FilterExtsAll = array();
24
+ public $FilterOn;
25
+ public $File;
26
+ public $Format;
27
+ public $PackDir;
28
+ public $Size = 0;
29
+ public $Dirs = array();
30
+ public $Files = array();
31
+ public $FilterInfo;
32
+ //PROTECTED
33
+ protected $Package;
34
+
35
+
36
+ /**
37
+ * Init this object
38
+ */
39
+ public function __construct($package)
40
+ {
41
+ $this->Package = $package;
42
+ $this->FilterOn = false;
43
+ $this->FilterInfo = new DUP_Archive_Filter_Info();
44
+ }
45
+
46
+ /**
47
+ * Builds the archive based on the archive type
48
+ *
49
+ * @param obj $package The package object that started this process
50
+ *
51
+ * @return null
52
+ */
53
+ public function build($package)
54
+ {
55
+ try {
56
+ $this->Package = $package;
57
+ if (!isset($this->PackDir) && !is_dir($this->PackDir)) throw new Exception("The 'PackDir' property must be a valid diretory.");
58
+ if (!isset($this->File)) throw new Exception("A 'File' property must be set.");
59
+
60
+ $this->Package->setStatus(DUP_PackageStatus::ARCSTART);
61
+ switch ($this->Format) {
62
+ case 'TAR': break;
63
+ case 'TAR-GZIP': break;
64
+ default:
65
+ if (class_exists(ZipArchive)) {
66
+ $this->Format = 'ZIP';
67
+ DUP_Zip::create($this);
68
+ }
69
+ break;
70
+ }
71
+
72
+ $storePath = "{$this->Package->StorePath}/{$this->File}";
73
+ $this->Size = @filesize($storePath);
74
+ $this->Package->setStatus(DUP_PackageStatus::ARCDONE);
75
+ } catch (Exception $e) {
76
+ echo 'Caught exception: ', $e->getMessage(), "\n";
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Gets the filter directory paths as an array
82
+ *
83
+ * @return array Returns an array of filter directory paths
84
+ */
85
+ public function getFilterDirAsArray()
86
+ {
87
+ return array_map('DUP_Util::safePath', explode(";", $this->FilterDirs, -1));
88
+ }
89
+
90
+ /**
91
+ * Gets the filter file extensions as an array
92
+ *
93
+ * @return array Returns an array of filter file extensions
94
+ */
95
+ public function getFilterExtsAsArray()
96
+ {
97
+ return explode(";", $this->FilterExts, -1);
98
+ }
99
+
100
+ /**
101
+ * Builds a list of files and directories to be included in the archive
102
+ *
103
+ * Get the directory size recursively, but don't calc the snapshot directory, exclusion diretories
104
+ * @link http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx Windows filename restrictions
105
+ *
106
+ * @return obj Returns a DUP_Archive object
107
+ */
108
+ public function getScanData()
109
+ {
110
+ $this->createFilterInfo();
111
+ $this->getDirs();
112
+ $this->getFiles();
113
+ return $this;
114
+ }
115
+
116
+ /**
117
+ * Creates the filter info setup data used for filtering the archive
118
+ *
119
+ * @return null
120
+ */
121
+ private function createFilterInfo()
122
+ {
123
+ //FILTER: INSTANCE ITEMS
124
+ //Add the items generated at create time
125
+ if ($this->FilterOn) {
126
+ $this->FilterInfo->Dirs->Instance = array_map('DUP_Util::safePath', explode(";", $this->FilterDirs, -1));
127
+ $this->FilterInfo->Exts->Instance = explode(";", $this->FilterExts, -1);
128
+ }
129
+
130
+ //FILTER: CORE ITMES
131
+ //Filters Duplicator free packages & All pro local directories
132
+ $this->FilterInfo->Dirs->Core[] = DUPLICATOR_SSDIR_PATH;
133
+
134
+ $this->FilterDirsAll = array_merge($this->FilterInfo->Dirs->Instance, $this->FilterInfo->Dirs->Core);
135
+ $this->FilterExtsAll = array_merge($this->FilterInfo->Exts->Instance, $this->FilterInfo->Exts->Core);
136
+ }
137
+
138
+ /**
139
+ * Builds the directory list and directory filter lists
140
+ *
141
+ * @return null
142
+ */
143
+ private function getDirs()
144
+ {
145
+ $rootPath = DUP_Util::safePath(rtrim(DUPLICATOR_WPROOTPATH, '//'));
146
+ $this->Dirs = array();
147
+
148
+ //If the root directory is a filter then we will only need the root files
149
+ if (in_array($this->PackDir, $this->FilterDirsAll)) {
150
+ $this->Dirs[] = $this->PackDir;
151
+ } else {
152
+ $this->Dirs = $this->dirsToArray($rootPath, $this->FilterDirsAll);
153
+ $this->Dirs[] = $this->PackDir;
154
+ }
155
+
156
+ //Filter Directories
157
+ //Invalid test contains checks for: characters over 250, invlaid characters,
158
+ //empty string and directories ending with period (Windows incompatable)
159
+ foreach ($this->Dirs as $key => $val) {
160
+ $name = basename($val);
161
+
162
+ $warn_test = strlen($val) > 250 || preg_match('/(\/|\*|\?|\>|\<|\:|\\|\|)/', $name)
163
+ || trim($name) == "" || (strrpos($name, '.') == strlen($name) - 1 && substr($name, -1) == '.')
164
+ || preg_match('/[^\x20-\x7f]/', $name);
165
+ if ($warn_test) {
166
+ $this->FilterInfo->Dirs->Warning[] = DUP_Encoding::toUTF8($val);
167
+ }
168
+
169
+ //UNREADABLE: Directory is unreadable flag it
170
+ if (!is_readable($this->Dirs[$key])) {
171
+ unset($this->Dirs[$key]);
172
+ $this->FilterInfo->Dirs->Unreadable[] = $val;
173
+ $this->FilterDirsAll[] = $val;
174
+ }
175
+ }
176
+ }
177
+
178
+
179
+ /**
180
+ * Get all files and filter out error prone subsets
181
+ *
182
+ * @return null
183
+ */
184
+ private function getFiles()
185
+ {
186
+ foreach ($this->Dirs as $key => $val) {
187
+ $files = DUP_Util::listFiles($val);
188
+ foreach ($files as $filePath) {
189
+ $fileName = basename($filePath);
190
+ if (!is_dir($filePath)) {
191
+ if (!in_array(@pathinfo($filePath, PATHINFO_EXTENSION), $this->FilterExtsAll)) {
192
+ //Unreadable
193
+ if (!is_readable($filePath)) {
194
+ $this->FilterInfo->Files->Unreadable[] = $filePath;
195
+ continue;
196
+ }
197
+
198
+ $fileSize = @filesize($filePath);
199
+ $fileSize = empty($fileSize) ? 0 : $fileSize;
200
+ $invalid_test = strlen($filePath) > 250 ||
201
+ preg_match('/(\/|\*|\?|\>|\<|\:|\\|\|)/', $fileName) ||
202
+ trim($fileName) == "";
203
+
204
+ if ($invalid_test || preg_match('/[^\x20-\x7f]/', $fileName)) {
205
+ $filePath = DUP_Encoding::toUTF8($filePath);
206
+ $this->FilterInfo->Files->Warning[] = $filePath;
207
+ }
208
+ $this->Size += $fileSize;
209
+ $this->Files[] = $filePath;
210
+
211
+
212
+ if ($fileSize > DUPLICATOR_SCAN_WARNFILESIZE) {
213
+ $this->FilterInfo->Files->Size[] = $filePath.' ['.DUP_Util::byteSize($fileSize).']';
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
219
+ }
220
+
221
+
222
+ /**
223
+ * Recursive function to get all Directories in a wp install
224
+ *
225
+ * @param string $path The path of the directory to add to the array
226
+ * @param array $filterDirsAll An array of all the filtered directories
227
+ *
228
+ * NOTE: Older PHP logic which is more stable on older version of PHP
229
+ * RecursiveIteratorIterator is problematic on some systems issues include:
230
+ * - error 'too many files open' for recursion
231
+ * - $file->getExtension() is not reliable as it silently fails at least in php 5.2.9
232
+ * - issues with when a file has a permission such as 705 and trying to get info (had to fallback to pathinfo)
233
+ * - basic conclusion wait on the SPL libs untill after php 5.4 is a requiremnt
234
+ * - inside a tight recursive loop lets remove the utiltiy call DUP_Util::safePath("{$path}/{$file}") and
235
+ * squeeze out as much performance as possible
236
+ *
237
+ * @return null
238
+ */
239
+ private function dirsToArray($path, $filterDirsAll)
240
+ {
241
+ $items = array();
242
+ $handle = @opendir($path);
243
+ if ($handle) {
244
+ while (($file = readdir($handle)) !== false) {
245
+ if ($file != '.' && $file != '..') {
246
+ $fullPath = str_replace("\\", '/', "{$path}/{$file}");
247
+
248
+ if (is_dir($fullPath)) {
249
+ $addDir = true;
250
+
251
+ //Remove path filter directories
252
+ foreach ($filterDirsAll as $filterDir) {
253
+ $trimmedFilterDir = rtrim($filterDir, '/');
254
+
255
+ if ($fullPath == $trimmedFilterDir || strstr($fullPath, $trimmedFilterDir.'/')) {
256
+ $addDir = false;
257
+ break;
258
+ }
259
+ }
260
+
261
+ if ($addDir) {
262
+ $items = array_merge($items, $this->dirsToArray($fullPath, $filterDirsAll));
263
+ $items[] = $fullPath;
264
+ }
265
+ }
266
+ }
267
+ }
268
+ closedir($handle);
269
+ }
270
+
271
+ return $items;
272
+ }
273
+ }
274
+ ?>
classes/package/class.pack.archive.zip.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('DUPLICATOR_VERSION')) exit; // Exit if accessed directly
3
+ require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/class.pack.archive.php');
4
+
5
+ /**
6
+ * Creates a zip file using the built in PHP ZipArchive class
7
+ */
8
+ class DUP_Zip extends DUP_Archive
9
+ {
10
+ //PRIVATE
11
+ private static $compressDir;
12
+ private static $countDirs = 0;
13
+ private static $countFiles = 0;
14
+ private static $sqlPath;
15
+ private static $zipPath;
16
+ private static $zipFileSize;
17
+ private static $zipArchive;
18
+ private static $limitItems = 0;
19
+ private static $networkFlush = false;
20
+ private static $scanReport;
21
+
22
+ /**
23
+ * Creates the zip file and adds the SQL file to the archive
24
+ */
25
+ public static function create(DUP_Archive $archive)
26
+ {
27
+ try {
28
+ $timerAllStart = DUP_Util::getMicrotime();
29
+ $package_zip_flush = DUP_Settings::Get('package_zip_flush');
30
+
31
+ self::$compressDir = rtrim(DUP_Util::safePath($archive->PackDir), '/');
32
+ self::$sqlPath = DUP_Util::safePath("{$archive->Package->StorePath}/{$archive->Package->Database->File}");
33
+ self::$zipPath = DUP_Util::safePath("{$archive->Package->StorePath}/{$archive->File}");
34
+ self::$zipArchive = new ZipArchive();
35
+ self::$networkFlush = empty($package_zip_flush) ? false : $package_zip_flush;
36
+
37
+ $filterDirs = empty($archive->FilterDirs) ? 'not set' : $archive->FilterDirs;
38
+ $filterExts = empty($archive->FilterExts) ? 'not set' : $archive->FilterExts;
39
+ $filterOn = ($archive->FilterOn) ? 'ON' : 'OFF';
40
+ $filterDirsFormat = rtrim(str_replace(';', "\n ", $filterDirs));
41
+ $lastDirSuccess = self::$compressDir;
42
+
43
+ //LOAD SCAN REPORT
44
+ $json = file_get_contents(DUPLICATOR_SSDIR_PATH_TMP."/{$archive->Package->NameHash}_scan.json");
45
+ self::$scanReport = json_decode($json);
46
+
47
+ DUP_Log::Info("\n********************************************************************************");
48
+ DUP_Log::Info("ARCHIVE (ZIP):");
49
+ DUP_Log::Info("********************************************************************************");
50
+ $isZipOpen = (self::$zipArchive->open(self::$zipPath, ZIPARCHIVE::CREATE) === TRUE);
51
+ if (!$isZipOpen) {
52
+ DUP_Log::Error("Cannot open zip file with PHP ZipArchive.", "Path location [".self::$zipPath."]");
53
+ }
54
+ DUP_Log::Info("ARCHIVE DIR: ".self::$compressDir);
55
+ DUP_Log::Info("ARCHIVE FILE: ".basename(self::$zipPath));
56
+ DUP_Log::Info("FILTERS: *{$filterOn}*");
57
+ DUP_Log::Info("DIRS: {$filterDirsFormat}");
58
+ DUP_Log::Info("EXTS: {$filterExts}");
59
+
60
+ DUP_Log::Info("----------------------------------------");
61
+ DUP_Log::Info("COMPRESSING");
62
+ DUP_Log::Info("SIZE:\t".self::$scanReport->ARC->Size);
63
+ DUP_Log::Info("STATS:\tDirs ".self::$scanReport->ARC->DirCount." | Files ".self::$scanReport->ARC->FileCount);
64
+
65
+ //ADD SQL
66
+ $isSQLInZip = self::$zipArchive->addFile(self::$sqlPath, "database.sql");
67
+ if ($isSQLInZip) {
68
+ DUP_Log::Info("SQL ADDED: ".basename(self::$sqlPath));
69
+ } else {
70
+ DUP_Log::Error("Unable to add database.sql to archive.", "SQL File Path [".self::$sqlath."]");
71
+ }
72
+ self::$zipArchive->close();
73
+ self::$zipArchive->open(self::$zipPath, ZipArchive::CREATE);
74
+
75
+ //ZIP DIRECTORIES
76
+ $info = '';
77
+ foreach (self::$scanReport->ARC->Dirs as $dir) {
78
+ if (is_readable($dir) && self::$zipArchive->addEmptyDir(ltrim(str_replace(self::$compressDir, '', $dir), '/'))) {
79
+ self::$countDirs++;
80
+ $lastDirSuccess = $dir;
81
+ } else {
82
+ //Don't warn when dirtory is the root path
83
+ if (strcmp($dir, rtrim(self::$compressDir, '/')) != 0) {
84
+ $dir_path = strlen($dir) ? "[{$dir}]" : "[Read Error] - last successful read was: [{$lastDirSuccess}]";
85
+ $info .= "DIR: {$dir_path}\n";
86
+ }
87
+ }
88
+ }
89
+
90
+ //LOG Unreadable DIR info
91
+ if (strlen($info)) {
92
+ DUP_Log::Info("\nWARNING: Unable to zip directories:");
93
+ DUP_Log::Info($info);
94
+ }
95
+
96
+ /* ZIP FILES: Network Flush
97
+ * This allows the process to not timeout on fcgi
98
+ * setups that need a response every X seconds */
99
+ $info = '';
100
+ if (self::$networkFlush) {
101
+ foreach (self::$scanReport->ARC->Files as $file) {
102
+ if (is_readable($file) && self::$zipArchive->addFile($file, ltrim(str_replace(self::$compressDir, '', $file), '/'))) {
103
+ self::$limitItems++;
104
+ self::$countFiles++;
105
+ } else {
106
+ $info .= "FILE: [{$file}]\n";
107
+ }
108
+ //Trigger a flush to the web server after so many files have been loaded.
109
+ if (self::$limitItems > DUPLICATOR_ZIP_FLUSH_TRIGGER) {
110
+ $sumItems = (self::$countDirs + self::$countFiles);
111
+ self::$zipArchive->close();
112
+ self::$zipArchive->open(self::$zipPath);
113
+ self::$limitItems = 0;
114
+ DUP_Util::fcgiFlush();
115
+ DUP_Log::Info("Items archived [{$sumItems}] flushing response.");
116
+ }
117
+ }
118
+ }
119
+ //Normal
120
+ else {
121
+ foreach (self::$scanReport->ARC->Files as $file) {
122
+ if (is_readable($file) && self::$zipArchive->addFile($file, ltrim(str_replace(self::$compressDir, '', $file), '/'))) {
123
+ self::$countFiles++;
124
+ } else {
125
+ $info .= "FILE: [{$file}]\n";
126
+ }
127
+ }
128
+ }
129
+
130
+ //LOG Unreadable FILE info
131
+ if (strlen($info)) {
132
+ DUP_Log::Info("\nWARNING: Unable to zip files:");
133
+ DUP_Log::Info($info);
134
+ unset($info);
135
+ }
136
+
137
+ DUP_Log::Info(print_r(self::$zipArchive, true));
138
+
139
+ //--------------------------------
140
+ //LOG FINAL RESULTS
141
+ DUP_Util::fcgiFlush();
142
+ $zipCloseResult = self::$zipArchive->close();
143
+ ($zipCloseResult) ? DUP_Log::Info("COMPRESSION RESULT: '{$zipCloseResult}'") : DUP_Log::Error("ZipArchive close failure.",
144
+ "This hosted server may have a disk quota limit.\nCheck to make sure this archive file can be stored.");
145
+
146
+ $timerAllEnd = DUP_Util::getMicrotime();
147
+ $timerAllSum = DUP_Util::elapsedTime($timerAllEnd, $timerAllStart);
148
+
149
+
150
+ self::$zipFileSize = @filesize(self::$zipPath);
151
+ DUP_Log::Info("COMPRESSED SIZE: ".DUP_Util::byteSize(self::$zipFileSize));
152
+ DUP_Log::Info("ARCHIVE RUNTIME: {$timerAllSum}");
153
+ DUP_Log::Info("MEMORY STACK: ".DUP_Server::getPHPMemory());
154
+ } catch (Exception $e) {
155
+ DUP_Log::Error("Runtime error in class.pack.archive.zip.php constructor.", "Exception: {$e}");
156
+ }
157
+ }
158
+ }
159
+ ?>
classes/package/class.pack.database.php ADDED
@@ -0,0 +1,375 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('DUPLICATOR_VERSION')) exit; // Exit if accessed directly
3
+
4
+ class DUP_Database
5
+ {
6
+ //PUBLIC
7
+ public $Type = 'MySQL';
8
+ public $Size;
9
+ public $File;
10
+ public $Path;
11
+ public $FilterTables;
12
+ public $FilterOn;
13
+ public $Name;
14
+ public $Compatible;
15
+ public $Comments;
16
+ //PROTECTED
17
+ protected $Package;
18
+ //PRIVATE
19
+ private $dbStorePath;
20
+ private $EOFMarker;
21
+ private $networkFlush;
22
+
23
+ /**
24
+ * Init this object
25
+ */
26
+ function __construct($package)
27
+ {
28
+ $this->Package = $package;
29
+ $this->EOFMarker = "";
30
+ $package_zip_flush = DUP_Settings::Get('package_zip_flush');
31
+ $this->networkFlush = empty($package_zip_flush) ? false : $package_zip_flush;
32
+ }
33
+
34
+ /**
35
+ * Build the database script
36
+ *
37
+ * @param obj $package A reference to the package that this database object belongs in
38
+ *
39
+ * @return null
40
+ */
41
+ public function build($package)
42
+ {
43
+ try {
44
+
45
+ $this->Package = $package;
46
+
47
+ $time_start = DUP_Util::getMicrotime();
48
+ $this->Package->setStatus(DUP_PackageStatus::DBSTART);
49
+ $this->dbStorePath = "{$this->Package->StorePath}/{$this->File}";
50
+
51
+ $package_mysqldump = DUP_Settings::Get('package_mysqldump');
52
+ $package_phpdump_qrylimit = DUP_Settings::Get('package_phpdump_qrylimit');
53
+
54
+ $mysqlDumpPath = DUP_DB::getMySqlDumpPath();
55
+ $mode = ($mysqlDumpPath && $package_mysqldump) ? 'MYSQLDUMP' : 'PHP';
56
+ $reserved_db_filepath = DUPLICATOR_WPROOTPATH.'database.sql';
57
+
58
+
59
+ $log = "\n********************************************************************************\n";
60
+ $log .= "DATABASE:\n";
61
+ $log .= "********************************************************************************\n";
62
+ $log .= "BUILD MODE: {$mode}";
63
+ $log .= ($mode == 'PHP') ? "(query limit - {$package_phpdump_qrylimit})\n" : "\n";
64
+ $log .= "MYSQLTIMEOUT: ".DUPLICATOR_DB_MAX_TIME."\n";
65
+ $log .= "MYSQLDUMP: ";
66
+ $log .= ($mysqlDumpPath) ? "Is Supported" : "Not Supported";
67
+ DUP_Log::Info($log);
68
+ $log = null;
69
+
70
+ //Reserved file found
71
+ if (file_exists($reserved_db_filepath)) {
72
+ DUP_Log::Error("Reserverd SQL file detected",
73
+ "The file database.sql was found at [{$reserved_db_filepath}].\n"
74
+ ."\tPlease remove/rename this file to continue with the package creation.");
75
+ }
76
+
77
+ switch ($mode) {
78
+ case 'MYSQLDUMP':
79
+ $this->mysqlDump($mysqlDumpPath);
80
+ break;
81
+ case 'PHP' :
82
+ $this->phpDump();
83
+ break;
84
+ }
85
+
86
+ DUP_Log::Info("SQL CREATED: {$this->File}");
87
+ $time_end = DUP_Util::getMicrotime();
88
+ $time_sum = DUP_Util::elapsedTime($time_end, $time_start);
89
+
90
+ //File below 10k will be incomplete
91
+ $sql_file_size = filesize($this->dbStorePath);
92
+ DUP_Log::Info("SQL FILE SIZE: ".DUP_Util::byteSize($sql_file_size)." ({$sql_file_size})");
93
+ if ($sql_file_size < 10000) {
94
+ DUP_Log::Error("SQL file size too low.", "File does not look complete. Check permission on file and parent directory at [{$this->dbStorePath}]");
95
+ }
96
+
97
+ DUP_Log::Info("SQL FILE TIME: ".date("Y-m-d H:i:s"));
98
+ DUP_Log::Info("SQL RUNTIME: {$time_sum}");
99
+
100
+ $this->Size = @filesize($this->dbStorePath);
101
+ $this->Package->setStatus(DUP_PackageStatus::DBDONE);
102
+ } catch (Exception $e) {
103
+ DUP_Log::Error("Runtime error in DUP_Database::Build", "Exception: {$e}");
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Get the database meta-data suc as tables as all there details
109
+ *
110
+ * @return array Returns an array full of meta-data about the database
111
+ */
112
+ public function getScanData()
113
+ {
114
+ global $wpdb;
115
+
116
+ $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : null;
117
+ $tblCount = 0;
118
+
119
+ $tables = $wpdb->get_results("SHOW TABLE STATUS", ARRAY_A);
120
+ $info = array();
121
+ $info['Status']['Success'] = is_null($tables) ? false : true;
122
+ //DB_Case for the database name is never checked on
123
+ $info['Status']['DB_Case'] = 'Good';
124
+ $info['Status']['DB_Rows'] = 'Good';
125
+ $info['Status']['DB_Size'] = 'Good';
126
+ $info['Status']['TBL_Case'] = 'Good';
127
+ $info['Status']['TBL_Rows'] = 'Good';
128
+ $info['Status']['TBL_Size'] = 'Good';
129
+
130
+ $info['Size'] = 0;
131
+ $info['Rows'] = 0;
132
+ $info['TableCount'] = 0;
133
+ $info['TableList'] = array();
134
+ $tblCaseFound = 0;
135
+ $tblRowsFound = 0;
136
+ $tblSizeFound = 0;
137
+
138
+ //Grab Table Stats
139
+ foreach ($tables as $table) {
140
+ $name = $table["Name"];
141
+ if ($this->FilterOn && is_array($filterTables)) {
142
+ if (in_array($name, $filterTables)) {
143
+ continue;
144
+ }
145
+ }
146
+
147
+ $size = ($table["Data_length"] + $table["Index_length"]);
148
+ $rows = empty($table["Rows"]) ? '0' : $table["Rows"];
149
+
150
+ $info['Size'] += $size;
151
+ $info['Rows'] += ($table["Rows"]);
152
+ $info['TableList'][$name]['Case'] = preg_match('/[A-Z]/', $name) ? 1 : 0;
153
+ $info['TableList'][$name]['Rows'] = number_format($rows);
154
+ $info['TableList'][$name]['Size'] = DUP_Util::byteSize($size);
155
+ $tblCount++;
156
+
157
+ //Table Uppercase
158
+ if ($info['TableList'][$name]['Case']) {
159
+ if (!$tblCaseFound) {
160
+ $tblCaseFound = 1;
161
+ }
162
+ }
163
+
164
+ //Table Row Count
165
+ if ($rows > DUPLICATOR_SCAN_DB_TBL_ROWS) {
166
+ if (!$tblRowsFound) {
167
+ $tblRowsFound = 1;
168
+ }
169
+ }
170
+
171
+ //Table Size
172
+ if ($size > DUPLICATOR_SCAN_DB_TBL_SIZE) {
173
+ if (!$tblSizeFound) {
174
+ $tblSizeFound = 1;
175
+ }
176
+ }
177
+ }
178
+
179
+ $info['Status']['DB_Case'] = preg_match('/[A-Z]/', $wpdb->dbname) ? 'Warn' : 'Good';
180
+ $info['Status']['DB_Rows'] = ($info['Rows'] > DUPLICATOR_SCAN_DB_ALL_ROWS) ? 'Warn' : 'Good';
181
+ $info['Status']['DB_Size'] = ($info['Size'] > DUPLICATOR_SCAN_DB_ALL_SIZE) ? 'Warn' : 'Good';
182
+
183
+
184
+ $info['Status']['TBL_Case'] = ($tblCaseFound) ? 'Warn' : 'Good';
185
+ $info['Status']['TBL_Rows'] = ($tblRowsFound) ? 'Warn' : 'Good';
186
+ $info['Status']['TBL_Size'] = ($tblSizeFound) ? 'Warn' : 'Good';
187
+
188
+ $info['Size'] = DUP_Util::byteSize($info['Size']) or "unknown";
189
+ $info['Rows'] = number_format($info['Rows']) or "unknown";
190
+ $info['TableList'] = $info['TableList'] or "unknown";
191
+ $info['TableCount'] = $tblCount;
192
+
193
+ return $info;
194
+ }
195
+
196
+ /**
197
+ * Build the database script using mysqldump
198
+ *
199
+ * @return bool Returns true if the sql script was succesfully created
200
+ */
201
+ private function mysqlDump($exePath)
202
+ {
203
+
204
+ global $wpdb;
205
+
206
+ $host = explode(':', DB_HOST);
207
+ $host = reset($host);
208
+ $port = strpos(DB_HOST, ':') ? end(explode(':', DB_HOST)) : '';
209
+ $name = DB_NAME;
210
+ $mysqlcompat_on = isset($this->Compatible) && strlen($this->Compatible);
211
+
212
+ //Build command
213
+ $cmd = escapeshellarg($exePath);
214
+ $cmd .= ' --no-create-db';
215
+ $cmd .= ' --single-transaction';
216
+ $cmd .= ' --hex-blob';
217
+ $cmd .= ' --skip-add-drop-table';
218
+
219
+ //Compatibility mode
220
+ if ($mysqlcompat_on) {
221
+ DUP_Log::Info("COMPATIBLE: [{$this->Compatible}]");
222
+ $cmd .= " --compatible={$this->Compatible}";
223
+ }
224
+
225
+ //Filter tables
226
+ $tables = $wpdb->get_col('SHOW TABLES');
227
+ $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : null;
228
+ $tblAllCount = count($tables);
229
+ $tblFilterOn = ($this->FilterOn) ? 'ON' : 'OFF';
230
+
231
+ if (is_array($filterTables) && $this->FilterOn) {
232
+ foreach ($tables as $key => $val) {
233
+ if (in_array($tables[$key], $filterTables)) {
234
+ $cmd .= " --ignore-table={$name}.{$tables[$key]} ";
235
+ unset($tables[$key]);
236
+ }
237
+ }
238
+ }
239
+
240
+ $cmd .= ' -u '.escapeshellarg(DB_USER);
241
+ $cmd .= (DB_PASSWORD) ? ' -p'.escapeshellarg(DB_PASSWORD) : '';
242
+ $cmd .= ' -h '.escapeshellarg($host);
243
+ $cmd .= (!empty($port) && is_numeric($port) ) ?
244
+ ' -P '.$port : '';
245
+ $cmd .= ' -r '.escapeshellarg($this->dbStorePath);
246
+ $cmd .= ' '.escapeshellarg(DB_NAME);
247
+ $cmd .= ' 2>&1';
248
+
249
+ $output = shell_exec($cmd);
250
+
251
+ // Password bug > 5.6 (@see http://bugs.mysql.com/bug.php?id=66546)
252
+ if (trim($output) === 'Warning: Using a password on the command line interface can be insecure.') {
253
+ $output = '';
254
+ }
255
+ $output = (strlen($output)) ? $output : "Ran from {$exePath}";
256
+
257
+ $tblCreateCount = count($tables);
258
+ $tblFilterCount = $tblAllCount - $tblCreateCount;
259
+
260
+ //DEBUG
261
+ //DUP_Log::Info("COMMAND: {$cmd}");
262
+ DUP_Log::Info("FILTERED: [{$this->FilterTables}]");
263
+ DUP_Log::Info("RESPONSE: {$output}");
264
+ DUP_Log::Info("TABLES: total:{$tblAllCount} | filtered:{$tblFilterCount} | create:{$tblCreateCount}");
265
+
266
+ $sql_footer = "\n\n/* Duplicator WordPress Timestamp: ".date("Y-m-d H:i:s")."*/\n";
267
+ $sql_footer .= "/* ".DUPLICATOR_DB_EOF_MARKER." */\n";
268
+ file_put_contents($this->dbStorePath, $sql_footer, FILE_APPEND);
269
+
270
+ return ($output) ? false : true;
271
+ }
272
+
273
+ /**
274
+ * Build the database script using php
275
+ *
276
+ * @return bool Returns true if the sql script was succesfully created
277
+ */
278
+ private function phpDump()
279
+ {
280
+
281
+ global $wpdb;
282
+
283
+ $wpdb->query("SET session wait_timeout = ".DUPLICATOR_DB_MAX_TIME);
284
+ $handle = fopen($this->dbStorePath, 'w+');
285
+ $tables = $wpdb->get_col('SHOW TABLES');
286
+
287
+ $filterTables = isset($this->FilterTables) ? explode(',', $this->FilterTables) : null;
288
+ $tblAllCount = count($tables);
289
+ $tblFilterOn = ($this->FilterOn) ? 'ON' : 'OFF';
290
+ $qryLimit = DUP_Settings::Get('package_phpdump_qrylimit');
291
+
292
+ if (is_array($filterTables) && $this->FilterOn) {
293
+ foreach ($tables as $key => $val) {
294
+ if (in_array($tables[$key], $filterTables)) {
295
+ unset($tables[$key]);
296
+ }
297
+ }
298
+ }
299
+ $tblCreateCount = count($tables);
300
+ $tblFilterCount = $tblAllCount - $tblCreateCount;
301
+
302
+ DUP_Log::Info("TABLES: total:{$tblAllCount} | filtered:{$tblFilterCount} | create:{$tblCreateCount}");
303
+ DUP_Log::Info("FILTERED: [{$this->FilterTables}]");
304
+
305
+ $sql_header = "/* DUPLICATOR MYSQL SCRIPT CREATED ON : ".@date("Y-m-d H:i:s")." */\n\n";
306
+ $sql_header .= "SET FOREIGN_KEY_CHECKS = 0;\n\n";
307
+ fwrite($handle, $sql_header);
308
+
309
+ //BUILD CREATES:
310
+ //All creates must be created before inserts do to foreign key constraints
311
+ foreach ($tables as $table) {
312
+ //$sql_del = ($GLOBALS['duplicator_opts']['dbadd_drop']) ? "DROP TABLE IF EXISTS {$table};\n\n" : "";
313
+ //@fwrite($handle, $sql_del);
314
+ $create = $wpdb->get_row("SHOW CREATE TABLE `{$table}`", ARRAY_N);
315
+ @fwrite($handle, "{$create[1]};\n\n");
316
+ }
317
+
318
+ //BUILD INSERTS:
319
+ //Create Insert in 100 row increments to better handle memory
320
+ foreach ($tables as $table) {
321
+
322
+ $row_count = $wpdb->get_var("SELECT Count(*) FROM `{$table}`");
323
+ //DUP_Log::Info("{$table} ({$row_count})");
324
+
325
+ if ($row_count > $qryLimit) {
326
+ $row_count = ceil($row_count / $qryLimit);
327
+ } else if ($row_count > 0) {
328
+ $row_count = 1;
329
+ }
330
+
331
+ if ($row_count >= 1) {
332
+ fwrite($handle, "\n/* INSERT TABLE DATA: {$table} */\n");
333
+ }
334
+
335
+ for ($i = 0; $i < $row_count; $i++) {
336
+ $sql = "";
337
+ $limit = $i * $qryLimit;
338
+ $query = "SELECT * FROM `{$table}` LIMIT {$limit}, {$qryLimit}";
339
+ $rows = $wpdb->get_results($query, ARRAY_A);
340
+ if (is_array($rows)) {
341
+ foreach ($rows as $row) {
342
+ $sql .= "INSERT INTO `{$table}` VALUES(";
343
+ $num_values = count($row);
344
+ $num_counter = 1;
345
+ foreach ($row as $value) {
346
+ if (is_null($value) || !isset($value)) {
347
+ ($num_values == $num_counter) ? $sql .= 'NULL' : $sql .= 'NULL, ';
348
+ } else {
349
+ ($num_values == $num_counter) ? $sql .= '"'.@esc_sql($value).'"' : $sql .= '"'.@esc_sql($value).'", ';
350
+ }
351
+ $num_counter++;
352
+ }
353
+ $sql .= ");\n";
354
+ }
355
+ fwrite($handle, $sql);
356
+ }
357
+ }
358
+
359
+ //Flush buffer if enabled
360
+ if ($this->networkFlush) {
361
+ DUP_Util::fcgiFlush();
362
+ }
363
+ $sql = null;
364
+ $rows = null;
365
+ }
366
+
367
+ $sql_footer = "\nSET FOREIGN_KEY_CHECKS = 1; \n\n";
368
+ $sql_footer .= "/* Duplicator WordPress Timestamp: ".date("Y-m-d H:i:s")."*/\n";
369
+ $sql_footer .= "/* ".DUPLICATOR_DB_EOF_MARKER." */\n";
370
+ fwrite($handle, $sql_footer);
371
+ $wpdb->flush();
372
+ fclose($handle);
373
+ }
374
+ }
375
+ ?>
classes/package/class.pack.installer.php ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('DUPLICATOR_VERSION')) exit; // Exit if accessed directly
3
+
4
+ class DUP_Installer
5
+ {
6
+ //PUBLIC
7
+ public $File;
8
+ public $Size = 0;
9
+ public $OptsDBHost;
10
+ public $OptsDBPort;
11
+ public $OptsDBName;
12
+ public $OptsDBUser;
13
+ public $OptsSSLAdmin;
14
+ public $OptsSSLLogin;
15
+ public $OptsCacheWP;
16
+ public $OptsCachePath;
17
+ public $OptsURLNew;
18
+ //PROTECTED
19
+ protected $Package;
20
+
21
+ /**
22
+ * Init this object
23
+ */
24
+ function __construct($package)
25
+ {
26
+ $this->Package = $package;
27
+ }
28
+
29
+ /**
30
+ * Build the installer script
31
+ *
32
+ * @param obj $package A reference to the package that this installer object belongs to
33
+ *
34
+ * @return null
35
+ */
36
+ public function build($package)
37
+ {
38
+
39
+ $this->Package = $package;
40
+
41
+ DUP_Log::Info("\n********************************************************************************");
42
+ DUP_Log::Info("MAKE INSTALLER:");
43
+ DUP_Log::Info("********************************************************************************");
44
+ DUP_Log::Info("Build Start");
45
+
46
+ $template_uniqid = uniqid('').'_'.time();
47
+ $template_path = DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP."/installer.template_{$template_uniqid}.php");
48
+ $main_path = DUP_Util::safePath(DUPLICATOR_PLUGIN_PATH.'installer/build/main.installer.php');
49
+ @chmod($template_path, 0777);
50
+ @chmod($main_path, 0777);
51
+
52
+ @touch($template_path);
53
+ $main_data = file_get_contents("{$main_path}");
54
+ $template_result = file_put_contents($template_path, $main_data);
55
+ if ($main_data === false || $template_result == false) {
56
+ $err_info = "These files may have permission issues. Please validate that PHP has read/write access.\n";
57
+ $err_info .= "Main Installer: '{$main_path}' \nTemplate Installer: '$template_path'";
58
+ DUP_Log::Error("Install builder failed to generate files.", "{$err_info}");
59
+ }
60
+
61
+ $embeded_files = array(
62
+ "assets/inc.libs.css.php" => "@@INC.LIBS.CSS.PHP@@",
63
+ "assets/inc.css.php" => "@@INC.CSS.PHP@@",
64
+ "assets/inc.libs.js.php" => "@@INC.LIBS.JS.PHP@@",
65
+ "assets/inc.js.php" => "@@INC.JS.PHP@@",
66
+ "classes/util/class.utils.php" => "@@CLASS.UTILS.PHP@@",
67
+ "classes/util/class.db.php" => "@@CLASS.DB.PHP@@",
68
+ "classes/class.logging.php" => "@@CLASS.LOGGING.PHP@@",
69
+ "classes/class.engine.php" => "@@CLASS.ENGINE.PHP@@",
70
+ "classes/config/class.conf.wp.php" => "@@CLASS.CONF.WP.PHP@@",
71
+ "classes/config/class.conf.srv.php" => "@@CLASS.CONF.SRV.PHP@@",
72
+ "ajax.step1.php" => "@@AJAX.STEP1.PHP@@",
73
+ "ajax.step2.php" => "@@AJAX.STEP2.PHP@@",
74
+ "view.step1.php" => "@@VIEW.STEP1.PHP@@",
75
+ "view.step2.php" => "@@VIEW.STEP2.PHP@@",
76
+ "view.step3.php" => "@@VIEW.STEP3.PHP@@",
77
+ "view.help.php" => "@@VIEW.HELP.PHP@@",);
78
+
79
+ foreach ($embeded_files as $name => $token) {
80
+ $file_path = DUPLICATOR_PLUGIN_PATH."installer/build/{$name}";
81
+ @chmod($file_path, 0777);
82
+
83
+ $search_data = @file_get_contents($template_path);
84
+ $insert_data = @file_get_contents($file_path);
85
+ file_put_contents($template_path, str_replace("${token}", "{$insert_data}", $search_data));
86
+ if ($search_data === false || $insert_data == false) {
87
+ DUP_Log::Error("Installer generation failed at {$token}.");
88
+ }
89
+ @chmod($file_path, 0644);
90
+ }
91
+
92
+ @chmod($template_path, 0644);
93
+ @chmod($main_path, 0644);
94
+
95
+ DUP_Log::Info("Build Finished");
96
+ $this->createFromTemplate($template_path);
97
+ $storePath = "{$this->Package->StorePath}/{$this->File}";
98
+ $this->Size = @filesize($storePath);
99
+ $this->addBackup();
100
+ }
101
+
102
+ /**
103
+ * Puts an installer zip file in the archive for backup purposes.
104
+ *
105
+ * @return null
106
+ */
107
+ private function addBackup()
108
+ {
109
+
110
+ $zipPath = DUP_Util::safePath("{$this->Package->StorePath}/{$this->Package->Archive->File}");
111
+ $installer = DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP)."/{$this->Package->NameHash}_installer.php";
112
+
113
+ $zipArchive = new ZipArchive();
114
+ if ($zipArchive->open($zipPath, ZIPARCHIVE::CREATE) === TRUE) {
115
+ if ($zipArchive->addFile($installer, "installer-backup.php")) {
116
+ DUP_Log::Info("Added to archive");
117
+ } else {
118
+ DUP_Log::Info("Unable to add installer-backup.php to archive.", "Installer File Path [{$installer}]");
119
+ }
120
+ $zipArchive->close();
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Generates the final installer file from the template file
126
+ *
127
+ * @param string $template The path to the installer template which is orginally copied from main.installer.php
128
+ *
129
+ * @return null
130
+ */
131
+ private function createFromTemplate($template)
132
+ {
133
+
134
+ global $wpdb;
135
+
136
+ DUP_Log::Info("Preping for use");
137
+ $installer = DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP)."/{$this->Package->NameHash}_installer.php";
138
+
139
+ //Option values to delete at install time
140
+ $deleteOpts = $GLOBALS['DUPLICATOR_OPTS_DELETE'];
141
+
142
+ $replace_items = Array(
143
+ //COMPARE VALUES
144
+ "fwrite_created" => $this->Package->Created,
145
+ "fwrite_version_dup" => DUPLICATOR_VERSION,
146
+ "fwrite_version_wp" => $this->Package->VersionWP,
147
+ "fwrite_version_db" => $this->Package->VersionDB,
148
+ "fwrite_version_php" => $this->Package->VersionPHP,
149
+ "fwrite_version_os" => $this->Package->VersionOS,
150
+ //GENERAL
151
+ "fwrite_url_old" => get_option('siteurl'),
152
+ "fwrite_package_name" => "{$this->Package->NameHash}_archive.zip",
153
+ "fwrite_package_notes" => $this->Package->Notes,
154
+ "fwrite_secure_name" => $this->Package->NameHash,
155
+ "fwrite_url_new" => $this->Package->Installer->OptsURLNew,
156
+ "fwrite_dbhost" => $this->Package->Installer->OptsDBHost,
157
+ "fwrite_dbport" => $this->Package->Installer->OptsDBPort,
158
+ "fwrite_dbname" => $this->Package->Installer->OptsDBName,
159
+ "fwrite_dbuser" => $this->Package->Installer->OptsDBUser,
160
+ "fwrite_dbpass" => '',
161
+ "fwrite_ssl_admin" => $this->Package->Installer->OptsSSLAdmin,
162
+ "fwrite_ssl_login" => $this->Package->Installer->OptsSSLLogin,
163
+ "fwrite_cache_wp" => $this->Package->Installer->OptsCacheWP,
164
+ "fwrite_cache_path" => $this->Package->Installer->OptsCachePath,
165
+ "fwrite_wp_tableprefix" => $wpdb->prefix,
166
+ "fwrite_opts_delete" => json_encode($deleteOpts),
167
+ "fwrite_blogname" => esc_html(get_option('blogname')),
168
+ "fwrite_wproot" => DUPLICATOR_WPROOTPATH,
169
+ "fwrite_duplicator_version" => DUPLICATOR_VERSION);
170
+
171
+ if (file_exists($template) && is_readable($template)) {
172
+ $err_msg = "ERROR: Unable to read/write installer. \nERROR INFO: Check permission/owner on file and parent folder.\nInstaller File = <{$installer}>";
173
+ $install_str = $this->parseTemplate($template, $replace_items);
174
+ (empty($install_str)) ? DUP_Log::Error("{$err_msg}", "DUP_Installer::createFromTemplate => file-empty-read") : DUP_Log::Info("Template parsed with new data");
175
+
176
+ //INSTALLER FILE
177
+ $fp = (!file_exists($installer)) ? fopen($installer, 'x+') : fopen($installer, 'w');
178
+ if (!$fp || !fwrite($fp, $install_str, strlen($install_str))) {
179
+ DUP_Log::Error("{$err_msg}", "DUP_Installer::createFromTemplate => file-write-error");
180
+ }
181
+
182
+ @fclose($fp);
183
+ } else {
184
+ DUP_Log::Error("Installer Template missing or unreadable.", "Template [{$template}]");
185
+ }
186
+ @unlink($template);
187
+ DUP_Log::Info("Complete [{$installer}]");
188
+ }
189
+
190
+ /**
191
+ * Tokenize a file based on an array key
192
+ *
193
+ * @param string $filename The filename to tokenize
194
+ * @param array $data The array of key value items to tokenize
195
+ */
196
+ private function parseTemplate($filename, $data)
197
+ {
198
+ $q = file_get_contents($filename);
199
+ foreach ($data as $key => $value) {
200
+ //NOTE: Use var_export as it's probably best and most "thorough" way to
201
+ //make sure the values are set correctly in the template. But in the template,
202
+ //need to make things properly formatted so that when real syntax errors
203
+ //exist they are easy to spot. So the values will be surrounded by quotes
204
+
205
+ $find = array("'%{$key}%'", "\"%{$key}%\"");
206
+ $q = str_replace($find, var_export($value, true), $q);
207
+ //now, account for places that do not surround with quotes... these
208
+ //places do NOT need to use var_export as they are not inside strings
209
+ $q = str_replace('%'.$key.'%', $value, $q);
210
+ }
211
+ return $q;
212
+ }
213
+ }
214
+ ?>
classes/package/class.pack.php ADDED
@@ -0,0 +1,622 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('DUPLICATOR_VERSION')) exit; // Exit if accessed directly
3
+
4
+ require_once (DUPLICATOR_PLUGIN_PATH.'classes/utilities/class.util.php');
5
+ require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/class.pack.archive.php');
6
+ require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/class.pack.installer.php');
7
+ require_once (DUPLICATOR_PLUGIN_PATH.'classes/package/class.pack.database.php');
8
+
9
+ final class DUP_PackageStatus
10
+ {
11
+
12
+ private function __construct()
13
+ {
14
+
15
+ }
16
+ const START = 10;
17
+ const DBSTART = 20;
18
+ const DBDONE = 30;
19
+ const ARCSTART = 40;
20
+ const ARCDONE = 50;
21
+ const COMPLETE = 100;
22
+
23
+ }
24
+
25
+ final class DUP_PackageType
26
+ {
27
+ const MANUAL = 0;
28
+ const SCHEDULED = 1;
29
+
30
+ }
31
+
32
+ /**
33
+ * Class used to store and process all Package logic
34
+ *
35
+ * @package Dupicator\classes
36
+ */
37
+ class DUP_Package
38
+ {
39
+ const OPT_ACTIVE = 'duplicator_package_active';
40
+
41
+ //Properties
42
+ public $Created;
43
+ public $Version;
44
+ public $VersionWP;
45
+ public $VersionDB;
46
+ public $VersionPHP;
47
+ public $VersionOS;
48
+ public $ID;
49
+ public $Name;
50
+ public $Hash;
51
+ public $NameHash;
52
+ public $Type;
53
+ public $Notes;
54
+ public $StorePath;
55
+ public $StoreURL;
56
+ public $ScanFile;
57
+ public $Runtime;
58
+ public $ExeSize;
59
+ public $ZipSize;
60
+ public $Status;
61
+ public $WPUser;
62
+ //Objects
63
+ public $Archive;
64
+ public $Installer;
65
+ public $Database;
66
+
67
+ /**
68
+ * Manages the Package Process
69
+ */
70
+ function __construct()
71
+ {
72
+
73
+ $this->ID = null;
74
+ $this->Version = DUPLICATOR_VERSION;
75
+
76
+ $this->Type = DUP_PackageType::MANUAL;
77
+ $this->Name = self::getDefaultName();
78
+ $this->Notes = null;
79
+ $this->StoreURL = DUP_Util::snapshotURL();
80
+ $this->StorePath = DUPLICATOR_SSDIR_PATH_TMP;
81
+ $this->Database = new DUP_Database($this);
82
+ $this->Archive = new DUP_Archive($this);
83
+ $this->Installer = new DUP_Installer($this);
84
+ }
85
+
86
+ /**
87
+ * Generates a json scan report
88
+ *
89
+ * @return array of scan results
90
+ *
91
+ * @notes: Testing = /wp-admin/admin-ajax.php?action=duplicator_package_scan
92
+ */
93
+ public function runScanner()
94
+ {
95
+ $timerStart = DUP_Util::getMicrotime();
96
+ $report = array();
97
+ $this->ScanFile = "{$this->NameHash}_scan.json";
98
+
99
+ $report['RPT']['ScanTime'] = "0";
100
+ $report['RPT']['ScanFile'] = $this->ScanFile;
101
+
102
+ //SERVER
103
+ $srv = DUP_Server::getChecks();
104
+ $report['SRV'] = $srv['SRV'];
105
+
106
+ //FILES
107
+ $this->Archive->getScanData();
108
+ $dirCount = count($this->Archive->Dirs);
109
+ $fileCount = count($this->Archive->Files);
110
+ $fullCount = $dirCount + $fileCount;
111
+
112
+ $report['ARC']['Size'] = DUP_Util::byteSize($this->Archive->Size) or "unknown";
113
+ $report['ARC']['DirCount'] = number_format($dirCount);
114
+ $report['ARC']['FileCount'] = number_format($fileCount);
115
+ $report['ARC']['FullCount'] = number_format($fullCount);
116
+
117
+ $report['ARC']['FilterInfo']['Dirs'] = $this->Archive->FilterInfo->Dirs;
118
+ $report['ARC']['FilterInfo']['Files'] = $this->Archive->FilterInfo->Files;
119
+ $report['ARC']['FilterInfo']['Exts'] = $this->Archive->FilterInfo->Exts;
120
+
121
+ $report['ARC']['Status']['Size'] = ($this->Archive->Size > DUPLICATOR_SCAN_SITE) ? 'Warn' : 'Good';
122
+ $report['ARC']['Status']['Names'] = (count($this->Archive->FilterInfo->Files->Warning) + count($this->Archive->FilterInfo->Dirs->Warning)) ? 'Warn' : 'Good';
123
+ $report['ARC']['Status']['Big'] = count($this->Archive->FilterInfo->Files->Size) ? 'Warn' : 'Good';
124
+
125
+ $report['ARC']['Dirs'] = $this->Archive->Dirs;
126
+ $report['ARC']['Files'] = $this->Archive->Files;
127
+
128
+ //DATABASE
129
+ $db = $this->Database->getScanData();
130
+ $report['DB'] = $db;
131
+
132
+ $warnings = array($report['SRV']['WEB']['ALL'],
133
+ $report['SRV']['PHP']['ALL'],
134
+ $report['SRV']['WP']['ALL'],
135
+ $report['ARC']['Status']['Size'],
136
+ $report['ARC']['Status']['Names'],
137
+ $report['ARC']['Status']['Big'],
138
+ $db['Status']['Size'],
139
+ $db['Status']['Rows'],
140
+ $db['Status']['Case']);
141
+
142
+ //array_count_values will throw a warning message if it has null values,
143
+ //so lets replace all nulls with empty string
144
+ foreach ($warnings as $i => $value) {
145
+ if (is_null($value)) {
146
+ $warnings[$i] = '';
147
+ }
148
+ }
149
+ $warn_counts = is_array($warnings) ? array_count_values($warnings) : 0;
150
+ $report['RPT']['Warnings'] = $warn_counts['Warn'];
151
+ $report['RPT']['Success'] = $warn_counts['Good'];
152
+ $report['RPT']['ScanTime'] = DUP_Util::elapsedTime(DUP_Util::getMicrotime(), $timerStart);
153
+ $fp = fopen(DUPLICATOR_SSDIR_PATH_TMP."/{$this->ScanFile}", 'w');
154
+ fwrite($fp, json_encode($report));
155
+ fclose($fp);
156
+
157
+ return $report;
158
+ }
159
+
160
+ /**
161
+ * Starts the package build process
162
+ *
163
+ * @return obj Retuns a DUP_Package object
164
+ */
165
+ public function runBuild()
166
+ {
167
+
168
+ global $wp_version;
169
+ global $wpdb;
170
+ global $current_user;
171
+
172
+ $timerStart = DUP_Util::getMicrotime();
173
+
174
+ $this->Archive->File = "{$this->NameHash}_archive.zip";
175
+ $this->Installer->File = "{$this->NameHash}_installer.php";
176
+ $this->Database->File = "{$this->NameHash}_database.sql";
177
+ $this->WPUser = isset($current_user->user_login) ? $current_user->user_login : 'unknown';
178
+
179
+ //START LOGGING
180
+ DUP_Log::Open($this->NameHash);
181
+ $php_max_time = @ini_get("max_execution_time");
182
+ $php_max_memory = @ini_set('memory_limit', DUPLICATOR_PHP_MAX_MEMORY);
183
+ $php_max_time = ($php_max_time == 0) ? "(0) no time limit imposed" : "[{$php_max_time}] not allowed";
184
+ $php_max_memory = ($php_max_memory === false) ? "Unabled to set php memory_limit" : DUPLICATOR_PHP_MAX_MEMORY." ({$php_max_memory} default)";
185
+
186
+ $info = "********************************************************************************\n";
187
+ $info .= "DUPLICATOR-LITE PACKAGE-LOG: ".@date("Y-m-d H:i:s")."\n";
188
+ $info .= "NOTICE: Do NOT post to public sites or forums \n";
189
+ $info .= "********************************************************************************\n";
190
+ $info .= "VERSION:\t".DUPLICATOR_VERSION."\n";
191
+ $info .= "WORDPRESS:\t{$wp_version}\n";
192
+ $info .= "PHP INFO:\t".phpversion().' | '.'SAPI: '.php_sapi_name()."\n";
193
+ $info .= "SERVER:\t\t{$_SERVER['SERVER_SOFTWARE']} \n";
194
+ $info .= "PHP TIME LIMIT: {$php_max_time} \n";
195
+ $info .= "PHP MAX MEMORY: {$php_max_memory} \n";
196
+ $info .= "MEMORY STACK: ".DUP_Server::getPHPMemory();
197
+ DUP_Log::Info($info);
198
+ $info = null;
199
+
200
+ //CREATE DB RECORD
201
+ $packageObj = serialize($this);
202
+ if (!$packageObj) {
203
+ DUP_Log::Error("Unable to serialize pacakge object while building record.");
204
+ }
205
+
206
+ $this->ID = $this->getHashKey($this->Hash);
207
+
208
+ if ($this->ID != 0) {
209
+ $this->setStatus(DUP_PackageStatus::START);
210
+ } else {
211
+ $results = $wpdb->insert($wpdb->prefix."duplicator_packages",
212
+ array(
213
+ 'name' => $this->Name,
214
+ 'hash' => $this->Hash,
215
+ 'status' => DUP_PackageStatus::START,
216
+ 'created' => current_time('mysql', get_option('gmt_offset', 1)),
217
+ 'owner' => isset($current_user->user_login) ? $current_user->user_login : 'unknown',
218
+ 'package' => $packageObj)
219
+ );
220
+ if ($results === false) {
221
+
222
+ $wpdb->print_error();
223
+ DUP_Log::Error("Duplicator is unable to insert a package record into the database table.", "'{$wpdb->last_error}'");
224
+ }
225
+ $this->ID = $wpdb->insert_id;
226
+ }
227
+
228
+ //START BUILD
229
+ //PHPs serialze method will return the object, but the ID above is not passed
230
+ //for one reason or another so passing the object back in seems to do the trick
231
+ $this->Database->build($this);
232
+ $this->Archive->build($this);
233
+ $this->Installer->build($this);
234
+
235
+
236
+ //INTEGRITY CHECKS
237
+ DUP_Log::Info("\n********************************************************************************");
238
+ DUP_Log::Info("INTEGRITY CHECKS:");
239
+ DUP_Log::Info("********************************************************************************");
240
+ $dbSizeRead = DUP_Util::byteSize($this->Database->Size);
241
+ $zipSizeRead = DUP_Util::byteSize($this->Archive->Size);
242
+ $exeSizeRead = DUP_Util::byteSize($this->Installer->Size);
243
+
244
+ DUP_Log::Info("SQL File: {$dbSizeRead}");
245
+ DUP_Log::Info("Installer File: {$exeSizeRead}");
246
+ DUP_Log::Info("Archive File: {$zipSizeRead} ");
247
+
248
+ if (!($this->Archive->Size && $this->Database->Size && $this->Installer->Size)) {
249
+ DUP_Log::Error("A required file contains zero bytes.", "Archive Size: {$zipSizeRead} | SQL Size: {$dbSizeRead} | Installer Size: {$exeSizeRead}");
250
+ }
251
+
252
+ //Validate SQL files completed
253
+ $sql_tmp_path = DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP.'/'.$this->Database->File);
254
+ $sql_complete_txt = DUP_Util::tailFile($sql_tmp_path, 3);
255
+ if (!strstr($sql_complete_txt, 'DUPLICATOR_MYSQLDUMP_EOF')) {
256
+ DUP_Log::Error("ERROR: SQL file not complete. The end of file marker was not found. Please try to re-create the package.");
257
+ }
258
+
259
+ $timerEnd = DUP_Util::getMicrotime();
260
+ $timerSum = DUP_Util::elapsedTime($timerEnd, $timerStart);
261
+
262
+ $this->Runtime = $timerSum;
263
+ $this->ExeSize = $exeSizeRead;
264
+ $this->ZipSize = $zipSizeRead;
265
+
266
+ $this->buildCleanup();
267
+
268
+ //FINAL REPORT
269
+ $info = "\n********************************************************************************\n";
270
+ $info .= "RECORD ID:[{$this->ID}]\n";
271
+ $info .= "TOTAL PROCESS RUNTIME: {$timerSum}\n";
272
+ $info .= "PEAK PHP MEMORY USED: ".DUP_Server::getPHPMemory(true)."\n";
273
+ $info .= "DONE PROCESSING => {$this->Name} ".@date("Y-m-d H:i:s")."\n";
274
+
275
+ DUP_Log::Info($info);
276
+ DUP_Log::Close();
277
+
278
+ $this->setStatus(DUP_PackageStatus::COMPLETE);
279
+ return $this;
280
+ }
281
+
282
+ /**
283
+ * Saves the active options associted with the active(latest) package.
284
+ *
285
+ * @see DUP_Package::getActive
286
+ *
287
+ * @param $_POST $post The Post server object
288
+ *
289
+ * @return null
290
+ */
291
+ public function saveActive($post = null)
292
+ {
293
+ global $wp_version;
294
+
295
+ if (isset($post)) {
296
+ $post = stripslashes_deep($post);
297
+
298
+ $name_chars = array(".", "-");
299
+ $name = ( isset($post['package-name']) && !empty($post['package-name'])) ? $post['package-name'] : self::getDefaultName();
300
+ $name = substr(sanitize_file_name($name), 0, 40);
301
+ $name = str_replace($name_chars, '', $name);
302
+
303
+ $filter_dirs = isset($post['filter-dirs']) ? $this->parseDirectoryFilter($post['filter-dirs']) : '';
304
+ $filter_exts = isset($post['filter-exts']) ? $this->parseExtensionFilter($post['filter-exts']) : '';
305
+ $tablelist = isset($post['dbtables']) ? implode(',', $post['dbtables']) : '';
306
+ $compatlist = isset($post['dbcompat']) ? implode(',', $post['dbcompat']) : '';
307
+ $dbversion = DUP_DB::getVersion();
308
+ $dbversion = is_null($dbversion) ? '- unknown -' : $dbversion;
309
+ $dbcomments = DUP_DB::getVariable('version_comment');
310
+ $dbcomments = is_null($dbcomments) ? '- unknown -' : $dbcomments;
311
+
312
+ //PACKAGE
313
+ $this->Created = date("Y-m-d H:i:s");
314
+ $this->Version = DUPLICATOR_VERSION;
315
+ $this->VersionOS = defined('PHP_OS') ? PHP_OS : 'unknown';
316
+ $this->VersionWP = $wp_version;
317
+ $this->VersionPHP = phpversion();
318
+ $this->VersionDB = $dbversion;
319
+ $this->Name = $name;
320
+ $this->Hash = $this->makeHash();
321
+ $this->NameHash = "{$this->Name}_{$this->Hash}";
322
+
323
+ $this->Notes = esc_html($post['package-notes']);
324
+ //ARCHIVE
325
+ $this->Archive->PackDir = rtrim(DUPLICATOR_WPROOTPATH, '/');
326
+ $this->Archive->Format = 'ZIP';
327
+ $this->Archive->FilterOn = isset($post['filter-on']) ? 1 : 0;
328
+ $this->Archive->FilterDirs = esc_html($filter_dirs);
329
+ $this->Archive->FilterExts = str_replace(array('.', ' '), "", esc_html($filter_exts));
330
+ //INSTALLER
331
+ $this->Installer->OptsDBHost = esc_html($post['dbhost']);
332
+ $this->Installer->OptsDBPort = esc_html($post['dbport']);
333
+ $this->Installer->OptsDBName = esc_html($post['dbname']);
334
+ $this->Installer->OptsDBUser = esc_html($post['dbuser']);
335
+ $this->Installer->OptsSSLAdmin = isset($post['ssl-admin']) ? 1 : 0;
336
+ $this->Installer->OptsSSLLogin = isset($post['ssl-login']) ? 1 : 0;
337
+ $this->Installer->OptsCacheWP = isset($post['cache-wp']) ? 1 : 0;
338
+ $this->Installer->OptsCachePath = isset($post['cache-path']) ? 1 : 0;
339
+ $this->Installer->OptsURLNew = esc_html($post['url-new']);
340
+ //DATABASE
341
+ $this->Database->FilterOn = isset($post['dbfilter-on']) ? 1 : 0;
342
+ $this->Database->FilterTables = esc_html($tablelist);
343
+ $this->Database->Compatible = $compatlist;
344
+ $this->Database->Comments = $dbcomments;
345
+
346
+ update_option(self::OPT_ACTIVE, $this);
347
+ }
348
+ }
349
+
350
+ /**
351
+ * Save any property of this class through reflection
352
+ *
353
+ * @param $property A valid public property in this class
354
+ * @param $value The value for the new dynamic property
355
+ *
356
+ * @return null
357
+ */
358
+ public function saveActiveItem($property, $value)
359
+ {
360
+ $package = self::getActive();
361
+
362
+ $reflectionClass = new ReflectionClass($package);
363
+ $reflectionClass->getProperty($property)->setValue($package, $value);
364
+ update_option(self::OPT_ACTIVE, $package);
365
+ }
366
+
367
+ /**
368
+ * Sets the status to log the state of the build
369
+ *
370
+ * @param $status The status level for where the package is
371
+ *
372
+ * @return void
373
+ */
374
+ public function setStatus($status)
375
+ {
376
+ global $wpdb;
377
+
378
+ $packageObj = serialize($this);
379
+
380
+ if (!isset($status)) {
381
+ DUP_Log::Error("Package SetStatus did not receive a proper code.");
382
+ }
383
+
384
+ if (!$packageObj) {
385
+ DUP_Log::Error("Package SetStatus was unable to serialize package object while updating record.");
386
+ }
387
+
388
+ $wpdb->flush();
389
+ $table = $wpdb->prefix."duplicator_packages";
390
+ $sql = "UPDATE `{$table}` SET status = {$status}, package = '{$packageObj}' WHERE ID = {$this->ID}";
391
+ $wpdb->query($sql);
392
+ }
393
+
394
+ /**
395
+ * Does a hash already exisit
396
+ *
397
+ * @param string $hash An existing hash value
398
+ *
399
+ * @return int Returns 0 if no hash is found, if found returns the table ID
400
+ */
401
+ public function getHashKey($hash)
402
+ {
403
+ global $wpdb;
404
+
405
+ $table = $wpdb->prefix."duplicator_packages";
406
+ $qry = $wpdb->get_row("SELECT ID, hash FROM `{$table}` WHERE hash = '{$hash}'");
407
+ if (strlen($qry->hash) == 0) {
408
+ return 0;
409
+ } else {
410
+ return $qry->ID;
411
+ }
412
+ }
413
+
414
+ /**
415
+ * Makes the hashkey for the package files
416
+ *
417
+ * @return string Returns a unique hashkey
418
+ */
419
+ public function makeHash()
420
+ {
421
+ return uniqid().mt_rand(1000, 9999).date("ymdHis");
422
+ }
423
+
424
+ /**
425
+ * Gets the active package which is defined as the package that was lasted saved.
426
+ * Do to cache issues with the built in WP function get_option moved call to a direct DB call.
427
+ *
428
+ * @see DUP_Package::saveActive
429
+ *
430
+ * @return obj A copy of the DUP_Package object
431
+ */
432
+ public static function getActive()
433
+ {
434
+ global $wpdb;
435
+
436
+ $obj = new DUP_Package();
437
+ $row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM `{$wpdb->options}` WHERE option_name = %s LIMIT 1", self::OPT_ACTIVE));
438
+ if (is_object($row)) {
439
+ $obj = @unserialize($row->option_value);
440
+ }
441
+ //Incase unserilaize fails
442
+ $obj = (is_object($obj)) ? $obj : new DUP_Package();
443
+ return $obj;
444
+ }
445
+
446
+ /**
447
+ * Gets the Package by ID
448
+ *
449
+ * @param int $id A valid package id form the duplicator_packages table
450
+ *
451
+ * @return obj A copy of the DUP_Package object
452
+ */
453
+ public static function getByID($id)
454
+ {
455
+
456
+ global $wpdb;
457
+ $obj = new DUP_Package();
458
+
459
+ $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM `{$wpdb->prefix}duplicator_packages` WHERE ID = %s", $id));
460
+ if (is_object($row)) {
461
+ $obj = @unserialize($row->package);
462
+ $obj->Status = $row->status;
463
+ }
464
+ //Incase unserilaize fails
465
+ $obj = (is_object($obj)) ? $obj : null;
466
+ return $obj;
467
+ }
468
+
469
+ /**
470
+ * Gets a default name for the package
471
+ *
472
+ * @return string A default packagename such as 20170218_blogname
473
+ */
474
+ public static function getDefaultName()
475
+ {
476
+ //Remove specail_chars from final result
477
+ $special_chars = array(".", "-");
478
+ $name = date('Ymd').'_'.sanitize_title(get_bloginfo('name', 'display'));
479
+ $name = substr(sanitize_file_name($name), 0, 40);
480
+ $name = str_replace($special_chars, '', $name);
481
+ return $name;
482
+ }
483
+
484
+ /**
485
+ * Cleanup all tmp files
486
+ *
487
+ * @param all empty all contents
488
+ *
489
+ * @return null
490
+ */
491
+ public static function tempFileCleanup($all = false)
492
+ {
493
+ //Delete all files now
494
+ if ($all) {
495
+ $dir = DUPLICATOR_SSDIR_PATH_TMP."/*";
496
+ foreach (glob($dir) as $file) {
497
+ unlink($file);
498
+ }
499
+ }
500
+ //Remove scan files that are 24 hours old
501
+ else {
502
+ $dir = DUPLICATOR_SSDIR_PATH_TMP."/*_scan.json";
503
+ foreach (glob($dir) as $file) {
504
+ if (filemtime($file) <= time() - 86400) {
505
+ unlink($file);
506
+ }
507
+ }
508
+ }
509
+ }
510
+
511
+ /**
512
+ * Provides various date formats
513
+ *
514
+ * @param $date The date to format
515
+ * @param $format Various date formats to apply
516
+ *
517
+ * @return a formated date based on the $format
518
+ */
519
+ public static function getCreatedDateFormat($date, $format = 1)
520
+ {
521
+ $date = new DateTime($date);
522
+ switch ($format) {
523
+ //YEAR
524
+ case 1: return $date->format('Y-m-d H:i');
525
+ break;
526
+ case 2: return $date->format('Y-m-d H:i:s');
527
+ break;
528
+ case 3: return $date->format('y-m-d H:i');
529
+ break;
530
+ case 4: return $date->format('y-m-d H:i:s');
531
+ break;
532
+ //MONTH
533
+ case 5: return $date->format('m-d-Y H:i');
534
+ break;
535
+ case 6: return $date->format('m-d-Y H:i:s');
536
+ break;
537
+ case 7: return $date->format('m-d-y H:i');
538
+ break;
539
+ case 8: return $date->format('m-d-y H:i:s');
540
+ break;
541
+ //DAY
542
+ case 9: return $date->format('d-m-Y H:i');
543
+ break;
544
+ case 10: return $date->format('d-m-Y H:i:s');
545
+ break;
546
+ case 11: return $date->format('d-m-y H:i');
547
+ break;
548
+ case 12: return $date->format('d-m-y H:i:s');
549
+ break;
550
+ default :
551
+ return $date->format('Y-m-d H:i');
552
+ }
553
+ }
554
+
555
+ /**
556
+ * Cleans up all the tmp files as part of the package build process
557
+ */
558
+ private function buildCleanup()
559
+ {
560
+
561
+ $files = DUP_Util::listFiles(DUPLICATOR_SSDIR_PATH_TMP);
562
+ $newPath = DUPLICATOR_SSDIR_PATH;
563
+
564
+ if (function_exists('rename')) {
565
+ foreach ($files as $file) {
566
+ $name = basename($file);
567
+ if (strstr($name, $this->NameHash)) {
568
+ rename($file, "{$newPath}/{$name}");
569
+ }
570
+ }
571
+ } else {
572
+ foreach ($files as $file) {
573
+ $name = basename($file);
574
+ if (strstr($name, $this->NameHash)) {
575
+ copy($file, "{$newPath}/{$name}");
576
+ unlink($file);
577
+ }
578
+ }
579
+ }
580
+ }
581
+
582
+ /**
583
+ * Properly creates the directory filter list that is used for filtering directories
584
+ *
585
+ * @param string $dirs A semi-colon list of dir paths
586
+ * /path1_/path/;/path1_/path2/;
587
+ *
588
+ * @returns string A cleaned up list of directory filters
589
+ */
590
+ private function parseDirectoryFilter($dirs = "")
591
+ {
592
+ $dirs = str_replace(array("\n", "\t", "\r"), '', $dirs);
593
+ $filter_dirs = "";
594
+ $dir_array = array_unique(explode(";", $dirs));
595
+ foreach ($dir_array as $val) {
596
+ if (strlen($val) >= 2) {
597
+ $filter_dirs .= DUP_Util::safePath(trim(rtrim($val, "/\\"))).";";
598
+ }
599
+ }
600
+ return $filter_dirs;
601
+ }
602
+
603
+ /**
604
+ * Properly creates the extension filter list that is used for filtering extensions
605
+ *
606
+ * @param string $dirs A semi-colon list of dir paths
607
+ * .jpg;.zip;.gif;
608
+ *
609
+ * @returns string A cleaned up list of extension filters
610
+ */
611
+ private function parseExtensionFilter($extensions = "")
612
+ {
613
+ $filter_exts = "";
614
+ if (strlen($extensions) >= 1 && $extensions != ";") {
615
+ $filter_exts = str_replace(array(' ', '.'), '', $extensions);
616
+ $filter_exts = str_replace(",", ";", $filter_exts);
617
+ $filter_exts = DUP_Util::appendOnce($extensions, ";");
618
+ }
619
+ return $filter_exts;
620
+ }
621
+ }
622
+ ?>
classes/scan.validator.php DELETED
@@ -1,93 +0,0 @@
1
- <?php
2
-
3
- /*Recursivly scans a directory and finds all sym-links and unreadable files */
4
- class DUP_ScanValidator
5
- {
6
- public $FileCount = 0;
7
- public $DirCount = 0;
8
-
9
- /*If the MaxFiles or MaxDirs limit is reached then true */
10
- public $LimitReached = false;
11
-
12
- /*The maximum count of files before the recursive function stops */
13
- public $MaxFiles = 1000000;
14
-
15
- /*The maximum count of directories before the recursive function stops */
16
- public $MaxDirs = 75000;
17
-
18
- public $Recursion = true;
19
-
20
- /*Stores a list of symbolic link files */
21
- public $SymLinks = array();
22
-
23
- /*Stores a list of files unreadable by PHP */
24
- public $Unreadable = array();
25
-
26
- public function Run($dir, &$results = array())
27
- {
28
- //Stop Recursion if Max search is reached
29
- if ($this->FileCount > $this->MaxFiles || $this->DirCount > $this->MaxDirs)
30
- {
31
- $this->LimitReached = true;
32
- return $results;
33
- }
34
-
35
- $files = @scandir($dir);
36
- if (is_array($files))
37
- {
38
- foreach($files as $key => $value)
39
- {
40
- $path = realpath($dir.DIRECTORY_SEPARATOR.$value);
41
- if ($path) {
42
- //Files
43
- if(!is_dir($path)) {
44
- if (!is_readable($path))
45
- {
46
- $results[] = $path;
47
- $this->Unreadable[] = $path;
48
- }
49
- else if ($this->_is_link($path))
50
- {
51
- $results[] = $path;
52
- $this->SymLinks[] = $path;
53
- }
54
- $this->FileCount++;
55
- }
56
- //Dirs
57
- else if($value != "." && $value != "..")
58
- {
59
- if (! $this->_is_link($path) && $this->Recursion)
60
- {
61
- $this->Run($path, $results);
62
- }
63
-
64
- if (!is_readable($path))
65
- {
66
- $results[] = $path;
67
- $this->Unreadable[] = $path;
68
- }
69
- else if ($this->_is_link($path)) {
70
- $results[] = $path;
71
- $this->SymLinks[] = $path;
72
- }
73
- $this->DirCount++;
74
- }
75
- }
76
- }
77
- }
78
- return $this;
79
- }
80
-
81
- //Supports windows and linux
82
- private function _is_link($target)
83
- {
84
- if (defined('PHP_WINDOWS_VERSION_BUILD')) {
85
- if(file_exists($target) && @readlink($target) != $target) {
86
- return true;
87
- }
88
- } elseif (is_link($target)) {
89
- return true;
90
- }
91
- return false;
92
- }
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/server.php DELETED
@@ -1,200 +0,0 @@
1
- <?php
2
- if ( ! defined( 'DUPLICATOR_VERSION' ) ) exit; // Exit if accessed directly
3
-
4
- require_once (DUPLICATOR_PLUGIN_PATH . 'classes/utility.php');
5
-
6
- /**
7
- * Class used to get server statis
8
- * @package Dupicator\classes
9
- */
10
- class DUP_Server
11
- {
12
-
13
- /**
14
- * Gets the system requirements which must pass to buld a package
15
- * @return array An array of requirements
16
- */
17
- public static function GetRequirements()
18
- {
19
-
20
- global $wpdb;
21
- $dup_tests = array();
22
-
23
- //PHP SUPPORT
24
- $safe_ini = strtolower(ini_get('safe_mode'));
25
- $dup_tests['PHP']['SAFE_MODE'] = $safe_ini != 'on' || $safe_ini != 'yes' || $safe_ini != 'true' || ini_get("safe_mode") != 1 ? 'Pass' : 'Fail';
26
- $dup_tests['PHP']['VERSION'] = DUP_Util::$on_php_529_plus ? 'Pass' : 'Fail';
27
- $dup_tests['PHP']['ZIP'] = class_exists('ZipArchive') ? 'Pass' : 'Fail';
28
- $dup_tests['PHP']['FUNC_1'] = function_exists("file_get_contents") ? 'Pass' : 'Fail';
29
- $dup_tests['PHP']['FUNC_2'] = function_exists("file_put_contents") ? 'Pass' : 'Fail';
30
- $dup_tests['PHP']['FUNC_3'] = function_exists("mb_strlen") ? 'Pass' : 'Fail';
31
- $dup_tests['PHP']['ALL'] = ! in_array('Fail', $dup_tests['PHP']) ? 'Pass' : 'Fail';
32
-
33
- //REQUIRED PATHS
34
- if (file_exists(DUPLICATOR_SSDIR_PATH) && is_writeable(DUPLICATOR_SSDIR_PATH))
35
- {
36
- $dup_tests['IO']['SSDIR'] = 'Pass';
37
- $dup_tests['IO']['WPROOT'] = 'Pass';
38
- }
39
- else
40
- {
41
- $handle_test = @opendir(DUPLICATOR_WPROOTPATH);
42
- $dup_tests['IO']['WPROOT'] = is_writeable(DUPLICATOR_WPROOTPATH) && $handle_test ? 'Pass' : 'Fail';
43
- $dup_tests['IO']['SSDIR'] = 'Fail';
44
- @closedir($handle_test);
45
- }
46
-
47
- $dup_tests['IO']['SSTMP'] = is_writeable(DUPLICATOR_SSDIR_PATH_TMP) ? 'Pass' : 'Fail';
48
- $dup_tests['IO']['ALL'] = ! in_array('Fail', $dup_tests['IO']) ? 'Pass' : 'Fail';
49
-
50
-
51
- //SERVER SUPPORT
52
- $dup_tests['SRV']['MYSQLi'] = function_exists('mysqli_connect') ? 'Pass' : 'Fail';
53
- $dup_tests['SRV']['MYSQL_VER'] = version_compare($wpdb->db_version(), '5.0', '>=') ? 'Pass' : 'Fail';
54
- $dup_tests['SRV']['ALL'] = ! in_array('Fail', $dup_tests['SRV']) ? 'Pass' : 'Fail';
55
-
56
- //RESERVED FILES
57
- $dup_tests['RES']['INSTALL'] = !(self::InstallerFilesFound()) ? 'Pass' : 'Fail';
58
- $dup_tests['Success'] = $dup_tests['PHP']['ALL'] == 'Pass' && $dup_tests['IO']['ALL'] == 'Pass' &&
59
- $dup_tests['SRV']['ALL'] == 'Pass' && $dup_tests['RES']['INSTALL'] == 'Pass';
60
-
61
- return $dup_tests;
62
- }
63
-
64
- /**
65
- * Gets the system checks which are not required
66
- * @return array An array of system checks
67
- */
68
- public static function GetChecks()
69
- {
70
- $checks = array();
71
-
72
- //WEB SERVER
73
- $web_test1 = false;
74
- foreach ($GLOBALS['DUPLICATOR_SERVER_LIST'] as $value) {
75
- if (stristr($_SERVER['SERVER_SOFTWARE'], $value)) {
76
- $web_test1 = true;
77
- break;
78
- }
79
- }
80
- $checks['SRV']['WEB']['model'] = $web_test1;
81
- $checks['SRV']['WEB']['ALL'] = ($web_test1) ? 'Good' : 'Warn';
82
-
83
- //PHP SETTINGS
84
- $php_test1 = ini_get("open_basedir");
85
- $php_test1 = empty($php_test1) ? true : false;
86
- $php_test2 = ini_get("max_execution_time");
87
- $php_test2 = ($php_test2 > DUPLICATOR_SCAN_TIMEOUT) || (strcmp($php_test2 , 'Off') == 0 || $php_test2 == 0) ? true : false;
88
- $php_test3 = function_exists('mysqli_connect');
89
- $php_test4 = DUP_Util::$on_php_53_plus ? true : false;
90
-
91
- $checks['SRV']['PHP']['openbase'] = $php_test1;
92
- $checks['SRV']['PHP']['maxtime'] = $php_test2;
93
- $checks['SRV']['PHP']['mysqli'] = $php_test3;
94
- $checks['SRV']['PHP']['version'] = $php_test4;
95
- $checks['SRV']['PHP']['ALL'] = ($php_test1 && $php_test2 && $php_test3 && $php_test4) ? 'Good' : 'Warn';
96
-
97
-
98
- //WORDPRESS SETTINGS
99
- global $wp_version;
100
- $wp_test1 = version_compare($wp_version, DUPLICATOR_SCAN_MIN_WP) >= 0 ? true : false;
101
-
102
- //Core Files
103
- $files = array();
104
- $files['wp-config.php'] = file_exists(DUP_Util::SafePath(DUPLICATOR_WPROOTPATH . '/wp-config.php'));
105
- $wp_test2 = $files['wp-config.php'];
106
-
107
- //Cache
108
- $Package = DUP_Package::GetActive();
109
- $cache_path = DUP_Util::SafePath(WP_CONTENT_DIR) . '/cache';
110
- $dirEmpty = DUP_Util::IsDirectoryEmpty($cache_path);
111
- $dirSize = DUP_Util::GetDirectorySize($cache_path);
112
- $cach_filtered = in_array($cache_path, explode(';', $Package->Archive->FilterDirs));
113
- $wp_test3 = ($cach_filtered || $dirEmpty || $dirSize < DUPLICATOR_SCAN_CACHESIZE ) ? true : false;
114
- $wp_test4 = is_multisite();
115
-
116
- $checks['SRV']['WP']['version'] = $wp_test1;
117
- $checks['SRV']['WP']['core'] = $wp_test2;
118
- $checks['SRV']['WP']['cache'] = $wp_test3;
119
- $checks['SRV']['WP']['ismu'] = $wp_test4;
120
- $checks['SRV']['WP']['ALL'] = $wp_test1 && $wp_test2 && $wp_test3 && ! $wp_test4 ? 'Good' : 'Warn';
121
-
122
- return $checks;
123
- }
124
-
125
- /**
126
- * Check to see if duplicator installer files are present
127
- * @return bool True if any reserved files are found
128
- */
129
- public static function InstallerFilesFound()
130
- {
131
- $files = self::GetInstallerFiles();
132
- foreach($files as $file => $path)
133
- {
134
- if (file_exists($path))
135
- return true;
136
- }
137
- return false;
138
- }
139
-
140
-
141
- /**
142
- * Gets a list of all the installer files by name and full path
143
- * @return array [file_name, file_path]
144
- */
145
- public static function GetInstallerFiles()
146
- {
147
- /* Files:
148
- * installer.php, installer-backup.php, installer-data.sql, installer-log.txt, database.sql */
149
- return array(
150
- DUPLICATOR_INSTALL_PHP => DUPLICATOR_WPROOTPATH . DUPLICATOR_INSTALL_PHP,
151
- DUPLICATOR_INSTALL_BAK => DUPLICATOR_WPROOTPATH . DUPLICATOR_INSTALL_BAK,
152
- DUPLICATOR_INSTALL_SQL => DUPLICATOR_WPROOTPATH . DUPLICATOR_INSTALL_SQL,
153
- DUPLICATOR_INSTALL_LOG => DUPLICATOR_WPROOTPATH . DUPLICATOR_INSTALL_LOG,
154
- DUPLICATOR_INSTALL_DB => DUPLICATOR_WPROOTPATH . DUPLICATOR_INSTALL_DB
155
- );
156
- }
157
-
158
-
159
- /**
160
- * Get the IP of a client machine
161
- * @return string IP of the client machine
162
- */
163
- public static function GetClientIP()
164
- {
165
-
166
- if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)){
167
- return $_SERVER["HTTP_X_FORWARDED_FOR"];
168
- }else if (array_key_exists('REMOTE_ADDR', $_SERVER)) {
169
- return $_SERVER["REMOTE_ADDR"];
170
- }else if (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
171
- return $_SERVER["HTTP_CLIENT_IP"];
172
- }
173
-
174
- return '';
175
- }
176
-
177
- /**
178
- * Get PHP memory useage
179
- * @return string Returns human readable memory useage.
180
- */
181
- public static function GetPHPMemory($peak = false)
182
- {
183
-
184
- if ($peak) {
185
- $result = 'Unable to read PHP peak memory usage';
186
- if (function_exists('memory_get_peak_usage')) {
187
- $result = DUP_Util::ByteSize(memory_get_peak_usage(true));
188
- }
189
- } else {
190
- $result = 'Unable to read PHP memory usage';
191
- if (function_exists('memory_get_usage')) {
192
- $result = DUP_Util::ByteSize(memory_get_usage(true));
193
- }
194
- }
195
-
196
- return $result;
197
- }
198
-
199
- }
200
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/ui.php DELETED
@@ -1,92 +0,0 @@
1
- <?php
2
- if ( ! defined('DUPLICATOR_VERSION') ) exit; // Exit if accessed directly
3
-
4
- /**
5
- * Helper Class for UI internactions
6
- * @package Dupicator\classes
7
- */
8
- class DUP_UI
9
- {
10
-
11
- /**
12
- * The key used in the wp_options table
13
- * @var string
14
- */
15
- private static $OptionsViewStateKey = 'duplicator_ui_view_state';
16
-
17
- /**
18
- * Save the view state of UI elements
19
- * @param string $key A unique key to define the ui element
20
- * @param string $value A generic value to use for the view state
21
- */
22
- public static function SaveViewState($key, $value)
23
- {
24
- $view_state = array();
25
- $view_state = get_option(self::$OptionsViewStateKey);
26
- $view_state[$key] = $value;
27
- $success = update_option(self::$OptionsViewStateKey, $view_state);
28
- return $success;
29
- }
30
-
31
-
32
- /**
33
- * Gets all the values from the settings array
34
- * @return array Returns and array of all the values stored in the settings array
35
- */
36
- public static function GetViewStateArray()
37
- {
38
- return get_option(self::$OptionsViewStateKey);
39
- }
40
-
41
- /**
42
- * Return the value of the of view state item
43
- * @param type $searchKey The key to search on
44
- * @return string Returns the value of the key searched or null if key is not found
45
- */
46
- public static function GetViewStateValue($searchKey)
47
- {
48
- $view_state = get_option(self::$OptionsViewStateKey);
49
- if (is_array($view_state)) {
50
- foreach ($view_state as $key => $value) {
51
- if ($key == $searchKey) {
52
- return $value;
53
- }
54
- }
55
- }
56
- return null;
57
- }
58
-
59
- /**
60
- * Shows a display message in the wp-admin if any researved files are found
61
- * @return type void
62
- */
63
- public static function ShowReservedFilesNotice()
64
- {
65
- //Show only on Duplicator pages and Dashboard when plugin is active
66
- $dup_active = is_plugin_active('duplicator/duplicator.php');
67
- $dup_perm = current_user_can( 'manage_options' );
68
- if (! $dup_active || ! $dup_perm)
69
- return;
70
-
71
- if (DUP_Server::InstallerFilesFound())
72
- {
73
- $screen = get_current_screen();
74
- $on_active_tab = isset($_GET['tab']) && $_GET['tab'] == 'cleanup' ? true : false;
75
-
76
- echo '<div class="error" id="dup-global-error-reserved-files"><p>';
77
- if ($screen->id == 'duplicator_page_duplicator-tools' && $on_active_tab)
78
- {
79
- _e('Reserved Duplicator install files have been detected in the root directory. Please delete these reserved files to avoid security issues.', 'duplicator');
80
- }
81
- else
82
- {
83
- $duplicator_nonce = wp_create_nonce('duplicator_cleanup_page');
84
- _e('Reserved Duplicator install files have been detected in the root directory. Please delete these reserved files to avoid security issues.', 'duplicator');
85
- @printf("<br/><a href='admin.php?page=duplicator-tools&tab=cleanup&_wpnonce=%s'>%s</a>", $duplicator_nonce, __('Take me to the cleanup page!', 'duplicator'));
86
- }
87
- echo "</p></div>";
88
- }
89
- }
90
-
91
- }
92
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/ui/class.dialog.php DELETED
@@ -1,165 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Inline Dialog:
5
- * Used to generate a thinkbox inline dialog.
6
- */
7
- class DUP_Dialog
8
- {
9
- //All Dialogs
10
- public $title;
11
- public $message;
12
- public $width;
13
- public $height;
14
-
15
- //Confirm Only
16
- public $progress_text;
17
- public $progress_on = true;
18
- public $jscallback;
19
-
20
- private $id;
21
- private $uniqid;
22
-
23
- public function __construct()
24
- {
25
- add_thickbox();
26
- $this->progress_text = __('Processing please wait...', 'duplicator');
27
- $this->uniqid = uniqid();
28
- $this->id = 'dup-dlg-' . $this->uniqid;
29
- }
30
-
31
-
32
- /**
33
- * Gets unique ID:
34
- * Get the unique id that is assigned to each instance of a dialog
35
- *
36
- * @access public
37
- * @return int
38
- */
39
- public function get_id()
40
- {
41
- return $this->id;
42
- }
43
-
44
- /**
45
- * Gets unique ID:
46
- * Get the unique id that is assigned to each instance of a dialog
47
- *
48
- * @access public
49
- * @return int
50
- */
51
- public function get_message_id()
52
- {
53
- return "{$this->id}_message";
54
- }
55
-
56
-
57
- /**
58
- * Init Alert:
59
- * Initilizes the alert base html code used to display when needed
60
- *
61
- * @access public
62
- * @return string The html content used for the alert dialog
63
- */
64
- public function init_alert()
65
- {
66
- $ok = __('OK', 'duplicator');
67
-
68
- $html = <<<HTML
69
- <div id="{$this->id}" style="display:none">
70
- <div class="dup-dlg-alert-txt">
71
- {$this->message}
72
- <br/><br/>
73
- </div>
74
- <div class="dup-dlg-alert-btns">
75
- <input type="button" class="button button-large" value="{$ok}" onclick="tb_remove()" />
76
- </div>
77
- </div>
78
- HTML;
79
-
80
- echo $html;
81
- }
82
-
83
-
84
- /**
85
- * Show Alert:
86
- * Shows the alert base js code used to display when needed
87
- *
88
- * @access public
89
- * @return string The javascript content used for the alert dialog
90
- */
91
- public function show_alert()
92
- {
93
- $this->width = is_numeric($this->width) ? $this->width : 475;
94
- $this->height = is_numeric($this->height) ? $this->height : 125;
95
-
96
- echo "tb_show('{$this->title}', '#TB_inline?width={$this->width}&height={$this->height}&inlineId={$this->id}');";
97
- }
98
-
99
-
100
- /**
101
- * Init Confirm:
102
- * Shows the confirm base js code used to display when needed
103
- *
104
- * @access public
105
- * @return string The javascript content used for the confirm dialog
106
- */
107
- public function init_confirm()
108
- {
109
- $ok = __('OK', 'duplicator');
110
- $cancel = __('Cancel', 'duplicator');
111
-
112
- $progress_data = '';
113
- $progress_func2 = '';
114
-
115
- //Enable the progress spinner
116
- if ($this->progress_on)
117
- {
118
- $progress_func1 = "__dup_dialog_" . $this->uniqid;
119
- $progress_func2 = ";{$progress_func1}(this)";
120
- $progress_data = <<<HTML
121
- <div class='dup-dlg-confirm-progress'><i class='fa fa-circle-o-notch fa-spin fa-lg fa-fw'></i> {$this->progress_text}</div>
122
- <script>
123
- function {$progress_func1}(obj)
124
- {
125
- jQuery(obj).parent().parent().find('.dup-dlg-confirm-progress').show();
126
- jQuery(obj).closest('.dup-dlg-confirm-btns').find('input').attr('disabled', 'true');
127
- }
128
- </script>
129
- HTML;
130
- }
131
-
132
- $html = <<<HTML
133
- <div id="{$this->id}" style="display:none">
134
- <div class="dup-dlg-confirm-txt">
135
- <span id="{$this->id}_message">{$this->message}</span>
136
- <br/><br/>
137
- {$progress_data}
138
- </div>
139
- <div class="dup-dlg-confirm-btns">
140
- <input type="button" class="button button-large" value="{$ok}" onclick="{$this->jscallback}{$progress_func2}" />
141
- <input type="button" class="button button-large" value="{$cancel}" onclick="tb_remove()" />
142
- </div>
143
- </div>
144
- HTML;
145
-
146
- echo $html;
147
- }
148
-
149
-
150
- /**
151
- * Show Confirm:
152
- * Shows the confirm base js code used to display when needed
153
- *
154
- * @access public
155
- * @return string The javascript content used for the confirm dialog
156
- */
157
- public function show_confirm()
158
- {
159
- $this->width = is_numeric($this->width) ? $this->width : 500;
160
- $this->height = is_numeric($this->height) ? $this->height : 150;
161
- echo "tb_show('{$this->title}', '#TB_inline?width={$this->width}&height={$this->height}&inlineId={$this->id}');";
162
- }
163
-
164
- }
165
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/ui/class.ui.dialog.php ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Used to generate a thinkbox inline dialog such as an alert or confirm popup
4
+ *
5
+ * Standard: PSR-2
6
+ * @link http://www.php-fig.org/psr/psr-2
7
+ *
8
+ * @package Duplicator
9
+ * @subpackage classes/ui
10
+ * @copyright (c) 2017, Snapcreek LLC
11
+ * @since 1.1.32
12
+ *
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if (!defined('DUPLICATOR_VERSION')) {
17
+ exit;
18
+ }
19
+
20
+ class DUP_UI_Dialog
21
+ {
22
+ /**
23
+ * The title that shows up in the dialog
24
+ */
25
+ public $title;
26
+
27
+ /**
28
+ * The message displayed in the body of the dialog
29
+ */
30
+ public $message;
31
+
32
+ /**
33
+ * The width of the dialog the default is used if not set
34
+ * Alert = 475px (default) | Confirm = 500px (default)
35
+ */
36
+ public $width;
37
+
38
+ /**
39
+ * The height of the dialog the default is used if not set
40
+ * Alert = 125px (default) | Confirm = 150px (default)
41
+ */
42
+ public $height;
43
+
44
+ /**
45
+ * When the progress meter is running show this text
46
+ * Available only on confirm dialogs
47
+ */
48
+ public $progressText;
49
+
50
+ /**
51
+ * When true a progress meter will run until page is reloaded
52
+ * Available only on confirm dialogs
53
+ */
54
+ public $progressOn = true;
55
+
56
+ /**
57
+ * The javascript call back method to call when the 'Yes' button is clicked
58
+ * Available only on confirm dialogs
59
+ */
60
+ public $jscallback;
61
+
62
+ /**
63
+ * The id given to the full dialog
64
+ */
65
+ private $id;
66
+
67
+ /**
68
+ * A unique id that is added to all id elements
69
+ */
70
+ private $uniqid;
71
+
72
+ public function __construct()
73
+ {
74
+ add_thickbox();
75
+ $this->progressText = __('Processing please wait...', 'duplicator');
76
+ $this->uniqid = uniqid();
77
+ $this->id = 'dup-dlg-'.$this->uniqid;
78
+ }
79
+
80
+ /**
81
+ * Gets the unique id that is assigned to each instance of a dialog
82
+ *
83
+ * @access public
84
+ * @return int The unique ID of this dialog
85
+ */
86
+ public function getID()
87
+ {
88
+ return $this->id;
89
+ }
90
+
91
+ /**
92
+ * Gets the unique id that is assigned to each instance of a dialogs message text
93
+ *
94
+ * @access public
95
+ * @return int The unique ID of the message
96
+ */
97
+ public function getMessageID()
98
+ {
99
+ return "{$this->id}_message";
100
+ }
101
+
102
+ /**
103
+ * Initilizes the alert base html code used to display when needed
104
+ *
105
+ * @access public
106
+ * @return string The html content used for the alert dialog
107
+ */
108
+ public function initAlert()
109
+ {
110
+ $ok = __('OK', 'duplicator');
111
+
112
+ $html = <<<HTML
113
+ <div id="{$this->id}" style="display:none">
114
+ <div class="dup-dlg-alert-txt">
115
+ {$this->message}
116
+ <br/><br/>
117
+ </div>
118
+ <div class="dup-dlg-alert-btns">
119
+ <input type="button" class="button button-large" value="{$ok}" onclick="tb_remove()" />
120
+ </div>
121
+ </div>
122
+ HTML;
123
+
124
+ echo $html;
125
+ }
126
+
127
+ /**
128
+ * Shows the alert base js code used to display when needed
129
+ *
130
+ * @access public
131
+ * @return string The javascript content used for the alert dialog
132
+ */
133
+ public function showAlert()
134
+ {
135
+ $this->width = is_numeric($this->width) ? $this->width : 475;
136
+ $this->height = is_numeric($this->height) ? $this->height : 125;
137
+
138
+ echo "tb_show('{$this->title}', '#TB_inline?width={$this->width}&height={$this->height}&inlineId={$this->id}');";
139
+ }
140
+
141
+ /**
142
+ * Shows the confirm base js code used to display when needed
143
+ *
144
+ * @access public
145
+ * @return string The javascript content used for the confirm dialog
146
+ */
147
+ public function initConfirm()
148
+ {
149
+ $ok = __('OK', 'duplicator');
150
+ $cancel = __('Cancel', 'duplicator');
151
+
152
+ $progress_data = '';
153
+ $progress_func2 = '';
154
+
155
+ //Enable the progress spinner
156
+ if ($this->progressOn) {
157
+ $progress_func1 = "__DUP_UI_Dialog_".$this->uniqid;
158
+ $progress_func2 = ";{$progress_func1}(this)";
159
+ $progress_data = <<<HTML
160
+ <div class='dup-dlg-confirm-progress'><i class='fa fa-circle-o-notch fa-spin fa-lg fa-fw'></i> {$this->progressText}</div>
161
+ <script>
162
+ function {$progress_func1}(obj)
163
+ {
164
+ jQuery(obj).parent().parent().find('.dup-dlg-confirm-progress').show();
165
+ jQuery(obj).closest('.dup-dlg-confirm-btns').find('input').attr('disabled', 'true');
166
+ }
167
+ </script>
168
+ HTML;
169
+ }
170
+
171
+ $html = <<<HTML
172
+ <div id="{$this->id}" style="display:none">
173
+ <div class="dup-dlg-confirm-txt">
174
+ <span id="{$this->id}_message">{$this->message}</span>
175
+ <br/><br/>
176
+ {$progress_data}
177
+ </div>
178
+ <div class="dup-dlg-confirm-btns">
179
+ <input type="button" class="button button-large" value="{$ok}" onclick="{$this->jscallback}{$progress_func2}" />
180
+ <input type="button" class="button button-large" value="{$cancel}" onclick="tb_remove()" />
181
+ </div>
182
+ </div>
183
+ HTML;
184
+
185
+ echo $html;
186
+ }
187
+
188
+ /**
189
+ * Shows the confirm base js code used to display when needed
190
+ *
191
+ * @access public
192
+ * @return string The javascript content used for the confirm dialog
193
+ */
194
+ public function showConfirm()
195
+ {
196
+ $this->width = is_numeric($this->width) ? $this->width : 500;
197
+ $this->height = is_numeric($this->height) ? $this->height : 150;
198
+ echo "tb_show('{$this->title}', '#TB_inline?width={$this->width}&height={$this->height}&inlineId={$this->id}');";
199
+ }
200
+ }
classes/ui/class.ui.notice.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Used to display notices in the WordPress Admin area
4
+ * This class takes advatage of the 'admin_notice' action.
5
+ *
6
+ * Standard: PSR-2
7
+ * @link http://www.php-fig.org/psr/psr-2
8
+ *
9
+ * @package Duplicator
10
+ * @subpackage classes/ui
11
+ * @copyright (c) 2017, Snapcreek LLC
12
+ * @since 1.1.0
13
+ *
14
+ */
15
+
16
+ // Exit if accessed directly
17
+ if (!defined('DUPLICATOR_VERSION')) {
18
+ exit;
19
+ }
20
+
21
+ class DUP_UI_Notice
22
+ {
23
+
24
+ /**
25
+ * Shows a display message in the wp-admin if any researved files are found
26
+ *
27
+ * @return string Html formated text notice warnings
28
+ */
29
+ public static function showReservedFilesNotice()
30
+ {
31
+ //Show only on Duplicator pages and Dashboard when plugin is active
32
+ $dup_active = is_plugin_active('duplicator/duplicator.php');
33
+ $dup_perm = current_user_can('manage_options');
34
+ if (!$dup_active || !$dup_perm) return;
35
+
36
+ if (DUP_Server::hasInstallerFiles()) {
37
+ $screen = get_current_screen();
38
+ $on_active_tab = isset($_GET['tab']) && $_GET['tab'] == 'cleanup' ? true : false;
39
+
40
+ echo '<div class="error" id="dup-global-error-reserved-files"><p>';
41
+ if ($screen->id == 'duplicator_page_duplicator-tools' && $on_active_tab) {
42
+ _e('Reserved Duplicator install files have been detected in the root directory. Please delete these reserved files to avoid security issues.', 'duplicator');
43
+ } else {
44
+ $duplicator_nonce = wp_create_nonce('duplicator_cleanup_page');
45
+ _e('Reserved Duplicator install files have been detected in the root directory. Please delete these reserved files to avoid security issues.', 'duplicator');
46
+ @printf("<br/><a href='admin.php?page=duplicator-tools&tab=cleanup&_wpnonce=%s'>%s</a>", $duplicator_nonce, __('Take me to the cleanup page!', 'duplicator'));
47
+ }
48
+ echo "</p></div>";
49
+ }
50
+ }
51
+ }
classes/ui/class.ui.viewstate.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Gets the view state of UI elements to remember its viewable state
4
+ *
5
+ * Standard: PSR-2
6
+ * @link http://www.php-fig.org/psr/psr-2
7
+ *
8
+ * @package Duplicator
9
+ * @subpackage classes/ui
10
+ * @copyright (c) 2017, Snapcreek LLC
11
+ * @since 1.1.0
12
+ *
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if (!defined('DUPLICATOR_VERSION')) {
17
+ exit;
18
+ }
19
+
20
+ class DUP_UI_ViewState
21
+ {
22
+ /**
23
+ * The key used in the wp_options table
24
+ *
25
+ * @var string
26
+ */
27
+ private static $optionsViewStateKey = 'duplicator_ui_view_state';
28
+
29
+ /**
30
+ * Save the view state of UI elements
31
+ *
32
+ * @param string $key A unique key to define the ui element
33
+ * @param string $value A generic value to use for the view state
34
+ */
35
+ public static function save($key, $value)
36
+ {
37
+ $view_state = array();
38
+ $view_state = get_option(self::$optionsViewStateKey);
39
+ $view_state[$key] = $value;
40
+ $success = update_option(self::$optionsViewStateKey, $view_state);
41
+ return $success;
42
+ }
43
+
44
+ /**
45
+ * Gets all the values from the settings array
46
+ *
47
+ * @return array Returns and array of all the values stored in the settings array
48
+ */
49
+ public static function getArray()
50
+ {
51
+ return get_option(self::$optionsViewStateKey);
52
+ }
53
+
54
+ /**
55
+ * Return the value of the of view state item
56
+ *
57
+ * @param type $searchKey The key to search on
58
+ * @return string Returns the value of the key searched or null if key is not found
59
+ */
60
+ public static function getValue($searchKey)
61
+ {
62
+ $view_state = get_option(self::$optionsViewStateKey);
63
+ if (is_array($view_state)) {
64
+ foreach ($view_state as $key => $value) {
65
+ if ($key == $searchKey) {
66
+ return $value;
67
+ }
68
+ }
69
+ }
70
+ return null;
71
+ }
72
+ }
classes/ui/ui.php DELETED
@@ -1,92 +0,0 @@
1
- <?php
2
- if ( ! defined('DUPLICATOR_VERSION') ) exit; // Exit if accessed directly
3
-
4
- /**
5
- * Helper Class for UI internactions
6
- * @package Dupicator\classes
7
- */
8
- class DUP_UI
9
- {
10
-
11
- /**
12
- * The key used in the wp_options table
13
- * @var string
14
- */
15
- private static $OptionsViewStateKey = 'duplicator_ui_view_state';
16
-
17
- /**
18
- * Save the view state of UI elements
19
- * @param string $key A unique key to define the ui element
20
- * @param string $value A generic value to use for the view state
21
- */
22
- public static function SaveViewState($key, $value)
23
- {
24
- $view_state = array();
25
- $view_state = get_option(self::$OptionsViewStateKey);
26
- $view_state[$key] = $value;
27
- $success = update_option(self::$OptionsViewStateKey, $view_state);
28
- return $success;
29
- }
30
-
31
-
32
- /**
33
- * Gets all the values from the settings array
34
- * @return array Returns and array of all the values stored in the settings array
35
- */
36
- public static function GetViewStateArray()
37
- {
38
- return get_option(self::$OptionsViewStateKey);
39
- }
40
-
41
- /**
42
- * Return the value of the of view state item
43
- * @param type $searchKey The key to search on
44
- * @return string Returns the value of the key searched or null if key is not found
45
- */
46
- public static function GetViewStateValue($searchKey)
47
- {
48
- $view_state = get_option(self::$OptionsViewStateKey);
49
- if (is_array($view_state)) {
50
- foreach ($view_state as $key => $value) {
51
- if ($key == $searchKey) {
52
- return $value;
53
- }
54
- }
55
- }
56
- return null;
57
- }
58
-
59
- /**
60
- * Shows a display message in the wp-admin if any researved files are found
61
- * @return type void
62
- */
63
- public static function ShowReservedFilesNotice()
64
- {
65
- //Show only on Duplicator pages and Dashboard when plugin is active
66
- $dup_active = is_plugin_active('duplicator/duplicator.php');
67
- $dup_perm = current_user_can( 'manage_options' );
68
- if (! $dup_active || ! $dup_perm)
69
- return;
70
-
71
- if (DUP_Server::InstallerFilesFound())
72
- {
73
- $screen = get_current_screen();
74
- $on_active_tab = isset($_GET['tab']) && $_GET['tab'] == 'cleanup' ? true : false;
75
-
76
- echo '<div class="error" id="dup-global-error-reserved-files"><p>';
77
- if ($screen->id == 'duplicator_page_duplicator-tools' && $on_active_tab)
78
- {
79
- _e('Reserved Duplicator install files have been detected in the root directory. Please delete these reserved files to avoid security issues.', 'duplicator');
80
- }
81
- else
82
- {
83
- $duplicator_nonce = wp_create_nonce('duplicator_cleanup_page');
84
- _e('Reserved Duplicator install files have been detected in the root directory. Please delete these reserved files to avoid security issues.', 'duplicator');
85
- @printf("<br/><a href='admin.php?page=duplicator-tools&tab=cleanup&_wpnonce=%s'>%s</a>", $duplicator_nonce, __('Take me to the cleanup page!', 'duplicator'));
86
- }
87
- echo "</p></div>";
88
- }
89
- }
90
-
91
- }
92
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/utilities/class.db.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Lightweight abstraction layer for common simple database routines
4
+ *
5
+ * Standard: PSR-2
6
+ * @link http://www.php-fig.org/psr/psr-2
7
+ *
8
+ * @package Duplicator
9
+ * @subpackage classes/utilities
10
+ * @copyright (c) 2017, Snapcreek LLC
11
+ * @since 1.1.32
12
+ *
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if (!defined('DUPLICATOR_VERSION')) {
17
+ exit;
18
+ }
19
+
20
+ class DUP_DB extends wpdb
21
+ {
22
+
23
+ /**
24
+ * Get the requested MySQL system variable
25
+ *
26
+ * @param string $name The database variable name to lookup
27
+ *
28
+ * @return string the server variable to query for
29
+ */
30
+ public static function getVariable($name)
31
+ {
32
+ global $wpdb;
33
+ $row = $wpdb->get_row("SHOW VARIABLES LIKE '{$name}'", ARRAY_N);
34
+ return isset($row[1]) ? $row[1] : null;
35
+ }
36
+
37
+ /**
38
+ * Gets the MySQL database version number
39
+ *
40
+ * @param bool $full True: Gets the full version
41
+ * False: Gets only the numeric portion i.e. 5.5.6 or 10.1.2 (for MariaDB)
42
+ *
43
+ * @return false|string 0 on failure, version number on success
44
+ */
45
+ public static function getVersion($full = false)
46
+ {
47
+ if ($full) {
48
+ $version = self::getVariable('version');
49
+ } else {
50
+ $version = preg_replace('/[^0-9.].*/', '', self::getVariable('version'));
51
+ }
52
+
53
+ return empty($version) ? 0 : $version;
54
+ }
55
+
56
+
57
+ /**
58
+ * Returns the mysqldump path if the server is enabled to execute it
59
+ * @return boolean|string
60
+ */
61
+ public static function getMySqlDumpPath()
62
+ {
63
+
64
+ //Is shell_exec possible
65
+ if (!DUP_Util::hasShellExec()) {
66
+ return false;
67
+ }
68
+
69
+ $custom_mysqldump_path = DUP_Settings::Get('package_mysqldump_path');
70
+ $custom_mysqldump_path = (strlen($custom_mysqldump_path)) ? $custom_mysqldump_path : '';
71
+
72
+ //Common Windows Paths
73
+ if (DUP_Util::isWindows()) {
74
+ $paths = array(
75
+ $custom_mysqldump_path,
76
+ 'C:/xampp/mysql/bin/mysqldump.exe',
77
+ 'C:/Program Files/xampp/mysql/bin/mysqldump',
78
+ 'C:/Program Files/MySQL/MySQL Server 6.0/bin/mysqldump',
79
+ 'C:/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump',
80
+ 'C:/Program Files/MySQL/MySQL Server 5.4/bin/mysqldump',
81
+ 'C:/Program Files/MySQL/MySQL Server 5.1/bin/mysqldump',
82
+ 'C:/Program Files/MySQL/MySQL Server 5.0/bin/mysqldump',
83
+ );
84
+
85
+ //Common Linux Paths
86
+ } else {
87
+ $path1 = '';
88
+ $path2 = '';
89
+ $mysqldump = `which mysqldump`;
90
+ if (@is_executable($mysqldump)) $path1 = (!empty($mysqldump)) ? $mysqldump : '';
91
+
92
+ $mysqldump = dirname(`which mysql`)."/mysqldump";
93
+ if (@is_executable($mysqldump)) $path2 = (!empty($mysqldump)) ? $mysqldump : '';
94
+
95
+ $paths = array(
96
+ $custom_mysqldump_path,
97
+ $path1,
98
+ $path2,
99
+ '/usr/local/bin/mysqldump',
100
+ '/usr/local/mysql/bin/mysqldump',
101
+ '/usr/mysql/bin/mysqldump',
102
+ '/usr/bin/mysqldump',
103
+ '/opt/local/lib/mysql6/bin/mysqldump',
104
+ '/opt/local/lib/mysql5/bin/mysqldump',
105
+ '/opt/local/lib/mysql4/bin/mysqldump',
106
+ );
107
+ }
108
+
109
+ // Find the one which works
110
+ foreach ($paths as $path) {
111
+ if (@is_executable($path)) return $path;
112
+ }
113
+
114
+ return false;
115
+ }
116
+
117
+ }
classes/utilities/class.scan.check.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Recursivly scans a directory and finds all sym-links and unreadable files
4
+ *
5
+ * Standard: PSR-2
6
+ * @link http://www.php-fig.org/psr/psr-2
7
+ *
8
+ * @package Duplicator
9
+ * @subpackage classes/utilites
10
+ * @copyright (c) 2017, Snapcreek LLC
11
+ * @since 1.1.26
12
+ *
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if (!defined('DUPLICATOR_VERSION')) {
17
+ exit;
18
+ }
19
+
20
+ class DUP_ScanCheck
21
+ {
22
+ /**
23
+ * The number of files scanned
24
+ */
25
+ public $fileCount = 0;
26
+
27
+ /**
28
+ * The number of directories scanned
29
+ */
30
+ public $dirCount = 0;
31
+
32
+ /**
33
+ * The maximum count of files before the recursive function stops
34
+ */
35
+ public $maxFiles = 1000000;
36
+
37
+ /**
38
+ * The maximum count of directories before the recursive function stops
39
+ */
40
+ public $maxDirs = 75000;
41
+
42
+ /**
43
+ * Recursivly scan the root directory provided
44
+ */
45
+ public $recursion = true;
46
+
47
+ /**
48
+ * Stores a list of symbolic link files
49
+ */
50
+ public $symLinks = array();
51
+
52
+ /**
53
+ * Stores a list of files unreadable by PHP
54
+ */
55
+ public $unreadable = array();
56
+
57
+ /**
58
+ * If the maxFiles or maxDirs limit is reached then true
59
+ */
60
+ protected $limitReached = false;
61
+
62
+ /**
63
+ * Is the server running on Windows
64
+ */
65
+ private $isWindows = false;
66
+
67
+ /**
68
+ * Init this instance of the object
69
+ */
70
+ function __construct()
71
+ {
72
+ $this->isWindows = defined('PHP_WINDOWS_VERSION_BUILD');
73
+ }
74
+
75
+ /**
76
+ * Start the scan process
77
+ *
78
+ * @param string $dir A valid directory path where the scan will run
79
+ * @param array $results Used for recursion, do not pass in value with calling
80
+ *
81
+ * @return obj The scan check object with the results of the scan
82
+ */
83
+ public function run($dir, &$results = array())
84
+ {
85
+ //Stop Recursion if Max search is reached
86
+ if ($this->fileCount > $this->maxFiles || $this->dirCount > $this->maxDirs) {
87
+ $this->limitReached = true;
88
+ return $results;
89
+ }
90
+
91
+ $files = @scandir($dir);
92
+ if (is_array($files)) {
93
+ foreach ($files as $key => $value) {
94
+ $path = realpath($dir.DIRECTORY_SEPARATOR.$value);
95
+ if ($path) {
96
+ //Files
97
+ if (!is_dir($path)) {
98
+ if (!is_readable($path)) {
99
+ $results[] = $path;
100
+ $this->unreadable[] = $path;
101
+ } else if ($this->isLink($path)) {
102
+ $results[] = $path;
103
+ $this->symLinks[] = $path;
104
+ }
105
+ $this->fileCount++;
106
+ }
107
+ //Dirs
108
+ else if ($value != "." && $value != "..") {
109
+ if (!$this->isLink($path) && $this->recursion) {
110
+ $this->Run($path, $results);
111
+ }
112
+
113
+ if (!is_readable($path)) {
114
+ $results[] = $path;
115
+ $this->unreadable[] = $path;
116
+ } else if ($this->isLink($path)) {
117
+ $results[] = $path;
118
+ $this->symLinks[] = $path;
119
+ }
120
+ $this->dirCount++;
121
+ }
122
+ }
123
+ }
124
+ }
125
+ return $this;
126
+ }
127
+
128
+ /**
129
+ * Seperation logic for supporting how different operating systems work
130
+ *
131
+ * @param string $target A valid file path
132
+ *
133
+ * @return bool Is the target a sym link
134
+ */
135
+ private function isLink($target)
136
+ {
137
+ if ($this->isWindows) {
138
+ if (file_exists($target) && @readlink($target) != $target) {
139
+ return true;
140
+ }
141
+ } elseif (is_link($target)) {
142
+ return true;
143
+ }
144
+ return false;
145
+ }
146
+ }
classes/utilities/class.server.php ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Used to get various pieces of information about the server enviroment
4
+ *
5
+ * Standard: PSR-2
6
+ * @link http://www.php-fig.org/psr/psr-2
7
+ *
8
+ * @package Duplicator
9
+ * @subpackage classes/utilites
10
+ * @copyright (c) 2017, Snapcreek LLC
11
+ * @since 1.1.0
12
+ *
13
+ */
14
+ require_once (DUPLICATOR_PLUGIN_PATH.'classes/utilities/class.util.php');
15
+
16
+ // Exit if accessed directly
17
+ if (!defined('DUPLICATOR_VERSION')) {
18
+ exit;
19
+ }
20
+
21
+ class DUP_Server
22
+ {
23
+
24
+ /**
25
+ * Gets the system requirements which must pass to buld a package
26
+ *
27
+ * @return array An array of requirements
28
+ */
29
+ public static function getRequirements()
30
+ {
31
+ global $wpdb;
32
+ $dup_tests = array();
33
+
34
+ //PHP SUPPORT
35
+ $safe_ini = strtolower(ini_get('safe_mode'));
36
+ $dup_tests['PHP']['SAFE_MODE'] = $safe_ini != 'on' || $safe_ini != 'yes' || $safe_ini != 'true' || ini_get("safe_mode") != 1 ? 'Pass' : 'Fail';
37
+ $dup_tests['PHP']['VERSION'] = DUP_Util::$on_php_529_plus ? 'Pass' : 'Fail';
38
+ $dup_tests['PHP']['ZIP'] = class_exists('ZipArchive') ? 'Pass' : 'Fail';
39
+ $dup_tests['PHP']['FUNC_1'] = function_exists("file_get_contents") ? 'Pass' : 'Fail';
40
+ $dup_tests['PHP']['FUNC_2'] = function_exists("file_put_contents") ? 'Pass' : 'Fail';
41
+ $dup_tests['PHP']['FUNC_3'] = function_exists("mb_strlen") ? 'Pass' : 'Fail';
42
+ $dup_tests['PHP']['ALL'] = !in_array('Fail', $dup_tests['PHP']) ? 'Pass' : 'Fail';
43
+
44
+ //REQUIRED PATHS
45
+ if (file_exists(DUPLICATOR_SSDIR_PATH) && is_writeable(DUPLICATOR_SSDIR_PATH)) {
46
+ $dup_tests['IO']['SSDIR'] = 'Pass';
47
+ $dup_tests['IO']['WPROOT'] = 'Pass';
48
+ } else {
49
+ $handle_test = @opendir(DUPLICATOR_WPROOTPATH);
50
+ $dup_tests['IO']['WPROOT'] = is_writeable(DUPLICATOR_WPROOTPATH) && $handle_test ? 'Pass' : 'Fail';
51
+ $dup_tests['IO']['SSDIR'] = 'Fail';
52
+ @closedir($handle_test);
53
+ }
54
+
55
+ $dup_tests['IO']['SSTMP'] = is_writeable(DUPLICATOR_SSDIR_PATH_TMP) ? 'Pass' : 'Fail';
56
+ $dup_tests['IO']['ALL'] = !in_array('Fail', $dup_tests['IO']) ? 'Pass' : 'Fail';
57
+
58
+ //SERVER SUPPORT
59
+ $dup_tests['SRV']['MYSQLi'] = function_exists('mysqli_connect') ? 'Pass' : 'Fail';
60
+ $dup_tests['SRV']['MYSQL_VER'] = version_compare(DUP_DB::getVersion(), '5.0', '>=') ? 'Pass' : 'Fail';
61
+ $dup_tests['SRV']['ALL'] = !in_array('Fail', $dup_tests['SRV']) ? 'Pass' : 'Fail';
62
+
63
+ //RESERVED FILES
64
+ $dup_tests['RES']['INSTALL'] = !(self::hasInstallerFiles()) ? 'Pass' : 'Fail';
65
+ $dup_tests['Success'] = $dup_tests['PHP']['ALL'] == 'Pass'
66
+ && $dup_tests['IO']['ALL'] == 'Pass'
67
+ && $dup_tests['SRV']['ALL'] == 'Pass'
68
+ && $dup_tests['RES']['INSTALL'] == 'Pass';
69
+
70
+ return $dup_tests;
71
+ }
72
+
73
+ /**
74
+ * Gets the system checks which are not required
75
+ *
76
+ * @return array An array of system checks
77
+ */
78
+ public static function getChecks()
79
+ {
80
+ $checks = array();
81
+
82
+ //WEB SERVER
83
+ $web_test1 = false;
84
+ foreach ($GLOBALS['DUPLICATOR_SERVER_LIST'] as $value) {
85
+ if (stristr($_SERVER['SERVER_SOFTWARE'], $value)) {
86
+ $web_test1 = true;
87
+ break;
88
+ }
89
+ }
90
+ $checks['SRV']['WEB']['model'] = $web_test1;
91
+ $checks['SRV']['WEB']['ALL'] = ($web_test1) ? 'Good' : 'Warn';
92
+
93
+ //PHP SETTINGS
94
+ $php_test1 = ini_get("open_basedir");
95
+ $php_test1 = empty($php_test1) ? true : false;
96
+ $php_test2 = ini_get("max_execution_time");
97
+ $php_test2 = ($php_test2 > DUPLICATOR_SCAN_TIMEOUT) || (strcmp($php_test2, 'Off') == 0 || $php_test2 == 0) ? true : false;
98
+ $php_test3 = function_exists('mysqli_connect');
99
+ $php_test4 = DUP_Util::$on_php_53_plus ? true : false;
100
+
101
+ $checks['SRV']['PHP']['openbase'] = $php_test1;
102
+ $checks['SRV']['PHP']['maxtime'] = $php_test2;
103
+ $checks['SRV']['PHP']['mysqli'] = $php_test3;
104
+ $checks['SRV']['PHP']['version'] = $php_test4;
105
+ $checks['SRV']['PHP']['ALL'] = ($php_test1 && $php_test2 && $php_test3 && $php_test4) ? 'Good' : 'Warn';
106
+
107
+
108
+ //WORDPRESS SETTINGS
109
+ global $wp_version;
110
+ $wp_test1 = version_compare($wp_version, DUPLICATOR_SCAN_MIN_WP) >= 0 ? true : false;
111
+
112
+ //Core Files
113
+ $files = array();
114
+ $files['wp-config.php'] = file_exists(DUP_Util::safePath(DUPLICATOR_WPROOTPATH.'/wp-config.php'));
115
+ $wp_test2 = $files['wp-config.php'];
116
+
117
+ //Cache
118
+ $Package = DUP_Package::getActive();
119
+ $cache_path = DUP_Util::safePath(WP_CONTENT_DIR).'/cache';
120
+ $dirEmpty = DUP_Util::isDirectoryEmpty($cache_path);
121
+ $dirSize = DUP_Util::getDirectorySize($cache_path);
122
+ $cach_filtered = in_array($cache_path, explode(';', $Package->Archive->FilterDirs));
123
+ $wp_test3 = ($cach_filtered || $dirEmpty || $dirSize < DUPLICATOR_SCAN_CACHESIZE ) ? true : false;
124
+ $wp_test4 = is_multisite();
125
+
126
+ $checks['SRV']['WP']['version'] = $wp_test1;
127
+ $checks['SRV']['WP']['core'] = $wp_test2;
128
+ $checks['SRV']['WP']['cache'] = $wp_test3;
129
+ $checks['SRV']['WP']['ismu'] = $wp_test4;
130
+ $checks['SRV']['WP']['ALL'] = $wp_test1 && $wp_test2 && $wp_test3 && !$wp_test4 ? 'Good' : 'Warn';
131
+
132
+ return $checks;
133
+ }
134
+
135
+ /**
136
+ * Check to see if duplicator installer files are present
137
+ *
138
+ * @return bool True if any reserved files are found
139
+ */
140
+ public static function hasInstallerFiles()
141
+ {
142
+ $files = self::getInstallerFiles();
143
+ foreach ($files as $file => $path) {
144
+ if (file_exists($path)) return true;
145
+ }
146
+ return false;
147
+ }
148
+
149
+ /**
150
+ * Gets a list of all the installer files by name and full path
151
+ *
152
+ * @return array [file_name, file_path]
153
+ */
154
+ public static function getInstallerFiles()
155
+ {
156
+ // Files: installer.php, installer-backup.php, installer-data.sql, installer-log.txt, database.sql
157
+ return array(
158
+ DUPLICATOR_INSTALL_PHP => DUPLICATOR_WPROOTPATH.DUPLICATOR_INSTALL_PHP,
159
+ DUPLICATOR_INSTALL_BAK => DUPLICATOR_WPROOTPATH.DUPLICATOR_INSTALL_BAK,
160
+ DUPLICATOR_INSTALL_SQL => DUPLICATOR_WPROOTPATH.DUPLICATOR_INSTALL_SQL,
161
+ DUPLICATOR_INSTALL_LOG => DUPLICATOR_WPROOTPATH.DUPLICATOR_INSTALL_LOG,
162
+ DUPLICATOR_INSTALL_DB => DUPLICATOR_WPROOTPATH.DUPLICATOR_INSTALL_DB
163
+ );
164
+ }
165
+
166
+ /**
167
+ * Get the IP of a client machine
168
+ *
169
+ * @return string IP of the client machine
170
+ */
171
+ public static function getClientIP()
172
+ {
173
+ if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
174
+ return $_SERVER["HTTP_X_FORWARDED_FOR"];
175
+ } else if (array_key_exists('REMOTE_ADDR', $_SERVER)) {
176
+ return $_SERVER["REMOTE_ADDR"];
177
+ } else if (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
178
+ return $_SERVER["HTTP_CLIENT_IP"];
179
+ }
180
+ return '';
181
+ }
182
+
183
+ /**
184
+ * Get PHP memory useage
185
+ *
186
+ * @return string Returns human readable memory useage.
187
+ */
188
+ public static function getPHPMemory($peak = false)
189
+ {
190
+ if ($peak) {
191
+ $result = 'Unable to read PHP peak memory usage';
192
+ if (function_exists('memory_get_peak_usage')) {
193
+ $result = DUP_Util::byteSize(memory_get_peak_usage(true));
194
+ }
195
+ } else {
196
+ $result = 'Unable to read PHP memory usage';
197
+ if (function_exists('memory_get_usage')) {
198
+ $result = DUP_Util::byteSize(memory_get_usage(true));
199
+ }
200
+ }
201
+ return $result;
202
+ }
203
+ }
204
+ ?>
classes/utilities/class.util.php ADDED
@@ -0,0 +1,481 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Recursivly scans a directory and finds all sym-links and unreadable files
4
+ *
5
+ * Standard: PSR-2
6
+ * @link http://www.php-fig.org/psr/psr-2
7
+ *
8
+ * @package Duplicator
9
+ * @subpackage classes/utilites
10
+ * @copyright (c) 2017, Snapcreek LLC
11
+ * @since 1.1.0
12
+ *
13
+ * @todo Refactor out IO methods into class.io.php file
14
+ */
15
+
16
+ // Exit if accessed directly
17
+ if (!defined('DUPLICATOR_VERSION')) {
18
+ exit;
19
+ }
20
+
21
+ class DUP_Util
22
+ {
23
+ /**
24
+ * Is PHP 5.2.9 or better running
25
+ */
26
+ public static $on_php_529_plus;
27
+
28
+ /**
29
+ * Is PHP 5.3 or better running
30
+ */
31
+ public static $on_php_53_plus;
32
+
33
+ /**
34
+ * Is PHP 5.4 or better running
35
+ */
36
+ public static $on_php_54_plus;
37
+
38
+ /**
39
+ * Inited on load (see end of file)
40
+ */
41
+ public static function init()
42
+ {
43
+ self::$on_php_529_plus = version_compare(PHP_VERSION, '5.2.9') >= 0;
44
+ self::$on_php_53_plus = version_compare(PHP_VERSION, '5.3.0') >= 0;
45
+ self::$on_php_54_plus = version_compare(PHP_VERSION, '5.4.0') >= 0;
46
+ }
47
+
48
+ /**
49
+ * PHP_SAPI for fcgi requires a data flush of at least 256
50
+ * bytes every 40 seconds or else it forces a script hault
51
+ *
52
+ * @return string A series of 256 space characters
53
+ */
54
+ public static function fcgiFlush()
55
+ {
56
+ echo(str_repeat(' ', 300));
57
+ @flush();
58
+ }
59
+
60
+ /**
61
+ * Returns the wp-snapshot url
62
+ *
63
+ * @return string The full url of the duplicators snapshot storage directory
64
+ */
65
+ public static function snapshotURL()
66
+ {
67
+ return get_site_url(null, '', is_ssl() ? 'https' : 'http').'/'.DUPLICATOR_SSDIR_NAME.'/';
68
+ }
69
+
70
+ /**
71
+ * Returns the last N lines of a file. Equivelent to tail command
72
+ *
73
+ * @param string $filepath The full path to the file to be tailed
74
+ * @param int $lines The number of lines to return with each tail call
75
+ *
76
+ * @return string The last N parts of the file
77
+ */
78
+ public static function tailFile($filepath, $lines = 2)
79
+ {
80
+
81
+ // Open file
82
+ $f = @fopen($filepath, "rb");
83
+ if ($f === false) return false;
84
+
85
+ // Sets buffer size
86
+ $buffer = 256;
87
+
88
+ // Jump to last character
89
+ fseek($f, -1, SEEK_END);
90
+
91
+ // Read it and adjust line number if necessary
92
+ // (Otherwise the result would be wrong if file doesn't end with a blank line)
93
+ if (fread($f, 1) != "\n") $lines -= 1;
94
+
95
+ // Start reading
96
+ $output = '';
97
+ $chunk = '';
98
+
99
+ // While we would like more
100
+ while (ftell($f) > 0 && $lines >= 0) {
101
+ // Figure out how far back we should jump
102
+ $seek = min(ftell($f), $buffer);
103
+ // Do the jump (backwards, relative to where we are)
104
+ fseek($f, -$seek, SEEK_CUR);
105
+ // Read a chunk and prepend it to our output
106
+ $output = ($chunk = fread($f, $seek)).$output;
107
+ // Jump back to where we started reading
108
+ fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
109
+ // Decrease our line counter
110
+ $lines -= substr_count($chunk, "\n");
111
+ }
112
+
113
+ // While we have too many lines
114
+ // (Because of buffer size we might have read too many)
115
+ while ($lines++ < 0) {
116
+ // Find first newline and remove all text before that
117
+ $output = substr($output, strpos($output, "\n") + 1);
118
+ }
119
+ fclose($f);
120
+ return trim($output);
121
+ }
122
+
123
+ /**
124
+ * Runs the APC cache to pre-cache the php files
125
+ *
126
+ * @returns bool True if all files where cached
127
+ */
128
+ public static function runAPC()
129
+ {
130
+ if (function_exists('apc_compile_file')) {
131
+ $file01 = @apc_compile_file(DUPLICATOR_PLUGIN_PATH."duplicator.php");
132
+ return ($file01);
133
+ } else {
134
+ return false;
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Display human readable byte sizes
140
+ *
141
+ * @param int $size The size in bytes
142
+ *
143
+ * @return string The size of bytes readable such as 100KB, 20MB, 1GB etc.
144
+ */
145
+ public static function byteSize($size)
146
+ {
147
+ try {
148
+ $units = array('B', 'KB', 'MB', 'GB', 'TB');
149
+ for ($i = 0; $size >= 1024 && $i < 4; $i++) {
150
+ $size /= 1024;
151
+ }
152
+ return round($size, 2).$units[$i];
153
+ } catch (Exception $e) {
154
+ return "n/a";
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Makes path safe for any OS
160
+ * Paths should ALWAYS READ be "/"
161
+ * uni: /home/path/file.xt
162
+ * win: D:/home/path/file.txt
163
+ *
164
+ * @param string $path The path to make safe
165
+ *
166
+ * @return string A path with all slashes facing "/"
167
+ */
168
+ public static function safePath($path)
169
+ {
170
+ return str_replace("\\", "/", $path);
171
+ }
172
+
173
+ /**
174
+ * Get current microtime as a float. Method is used for simple profiling
175
+ *
176
+ * @see elapsedTime
177
+ *
178
+ * @return string A float in the form "msec sec", where sec is the number of seconds since the Unix epoch
179
+ */
180
+ public static function getMicrotime()
181
+ {
182
+ return microtime(true);
183
+ }
184
+
185
+ /**
186
+ * Append the value to the string if it doesn't already exist
187
+ *
188
+ * @param string $string The string to append to
189
+ * @param string $value The string to append to the $string
190
+ *
191
+ * @return string Returns the string with the $value appended once
192
+ */
193
+ public static function appendOnce($string, $value)
194
+
195
+ {
196
+ return $string.(substr($string, -1) == $value ? '' : $value);
197
+ }
198
+
199
+ /**
200
+ * Return a string with the elapsed time
201
+ *
202
+ * @see getMicrotime()
203
+ *
204
+ * @param mixed number $end The final time in the sequence to measure
205
+ * @param mixed number $start The start time in the sequence to measure
206
+ *
207
+ * @return string The time elapsed from $start to $end
208
+ */
209
+ public static function elapsedTime($end, $start)
210
+ {
211
+ return sprintf("%.2f sec.", abs($end - $start));
212
+ }
213
+
214
+ /**
215
+ * List all of the files of a path
216
+ *
217
+ * @param string $path The full path to a system directory
218
+ *
219
+ * @return array of all files in that path
220
+ *
221
+ * Notes:
222
+ * - Avoid using glob() as GLOB_BRACE is not an option on some operating systems
223
+ * - Pre PHP 5.3 DirectoryIterator will crash on unreadable files
224
+ */
225
+ public static function listFiles($path = '.')
226
+ {
227
+ $files = array();
228
+ foreach (new DirectoryIterator($path) as $file) {
229
+ $files[] = str_replace("\\", '/', $file->getPathname());
230
+ }
231
+ return $files;
232
+ }
233
+
234
+ /**
235
+ * List all of the directories of a path
236
+ *
237
+ * @param string $path The full path to a system directory
238
+ *
239
+ * @return array of all dirs in the $path
240
+ */
241
+ public static function listDirs($path = '.')
242
+ {
243
+ $dirs = array();
244
+
245
+ foreach (new DirectoryIterator($path) as $file) {
246
+ if ($file->isDir() && !$file->isDot()) {
247
+ $dirs[] = DUP_Util::safePath($file->getPathname());
248
+ }
249
+ }
250
+ return $dirs;
251
+ }
252
+
253
+ /**
254
+ * Does the directory have content
255
+ *
256
+ * @param string $path The full path to a system directory
257
+ *
258
+ * @return bool Returns true if directory is empty
259
+ */
260
+ public static function isDirectoryEmpty($path)
261
+ {
262
+ if (!is_readable($path)) return NULL;
263
+ return (count(scandir($path)) == 2);
264
+ }
265
+
266
+ /**
267
+ * Size of the directory recursively in bytes
268
+ *
269
+ * @param string $path The full path to a system directory
270
+ *
271
+ * @return int Returns the size of the directory in bytes
272
+ *
273
+ */
274
+ public static function getDirectorySize($path)
275
+ {
276
+ if (!file_exists($path)) return 0;
277
+ if (is_file($path)) return filesize($path);
278
+
279
+ $size = 0;
280
+ $list = glob($path."/*");
281
+ if (!empty($list)) {
282
+ foreach ($list as $file)
283
+ $size += self::getDirectorySize($file);
284
+ }
285
+ return $size;
286
+ }
287
+
288
+ /**
289
+ * Can shell_exec be called on this server
290
+ *
291
+ * @return bool Returns true if shell_exec can be called on server
292
+ *
293
+ */
294
+ public static function hasShellExec()
295
+ {
296
+ $cmds = array('shell_exec', 'escapeshellarg', 'escapeshellcmd', 'extension_loaded');
297
+
298
+ //Function disabled at server level
299
+ if (array_intersect($cmds, array_map('trim', explode(',', @ini_get('disable_functions'))))) return false;
300
+
301
+ //Suhosin: http://www.hardened-php.net/suhosin/
302
+ //Will cause PHP to silently fail
303
+ if (extension_loaded('suhosin')) {
304
+ $suhosin_ini = @ini_get("suhosin.executor.func.blacklist");
305
+ if (array_intersect($cmds, array_map('trim', explode(',', $suhosin_ini)))) return false;
306
+ }
307
+
308
+ // Can we issue a simple echo command?
309
+ if (!@shell_exec('echo duplicator')) return false;
310
+
311
+ return true;
312
+ }
313
+
314
+ /**
315
+ * Is the server running Windows operating system
316
+ *
317
+ * @return bool Returns true if operating system is Windows
318
+ *
319
+ */
320
+ public static function isWindows()
321
+ {
322
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
323
+ return true;
324
+ }
325
+ return false;
326
+ }
327
+
328
+ /**
329
+ * Does the current user have the capability
330
+ *
331
+ * @return null Dies if user doesn't have the correct capability
332
+ */
333
+ public static function hasCapability($permission = 'read')
334
+ {
335
+ $capability = $permission;
336
+ $capability = apply_filters('wpfront_user_role_editor_duplicator_translate_capability', $capability);
337
+
338
+ if (!current_user_can($capability)) {
339
+ wp_die(__('You do not have sufficient permissions to access this page.', 'duplicator'));
340
+ return;
341
+ }
342
+ }
343
+
344
+ /**
345
+ * Gets the name of the owner of the current PHP script
346
+ *
347
+ * @return string The name of the owner of the current PHP script
348
+ */
349
+ public static function getCurrentUser()
350
+ {
351
+ $unreadable = 'Undetectable';
352
+ if (function_exists('get_current_user') && is_callable('get_current_user')) {
353
+ $user = get_current_user();
354
+ return strlen($user) ? $user : $unreadable;
355
+ }
356
+ return $unreadable;
357
+ }
358
+
359
+ /**
360
+ * Gets the owner of the PHP process
361
+ *
362
+ * @return string Gets the owner of the PHP process
363
+ */
364
+ public static function getProcessOwner()
365
+ {
366
+ $unreadable = 'Undetectable';
367
+ $user = '';
368
+ try {
369
+ if (function_exists('exec')) {
370
+ $user = exec('whoami');
371
+ }
372
+
373
+ if (!strlen($user) && function_exists('posix_getpwuid') && function_exists('posix_geteuid')) {
374
+ $user = posix_getpwuid(posix_geteuid());
375
+ $user = $user['name'];
376
+ }
377
+
378
+ return strlen($user) ? $user : $unreadable;
379
+ } catch (Exception $ex) {
380
+ return $unreadable;
381
+ }
382
+ }
383
+
384
+ /**
385
+ * Creates the snapshot directory if it doesn't already exisit
386
+ *
387
+ * @return null
388
+ */
389
+ public static function initSnapshotDirectory()
390
+ {
391
+ $path_wproot = DUP_Util::safePath(DUPLICATOR_WPROOTPATH);
392
+ $path_ssdir = DUP_Util::safePath(DUPLICATOR_SSDIR_PATH);
393
+ $path_plugin = DUP_Util::safePath(DUPLICATOR_PLUGIN_PATH);
394
+
395
+ //--------------------------------
396
+ //CHMOD DIRECTORY ACCESS
397
+ //wordpress root directory
398
+ @chmod($path_wproot, 0755);
399
+
400
+ //snapshot directory
401
+ @mkdir($path_ssdir, 0755);
402
+ @chmod($path_ssdir, 0755);
403
+
404
+ //snapshot tmp directory
405
+ $path_ssdir_tmp = $path_ssdir.'/tmp';
406
+ @mkdir($path_ssdir_tmp, 0755);
407
+ @chmod($path_ssdir_tmp, 0755);
408
+
409
+ //plugins dir/files
410
+ @chmod($path_plugin.'files', 0755);
411
+
412
+ //--------------------------------
413
+ //FILE CREATION
414
+ //SSDIR: Create Index File
415
+ $ssfile = @fopen($path_ssdir.'/index.php', 'w');
416
+ @fwrite($ssfile,
417
+ '<?php error_reporting(0); if (stristr(php_sapi_name(), "fcgi")) { $url = "http://" . $_SERVER["HTTP_HOST"]; header("Location: {$url}/404.html");} else { header("HTTP/1.1 404 Not Found", true, 404);} exit(); ?>');
418
+ @fclose($ssfile);
419
+
420
+ //SSDIR: Create token file in snapshot
421
+ $tokenfile = @fopen($path_ssdir.'/dtoken.php', 'w');
422
+ @fwrite($tokenfile,
423
+ '<?php error_reporting(0); if (stristr(php_sapi_name(), "fcgi")) { $url = "http://" . $_SERVER["HTTP_HOST"]; header("Location: {$url}/404.html");} else { header("HTTP/1.1 404 Not Found", true, 404);} exit(); ?>');
424
+ @fclose($tokenfile);
425
+
426
+ //SSDIR: Create .htaccess
427
+ $storage_htaccess_off = DUP_Settings::Get('storage_htaccess_off');
428
+ if ($storage_htaccess_off) {
429
+ @unlink($path_ssdir.'/.htaccess');
430
+ } else {
431
+ $htfile = @fopen($path_ssdir.'/.htaccess', 'w');
432
+ $htoutput = "Options -Indexes";
433
+ @fwrite($htfile, $htoutput);
434
+ @fclose($htfile);
435
+ }
436
+
437
+ //SSDIR: Robots.txt file
438
+ $robotfile = @fopen($path_ssdir.'/robots.txt', 'w');
439
+ @fwrite($robotfile, "User-agent: * \nDisallow: /".DUPLICATOR_SSDIR_NAME.'/');
440
+ @fclose($robotfile);
441
+
442
+ //PLUG DIR: Create token file in plugin
443
+ $tokenfile2 = @fopen($path_plugin.'installer/dtoken.php', 'w');
444
+ @fwrite($tokenfile2,
445
+ '<?php @error_reporting(0); @require_once("../../../../wp-admin/admin.php"); global $wp_query; $wp_query->set_404(); header("HTTP/1.1 404 Not Found", true, 404); header("Status: 404 Not Found"); @include(get_template_directory () . "/404.php"); ?>');
446
+ @fclose($tokenfile2);
447
+ }
448
+
449
+ /**
450
+ * Attempts to get the file zip path on a users system
451
+ *
452
+ * @return null
453
+ */
454
+ public static function getZipPath()
455
+ {
456
+ $filepath = null;
457
+
458
+ if (self::hasShellExec()) {
459
+ if (shell_exec('hash zip 2>&1') == NULL) {
460
+ $filepath = 'zip';
461
+ } else {
462
+ $possible_paths = array(
463
+ '/usr/bin/zip',
464
+ '/opt/local/bin/zip'
465
+ //'C:/Program\ Files\ (x86)/GnuWin32/bin/zip.exe');
466
+ );
467
+
468
+ foreach ($possible_paths as $path) {
469
+ if (file_exists($path)) {
470
+ $filepath = $path;
471
+ break;
472
+ }
473
+ }
474
+ }
475
+ }
476
+
477
+ return $filepath;
478
+ }
479
+ }
480
+ DUP_Util::init();
481
+ ?>
classes/utility.php DELETED
@@ -1,393 +0,0 @@
1
- <?php
2
- if ( ! defined( 'DUPLICATOR_VERSION' ) ) exit; // Exit if accessed directly
3
-
4
- class DUP_Util
5
- {
6
- public static $on_php_529_plus;
7
- public static $on_php_53_plus;
8
- public static $on_php_54_plus;
9
-
10
-
11
- public static function init()
12
- {
13
- self::$on_php_529_plus = version_compare(PHP_VERSION, '5.2.9') >= 0;
14
- self::$on_php_53_plus = version_compare(PHP_VERSION, '5.3.0') >= 0;
15
- self::$on_php_54_plus = version_compare(PHP_VERSION, '5.4.0') >= 0;
16
- }
17
-
18
- /**
19
- * PHP_SAPI for fcgi requires a data flush of at least 256
20
- * bytes every 40 seconds or else it forces a script hault
21
- */
22
- public static function FcgiFlush() {
23
- echo(str_repeat(' ', 300));
24
- @flush();
25
- }
26
-
27
- /**
28
- * returns the snapshot url
29
- */
30
- public static function SSDirURL() {
31
- return get_site_url(null, '', is_ssl() ? 'https' : 'http') . '/' . DUPLICATOR_SSDIR_NAME . '/';
32
- }
33
-
34
- /**
35
- * Returns the last N lines of a file
36
- * Equivelent to tail command
37
- */
38
- public static function TailFile($filepath, $lines = 2) {
39
-
40
- // Open file
41
- $f = @fopen($filepath, "rb");
42
- if ($f === false) return false;
43
-
44
- // Sets buffer size
45
- $buffer = 256;
46
-
47
- // Jump to last character
48
- fseek($f, -1, SEEK_END);
49
-
50
- // Read it and adjust line number if necessary
51
- // (Otherwise the result would be wrong if file doesn't end with a blank line)
52
- if (fread($f, 1) != "\n") $lines -= 1;
53
-
54
- // Start reading
55
- $output = '';
56
- $chunk = '';
57
-
58
- // While we would like more
59
- while (ftell($f) > 0 && $lines >= 0) {
60
- // Figure out how far back we should jump
61
- $seek = min(ftell($f), $buffer);
62
- // Do the jump (backwards, relative to where we are)
63
- fseek($f, -$seek, SEEK_CUR);
64
- // Read a chunk and prepend it to our output
65
- $output = ($chunk = fread($f, $seek)) . $output;
66
- // Jump back to where we started reading
67
- fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
68
- // Decrease our line counter
69
- $lines -= substr_count($chunk, "\n");
70
- }
71
-
72
- // While we have too many lines
73
- // (Because of buffer size we might have read too many)
74
- while ($lines++ < 0) {
75
- // Find first newline and remove all text before that
76
- $output = substr($output, strpos($output, "\n") + 1);
77
- }
78
- fclose($f);
79
- return trim($output);
80
- }
81
-
82
-
83
- /**
84
- * Runs the APC cache to pre-cache the php files
85
- * returns true if all files where cached
86
- */
87
- public static function RunAPC() {
88
- if(function_exists('apc_compile_file')){
89
- $file01 = @apc_compile_file(DUPLICATOR_PLUGIN_PATH . "duplicator.php");
90
- return ($file01);
91
- } else {
92
- return false;
93
- }
94
- }
95
-
96
- /**
97
- * Display human readable byte sizes
98
- * @param string $size The size in bytes
99
- */
100
- public static function ByteSize($size) {
101
- try {
102
- $units = array('B', 'KB', 'MB', 'GB', 'TB');
103
- for ($i = 0; $size >= 1024 && $i < 4; $i++)
104
- $size /= 1024;
105
- return round($size, 2) . $units[$i];
106
- } catch (Exception $e) {
107
- return "n/a";
108
- }
109
- }
110
-
111
- /**
112
- * Makes path safe for any OS
113
- * Paths should ALWAYS READ be "/"
114
- * uni: /home/path/file.xt
115
- * win: D:/home/path/file.txt
116
- * @param string $path The path to make safe
117
- */
118
- public static function SafePath($path) {
119
- return str_replace("\\", "/", $path);
120
- }
121
-
122
- /**
123
- * Get current microtime as a float. Can be used for simple profiling.
124
- */
125
- public static function GetMicrotime() {
126
- return microtime(true);
127
- }
128
-
129
- /**
130
- * Append the value to the string if it doesn't already exist
131
- */
132
- public static function StringAppend($string, $value ) {
133
- return $string . (substr($string, -1) == $value ? '' : $value);
134
- }
135
-
136
- /**
137
- * Return a string with the elapsed time.
138
- * Order of $end and $start can be switched.
139
- */
140
- public static function ElapsedTime($end, $start) {
141
- return sprintf("%.2f sec.", abs($end - $start));
142
- }
143
-
144
- /**
145
- * Get the MySQL system variables
146
- * @param conn $dbh Database connection handle
147
- * @return string the server variable to query for
148
- */
149
- public static function MysqlVariableValue($variable) {
150
- global $wpdb;
151
- $row = $wpdb->get_row("SHOW VARIABLES LIKE '{$variable}'", ARRAY_N);
152
- return isset($row[1]) ? $row[1] : null;
153
- }
154
-
155
- /**
156
- * List all of the files of a path
157
- * @path path to a system directory
158
- * @return array of all files in that path
159
- *
160
- * Compatibility Notes:
161
- * - Avoid using glob() as GLOB_BRACE is not an option on some operating systems
162
- * - Pre PHP 5.3 DirectoryIterator will crash on unreadable files
163
- */
164
- public static function ListFiles($path = '.')
165
- {
166
- $files = array();
167
- foreach (new DirectoryIterator($path) as $file)
168
- {
169
- $files[] = str_replace("\\", '/', $file->getPathname());
170
- }
171
- return $files;
172
- }
173
-
174
- /**
175
- * List all of the directories of a path
176
- * @path path to a system directory
177
- * @return array of all directories in that path
178
- */
179
- public static function ListDirs($path = '.') {
180
- $dirs = array();
181
-
182
- foreach (new DirectoryIterator($path) as $file) {
183
- if ($file->isDir() && !$file->isDot()) {
184
- $dirs[] = DUP_Util::SafePath($file->getPathname());
185
- }
186
- }
187
- return $dirs;
188
- }
189
-
190
- /**
191
- * Does the directory have content
192
- */
193
- public static function IsDirectoryEmpty($dir) {
194
- if (!is_readable($dir)) return NULL;
195
- return (count(scandir($dir)) == 2);
196
- }
197
-
198
- /**
199
- * Size of the directory recuresivly in bytes
200
- */
201
- public static function GetDirectorySize($dir) {
202
- if(!file_exists($dir))
203
- return 0;
204
- if(is_file($dir))
205
- return filesize($dir);
206
-
207
- $size = 0;
208
- $list = glob($dir."/*");
209
- if (! empty($list)) {
210
- foreach($list as $file)
211
- $size += self::GetDirectorySize($file);
212
- }
213
- return $size;
214
- }
215
-
216
- /**
217
- * Can shell_exec be called on this server
218
- */
219
- public static function IsShellExecAvailable()
220
- {
221
- $cmds = array('shell_exec', 'escapeshellarg', 'escapeshellcmd', 'extension_loaded');
222
-
223
- //Function disabled at server level
224
- if (array_intersect($cmds, array_map('trim', explode(',', @ini_get('disable_functions')))))
225
- return false;
226
-
227
- //Suhosin: http://www.hardened-php.net/suhosin/
228
- //Will cause PHP to silently fail
229
- if (extension_loaded('suhosin'))
230
- {
231
- $suhosin_ini = @ini_get("suhosin.executor.func.blacklist");
232
- if (array_intersect($cmds, array_map('trim', explode(',', $suhosin_ini))))
233
- return false;
234
- }
235
-
236
- // Can we issue a simple echo command?
237
- if (!@shell_exec('echo duplicator'))
238
- return false;
239
-
240
- return true;
241
- }
242
-
243
- public static function IsOSWindows() {
244
- if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
245
- return true;
246
- }
247
- return false;
248
- }
249
-
250
- public static function CheckPermissions($permission = 'read') {
251
- $capability = $permission;
252
- $capability = apply_filters('wpfront_user_role_editor_duplicator_translate_capability', $capability);
253
-
254
- if(!current_user_can($capability)) {
255
- wp_die(__('You do not have sufficient permissions to access this page.', 'duplicator'));
256
- return;
257
- }
258
- }
259
-
260
- /**
261
- * Creates the snapshot directory if it doesn't already exisit
262
- */
263
- public static function GetCurrentUser() {
264
- $unreadable = 'Undetectable';
265
- if (function_exists('get_current_user') && is_callable('get_current_user')) {
266
- $user = get_current_user();
267
- return strlen($user) ? $user : $unreadable;
268
- }
269
- return $unreadable;
270
- }
271
-
272
- /**
273
- * Gets the owner of the PHP process
274
- */
275
- public static function GetProcessOwner() {
276
- $unreadable = 'Undetectable';
277
- $user = '';
278
- try {
279
- if (function_exists('exec')) {
280
- $user = exec('whoami');
281
- }
282
-
283
- if (! strlen($user) && function_exists('posix_getpwuid') && function_exists('posix_geteuid')) {
284
- $user = posix_getpwuid(posix_geteuid());
285
- $user = $user['name'];
286
- }
287
-
288
- return strlen($user) ? $user : $unreadable;
289
-
290
- } catch (Exception $ex) {
291
- return $unreadable;
292
- }
293
- }
294
-
295
- /**
296
- * Creates the snapshot directory if it doesn't already exisit
297
- */
298
- public static function InitSnapshotDirectory() {
299
- $path_wproot = DUP_Util::SafePath(DUPLICATOR_WPROOTPATH);
300
- $path_ssdir = DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH);
301
- $path_plugin = DUP_Util::SafePath(DUPLICATOR_PLUGIN_PATH);
302
-
303
- //--------------------------------
304
- //CHMOD DIRECTORY ACCESS
305
- //wordpress root directory
306
- @chmod($path_wproot, 0755);
307
-
308
- //snapshot directory
309
- @mkdir($path_ssdir, 0755);
310
- @chmod($path_ssdir, 0755);
311
-
312
- //snapshot tmp directory
313
- $path_ssdir_tmp = $path_ssdir . '/tmp';
314
- @mkdir($path_ssdir_tmp, 0755);
315
- @chmod($path_ssdir_tmp, 0755);
316
-
317
- //plugins dir/files
318
- @chmod($path_plugin . 'files', 0755);
319
-
320
- //--------------------------------
321
- //FILE CREATION
322
- //SSDIR: Create Index File
323
- $ssfile = @fopen($path_ssdir . '/index.php', 'w');
324
- @fwrite($ssfile, '<?php error_reporting(0); if (stristr(php_sapi_name(), "fcgi")) { $url = "http://" . $_SERVER["HTTP_HOST"]; header("Location: {$url}/404.html");} else { header("HTTP/1.1 404 Not Found", true, 404);} exit(); ?>');
325
- @fclose($ssfile);
326
-
327
- //SSDIR: Create token file in snapshot
328
- $tokenfile = @fopen($path_ssdir . '/dtoken.php', 'w');
329
- @fwrite($tokenfile, '<?php error_reporting(0); if (stristr(php_sapi_name(), "fcgi")) { $url = "http://" . $_SERVER["HTTP_HOST"]; header("Location: {$url}/404.html");} else { header("HTTP/1.1 404 Not Found", true, 404);} exit(); ?>');
330
- @fclose($tokenfile);
331
-
332
- //SSDIR: Create .htaccess
333
- $storage_htaccess_off = DUP_Settings::Get('storage_htaccess_off');
334
- if ($storage_htaccess_off) {
335
- @unlink($path_ssdir . '/.htaccess');
336
- } else {
337
- $htfile = @fopen($path_ssdir . '/.htaccess', 'w');
338
- $htoutput = "Options -Indexes" ;
339
- @fwrite($htfile, $htoutput);
340
- @fclose($htfile);
341
- }
342
-
343
- //SSDIR: Robots.txt file
344
- $robotfile = @fopen($path_ssdir . '/robots.txt', 'w');
345
- @fwrite($robotfile, "User-agent: * \nDisallow: /" . DUPLICATOR_SSDIR_NAME . '/');
346
- @fclose($robotfile);
347
-
348
- //PLUG DIR: Create token file in plugin
349
- $tokenfile2 = @fopen($path_plugin . 'installer/dtoken.php', 'w');
350
- @fwrite($tokenfile2, '<?php @error_reporting(0); @require_once("../../../../wp-admin/admin.php"); global $wp_query; $wp_query->set_404(); header("HTTP/1.1 404 Not Found", true, 404); header("Status: 404 Not Found"); @include(get_template_directory () . "/404.php"); ?>');
351
- @fclose($tokenfile2);
352
- }
353
-
354
- /**
355
- * Attempts to file zip on a users system
356
- */
357
- public static function GetZipPath()
358
- {
359
- $filepath = null;
360
-
361
- if(self::IsShellExecAvailable())
362
- {
363
- if (shell_exec('hash zip 2>&1') == NULL)
364
- {
365
- $filepath = 'zip';
366
- }
367
- else
368
- {
369
- $possible_paths = array(
370
- '/usr/bin/zip',
371
- '/opt/local/bin/zip'
372
- //'C:/Program\ Files\ (x86)/GnuWin32/bin/zip.exe');
373
- );
374
-
375
- foreach ($possible_paths as $path)
376
- {
377
- if (file_exists($path))
378
- {
379
- $filepath = $path;
380
- break;
381
- }
382
- }
383
- }
384
- }
385
-
386
- return $filepath;
387
- }
388
-
389
- }
390
-
391
-
392
- DUP_Util::init();
393
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ctrls/ctrl.base.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- require_once(DUPLICATOR_PLUGIN_PATH . '/classes/utility.php');
4
 
5
  //Enum used to define the various test statues
6
  final class DUP_CTRL_Status
@@ -78,7 +78,7 @@ class DUP_CTRL_Result
78
 
79
  function __construct(DUP_CTRL_Base $CTRL_OBJ)
80
  {
81
- DUP_Util::CheckPermissions('read');
82
  $this->time_start = $this->microtimeFloat();
83
  $this->CTRL = $CTRL_OBJ;
84
 
1
  <?php
2
 
3
+ require_once(DUPLICATOR_PLUGIN_PATH . '/classes/utilities/class.util.php');
4
 
5
  //Enum used to define the various test statues
6
  final class DUP_CTRL_Status
78
 
79
  function __construct(DUP_CTRL_Base $CTRL_OBJ)
80
  {
81
+ DUP_Util::hasCapability('read');
82
  $this->time_start = $this->microtimeFloat();
83
  $this->CTRL = $CTRL_OBJ;
84
 
ctrls/ctrl.package.php CHANGED
@@ -10,20 +10,20 @@
10
  function duplicator_package_scan() {
11
 
12
  header('Content-Type: application/json;');
13
- DUP_Util::CheckPermissions('export');
14
 
15
  @set_time_limit(0);
16
  $errLevel = error_reporting();
17
  error_reporting(E_ERROR);
18
- DUP_Util::InitSnapshotDirectory();
19
 
20
- $Package = DUP_Package::GetActive();
21
- $report = $Package->Scan();
22
 
23
- $Package->SaveActiveItem('ScanFile', $Package->ScanFile);
24
  $json_response = json_encode($report);
25
 
26
- DUP_Package::TmpCleanup();
27
  error_reporting($errLevel);
28
  die($json_response);
29
  }
@@ -36,7 +36,7 @@ function duplicator_package_scan() {
36
  */
37
  function duplicator_package_build() {
38
 
39
- DUP_Util::CheckPermissions('export');
40
 
41
  check_ajax_referer( 'dup_package_build', 'nonce');
42
 
@@ -45,15 +45,15 @@ function duplicator_package_build() {
45
  @set_time_limit(0);
46
  $errLevel = error_reporting();
47
  error_reporting(E_ERROR);
48
- DUP_Util::InitSnapshotDirectory();
49
 
50
- $Package = DUP_Package::GetActive();
51
 
52
  if (!is_readable(DUPLICATOR_SSDIR_PATH_TMP . "/{$Package->ScanFile}")) {
53
  die("The scan result file was not found. Please run the scan step before building the package.");
54
  }
55
 
56
- $Package->Build();
57
 
58
  //JSON:Debug Response
59
  //Pass = 1, Warn = 2, Fail = 3
@@ -78,7 +78,7 @@ function duplicator_package_build() {
78
  */
79
  function duplicator_package_delete() {
80
 
81
- DUP_Util::CheckPermissions('export');
82
  check_ajax_referer( 'package_list', 'nonce' );
83
 
84
  try {
@@ -102,29 +102,28 @@ function duplicator_package_delete() {
102
  $delResult = $wpdb->query($wpdb->prepare( "DELETE FROM `{$tblName}` WHERE id = %d", $id ));
103
  if ($delResult != 0) {
104
  //Perms
105
- @chmod(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_archive.zip"), 0644);
106
- @chmod(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_database.sql"), 0644);
107
- @chmod(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_installer.php"), 0644);
108
- @chmod(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_archive.zip"), 0644);
109
- @chmod(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_database.sql"), 0644);
110
- @chmod(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_installer.php"), 0644);
111
- @chmod(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_scan.json"), 0644);
112
- @chmod(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}.log"), 0644);
113
  //Remove
114
- @unlink(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_archive.zip"));
115
- @unlink(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_database.sql"));
116
- @unlink(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_installer.php"));
117
- @unlink(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_archive.zip"));
118
- @unlink(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_database.sql"));
119
- @unlink(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_installer.php"));
120
- @unlink(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_scan.json"));
121
- @unlink(DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}.log"));
122
  //Unfinished Zip files
123
  $tmpZip = DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_archive.zip.*";
124
  if ($tmpZip !== false) {
125
  array_map('unlink', glob($tmpZip));
126
  }
127
- @unlink(DUP_Util::SafePath());
128
  $delCount++;
129
  }
130
  }
10
  function duplicator_package_scan() {
11
 
12
  header('Content-Type: application/json;');
13
+ DUP_Util::hasCapability('export');
14
 
15
  @set_time_limit(0);
16
  $errLevel = error_reporting();
17
  error_reporting(E_ERROR);
18
+ DUP_Util::initSnapshotDirectory();
19
 
20
+ $Package = DUP_Package::getActive();
21
+ $report = $Package->runScanner();
22
 
23
+ $Package->saveActiveItem('ScanFile', $Package->ScanFile);
24
  $json_response = json_encode($report);
25
 
26
+ DUP_Package::tempFileCleanup();
27
  error_reporting($errLevel);
28
  die($json_response);
29
  }
36
  */
37
  function duplicator_package_build() {
38
 
39
+ DUP_Util::hasCapability('export');
40
 
41
  check_ajax_referer( 'dup_package_build', 'nonce');
42
 
45
  @set_time_limit(0);
46
  $errLevel = error_reporting();
47
  error_reporting(E_ERROR);
48
+ DUP_Util::initSnapshotDirectory();
49
 
50
+ $Package = DUP_Package::getActive();
51
 
52
  if (!is_readable(DUPLICATOR_SSDIR_PATH_TMP . "/{$Package->ScanFile}")) {
53
  die("The scan result file was not found. Please run the scan step before building the package.");
54
  }
55
 
56
+ $Package->runBuild();
57
 
58
  //JSON:Debug Response
59
  //Pass = 1, Warn = 2, Fail = 3
78
  */
79
  function duplicator_package_delete() {
80
 
81
+ DUP_Util::hasCapability('export');
82
  check_ajax_referer( 'package_list', 'nonce' );
83
 
84
  try {
102
  $delResult = $wpdb->query($wpdb->prepare( "DELETE FROM `{$tblName}` WHERE id = %d", $id ));
103
  if ($delResult != 0) {
104
  //Perms
105
+ @chmod(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_archive.zip"), 0644);
106
+ @chmod(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_database.sql"), 0644);
107
+ @chmod(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_installer.php"), 0644);
108
+ @chmod(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_archive.zip"), 0644);
109
+ @chmod(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_database.sql"), 0644);
110
+ @chmod(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_installer.php"), 0644);
111
+ @chmod(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_scan.json"), 0644);
112
+ @chmod(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}.log"), 0644);
113
  //Remove
114
+ @unlink(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_archive.zip"));
115
+ @unlink(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_database.sql"));
116
+ @unlink(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_installer.php"));
117
+ @unlink(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_archive.zip"));
118
+ @unlink(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_database.sql"));
119
+ @unlink(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_installer.php"));
120
+ @unlink(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}_scan.json"));
121
+ @unlink(DUP_Util::safePath(DUPLICATOR_SSDIR_PATH . "/{$nameHash}.log"));
122
  //Unfinished Zip files
123
  $tmpZip = DUPLICATOR_SSDIR_PATH_TMP . "/{$nameHash}_archive.zip.*";
124
  if ($tmpZip !== false) {
125
  array_map('unlink', glob($tmpZip));
126
  }
 
127
  $delCount++;
128
  }
129
  }
ctrls/ctrl.tools.php CHANGED
@@ -2,7 +2,7 @@
2
  if ( ! defined('DUPLICATOR_VERSION') ) exit; // Exit if accessed directly
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/ctrls/ctrl.base.php');
5
- require_once(DUPLICATOR_PLUGIN_PATH . '/classes/scan.validator.php');
6
 
7
  /**
8
  * Controller for Tools
@@ -10,7 +10,9 @@ require_once(DUPLICATOR_PLUGIN_PATH . '/classes/scan.validator.php');
10
  */
11
  class DUP_CTRL_Tools extends DUP_CTRL_Base
12
  {
13
-
 
 
14
  function __construct()
15
  {
16
  add_action('wp_ajax_DUP_CTRL_Tools_RunScanValidator', array($this, 'RunScanValidator'));
@@ -26,6 +28,7 @@ class DUP_CTRL_Tools extends DUP_CTRL_Base
26
  */
27
  public function RunScanValidator($post)
28
  {
 
29
  $post = $this->PostParamMerge($post);
30
  check_ajax_referer($post['action'], 'nonce');
31
 
@@ -38,12 +41,12 @@ class DUP_CTRL_Tools extends DUP_CTRL_Base
38
  if (!is_dir($path)) {
39
  throw new Exception("Invalid directory provided '{$path}'!");
40
  }
41
- $scanner = new DUP_ScanValidator();
42
- $scanner->Recursion = (isset($post['scan-recursive']) && $post['scan-recursive'] != 'false') ? true : false;
43
- $payload = $scanner->Run($path);
44
 
45
  //RETURN RESULT
46
- $test = ($payload->FileCount > 0)
47
  ? DUP_CTRL_Status::SUCCESS
48
  : DUP_CTRL_Status::FAILED;
49
  $result->Process($payload, $test);
2
  if ( ! defined('DUPLICATOR_VERSION') ) exit; // Exit if accessed directly
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/ctrls/ctrl.base.php');
5
+ require_once(DUPLICATOR_PLUGIN_PATH . '/classes/utilities/class.scan.check.php');
6
 
7
  /**
8
  * Controller for Tools
10
  */
11
  class DUP_CTRL_Tools extends DUP_CTRL_Base
12
  {
13
+ /**
14
+ * Init this instance of the object
15
+ */
16
  function __construct()
17
  {
18
  add_action('wp_ajax_DUP_CTRL_Tools_RunScanValidator', array($this, 'RunScanValidator'));
28
  */
29
  public function RunScanValidator($post)
30
  {
31
+ @set_time_limit(0);
32
  $post = $this->PostParamMerge($post);
33
  check_ajax_referer($post['action'], 'nonce');
34
 
41
  if (!is_dir($path)) {
42
  throw new Exception("Invalid directory provided '{$path}'!");
43
  }
44
+ $scanner = new DUP_ScanCheck();
45
+ $scanner->recursion = (isset($post['scan-recursive']) && $post['scan-recursive'] != 'false') ? true : false;
46
+ $payload = $scanner->run($path);
47
 
48
  //RETURN RESULT
49
+ $test = ($payload->fileCount > 0)
50
  ? DUP_CTRL_Status::SUCCESS
51
  : DUP_CTRL_Status::FAILED;
52
  $result->Process($payload, $test);
ctrls/ctrl.ui.php CHANGED
@@ -2,7 +2,7 @@
2
  if ( ! defined('DUPLICATOR_VERSION') ) exit; // Exit if accessed directly
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/ctrls/ctrl.base.php');
5
- require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/ui.php');
6
 
7
  /**
8
  * Controller for Tools
@@ -32,7 +32,7 @@ class DUP_CTRL_UI extends DUP_CTRL_Base
32
  * Duplicator.UI.SaveViewState('dup-pack-archive-panel', 1);
33
  *
34
  * //Call PHP Code
35
- * $view_state = DUP_UI::GetViewStateValue('dup-pack-archive-panel');
36
  * $ui_css_archive = ($view_state == 1) ? 'display:block' : 'display:none';
37
  * </code>
38
  */
@@ -47,7 +47,7 @@ class DUP_CTRL_UI extends DUP_CTRL_Base
47
  $post = stripslashes_deep($_POST);
48
  $key = esc_html($post['key']);
49
  $value = esc_html($post['value']);
50
- $success = DUP_UI::SaveViewState($key, $value);
51
 
52
  $payload = array();
53
  $payload['key'] = $key;
@@ -83,7 +83,7 @@ class DUP_CTRL_UI extends DUP_CTRL_Base
83
  try
84
  {
85
  //CONTROLLER LOGIC
86
- $payload = DUP_UI::GetViewStateArray();
87
 
88
  //RETURN RESULT
89
  $test = (count($payload))
2
  if ( ! defined('DUPLICATOR_VERSION') ) exit; // Exit if accessed directly
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/ctrls/ctrl.base.php');
5
+ require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.viewstate.php');
6
 
7
  /**
8
  * Controller for Tools
32
  * Duplicator.UI.SaveViewState('dup-pack-archive-panel', 1);
33
  *
34
  * //Call PHP Code
35
+ * $view_state = DUP_UI_ViewState::getValue('dup-pack-archive-panel');
36
  * $ui_css_archive = ($view_state == 1) ? 'display:block' : 'display:none';
37
  * </code>
38
  */
47
  $post = stripslashes_deep($_POST);
48
  $key = esc_html($post['key']);
49
  $value = esc_html($post['value']);
50
+ $success = DUP_UI_ViewState::save($key, $value);
51
 
52
  $payload = array();
53
  $payload['key'] = $key;
83
  try
84
  {
85
  //CONTROLLER LOGIC
86
+ $payload = DUP_UI_ViewState::getArray();
87
 
88
  //RETURN RESULT
89
  $test = (count($payload))
debug/main.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- DUP_Util::CheckPermissions('read');
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
5
  require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
1
  <?php
2
+ DUP_Util::hasCapability('read');
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
5
  require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
define.php CHANGED
@@ -2,7 +2,7 @@
2
  //Prevent directly browsing to the file
3
  if (function_exists('plugin_dir_url'))
4
  {
5
- define('DUPLICATOR_VERSION', '1.1.32');
6
  define('DUPLICATOR_HOMEPAGE', 'http://lifeinthegrid.com/labs/duplicator');
7
  define('DUPLICATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
8
  define('DUPLICATOR_SITE_URL', get_site_url());
2
  //Prevent directly browsing to the file
3
  if (function_exists('plugin_dir_url'))
4
  {
5
+ define('DUPLICATOR_VERSION', '1.1.34');
6
  define('DUPLICATOR_HOMEPAGE', 'http://lifeinthegrid.com/labs/duplicator');
7
  define('DUPLICATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
8
  define('DUPLICATOR_SITE_URL', get_site_url());
duplicator.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
- /* ===============================================================================
3
  Plugin Name: Duplicator
4
  Plugin URI: http://www.lifeinthegrid.com/duplicator/
5
  Description: Create and transfer a copy of your WordPress files and database. Duplicate and move a site from one location to another quickly.
6
- Version: 1.1.32
7
  Author: Snap Creek
8
  Author URI: http://www.snapcreek.com/duplicator/
9
  Text Domain: duplicator
@@ -30,25 +30,27 @@ require_once("define.php");
30
  if (is_admin() == true)
31
  {
32
  //Classes
33
- require_once 'classes/logging.php';
34
- require_once 'classes/utility.php';
35
- require_once 'classes/settings.php';
36
- require_once 'classes/server.php';
37
- require_once 'classes/package.php';
38
- require_once 'classes/ui/ui.php';
 
 
39
 
40
  //Controllers
41
  require_once 'ctrls/ctrl.package.php';
42
  require_once 'ctrls/ctrl.tools.php';
43
  require_once 'ctrls/ctrl.ui.php';
44
 
45
- /* =====================================
46
- * ACTIVATE/DEACTIVE/UPDATE HOOKS */
 
47
  register_activation_hook(__FILE__, 'duplicator_activate');
48
  register_deactivation_hook(__FILE__, 'duplicator_deactivate');
49
 
50
  /**
51
- * Activation Hook:
52
  * Hooked into `register_activation_hook`. Routines used to activate the plugin
53
  *
54
  * @access global
@@ -84,12 +86,10 @@ if (is_admin() == true)
84
  update_option('duplicator_version_plugin', DUPLICATOR_VERSION);
85
 
86
  //Setup All Directories
87
- DUP_Util::InitSnapshotDirectory();
88
  }
89
 
90
-
91
  /**
92
- * Activation Hook:
93
  * Hooked into `plugins_loaded`. Routines used to update the plugin
94
  *
95
  * @access global
@@ -103,9 +103,7 @@ if (is_admin() == true)
103
  load_plugin_textdomain( 'duplicator' );
104
  }
105
 
106
-
107
  /**
108
- * Deactivation Hook:
109
  * Hooked into `register_deactivation_hook`. Routines used to deactivae the plugin
110
  * For uninstall see uninstall.php Wordpress by default will call the uninstall.php file
111
  *
@@ -117,14 +115,14 @@ if (is_admin() == true)
117
  //Logic has been added to uninstall.php
118
  }
119
 
120
-
121
- /* =====================================
122
- * ACTION HOOKS */
123
  add_action('plugins_loaded', 'duplicator_update');
124
  add_action('plugins_loaded', 'duplicator_wpfront_integrate');
125
  add_action('admin_init', 'duplicator_init');
126
  add_action('admin_menu', 'duplicator_menu');
127
- add_action('admin_notices', array('DUP_UI', 'ShowReservedFilesNotice'));
128
 
129
  //CTRL ACTIONS
130
  add_action('wp_ajax_duplicator_package_scan', 'duplicator_package_scan');
@@ -133,9 +131,7 @@ if (is_admin() == true)
133
  $GLOBALS['CTRLS_DUP_CTRL_UI'] = new DUP_CTRL_UI();
134
  $GLOBALS['CTRLS_DUP_CTRL_Tools'] = new DUP_CTRL_Tools();
135
 
136
-
137
  /**
138
- * Action Hook:
139
  * User role editor integration
140
  *
141
  * @access global
@@ -148,9 +144,7 @@ if (is_admin() == true)
148
  }
149
  }
150
 
151
-
152
  /**
153
- * Action Hook:
154
  * Hooked into `admin_init`. Init routines for all admin pages
155
  *
156
  * @access global
@@ -169,9 +163,7 @@ if (is_admin() == true)
169
  wp_register_script('dup-jquery-qtip', DUPLICATOR_PLUGIN_URL . 'assets/js/jquery.qtip/jquery.qtip.min.js', array('jquery'), '2.2.1');
170
  }
171
 
172
-
173
  /**
174
- * Menu Redirect:
175
  * Redirects the clicked menu item to the correct location
176
  *
177
  * @access global
@@ -192,9 +184,7 @@ if (is_admin() == true)
192
  }
193
  }
194
 
195
-
196
  /**
197
- * Action Hook:
198
  * Hooked into `admin_menu`. Loads all of the wp left nav admin menus for Duplicator
199
  *
200
  * @access global
@@ -271,9 +261,7 @@ if (is_admin() == true)
271
 
272
  }
273
 
274
-
275
  /**
276
- * Enqueue Scripts:
277
  * Loads all required javascript libs/source for DupPro
278
  *
279
  * @access global
@@ -289,9 +277,7 @@ if (is_admin() == true)
289
 
290
  }
291
 
292
-
293
  /**
294
- * Enqueue CSS Styles:
295
  * Loads all CSS style libs/source for DupPro
296
  *
297
  * @access global
@@ -306,13 +292,13 @@ if (is_admin() == true)
306
  }
307
 
308
 
309
- /* =====================================
310
- * FILTERS */
 
311
  add_filter('plugin_action_links', 'duplicator_manage_link', 10, 2);
312
  add_filter('plugin_row_meta', 'duplicator_meta_links', 10, 2);
313
 
314
  /**
315
- * Plugin MetaData:
316
  * Adds the manage link in the plugins list
317
  *
318
  * @access global
@@ -331,9 +317,7 @@ if (is_admin() == true)
331
  return $links;
332
  }
333
 
334
-
335
  /**
336
- * Plugin MetaData:
337
  * Adds links to the plugins manager page
338
  *
339
  * @access global
1
  <?php
2
+ /** ===============================================================================
3
  Plugin Name: Duplicator
4
  Plugin URI: http://www.lifeinthegrid.com/duplicator/
5
  Description: Create and transfer a copy of your WordPress files and database. Duplicate and move a site from one location to another quickly.
6
+ Version: 1.1.34
7
  Author: Snap Creek
8
  Author URI: http://www.snapcreek.com/duplicator/
9
  Text Domain: duplicator
30
  if (is_admin() == true)
31
  {
32
  //Classes
33
+ require_once 'classes/class.logging.php';
34
+ require_once 'classes/class.settings.php';
35
+ require_once 'classes/utilities/class.util.php';
36
+ require_once 'classes/utilities/class.db.php';
37
+ require_once 'classes/utilities/class.server.php';
38
+ require_once 'classes/ui/class.ui.viewstate.php';
39
+ require_once 'classes/ui/class.ui.notice.php';
40
+ require_once 'classes/package/class.pack.php';
41
 
42
  //Controllers
43
  require_once 'ctrls/ctrl.package.php';
44
  require_once 'ctrls/ctrl.tools.php';
45
  require_once 'ctrls/ctrl.ui.php';
46
 
47
+ /** ========================================================
48
+ * ACTIVATE/DEACTIVE/UPDATE HOOKS
49
+ * ===================================================== */
50
  register_activation_hook(__FILE__, 'duplicator_activate');
51
  register_deactivation_hook(__FILE__, 'duplicator_deactivate');
52
 
53
  /**
 
54
  * Hooked into `register_activation_hook`. Routines used to activate the plugin
55
  *
56
  * @access global
86
  update_option('duplicator_version_plugin', DUPLICATOR_VERSION);
87
 
88
  //Setup All Directories
89
+ DUP_Util::initSnapshotDirectory();
90
  }
91
 
 
92
  /**
 
93
  * Hooked into `plugins_loaded`. Routines used to update the plugin
94
  *
95
  * @access global
103
  load_plugin_textdomain( 'duplicator' );
104
  }
105
 
 
106
  /**
 
107
  * Hooked into `register_deactivation_hook`. Routines used to deactivae the plugin
108
  * For uninstall see uninstall.php Wordpress by default will call the uninstall.php file
109
  *
115
  //Logic has been added to uninstall.php
116
  }
117
 
118
+ /** ========================================================
119
+ * ACTION HOOKS
120
+ * ===================================================== */
121
  add_action('plugins_loaded', 'duplicator_update');
122
  add_action('plugins_loaded', 'duplicator_wpfront_integrate');
123
  add_action('admin_init', 'duplicator_init');
124
  add_action('admin_menu', 'duplicator_menu');
125
+ add_action('admin_notices', array('DUP_UI_Notice', 'showReservedFilesNotice'));
126
 
127
  //CTRL ACTIONS
128
  add_action('wp_ajax_duplicator_package_scan', 'duplicator_package_scan');
131
  $GLOBALS['CTRLS_DUP_CTRL_UI'] = new DUP_CTRL_UI();
132
  $GLOBALS['CTRLS_DUP_CTRL_Tools'] = new DUP_CTRL_Tools();
133
 
 
134
  /**
 
135
  * User role editor integration
136
  *
137
  * @access global
144
  }
145
  }
146
 
 
147
  /**
 
148
  * Hooked into `admin_init`. Init routines for all admin pages
149
  *
150
  * @access global
163
  wp_register_script('dup-jquery-qtip', DUPLICATOR_PLUGIN_URL . 'assets/js/jquery.qtip/jquery.qtip.min.js', array('jquery'), '2.2.1');
164
  }
165
 
 
166
  /**
 
167
  * Redirects the clicked menu item to the correct location
168
  *
169
  * @access global
184
  }
185
  }
186
 
 
187
  /**
 
188
  * Hooked into `admin_menu`. Loads all of the wp left nav admin menus for Duplicator
189
  *
190
  * @access global
261
 
262
  }
263
 
 
264
  /**
 
265
  * Loads all required javascript libs/source for DupPro
266
  *
267
  * @access global
277
 
278
  }
279
 
 
280
  /**
 
281
  * Loads all CSS style libs/source for DupPro
282
  *
283
  * @access global
292
  }
293
 
294
 
295
+ /** ========================================================
296
+ * FILTERS
297
+ * ===================================================== */
298
  add_filter('plugin_action_links', 'duplicator_manage_link', 10, 2);
299
  add_filter('plugin_row_meta', 'duplicator_meta_links', 10, 2);
300
 
301
  /**
 
302
  * Adds the manage link in the plugins list
303
  *
304
  * @access global
317
  return $links;
318
  }
319
 
 
320
  /**
 
321
  * Adds links to the plugins manager page
322
  *
323
  * @access global
installer/build/ajax.step1.php CHANGED
@@ -44,7 +44,7 @@ if (isset($_GET['dbtest']))
44
  {
45
  $html = "";
46
  $baseport = parse_url($_POST['dbhost'], PHP_URL_PORT);
47
- $dbConn = DUPX_Util::db_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], null, $_POST['dbport']);
48
  $dbErr = mysqli_connect_error();
49
 
50
  $dbFound = mysqli_select_db($dbConn, $_POST['dbname']);
@@ -52,14 +52,23 @@ if (isset($_GET['dbtest']))
52
 
53
  $tstSrv = ($dbConn) ? "<div class='dup-pass'>Success</div>" : "<div class='dup-fail'>Fail</div>";
54
  $tstDB = ($dbFound) ? "<div class='dup-pass'>Success</div>" : "<div class='dup-fail'>Fail</div>";
55
-
56
- $dbvar_version = DUPX_Util::mysqldb_version($dbConn);
57
- $dbvar_version = ($dbvar_version == 0) ? 'no connection' : $dbvar_version;
58
- $dbvar_version_fail = version_compare($dbvar_version, $GLOBALS['FW_VERSION_DB']) < 0;
59
- $tstCompat = ($dbvar_version_fail)
60
- ? "<div class='dup-notice'>This Server: [{$dbvar_version}] -- Package Server: [{$GLOBALS['FW_VERSION_DB']}]</div>"
61
- : "<div class='dup-pass'>This Server: [{$dbvar_version}] -- Package Server: [{$GLOBALS['FW_VERSION_DB']}]</div>";
62
-
 
 
 
 
 
 
 
 
 
63
  $html .= <<<DATA
64
  <div class='dup-db-test'>
65
  <small>
@@ -77,8 +86,12 @@ if (isset($_GET['dbtest']))
77
  </tr>
78
  <tr>
79
  <td>Version:</td>
 
 
 
 
80
  <td>{$tstCompat}</td>
81
- </tr>
82
  </table>
83
  DATA;
84
 
@@ -86,7 +99,7 @@ DATA;
86
  //WARNING: DB has tables with create option
87
  if ($_POST['dbaction'] == 'create')
88
  {
89
- $tblcount = DUPX_Util::dbtable_count($dbConn, $_POST['dbname']);
90
  $html .= ($tblcount > 0)
91
  ? "<div class='warn-msg'><b>WARNING:</b> " . sprintf(ERR_DBEMPTY, $_POST['dbname'], $tblcount) . "</div>"
92
  : '';
@@ -102,13 +115,20 @@ DATA;
102
  break;
103
  }
104
  }
 
 
105
  $html .= (! $dbConn && $dbUTF8_tst)
106
  ? "<div class='warn-msg'><b>WARNING:</b> " . ERR_TESTDB_UTF8 . "</div>"
107
  : '';
108
 
109
- //WARNING Version Incompat
110
- $html .= ($dbvar_version_fail)
111
- ? "<div class='warn-msg'><b>NOTICE:</b> " . ERR_TESTDB_VERSION . "</div>"
 
 
 
 
 
112
  : '';
113
 
114
  $html .= "</div>";
@@ -119,60 +139,60 @@ DATA;
119
  //ERROR MESSAGES
120
  //===============================
121
  //ERR_MAKELOG
122
- ($GLOBALS['LOG_FILE_HANDLE'] != false) or DUPX_Log::Error(ERR_MAKELOG);
123
 
124
  //ERR_MYSQLI_SUPPORT
125
- function_exists('mysqli_connect') or DUPX_Log::Error(ERR_MYSQLI_SUPPORT);
126
 
127
  //ERR_DBCONNECT
128
- $dbh = DUPX_Util::db_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], null, $_POST['dbport']);
129
  @mysqli_query($dbh, "SET wait_timeout = {$GLOBALS['DB_MAX_TIME']}");
130
- ($dbh) or DUPX_Log::Error(ERR_DBCONNECT . mysqli_connect_error());
131
  if ($_POST['dbaction'] == 'empty') {
132
- mysqli_select_db($dbh, $_POST['dbname']) or DUPX_Log::Error(sprintf(ERR_DBCREATE, $_POST['dbname']));
133
  }
134
  //ERR_DBEMPTY
135
  if ($_POST['dbaction'] == 'create' ) {
136
- $tblcount = DUPX_Util::dbtable_count($dbh, $_POST['dbname']);
137
  if ($tblcount > 0) {
138
- DUPX_Log::Error(sprintf(ERR_DBEMPTY, $_POST['dbname'], $tblcount));
139
  }
140
  }
141
 
142
  //ERR_ZIPMANUAL
143
  if ($_POST['zip_manual']) {
144
  if (!file_exists("wp-config.php") && !file_exists("database.sql")) {
145
- DUPX_Log::Error(ERR_ZIPMANUAL);
146
  }
147
  } else {
148
  //ERR_CONFIG_FOUND
149
  (!file_exists('wp-config.php'))
150
- or DUPX_Log::Error(ERR_CONFIG_FOUND);
151
  //ERR_ZIPNOTFOUND
152
  (is_readable("{$package_path}"))
153
- or DUPX_Log::Error(ERR_ZIPNOTFOUND);
154
  }
155
 
156
- DUPX_Log::Info("********************************************************************************");
157
- DUPX_Log::Info('DUPLICATOR-LITE INSTALL-LOG');
158
- DUPX_Log::Info('STEP1 START @ ' . @date('h:i:s'));
159
- DUPX_Log::Info('NOTICE: Do NOT post to public sites or forums');
160
- DUPX_Log::Info("********************************************************************************");
161
- DUPX_Log::Info("VERSION:\t{$GLOBALS['FW_DUPLICATOR_VERSION']}");
162
- DUPX_Log::Info("PHP:\t\t" . phpversion() . ' | SAPI: ' . php_sapi_name());
163
- DUPX_Log::Info("PHP MEMORY:\t" . $GLOBALS['PHP_MEMORY_LIMIT'] . ' | SUHOSIN: ' . $GLOBALS['PHP_SUHOSIN_ON'] );
164
- DUPX_Log::Info("SERVER:\t\t{$_SERVER['SERVER_SOFTWARE']}");
165
- DUPX_Log::Info("DOC ROOT:\t{$root_path}");
166
- DUPX_Log::Info("DOC ROOT 755:\t" . var_export($GLOBALS['CHOWN_ROOT_PATH'], true));
167
- DUPX_Log::Info("LOG FILE 644:\t" . var_export($GLOBALS['CHOWN_LOG_PATH'], true));
168
- DUPX_Log::Info("BUILD NAME:\t{$GLOBALS['FW_SECURE_NAME']}");
169
- DUPX_Log::Info("REQUEST URL:\t{$GLOBALS['URL_PATH']}");
170
 
171
  $log = "--------------------------------------\n";
172
  $log .= "POST DATA\n";
173
  $log .= "--------------------------------------\n";
174
  $log .= print_r($POST_LOG, true);
175
- DUPX_Log::Info($log, 2);
176
 
177
 
178
  //====================================================================================================
@@ -184,13 +204,13 @@ $log .= "***********************************************************************
184
  $log .= "NAME:\t{$_POST['package_name']}\n";
185
  $log .= "SIZE:\t" . DUPX_Util::readable_bytesize(@filesize($_POST['package_name'])) . "\n";
186
  $log .= "ZIP:\t{$zip_support} (ZipArchive Support)";
187
- DUPX_Log::Info($log);
188
 
189
  $zip_start = DUPX_Util::get_microtime();
190
 
191
  if ($_POST['zip_manual'])
192
  {
193
- DUPX_Log::Info("\n** PACKAGE EXTRACTION IS IN MANUAL MODE ** \n");
194
  }
195
  else
196
  {
@@ -200,21 +220,21 @@ else
200
  $log .= "To guarantee accuracy the installer and archive should match. For details see the online FAQs.";
201
  $log .= "\nCREATED WITH:\t{$GLOBALS['FW_PACKAGE_NAME']} \nPROCESSED WITH:\t{$_POST['package_name']} \n";
202
  $log .= "--------------------------------------\n";
203
- DUPX_Log::Info($log);
204
  }
205
 
206
  if (! class_exists('ZipArchive')) {
207
- DUPX_Log::Info("ERROR: Stopping install process. Trying to extract without ZipArchive module installed. Please use the 'Manual Package extraction' mode to extract zip file.");
208
- DUPX_Log::Error(ERR_ZIPARCHIVE);
209
  }
210
 
211
  $target = $root_path;
212
  $zip = new ZipArchive();
213
  if ($zip->open($_POST['package_name']) === TRUE)
214
  {
215
- DUPX_Log::Info("\nEXTRACTING");
216
  if (! $zip->extractTo($target)) {
217
- DUPX_Log::Error(ERR_ZIPEXTRACTION);
218
  }
219
  $log = print_r($zip, true);
220
 
@@ -234,9 +254,9 @@ else
234
 
235
  $close_response = $zip->close();
236
  $log .= "COMPLETE: " . var_export($close_response, true);
237
- DUPX_Log::Info($log);
238
  } else {
239
- DUPX_Log::Error(ERR_ZIPOPEN);
240
  }
241
  $zip = null;
242
  }
@@ -245,7 +265,7 @@ else
245
  //CONFIG FILE RESETS
246
  $log = '';
247
  DUPX_WPConfig::UpdateStep1();
248
- DUPX_ServerConfig::Reset();
249
 
250
 
251
  //====================================================================================================
@@ -267,7 +287,7 @@ if ($db_file_size >= $php_mem_range && $php_mem_range != 0)
267
  $msg .= "a memory allocation error when trying to load the database.sql file. It is\n";
268
  $msg .= "recommended to increase the 'memory_limit' setting in the php.ini config file.\n";
269
  $msg .= "see: {$faq_url}#faq-trouble-056-q \n";
270
- DUPX_Log::Info($msg);
271
  }
272
 
273
  @chmod("{$root_path}/database.sql", 0777);
@@ -282,14 +302,14 @@ if ($sql_file === FALSE || strlen($sql_file) < 10)
282
  $msg .= "<i>see: <a href='{$faq_url}#faq-trouble-055-q' target='_blank'>{$faq_url}#faq-trouble-055-q</a></i> <br/>";
283
  $msg .= "2. Validate the database.sql file exists and is in the root of the archive.zip file <br/>";
284
  $msg .= "<i>see: <a href='{$faq_url}#faq-installer-020-q' target='_blank'>{$faq_url}#faq-installer-020-q</a></i> <br/>";
285
- DUPX_Log::Error($msg);
286
  }
287
 
288
  //Removes invalid space characters
289
  //Complex Subject See: http://webcollab.sourceforge.net/unicode.html
290
  if ($_POST['dbnbsp'])
291
  {
292
- DUPX_Log::Info("NOTICE: Ran fix non-breaking space characters\n");
293
  $sql_file = preg_replace('/\xC2\xA0/', ' ', $sql_file);
294
  }
295
 
@@ -307,20 +327,20 @@ if ($sql_file_copy_status === FALSE || filesize($sql_result_file_path) == 0 || !
307
  $msg = "\nWARNING: Unable to properly copy database.sql ({$sql_file_size}) to {$GLOBALS['SQL_FILE_NAME']}. Please check these items:\n";
308
  $msg .= "- Validate permissions and/or group-owner rights on database.sql and directory [{$root_path}] \n";
309
  $msg .= "- see: {$faq_url}#faq-trouble-055-q \n";
310
- DUPX_Log::Info($msg);
311
  }
312
 
313
- DUPX_Log::Info("\nUPDATED FILES:");
314
- DUPX_Log::Info("- SQL FILE: '{$sql_result_file_path}'");
315
- DUPX_Log::Info("- WP-CONFIG: '{$root_path}/wp-config.php' (if present)");
316
- DUPX_Log::Info("\nARCHIVE RUNTIME: " . DUPX_Util::elapsed_time(DUPX_Util::get_microtime(), $zip_start) . "\n");
317
  DUPX_Util::fcgi_flush();
318
 
319
  //=================================
320
  //START DB RUN
321
  @mysqli_query($dbh, "SET wait_timeout = {$GLOBALS['DB_MAX_TIME']}");
322
  @mysqli_query($dbh, "SET max_allowed_packet = {$GLOBALS['DB_MAX_PACKETS']}");
323
- DUPX_Util::mysqldb_set_charset($dbh, $_POST['dbcharset'], $_POST['dbcollate']);
324
 
325
  //Will set mode to null only for this db handle session
326
  //sql_mode can cause db create issues on some systems
@@ -342,32 +362,32 @@ switch ($_POST['dbmysqlmode']) {
342
  }
343
 
344
  //Set defaults in-case the variable could not be read
345
- $dbvar_maxtime = DUPX_Util::mysqldb_variable_value($dbh, 'wait_timeout');
346
- $dbvar_maxpacks = DUPX_Util::mysqldb_variable_value($dbh, 'max_allowed_packet');
347
- $dbvar_sqlmode = DUPX_Util::mysqldb_variable_value($dbh, 'sql_mode');
348
  $dbvar_maxtime = is_null($dbvar_maxtime) ? 300 : $dbvar_maxtime;
349
  $dbvar_maxpacks = is_null($dbvar_maxpacks) ? 1048576 : $dbvar_maxpacks;
350
  $dbvar_sqlmode = empty($dbvar_sqlmode) ? 'NOT_SET' : $dbvar_sqlmode;
351
- $dbvar_version = DUPX_Util::mysqldb_version($dbh);
352
  $sql_file_size1 = DUPX_Util::readable_bytesize(@filesize("database.sql"));
353
  $sql_file_size2 = DUPX_Util::readable_bytesize(@filesize("{$GLOBALS['SQL_FILE_NAME']}"));
354
 
355
 
356
- DUPX_Log::Info("{$GLOBALS['SEPERATOR1']}");
357
- DUPX_Log::Info('DATABASE-ROUTINES');
358
- DUPX_Log::Info("{$GLOBALS['SEPERATOR1']}");
359
- DUPX_Log::Info("--------------------------------------");
360
- DUPX_Log::Info("SERVER ENVIRONMENT");
361
- DUPX_Log::Info("--------------------------------------");
362
- DUPX_Log::Info("MYSQL VERSION:\tThis Server: {$dbvar_version} -- Build Server: {$GLOBALS['FW_VERSION_DB']}");
363
- DUPX_Log::Info("FILE SIZE:\tdatabase.sql ({$sql_file_size1}) - installer-data.sql ({$sql_file_size2})");
364
- DUPX_Log::Info("TIMEOUT:\t{$dbvar_maxtime}");
365
- DUPX_Log::Info("MAXPACK:\t{$dbvar_maxpacks}");
366
- DUPX_Log::Info("SQLMODE:\t{$dbvar_sqlmode}");
367
 
368
  if ($qry_session_custom == false)
369
  {
370
- DUPX_Log::Info("\n{$log}\n");
371
  }
372
 
373
  //CREATE DB
@@ -375,7 +395,7 @@ switch ($_POST['dbaction']) {
375
  case "create":
376
  mysqli_query($dbh, "CREATE DATABASE IF NOT EXISTS `{$_POST['dbname']}`");
377
  mysqli_select_db($dbh, $_POST['dbname'])
378
- or DUPX_Log::Error(sprintf(ERR_DBCONNECT_CREATE, $_POST['dbname']));
379
  break;
380
  case "empty":
381
  //DROP DB TABLES
@@ -390,7 +410,7 @@ switch ($_POST['dbaction']) {
390
  foreach ($found_tables as $table_name) {
391
  $sql = "DROP TABLE `{$_POST['dbname']}`.`{$table_name}`";
392
  if (!$result = mysqli_query($dbh, $sql)) {
393
- DUPX_Log::Error(sprintf(ERR_DBTRYCLEAN, $_POST['dbname']));
394
  }
395
  }
396
  }
@@ -401,9 +421,9 @@ switch ($_POST['dbaction']) {
401
 
402
 
403
  //WRITE DATA
404
- DUPX_Log::Info("--------------------------------------");
405
- DUPX_Log::Info("DATABASE RESULTS");
406
- DUPX_Log::Info("--------------------------------------");
407
  $profile_start = DUPX_Util::get_microtime();
408
  $fcgi_buffer_pool = 5000;
409
  $fcgi_buffer_count = 0;
@@ -416,7 +436,7 @@ while ($counter < $sql_result_file_length) {
416
 
417
  $query_strlen = strlen(trim($sql_result_file_data[$counter]));
418
  if ($dbvar_maxpacks < $query_strlen) {
419
- DUPX_Log::Info("**ERROR** Query size limit [length={$query_strlen}] [sql=" . substr($sql_result_file_data[$counter], 75) . "...]");
420
  $dbquery_errs++;
421
  } elseif ($query_strlen > 0) {
422
  @mysqli_free_result(@mysqli_query($dbh, ($sql_result_file_data[$counter])));
@@ -426,12 +446,12 @@ while ($counter < $sql_result_file_length) {
426
 
427
  if (!mysqli_ping($dbh)) {
428
  mysqli_close($dbh);
429
- $dbh = DUPX_Util::db_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname'], $_POST['dbport'] );
430
  // Reset session setup
431
  @mysqli_query($dbh, "SET wait_timeout = {$GLOBALS['DB_MAX_TIME']}");
432
- DUPX_Util::mysqldb_set_charset($dbh, $_POST['dbcharset'], $_POST['dbcollate']);
433
  }
434
- DUPX_Log::Info("**ERROR** database error write '{$err}' - [sql=" . substr($sql_result_file_data[$counter], 0, 75) . "...]");
435
  $dbquery_errs++;
436
 
437
  //Buffer data to browser to keep connection open
@@ -448,23 +468,23 @@ while ($counter < $sql_result_file_length) {
448
  @mysqli_commit($dbh);
449
  @mysqli_autocommit($dbh, true);
450
 
451
- DUPX_Log::Info("ERRORS FOUND:\t{$dbquery_errs}");
452
- DUPX_Log::Info("DROP TABLE:\t{$drop_log}");
453
- DUPX_Log::Info("QUERIES RAN:\t{$dbquery_rows}\n");
454
 
455
  $dbtable_count = 0;
456
  if ($result = mysqli_query($dbh, "SHOW TABLES")) {
457
  while ($row = mysqli_fetch_array($result, MYSQLI_NUM)) {
458
- $table_rows = DUPX_Util::table_row_count($dbh, $row[0]);
459
  $dbtable_rows += $table_rows;
460
- DUPX_Log::Info("{$row[0]}: ({$table_rows})");
461
  $dbtable_count++;
462
  }
463
  @mysqli_free_result($result);
464
  }
465
 
466
  if ($dbtable_count == 0) {
467
- DUPX_Log::Error("No tables where created during step 1 of the install. Please review the <a href='installer-log.txt' target='_blank'>installer-log.txt</a> file for
468
  ERROR messages. You may have to manually run the installer-data.sql with a tool like phpmyadmin to validate the data input. If you have enabled compatibility mode
469
  during the package creation process then the database server version your using may not be compatible with this script.\n");
470
  }
@@ -478,7 +498,7 @@ $dbdelete_count1 = @mysqli_affected_rows($dbh) or 0;
478
  @mysqli_query($dbh, "DELETE FROM `{$GLOBALS['FW_TABLEPREFIX']}options` WHERE `option_name` LIKE ('_transient%') OR `option_name` LIKE ('_site_transient%')");
479
  $dbdelete_count2 = @mysqli_affected_rows($dbh) or 0;
480
  $dbdelete_count = (abs($dbdelete_count1) + abs($dbdelete_count2));
481
- DUPX_Log::Info("Removed '{$dbdelete_count}' cache/transient rows");
482
  //Reset Duplicator Options
483
  foreach ($GLOBALS['FW_OPTS_DELETE'] as $value) {
484
  mysqli_query($dbh, "DELETE FROM `{$GLOBALS['FW_TABLEPREFIX']}options` WHERE `option_name` = '{$value}'");
@@ -487,14 +507,14 @@ foreach ($GLOBALS['FW_OPTS_DELETE'] as $value) {
487
  @mysqli_close($dbh);
488
 
489
  $profile_end = DUPX_Util::get_microtime();
490
- DUPX_Log::Info("\nSECTION RUNTIME: " . DUPX_Util::elapsed_time($profile_end, $profile_start));
491
 
492
  //FINAL RESULTS
493
  $ajax1_end = DUPX_Util::get_microtime();
494
  $ajax1_sum = DUPX_Util::elapsed_time($ajax1_end, $ajax1_start);
495
- DUPX_Log::Info("\n{$GLOBALS['SEPERATOR1']}");
496
- DUPX_Log::Info('STEP1 COMPLETE @ ' . @date('h:i:s') . " - TOTAL RUNTIME: {$ajax1_sum}");
497
- DUPX_Log::Info("{$GLOBALS['SEPERATOR1']}");
498
 
499
  $JSON['pass'] = 1;
500
  $JSON['table_count'] = $dbtable_count;
44
  {
45
  $html = "";
46
  $baseport = parse_url($_POST['dbhost'], PHP_URL_PORT);
47
+ $dbConn = DUPX_DB::connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], null, $_POST['dbport']);
48
  $dbErr = mysqli_connect_error();
49
 
50
  $dbFound = mysqli_select_db($dbConn, $_POST['dbname']);
52
 
53
  $tstSrv = ($dbConn) ? "<div class='dup-pass'>Success</div>" : "<div class='dup-fail'>Fail</div>";
54
  $tstDB = ($dbFound) ? "<div class='dup-pass'>Success</div>" : "<div class='dup-fail'>Fail</div>";
55
+
56
+ $dbversion_info = DUPX_DB::getServerInfo($dbConn);
57
+ $dbversion_info = empty($dbversion_info) ? 'no connection' : $dbversion_info;
58
+ $dbversion_info_fail = version_compare(DUPX_DB::getVersion($dbConn), '5.5.3') < 0;
59
+
60
+ $dbversion_compat = DUPX_DB::getVersion($dbConn);
61
+ $dbversion_compat = empty($dbversion_compat) ? 'no connection' : $dbversion_compat;
62
+ $dbversion_compat_fail = version_compare($dbversion_compat, $GLOBALS['FW_VERSION_DB']) < 0;
63
+
64
+ $tstInfo = ($dbversion_info_fail)
65
+ ? "<div class='dup-notice'>{$dbversion_info}</div>"
66
+ : "<div class='dup-pass'>{$dbversion_info}</div>";
67
+
68
+ $tstCompat = ($dbversion_compat_fail)
69
+ ? "<div class='dup-notice'>This Server: [{$dbversion_compat}] -- Package Server: [{$GLOBALS['FW_VERSION_DB']}]</div>"
70
+ : "<div class='dup-pass'>This Server: [{$dbversion_compat}] -- Package Server: [{$GLOBALS['FW_VERSION_DB']}]</div>";
71
+
72
  $html .= <<<DATA
73
  <div class='dup-db-test'>
74
  <small>
86
  </tr>
87
  <tr>
88
  <td>Version:</td>
89
+ <td>{$tstInfo}</td>
90
+ </tr>
91
+ <tr>
92
+ <td>Compatibility:</td>
93
  <td>{$tstCompat}</td>
94
+ </tr>
95
  </table>
96
  DATA;
97
 
99
  //WARNING: DB has tables with create option
100
  if ($_POST['dbaction'] == 'create')
101
  {
102
+ $tblcount = DUPX_DB::countTables($dbConn, $_POST['dbname']);
103
  $html .= ($tblcount > 0)
104
  ? "<div class='warn-msg'><b>WARNING:</b> " . sprintf(ERR_DBEMPTY, $_POST['dbname'], $tblcount) . "</div>"
105
  : '';
115
  break;
116
  }
117
  }
118
+
119
+ //WARNING: UTF8 Data in Connection String
120
  $html .= (! $dbConn && $dbUTF8_tst)
121
  ? "<div class='warn-msg'><b>WARNING:</b> " . ERR_TESTDB_UTF8 . "</div>"
122
  : '';
123
 
124
+ //NOTICE: Version Too Low
125
+ $html .= ($dbversion_info_fail)
126
+ ? "<div class='warn-msg'><b>NOTICE:</b> " . ERR_TESTDB_VERSION_INFO . "</div>"
127
+ : '';
128
+
129
+ //NOTICE: Version Incompatibility
130
+ $html .= ($dbversion_compat_fail)
131
+ ? "<div class='warn-msg'><b>NOTICE:</b> " . ERR_TESTDB_VERSION_COMPAT . "</div>"
132
  : '';
133
 
134
  $html .= "</div>";
139
  //ERROR MESSAGES
140
  //===============================
141
  //ERR_MAKELOG
142
+ ($GLOBALS['LOG_FILE_HANDLE'] != false) or DUPX_Log::error(ERR_MAKELOG);
143
 
144
  //ERR_MYSQLI_SUPPORT
145
+ function_exists('mysqli_connect') or DUPX_Log::error(ERR_MYSQLI_SUPPORT);
146
 
147
  //ERR_DBCONNECT
148
+ $dbh = DUPX_DB::connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], null, $_POST['dbport']);
149
  @mysqli_query($dbh, "SET wait_timeout = {$GLOBALS['DB_MAX_TIME']}");
150
+ ($dbh) or DUPX_Log::error(ERR_DBCONNECT . mysqli_connect_error());
151
  if ($_POST['dbaction'] == 'empty') {
152
+ mysqli_select_db($dbh, $_POST['dbname']) or DUPX_Log::error(sprintf(ERR_DBCREATE, $_POST['dbname']));
153
  }
154
  //ERR_DBEMPTY
155
  if ($_POST['dbaction'] == 'create' ) {
156
+ $tblcount = DUPX_DB::countTables($dbh, $_POST['dbname']);
157
  if ($tblcount > 0) {
158
+ DUPX_Log::error(sprintf(ERR_DBEMPTY, $_POST['dbname'], $tblcount));
159
  }
160
  }
161
 
162
  //ERR_ZIPMANUAL
163
  if ($_POST['zip_manual']) {
164
  if (!file_exists("wp-config.php") && !file_exists("database.sql")) {
165
+ DUPX_Log::error(ERR_ZIPMANUAL);
166
  }
167
  } else {
168
  //ERR_CONFIG_FOUND
169
  (!file_exists('wp-config.php'))
170
+ or DUPX_Log::error(ERR_CONFIG_FOUND);
171
  //ERR_ZIPNOTFOUND
172
  (is_readable("{$package_path}"))
173
+ or DUPX_Log::error(ERR_ZIPNOTFOUND);
174
  }
175
 
176
+ DUPX_Log::info("********************************************************************************");
177
+ DUPX_Log::info('DUPLICATOR-LITE INSTALL-LOG');
178
+ DUPX_Log::info('STEP1 START @ ' . @date('h:i:s'));
179
+ DUPX_Log::info('NOTICE: Do NOT post to public sites or forums');
180
+ DUPX_Log::info("********************************************************************************");
181
+ DUPX_Log::info("VERSION:\t{$GLOBALS['FW_DUPLICATOR_VERSION']}");
182
+ DUPX_Log::info("PHP:\t\t" . phpversion() . ' | SAPI: ' . php_sapi_name());
183
+ DUPX_Log::info("PHP MEMORY:\t" . $GLOBALS['PHP_MEMORY_LIMIT'] . ' | SUHOSIN: ' . $GLOBALS['PHP_SUHOSIN_ON'] );
184
+ DUPX_Log::info("SERVER:\t\t{$_SERVER['SERVER_SOFTWARE']}");
185
+ DUPX_Log::info("DOC ROOT:\t{$root_path}");
186
+ DUPX_Log::info("DOC ROOT 755:\t" . var_export($GLOBALS['CHOWN_ROOT_PATH'], true));
187
+ DUPX_Log::info("LOG FILE 644:\t" . var_export($GLOBALS['CHOWN_LOG_PATH'], true));
188
+ DUPX_Log::info("BUILD NAME:\t{$GLOBALS['FW_SECURE_NAME']}");
189
+ DUPX_Log::info("REQUEST URL:\t{$GLOBALS['URL_PATH']}");
190
 
191
  $log = "--------------------------------------\n";
192
  $log .= "POST DATA\n";
193
  $log .= "--------------------------------------\n";
194
  $log .= print_r($POST_LOG, true);
195
+ DUPX_Log::info($log, 2);
196
 
197
 
198
  //====================================================================================================
204
  $log .= "NAME:\t{$_POST['package_name']}\n";
205
  $log .= "SIZE:\t" . DUPX_Util::readable_bytesize(@filesize($_POST['package_name'])) . "\n";
206
  $log .= "ZIP:\t{$zip_support} (ZipArchive Support)";
207
+ DUPX_Log::info($log);
208
 
209
  $zip_start = DUPX_Util::get_microtime();
210
 
211
  if ($_POST['zip_manual'])
212
  {
213
+ DUPX_Log::info("\n** PACKAGE EXTRACTION IS IN MANUAL MODE ** \n");
214
  }
215
  else
216
  {
220
  $log .= "To guarantee accuracy the installer and archive should match. For details see the online FAQs.";
221
  $log .= "\nCREATED WITH:\t{$GLOBALS['FW_PACKAGE_NAME']} \nPROCESSED WITH:\t{$_POST['package_name']} \n";
222
  $log .= "--------------------------------------\n";
223
+ DUPX_Log::info($log);
224
  }
225
 
226
  if (! class_exists('ZipArchive')) {
227
+ DUPX_Log::info("ERROR: Stopping install process. Trying to extract without ZipArchive module installed. Please use the 'Manual Package extraction' mode to extract zip file.");
228
+ DUPX_Log::error(ERR_ZIPARCHIVE);
229
  }
230
 
231
  $target = $root_path;
232
  $zip = new ZipArchive();
233
  if ($zip->open($_POST['package_name']) === TRUE)
234
  {
235
+ DUPX_Log::info("\nEXTRACTING");
236
  if (! $zip->extractTo($target)) {
237
+ DUPX_Log::error(ERR_ZIPEXTRACTION);
238
  }
239
  $log = print_r($zip, true);
240
 
254
 
255
  $close_response = $zip->close();
256
  $log .= "COMPLETE: " . var_export($close_response, true);
257
+ DUPX_Log::info($log);
258
  } else {
259
+ DUPX_Log::error(ERR_ZIPOPEN);
260
  }
261
  $zip = null;
262
  }
265
  //CONFIG FILE RESETS
266
  $log = '';
267
  DUPX_WPConfig::UpdateStep1();
268
+ DUPX_ServerConfig::reset();
269
 
270
 
271
  //====================================================================================================
287
  $msg .= "a memory allocation error when trying to load the database.sql file. It is\n";
288
  $msg .= "recommended to increase the 'memory_limit' setting in the php.ini config file.\n";
289
  $msg .= "see: {$faq_url}#faq-trouble-056-q \n";
290
+ DUPX_Log::info($msg);
291
  }
292
 
293
  @chmod("{$root_path}/database.sql", 0777);
302
  $msg .= "<i>see: <a href='{$faq_url}#faq-trouble-055-q' target='_blank'>{$faq_url}#faq-trouble-055-q</a></i> <br/>";
303
  $msg .= "2. Validate the database.sql file exists and is in the root of the archive.zip file <br/>";
304
  $msg .= "<i>see: <a href='{$faq_url}#faq-installer-020-q' target='_blank'>{$faq_url}#faq-installer-020-q</a></i> <br/>";
305
+ DUPX_Log::error($msg);
306
  }
307
 
308
  //Removes invalid space characters
309
  //Complex Subject See: http://webcollab.sourceforge.net/unicode.html
310
  if ($_POST['dbnbsp'])
311
  {
312
+ DUPX_Log::info("NOTICE: Ran fix non-breaking space characters\n");
313
  $sql_file = preg_replace('/\xC2\xA0/', ' ', $sql_file);
314
  }
315
 
327
  $msg = "\nWARNING: Unable to properly copy database.sql ({$sql_file_size}) to {$GLOBALS['SQL_FILE_NAME']}. Please check these items:\n";
328
  $msg .= "- Validate permissions and/or group-owner rights on database.sql and directory [{$root_path}] \n";
329
  $msg .= "- see: {$faq_url}#faq-trouble-055-q \n";
330
+ DUPX_Log::info($msg);
331
  }
332
 
333
+ DUPX_Log::info("\nUPDATED FILES:");
334
+ DUPX_Log::info("- SQL FILE: '{$sql_result_file_path}'");
335
+ DUPX_Log::info("- WP-CONFIG: '{$root_path}/wp-config.php' (if present)");
336
+ DUPX_Log::info("\nARCHIVE RUNTIME: " . DUPX_Util::elapsed_time(DUPX_Util::get_microtime(), $zip_start) . "\n");
337
  DUPX_Util::fcgi_flush();
338
 
339
  //=================================
340
  //START DB RUN
341
  @mysqli_query($dbh, "SET wait_timeout = {$GLOBALS['DB_MAX_TIME']}");
342
  @mysqli_query($dbh, "SET max_allowed_packet = {$GLOBALS['DB_MAX_PACKETS']}");
343
+ DUPX_DB::setCharset($dbh, $_POST['dbcharset'], $_POST['dbcollate']);
344
 
345
  //Will set mode to null only for this db handle session
346
  //sql_mode can cause db create issues on some systems
362
  }
363
 
364
  //Set defaults in-case the variable could not be read
365
+ $dbvar_maxtime = DUPX_DB::getVariable($dbh, 'wait_timeout');
366
+ $dbvar_maxpacks = DUPX_DB::getVariable($dbh, 'max_allowed_packet');
367
+ $dbvar_sqlmode = DUPX_DB::getVariable($dbh, 'sql_mode');
368
  $dbvar_maxtime = is_null($dbvar_maxtime) ? 300 : $dbvar_maxtime;
369
  $dbvar_maxpacks = is_null($dbvar_maxpacks) ? 1048576 : $dbvar_maxpacks;
370
  $dbvar_sqlmode = empty($dbvar_sqlmode) ? 'NOT_SET' : $dbvar_sqlmode;
371
+ $dbvar_version = DUPX_DB::getVersion($dbh);
372
  $sql_file_size1 = DUPX_Util::readable_bytesize(@filesize("database.sql"));
373
  $sql_file_size2 = DUPX_Util::readable_bytesize(@filesize("{$GLOBALS['SQL_FILE_NAME']}"));
374
 
375
 
376
+ DUPX_Log::info("{$GLOBALS['SEPERATOR1']}");
377
+ DUPX_Log::info('DATABASE-ROUTINES');
378
+ DUPX_Log::info("{$GLOBALS['SEPERATOR1']}");
379
+ DUPX_Log::info("--------------------------------------");
380
+ DUPX_Log::info("SERVER ENVIRONMENT");
381
+ DUPX_Log::info("--------------------------------------");
382
+ DUPX_Log::info("MYSQL VERSION:\tThis Server: {$dbvar_version} -- Build Server: {$GLOBALS['FW_VERSION_DB']}");
383
+ DUPX_Log::info("FILE SIZE:\tdatabase.sql ({$sql_file_size1}) - installer-data.sql ({$sql_file_size2})");
384
+ DUPX_Log::info("TIMEOUT:\t{$dbvar_maxtime}");
385
+ DUPX_Log::info("MAXPACK:\t{$dbvar_maxpacks}");
386
+ DUPX_Log::info("SQLMODE:\t{$dbvar_sqlmode}");
387
 
388
  if ($qry_session_custom == false)
389
  {
390
+ DUPX_Log::info("\n{$log}\n");
391
  }
392
 
393
  //CREATE DB
395
  case "create":
396
  mysqli_query($dbh, "CREATE DATABASE IF NOT EXISTS `{$_POST['dbname']}`");
397
  mysqli_select_db($dbh, $_POST['dbname'])
398
+ or DUPX_Log::error(sprintf(ERR_DBCONNECT_CREATE, $_POST['dbname']));
399
  break;
400
  case "empty":
401
  //DROP DB TABLES
410
  foreach ($found_tables as $table_name) {
411
  $sql = "DROP TABLE `{$_POST['dbname']}`.`{$table_name}`";
412
  if (!$result = mysqli_query($dbh, $sql)) {
413
+ DUPX_Log::error(sprintf(ERR_DBTRYCLEAN, $_POST['dbname']));
414
  }
415
  }
416
  }
421
 
422
 
423
  //WRITE DATA
424
+ DUPX_Log::info("--------------------------------------");
425
+ DUPX_Log::info("DATABASE RESULTS");
426
+ DUPX_Log::info("--------------------------------------");
427
  $profile_start = DUPX_Util::get_microtime();
428
  $fcgi_buffer_pool = 5000;
429
  $fcgi_buffer_count = 0;
436
 
437
  $query_strlen = strlen(trim($sql_result_file_data[$counter]));
438
  if ($dbvar_maxpacks < $query_strlen) {
439
+ DUPX_Log::info("**ERROR** Query size limit [length={$query_strlen}] [sql=" . substr($sql_result_file_data[$counter], 75) . "...]");
440
  $dbquery_errs++;
441
  } elseif ($query_strlen > 0) {
442
  @mysqli_free_result(@mysqli_query($dbh, ($sql_result_file_data[$counter])));
446
 
447
  if (!mysqli_ping($dbh)) {
448
  mysqli_close($dbh);
449
+ $dbh = DUPX_DB::connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname'], $_POST['dbport'] );
450
  // Reset session setup
451
  @mysqli_query($dbh, "SET wait_timeout = {$GLOBALS['DB_MAX_TIME']}");
452
+ DUPX_DB::setCharset($dbh, $_POST['dbcharset'], $_POST['dbcollate']);
453
  }
454
+ DUPX_Log::info("**ERROR** database error write '{$err}' - [sql=" . substr($sql_result_file_data[$counter], 0, 75) . "...]");
455
  $dbquery_errs++;
456
 
457
  //Buffer data to browser to keep connection open
468
  @mysqli_commit($dbh);
469
  @mysqli_autocommit($dbh, true);
470
 
471
+ DUPX_Log::info("ERRORS FOUND:\t{$dbquery_errs}");
472
+ DUPX_Log::info("DROP TABLE:\t{$drop_log}");
473
+ DUPX_Log::info("QUERIES RAN:\t{$dbquery_rows}\n");
474
 
475
  $dbtable_count = 0;
476
  if ($result = mysqli_query($dbh, "SHOW TABLES")) {
477
  while ($row = mysqli_fetch_array($result, MYSQLI_NUM)) {
478
+ $table_rows = DUPX_DB::countTableRows($dbh, $row[0]);
479
  $dbtable_rows += $table_rows;
480
+ DUPX_Log::info("{$row[0]}: ({$table_rows})");
481
  $dbtable_count++;
482
  }
483
  @mysqli_free_result($result);
484
  }
485
 
486
  if ($dbtable_count == 0) {
487
+ DUPX_Log::error("No tables where created during step 1 of the install. Please review the <a href='installer-log.txt' target='_blank'>installer-log.txt</a> file for
488
  ERROR messages. You may have to manually run the installer-data.sql with a tool like phpmyadmin to validate the data input. If you have enabled compatibility mode
489
  during the package creation process then the database server version your using may not be compatible with this script.\n");
490
  }
498
  @mysqli_query($dbh, "DELETE FROM `{$GLOBALS['FW_TABLEPREFIX']}options` WHERE `option_name` LIKE ('_transient%') OR `option_name` LIKE ('_site_transient%')");
499
  $dbdelete_count2 = @mysqli_affected_rows($dbh) or 0;
500
  $dbdelete_count = (abs($dbdelete_count1) + abs($dbdelete_count2));
501
+ DUPX_Log::info("Removed '{$dbdelete_count}' cache/transient rows");
502
  //Reset Duplicator Options
503
  foreach ($GLOBALS['FW_OPTS_DELETE'] as $value) {
504
  mysqli_query($dbh, "DELETE FROM `{$GLOBALS['FW_TABLEPREFIX']}options` WHERE `option_name` = '{$value}'");
507
  @mysqli_close($dbh);
508
 
509
  $profile_end = DUPX_Util::get_microtime();
510
+ DUPX_Log::info("\nSECTION RUNTIME: " . DUPX_Util::elapsed_time($profile_end, $profile_start));
511
 
512
  //FINAL RESULTS
513
  $ajax1_end = DUPX_Util::get_microtime();
514
  $ajax1_sum = DUPX_Util::elapsed_time($ajax1_end, $ajax1_start);
515
+ DUPX_Log::info("\n{$GLOBALS['SEPERATOR1']}");
516
+ DUPX_Log::info('STEP1 COMPLETE @ ' . @date('h:i:s') . " - TOTAL RUNTIME: {$ajax1_sum}");
517
+ DUPX_Log::info("{$GLOBALS['SEPERATOR1']}");
518
 
519
  $JSON['pass'] = 1;
520
  $JSON['table_count'] = $dbtable_count;
installer/build/ajax.step2.php CHANGED
@@ -19,10 +19,10 @@ error_reporting(E_ERROR);
19
  $ajax2_start = DUPX_Util::get_microtime();
20
 
21
  //MYSQL CONNECTION
22
- $dbh = DUPX_Util::db_connect($_POST['dbhost'], $_POST['dbuser'], html_entity_decode($_POST['dbpass']), $_POST['dbname'], $_POST['dbport']);
23
  $charset_server = @mysqli_character_set_name($dbh);
24
  @mysqli_query($dbh, "SET wait_timeout = {$GLOBALS['DB_MAX_TIME']}");
25
- DUPX_Util::mysqldb_set_charset($dbh, $_POST['dbcharset'], $_POST['dbcollate']);
26
 
27
  //POST PARAMS
28
  $_POST['blogname'] = mysqli_real_escape_string($dbh, $_POST['blogname']);
@@ -55,7 +55,7 @@ NOTICE: Do not post to public sites or forums
55
  CHARSET SERVER:\t{$charset_server}
56
  CHARSET CLIENT:\t {$charset_client} \n
57
  LOG;
58
- DUPX_Log::Info($log);
59
 
60
  //Detailed logging
61
  $log = "--------------------------------------\n";
@@ -74,7 +74,7 @@ $log .= "--------------------------------------\n";
74
  $log .= (isset($_POST['plugins']) && count($_POST['plugins'] > 0))
75
  ? print_r($_POST['plugins'], true)
76
  : 'No plugins selected for activation';
77
- DUPX_Log::Info($log, 2);
78
 
79
  //UPDATE SETTINGS
80
  $serial_plugin_list = (isset($_POST['plugins']) && count($_POST['plugins'] > 0)) ? @serialize($_POST['plugins']) : '';
@@ -87,7 +87,7 @@ $log .= "[*] scan every column\n";
87
  $log .= "[~] scan only text columns\n";
88
  $log .= "[^] no searchable columns\n";
89
  $log .= "--------------------------------------";
90
- DUPX_Log::Info($log);
91
 
92
  $url_old_json = str_replace('"', "", json_encode($_POST['url_old']));
93
  $url_new_json = str_replace('"', "", json_encode($_POST['url_new']));
@@ -123,14 +123,14 @@ $JSON['step2'] = $report;
123
  $JSON['step2']['warn_all'] = 0;
124
  $JSON['step2']['warnlist'] = array();
125
 
126
- DUPX_UpdateEngine::log_stats($report);
127
- DUPX_UpdateEngine::log_errors($report);
128
 
129
  //Reset the postguid data
130
  if ($_POST['postguid']) {
131
  mysqli_query($dbh, "UPDATE `{$GLOBALS['FW_TABLEPREFIX']}posts` SET guid = REPLACE(guid, '{$_POST['url_new']}', '{$_POST['url_old']}')");
132
  $update_guid = @mysqli_affected_rows($dbh) or 0;
133
- DUPX_Log::Info("Reverted '{$update_guid}' post guid columns back to '{$_POST['url_old']}'");
134
  }
135
 
136
  /* FINAL UPDATES: Must happen after the global replace to prevent double pathing
@@ -142,9 +142,9 @@ mysqli_query($dbh, "UPDATE `{$GLOBALS['FW_TABLEPREFIX']}options` SET option_valu
142
  //====================================================================================================
143
  //FINAL CLEANUP
144
  //====================================================================================================
145
- DUPX_Log::Info("\n********************************************************************************");
146
- DUPX_Log::Info('START FINAL CLEANUP: ' . @date('h:i:s'));
147
- DUPX_Log::Info("********************************************************************************");
148
 
149
  /*CREATE NEW USER LOGIC */
150
  if (strlen($_POST['wp_username']) >= 4 && strlen($_POST['wp_password']) >= 6) {
@@ -176,17 +176,17 @@ if (strlen($_POST['wp_username']) >= 4 && strlen($_POST['wp_password']) >= 6) {
176
  @mysqli_query($dbh, "INSERT INTO `{$GLOBALS['FW_TABLEPREFIX']}usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES ('{$newuser_insert_id}', 'nickname', '{$_POST['wp_username']}')");
177
 
178
  if ($newuser_test1 && $newuser_test2 && $newuser_test3) {
179
- DUPX_Log::Info("NEW WP-ADMIN USER: New username '{$_POST['wp_username']}' was created successfully \n ");
180
  } else {
181
  $newuser_warnmsg = "NEW WP-ADMIN USER: Failed to create the user '{$_POST['wp_username']}' \n ";
182
  $JSON['step2']['warnlist'][] = $newuser_warnmsg;
183
- DUPX_Log::Info($newuser_warnmsg);
184
  }
185
  }
186
  else {
187
  $newuser_warnmsg = "NEW WP-ADMIN USER: Username '{$_POST['wp_username']}' already exists in the database. Unable to create new account \n";
188
  $JSON['step2']['warnlist'][] = $newuser_warnmsg;
189
- DUPX_Log::Info($newuser_warnmsg);
190
  }
191
  }
192
 
@@ -205,15 +205,15 @@ $mu_oldUrlPath = (empty($mu_oldUrlPath) || ($mu_oldUrlPath == '/')) ? '/' : rtr
205
 
206
  $mu_updates = @mysqli_query($dbh, "UPDATE `{$GLOBALS['FW_TABLEPREFIX']}blogs` SET domain = '{$mu_newDomainHost}' WHERE domain = '{$mu_oldDomainHost}'");
207
  if ($mu_updates) {
208
- DUPX_Log::Info("Update MU table blogs: domain {$mu_newDomainHost} ");
209
  } else {
210
- DUPX_Log::Info("UPDATE `{$GLOBALS['FW_TABLEPREFIX']}blogs` SET domain = '{$mu_newDomainHost}' WHERE domain = '{$mu_oldDomainHost}'");
211
  }
212
 
213
 
214
  /* ==============================
215
  * UPDATE WP-CONFIG FILE */
216
- $config_file = DUPX_WPConfig::UpdateStep2();
217
 
218
  //Create snapshots directory in order to
219
  //compensate for permissions on some servers
@@ -226,9 +226,9 @@ fclose($fp);
226
 
227
  /* ==============================
228
  NOTICE TESTS */
229
- DUPX_Log::Info("\n--------------------------------------");
230
- DUPX_Log::Info("NOTICES");
231
- DUPX_Log::Info("--------------------------------------");
232
  $config_vars = array('WP_CONTENT_DIR', 'WP_CONTENT_URL', 'WPCACHEHOME', 'COOKIE_DOMAIN', 'WP_SITEURL', 'WP_HOME', 'WP_TEMP_DIR');
233
  $config_items = DUPX_Util::search_list_values($config_vars, $config_file);
234
 
@@ -237,7 +237,7 @@ if (! empty($config_items)) {
237
  $msg = 'NOTICE: The wp-config.php has one or more of the following values set [' . implode(", ", $config_items) . ']. ';
238
  $msg .= 'Please validate these values are correct by opening the file and checking the values. To validate the meaning and proper usage of each parameter used the codex link above.';
239
  $JSON['step2']['warnlist'][] = $msg;
240
- DUPX_Log::Info($msg);
241
  }
242
 
243
  //Database:
@@ -248,14 +248,14 @@ if ($result) {
248
  $msg = "NOTICE: The media settings values in the table '{$GLOBALS['FW_TABLEPREFIX']}options' has at least one the following values ['upload_url_path','upload_path'] set. ";
249
  $msg .= "Please validate these settings by logging into your wp-admin and going to Settings->Media area and validating the 'Uploading Files' section";
250
  $JSON['step2']['warnlist'][] = $msg;
251
- DUPX_Log::Info($msg);
252
  break;
253
  }
254
  }
255
  }
256
 
257
  if (empty($JSON['step2']['warnlist'])) {
258
- DUPX_Log::Info("No Notices Found\n");
259
  }
260
 
261
  $JSON['step2']['warn_all'] = empty($JSON['step2']['warnlist']) ? 0 : count($JSON['step2']['warnlist']);
@@ -264,13 +264,13 @@ mysqli_close($dbh);
264
  @unlink('database.sql');
265
 
266
  //CONFIG Setup
267
- DUPX_ServerConfig::Setup();
268
 
269
  $ajax2_end = DUPX_Util::get_microtime();
270
  $ajax2_sum = DUPX_Util::elapsed_time($ajax2_end, $ajax2_start);
271
- DUPX_Log::Info("********************************************************************************");
272
- DUPX_Log::Info('STEP 2 COMPLETE @ ' . @date('h:i:s') . " - TOTAL RUNTIME: {$ajax2_sum}");
273
- DUPX_Log::Info("********************************************************************************");
274
 
275
  $JSON['step2']['pass'] = 1;
276
  error_reporting($ajax2_error_level);
19
  $ajax2_start = DUPX_Util::get_microtime();
20
 
21
  //MYSQL CONNECTION
22
+ $dbh = DUPX_DB::connect($_POST['dbhost'], $_POST['dbuser'], html_entity_decode($_POST['dbpass']), $_POST['dbname'], $_POST['dbport']);
23
  $charset_server = @mysqli_character_set_name($dbh);
24
  @mysqli_query($dbh, "SET wait_timeout = {$GLOBALS['DB_MAX_TIME']}");
25
+ DUPX_DB::setCharset($dbh, $_POST['dbcharset'], $_POST['dbcollate']);
26
 
27
  //POST PARAMS
28
  $_POST['blogname'] = mysqli_real_escape_string($dbh, $_POST['blogname']);
55
  CHARSET SERVER:\t{$charset_server}
56
  CHARSET CLIENT:\t {$charset_client} \n
57
  LOG;
58
+ DUPX_Log::info($log);
59
 
60
  //Detailed logging
61
  $log = "--------------------------------------\n";
74
  $log .= (isset($_POST['plugins']) && count($_POST['plugins'] > 0))
75
  ? print_r($_POST['plugins'], true)
76
  : 'No plugins selected for activation';
77
+ DUPX_Log::info($log, 2);
78
 
79
  //UPDATE SETTINGS
80
  $serial_plugin_list = (isset($_POST['plugins']) && count($_POST['plugins'] > 0)) ? @serialize($_POST['plugins']) : '';
87
  $log .= "[~] scan only text columns\n";
88
  $log .= "[^] no searchable columns\n";
89
  $log .= "--------------------------------------";
90
+ DUPX_Log::info($log);
91
 
92
  $url_old_json = str_replace('"', "", json_encode($_POST['url_old']));
93
  $url_new_json = str_replace('"', "", json_encode($_POST['url_new']));
123
  $JSON['step2']['warn_all'] = 0;
124
  $JSON['step2']['warnlist'] = array();
125
 
126
+ DUPX_UpdateEngine::logStats($report);
127
+ DUPX_UpdateEngine::logErrors($report);
128
 
129
  //Reset the postguid data
130
  if ($_POST['postguid']) {
131
  mysqli_query($dbh, "UPDATE `{$GLOBALS['FW_TABLEPREFIX']}posts` SET guid = REPLACE(guid, '{$_POST['url_new']}', '{$_POST['url_old']}')");
132
  $update_guid = @mysqli_affected_rows($dbh) or 0;
133
+ DUPX_Log::info("Reverted '{$update_guid}' post guid columns back to '{$_POST['url_old']}'");
134
  }
135
 
136
  /* FINAL UPDATES: Must happen after the global replace to prevent double pathing
142
  //====================================================================================================
143
  //FINAL CLEANUP
144
  //====================================================================================================
145
+ DUPX_Log::info("\n********************************************************************************");
146
+ DUPX_Log::info('START FINAL CLEANUP: ' . @date('h:i:s'));
147
+ DUPX_Log::info("********************************************************************************");
148
 
149
  /*CREATE NEW USER LOGIC */
150
  if (strlen($_POST['wp_username']) >= 4 && strlen($_POST['wp_password']) >= 6) {
176
  @mysqli_query($dbh, "INSERT INTO `{$GLOBALS['FW_TABLEPREFIX']}usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES ('{$newuser_insert_id}', 'nickname', '{$_POST['wp_username']}')");
177
 
178
  if ($newuser_test1 && $newuser_test2 && $newuser_test3) {
179
+ DUPX_Log::info("NEW WP-ADMIN USER: New username '{$_POST['wp_username']}' was created successfully \n ");
180
  } else {
181
  $newuser_warnmsg = "NEW WP-ADMIN USER: Failed to create the user '{$_POST['wp_username']}' \n ";
182
  $JSON['step2']['warnlist'][] = $newuser_warnmsg;
183
+ DUPX_Log::info($newuser_warnmsg);
184
  }
185
  }
186
  else {
187
  $newuser_warnmsg = "NEW WP-ADMIN USER: Username '{$_POST['wp_username']}' already exists in the database. Unable to create new account \n";
188
  $JSON['step2']['warnlist'][] = $newuser_warnmsg;
189
+ DUPX_Log::info($newuser_warnmsg);
190
  }
191
  }
192
 
205
 
206
  $mu_updates = @mysqli_query($dbh, "UPDATE `{$GLOBALS['FW_TABLEPREFIX']}blogs` SET domain = '{$mu_newDomainHost}' WHERE domain = '{$mu_oldDomainHost}'");
207
  if ($mu_updates) {
208
+ DUPX_Log::info("Update MU table blogs: domain {$mu_newDomainHost} ");
209
  } else {
210
+ DUPX_Log::info("UPDATE `{$GLOBALS['FW_TABLEPREFIX']}blogs` SET domain = '{$mu_newDomainHost}' WHERE domain = '{$mu_oldDomainHost}'");
211
  }
212
 
213
 
214
  /* ==============================
215
  * UPDATE WP-CONFIG FILE */
216
+ $config_file = DUPX_WPConfig::updateStep2();
217
 
218
  //Create snapshots directory in order to
219
  //compensate for permissions on some servers
226
 
227
  /* ==============================
228
  NOTICE TESTS */
229
+ DUPX_Log::info("\n--------------------------------------");
230
+ DUPX_Log::info("NOTICES");
231
+ DUPX_Log::info("--------------------------------------");
232
  $config_vars = array('WP_CONTENT_DIR', 'WP_CONTENT_URL', 'WPCACHEHOME', 'COOKIE_DOMAIN', 'WP_SITEURL', 'WP_HOME', 'WP_TEMP_DIR');
233
  $config_items = DUPX_Util::search_list_values($config_vars, $config_file);
234
 
237
  $msg = 'NOTICE: The wp-config.php has one or more of the following values set [' . implode(", ", $config_items) . ']. ';
238
  $msg .= 'Please validate these values are correct by opening the file and checking the values. To validate the meaning and proper usage of each parameter used the codex link above.';
239
  $JSON['step2']['warnlist'][] = $msg;
240
+ DUPX_Log::info($msg);
241
  }
242
 
243
  //Database:
248
  $msg = "NOTICE: The media settings values in the table '{$GLOBALS['FW_TABLEPREFIX']}options' has at least one the following values ['upload_url_path','upload_path'] set. ";
249
  $msg .= "Please validate these settings by logging into your wp-admin and going to Settings->Media area and validating the 'Uploading Files' section";
250
  $JSON['step2']['warnlist'][] = $msg;
251
+ DUPX_Log::info($msg);
252
  break;
253
  }
254
  }
255
  }
256
 
257
  if (empty($JSON['step2']['warnlist'])) {
258
+ DUPX_Log::info("No Notices Found\n");
259
  }
260
 
261
  $JSON['step2']['warn_all'] = empty($JSON['step2']['warnlist']) ? 0 : count($JSON['step2']['warnlist']);
264
  @unlink('database.sql');
265
 
266
  //CONFIG Setup
267
+ DUPX_ServerConfig::setup();
268
 
269
  $ajax2_end = DUPX_Util::get_microtime();
270
  $ajax2_sum = DUPX_Util::elapsed_time($ajax2_end, $ajax2_start);
271
+ DUPX_Log::info("********************************************************************************");
272
+ DUPX_Log::info('STEP 2 COMPLETE @ ' . @date('h:i:s') . " - TOTAL RUNTIME: {$ajax2_sum}");
273
+ DUPX_Log::info("********************************************************************************");
274
 
275
  $JSON['step2']['pass'] = 1;
276
  error_reporting($ajax2_error_level);
installer/build/assets/inc.css.php CHANGED
@@ -86,7 +86,7 @@
86
  table.dup-db-test-dtls {text-align: left; margin: auto}
87
  table.dup-db-test-dtls td:first-child {font-weight: bold}
88
  div#dbconn-test-msg {font-size:12px}
89
- div#s1-dbconn-status {border:1px solid silver; border-radius:3px; background-color:#f9f9f9; padding:2px 5px; margin-top:10px; height:165px; overflow-y: scroll}
90
  div#s1-dbconn-status div.warn-msg {text-align: left; padding:5px; margin:10px 0 10px 0}
91
  div#s1-dbconn-status div.warn-msg b{color:maroon}
92
 
86
  table.dup-db-test-dtls {text-align: left; margin: auto}
87
  table.dup-db-test-dtls td:first-child {font-weight: bold}
88
  div#dbconn-test-msg {font-size:12px}
89
+ div#s1-dbconn-status {border:1px solid silver; border-radius:3px; background-color:#f9f9f9; padding:2px 5px; margin-top:10px; height:175px; overflow-y: scroll}
90
  div#s1-dbconn-status div.warn-msg {text-align: left; padding:5px; margin:10px 0 10px 0}
91
  div#s1-dbconn-status div.warn-msg b{color:maroon}
92
 
installer/build/classes/class.conf.srv.php DELETED
@@ -1,77 +0,0 @@
1
- <?php
2
- // Exit if accessed directly
3
- if (! defined('DUPLICATOR_INIT')) {
4
- $_baseURL = "http://" . strlen($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'];
5
- header("HTTP/1.1 301 Moved Permanently");
6
- header("Location: $_baseURL");
7
- exit;
8
- }
9
-
10
- /** * *****************************************************
11
- * Class used to update and edit web server configuration files */
12
- class DUPX_ServerConfig {
13
-
14
- /**
15
- * Clear .htaccess and web.config files and backup
16
- */
17
- static public function Reset() {
18
-
19
- DUPX_Log::Info("\nWEB SERVER CONFIGURATION FILE RESET:");
20
- $timeStamp = date("ymdHis");
21
-
22
- //Apache
23
- @copy('.htaccess', ".htaccess.{$timeStamp}.orig");
24
- @unlink('.htaccess');
25
-
26
- //IIS
27
- @copy('web.config', "web.config.{$timeStamp}.orig");
28
- @unlink('web.config');
29
-
30
- //.user.ini - For WordFence
31
- @copy('.user.ini', ".user.ini.{$timeStamp}.orig");
32
- @unlink('.user.ini');
33
-
34
- DUPX_Log::Info("- Backup of .htaccess/web.config made to *.{$timeStamp}.orig");
35
- DUPX_Log::Info("- Reset of .htaccess/web.config files");
36
- $tmp_htaccess = '# RESET FOR DUPLICATOR INSTALLER USEAGE';
37
- file_put_contents('.htaccess', $tmp_htaccess);
38
- @chmod('.htaccess', 0644);
39
- }
40
-
41
- /** METHOD: ResetHTACCESS
42
- * Resets the .htaccess file
43
- */
44
- static public function Setup() {
45
-
46
- if (! isset($_POST['url_new'])) {
47
- return;
48
- }
49
-
50
- DUPX_Log::Info("\nWEB SERVER CONFIGURATION FILE BASIC SETUP:");
51
- $currdata = parse_url($_POST['url_old']);
52
- $newdata = parse_url($_POST['url_new']);
53
- $currpath = DUPX_Util::add_slash(isset($currdata['path']) ? $currdata['path'] : "");
54
- $newpath = DUPX_Util::add_slash(isset($newdata['path']) ? $newdata['path'] : "");
55
-
56
- $tmp_htaccess = <<<HTACCESS
57
- # BEGIN WordPress
58
- <IfModule mod_rewrite.c>
59
- RewriteEngine On
60
- RewriteBase {$newpath}
61
- RewriteRule ^index\.php$ - [L]
62
- RewriteCond %{REQUEST_FILENAME} !-f
63
- RewriteCond %{REQUEST_FILENAME} !-d
64
- RewriteRule . {$newpath}index.php [L]
65
- </IfModule>
66
- # END WordPress
67
- HTACCESS;
68
-
69
- file_put_contents('.htaccess', $tmp_htaccess);
70
- @chmod('.htaccess', 0644);
71
- DUPX_Log::Info("created basic .htaccess file. If using IIS web.config this process will need to be done manually.");
72
-
73
- }
74
-
75
-
76
- }
77
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
installer/build/classes/class.conf.wp.php DELETED
@@ -1,113 +0,0 @@
1
- <?php
2
- // Exit if accessed directly
3
- if (!defined('DUPLICATOR_INIT')) {
4
- $_baseURL = "http://" . strlen($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'];
5
- header("HTTP/1.1 301 Moved Permanently");
6
- header("Location: {$_baseURL}");
7
- exit;
8
- }
9
-
10
- /**
11
- * Class used to update and edit and update the wp-config.php */
12
- class DUPX_WPConfig
13
- {
14
- /**
15
- * Updates the web server config files in Step 1 */
16
- public static function UpdateStep1()
17
- {
18
- if (! file_exists('wp-config.php'))
19
- return;
20
-
21
- $root_path = DUPX_Util::set_safe_path($GLOBALS['CURRENT_ROOT_PATH']);
22
- $wpconfig = @file_get_contents('wp-config.php', true);
23
-
24
- $patterns = array(
25
- "/'DB_NAME',\s*'.*?'/",
26
- "/'DB_USER',\s*'.*?'/",
27
- "/'DB_PASSWORD',\s*'.*?'/",
28
- "/'DB_HOST',\s*'.*?'/");
29
-
30
- $db_host = ($_POST['dbport'] == 3306) ? $_POST['dbhost'] : "{$_POST['dbhost']}:{$_POST['dbport']}";
31
-
32
- $replace = array(
33
- "'DB_NAME', " . '\'' . $_POST['dbname'] . '\'',
34
- "'DB_USER', " . '\'' . $_POST['dbuser'] . '\'',
35
- "'DB_PASSWORD', " . '\'' . DUPX_Util::preg_replacement_quote($_POST['dbpass']) . '\'',
36
- "'DB_HOST', " . '\'' . $db_host . '\'');
37
-
38
- //SSL CHECKS
39
- if ($_POST['ssl_admin']) {
40
- if (! strstr($wpconfig, 'FORCE_SSL_ADMIN')) {
41
- $wpconfig = $wpconfig . PHP_EOL . "define('FORCE_SSL_ADMIN', true);";
42
- }
43
- } else {
44
- array_push($patterns, "/'FORCE_SSL_ADMIN',\s*true/");
45
- array_push($replace, "'FORCE_SSL_ADMIN', false");
46
- }
47
-
48
- if ($_POST['ssl_login']) {
49
- if (! strstr($wpconfig, 'FORCE_SSL_LOGIN')) {
50
- $wpconfig = $wpconfig . PHP_EOL . "define('FORCE_SSL_LOGIN', true);";
51
- }
52
- } else {
53
- array_push($patterns, "/'FORCE_SSL_LOGIN',\s*true/");
54
- array_push($replace, "'FORCE_SSL_LOGIN', false");
55
- }
56
-
57
- //CACHE CHECKS
58
- if ($_POST['cache_wp']) {
59
- if (! strstr($wpconfig, 'WP_CACHE')) {
60
- $wpconfig = $wpconfig . PHP_EOL . "define('WP_CACHE', true);";
61
- }
62
- } else {
63
- array_push($patterns, "/'WP_CACHE',\s*true/");
64
- array_push($replace, "'WP_CACHE', false");
65
- }
66
- if (! $_POST['cache_path']) {
67
- array_push($patterns, "/'WPCACHEHOME',\s*'.*?'/");
68
- array_push($replace, "'WPCACHEHOME', ''");
69
- }
70
-
71
- if (! is_writable("{$root_path}/wp-config.php") )
72
- {
73
- if (file_exists("{$root_path}/wp-config.php"))
74
- {
75
- chmod("{$root_path}/wp-config.php", 0644)
76
- ? DUPX_Log::Info('File Permission Update: wp-config.php set to 0644')
77
- : DUPX_Log::Info('WARNING: Unable to update file permissions and write to wp-config.php. Please visit the online FAQ for setting file permissions and work with your hosting provider or server administrator to enable this installer.php script to write to the wp-config.php file.');
78
- } else {
79
- DUPX_Log::Info('WARNING: Unable to locate wp-config.php file. Be sure the file is present in your archive.');
80
- }
81
- }
82
-
83
- $wpconfig = preg_replace($patterns, $replace, $wpconfig);
84
- file_put_contents('wp-config.php', $wpconfig);
85
- $wpconfig = null;
86
- }
87
-
88
- /**
89
- * Updates the web server config files in Step 2 */
90
- public static function UpdateStep2()
91
- {
92
- $config_file = '';
93
- if (! file_exists('wp-config.php')) {
94
- return $config_file;
95
- }
96
-
97
- $patterns = array("/('|\")WP_HOME.*?\)\s*;/",
98
- "/('|\")WP_SITEURL.*?\)\s*;/",
99
- "/('|\")DOMAIN_CURRENT_SITE.*?\)\s*;/",
100
- "/('|\")PATH_CURRENT_SITE.*?\)\s*;/");
101
- $replace = array("'WP_HOME', '{$_POST['url_new']}');",
102
- "'WP_SITEURL', '{$_POST['url_new']}');",
103
- "'DOMAIN_CURRENT_SITE', '{$mu_newDomainHost}');",
104
- "'PATH_CURRENT_SITE', '{$mu_newUrlPath}');");
105
-
106
- $config_file = file_get_contents('wp-config.php', true);
107
- $config_file = preg_replace($patterns, $replace, $config_file);
108
- file_put_contents('wp-config.php', $config_file);
109
-
110
- return $config_file;
111
- }
112
- }
113
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
installer/build/classes/class.engine.php ADDED
@@ -0,0 +1,441 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if (!defined('DUPLICATOR_INIT')) {
4
+ $_baseURL = "http://".strlen($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'];
5
+ header("HTTP/1.1 301 Moved Permanently");
6
+ header("Location: {$_baseURL}");
7
+ exit;
8
+ }
9
+
10
+ /**
11
+ * Walks every table in db that then walks every row and column replacing searches with replaces
12
+ * large tables are split into 50k row blocks to save on memory.
13
+ *
14
+ * Standard: PSR-2
15
+ * @link http://www.php-fig.org/psr/psr-2 Full Documentation
16
+ *
17
+ * @package SC\DUPX\UpdateEngine
18
+ *
19
+ */
20
+ class DUPX_UpdateEngine
21
+ {
22
+
23
+ /**
24
+ * Used to report on all log errors into the installer-txt.log
25
+ *
26
+ * @param string $report The report error array of all error types
27
+ *
28
+ * @return string Writes the results of the update engine tables to the log
29
+ */
30
+ public static function logErrors($report)
31
+ {
32
+ if (!empty($report['errsql'])) {
33
+ DUPX_Log::info("====================================");
34
+ DUPX_Log::info("DATA-REPLACE ERRORS (MySQL)");
35
+ foreach ($report['errsql'] as $error) {
36
+ DUPX_Log::info($error);
37
+ }
38
+ DUPX_Log::info("");
39
+ }
40
+ if (!empty($report['errser'])) {
41
+ DUPX_Log::info("====================================");
42
+ DUPX_Log::info("DATA-REPLACE ERRORS (Serialization):");
43
+ foreach ($report['errser'] as $error) {
44
+ DUPX_Log::info($error);
45
+ }
46
+ DUPX_Log::info("");
47
+ }
48
+ if (!empty($report['errkey'])) {
49
+ DUPX_Log::info("====================================");
50
+ DUPX_Log::info("DATA-REPLACE ERRORS (Key):");
51
+ DUPX_Log::info('Use SQL: SELECT @row := @row + 1 as row, t.* FROM some_table t, (SELECT @row := 0) r');
52
+ foreach ($report['errkey'] as $error) {
53
+ DUPX_Log::info($error);
54
+ }
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Used to report on all log stats into the installer-txt.log
60
+ *
61
+ * @param string $report The report stats array of all error types
62
+ *
63
+ * @return string Writes the results of the update engine tables to the log
64
+ */
65
+ public static function logStats($report)
66
+ {
67
+ if (!empty($report) && is_array($report)) {
68
+ $stats = "--------------------------------------\n";
69
+ $srchnum = 0;
70
+ foreach ($GLOBALS['REPLACE_LIST'] as $item) {
71
+ $srchnum++;
72
+ $stats .= sprintf("Search{$srchnum}:\t'%s' \nChange{$srchnum}:\t'%s' \n", $item['search'], $item['replace']);
73
+ }
74
+ $stats .= sprintf("SCANNED:\tTables:%d \t|\t Rows:%d \t|\t Cells:%d \n", $report['scan_tables'], $report['scan_rows'], $report['scan_cells']);
75
+ $stats .= sprintf("UPDATED:\tTables:%d \t|\t Rows:%d \t|\t Cells:%d \n", $report['updt_tables'], $report['updt_rows'], $report['updt_cells']);
76
+ $stats .= sprintf("ERRORS:\t\t%d \nRUNTIME:\t%f sec", $report['err_all'], $report['time']);
77
+ DUPX_Log::info($stats);
78
+ }
79
+ }
80
+
81
+
82
+ /**
83
+ * Returns only the text type columns of a table ignoring all numeric types
84
+ *
85
+ * @param obj $dbh A valid database link handle
86
+ * @param string $table A valid table name
87
+ *
88
+ * @return array All the column names of a table
89
+ */
90
+ public static function getTextColumns($dbh, $table)
91
+ {
92
+ $type_where = "type NOT LIKE 'tinyint%' AND ";
93
+ $type_where .= "type NOT LIKE 'smallint%' AND ";
94
+ $type_where .= "type NOT LIKE 'mediumint%' AND ";
95
+ $type_where .= "type NOT LIKE 'int%' AND ";
96
+ $type_where .= "type NOT LIKE 'bigint%' AND ";
97
+ $type_where .= "type NOT LIKE 'float%' AND ";
98
+ $type_where .= "type NOT LIKE 'double%' AND ";
99
+ $type_where .= "type NOT LIKE 'decimal%' AND ";
100
+ $type_where .= "type NOT LIKE 'numeric%' AND ";
101
+ $type_where .= "type NOT LIKE 'date%' AND ";
102
+ $type_where .= "type NOT LIKE 'time%' AND ";
103
+ $type_where .= "type NOT LIKE 'year%' ";
104
+
105
+ $result = mysqli_query($dbh, "SHOW COLUMNS FROM `{$table}` WHERE {$type_where}");
106
+ if (!$result) {
107
+ return null;
108
+ }
109
+ $fields = array();
110
+ if (mysqli_num_rows($result) > 0) {
111
+ while ($row = mysqli_fetch_assoc($result)) {
112
+ $fields[] = $row['Field'];
113
+ }
114
+ }
115
+
116
+ //Return Primary which is needed for index lookup
117
+ //$result = mysqli_query($dbh, "SHOW INDEX FROM `{$table}` WHERE KEY_NAME LIKE '%PRIMARY%'"); 1.1.15 updated
118
+ $result = mysqli_query($dbh, "SHOW INDEX FROM `{$table}`");
119
+ if (mysqli_num_rows($result) > 0) {
120
+ while ($row = mysqli_fetch_assoc($result)) {
121
+ $fields[] = $row['Column_name'];
122
+ }
123
+ }
124
+
125
+ return (count($fields) > 0) ? $fields : null;
126
+ }
127
+
128
+ /**
129
+ * Begins the processing for replace logic
130
+ *
131
+ * @param mysql $dbh The db connection object
132
+ * @param array $list Key value pair of 'search' and 'replace' arrays
133
+ * @param array $tables The tables we want to look at
134
+ * @param array $fullsearch Search every column reguardless of its data type
135
+ *
136
+ * @return array Collection of information gathered during the run.
137
+ */
138
+ public static function load($dbh, $list = array(), $tables = array(), $fullsearch = false)
139
+ {
140
+ $report = array(
141
+ 'scan_tables' => 0,
142
+ 'scan_rows' => 0,
143
+ 'scan_cells' => 0,
144
+ 'updt_tables' => 0,
145
+ 'updt_rows' => 0,
146
+ 'updt_cells' => 0,
147
+ 'errsql' => array(),
148
+ 'errser' => array(),
149
+ 'errkey' => array(),
150
+ 'errsql_sum' => 0,
151
+ 'errser_sum' => 0,
152
+ 'errkey_sum' => 0,
153
+ 'time' => '',
154
+ 'err_all' => 0
155
+ );
156
+
157
+ $walk_function = create_function('&$str', '$str = "`$str`";');
158
+
159
+ $profile_start = DUPX_Util::get_microtime();
160
+ if (is_array($tables) && !empty($tables)) {
161
+
162
+ foreach ($tables as $table) {
163
+ $report['scan_tables'] ++;
164
+ $columns = array();
165
+
166
+ // Get a list of columns in this table
167
+ $fields = mysqli_query($dbh, 'DESCRIBE '.$table);
168
+ while ($column = mysqli_fetch_array($fields)) {
169
+ $columns[$column['Field']] = $column['Key'] == 'PRI' ? true : false;
170
+ }
171
+
172
+ // Count the number of rows we have in the table if large we'll split into blocks
173
+ $row_count = mysqli_query($dbh, "SELECT COUNT(*) FROM `{$table}`");
174
+ $rows_result = mysqli_fetch_array($row_count);
175
+ @mysqli_free_result($row_count);
176
+ $row_count = $rows_result[0];
177
+ if ($row_count == 0) {
178
+ DUPX_Log::info("{$table}^ ({$row_count})");
179
+ continue;
180
+ }
181
+
182
+ $page_size = 25000;
183
+ $offset = ($page_size + 1);
184
+ $pages = ceil($row_count / $page_size);
185
+
186
+ // Grab the columns of the table. Only grab text based columns because
187
+ // they are the only data types that should allow any type of search/replace logic
188
+ $colList = '*';
189
+ $colMsg = '*';
190
+ if (!$fullsearch) {
191
+ $colList = self::getTextColumns($dbh, $table);
192
+ if ($colList != null && is_array($colList)) {
193
+ array_walk($colList, $walk_function);
194
+ $colList = implode(',', $colList);
195
+ }
196
+ $colMsg = (empty($colList)) ? '*' : '~';
197
+ }
198
+
199
+ if (empty($colList)) {
200
+ DUPX_Log::info("{$table}^ ({$row_count})");
201
+ continue;
202
+ } else {
203
+ DUPX_Log::info("{$table}{$colMsg} ({$row_count})");
204
+ }
205
+
206
+ //Paged Records
207
+ for ($page = 0; $page < $pages; $page++) {
208
+ $current_row = 0;
209
+ $start = $page * $page_size;
210
+ $end = $start + $page_size;
211
+ $sql = sprintf("SELECT {$colList} FROM `%s` LIMIT %d, %d", $table, $start, $offset);
212
+ $data = mysqli_query($dbh, $sql);
213
+
214
+ if (!$data) $report['errsql'][] = mysqli_error($dbh);
215
+
216
+ $scan_count = ($row_count < $end) ? $row_count : $end;
217
+ DUPX_Log::info("\tScan => {$start} of {$scan_count}", 2);
218
+
219
+ //Loops every row
220
+ while ($row = mysqli_fetch_array($data)) {
221
+ $report['scan_rows'] ++;
222
+ $current_row++;
223
+ $upd_col = array();
224
+ $upd_sql = array();
225
+ $where_sql = array();
226
+ $upd = false;
227
+ $serial_err = 0;
228
+
229
+ //Loops every cell
230
+ foreach ($columns as $column => $primary_key) {
231
+ $report['scan_cells'] ++;
232
+ $edited_data = $data_to_fix = $row[$column];
233
+ $base64coverted = false;
234
+ $txt_found = false;
235
+
236
+ //Only replacing string values
237
+ if (!empty($row[$column]) && !is_numeric($row[$column])) {
238
+ //Base 64 detection
239
+ if (base64_decode($row[$column], true)) {
240
+ $decoded = base64_decode($row[$column], true);
241
+ if (self::isSerialized($decoded)) {
242
+ $edited_data = $decoded;
243
+ $base64coverted = true;
244
+ }
245
+ }
246
+
247
+ //Skip table cell if match not found
248
+ foreach ($list as $item) {
249
+ if (strpos($edited_data, $item['search']) !== false) {
250
+ $txt_found = true;
251
+ break;
252
+ }
253
+ }
254
+ if (!$txt_found) {
255
+ continue;
256
+ }
257
+
258
+ //Replace logic - level 1: simple check on any string or serlized strings
259
+ foreach ($list as $item) {
260
+ $edited_data = self::recursiveUnserializeReplace($item['search'], $item['replace'], $edited_data);
261
+ }
262
+
263
+ //Replace logic - level 2: repair serilized strings that have become broken
264
+ $serial_check = self::fixSerialString($edited_data);
265
+ if ($serial_check['fixed']) {
266
+ $edited_data = $serial_check['data'];
267
+ } elseif ($serial_check['tried'] && !$serial_check['fixed']) {
268
+ $serial_err++;
269
+ }
270
+ }
271
+
272
+ //Change was made
273
+ if ($edited_data != $data_to_fix || $serial_err > 0) {
274
+ $report['updt_cells'] ++;
275
+ //Base 64 encode
276
+ if ($base64coverted) {
277
+ $edited_data = base64_encode($edited_data);
278
+ }
279
+ $upd_col[] = $column;
280
+ $upd_sql[] = $column.' = "'.mysqli_real_escape_string($dbh, $edited_data).'"';
281
+ $upd = true;
282
+ }
283
+
284
+ if ($primary_key) {
285
+ $where_sql[] = $column.' = "'.mysqli_real_escape_string($dbh, $data_to_fix).'"';
286
+ }
287
+ }
288
+
289
+ //PERFORM ROW UPDATE
290
+ if ($upd && !empty($where_sql)) {
291
+ $sql = "UPDATE `{$table}` SET ".implode(', ', $upd_sql).' WHERE '.implode(' AND ', array_filter($where_sql));
292
+ $result = mysqli_query($dbh, $sql) or $report['errsql'][] = mysqli_error($dbh);
293
+ //DEBUG ONLY:
294
+ DUPX_Log::info("\t{$sql}\n", 3);
295
+ if ($result) {
296
+ if ($serial_err > 0) {
297
+ $report['errser'][] = "SELECT ".implode(', ', $upd_col)." FROM `{$table}` WHERE ".implode(' AND ', array_filter($where_sql)).';';
298
+ }
299
+ $report['updt_rows'] ++;
300
+ }
301
+ } elseif ($upd) {
302
+ $report['errkey'][] = sprintf("Row [%s] on Table [%s] requires a manual update.", $current_row, $table);
303
+ }
304
+ }
305
+ DUPX_Util::fcgi_flush();
306
+ @mysqli_free_result($data);
307
+ }
308
+
309
+ if ($upd) {
310
+ $report['updt_tables'] ++;
311
+ }
312
+ }
313
+ }
314
+ $profile_end = DUPX_Util::get_microtime();
315
+ $report['time'] = DUPX_Util::elapsed_time($profile_end, $profile_start);
316
+ $report['errsql_sum'] = empty($report['errsql']) ? 0 : count($report['errsql']);
317
+ $report['errser_sum'] = empty($report['errser']) ? 0 : count($report['errser']);
318
+ $report['errkey_sum'] = empty($report['errkey']) ? 0 : count($report['errkey']);
319
+ $report['err_all'] = $report['errsql_sum'] + $report['errser_sum'] + $report['errkey_sum'];
320
+ return $report;
321
+ }
322
+
323
+ /**
324
+ * Take a serialised array and unserialise it replacing elements and
325
+ * unserialising any subordinate arrays and performing the replace.
326
+ *
327
+ * @param string $from String we're looking to replace.
328
+ * @param string $to What we want it to be replaced with
329
+ * @param array $data Used to pass any subordinate arrays back to in.
330
+ * @param bool $serialised Does the array passed via $data need serialising.
331
+ *
332
+ * @return array The original array with all elements replaced as needed.
333
+ */
334
+ public static function recursiveUnserializeReplace($from = '', $to = '', $data = '', $serialised = false)
335
+ {
336
+ // some unseriliased data cannot be re-serialised eg. SimpleXMLElements
337
+ try {
338
+ if (is_string($data) && ($unserialized = @unserialize($data)) !== false) {
339
+ $data = self::recursiveUnserializeReplace($from, $to, $unserialized, true);
340
+ } elseif (is_array($data)) {
341
+ $_tmp = array();
342
+ foreach ($data as $key => $value) {
343
+ $_tmp[$key] = self::recursiveUnserializeReplace($from, $to, $value, false);
344
+ }
345
+ $data = $_tmp;
346
+ unset($_tmp);
347
+
348
+ /* CJL
349
+ Check for an update to the key of an array e.g. [http://localhost/projects/wpplugins/] => 1.41
350
+ This could have unintended consequences would need to enable with full-search needs more testing
351
+ if (array_key_exists($from, $data))
352
+ {
353
+ $data[$to] = $data[$from];
354
+ unset($data[$from]);
355
+ } */
356
+ } elseif (is_object($data)) {
357
+ /* RSR Old logic that didn't work with Beaver Builder - they didn't want to create a brand new
358
+ object instead reused the existing one...
359
+ $dataClass = get_class($data);
360
+ $_tmp = new $dataClass();
361
+ foreach ($data as $key => $value) {
362
+ $_tmp->$key = self::recursiveUnserializeReplace($from, $to, $value, false);
363
+ }
364
+ $data = $_tmp;
365
+ unset($_tmp); */
366
+
367
+ // RSR NEW LOGIC
368
+ $_tmp = $data;
369
+ $props = get_object_vars($data);
370
+ foreach ($props as $key => $value) {
371
+ $_tmp->$key = self::recursiveUnserializeReplace($from, $to, $value, false);
372
+ }
373
+ $data = $_tmp;
374
+ unset($_tmp);
375
+ } else {
376
+ if (is_string($data)) {
377
+ $data = str_replace($from, $to, $data);
378
+ }
379
+ }
380
+
381
+ if ($serialised) return serialize($data);
382
+ } catch (Exception $error) {
383
+ DUPX_Log::info("\nRECURSIVE UNSERIALIZE ERROR: With string\n".$error, 2);
384
+ }
385
+ return $data;
386
+ }
387
+
388
+ /**
389
+ * Test if a string in properly serialized
390
+ *
391
+ * @param string $data Any string type
392
+ *
393
+ * @return bool Is the string a serialized string
394
+ */
395
+ public static function isSerialized($data)
396
+ {
397
+ $test = @unserialize(($data));
398
+ return ($test !== false || $test === 'b:0;') ? true : false;
399
+ }
400
+
401
+ /**
402
+ * Fixes the string length of a string object that has been serialized but the length is broken
403
+ *
404
+ * @param string $data The string ojbect to recalculate the size on.
405
+ *
406
+ * @return string A serialized string that fixes and string length types
407
+ */
408
+ public static function fixSerialString($data)
409
+ {
410
+ $result = array('data' => $data, 'fixed' => false, 'tried' => false);
411
+ if (preg_match("/s:[0-9]+:/", $data)) {
412
+ if (!self::isSerialized($data)) {
413
+ $regex = '!(?<=^|;)s:(\d+)(?=:"(.*?)";(?:}|a:|s:|b:|d:|i:|o:|N;))!s';
414
+ $serial_string = preg_match('/^s:[0-9]+:"(.*$)/s', trim($data), $matches);
415
+ //Nested serial string
416
+ if ($serial_string) {
417
+ $inner = preg_replace_callback($regex, 'DUPX_UpdateEngine::fixStringCallback', rtrim($matches[1], '";'));
418
+ $serialized_fixed = 's:'.strlen($inner).':"'.$inner.'";';
419
+ } else {
420
+ $serialized_fixed = preg_replace_callback($regex, 'DUPX_UpdateEngine::fixStringCallback', $data);
421
+ }
422
+
423
+ if (self::isSerialized($serialized_fixed)) {
424
+ $result['data'] = $serialized_fixed;
425
+ $result['fixed'] = true;
426
+ }
427
+ $result['tried'] = true;
428
+ }
429
+ }
430
+ return $result;
431
+ }
432
+
433
+ /**
434
+ * The call back method call from via fixSerialString
435
+ */
436
+ private static function fixStringCallback($matches)
437
+ {
438
+ return 's:'.strlen(($matches[2]));
439
+ }
440
+ }
441
+ ?>
installer/build/classes/class.logging.php CHANGED
@@ -21,34 +21,53 @@ define('ERR_DBTRYCLEAN', 'DATABASE CREATION FAILURE!<br/> Unable to remove all
21
  define('ERR_DBCREATE', 'The database "%s" does not exists.<br/> Change mode to create in order to create a new database.');
22
  define('ERR_DBEMPTY', 'The database "%s" has "%s" tables. The Duplicator only works with an EMPTY database. Enable the action "Connect and Remove All Data" radio button to remove all tables and or create a new database. Some hosting providers do not allow table removal from scripts. In this case you will need to login to your hosting providers control panel and remove the tables manually. Please contact your hosting provider for further details. Always backup all your data before proceeding!');
23
  define('ERR_TESTDB_UTF8', 'UTF8 Characters were detected as part of the database connection string. If your connection fails be sure to update the MySQL my.ini configuration file setting to support UTF8 characters by enabling this option [character_set_server=utf8] and restarting the database server.');
24
- define('ERR_TESTDB_VERSION', 'In order to avoid database incompatibility issues make sure the database versions between the build and installer servers are as close as possible. If the package was created on a newer database version than where it is being installed then you might run into issues.<br/><br/> It is best to make sure the server where the installer is running has the same or higher version number than where it was built. If the major and minor version are the same or close for example [5.7 to 5.6], then the migration should work without issues. A version pair of [5.7 to 5.1] is more likely to cause issues unless you have a very simple setup. If the versions are too far apart work with your hosting provider to upgrade the MySQL engine on this server.');
 
25
 
26
- /** * *****************************************************
27
- * DUPX_Log
28
- * Class used to log information */
29
 
 
 
 
 
 
 
 
 
 
30
  class DUPX_Log
31
  {
32
 
33
- /** METHOD: LOG
34
  * Used to write debug info to the text log file
 
35
  * @param string $msg Any text data
36
  * @param int $loglevel Log level
 
 
37
  */
38
- public static function Info($msg, $logging = 1)
39
  {
40
  if ($logging <= $GLOBALS["LOGGING"]) {
41
  @fwrite($GLOBALS["LOG_FILE_HANDLE"], "{$msg}\n");
42
  }
43
  }
44
- public static function Error($errorMessage)
 
 
 
 
 
 
 
 
 
45
  {
46
  $breaks = array("<br />","<br>","<br/>");
47
- $log_msg = str_ireplace($breaks, "\r\n", $errorMessage);
48
  $log_msg = strip_tags($log_msg);
49
  @fwrite($GLOBALS["LOG_FILE_HANDLE"], "\nINSTALLER ERROR:\n{$log_msg}\n");
50
  @fclose($GLOBALS["LOG_FILE_HANDLE"]);
51
- die("<div class='dup-ui-error'><hr size='1' /><b style='color:#B80000;'>INSTALL ERROR!</b><br/>{$errorMessage}</div><br/>");
52
  }
53
  }
54
- ?>
21
  define('ERR_DBCREATE', 'The database "%s" does not exists.<br/> Change mode to create in order to create a new database.');
22
  define('ERR_DBEMPTY', 'The database "%s" has "%s" tables. The Duplicator only works with an EMPTY database. Enable the action "Connect and Remove All Data" radio button to remove all tables and or create a new database. Some hosting providers do not allow table removal from scripts. In this case you will need to login to your hosting providers control panel and remove the tables manually. Please contact your hosting provider for further details. Always backup all your data before proceeding!');
23
  define('ERR_TESTDB_UTF8', 'UTF8 Characters were detected as part of the database connection string. If your connection fails be sure to update the MySQL my.ini configuration file setting to support UTF8 characters by enabling this option [character_set_server=utf8] and restarting the database server.');
24
+ define('ERR_TESTDB_VERSION_INFO', 'The current version detected was released prior to MySQL 5.5.3 which had a release date of April 8th 2010. WordPress 4.2 included support for utf8mb4 which is only supported in MySQL server 5.5.3+. It is highly recommended to upgrade your version of MySQL server on this server to be more compatible with recent releases of WordPress and avoid issues with install errors.');
25
+ define('ERR_TESTDB_VERSION_COMPAT', 'In order to avoid database incompatibility issues make sure the database versions between the build and installer servers are as close as possible. If the package was created on a newer database version than where it is being installed then you might run into issues.<br/><br/> It is best to make sure the server where the installer is running has the same or higher version number than where it was built. If the major and minor version are the same or close for example [5.7 to 5.6], then the migration should work without issues. A version pair of [5.7 to 5.1] is more likely to cause issues unless you have a very simple setup. If the versions are too far apart work with your hosting provider to upgrade the MySQL engine on this server.<br/><br/> <b>MariaDB:</b> If see a version of 10.N.N then the database distribution is a MariaDB flavor of MySQL. While the distributions are very close there are some subtle differences. Some operating systems will report the version such as "5.5.5-10.1.21-MariaDB" showing the correlation of both. Please visit the online <a href="https://mariadb.com/kb/en/mariadb/mariadb-vs-mysql-compatibility/" target="_blank">MariaDB versus MySQL - Compatibility</a> page for more details.<br/><br/> Please note these messages are simply notices. It is highly recommended that you continue with the install process and closely monitor the installer-log.txt file along with the install report found on step 3 of the installer. Be sure to look for any notices/warnings/errors in these locations to validate the install process did not detect any errors. If any issues are found please visit the FAQ pages and see the question <a href="https://snapcreek.com/duplicator/docs/faqs-tech/#faq-installer-260-q" target="_blank">What if I get database errors or general warnings on the install report?</a>.');
26
 
 
 
 
27
 
28
+ /**
29
+ * Class used to log information to the installer-log.txt file
30
+ *
31
+ * Standard: PSR-2
32
+ * @link http://www.php-fig.org/psr/psr-2 Full Documentation
33
+ *
34
+ * @package SC\DUPX\Log
35
+ *
36
+ */
37
  class DUPX_Log
38
  {
39
 
40
+ /**
41
  * Used to write debug info to the text log file
42
+ *
43
  * @param string $msg Any text data
44
  * @param int $loglevel Log level
45
+ *
46
+ * @return string Write info to both the log and browser
47
  */
48
+ public static function info($msg, $logging = 1)
49
  {
50
  if ($logging <= $GLOBALS["LOGGING"]) {
51
  @fwrite($GLOBALS["LOG_FILE_HANDLE"], "{$msg}\n");
52
  }
53
  }
54
+
55
+ /**
56
+ * Used to write errors to the text log file
57
+ *
58
+ * @param string $msg Any text data
59
+ * @param int $loglevel Log level
60
+ *
61
+ * @return string Write errors to both the log and browser
62
+ */
63
+ public static function error($msg)
64
  {
65
  $breaks = array("<br />","<br>","<br/>");
66
+ $log_msg = str_ireplace($breaks, "\r\n", $msg);
67
  $log_msg = strip_tags($log_msg);
68
  @fwrite($GLOBALS["LOG_FILE_HANDLE"], "\nINSTALLER ERROR:\n{$log_msg}\n");
69
  @fclose($GLOBALS["LOG_FILE_HANDLE"]);
70
+ die("<div class='dup-ui-error'><hr size='1' /><b style='color:#B80000;'>INSTALL ERROR!</b><br/>{$msg}</div><br/>");
71
  }
72
  }
73
+ ?>
installer/build/classes/class.serializer.php DELETED
@@ -1,452 +0,0 @@
1
- <?php
2
- // Exit if accessed directly
3
- if (!defined('DUPLICATOR_INIT')) {
4
- $_baseURL = "http://" . strlen($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'];
5
- header("HTTP/1.1 301 Moved Permanently");
6
- header("Location: {$_baseURL}");
7
- exit;
8
- }
9
-
10
- /** * *****************************************************
11
- * CLASS::DUPX_UpdateEngine
12
- * Walks every table in db that then walks every row and column replacing searches with replaces
13
- * large tables are split into 50k row blocks to save on memory. */
14
- class DUPX_UpdateEngine
15
- {
16
- /**
17
- * LOG ERRORS
18
- */
19
- public static function log_errors($report)
20
- {
21
- if (!empty($report['errsql'])) {
22
- DUPX_Log::Info("====================================");
23
- DUPX_Log::Info("DATA-REPLACE ERRORS (MySQL)");
24
- foreach ($report['errsql'] as $error) {
25
- DUPX_Log::Info($error);
26
- }
27
- DUPX_Log::Info("");
28
- }
29
- if (!empty($report['errser'])) {
30
- DUPX_Log::Info("====================================");
31
- DUPX_Log::Info("DATA-REPLACE ERRORS (Serialization):");
32
- foreach ($report['errser'] as $error) {
33
- DUPX_Log::Info($error);
34
- }
35
- DUPX_Log::Info("");
36
- }
37
- if (!empty($report['errkey'])) {
38
- DUPX_Log::Info("====================================");
39
- DUPX_Log::Info("DATA-REPLACE ERRORS (Key):");
40
- DUPX_Log::Info('Use SQL: SELECT @row := @row + 1 as row, t.* FROM some_table t, (SELECT @row := 0) r');
41
- foreach ($report['errkey'] as $error) {
42
- DUPX_Log::Info($error);
43
- }
44
- }
45
- }
46
-
47
- /**
48
- * LOG STATS
49
- */
50
- public static function log_stats($report)
51
- {
52
- if (!empty($report) && is_array($report))
53
- {
54
- $stats = "--------------------------------------\n";
55
- $srchnum = 0;
56
- foreach ($GLOBALS['REPLACE_LIST'] as $item)
57
- {
58
- $srchnum++;
59
- $stats .= sprintf("Search{$srchnum}:\t'%s' \nChange{$srchnum}:\t'%s' \n", $item['search'], $item['replace']);
60
- }
61
- $stats .= sprintf("SCANNED:\tTables:%d \t|\t Rows:%d \t|\t Cells:%d \n", $report['scan_tables'], $report['scan_rows'], $report['scan_cells']);
62
- $stats .= sprintf("UPDATED:\tTables:%d \t|\t Rows:%d \t|\t Cells:%d \n", $report['updt_tables'], $report['updt_rows'], $report['updt_cells']);
63
- $stats .= sprintf("ERRORS:\t\t%d \nRUNTIME:\t%f sec", $report['err_all'], $report['time']);
64
- DUPX_Log::Info($stats);
65
- }
66
- }
67
-
68
- /**
69
- * Returns only the text type columns of a table ignoring all numeric types
70
- */
71
- public static function getTextColumns($conn, $table)
72
- {
73
- $type_where = "type NOT LIKE 'tinyint%' AND ";
74
- $type_where .= "type NOT LIKE 'smallint%' AND ";
75
- $type_where .= "type NOT LIKE 'mediumint%' AND ";
76
- $type_where .= "type NOT LIKE 'int%' AND ";
77
- $type_where .= "type NOT LIKE 'bigint%' AND ";
78
- $type_where .= "type NOT LIKE 'float%' AND ";
79
- $type_where .= "type NOT LIKE 'double%' AND ";
80
- $type_where .= "type NOT LIKE 'decimal%' AND ";
81
- $type_where .= "type NOT LIKE 'numeric%' AND ";
82
- $type_where .= "type NOT LIKE 'date%' AND ";
83
- $type_where .= "type NOT LIKE 'time%' AND ";
84
- $type_where .= "type NOT LIKE 'year%' ";
85
-
86
- $result = mysqli_query($conn, "SHOW COLUMNS FROM `{$table}` WHERE {$type_where}");
87
- if (!$result) {
88
- return null;
89
- }
90
- $fields = array();
91
- if (mysqli_num_rows($result) > 0) {
92
- while ($row = mysqli_fetch_assoc($result)) {
93
- $fields[] = $row['Field'];
94
- }
95
- }
96
-
97
- //Return Primary which is needed for index lookup
98
- //$result = mysqli_query($conn, "SHOW INDEX FROM `{$table}` WHERE KEY_NAME LIKE '%PRIMARY%'"); 1.1.15 updated
99
- $result = mysqli_query($conn, "SHOW INDEX FROM `{$table}`");
100
- if (mysqli_num_rows($result) > 0) {
101
- while ($row = mysqli_fetch_assoc($result)) {
102
- $fields[] = $row['Column_name'];
103
- }
104
- }
105
-
106
- return (count($fields) > 0) ? $fields : null;
107
- }
108
-
109
- /**
110
- * LOAD
111
- * Begins the processing for replace logic
112
- * @param mysql $conn The db connection object
113
- * @param array $list Key value pair of 'search' and 'replace' arrays
114
- * @param array $tables The tables we want to look at
115
- * @param array $fullsearch Search every column reguardless of its data type
116
- * @return array Collection of information gathered during the run.
117
- */
118
- public static function load($conn, $list = array(), $tables = array(), $fullsearch = false)
119
- {
120
- $report = array(
121
- 'scan_tables' => 0,
122
- 'scan_rows' => 0,
123
- 'scan_cells' => 0,
124
- 'updt_tables' => 0,
125
- 'updt_rows' => 0,
126
- 'updt_cells' => 0,
127
- 'errsql' => array(),
128
- 'errser' => array(),
129
- 'errkey' => array(),
130
- 'errsql_sum' => 0,
131
- 'errser_sum' => 0,
132
- 'errkey_sum' => 0,
133
- 'time' => '',
134
- 'err_all' => 0
135
- );
136
-
137
- $walk_function = create_function('&$str', '$str = "`$str`";');
138
-
139
- $profile_start = DUPX_Util::get_microtime();
140
- if (is_array($tables) && !empty($tables)) {
141
-
142
- foreach ($tables as $table)
143
- {
144
- $report['scan_tables']++;
145
- $columns = array();
146
-
147
- // Get a list of columns in this table
148
- $fields = mysqli_query($conn, 'DESCRIBE ' . $table);
149
- while ($column = mysqli_fetch_array($fields)) {
150
- $columns[$column['Field']] = $column['Key'] == 'PRI' ? true : false;
151
- }
152
-
153
- // Count the number of rows we have in the table if large we'll split into blocks
154
- $row_count = mysqli_query($conn, "SELECT COUNT(*) FROM `{$table}`");
155
- $rows_result = mysqli_fetch_array($row_count);
156
- @mysqli_free_result($row_count);
157
- $row_count = $rows_result[0];
158
- if ($row_count == 0) {
159
- DUPX_Log::Info("{$table}^ ({$row_count})");
160
- continue;
161
- }
162
-
163
- $page_size = 25000;
164
- $offset = ($page_size + 1);
165
- $pages = ceil($row_count / $page_size);
166
-
167
- // Grab the columns of the table. Only grab text based columns because
168
- // they are the only data types that should allow any type of search/replace logic
169
- $colList = '*';
170
- $colMsg = '*';
171
- if (! $fullsearch)
172
- {
173
- $colList = self::getTextColumns($conn, $table);
174
- if ($colList != null && is_array($colList)) {
175
- array_walk($colList, $walk_function);
176
- $colList = implode(',', $colList);
177
- }
178
- $colMsg = (empty($colList)) ? '*' : '~';
179
- }
180
-
181
- if (empty($colList))
182
- {
183
- DUPX_Log::Info("{$table}^ ({$row_count})");
184
- continue;
185
- }
186
- else
187
- {
188
- DUPX_Log::Info("{$table}{$colMsg} ({$row_count})");
189
- }
190
-
191
- //Paged Records
192
- for ($page = 0; $page < $pages; $page++)
193
- {
194
- $current_row = 0;
195
- $start = $page * $page_size;
196
- $end = $start + $page_size;
197
- $sql = sprintf("SELECT {$colList} FROM `%s` LIMIT %d, %d", $table, $start, $offset);
198
- $data = mysqli_query($conn, $sql);
199
-
200
- if (!$data)
201
- $report['errsql'][] = mysqli_error($conn);
202
-
203
- $scan_count = ($row_count < $end) ? $row_count : $end;
204
- DUPX_Log::Info("\tScan => {$start} of {$scan_count}", 2);
205
-
206
- //Loops every row
207
- while ($row = mysqli_fetch_array($data))
208
- {
209
- $report['scan_rows']++;
210
- $current_row++;
211
- $upd_col = array();
212
- $upd_sql = array();
213
- $where_sql = array();
214
- $upd = false;
215
- $serial_err = 0;
216
-
217
- //Loops every cell
218
- foreach ($columns as $column => $primary_key)
219
- {
220
- $report['scan_cells']++;
221
- $edited_data = $data_to_fix = $row[$column];
222
- $base64coverted = false;
223
- $txt_found = false;
224
-
225
- //Only replacing string values
226
- if (!empty($row[$column]) && !is_numeric($row[$column]))
227
- {
228
- //Base 64 detection
229
- if (base64_decode($row[$column], true))
230
- {
231
- $decoded = base64_decode($row[$column], true);
232
- if (self::is_serialized($decoded))
233
- {
234
- $edited_data = $decoded;
235
- $base64coverted = true;
236
- }
237
- }
238
-
239
- //Skip table cell if match not found
240
- foreach ($list as $item)
241
- {
242
- if (strpos($edited_data, $item['search']) !== false) {
243
- $txt_found = true;
244
- break;
245
- }
246
- }
247
- if (! $txt_found) {
248
- continue;
249
- }
250
-
251
- //Replace logic - level 1: simple check on any string or serlized strings
252
- foreach ($list as $item) {
253
- $edited_data = self::recursive_unserialize_replace($item['search'], $item['replace'], $edited_data);
254
- }
255
-
256
- //Replace logic - level 2: repair serilized strings that have become broken
257
- $serial_check = self::fix_serial_string($edited_data);
258
- if ($serial_check['fixed'])
259
- {
260
- $edited_data = $serial_check['data'];
261
- }
262
- elseif ($serial_check['tried'] && !$serial_check['fixed'])
263
- {
264
- $serial_err++;
265
- }
266
- }
267
-
268
- //Change was made
269
- if ($edited_data != $data_to_fix || $serial_err > 0)
270
- {
271
- $report['updt_cells']++;
272
- //Base 64 encode
273
- if ($base64coverted) {
274
- $edited_data = base64_encode($edited_data);
275
- }
276
- $upd_col[] = $column;
277
- $upd_sql[] = $column . ' = "' . mysqli_real_escape_string($conn, $edited_data) . '"';
278
- $upd = true;
279
- }
280
-
281
- if ($primary_key) {
282
- $where_sql[] = $column . ' = "' . mysqli_real_escape_string($conn, $data_to_fix) . '"';
283
- }
284
- }
285
-
286
- //PERFORM ROW UPDATE
287
- if ($upd && !empty($where_sql))
288
- {
289
- $sql = "UPDATE `{$table}` SET " . implode(', ', $upd_sql) . ' WHERE ' . implode(' AND ', array_filter($where_sql));
290
- $result = mysqli_query($conn, $sql) or $report['errsql'][] = mysqli_error($conn);
291
- //DEBUG ONLY:
292
- DUPX_Log::Info("\t{$sql}\n", 3);
293
- if ($result) {
294
- if ($serial_err > 0) {
295
- $report['errser'][] = "SELECT " . implode(', ', $upd_col) . " FROM `{$table}` WHERE " . implode(' AND ', array_filter($where_sql)) . ';';
296
- }
297
- $report['updt_rows']++;
298
- }
299
- } elseif ($upd) {
300
- $report['errkey'][] = sprintf("Row [%s] on Table [%s] requires a manual update.", $current_row, $table);
301
- }
302
- }
303
- DUPX_Util::fcgi_flush();
304
- @mysqli_free_result($data);
305
- }
306
-
307
- if ($upd) {
308
- $report['updt_tables']++;
309
- }
310
- }
311
- }
312
- $profile_end = DUPX_Util::get_microtime();
313
- $report['time'] = DUPX_Util::elapsed_time($profile_end, $profile_start);
314
- $report['errsql_sum'] = empty($report['errsql']) ? 0 : count($report['errsql']);
315
- $report['errser_sum'] = empty($report['errser']) ? 0 : count($report['errser']);
316
- $report['errkey_sum'] = empty($report['errkey']) ? 0 : count($report['errkey']);
317
- $report['err_all'] = $report['errsql_sum'] + $report['errser_sum'] + $report['errkey_sum'];
318
- return $report;
319
- }
320
-
321
- /**
322
- * Take a serialised array and unserialise it replacing elements and
323
- * unserialising any subordinate arrays and performing the replace.
324
- * @param string $from String we're looking to replace.
325
- * @param string $to What we want it to be replaced with
326
- * @param array $data Used to pass any subordinate arrays back to in.
327
- * @param bool $serialised Does the array passed via $data need serialising.
328
- * @return array The original array with all elements replaced as needed.
329
- */
330
- public static function recursive_unserialize_replace($from = '', $to = '', $data = '', $serialised = false)
331
- {
332
- // some unseriliased data cannot be re-serialised eg. SimpleXMLElements
333
- try
334
- {
335
- if (is_string($data) && ($unserialized = @unserialize($data)) !== false)
336
- {
337
- $data = self::recursive_unserialize_replace($from, $to, $unserialized, true);
338
- }
339
- elseif (is_array($data))
340
- {
341
- $_tmp = array();
342
- foreach ($data as $key => $value)
343
- {
344
- $_tmp[$key] = self::recursive_unserialize_replace($from, $to, $value, false);
345
- }
346
- $data = $_tmp;
347
- unset($_tmp);
348
-
349
- /* CJL
350
- Check for an update to the key of an array e.g. [http://localhost/projects/wpplugins/] => 1.41
351
- This could have unintended consequences would need to enable with full-search needs more testing
352
- if (array_key_exists($from, $data))
353
- {
354
- $data[$to] = $data[$from];
355
- unset($data[$from]);
356
- }*/
357
-
358
- }
359
- elseif (is_object($data))
360
- {
361
- /* RSR Old logic that didn't work with Beaver Builder - they didn't want to create a brand new
362
- object instead reused the existing one...
363
- $dataClass = get_class($data);
364
- $_tmp = new $dataClass();
365
- foreach ($data as $key => $value) {
366
- $_tmp->$key = self::recursive_unserialize_replace($from, $to, $value, false);
367
- }
368
- $data = $_tmp;
369
- unset($_tmp);*/
370
-
371
- // RSR NEW LOGIC
372
- $_tmp = $data;
373
- $props = get_object_vars( $data );
374
- foreach ($props as $key => $value)
375
- {
376
- $_tmp->$key = self::recursive_unserialize_replace( $from, $to, $value, false );
377
- }
378
- $data = $_tmp;
379
- unset($_tmp);
380
- }
381
-
382
- else
383
- {
384
- if (is_string($data)) {
385
- $data = str_replace($from, $to, $data);
386
- }
387
- }
388
-
389
- if ($serialised)
390
- return serialize($data);
391
-
392
- }
393
- catch (Exception $error)
394
- {
395
- DUPX_Log::Info("\nRECURSIVE UNSERIALIZE ERROR: With string\n" . $error, 2);
396
- }
397
- return $data;
398
- }
399
-
400
- /**
401
- * IS_SERIALIZED
402
- * Test if a string in properly serialized */
403
- public static function is_serialized($data)
404
- {
405
- $test = @unserialize(($data));
406
- return ($test !== false || $test === 'b:0;') ? true : false;
407
- }
408
-
409
- /**
410
- * FIX_STRING
411
- * Fixes the string length of a string object that has been serialized but the length is broken
412
- * @param string $data The string ojbect to recalculate the size on.
413
- * @return
414
- */
415
- public static function fix_serial_string($data)
416
- {
417
- $result = array('data' => $data, 'fixed' => false, 'tried' => false);
418
- if (preg_match("/s:[0-9]+:/", $data))
419
- {
420
- if (!self::is_serialized($data))
421
- {
422
- $regex = '!(?<=^|;)s:(\d+)(?=:"(.*?)";(?:}|a:|s:|b:|d:|i:|o:|N;))!s';
423
- $serial_string = preg_match('/^s:[0-9]+:"(.*$)/s', trim($data), $matches);
424
- //Nested serial string
425
- if ($serial_string)
426
- {
427
- $inner = preg_replace_callback($regex, 'DUPX_UpdateEngine::fix_string_callback', rtrim($matches[1], '";'));
428
- $serialized_fixed = 's:' . strlen($inner) . ':"' . $inner . '";';
429
- }
430
- else
431
- {
432
- $serialized_fixed = preg_replace_callback($regex, 'DUPX_UpdateEngine::fix_string_callback', $data);
433
- }
434
-
435
- if (self::is_serialized($serialized_fixed))
436
- {
437
- $result['data'] = $serialized_fixed;
438
- $result['fixed'] = true;
439
- }
440
- $result['tried'] = true;
441
- }
442
- }
443
- return $result;
444
- }
445
-
446
- private static function fix_string_callback($matches)
447
- {
448
- return 's:' . strlen(($matches[2]));
449
- }
450
-
451
- }
452
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
installer/build/classes/class.utils.php DELETED
@@ -1,376 +0,0 @@
1
- <?php
2
- // Exit if accessed directly
3
- if (! defined('DUPLICATOR_INIT')) {
4
- $_baseURL = "http://" . strlen($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'];
5
- header("HTTP/1.1 301 Moved Permanently");
6
- header("Location: $_baseURL");
7
- exit;
8
- }
9
-
10
- /** * *****************************************************
11
- * Various Static Utility methods for working with the installer */
12
- class DUPX_Util
13
- {
14
-
15
- /**
16
- * Get current microtime as a float. Can be used for simple profiling.
17
- */
18
- public static function get_microtime() {
19
- return microtime(true);
20
- }
21
-
22
- /**
23
- * Return a string with the elapsed time.
24
- * Order of $end and $start can be switched.
25
- */
26
- public static function elapsed_time($end, $start) {
27
- return sprintf("%.4f sec.", abs($end - $start));
28
- }
29
-
30
- /**
31
- * @param string $string Thing that needs escaping
32
- * @param bool $echo Do we echo or return?
33
- * @return string Escaped string.
34
- */
35
- public static function esc_html_attr($string = '', $echo = false) {
36
- $output = htmlentities($string, ENT_QUOTES, 'UTF-8');
37
- if ($echo)
38
- echo $output;
39
- else
40
- return $output;
41
- }
42
-
43
- /**
44
- * Count the tables in a given database
45
- * @param string $_POST['dbname'] Database to count tables in
46
- */
47
- public static function dbtable_count($conn, $dbname) {
48
- $res = mysqli_query($conn, "SELECT COUNT(*) AS count FROM information_schema.tables WHERE table_schema = '{$dbname}' ");
49
- $row = mysqli_fetch_row($res);
50
- return is_null($row) ? 0 : $row[0];
51
- }
52
-
53
- /**
54
- * Returns the table count
55
- * @param string $conn A valid link resource
56
- * @param string $table_name A valid table name
57
- */
58
- public static function table_row_count($conn, $table_name) {
59
- $total = mysqli_query($conn, "SELECT COUNT(*) FROM `$table_name`");
60
- if ($total) {
61
- $total = @mysqli_fetch_array($total);
62
- return $total[0];
63
- } else {
64
- return 0;
65
- }
66
- }
67
-
68
- /**
69
- * Adds a slash to the end of a path
70
- * @param string $path A path
71
- */
72
- public static function add_slash($path) {
73
- $last_char = substr($path, strlen($path) - 1, 1);
74
- if ($last_char != '/') {
75
- $path .= '/';
76
- }
77
- return $path;
78
- }
79
-
80
- /**
81
- * Makes path safe for any OS
82
- * Paths should ALWAYS READ be "/"
83
- * uni: /home/path/file.xt
84
- * win: D:/home/path/file.txt
85
- * @param string $path The path to make safe
86
- */
87
- public static function set_safe_path($path) {
88
- return str_replace("\\", "/", $path);
89
- }
90
-
91
- public static function unset_safe_path($path) {
92
- return str_replace("/", "\\", $path);
93
- }
94
-
95
- /**
96
- * PHP_SAPI for fcgi requires a data flush of at least 256
97
- * bytes every 40 seconds or else it forces a script hault
98
- */
99
- public static function fcgi_flush() {
100
- echo(str_repeat(' ', 256));
101
- @flush();
102
- }
103
-
104
- /**
105
- * A safe method used to copy larger files
106
- * @param string $source The path to the file being copied
107
- * @param string $destination The path to the file being made
108
- */
109
- public static function copy_file($source, $destination) {
110
- $sp = fopen($source, 'r');
111
- $op = fopen($destination, 'w');
112
-
113
- while (!feof($sp)) {
114
- $buffer = fread($sp, 512); // use a buffer of 512 bytes
115
- fwrite($op, $buffer);
116
- }
117
- // close handles
118
- fclose($op);
119
- fclose($sp);
120
- }
121
-
122
- /**
123
- * Looks for a list of strings in a string and returns each list item that is found
124
- * @param array $list A list of strings to search for
125
- * @param string $haystack The string to search in
126
- */
127
- public static function search_list_values($list, $haystack) {
128
- $found = array();
129
- foreach ($list as $var) {
130
- if (strstr($haystack, $var) !== false) {
131
- array_push($found, $var);
132
- }
133
- }
134
- return $found;
135
- }
136
-
137
- /** METHOD: get_active_plugins
138
- * Returns the active plugins for a package
139
- * @param conn $dbh A database connection handle
140
- * @return array $list A list of active plugins
141
- */
142
- public static function get_active_plugins($dbh) {
143
- $query = @mysqli_query($dbh, "SELECT option_value FROM `{$GLOBALS['FW_TABLEPREFIX']}options` WHERE option_name = 'active_plugins' ");
144
- if ($query) {
145
- $row = @mysqli_fetch_array($query);
146
- $all_plugins = unserialize($row[0]);
147
- if (is_array($all_plugins)) {
148
- return $all_plugins;
149
- }
150
- }
151
- return array();
152
- }
153
-
154
- /**
155
- * Returns the tables for a database
156
- * @param conn $dbh A database connection handle
157
- * @return array $list A list of all table names
158
- */
159
- public static function get_database_tables($dbh) {
160
- $query = @mysqli_query($dbh, 'SHOW TABLES');
161
- if ($query) {
162
- while ($table = @mysqli_fetch_array($query)) {
163
- $all_tables[] = $table[0];
164
- }
165
- if (isset($all_tables) && is_array($all_tables)) {
166
- return $all_tables;
167
- }
168
- }
169
- return array();
170
- }
171
-
172
- /**
173
- * MySQL connection support for sock
174
- * @param same as mysqli_connect
175
- * @return database connection handle
176
- */
177
- public static function db_connect( $host, $username, $password, $dbname = '', $port = null ) {
178
-
179
- //sock connections
180
- if ( 'sock' === substr( $host, -4 ) )
181
- {
182
- $url_parts = parse_url( $host );
183
- $dbh = @mysqli_connect( 'localhost', $username, $password, $dbname, null, $url_parts['path'] );
184
- }
185
- else
186
- {
187
- $dbh = @mysqli_connect( $host, $username, $password, $dbname, $port );
188
- }
189
- return $dbh;
190
- }
191
-
192
- /**
193
- * MySQL database version number
194
- * @param conn $dbh Database connection handle
195
- * @return false|string false on failure, version number on success
196
- */
197
- public static function mysqldb_version($dbh) {
198
- if (function_exists('mysqli_get_server_info')) {
199
- return preg_replace('/[^0-9.].*/', '', mysqli_get_server_info($dbh));
200
- } else {
201
- return 0;
202
- }
203
- }
204
-
205
- /**
206
- * MySQL server variable
207
- * @param conn $dbh Database connection handle
208
- * @return string the server variable to query for
209
- */
210
- public static function mysqldb_variable_value($dbh, $variable) {
211
- $result = @mysqli_query($dbh, "SHOW VARIABLES LIKE '{$variable}'");
212
- $row = @mysqli_fetch_array($result);
213
- @mysqli_free_result($result);
214
- return isset($row[1]) ? $row[1] : null;
215
- }
216
-
217
- /**
218
- * Determine if a MySQL database supports a particular feature
219
- * @param conn $dbh Database connection handle
220
- * @param string $feature the feature to check for
221
- * @return bool
222
- */
223
- public static function mysqldb_has_ability($dbh, $feature) {
224
- $version = self::mysqldb_version($dbh);
225
-
226
- switch (strtolower($feature)) {
227
- case 'collation' :
228
- case 'group_concat' :
229
- case 'subqueries' :
230
- return version_compare($version, '4.1', '>=');
231
- case 'set_charset' :
232
- return version_compare($version, '5.0.7', '>=');
233
- };
234
- return false;
235
- }
236
-
237
- /**
238
- * Sets the MySQL connection's character set.
239
- * @param resource $dbh The resource given by mysqli_connect
240
- * @param string $charset The character set (optional)
241
- * @param string $collate The collation (optional)
242
- */
243
- public static function mysqldb_set_charset($dbh, $charset = null, $collate = null) {
244
-
245
- $charset = (!isset($charset) ) ? $GLOBALS['DBCHARSET_DEFAULT'] : $charset;
246
- $collate = (!isset($collate) ) ? $GLOBALS['DBCOLLATE_DEFAULT'] : $collate;
247
-
248
- if (self::mysqldb_has_ability($dbh, 'collation') && !empty($charset)) {
249
- if (function_exists('mysqli_set_charset') && self::mysqldb_has_ability($dbh, 'set_charset')) {
250
- return mysqli_set_charset($dbh, $charset);
251
- } else {
252
- $sql = " SET NAMES {$charset}";
253
- if (!empty($collate))
254
- $sql .= " COLLATE {$collate}";
255
- return mysqli_query($dbh, $sql);
256
- }
257
- }
258
- }
259
-
260
- /**
261
- * Display human readable byte sizes
262
- * @param string $size The size in bytes
263
- */
264
- public static function readable_bytesize($size) {
265
- try {
266
- $units = array('B', 'KB', 'MB', 'GB', 'TB');
267
- for ($i = 0; $size >= 1024 && $i < 4; $i++)
268
- $size /= 1024;
269
- return round($size, 2) . $units[$i];
270
- } catch (Exception $e) {
271
- return "n/a";
272
- }
273
- }
274
-
275
- /**
276
- * Converts shorthand memory notation value to bytes
277
- * From http://php.net/manual/en/function.ini-get.php
278
- *
279
- * @param $val Memory size shorthand notation string
280
- */
281
- public static function return_bytes($val)
282
- {
283
- $val = trim($val);
284
- $last = strtolower($val[strlen($val)-1]);
285
- switch($last) {
286
- // The 'G' modifier is available since PHP 5.1.0
287
- case 'g':
288
- $val *= 1024;
289
- case 'm':
290
- $val *= 1024;
291
- case 'k':
292
- $val *= 1024;
293
- break;
294
- default :
295
- $val = null;
296
- }
297
- return $val;
298
- }
299
-
300
- /**
301
- * The characters that are special in the replacement value of preg_replace are not the
302
- * same characters that are special in the pattern
303
- * @param string $str The string to replace on
304
- */
305
- public static function preg_replacement_quote($str) {
306
- return preg_replace('/(\$|\\\\)(?=\d)/', '\\\\\1', $str);
307
- }
308
-
309
-
310
- /**
311
- * Check to see if the internet is accessable
312
- * NOTE: fsocketopen on windows doesn't seem to honor $timeout setting.
313
- *
314
- * @param string $url A url e.g without prefix "ajax.googleapis.com"
315
- * @param string $port A valid port number
316
- * @return bool
317
- */
318
- public static function is_url_active($url, $port, $timeout=5)
319
- {
320
- if (function_exists('fsockopen'))
321
- {
322
- @ini_set("default_socket_timeout", 5);
323
- $port = isset($port) && is_integer($port) ? $port : 80;
324
- $connected = @fsockopen($url, $port, $errno, $errstr, $timeout); //website and port
325
- if ($connected){
326
- @fclose($connected);
327
- return true;
328
- }
329
- return false;
330
- } else {
331
- return false;
332
- }
333
- }
334
-
335
- /**
336
- * Returns an array of zip files found in the current directory
337
- * @return array of zip files
338
- */
339
- public static function get_zip_files() {
340
-
341
- $files = array();
342
- foreach (glob("*.zip") as $name) {
343
- if (file_exists($name)) {
344
- $files[] = $name;
345
- }
346
- }
347
-
348
- if (count($files) > 0) {
349
- return $files;
350
- }
351
-
352
- //FALL BACK: Windows XP has bug with glob,
353
- //add secondary check for PHP lameness
354
- if ($dh = opendir('.'))
355
- {
356
- while (false !== ($name = readdir($dh))) {
357
- $ext = substr($name, strrpos($name, '.') + 1);
358
- if(in_array($ext, array("zip"))) {
359
- $files[] = $name;
360
- }
361
- }
362
- closedir($dh);
363
- }
364
-
365
- return $files;
366
- }
367
-
368
- /**
369
- * Does a string have non ascii characters
370
- */
371
- public static function is_non_ascii($string)
372
- {
373
- return preg_match('/[^\x20-\x7f]/', $string);
374
- }
375
- }
376
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
installer/build/classes/config/class.conf.srv.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if (!defined('DUPLICATOR_INIT')) {
4
+ $_baseURL = "http://".strlen($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'];
5
+ header("HTTP/1.1 301 Moved Permanently");
6
+ header("Location: $_baseURL");
7
+ exit;
8
+ }
9
+
10
+ /**
11
+ * Class used to update and edit web server configuration files
12
+ *
13
+ * Standard: PSR-2
14
+ * @link http://www.php-fig.org/psr/psr-2 Full Documentation
15
+ *
16
+ * @package SC\DUPX\ServerConfig
17
+ *
18
+ */
19
+ class DUPX_ServerConfig
20
+ {
21
+
22
+ /**
23
+ * Clear .htaccess and web.config files and backup
24
+ *
25
+ * @return null
26
+ */
27
+ public static function reset()
28
+ {
29
+ DUPX_Log::info("\nWEB SERVER CONFIGURATION FILE RESET:");
30
+ $timeStamp = date("ymdHis");
31
+
32
+ //Apache
33
+ @copy('.htaccess', ".htaccess.{$timeStamp}.orig");
34
+ @unlink('.htaccess');
35
+
36
+ //IIS
37
+ @copy('web.config', "web.config.{$timeStamp}.orig");
38
+ @unlink('web.config');
39
+
40
+ //.user.ini - For WordFence
41
+ @copy('.user.ini', ".user.ini.{$timeStamp}.orig");
42
+ @unlink('.user.ini');
43
+
44
+ DUPX_Log::info("- Backup of .htaccess/web.config made to *.{$timeStamp}.orig");
45
+ DUPX_Log::info("- Reset of .htaccess/web.config files");
46
+ $tmp_htaccess = '# RESET FOR DUPLICATOR INSTALLER USEAGE';
47
+ file_put_contents('.htaccess', $tmp_htaccess);
48
+ @chmod('.htaccess', 0644);
49
+ }
50
+
51
+ /**
52
+ * Resets the .htaccess file to a very slimed down version with new paths
53
+ *
54
+ * @return null
55
+ */
56
+ public static function setup()
57
+ {
58
+
59
+ if (!isset($_POST['url_new'])) {
60
+ return;
61
+ }
62
+
63
+ DUPX_Log::info("\nWEB SERVER CONFIGURATION FILE BASIC SETUP:");
64
+ $currdata = parse_url($_POST['url_old']);
65
+ $newdata = parse_url($_POST['url_new']);
66
+ $currpath = DUPX_Util::add_slash(isset($currdata['path']) ? $currdata['path'] : "");
67
+ $newpath = DUPX_Util::add_slash(isset($newdata['path']) ? $newdata['path'] : "");
68
+
69
+ $tmp_htaccess = <<<HTACCESS
70
+ # BEGIN WordPress
71
+ <IfModule mod_rewrite.c>
72
+ RewriteEngine On
73
+ RewriteBase {$newpath}
74
+ RewriteRule ^index\.php$ - [L]
75
+ RewriteCond %{REQUEST_FILENAME} !-f
76
+ RewriteCond %{REQUEST_FILENAME} !-d
77
+ RewriteRule . {$newpath}index.php [L]
78
+ </IfModule>
79
+ # END WordPress
80
+ HTACCESS;
81
+
82
+ file_put_contents('.htaccess', $tmp_htaccess);
83
+ @chmod('.htaccess', 0644);
84
+ DUPX_Log::info("created basic .htaccess file. If using IIS web.config this process will need to be done manually.");
85
+ }
86
+ }
87
+ ?>
installer/build/classes/config/class.conf.wp.php ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if (!defined('DUPLICATOR_INIT')) {
4
+ $_baseURL = "http://".strlen($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'];
5
+ header("HTTP/1.1 301 Moved Permanently");
6
+ header("Location: {$_baseURL}");
7
+ exit;
8
+ }
9
+
10
+ /**
11
+ * Class used to update and edit and update the wp-config.php
12
+ *
13
+ * Standard: PSR-2
14
+ * @link http://www.php-fig.org/psr/psr-2 Full Documentation
15
+ *
16
+ * @package SC\DUPX\WPConfig
17
+ *
18
+ */
19
+ class DUPX_WPConfig
20
+ {
21
+
22
+ /**
23
+ * Updates the web server config files in Step 1
24
+ *
25
+ * @return null
26
+ */
27
+ public static function updateStep1()
28
+ {
29
+ if (!file_exists('wp-config.php')) return;
30
+
31
+ $root_path = DUPX_Util::set_safe_path($GLOBALS['CURRENT_ROOT_PATH']);
32
+ $wpconfig = @file_get_contents('wp-config.php', true);
33
+
34
+ $patterns = array(
35
+ "/'DB_NAME',\s*'.*?'/",
36
+ "/'DB_USER',\s*'.*?'/",
37
+ "/'DB_PASSWORD',\s*'.*?'/",
38
+ "/'DB_HOST',\s*'.*?'/");
39
+
40
+ $db_host = ($_POST['dbport'] == 3306) ? $_POST['dbhost'] : "{$_POST['dbhost']}:{$_POST['dbport']}";
41
+
42
+ $replace = array(
43
+ "'DB_NAME', ".'\''.$_POST['dbname'].'\'',
44
+ "'DB_USER', ".'\''.$_POST['dbuser'].'\'',
45
+ "'DB_PASSWORD', ".'\''.DUPX_Util::preg_replacement_quote($_POST['dbpass']).'\'',
46
+ "'DB_HOST', ".'\''.$db_host.'\'');
47
+
48
+ //SSL CHECKS
49
+ if ($_POST['ssl_admin']) {
50
+ if (!strstr($wpconfig, 'FORCE_SSL_ADMIN')) {
51
+ $wpconfig = $wpconfig.PHP_EOL."define('FORCE_SSL_ADMIN', true);";
52
+ }
53
+ } else {
54
+ array_push($patterns, "/'FORCE_SSL_ADMIN',\s*true/");
55
+ array_push($replace, "'FORCE_SSL_ADMIN', false");
56
+ }
57
+
58
+ if ($_POST['ssl_login']) {
59
+ if (!strstr($wpconfig, 'FORCE_SSL_LOGIN')) {
60
+ $wpconfig = $wpconfig.PHP_EOL."define('FORCE_SSL_LOGIN', true);";
61
+ }
62
+ } else {
63
+ array_push($patterns, "/'FORCE_SSL_LOGIN',\s*true/");
64
+ array_push($replace, "'FORCE_SSL_LOGIN', false");
65
+ }
66
+
67
+ //CACHE CHECKS
68
+ if ($_POST['cache_wp']) {
69
+ if (!strstr($wpconfig, 'WP_CACHE')) {
70
+ $wpconfig = $wpconfig.PHP_EOL."define('WP_CACHE', true);";
71
+ }
72
+ } else {
73
+ array_push($patterns, "/'WP_CACHE',\s*true/");
74
+ array_push($replace, "'WP_CACHE', false");
75
+ }
76
+ if (!$_POST['cache_path']) {
77
+ array_push($patterns, "/'WPCACHEHOME',\s*'.*?'/");
78
+ array_push($replace, "'WPCACHEHOME', ''");
79
+ }
80
+
81
+ if (!is_writable("{$root_path}/wp-config.php")) {
82
+ if (file_exists("{$root_path}/wp-config.php")) {
83
+ chmod("{$root_path}/wp-config.php", 0644) ? DUPX_Log::info('File Permission Update: wp-config.php set to 0644') : DUPX_Log::info('WARNING: Unable to update file permissions and write to wp-config.php. Please visit the online FAQ for setting file permissions and work with your hosting provider or server administrator to enable this installer.php script to write to the wp-config.php file.');
84
+ } else {
85
+ DUPX_Log::info('WARNING: Unable to locate wp-config.php file. Be sure the file is present in your archive.');
86
+ }
87
+ }
88
+
89
+ $wpconfig = preg_replace($patterns, $replace, $wpconfig);
90
+ file_put_contents('wp-config.php', $wpconfig);
91
+ $wpconfig = null;
92
+ }
93
+
94
+ /**
95
+ * Updates the web server config files in Step 1
96
+ *
97
+ * @return null
98
+ */
99
+ public static function updateStep2()
100
+ {
101
+ $config_file = '';
102
+ if (!file_exists('wp-config.php')) {
103
+ return $config_file;
104
+ }
105
+
106
+ $patterns = array("/('|\")WP_HOME.*?\)\s*;/",
107
+ "/('|\")WP_SITEURL.*?\)\s*;/",
108
+ "/('|\")DOMAIN_CURRENT_SITE.*?\)\s*;/",
109
+ "/('|\")PATH_CURRENT_SITE.*?\)\s*;/");
110
+ $replace = array("'WP_HOME', '{$_POST['url_new']}');",
111
+ "'WP_SITEURL', '{$_POST['url_new']}');",
112
+ "'DOMAIN_CURRENT_SITE', '{$mu_newDomainHost}');",
113
+ "'PATH_CURRENT_SITE', '{$mu_newUrlPath}');");
114
+
115
+ $config_file = file_get_contents('wp-config.php', true);
116
+ $config_file = preg_replace($patterns, $replace, $config_file);
117
+ file_put_contents('wp-config.php', $config_file);
118
+
119
+ return $config_file;
120
+ }
121
+ }
122
+ ?>
installer/build/classes/util/class.db.php ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if (!defined('DUPLICATOR_INIT')) {
4
+ $_baseURL = "http://".strlen($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'];
5
+ header("HTTP/1.1 301 Moved Permanently");
6
+ header("Location: $_baseURL");
7
+ exit;
8
+ }
9
+
10
+ /**
11
+ * Lightweight abstraction layer for common simple database routines
12
+ *
13
+ * Standard: PSR-2
14
+ * @link http://www.php-fig.org/psr/psr-2 Full Documentation
15
+ *
16
+ * @package SC\DUPX\DB
17
+ *
18
+ */
19
+ class DUPX_DB
20
+ {
21
+
22
+ /**
23
+ * MySQL connection wrapper with support for port
24
+ *
25
+ * @param string $host The server host name
26
+ * @param string $username The server DB user name
27
+ * @param string $password The server DB password
28
+ * @param string $dbname The server DB name
29
+ * @param int $port The server DB port
30
+ *
31
+ * @return database connection handle
32
+ */
33
+ public static function connect($host, $username, $password, $dbname = '', $port = null)
34
+ {
35
+ //sock connections
36
+ if ('sock' === substr($host, -4)) {
37
+ $url_parts = parse_url($host);
38
+ $dbh = @mysqli_connect('localhost', $username, $password, $dbname, null, $url_parts['path']);
39
+ } else {
40
+ $dbh = @mysqli_connect($host, $username, $password, $dbname, $port);
41
+ }
42
+ return $dbh;
43
+ }
44
+
45
+ /**
46
+ * Count the tables in a given database
47
+ *
48
+ * @param obj $dbh A valid database link handle
49
+ * @param string $dbname Database to count tables in
50
+ *
51
+ * @return int The number of tables in the database
52
+ */
53
+ public static function countTables($dbh, $dbname)
54
+ {
55
+ $res = mysqli_query($dbh, "SELECT COUNT(*) AS count FROM information_schema.tables WHERE table_schema = '{$dbname}' ");
56
+ $row = mysqli_fetch_row($res);
57
+ return is_null($row) ? 0 : $row[0];
58
+ }
59
+
60
+ /**
61
+ * Returns the number of rows in a table
62
+ *
63
+ * @param obj $dbh A valid database link handle
64
+ * @param string $name A valid table name
65
+ */
66
+ public static function countTableRows($dbh, $name)
67
+ {
68
+ $total = mysqli_query($dbh, "SELECT COUNT(*) FROM `$name`");
69
+ if ($total) {
70
+ $total = @mysqli_fetch_array($total);
71
+ return $total[0];
72
+ } else {
73
+ return 0;
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Returns the tables for a database as an array
79
+ *
80
+ * @param obj $dbh A valid database link handle
81
+ *
82
+ * @return array A list of all table names
83
+ */
84
+ public static function getTables($dbh)
85
+ {
86
+ $query = @mysqli_query($dbh, 'SHOW TABLES');
87
+ if ($query) {
88
+ while ($table = @mysqli_fetch_array($query)) {
89
+ $all_tables[] = $table[0];
90
+ }
91
+ if (isset($all_tables) && is_array($all_tables)) {
92
+ return $all_tables;
93
+ }
94
+ }
95
+ return array();
96
+ }
97
+
98
+ /**
99
+ * Get the requested MySQL system variable
100
+ *
101
+ * @param obj $dbh A valid database link handle
102
+ * @param string $name The database variable name to lookup
103
+ *
104
+ * @return string the server variable to query for
105
+ */
106
+ public static function getVariable($dbh, $name)
107
+ {
108
+ $result = @mysqli_query($dbh, "SHOW VARIABLES LIKE '{$name}'");
109
+ $row = @mysqli_fetch_array($result);
110
+ @mysqli_free_result($result);
111
+ return isset($row[1]) ? $row[1] : null;
112
+ }
113
+
114
+ /**
115
+ * Gets the MySQL database version number
116
+ *
117
+ * @param obj $dbh A valid database link handle
118
+ * @param bool $full True: Gets the full version
119
+ * False: Gets only the numeric portion i.e. 5.5.6 or 10.1.2 (for MariaDB)
120
+ *
121
+ * @return false|string 0 on failure, version number on success
122
+ */
123
+ public static function getVersion($dbh, $full = false)
124
+ {
125
+ if ($full) {
126
+ $version = self::getVariable($dbh, 'version');
127
+ } else {
128
+ $version = preg_replace('/[^0-9.].*/', '', self::getVariable($dbh, 'version'));
129
+ }
130
+
131
+ $version = is_null($version) ? null : $version;
132
+ return empty($version) ? 0 : $version;
133
+ }
134
+
135
+ /**
136
+ * Returns a more detailed string about the msyql server version
137
+ * For example on some systems the result is 5.5.5-10.1.21-MariaDB
138
+ * this format is helpful for providing the user a full overview
139
+ *
140
+ * @param conn $dbh Database connection handle
141
+ *
142
+ * @return string The full details of mysql
143
+ */
144
+ public static function getServerInfo($dbh)
145
+ {
146
+ return mysqli_get_server_info($dbh);
147
+ }
148
+
149
+ /**
150
+ * Determine if a MySQL database supports a particular feature
151
+ *
152
+ * @param conn $dbh Database connection handle
153
+ * @param string $feature the feature to check for
154
+ * @return bool
155
+ */
156
+ public static function hasAbility($dbh, $feature)
157
+ {
158
+ $version = self::getVersion($dbh);
159
+
160
+ switch (strtolower($feature)) {
161
+ case 'collation' :
162
+ case 'group_concat' :
163
+ case 'subqueries' :
164
+ return version_compare($version, '4.1', '>=');
165
+ case 'set_charset' :
166
+ return version_compare($version, '5.0.7', '>=');
167
+ };
168
+ return false;
169
+ }
170
+
171
+ /**
172
+ * Sets the MySQL connection's character set.
173
+ *
174
+ * @param resource $dbh The resource given by mysqli_connect
175
+ * @param string $charset The character set (optional)
176
+ * @param string $collate The collation (optional)
177
+ */
178
+ public static function setCharset($dbh, $charset = null, $collate = null)
179
+ {
180
+ $charset = (!isset($charset) ) ? $GLOBALS['DBCHARSET_DEFAULT'] : $charset;
181
+ $collate = (!isset($collate) ) ? $GLOBALS['DBCOLLATE_DEFAULT'] : $collate;
182
+
183
+ if (self::hasAbility($dbh, 'collation') && !empty($charset)) {
184
+ if (function_exists('mysqli_set_charset') && self::hasAbility($dbh, 'set_charset')) {
185
+ return mysqli_set_charset($dbh, $charset);
186
+ } else {
187
+ $sql = " SET NAMES {$charset}";
188
+ if (!empty($collate)) $sql .= " COLLATE {$collate}";
189
+ return mysqli_query($dbh, $sql);
190
+ }
191
+ }
192
+ }
193
+ }
194
+ ?>
installer/build/classes/util/class.utils.php ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if (!defined('DUPLICATOR_INIT')) {
4
+ $_baseURL = "http://".strlen($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'];
5
+ header("HTTP/1.1 301 Moved Permanently");
6
+ header("Location: $_baseURL");
7
+ exit;
8
+ }
9
+
10
+ /**
11
+ * Various Static Utility methods for working with the installer
12
+ *
13
+ * @package SC\DUPX\Util
14
+ *
15
+ */
16
+ class DUPX_Util
17
+ {
18
+
19
+ /**
20
+ * Adds a slash to the end of a file or directory path
21
+ *
22
+ * @param string $path A path
23
+ *
24
+ * @return string The orginal $path with a with '/'.
25
+ */
26
+ public static function add_slash($path)
27
+ {
28
+ $last_char = substr($path, strlen($path) - 1, 1);
29
+ if ($last_char != '/') {
30
+ $path .= '/';
31
+ }
32
+ return $path;
33
+ }
34
+
35
+ /**
36
+ * A safe method used to copy larger files
37
+ *
38
+ * @param string $source The path to the file being copied
39
+ * @param string $destination The path to the file being made
40
+ */
41
+ public static function copy_file($source, $destination)
42
+ {
43
+ $sp = fopen($source, 'r');
44
+ $op = fopen($destination, 'w');
45
+
46
+ while (!feof($sp)) {
47
+ $buffer = fread($sp, 512); // use a buffer of 512 bytes
48
+ fwrite($op, $buffer);
49
+ }
50
+ // close handles
51
+ fclose($op);
52
+ fclose($sp);
53
+ }
54
+
55
+ /**
56
+ * Return a string with the elapsed time
57
+ *
58
+ * @see get_microtime()
59
+ *
60
+ * @param mixed number $end The final time in the sequence to measure
61
+ * @param mixed number $start The start time in the sequence to measure
62
+ *
63
+ * @return string The time elapsed from $start to $end
64
+ */
65
+ public static function elapsed_time($end, $start)
66
+ {
67
+ return sprintf("%.4f sec.", abs($end - $start));
68
+ }
69
+
70
+ /**
71
+ * Convert all applicable characters to HTML entities
72
+ *
73
+ * @param string $string String that needs conversion
74
+ * @param bool $echo Echo or return as a variable
75
+ *
76
+ * @return string Escaped string.
77
+ */
78
+ public static function esc_html_attr($string = '', $echo = false)
79
+ {
80
+ $output = htmlentities($string, ENT_QUOTES, 'UTF-8');
81
+ if ($echo) {
82
+ echo $output;
83
+ } else {
84
+ return $output;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Returns 256 spaces
90
+ *
91
+ * PHP_SAPI for fcgi requires a data flush of at least 256
92
+ * bytes every 40 seconds or else it forces a script hault
93
+ *
94
+ * @return string A series of 256 spaces ' '
95
+ */
96
+ public static function fcgi_flush()
97
+ {
98
+ echo(str_repeat(' ', 256));
99
+ @flush();
100
+ }
101
+
102
+ /**
103
+ * Get current microtime as a float. Method is used for simple profiling
104
+ *
105
+ * @see elapsed_time
106
+ *
107
+ * @return string A float in the form "msec sec", where sec is the number of seconds since the Unix epoch
108
+ */
109
+ public static function get_microtime()
110
+ {
111
+ return microtime(true);
112
+ }
113
+
114
+ /**
115
+ * Returns the active plugins for the WordPress website in the package
116
+ *
117
+ * @param obj $dbh A database connection handle
118
+ * @return array $list A list of active plugins
119
+ */
120
+ public static function get_active_plugins($dbh)
121
+ {
122
+ $query = @mysqli_query($dbh, "SELECT option_value FROM `{$GLOBALS['FW_TABLEPREFIX']}options` WHERE option_name = 'active_plugins' ");
123
+ if ($query) {
124
+ $row = @mysqli_fetch_array($query);
125
+ $all_plugins = unserialize($row[0]);
126
+ if (is_array($all_plugins)) {
127
+ return $all_plugins;
128
+ }
129
+ }
130
+ return array();
131
+ }
132
+
133
+ /**
134
+ * Returns an array of zip files found in the current executing directory
135
+ *
136
+ * @return array of zip files
137
+ */
138
+ public static function get_zip_files()
139
+ {
140
+ $files = array();
141
+ foreach (glob("*.zip") as $name) {
142
+ if (file_exists($name)) {
143
+ $files[] = $name;
144
+ }
145
+ }
146
+
147
+ if (count($files) > 0) {
148
+ return $files;
149
+ }
150
+
151
+ //FALL BACK: Windows XP has bug with glob,
152
+ //add secondary check for PHP lameness
153
+ if ($dh = opendir('.')) {
154
+ while (false !== ($name = readdir($dh))) {
155
+ $ext = substr($name, strrpos($name, '.') + 1);
156
+ if (in_array($ext, array("zip"))) {
157
+ $files[] = $name;
158
+ }
159
+ }
160
+ closedir($dh);
161
+ }
162
+
163
+ return $files;
164
+ }
165
+
166
+ /**
167
+ * Check to see if the internet is accessable
168
+ *
169
+ * Note: fsocketopen on windows doesn't seem to honor $timeout setting.
170
+ *
171
+ * @param string $url A url e.g without prefix "ajax.googleapis.com"
172
+ * @param string $port A valid port number
173
+ *
174
+ * @return bool
175
+ */
176
+ public static function is_url_active($url, $port, $timeout = 5)
177
+ {
178
+ if (function_exists('fsockopen')) {
179
+ @ini_set("default_socket_timeout", 5);
180
+ $port = isset($port) && is_integer($port) ? $port : 80;
181
+ $connected = @fsockopen($url, $port, $errno, $errstr, $timeout); //website and port
182
+ if ($connected) {
183
+ @fclose($connected);
184
+ return true;
185
+ }
186
+ return false;
187
+ } else {
188
+ return false;
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Does a string have non ascii characters
194
+ *
195
+ * @param string $string Any string blob
196
+ *
197
+ * @return bool Returns true if any non ascii character is found in the blob
198
+ *
199
+ */
200
+ public static function is_non_ascii($string)
201
+ {
202
+ return preg_match('/[^\x20-\x7f]/', $string);
203
+ }
204
+
205
+
206
+ /**
207
+ * The characters that are special in the replacement value of preg_replace are not the
208
+ * same characters that are special in the pattern. Allows for '$' to be safely passed.
209
+ *
210
+ * @param string $str The string to replace on
211
+ */
212
+ public static function preg_replacement_quote($str)
213
+ {
214
+ return preg_replace('/(\$|\\\\)(?=\d)/', '\\\\\1', $str);
215
+ }
216
+
217
+ /**
218
+ * Display human readable byte sizes
219
+ *
220
+ * @param string $size The size in bytes
221
+ *
222
+ * @return string Human readable bytes such as 50MB, 1GB
223
+ */
224
+ public static function readable_bytesize($size)
225
+ {
226
+ try {
227
+ $units = array('B', 'KB', 'MB', 'GB', 'TB');
228
+ for ($i = 0; $size >= 1024 && $i < 4; $i++)
229
+ $size /= 1024;
230
+ return round($size, 2).$units[$i];
231
+ } catch (Exception $e) {
232
+ return "n/a";
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Converts shorthand memory notation value to bytes
238
+ *
239
+ * @param $val Memory size shorthand notation string such as 10M, 1G
240
+ *
241
+ * @returns int The byte representation of the shortand $val
242
+ */
243
+ public static function return_bytes($val)
244
+ {
245
+ $val = trim($val);
246
+ $last = strtolower($val[strlen($val) - 1]);
247
+ switch ($last) {
248
+ // The 'G' modifier is available since PHP 5.1.0
249
+ case 'g':
250
+ $val *= 1024;
251
+ case 'm':
252
+ $val *= 1024;
253
+ case 'k':
254
+ $val *= 1024;
255
+ break;
256
+ default :
257
+ $val = null;
258
+ }
259
+ return $val;
260
+ }
261
+
262
+ /**
263
+ * Makes path safe for any OS for PHP
264
+ *
265
+ * Paths should ALWAYS READ be "/"
266
+ * uni: /home/path/file.xt
267
+ * win: D:/home/path/file.txt
268
+ *
269
+ * @param string $path The path to make safe
270
+ *
271
+ * @return string The orginal $path with a with all slashes facing '/'.
272
+ */
273
+ public static function set_safe_path($path)
274
+ {
275
+ return str_replace("\\", "/", $path);
276
+ }
277
+
278
+ /**
279
+ * Looks for a list of strings in a string and returns each list item that is found
280
+ *
281
+ * @param array $list An array of strings to search for
282
+ * @param string $haystack The string blob to search through
283
+ *
284
+ * @return array An array of strings from the $list array fround in the $haystack
285
+ */
286
+ public static function search_list_values($list, $haystack)
287
+ {
288
+ $found = array();
289
+ foreach ($list as $var) {
290
+ if (strstr($haystack, $var) !== false) {
291
+ array_push($found, $var);
292
+ }
293
+ }
294
+ return $found;
295
+ }
296
+
297
+ /**
298
+ * Makes path unsafe for any OS for PHP used primarly to show default
299
+ * Winodws OS path standard
300
+ *
301
+ * @param string $path The path to make unsafe
302
+ *
303
+ * @return string The orginal $path with a with all slashes facing '\'.
304
+ */
305
+ public static function unset_safe_path($path)
306
+ {
307
+ return str_replace("/", "\\", $path);
308
+ }
309
+
310
+
311
+ }
312
+ ?>
installer/build/main.installer.php CHANGED
@@ -183,15 +183,18 @@ if ($_POST['action_step'] == 1) {
183
  }
184
  ?>
185
 
 
 
 
 
186
  @@CLASS.LOGGING.PHP@@
187
 
188
- @@CLASS.UTILS.PHP@@
189
 
190
  @@CLASS.CONF.WP.PHP@@
191
 
192
  @@CLASS.CONF.SRV.PHP@@
193
 
194
- @@CLASS.SERIALIZER.PHP@@
195
 
196
  <?php
197
  if (isset($_POST['action_ajax'])) {
183
  }
184
  ?>
185
 
186
+ @@CLASS.UTILS.PHP@@
187
+
188
+ @@CLASS.DB.PHP@@
189
+
190
  @@CLASS.LOGGING.PHP@@
191
 
192
+ @@CLASS.ENGINE.PHP@@
193
 
194
  @@CLASS.CONF.WP.PHP@@
195
 
196
  @@CLASS.CONF.SRV.PHP@@
197
 
 
198
 
199
  <?php
200
  if (isset($_POST['action_ajax'])) {
installer/build/view.step2.php CHANGED
@@ -6,9 +6,9 @@
6
  header("Location: $_baseURL");
7
  exit;
8
  }
9
- $dbh = DUPX_Util::db_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname'], $_POST['dbport']);
10
 
11
- $all_tables = DUPX_Util::get_database_tables($dbh);
12
  $active_plugins = DUPX_Util::get_active_plugins($dbh);
13
 
14
 
6
  header("Location: $_baseURL");
7
  exit;
8
  }
9
+ $dbh = DUPX_DB::connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname'], $_POST['dbport']);
10
 
11
+ $all_tables = DUPX_DB::getTables($dbh);
12
  $active_plugins = DUPX_Util::get_active_plugins($dbh);
13
 
14
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: www.lifeinthegrid.com/partner
4
  Tags: backup, restore, move, migrate, localhost, synchronize, duplicate, clone, automate, niche site
5
  Requires at least: 4.0
6
  Tested up to: 4.7
7
- Stable tag: 1.1.32
8
  License: GPLv2
9
 
10
  Duplicate, clone, backup, move and transfer an entire site from one location to another.
4
  Tags: backup, restore, move, migrate, localhost, synchronize, duplicate, clone, automate, niche site
5
  Requires at least: 4.0
6
  Tested up to: 4.7
7
+ Stable tag: 1.1.34
8
  License: GPLv2
9
 
10
  Duplicate, clone, backup, move and transfer an entire site from one location to another.
uninstall.php CHANGED
@@ -8,8 +8,8 @@ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
8
  exit;
9
  }
10
  require_once 'define.php';
11
- require_once 'classes/settings.php';
12
- require_once 'classes/utility.php';
13
 
14
  global $wpdb;
15
  $DUP_Settings = new DUP_Settings();
@@ -22,8 +22,8 @@ delete_option('duplicator_version_plugin');
22
  //Remvoe entire wp-snapshots directory
23
  if (DUP_Settings::Get('uninstall_files')) {
24
 
25
- $ssdir = DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH);
26
- $ssdir_tmp = DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH_TMP);
27
 
28
  //Sanity check for strange setup
29
  $check = glob("{$ssdir}/wp-config.php");
8
  exit;
9
  }
10
  require_once 'define.php';
11
+ require_once 'classes/class.settings.php';
12
+ require_once 'classes/utilities/class.util.php';
13
 
14
  global $wpdb;
15
  $DUP_Settings = new DUP_Settings();
22
  //Remvoe entire wp-snapshots directory
23
  if (DUP_Settings::Get('uninstall_files')) {
24
 
25
+ $ssdir = DUP_Util::safePath(DUPLICATOR_SSDIR_PATH);
26
+ $ssdir_tmp = DUP_Util::safePath(DUPLICATOR_SSDIR_PATH_TMP);
27
 
28
  //Sanity check for strange setup
29
  $check = glob("{$ssdir}/wp-config.php");
views/help/about.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- DUP_Util::CheckPermissions('read');
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
5
  require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
1
  <?php
2
+ DUP_Util::hasCapability('read');
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
5
  require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
views/help/gopro.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- DUP_Util::CheckPermissions('read');
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
5
  require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
1
  <?php
2
+ DUP_Util::hasCapability('read');
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
5
  require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
views/help/help.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- DUP_Util::CheckPermissions('read');
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
5
  require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
1
  <?php
2
+ DUP_Util::hasCapability('read');
3
 
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
5
  require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
views/help/perks.php DELETED
@@ -1,183 +0,0 @@
1
- <?php
2
- DUP_Util::CheckPermissions('read');
3
-
4
- require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
5
- require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
6
- $_GET['a'] = isset($_GET['a']) ? $_GET['a'] : -1;
7
-
8
- ?>
9
- <style>
10
- div.dup-perks-all {font-size:13px; line-height:20px}
11
- div.dup-perks-hlp-area {width:315px; height:160px; float:left; border:1px solid #dfdfdf; border-radius:8px; margin:20px 30px 10px 40px;box-shadow: 0 8px 6px -6px #ccc; background: #fff}
12
- div.dup-perks-hlp-hdrs {
13
- font-weight:bold; font-size:17px; height: 25px; padding:10px 0 5px 0; text-align: center;
14
- background: #eeeeee;
15
- background: -moz-linear-gradient(top, #eeeeee 0%, #cccccc 100%);
16
- background: -webkit-linear-gradient(top, #eeeeee 0%,#cccccc 100%);
17
- background: linear-gradient(to bottom, #eeeeee 0%,#cccccc 100%);
18
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 );
19
- }
20
- div.dup-perks-txt{padding:10px 4px 4px 4px; text-align:center; font-size:16px; font-weight: bold}
21
- div.dup-active-item {font-weight: bold; font-style: italic}
22
- div.dup-active-item div.dup-perks-hlp-hdrs{ color:#fff; border-top-right-radius: 8px; border-top-left-radius: 8px;
23
- background: #4c4c4c;
24
- background: -moz-linear-gradient(top, #4c4c4c 0%, #595959 12%, #666666 25%, #474747 39%, #2c2c2c 50%, #000000 51%, #111111 60%, #2b2b2b 76%, #1c1c1c 91%, #131313 100%);
25
- background: -webkit-linear-gradient(top, #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);
26
- background: linear-gradient(to bottom, #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);
27
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 );
28
- }
29
- </style>
30
-
31
- <div class="wrap dup-wrap dup-perks-all">
32
-
33
- <?php duplicator_header(__("Perks", 'duplicator')) ?>
34
- <hr size="1" />
35
-
36
- <div style="width:800px; margin:auto; margin-top:10px;">
37
- <div style="text-align: center; font-size:18px; line-height: 24px">
38
- <b><?php _e("Get Great Deals and Amazing Products!", 'duplicator'); ?></b><br/>
39
- <i><?php _e("While helping to support Duplicator...", 'duplicator'); ?></i>
40
- </div>
41
-
42
- <!-- ==========================================================
43
- ROW 1 -->
44
- <!-- BLUEHOST -->
45
- <div class="dup-perks-hlp-area" id="bluehost">
46
- <div class="dup-perks-hlp-hdrs">
47
- <i class="fa fa-th fa-1x"></i> <?php _e('Bluehost', 'duplicator') ?>
48
- </div>
49
- <div class="dup-perks-txt">
50
- <a href="https://snapcreek.com/visit/bluehost" target="_blank">
51
- <img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/perks_bluehost.png" style="padding:10px 0 15px 0" /><br/>
52
- <?php _e('50% Off Normal Price!', 'duplicator') ?>
53
- </a>
54
- </div>
55
- </div>
56
-
57
- <!-- INMOTION -->
58
- <div class="dup-perks-hlp-area" id="inmotion">
59
- <div class="dup-perks-hlp-hdrs">
60
- <i class="fa fa-cube fa-1x"></i> <?php _e('InMotion', 'duplicator') ?>
61
- </div>
62
- <div class="dup-perks-txt">
63
- <a href="https://snapcreek.com/visit/inmotion" target="_blank">
64
- <img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/perks_inmotion.png" style="padding:10px 0 5px 0" /><br/>
65
- <?php _e('Up to 25% Off - With FREE SSDs', 'duplicator') ?>
66
- </a>
67
- </div>
68
- </div>
69
-
70
- <!-- ==========================================================
71
- ROW 2 -->
72
- <!-- ELEGANT THEMES -->
73
- <div class="dup-perks-hlp-area" id="ethemes">
74
- <div class="dup-perks-hlp-hdrs">
75
- <i class="fa fa-asterisk fa-1x"></i> <?php _e('Elegant Themes', 'duplicator') ?>
76
- </div>
77
- <div class="dup-perks-txt">
78
- <a href="https://snapcreek.com/visit/elegantthemes" target="_blank">
79
- <img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/perks_ethemes.png" style="padding:0 0 5px 0" /><br/>
80
- <?php _e('10% Off Lifetime Access!', 'duplicator') ?>
81
- </a>
82
- </div>
83
- </div>
84
-
85
- <!-- MAX CDN -->
86
- <div class="dup-perks-hlp-area" id="maxcdn">
87
- <div class="dup-perks-hlp-hdrs">
88
- <i class="fa fa-maxcdn fa-1x"></i> <?php _e('MaxCDN', 'duplicator') ?>
89
- </div>
90
- <div class="dup-perks-txt">
91
- <a href="https://snapcreek.com/visit/maxcdn" target="_blank">
92
- <img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/perks_maxcdn.png" style="padding:5px 0 10px 0" /><br/>
93
- <?php _e('Get 25% Off With Duplicator', 'duplicator') ?>
94
- </a>
95
- </div>
96
- </div>
97
-
98
-
99
- <!-- ==========================================================
100
- ROW 3 -->
101
- <!-- MANAGE WP -->
102
- <div class="dup-perks-hlp-area" id="managewp">
103
- <div class="dup-perks-hlp-hdrs">
104
- <i class="fa fa-sitemap fa-1x"></i> <?php _e('ManageWP', 'duplicator') ?>
105
- </div>
106
- <div class="dup-perks-txt">
107
- <a href="https://snapcreek.com/visit/managewp" target="_blank">
108
- <img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/perks_managewp.png" style="padding:5px 0 10px 0" /><br/>
109
- <?php _e('Exclusive 10% Off Deal!', 'duplicator') ?>
110
- </a>
111
- </div>
112
- </div>
113
-
114
- <!-- DUPLICATOR PRO -->
115
- <div class="dup-perks-hlp-area" id="dpro">
116
- <div class="dup-perks-hlp-hdrs">
117
- <i class="fa fa-share-alt fa-1x"></i> <?php _e('Duplicator Pro', 'duplicator') ?>
118
- </div>
119
- <div class="dup-perks-txt">
120
- <a href="https://snapcreek.com/visit/managewp" target="_blank">
121
- <img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/logo-dpro-300x50-nosnap.png" style="padding:10px 0 10px 0; width:250px" /><br/>
122
- <?php _e('Go Professional!', 'duplicator') ?>
123
- </a>
124
- </div>
125
- </div>
126
-
127
- <!-- ==========================================================
128
- ROW 4 -->
129
- <!-- NINJA FORMS
130
- <div class="dup-perks-hlp-area">
131
- <div class="dup-perks-hlp-hdrs">
132
- <i class="fa fa-check-square-o fa-1x"></i> <?php _e('Ninja Forms', 'duplicator') ?>
133
- </div>
134
- <div class="dup-perks-txt">
135
- <a href="https://snapcreek.com/visit/ninjaforms" target="_blank">
136
- <img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/perks_ninjaforms.png" style="padding:5px 0 10px 0; " /><br/>
137
- <?php _e('Power Manage It All!', 'duplicator') ?>
138
- </a>
139
- </div>
140
- </div> -->
141
-
142
- <!-- OPTIN MONSTER
143
- <div class="dup-perks-hlp-area">
144
- <div class="dup-perks-hlp-hdrs">
145
- <i class="fa fa-envelope fa-1x"></i> <?php _e('OptinMonster', 'duplicator') ?>
146
- </div>
147
- <div class="dup-perks-txt">
148
- <a href="https://snapcreek.com/visit/managewp" target="_blank">
149
- <img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/perks_optinmonster.png" style="padding:5px 0 10px 0" /><br/>
150
- <?php _e('Power Manage It All!', 'duplicator') ?>
151
- </a>
152
- </div>
153
- </div> -->
154
-
155
- <br style="clear:both"/>
156
-
157
- <div style="margin:60px 20px; text-align: center"><small>Some promotions may change</small></div>
158
-
159
- </div>
160
- </div>
161
- <br/><br/><br/><br/>
162
-
163
- <script type="text/javascript">
164
- jQuery(document).ready(function($)
165
- {
166
- //ATTACHED EVENTS
167
- jQuery('#dup-perks-kb-lnks').change(function() {
168
- if (jQuery(this).val() != "null")
169
- window.open(jQuery(this).val())
170
- });
171
-
172
- <?php
173
- switch ($_GET['a'])
174
- {
175
- case "0" : echo "$('#bluehost').addClass('dup-active-item');"; break;
176
- case "1" : echo "$('#inmotion').addClass('dup-active-item');"; break;
177
- case "2" : echo "$('#ethemes').addClass('dup-active-item');"; break;
178
- case "3" : echo "$('#managewp').addClass('dup-active-item');"; break;
179
- case "4" : echo "$('#maxcdn').addClass('dup-active-item');"; break;
180
- }
181
- ?>
182
- });
183
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
views/packages/controller.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- DUP_Util::CheckPermissions('export');
4
 
5
  global $wpdb;
6
 
1
  <?php
2
 
3
+ DUP_Util::hasCapability('export');
4
 
5
  global $wpdb;
6
 
views/packages/details/controller.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php
2
- DUP_Util::CheckPermissions('manage_options');
3
  global $wpdb;
4
 
5
  //COMMON HEADER DISPLAY
6
  $current_tab = isset($_REQUEST['tab']) ? esc_html($_REQUEST['tab']) : 'detail';
7
  $package_id = isset($_REQUEST["id"]) ? $_REQUEST["id"] : 0;
8
 
9
- $package = DUP_Package::GetByID($package_id);
10
  $err_found = ($package == null || $package->Status < 100);
11
  $link_log = "{$package->StoreURL}{$package->NameHash}.log";
12
  $err_link_log = "<a target='_blank' href='{$link_log}' >" . __('package log', 'duplicator') . '</a>';
1
  <?php
2
+ DUP_Util::hasCapability('manage_options');
3
  global $wpdb;
4
 
5
  //COMMON HEADER DISPLAY
6
  $current_tab = isset($_REQUEST['tab']) ? esc_html($_REQUEST['tab']) : 'detail';
7
  $package_id = isset($_REQUEST["id"]) ? $_REQUEST["id"] : 0;
8
 
9
+ $package = DUP_Package::getByID($package_id);
10
  $err_found = ($package == null || $package->Status < 100);
11
  $link_log = "{$package->StoreURL}{$package->NameHash}.log";
12
  $err_link_log = "<a target='_blank' href='{$link_log}' >" . __('package log', 'duplicator') . '</a>';
views/packages/details/detail.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- $view_state = DUP_UI::GetViewStateArray();
3
  $ui_css_general = (isset($view_state['dup-package-dtl-general-panel']) && $view_state['dup-package-dtl-general-panel']) ? 'display:block' : 'display:none';
4
  $ui_css_storage = (isset($view_state['dup-package-dtl-storage-panel']) && $view_state['dup-package-dtl-storage-panel']) ? 'display:block' : 'display:none';
5
  $ui_css_archive = (isset($view_state['dup-package-dtl-archive-panel']) && $view_state['dup-package-dtl-archive-panel']) ? 'display:block' : 'display:none';
@@ -12,7 +12,7 @@ $link_log = "{$package->StoreURL}{$package->NameHash}.log";
12
  $link_scan = "{$package->StoreURL}{$package->NameHash}_scan.json";
13
 
14
  $debug_on = DUP_Settings::Get('package_debug');
15
- $mysqldump_on = DUP_Settings::Get('package_mysqldump') && DUP_Database::GetMySqlDumpPath();
16
  $mysqlcompat_on = isset($Package->Database->Compatible) && strlen($Package->Database->Compatible);
17
  $mysqlcompat_on = ($mysqldump_on && $mysqlcompat_on) ? true : false;
18
  $dbbuild_mode = ($mysqldump_on) ? 'mysqldump (fast)' : 'PHP (slow)';
@@ -84,8 +84,10 @@ GENERAL -->
84
  <a href="javascript:void(0);" onclick="jQuery('#dup-version-info').toggle()"><?php echo $package->Version ?></a>
85
  <div id="dup-version-info">
86
  <b><?php _e('WordPress', 'duplicator') ?>:</b> <?php echo strlen($package->VersionWP) ? $package->VersionWP : __('- unknown -', 'duplicator') ?><br/>
87
- <b><?php _e('Mysql', 'duplicator') ?>:</b> <?php echo strlen($package->VersionDB) ? $package->VersionDB : __('- unknown -', 'duplicator') ?><br/>
88
  <b><?php _e('PHP', 'duplicator') ?>:</b> <?php echo strlen($package->VersionPHP) ? $package->VersionPHP : __('- unknown -', 'duplicator') ?><br/>
 
 
 
89
  </div>
90
  </td>
91
  </tr>
@@ -109,7 +111,7 @@ GENERAL -->
109
 
110
  <button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_installer; ?>', this);return false;"><i class="fa fa-bolt"></i> Installer</button>
111
  <button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_archive; ?>', this);return false;"><i class="fa fa-file-archive-o"></i> Archive - <?php echo $package->ZipSize ?></button>
112
- <button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_sql; ?>', this);return false;"><i class="fa fa-table"></i> &nbsp; SQL - <?php echo DUP_Util::ByteSize($package->Database->Size) ?></button>
113
  <button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_log; ?>', this);return false;"><i class="fa fa-list-alt"></i> &nbsp; Log </button>
114
  <button class="button" onclick="Duplicator.Pack.ShowLinksDialog(<?php echo "'{$link_sql}','{$link_archive}','{$link_installer}','{$link_log}'" ;?>);" class="thickbox"><i class="fa fa-lock"></i> &nbsp; <?php _e("Share", 'duplicator')?></button>
115
  <?php else: ?>
1
  <?php
2
+ $view_state = DUP_UI_ViewState::getArray();
3
  $ui_css_general = (isset($view_state['dup-package-dtl-general-panel']) && $view_state['dup-package-dtl-general-panel']) ? 'display:block' : 'display:none';
4
  $ui_css_storage = (isset($view_state['dup-package-dtl-storage-panel']) && $view_state['dup-package-dtl-storage-panel']) ? 'display:block' : 'display:none';
5
  $ui_css_archive = (isset($view_state['dup-package-dtl-archive-panel']) && $view_state['dup-package-dtl-archive-panel']) ? 'display:block' : 'display:none';
12
  $link_scan = "{$package->StoreURL}{$package->NameHash}_scan.json";
13
 
14
  $debug_on = DUP_Settings::Get('package_debug');
15
+ $mysqldump_on = DUP_Settings::Get('package_mysqldump') && DUP_DB::getMySqlDumpPath();
16
  $mysqlcompat_on = isset($Package->Database->Compatible) && strlen($Package->Database->Compatible);
17
  $mysqlcompat_on = ($mysqldump_on && $mysqlcompat_on) ? true : false;
18
  $dbbuild_mode = ($mysqldump_on) ? 'mysqldump (fast)' : 'PHP (slow)';
84
  <a href="javascript:void(0);" onclick="jQuery('#dup-version-info').toggle()"><?php echo $package->Version ?></a>
85
  <div id="dup-version-info">
86
  <b><?php _e('WordPress', 'duplicator') ?>:</b> <?php echo strlen($package->VersionWP) ? $package->VersionWP : __('- unknown -', 'duplicator') ?><br/>
 
87
  <b><?php _e('PHP', 'duplicator') ?>:</b> <?php echo strlen($package->VersionPHP) ? $package->VersionPHP : __('- unknown -', 'duplicator') ?><br/>
88
+ <b><?php _e('Mysql', 'duplicator') ?>:</b>
89
+ <?php echo strlen($package->VersionDB) ? $package->VersionDB : __('- unknown -', 'duplicator') ?> |
90
+ <?php echo strlen($package->Database->Comments) ? $package->Database->Comments : __('- unknown -', 'duplicator') ?><br/>
91
  </div>
92
  </td>
93
  </tr>
111
 
112
  <button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_installer; ?>', this);return false;"><i class="fa fa-bolt"></i> Installer</button>
113
  <button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_archive; ?>', this);return false;"><i class="fa fa-file-archive-o"></i> Archive - <?php echo $package->ZipSize ?></button>
114
+ <button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_sql; ?>', this);return false;"><i class="fa fa-table"></i> &nbsp; SQL - <?php echo DUP_Util::byteSize($package->Database->Size) ?></button>
115
  <button class="button" onclick="Duplicator.Pack.DownloadFile('<?php echo $link_log; ?>', this);return false;"><i class="fa fa-list-alt"></i> &nbsp; Log </button>
116
  <button class="button" onclick="Duplicator.Pack.ShowLinksDialog(<?php echo "'{$link_sql}','{$link_archive}','{$link_installer}','{$link_log}'" ;?>);" class="thickbox"><i class="fa fa-lock"></i> &nbsp; <?php _e("Share", 'duplicator')?></button>
117
  <?php else: ?>
views/packages/main/controller.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.dialog.php');
3
  $current_tab = isset($_REQUEST['tab']) ? esc_html($_REQUEST['tab']) : 'list';
4
  ?>
5
 
1
  <?php
2
+ require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.dialog.php');
3
  $current_tab = isset($_REQUEST['tab']) ? esc_html($_REQUEST['tab']) : 'list';
4
  ?>
5
 
views/packages/main/new1.inc.form.php CHANGED
@@ -131,7 +131,7 @@ ARCHIVE -->
131
  <!-- FILTERS -->
132
  <?php
133
  $uploads = wp_upload_dir();
134
- $upload_dir = DUP_Util::SafePath($uploads['basedir']);
135
  ?>
136
  <div class="dup-enable-filters">
137
  <input type="checkbox" id="filter-on" name="filter-on" onclick="Duplicator.Pack.ToggleFileFilters()" <?php echo ($Package->Archive->FilterOn) ? "checked='checked'" :""; ?> />
@@ -148,7 +148,7 @@ ARCHIVE -->
148
  <div class='dup-quick-links'>
149
  <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo rtrim(DUPLICATOR_WPROOTPATH, '/'); ?>')">[<?php _e("root path", 'duplicator') ?>]</a>
150
  <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo rtrim($upload_dir, '/'); ?>')">[<?php _e("wp-uploads", 'duplicator') ?>]</a>
151
- <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo DUP_Util::SafePath(WP_CONTENT_DIR); ?>/cache')">[<?php _e("cache", 'duplicator') ?>]</a>
152
  <a href="javascript:void(0)" onclick="jQuery('#filter-dirs').val('')"><?php _e("(clear)", 'duplicator') ?></a>
153
  </div>
154
  <textarea name="filter-dirs" id="filter-dirs" placeholder="/full_path/exclude_path1;/full_path/exclude_path2;"><?php echo str_replace(";", ";\n", esc_textarea($Package->Archive->FilterDirs)) ?></textarea><br/>
@@ -362,7 +362,7 @@ INSTALLER -->
362
  <div style="padding:10px 0 0 12px;">
363
  <span class="dup-pro-text">
364
  <img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/cpanel-48.png" style="width:16px; height:12px" />
365
- <?php _e("Connect to a cPanel database with.", 'duplicator'); ?>
366
  <a href="https://snapcreek.com/duplicator/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=free_cpanel&utm_campaign=duplicator_pro" target="_blank"><?php _e('Professional', 'duplicator');?></a>
367
  <i class="fa fa-lightbulb-o"
368
  data-tooltip-title="<?php _e("cPanel Access:", 'duplicator'); ?>"
@@ -386,11 +386,11 @@ INSTALLER -->
386
  THICK-BOX DIALOGS: -->
387
  <?php
388
 
389
- $confirm1 = new DUP_Dialog();
390
  $confirm1->title = __('Reset Package Settings?', 'duplicator');
391
  $confirm1->message = __('This will clear and reset all of the current package settings. Would you like to continue?', 'duplicator');
392
  $confirm1->jscallback = 'Duplicator.Pack.ResetSettings()';
393
- $confirm1->init_confirm();
394
  ?>
395
  <script>
396
  jQuery(document).ready(function ($)
@@ -445,7 +445,7 @@ jQuery(document).ready(function ($)
445
 
446
  Duplicator.Pack.ConfirmReset = function ()
447
  {
448
- <?php $confirm1->show_confirm(); ?>
449
  }
450
 
451
  Duplicator.Pack.ResetSettings = function ()
131
  <!-- FILTERS -->
132
  <?php
133
  $uploads = wp_upload_dir();
134
+ $upload_dir = DUP_Util::safePath($uploads['basedir']);
135
  ?>
136
  <div class="dup-enable-filters">
137
  <input type="checkbox" id="filter-on" name="filter-on" onclick="Duplicator.Pack.ToggleFileFilters()" <?php echo ($Package->Archive->FilterOn) ? "checked='checked'" :""; ?> />
148
  <div class='dup-quick-links'>
149
  <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo rtrim(DUPLICATOR_WPROOTPATH, '/'); ?>')">[<?php _e("root path", 'duplicator') ?>]</a>
150
  <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo rtrim($upload_dir, '/'); ?>')">[<?php _e("wp-uploads", 'duplicator') ?>]</a>
151
+ <a href="javascript:void(0)" onclick="Duplicator.Pack.AddExcludePath('<?php echo DUP_Util::safePath(WP_CONTENT_DIR); ?>/cache')">[<?php _e("cache", 'duplicator') ?>]</a>
152
  <a href="javascript:void(0)" onclick="jQuery('#filter-dirs').val('')"><?php _e("(clear)", 'duplicator') ?></a>
153
  </div>
154
  <textarea name="filter-dirs" id="filter-dirs" placeholder="/full_path/exclude_path1;/full_path/exclude_path2;"><?php echo str_replace(";", ";\n", esc_textarea($Package->Archive->FilterDirs)) ?></textarea><br/>
362
  <div style="padding:10px 0 0 12px;">
363
  <span class="dup-pro-text">
364
  <img src="<?php echo DUPLICATOR_PLUGIN_URL ?>assets/img/cpanel-48.png" style="width:16px; height:12px" />
365
+ <?php _e("Create the database and user directly from the installer with ", 'duplicator'); ?>
366
  <a href="https://snapcreek.com/duplicator/?utm_source=duplicator_free&utm_medium=wordpress_plugin&utm_content=free_cpanel&utm_campaign=duplicator_pro" target="_blank"><?php _e('Professional', 'duplicator');?></a>
367
  <i class="fa fa-lightbulb-o"
368
  data-tooltip-title="<?php _e("cPanel Access:", 'duplicator'); ?>"
386
  THICK-BOX DIALOGS: -->
387
  <?php
388
 
389
+ $confirm1 = new DUP_UI_Dialog();
390
  $confirm1->title = __('Reset Package Settings?', 'duplicator');
391
  $confirm1->message = __('This will clear and reset all of the current package settings. Would you like to continue?', 'duplicator');
392
  $confirm1->jscallback = 'Duplicator.Pack.ResetSettings()';
393
+ $confirm1->initConfirm();
394
  ?>
395
  <script>
396
  jQuery(document).ready(function ($)
445
 
446
  Duplicator.Pack.ConfirmReset = function ()
447
  {
448
+ <?php $confirm1->showConfirm(); ?>
449
  }
450
 
451
  Duplicator.Pack.ResetSettings = function ()
views/packages/main/new1.setup.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
- require_once (DUPLICATOR_PLUGIN_PATH . 'classes/package.php');
3
 
4
  global $wpdb;
5
 
@@ -15,12 +14,12 @@ if (isset($_POST['action']))
15
  }
16
  }
17
 
18
- DUP_Util::InitSnapshotDirectory();
19
 
20
- $Package = DUP_Package::GetActive();
21
  $dup_tests = array();
22
- $dup_tests = DUP_Server::GetRequirements();
23
- $default_name = DUP_Package::GetDefaultName();
24
 
25
  //View State
26
  $ctrl_ui = new DUP_CTRL_UI();
@@ -30,8 +29,8 @@ $data = $ctrl_ui->GetViewStateList();
30
  $ui_css_storage = (isset($data->Payload['dup-pack-storage-panel']) && $data->Payload['dup-pack-storage-panel']) ? 'display:block' : 'display:none';
31
  $ui_css_archive = (isset($data->Payload['dup-pack-archive-panel']) && $data->Payload['dup-pack-archive-panel']) ? 'display:block' : 'display:none';
32
  $ui_css_installer = (isset($data->Payload['dup-pack-installer-panel']) && $data->Payload['dup-pack-installer-panel']) ? 'display:block' : 'display:none';
33
- $dup_intaller_files = implode(", ", array_keys(DUP_Server::GetInstallerFiles()));
34
- $dbbuild_mode = (DUP_Settings::Get('package_mysqldump') && DUP_Database::GetMySqlDumpPath()) ? 'mysqldump' : 'PHP';
35
 
36
  ?>
37
 
@@ -165,7 +164,7 @@ SYSTEM REQUIREMENTS -->
165
  <div class="dup-sys-info dup-info-box">
166
  <table class="dup-sys-info-results">
167
  <tr>
168
- <td><?php printf("%s [%s]", __("MySQL Version", 'duplicator'), $wpdb->db_version()); ?></td>
169
  <td><?php echo $dup_tests['SRV']['MYSQL_VER'] ?></td>
170
  </tr>
171
  <tr>
@@ -175,7 +174,7 @@ SYSTEM REQUIREMENTS -->
175
  </table>
176
  <small>
177
  <?php
178
- _e("MySQL version 5.0+ or better is required and the PHP MySQLi extension (note the trailing 'i') is also required. Contact your server administrator and request that mysqli extension and MySQL Server 5.0+ be installed. Please note in future versions support for other databases and extensions will be added.", 'duplicator');
179
  echo "&nbsp;<i><a href='http://php.net/manual/en/mysqli.installation.php' target='_blank'>[" . __('more info', 'duplicator') . "]</a></i>";
180
  ?>
181
  </small>
1
  <?php
 
2
 
3
  global $wpdb;
4
 
14
  }
15
  }
16
 
17
+ DUP_Util::initSnapshotDirectory();
18
 
19
+ $Package = DUP_Package::getActive();
20
  $dup_tests = array();
21
+ $dup_tests = DUP_Server::getRequirements();
22
+ $default_name = DUP_Package::getDefaultName();
23
 
24
  //View State
25
  $ctrl_ui = new DUP_CTRL_UI();
29
  $ui_css_storage = (isset($data->Payload['dup-pack-storage-panel']) && $data->Payload['dup-pack-storage-panel']) ? 'display:block' : 'display:none';
30
  $ui_css_archive = (isset($data->Payload['dup-pack-archive-panel']) && $data->Payload['dup-pack-archive-panel']) ? 'display:block' : 'display:none';
31
  $ui_css_installer = (isset($data->Payload['dup-pack-installer-panel']) && $data->Payload['dup-pack-installer-panel']) ? 'display:block' : 'display:none';
32
+ $dup_intaller_files = implode(", ", array_keys(DUP_Server::getInstallerFiles()));
33
+ $dbbuild_mode = (DUP_Settings::Get('package_mysqldump') && DUP_DB::getMySqlDumpPath()) ? 'mysqldump' : 'PHP';
34
 
35
  ?>
36
 
164
  <div class="dup-sys-info dup-info-box">
165
  <table class="dup-sys-info-results">
166
  <tr>
167
+ <td><?php printf("%s [%s]", __("MySQL Version", 'duplicator'), DUP_DB::getVersion()); ?></td>
168
  <td><?php echo $dup_tests['SRV']['MYSQL_VER'] ?></td>
169
  </tr>
170
  <tr>
174
  </table>
175
  <small>
176
  <?php
177
+ _e("MySQL version 5.0+ or better is required and the PHP MySQLi extension (note the trailing 'i') is also required. Contact your server administrator and request that mysqli extension and MySQL Server 5.0+ be installed.", 'duplicator');
178
  echo "&nbsp;<i><a href='http://php.net/manual/en/mysqli.installation.php' target='_blank'>[" . __('more info', 'duplicator') . "]</a></i>";
179
  ?>
180
  </small>
views/packages/main/new2.scan.php CHANGED
@@ -1,6 +1,4 @@
1
  <?php
2
- require_once (DUPLICATOR_PLUGIN_PATH . 'classes/package.php');
3
- require_once (DUPLICATOR_PLUGIN_PATH . 'classes/utility.php');
4
 
5
  if(empty($_POST))
6
  {
@@ -19,15 +17,15 @@
19
  die('Unauthorized');
20
  }
21
 
22
- $Package->SaveActive($_POST);
23
- $Package = DUP_Package::GetActive();
24
 
25
- $mysqldump_on = DUP_Settings::Get('package_mysqldump') && DUP_Database::GetMySqlDumpPath();
26
  $mysqlcompat_on = isset($Package->Database->Compatible) && strlen($Package->Database->Compatible);
27
  $mysqlcompat_on = ($mysqldump_on && $mysqlcompat_on) ? true : false;
28
  $dbbuild_mode = ($mysqldump_on) ? 'mysqldump (fast)' : 'PHP (slow)';
29
 
30
- $zip_check = DUP_Util::GetZipPath();
31
  ?>
32
 
33
  <style>
@@ -223,12 +221,12 @@ TOOL BAR: STEPS -->
223
  echo '</small>';
224
 
225
  //CACHE DIR
226
- $cache_path = $cache_path = DUP_Util::SafePath(WP_CONTENT_DIR) . '/cache';
227
- $cache_size = DUP_Util::ByteSize(DUP_Util::GetDirectorySize($cache_path));
228
  echo '<hr size="1" /><span id="data-srv-wp-cache"></span>&nbsp;<b>' . __('Cache Path', 'duplicator') . ":</b>&nbsp; '{$cache_path}' ({$cache_size}) <br/>";
229
  echo '<small>';
230
  _e("Cached data will lead to issues at install time and increases your archive size. It is recommended to empty your cache directory at build time. Use caution when removing data from the cache directory. If you have a cache plugin review the documentation for how to empty it; simply removing files might cause errors on your site. The cache size minimum threshold is currently set at ", 'duplicator');
231
- echo DUP_Util::ByteSize(DUPLICATOR_SCAN_CACHESIZE) . '.';
232
  echo '</small>';
233
 
234
  //MU SITE
@@ -291,8 +289,8 @@ TOOL BAR: STEPS -->
291
  <small>
292
  <?php
293
  printf(__('Total size represents all files minus any filters that have been setup. The current thresholds that triggers a warning is %1$s for the total size. Some budget hosts limit the amount of time a PHP/Web request process can run. When working with larger sites this can cause timeout issues. Consider using a file filter in step 1 to shrink and filter the overall size of your package.', 'duplicator'),
294
- DUP_Util::ByteSize(DUPLICATOR_SCAN_SITE),
295
- DUP_Util::ByteSize(DUPLICATOR_SCAN_WARNFILESIZE));
296
 
297
  if ($zip_check != null) {
298
  echo '<br/><br/>';
@@ -334,7 +332,7 @@ TOOL BAR: STEPS -->
334
  <small>
335
  <?php
336
  printf(__('Large files such as movies or other backuped data can cause issues with timeouts. The current check for large files is %1$s per file. If your having issues creating a package consider excluding these files with the files filter and manually moving them to your new location.', 'duplicator'),
337
- DUP_Util::ByteSize(DUPLICATOR_SCAN_WARNFILESIZE));
338
  ?>
339
  </small><br/>
340
  <a href="javascript:void(0)" onclick="jQuery('#data-arc-big-data').toggle()">[<?php _e('Show Paths', 'duplicator');?>]</a>
@@ -420,7 +418,7 @@ TOOL BAR: STEPS -->
420
  //OVERVIEW
421
  echo '<b>' . __('Overview:', 'duplicator') . '</b><br/>';
422
  printf(__('Total size and row count for all database tables are approximate values. The thresholds that trigger warnings are %1$s OR %2$s records total for the entire database. The larger the databases the more time it takes to process and execute. This can cause issues with budget hosts that have cpu/memory limits, and timeout constraints.', 'duplicator'),
423
- DUP_Util::ByteSize(DUPLICATOR_SCAN_DB_ALL_SIZE),
424
  number_format(DUPLICATOR_SCAN_DB_ALL_ROWS));
425
 
426
  //OPTIONS
@@ -450,7 +448,7 @@ TOOL BAR: STEPS -->
450
  //OVERVIEW
451
  echo '<b>' . __('Overview:', 'duplicator') . '</b><br/>';
452
  printf(__('The thresholds that trigger warnings for individual tables are %1$s OR %2$s records OR tables names with upper-case characters. The larger the table the more time it takes to process and execute. This can cause issues with budget hosts that have cpu/memory limits, and timeout constraints.', 'duplicator'),
453
- DUP_Util::ByteSize(DUPLICATOR_SCAN_DB_TBL_SIZE),
454
  number_format(DUPLICATOR_SCAN_DB_TBL_ROWS));
455
 
456
  //OPTIONS
1
  <?php
 
 
2
 
3
  if(empty($_POST))
4
  {
17
  die('Unauthorized');
18
  }
19
 
20
+ $Package->saveActive($_POST);
21
+ $Package = DUP_Package::getActive();
22
 
23
+ $mysqldump_on = DUP_Settings::Get('package_mysqldump') && DUP_DB::getMySqlDumpPath();
24
  $mysqlcompat_on = isset($Package->Database->Compatible) && strlen($Package->Database->Compatible);
25
  $mysqlcompat_on = ($mysqldump_on && $mysqlcompat_on) ? true : false;
26
  $dbbuild_mode = ($mysqldump_on) ? 'mysqldump (fast)' : 'PHP (slow)';
27
 
28
+ $zip_check = DUP_Util::getZipPath();
29
  ?>
30
 
31
  <style>
221
  echo '</small>';
222
 
223
  //CACHE DIR
224
+ $cache_path = $cache_path = DUP_Util::safePath(WP_CONTENT_DIR) . '/cache';
225
+ $cache_size = DUP_Util::byteSize(DUP_Util::getDirectorySize($cache_path));
226
  echo '<hr size="1" /><span id="data-srv-wp-cache"></span>&nbsp;<b>' . __('Cache Path', 'duplicator') . ":</b>&nbsp; '{$cache_path}' ({$cache_size}) <br/>";
227
  echo '<small>';
228
  _e("Cached data will lead to issues at install time and increases your archive size. It is recommended to empty your cache directory at build time. Use caution when removing data from the cache directory. If you have a cache plugin review the documentation for how to empty it; simply removing files might cause errors on your site. The cache size minimum threshold is currently set at ", 'duplicator');
229
+ echo DUP_Util::byteSize(DUPLICATOR_SCAN_CACHESIZE) . '.';
230
  echo '</small>';
231
 
232
  //MU SITE
289
  <small>
290
  <?php
291
  printf(__('Total size represents all files minus any filters that have been setup. The current thresholds that triggers a warning is %1$s for the total size. Some budget hosts limit the amount of time a PHP/Web request process can run. When working with larger sites this can cause timeout issues. Consider using a file filter in step 1 to shrink and filter the overall size of your package.', 'duplicator'),
292
+ DUP_Util::byteSize(DUPLICATOR_SCAN_SITE),
293
+ DUP_Util::byteSize(DUPLICATOR_SCAN_WARNFILESIZE));
294
 
295
  if ($zip_check != null) {
296
  echo '<br/><br/>';
332
  <small>
333
  <?php
334
  printf(__('Large files such as movies or other backuped data can cause issues with timeouts. The current check for large files is %1$s per file. If your having issues creating a package consider excluding these files with the files filter and manually moving them to your new location.', 'duplicator'),
335
+ DUP_Util::byteSize(DUPLICATOR_SCAN_WARNFILESIZE));
336
  ?>
337
  </small><br/>
338
  <a href="javascript:void(0)" onclick="jQuery('#data-arc-big-data').toggle()">[<?php _e('Show Paths', 'duplicator');?>]</a>
418
  //OVERVIEW
419
  echo '<b>' . __('Overview:', 'duplicator') . '</b><br/>';
420
  printf(__('Total size and row count for all database tables are approximate values. The thresholds that trigger warnings are %1$s OR %2$s records total for the entire database. The larger the databases the more time it takes to process and execute. This can cause issues with budget hosts that have cpu/memory limits, and timeout constraints.', 'duplicator'),
421
+ DUP_Util::byteSize(DUPLICATOR_SCAN_DB_ALL_SIZE),
422
  number_format(DUPLICATOR_SCAN_DB_ALL_ROWS));
423
 
424
  //OPTIONS
448
  //OVERVIEW
449
  echo '<b>' . __('Overview:', 'duplicator') . '</b><br/>';
450
  printf(__('The thresholds that trigger warnings for individual tables are %1$s OR %2$s records OR tables names with upper-case characters. The larger the table the more time it takes to process and execute. This can cause issues with budget hosts that have cpu/memory limits, and timeout constraints.', 'duplicator'),
451
+ DUP_Util::byteSize(DUPLICATOR_SCAN_DB_TBL_SIZE),
452
  number_format(DUPLICATOR_SCAN_DB_TBL_ROWS));
453
 
454
  //OPTIONS
views/packages/main/new3.build.php CHANGED
@@ -1,6 +1,5 @@
1
  <?php
2
- require_once (DUPLICATOR_PLUGIN_PATH . 'classes/package.php');
3
- $Package = DUP_Package::GetActive();
4
  $ajax_nonce = wp_create_nonce('dup_package_build');
5
 
6
  ?>
1
  <?php
2
+ $Package = DUP_Package::getActive();
 
3
  $ajax_nonce = wp_create_nonce('dup_package_build');
4
 
5
  ?>
views/packages/main/packages.php CHANGED
@@ -131,8 +131,8 @@ TOOL-BAR -->
131
  <?php if ($row['status'] >= 100) : ?>
132
  <tr class="dup-pack-info <?php echo $css_alt ?>">
133
  <td class="pass"><input name="delete_confirm" type="checkbox" id="<?php echo $row['id'] ;?>" /></td>
134
- <td><?php echo DUP_Package::FormatCreatedDate($row['created'], $ui_create_frmt);?></td>
135
- <td><?php echo DUP_Util::ByteSize($pack_archive_size); ?></td>
136
  <td class='pack-name'><?php echo $pack_name ;?></td>
137
  <td class="get-btns">
138
  <button id="<?php echo "{$uniqueid}_installer.php" ?>" class="button no-select" onclick="Duplicator.Pack.DownloadFile('<?php echo $installfilelink; ?>', this); return false;">
@@ -162,8 +162,8 @@ TOOL-BAR -->
162
  ?>
163
  <tr class="dup-pack-info <?php echo $css_alt ?>">
164
  <td class="fail"><input name="delete_confirm" type="checkbox" id="<?php echo $row['id'] ;?>" /></td>
165
- <td><?php echo DUP_Package::FormatCreatedDate($row['created'], $ui_create_frmt);?></td>
166
- <td><?php echo DUP_Util::ByteSize($size); ?></td>
167
  <td class='pack-name'><?php echo $pack_name ;?></td>
168
  <td class="get-btns error-msg" colspan="2">
169
  <span>
@@ -185,7 +185,7 @@ TOOL-BAR -->
185
  <tr>
186
  <th colspan="11" style='text-align:right; font-size:12px'>
187
  <?php echo _e("Packages", 'duplicator') . ': ' . $totalElements; ?> |
188
- <?php echo _e("Total Size", 'duplicator') . ': ' . DUP_Util::ByteSize($totalSize); ?>
189
  </th>
190
  </tr>
191
  </tfoot>
@@ -196,22 +196,22 @@ TOOL-BAR -->
196
  <!-- ==========================================
197
  THICK-BOX DIALOGS: -->
198
  <?php
199
- $alert1 = new DUP_Dialog();
200
  $alert1->title = __('Bulk Action Required', 'duplicator');
201
  $alert1->message = __('Please select an action from the "Bulk Actions" drop down menu!', 'duplicator');
202
- $alert1->init_alert();
203
 
204
- $alert2 = new DUP_Dialog();
205
  $alert2->title = __('Selection Required', 'duplicator', 'duplicator');
206
  $alert2->message = __('Please select at least one package to delete!', 'duplicator');
207
- $alert2->init_alert();
208
 
209
- $confirm1 = new DUP_Dialog();
210
  $confirm1->title = __('Delete Packages?', 'duplicator');
211
  $confirm1->message = __('Are you sure, you want to delete the selected package(s)?', 'duplicator');
212
- $confirm1->progress_text = __('Removing Packages, Please Wait...', 'duplicator');
213
  $confirm1->jscallback = 'Duplicator.Pack.Delete()';
214
- $confirm1->init_confirm();
215
  ?>
216
 
217
  <script type="text/javascript">
@@ -237,17 +237,17 @@ jQuery(document).ready(function($)
237
  {
238
  if ($("#dup-pack-bulk-actions").val() != "delete")
239
  {
240
- <?php $alert1->show_alert(); ?>
241
  return;
242
  }
243
 
244
  var list = Duplicator.Pack.GetDeleteList();
245
  if (list.length == 0)
246
  {
247
- <?php $alert2->show_alert(); ?>
248
  return;
249
  }
250
- <?php $confirm1->show_confirm(); ?>
251
  }
252
 
253
 
@@ -256,13 +256,13 @@ jQuery(document).ready(function($)
256
  Duplicator.Pack.Delete = function (event)
257
  {
258
  var list = Duplicator.Pack.GetDeleteList();
259
-
260
  $.ajax({
261
  type: "POST",
262
  url: ajaxurl,
263
  dataType: "json",
264
  data: {action : 'duplicator_package_delete', duplicator_delid : list, nonce: '<?php echo $ajax_nonce; ?>' },
265
- success: function(data) {
266
  Duplicator.ReloadWindow(data);
267
  }
268
  });
131
  <?php if ($row['status'] >= 100) : ?>
132
  <tr class="dup-pack-info <?php echo $css_alt ?>">
133
  <td class="pass"><input name="delete_confirm" type="checkbox" id="<?php echo $row['id'] ;?>" /></td>
134
+ <td><?php echo DUP_Package::getCreatedDateFormat($row['created'], $ui_create_frmt);?></td>
135
+ <td><?php echo DUP_Util::byteSize($pack_archive_size); ?></td>
136
  <td class='pack-name'><?php echo $pack_name ;?></td>
137
  <td class="get-btns">
138
  <button id="<?php echo "{$uniqueid}_installer.php" ?>" class="button no-select" onclick="Duplicator.Pack.DownloadFile('<?php echo $installfilelink; ?>', this); return false;">
162
  ?>
163
  <tr class="dup-pack-info <?php echo $css_alt ?>">
164
  <td class="fail"><input name="delete_confirm" type="checkbox" id="<?php echo $row['id'] ;?>" /></td>
165
+ <td><?php echo DUP_Package::getCreatedDateFormat($row['created'], $ui_create_frmt);?></td>
166
+ <td><?php echo DUP_Util::byteSize($size); ?></td>
167
  <td class='pack-name'><?php echo $pack_name ;?></td>
168
  <td class="get-btns error-msg" colspan="2">
169
  <span>
185
  <tr>
186
  <th colspan="11" style='text-align:right; font-size:12px'>
187
  <?php echo _e("Packages", 'duplicator') . ': ' . $totalElements; ?> |
188
+ <?php echo _e("Total Size", 'duplicator') . ': ' . DUP_Util::byteSize($totalSize); ?>
189
  </th>
190
  </tr>
191
  </tfoot>
196
  <!-- ==========================================
197
  THICK-BOX DIALOGS: -->
198
  <?php
199
+ $alert1 = new DUP_UI_Dialog();
200
  $alert1->title = __('Bulk Action Required', 'duplicator');
201
  $alert1->message = __('Please select an action from the "Bulk Actions" drop down menu!', 'duplicator');
202
+ $alert1->initAlert();
203
 
204
+ $alert2 = new DUP_UI_Dialog();
205
  $alert2->title = __('Selection Required', 'duplicator', 'duplicator');
206
  $alert2->message = __('Please select at least one package to delete!', 'duplicator');
207
+ $alert2->initAlert();
208
 
209
+ $confirm1 = new DUP_UI_Dialog();
210
  $confirm1->title = __('Delete Packages?', 'duplicator');
211
  $confirm1->message = __('Are you sure, you want to delete the selected package(s)?', 'duplicator');
212
+ $confirm1->progressText = __('Removing Packages, Please Wait...', 'duplicator');
213
  $confirm1->jscallback = 'Duplicator.Pack.Delete()';
214
+ $confirm1->initConfirm();
215
  ?>
216
 
217
  <script type="text/javascript">
237
  {
238
  if ($("#dup-pack-bulk-actions").val() != "delete")
239
  {
240
+ <?php $alert1->showAlert(); ?>
241
  return;
242
  }
243
 
244
  var list = Duplicator.Pack.GetDeleteList();
245
  if (list.length == 0)
246
  {
247
+ <?php $alert2->showAlert(); ?>
248
  return;
249
  }
250
+ <?php $confirm1->showConfirm(); ?>
251
  }
252
 
253
 
256
  Duplicator.Pack.Delete = function (event)
257
  {
258
  var list = Duplicator.Pack.GetDeleteList();
259
+
260
  $.ajax({
261
  type: "POST",
262
  url: ajaxurl,
263
  dataType: "json",
264
  data: {action : 'duplicator_package_delete', duplicator_delid : list, nonce: '<?php echo $ajax_nonce; ?>' },
265
+ complete: function(data) {
266
  Duplicator.ReloadWindow(data);
267
  }
268
  });
views/settings/controller.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- DUP_Util::CheckPermissions('manage_options');
4
 
5
  global $wpdb;
6
 
1
  <?php
2
 
3
+ DUP_Util::hasCapability('manage_options');
4
 
5
  global $wpdb;
6
 
views/settings/general.php CHANGED
@@ -34,7 +34,7 @@ if (isset($_POST['action']) && $_POST['action'] == 'save') {
34
  DUP_Settings::Set('wpfront_integrate', isset($_POST['wpfront_integrate']) ? "1" : "0");
35
 
36
  $action_updated = DUP_Settings::Save();
37
- DUP_Util::InitSnapshotDirectory();
38
  }
39
 
40
  $uninstall_settings = DUP_Settings::Get('uninstall_settings');
@@ -55,7 +55,7 @@ $package_ui_created = is_numeric(DUP_Settings::Get('package_ui_created')) ? DUP_
55
  $wpfront_integrate = DUP_Settings::Get('wpfront_integrate');
56
  $wpfront_ready = apply_filters('wpfront_user_role_editor_duplicator_integration_ready', false);
57
 
58
- $mysqlDumpPath = DUP_Database::GetMySqlDumpPath();
59
  $mysqlDumpFound = ($mysqlDumpPath) ? true : false;
60
 
61
 
@@ -104,7 +104,7 @@ $mysqlDumpFound = ($mysqlDumpPath) ? true : false;
104
  <th scope="row"><label><?php _e("Storage", 'duplicator'); ?></label></th>
105
  <td>
106
  <?php _e("Full Path", 'duplicator'); ?>:
107
- <?php echo DUP_Util::SafePath(DUPLICATOR_SSDIR_PATH); ?><br/><br/>
108
  <input type="checkbox" name="storage_htaccess_off" id="storage_htaccess_off" <?php echo ($storage_htaccess_off) ? 'checked="checked"' : ''; ?> />
109
  <label for="storage_htaccess_off"><?php _e("Disable .htaccess File In Storage Directory", 'duplicator') ?> </label>
110
  <p class="description">
@@ -154,7 +154,7 @@ $mysqlDumpFound = ($mysqlDumpPath) ? true : false;
154
  <tr>
155
  <th scope="row"><label><?php _e("Database Script", 'duplicator'); ?></label></th>
156
  <td>
157
- <?php if (!DUP_Util::IsShellExecAvailable()) : ?>
158
  <input type="radio" disabled="true" />
159
  <label><?php _e("Use mysqldump", 'duplicator'); ?></label>
160
  <p class="description" style="width:550px; margin:5px 0 0 20px">
34
  DUP_Settings::Set('wpfront_integrate', isset($_POST['wpfront_integrate']) ? "1" : "0");
35
 
36
  $action_updated = DUP_Settings::Save();
37
+ DUP_Util::initSnapshotDirectory();
38
  }
39
 
40
  $uninstall_settings = DUP_Settings::Get('uninstall_settings');
55
  $wpfront_integrate = DUP_Settings::Get('wpfront_integrate');
56
  $wpfront_ready = apply_filters('wpfront_user_role_editor_duplicator_integration_ready', false);
57
 
58
+ $mysqlDumpPath = DUP_DB::getMySqlDumpPath();
59
  $mysqlDumpFound = ($mysqlDumpPath) ? true : false;
60
 
61
 
104
  <th scope="row"><label><?php _e("Storage", 'duplicator'); ?></label></th>
105
  <td>
106
  <?php _e("Full Path", 'duplicator'); ?>:
107
+ <?php echo DUP_Util::safePath(DUPLICATOR_SSDIR_PATH); ?><br/><br/>
108
  <input type="checkbox" name="storage_htaccess_off" id="storage_htaccess_off" <?php echo ($storage_htaccess_off) ? 'checked="checked"' : ''; ?> />
109
  <label for="storage_htaccess_off"><?php _e("Disable .htaccess File In Storage Directory", 'duplicator') ?> </label>
110
  <p class="description">
154
  <tr>
155
  <th scope="row"><label><?php _e("Database Script", 'duplicator'); ?></label></th>
156
  <td>
157
+ <?php if (!DUP_Util::hasShellExec()) : ?>
158
  <input type="radio" disabled="true" />
159
  <label><?php _e("Use mysqldump", 'duplicator'); ?></label>
160
  <p class="description" style="width:550px; margin:5px 0 0 20px">
views/tools/cleanup.php CHANGED
@@ -20,7 +20,7 @@
20
 
21
  $txt_found = __('File Found', 'duplicator');
22
  $txt_not_found = __('File Removed', 'duplicator');
23
- $installer_files = DUP_Server::GetInstallerFiles();
24
 
25
  switch ($_GET['action']) {
26
  case 'installer' :
@@ -32,7 +32,7 @@
32
  $action_response = __('Legacy data removed.', 'duplicator');
33
  break;
34
  case 'tmp-cache':
35
- DUP_Package::TmpCleanup(true);
36
  $action_response = __('Build cache removed.', 'duplicator');
37
  break;
38
  }
@@ -151,17 +151,17 @@ THICK-BOX DIALOGS: -->
151
  $msg = __('This action will remove all legacy settings prior to version %1$s. ', 'duplicator');
152
  $msg .= __('Legacy settings are only needed if you plan to migrate back to an older version of this plugin.', 'duplicator');
153
 
154
- $confirm1 = new DUP_Dialog();
155
  $confirm1->title = __('Delete Packages?', 'duplicator');
156
  $confirm1->message = sprintf(__($msg, 'duplicator'), DUPLICATOR_VERSION);
157
  $confirm1->jscallback = 'Duplicator.Tools.DeleteLegacy()';
158
- $confirm1->init_confirm();
159
 
160
- $confirm2 = new DUP_Dialog();
161
  $confirm2->title = __('Clear Build Cache?', 'duplicator');
162
  $confirm2->message = __('This process will remove all build cache files. Be sure no packages are currently building or else they will be cancelled.', 'duplicator');
163
  $confirm2->jscallback = 'Duplicator.Tools.ClearBuildCache()';
164
- $confirm2->init_confirm();
165
  ?>
166
 
167
  <script>
@@ -169,7 +169,7 @@ jQuery(document).ready(function($)
169
  {
170
  Duplicator.Tools.ConfirmDeleteLegacy = function ()
171
  {
172
- <?php $confirm1->show_confirm(); ?>
173
  }
174
 
175
 
@@ -181,7 +181,7 @@ jQuery(document).ready(function($)
181
 
182
  Duplicator.Tools.ConfirmClearBuildCache = function ()
183
  {
184
- <?php $confirm2->show_confirm(); ?>
185
  }
186
 
187
  Duplicator.Tools.ClearBuildCache = function ()
20
 
21
  $txt_found = __('File Found', 'duplicator');
22
  $txt_not_found = __('File Removed', 'duplicator');
23
+ $installer_files = DUP_Server::getInstallerFiles();
24
 
25
  switch ($_GET['action']) {
26
  case 'installer' :
32
  $action_response = __('Legacy data removed.', 'duplicator');
33
  break;
34
  case 'tmp-cache':
35
+ DUP_Package::tempFileCleanup(true);
36
  $action_response = __('Build cache removed.', 'duplicator');
37
  break;
38
  }
151
  $msg = __('This action will remove all legacy settings prior to version %1$s. ', 'duplicator');
152
  $msg .= __('Legacy settings are only needed if you plan to migrate back to an older version of this plugin.', 'duplicator');
153
 
154
+ $confirm1 = new DUP_UI_Dialog();
155
  $confirm1->title = __('Delete Packages?', 'duplicator');
156
  $confirm1->message = sprintf(__($msg, 'duplicator'), DUPLICATOR_VERSION);
157
  $confirm1->jscallback = 'Duplicator.Tools.DeleteLegacy()';
158
+ $confirm1->initConfirm();
159
 
160
+ $confirm2 = new DUP_UI_Dialog();
161
  $confirm2->title = __('Clear Build Cache?', 'duplicator');
162
  $confirm2->message = __('This process will remove all build cache files. Be sure no packages are currently building or else they will be cancelled.', 'duplicator');
163
  $confirm2->jscallback = 'Duplicator.Tools.ClearBuildCache()';
164
+ $confirm2->initConfirm();
165
  ?>
166
 
167
  <script>
169
  {
170
  Duplicator.Tools.ConfirmDeleteLegacy = function ()
171
  {
172
+ <?php $confirm1->showConfirm(); ?>
173
  }
174
 
175
 
181
 
182
  Duplicator.Tools.ConfirmClearBuildCache = function ()
183
  {
184
+ <?php $confirm2->showConfirm(); ?>
185
  }
186
 
187
  Duplicator.Tools.ClearBuildCache = function ()
views/tools/controller.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
- require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.dialog.php');
3
 
4
- DUP_Util::CheckPermissions('manage_options');
5
 
6
  global $wpdb;
7
 
1
  <?php
2
+ require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.dialog.php');
3
 
4
+ DUP_Util::hasCapability('manage_options');
5
 
6
  global $wpdb;
7
 
views/tools/diagnostics/inc.data.php CHANGED
@@ -44,12 +44,12 @@ OPTIONS DATA -->
44
  <!-- ==========================================
45
  THICK-BOX DIALOGS: -->
46
  <?php
47
- $confirm1 = new DUP_Dialog();
48
  $confirm1->title = __('Delete Option?', 'duplicator');
49
  $confirm1->message = __('Delete the option value just selected?', 'duplicator');
50
- $confirm1->progress_text = __('Removing Option, Please Wait...', 'duplicator');
51
  $confirm1->jscallback = 'Duplicator.Settings.DeleteOption()';
52
- $confirm1->init_confirm();
53
  ?>
54
 
55
  <script>
@@ -58,11 +58,11 @@ jQuery(document).ready(function($)
58
  Duplicator.Settings.ConfirmDeleteOption = function (anchor)
59
  {
60
  var key = $(anchor).text();
61
- var msg_id = '<?php echo $confirm1->get_message_id() ?>';
62
  var msg = '<?php _e('Delete the option value', 'duplicator');?>' + ' [' + key + '] ?';
63
  jQuery('#dup-settings-form-action').val(key);
64
  jQuery('#' + msg_id).html(msg)
65
- <?php $confirm1->show_confirm(); ?>
66
  }
67
 
68
 
44
  <!-- ==========================================
45
  THICK-BOX DIALOGS: -->
46
  <?php
47
+ $confirm1 = new DUP_UI_Dialog();
48
  $confirm1->title = __('Delete Option?', 'duplicator');
49
  $confirm1->message = __('Delete the option value just selected?', 'duplicator');
50
+ $confirm1->progressText = __('Removing Option, Please Wait...', 'duplicator');
51
  $confirm1->jscallback = 'Duplicator.Settings.DeleteOption()';
52
+ $confirm1->initConfirm();
53
  ?>
54
 
55
  <script>
58
  Duplicator.Settings.ConfirmDeleteOption = function (anchor)
59
  {
60
  var key = $(anchor).text();
61
+ var msg_id = '<?php echo $confirm1->getMessageID() ?>';
62
  var msg = '<?php _e('Delete the option value', 'duplicator');?>' + ' [' + key + '] ?';
63
  jQuery('#dup-settings-form-action').val(key);
64
  jQuery('#' + msg_id).html(msg)
65
+ <?php $confirm1->showConfirm(); ?>
66
  }
67
 
68
 
views/tools/diagnostics/inc.settings.php CHANGED
@@ -1,16 +1,16 @@
1
  <?php
2
- $dbvar_maxtime = DUP_Util::MysqlVariableValue('wait_timeout');
3
- $dbvar_maxpacks = DUP_Util::MysqlVariableValue('max_allowed_packet');
4
  $dbvar_maxtime = is_null($dbvar_maxtime) ? __("unknow", 'duplicator') : $dbvar_maxtime;
5
  $dbvar_maxpacks = is_null($dbvar_maxpacks) ? __("unknow", 'duplicator') : $dbvar_maxpacks;
6
 
7
  $space = @disk_total_space(DUPLICATOR_WPROOTPATH);
8
  $space_free = @disk_free_space(DUPLICATOR_WPROOTPATH);
9
  $perc = @round((100/$space)*$space_free,2);
10
- $mysqldumpPath = DUP_Database::GetMySqlDumpPath();
11
  $mysqlDumpSupport = ($mysqldumpPath) ? $mysqldumpPath : 'Path Not Found';
12
 
13
- $client_ip_address = DUP_Server::GetClientIP();
14
  ?>
15
 
16
  <!-- ==============================
@@ -48,7 +48,7 @@ SERVER SETTINGS -->
48
  </tr>
49
  <tr>
50
  <td><?php _e("APC Enabled", 'duplicator'); ?></td>
51
- <td><?php echo DUP_Util::RunAPC() ? 'Yes' : 'No' ?></td>
52
  </tr>
53
  <tr>
54
  <td><?php _e("Root Path", 'duplicator'); ?></td>
@@ -60,7 +60,7 @@ SERVER SETTINGS -->
60
  </tr>
61
  <tr>
62
  <td><?php _e("Plugins Path", 'duplicator'); ?></td>
63
- <td><?php echo DUP_Util::SafePath(WP_PLUGIN_DIR) ?></td>
64
  </tr>
65
  <tr>
66
  <td><?php _e("Loaded PHP INI", 'duplicator'); ?></td>
@@ -106,11 +106,11 @@ SERVER SETTINGS -->
106
  </tr>
107
  <tr>
108
  <td><?php _e("User", 'duplicator'); ?></td>
109
- <td><?php echo DUP_Util::GetCurrentUser(); ?></td>
110
  </tr>
111
  <tr>
112
  <td><?php _e("Process", 'duplicator'); ?></td>
113
- <td><?php echo DUP_Util::GetProcessOwner(); ?></td>
114
  </tr>
115
  <tr>
116
  <td><a href="http://php.net/manual/en/features.safe-mode.php" target="_blank"><?php _e("Safe Mode", 'duplicator'); ?></a></td>
@@ -135,18 +135,22 @@ SERVER SETTINGS -->
135
  </tr>
136
  <tr>
137
  <td><a href="http://us3.php.net/shell_exec" target="_blank"><?php _e("Shell Exec", 'duplicator'); ?></a></td>
138
- <td><?php echo (DUP_Util::IsShellExecAvailable()) ? _e("Is Supported", 'duplicator') : _e("Not Supported", 'duplicator'); ?></td>
139
  </tr>
140
  <tr>
141
  <td><?php _e("Shell Exec Zip", 'duplicator'); ?></td>
142
- <td><?php echo (DUP_Util::GetZipPath() != null) ? _e("Is Supported", 'duplicator') : _e("Not Supported", 'duplicator'); ?></td>
143
  </tr>
144
  <tr>
145
  <td class='dup-settings-diag-header' colspan="2">MySQL</td>
146
  </tr>
147
  <tr>
148
  <td><?php _e("Version", 'duplicator'); ?></td>
149
- <td><?php echo $wpdb->db_version() ?></td>
 
 
 
 
150
  </tr>
151
  <tr>
152
  <td><?php _e("Charset", 'duplicator'); ?></td>
@@ -169,7 +173,7 @@ SERVER SETTINGS -->
169
  </tr>
170
  <tr valign="top">
171
  <td><?php _e('Free space', 'hyper-cache'); ?></td>
172
- <td><?php echo $perc;?>% -- <?php echo DUP_Util::ByteSize($space_free);?> from <?php echo DUP_Util::ByteSize($space);?><br/>
173
  <small>
174
  <?php _e("Note: This value is the physical servers hard-drive allocation.", 'duplicator'); ?> <br/>
175
  <?php _e("On shared hosts check your control panel for the 'TRUE' disk space quota value.", 'duplicator'); ?>
1
  <?php
2
+ $dbvar_maxtime = DUP_DB::getVariable('wait_timeout');
3
+ $dbvar_maxpacks = DUP_DB::getVariable('max_allowed_packet');
4
  $dbvar_maxtime = is_null($dbvar_maxtime) ? __("unknow", 'duplicator') : $dbvar_maxtime;
5
  $dbvar_maxpacks = is_null($dbvar_maxpacks) ? __("unknow", 'duplicator') : $dbvar_maxpacks;
6
 
7
  $space = @disk_total_space(DUPLICATOR_WPROOTPATH);
8
  $space_free = @disk_free_space(DUPLICATOR_WPROOTPATH);
9
  $perc = @round((100/$space)*$space_free,2);
10
+ $mysqldumpPath = DUP_DB::getMySqlDumpPath();
11
  $mysqlDumpSupport = ($mysqldumpPath) ? $mysqldumpPath : 'Path Not Found';
12
 
13
+ $client_ip_address = DUP_Server::getClientIP();
14
  ?>
15
 
16
  <!-- ==============================
48
  </tr>
49
  <tr>
50
  <td><?php _e("APC Enabled", 'duplicator'); ?></td>
51
+ <td><?php echo DUP_Util::runAPC() ? 'Yes' : 'No' ?></td>
52
  </tr>
53
  <tr>
54
  <td><?php _e("Root Path", 'duplicator'); ?></td>
60
  </tr>
61
  <tr>
62
  <td><?php _e("Plugins Path", 'duplicator'); ?></td>
63
+ <td><?php echo DUP_Util::safePath(WP_PLUGIN_DIR) ?></td>
64
  </tr>
65
  <tr>
66
  <td><?php _e("Loaded PHP INI", 'duplicator'); ?></td>
106
  </tr>
107
  <tr>
108
  <td><?php _e("User", 'duplicator'); ?></td>
109
+ <td><?php echo DUP_Util::getCurrentUser(); ?></td>
110
  </tr>
111
  <tr>
112
  <td><?php _e("Process", 'duplicator'); ?></td>
113
+ <td><?php echo DUP_Util::getProcessOwner(); ?></td>
114
  </tr>
115
  <tr>
116
  <td><a href="http://php.net/manual/en/features.safe-mode.php" target="_blank"><?php _e("Safe Mode", 'duplicator'); ?></a></td>
135
  </tr>
136
  <tr>
137
  <td><a href="http://us3.php.net/shell_exec" target="_blank"><?php _e("Shell Exec", 'duplicator'); ?></a></td>
138
+ <td><?php echo (DUP_Util::hasShellExec()) ? _e("Is Supported", 'duplicator') : _e("Not Supported", 'duplicator'); ?></td>
139
  </tr>
140
  <tr>
141
  <td><?php _e("Shell Exec Zip", 'duplicator'); ?></td>
142
+ <td><?php echo (DUP_Util::getZipPath() != null) ? _e("Is Supported", 'duplicator') : _e("Not Supported", 'duplicator'); ?></td>
143
  </tr>
144
  <tr>
145
  <td class='dup-settings-diag-header' colspan="2">MySQL</td>
146
  </tr>
147
  <tr>
148
  <td><?php _e("Version", 'duplicator'); ?></td>
149
+ <td><?php echo DUP_DB::getVersion() ?></td>
150
+ </tr>
151
+ <tr>
152
+ <td><?php _e("Comments", 'duplicator'); ?></td>
153
+ <td><?php echo DUP_DB::getVariable('version_comment') ?></td>
154
  </tr>
155
  <tr>
156
  <td><?php _e("Charset", 'duplicator'); ?></td>
173
  </tr>
174
  <tr valign="top">
175
  <td><?php _e('Free space', 'hyper-cache'); ?></td>
176
+ <td><?php echo $perc;?>% -- <?php echo DUP_Util::byteSize($space_free);?> from <?php echo DUP_Util::byteSize($space);?><br/>
177
  <small>
178
  <?php _e("Note: This value is the physical servers hard-drive allocation.", 'duplicator'); ?> <br/>
179
  <?php _e("On shared hosts check your control panel for the 'TRUE' disk space quota value.", 'duplicator'); ?>
views/tools/diagnostics/inc.validator.php CHANGED
@@ -10,12 +10,12 @@
10
  <!-- ==========================================
11
  THICK-BOX DIALOGS: -->
12
  <?php
13
- $confirm1 = new DUP_Dialog();
14
  $confirm1->title = __('Run Validator', 'duplicator');
15
  $confirm1->message = __('This will run the scan validation check. This may take several minutes. Do you want to Continue?', 'duplicator');
16
- $confirm1->progress_on = false;
17
  $confirm1->jscallback = 'Duplicator.Tools.RunScanValidator()';
18
- $confirm1->init_confirm();
19
  ?>
20
 
21
  <!-- ==============================
@@ -46,17 +46,17 @@ SCAN VALIDATOR -->
46
  <table>
47
  <tr>
48
  <td><b>Files:</b></td>
49
- <td>{{Payload.FileCount}} </td>
50
  </tr>
51
  <tr>
52
  <td><b>Dirs:</b></td>
53
- <td>{{Payload.DirCount}} </td>
54
  </tr>
55
  </table>
56
 
57
  <b>Unreadable Files:</b> <br/>
58
- {{#if Payload.Unreadable}}
59
- {{#each Payload.Unreadable}}
60
  &nbsp; &nbsp; {{@index}} : {{this}}<br/>
61
  {{/each}}
62
  {{else}}
@@ -64,8 +64,8 @@ SCAN VALIDATOR -->
64
  {{/if}}
65
 
66
  <b>Symbolic Links:</b> <br/>
67
- {{#if Payload.SymLinks}}
68
- {{#each Payload.SymLinks}}
69
  &nbsp; &nbsp; {{@index}} : {{this}}<br/>
70
  {{/each}}
71
  {{else}}
@@ -84,7 +84,7 @@ jQuery(document).ready(function($)
84
  {
85
  Duplicator.Tools.ConfirmScanValidator = function()
86
  {
87
- <?php $confirm1->show_confirm(); ?>
88
  }
89
 
90
 
10
  <!-- ==========================================
11
  THICK-BOX DIALOGS: -->
12
  <?php
13
+ $confirm1 = new DUP_UI_Dialog();
14
  $confirm1->title = __('Run Validator', 'duplicator');
15
  $confirm1->message = __('This will run the scan validation check. This may take several minutes. Do you want to Continue?', 'duplicator');
16
+ $confirm1->progressOn = false;
17
  $confirm1->jscallback = 'Duplicator.Tools.RunScanValidator()';
18
+ $confirm1->initConfirm();
19
  ?>
20
 
21
  <!-- ==============================
46
  <table>
47
  <tr>
48
  <td><b>Files:</b></td>
49
+ <td>{{Payload.fileCount}} </td>
50
  </tr>
51
  <tr>
52
  <td><b>Dirs:</b></td>
53
+ <td>{{Payload.dirCount}} </td>
54
  </tr>
55
  </table>
56
 
57
  <b>Unreadable Files:</b> <br/>
58
+ {{#if Payload.unreadable}}
59
+ {{#each Payload.unreadable}}
60
  &nbsp; &nbsp; {{@index}} : {{this}}<br/>
61
  {{/each}}
62
  {{else}}
64
  {{/if}}
65
 
66
  <b>Symbolic Links:</b> <br/>
67
+ {{#if Payload.symLinks}}
68
+ {{#each Payload.symLinks}}
69
  &nbsp; &nbsp; {{@index}} : {{this}}<br/>
70
  {{/each}}
71
  {{else}}
84
  {
85
  Duplicator.Tools.ConfirmScanValidator = function()
86
  {
87
+ <?php $confirm1->showConfirm(); ?>
88
  }
89
 
90
 
views/tools/diagnostics/main.php CHANGED
@@ -2,7 +2,7 @@
2
  wp_enqueue_script('dup-handlebars');
3
  require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
5
- require_once(DUPLICATOR_PLUGIN_PATH . '/classes/scan.validator.php');
6
 
7
  global $wp_version;
8
  global $wpdb;
2
  wp_enqueue_script('dup-handlebars');
3
  require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php');
4
  require_once(DUPLICATOR_PLUGIN_PATH . '/views/inc.header.php');
5
+ require_once(DUPLICATOR_PLUGIN_PATH . '/classes/utilities/class.scan.check.php');
6
 
7
  global $wp_version;
8
  global $wpdb;
views/tools/logging.php CHANGED
@@ -6,7 +6,7 @@ $logs = glob(DUPLICATOR_SSDIR_PATH . '/*.log') ;
6
  if ($logs != false && count($logs))
7
  {
8
  usort($logs, create_function('$a,$b', 'return filemtime($b) - filemtime($a);'));
9
- @chmod(DUP_Util::SafePath($logs[0]), 0644);
10
  }
11
 
12
  $logname = (isset($_GET['logname'])) ? trim(sanitize_text_field($_GET['logname'])) : "";
6
  if ($logs != false && count($logs))
7
  {
8
  usort($logs, create_function('$a,$b', 'return filemtime($b) - filemtime($a);'));
9
+ @chmod(DUP_Util::safePath($logs[0]), 0644);
10
  }
11
 
12
  $logname = (isset($_GET['logname'])) ? trim(sanitize_text_field($_GET['logname'])) : "";