PluginProbe ʕ •ᴥ•ʔ
Backup Migration / 1.4.6
Backup Migration v1.4.6
2.1.7 2.1.6 2.1.5.2 trunk 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.6.1 1.4.7 1.4.8 1.4.9 1.4.9.1 2.0.0 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.5.1
backup-backup / includes / extracter / extract.php
backup-backup / includes / extracter Last commit date
extract.php 2 years ago
extract.php
2041 lines
1 <?php
2
3 // Namespace
4 namespace BMI\Plugin\Extracter;
5
6 // Use
7 use BMI\Plugin\BMI_Logger as Logger;
8 use BMI\Plugin\Dashboard as Dashboard;
9 use BMI\Plugin\Database\BMI_Database as Database;
10 use BMI\Plugin\Database\BMI_Database_Importer as BetterDatabaseImport;
11 use BMI\Plugin\Database\BMI_Even_Better_Database_Restore as EvenBetterDatabaseImport;
12 use BMI\Plugin\Progress\BMI_ZipProgress as Progress;
13 use BMI\Plugin\Backup_Migration_Plugin as BMP;
14 use BMI\Plugin\Zipper\Zip as Zip;
15 use BMI\Plugin\Zipper\BMI_Zipper as ZipManager;
16 use BMI\Plugin\Database\BMI_Database_Sorting as SmartDatabaseSort;
17
18 // Exit on direct access
19 if (!defined('ABSPATH')) {
20 exit;
21 }
22
23 /**
24 * BMI_Extracter
25 */
26 class BMI_Extracter {
27
28 public function __construct($backup, &$migration, $tmptime = false, $isCLI = false, $options = []) {
29
30 // Globals
31 global $table_prefix;
32
33 // Requirements
34 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'manager.php';
35 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'better-restore.php';
36 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'smart-sort.php';
37
38 // IsCLI?
39 $this->isCLI = $isCLI;
40
41 // Backup name
42 $this->backup_name = $backup;
43
44 // Logger
45 $this->migration = $migration;
46
47 // Temp name
48 $this->tmptime = time();
49
50 // Use specified name if it is in batching mode
51 if (is_numeric($tmptime)) $this->tmptime = $tmptime;
52
53 // Splitting enabled?
54 $this->splitting = Dashboard\bmi_get_config('OTHER:RESTORE:SPLITTING') ? true : false;
55 $this->v3engine = Dashboard\bmi_get_config('OTHER:RESTORE:DB:V3') ? true : false;
56 $this->cleanupbefore = Dashboard\bmi_get_config('OTHER:RESTORE:BEFORE:CLEANUP') ? true : false;
57
58 // Restore start time
59 $this->start = intval(microtime(true));
60
61 // File amount by default 0 later we replace it with scan
62 $this->fileAmount = 0;
63 $this->recent_export_seek = 0;
64 $this->processData = [];
65 $this->conversionStats = [];
66
67 // Options
68 $this->batchStep = 0;
69 if (isset($options['amount'])) {
70 $this->fileAmount = intval($options['amount']);
71 }
72 if (isset($options['start'])) {
73 $this->start = intval($options['start']);
74 }
75 $this->continueFile = false;
76 if (isset($options['continueFile'])) {
77 $this->continueFile = $options['continueFile'];
78 }
79 $this->continueSeek = false;
80 if (isset($options['continueSeek'])) {
81 $this->continueSeek = $options['continueSeek'];
82 }
83 if (isset($options['step'])) {
84 $this->batchStep = intval($options['step']);
85 }
86 $this->databaseExist = false;
87 if (isset($options['databaseExist'])) {
88 $this->databaseExist = (($options['databaseExist'] == 'true' || $options['databaseExist'] === '1' || $options['databaseExist'] === 1 || $options['databaseExist'] === true) ? true : false);
89 }
90 $this->firstDB = true;
91 if (isset($options['firstDB'])) {
92 $this->firstDB = (($options['firstDB'] == 'true' || $options['firstDB'] === '1' || $options['firstDB'] === 1 || $options['firstDB'] === true) ? true : false);
93 }
94 $this->v3RestoreUsed = false;
95 if (isset($options['v3RestoreUsed'])) {
96 $this->v3RestoreUsed = (($options['v3RestoreUsed'] == 'true' || $options['v3RestoreUsed'] === '1' || $options['v3RestoreUsed'] === 1 || $options['v3RestoreUsed'] === true) ? true : false);
97 }
98 $this->firstExtract = true;
99 if (isset($options['firstExtract'])) {
100 $this->firstExtract = (($options['firstExtract'] == 'false' || $options['firstExtract'] === '1' || $options['firstExtract'] === 1 || $options['firstExtract'] === false) ? false : true);
101 }
102
103 $this->db_xi = 0;
104 $this->ini_start = 0;
105 $this->table_names_alter = [];
106
107 if (isset($options['db_xi'])) {
108 $this->db_xi = ((is_numeric($options['db_xi'])) ? intval($options['db_xi']) : 0);
109 }
110 if (isset($options['ini_start'])) {
111 $this->ini_start = ((is_numeric($options['ini_start'])) ? intval($options['ini_start']) : microtime(true));
112 }
113 if (isset($options['table_names_alter'])) {
114 $this->table_names_alter = $options['table_names_alter'];
115 }
116 if (isset($options['recent_export_seek'])) {
117 $this->recent_export_seek = intval($options['recent_export_seek']);
118 }
119 if (isset($options['processData'])) {
120 $this->processData = $options['processData'];
121 }
122 if (isset($options['conversionStats'])) {
123 $this->conversionStats = $options['conversionStats'];
124 }
125
126 $this->tableIndex = 0;
127 $this->replaceStep = 0;
128 $this->totalReplacePage = 0;
129 $this->currentReplacePage = 0;
130 $this->fieldAdjustments = 0;
131 $this->dbFoundPrefix = 'wp_';
132
133 if (isset($options['replaceStep'])) {
134 $this->replaceStep = intval($options['replaceStep']);
135 }
136 if (isset($options['tableIndex'])) {
137 $this->tableIndex = intval($options['tableIndex']);
138 }
139 if (isset($options['currentReplacePage'])) {
140 $this->currentReplacePage = intval($options['currentReplacePage']);
141 }
142 if (isset($options['totalReplacePage'])) {
143 $this->totalReplacePage = intval($options['totalReplacePage']);
144 }
145 if (isset($options['fieldAdjustments'])) {
146 $this->fieldAdjustments = intval($options['fieldAdjustments']);
147 }
148 if (isset($options['dbFoundPrefix'])) {
149 $this->dbFoundPrefix = sanitize_text_field($options['dbFoundPrefix']);
150 }
151
152 // Name
153 // $this->tmp = untrailingslashit(ABSPATH) . DIRECTORY_SEPARATOR . 'backup-migration_' . $this->tmptime;
154 $this->tmp = BMI_TMP . DIRECTORY_SEPARATOR . 'backup-migration_' . $this->tmptime;
155 $GLOBALS['bmi_current_tmp_restore'] = $this->tmp;
156 $GLOBALS['bmi_current_tmp_restore_unique'] = $this->tmptime;
157
158 // Scan file
159 $this->scanFile = BMI_TMP . DIRECTORY_SEPARATOR . '.restore_scan_' . $this->tmptime;
160
161 // Prepare database connection
162 $this->db = new Database(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
163
164 // Save current wp-config to replace (only those required)
165 $this->DB_NAME = DB_NAME;
166 $this->DB_USER = DB_USER;
167 $this->DB_PASSWORD = DB_PASSWORD;
168 $this->DB_HOST = DB_HOST;
169 $this->DB_CHARSET = (defined('DB_CHARSET') ? DB_CHARSET : '');
170 $this->DB_COLLATE = (defined('DB_COLLATE') ? DB_COLLATE : '');
171
172 $this->AUTH_KEY = (defined('AUTH_KEY') ? AUTH_KEY : '');
173 $this->SECURE_AUTH_KEY = (defined('SECURE_AUTH_KEY') ? SECURE_AUTH_KEY : '');
174 $this->LOGGED_IN_KEY = (defined('LOGGED_IN_KEY') ? LOGGED_IN_KEY : '');
175 $this->NONCE_KEY = (defined('NONCE_KEY') ? NONCE_KEY : '');
176 $this->AUTH_SALT = (defined('AUTH_SALT') ? AUTH_SALT : '');
177 $this->SECURE_AUTH_SALT = (defined('SECURE_AUTH_SALT') ? SECURE_AUTH_SALT : '');
178 $this->LOGGED_IN_SALT = (defined('LOGGED_IN_SALT') ? LOGGED_IN_SALT : '');
179 $this->NONCE_SALT = (defined('NONCE_SALT') ? NONCE_SALT : '');
180
181 $this->ABSPATH = ABSPATH;
182 $this->WP_CONTENT_DIR = trailingslashit(WP_CONTENT_DIR);
183
184 $this->WP_DEBUG_LOG = WP_DEBUG_LOG;
185 $this->table_prefix = $table_prefix;
186 $this->code = get_option('z__bmi_xhria', false);
187 if (isset($options['code']) && $this->code == false) {
188 $this->code = $options['code'];
189 }
190
191 $this->backupStorage = get_option('BMI::STORAGE::LOCAL::PATH', false);
192 if (isset($options['storage'])) $this->backupStorage = $options['storage'];
193
194 $this->siteurl = get_option('siteurl');
195 $this->home = get_option('home');
196
197 $this->src = BMI_BACKUPS . DIRECTORY_SEPARATOR . $this->backup_name;
198
199 $this->v3Importer = null;
200 $this->usingDbEngineV4 = null;
201
202 $this->backupStorage = str_replace('/', DIRECTORY_SEPARATOR, $this->backupStorage);
203
204 }
205
206 public function removeUnwantedFiles() {
207 $preventMoveFiles = [
208 'wp-config.php',
209 'debug.log',
210 '.user.ini',
211 'php.ini',
212 '.htaccess'
213 ];
214
215 $base = $this->tmp . DIRECTORY_SEPARATOR . 'wordpress' . DIRECTORY_SEPARATOR;
216
217 foreach ($preventMoveFiles as $idx => $value) {
218 if (file_exists($base . $value)) @unlink($base . $value);
219 }
220 }
221
222 public function replacePath($path, $sub, $content) {
223 $path .= DIRECTORY_SEPARATOR . 'wordpress' . $sub;
224
225 // Handle only database backup
226 if (!file_exists($path)) return;
227
228 $rii = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
229
230 $clent = strlen($content);
231 $sublen = strlen($path);
232 $files = [];
233 $dirs = [];
234
235 $preventMoveFiles = [
236 'wp-config.php',
237 'debug.log',
238 '.user.ini',
239 'php.ini',
240 '.htaccess'
241 ];
242
243 foreach ($rii as $file) {
244 if (!$file->isDir()) {
245 $files[] = substr($file->getPathname(), $sublen);
246 } else {
247 $dirs[] = substr($file->getPathname(), $sublen);
248 }
249 }
250
251 for ($i = 0; $i < sizeof($dirs); ++$i) {
252 $src = $path . $dirs[$i];
253 if (strpos($dirs[$i], $content) !== false) {
254 $dest = untrailingslashit($this->WP_CONTENT_DIR) . $sub . ltrim(substr($dirs[$i], $clent), DIRECTORY_SEPARATOR);
255 } else {
256 $dest = untrailingslashit($this->ABSPATH) . $sub . ltrim($dirs[$i], DIRECTORY_SEPARATOR);
257 }
258
259 $dest = untrailingslashit($dest);
260 if (!(file_exists($dest) && is_dir($dest))) {
261 try { @mkdir($dest, 0755, true); }
262 catch (Exception $e) { /* Slience */ }
263 catch (Throwable $t) { /* Slience */ }
264 }
265 }
266
267 $max = sizeof($files);
268 for ($i = 0; $i < $max; ++$i) {
269 $src = $path . $files[$i];
270 if (strpos($files[$i], $content) !== false) {
271 $dest = untrailingslashit($this->WP_CONTENT_DIR) . $sub . substr($files[$i], $clent);
272 } else {
273 $dest = untrailingslashit($this->ABSPATH) . $sub . $files[$i];
274 }
275
276 if (file_exists($src)) {
277 $fileDest = BMP::fixSlashes($dest);
278 foreach ($preventMoveFiles as $idx => $preventedFile) {
279 if (strpos($src, $preventedFile) === false) {
280 rename($src, $fileDest);
281 }
282 }
283 }
284
285 if ($i % 100 === 0 || ($i == ($max - 1))) {
286 $this->migration->progress(25 + intval((($i / $max) * 100) / 4));
287 if ($i != 0 && ($i % 500 === 0 || ($i == ($max - 1)))) {
288 if ($i == ($max - 1)) $i++;
289 $this->migration->log(sprintf(__('File replacement progress: %s/%s (%s%%)', 'backup-backup'), $i, $max, intval(($i / $max) * 100)));
290 }
291 }
292 }
293 }
294
295 public function removePreviousSelectionsIfDatabaseIncluded() {
296
297 $themedir = get_theme_root();
298 $tempTheme = $themedir . DIRECTORY_SEPARATOR . 'backup_migration_restoration_in_progress';
299
300 if (file_exists($tempTheme . DIRECTORY_SEPARATOR . '.previous_theme')) {
301 @unlink($tempTheme . DIRECTORY_SEPARATOR . '.previous_theme');
302 }
303
304 if (file_exists($tempTheme . DIRECTORY_SEPARATOR . '.previous_stylesheet')) {
305 @unlink($tempTheme . DIRECTORY_SEPARATOR . '.previous_stylesheet');
306 }
307
308 if (file_exists($tempTheme . DIRECTORY_SEPARATOR . '.earlier_active_plugins')) {
309 @unlink($tempTheme . DIRECTORY_SEPARATOR . '.earlier_active_plugins');
310 }
311
312 }
313
314 public function replaceAll($content) {
315
316 $themedir = get_theme_root();
317 $tempTheme = $themedir . DIRECTORY_SEPARATOR . 'backup_migration_restoration_in_progress';
318 if (!(file_exists($tempTheme) && is_dir($tempTheme))) {
319 @mkdir($tempTheme, 0755, true);
320 }
321
322 $visitLaterText = __('Site restoration in progress, please visit that website a bit later, thank you! :)', 'backup-backup');
323 file_put_contents($tempTheme . DIRECTORY_SEPARATOR . 'header.php', '<?php wp_head(); show_admin_bar(true);');
324 file_put_contents($tempTheme . DIRECTORY_SEPARATOR . 'footer.php', '<?php wp_footer(); get_footer();');
325 file_put_contents($tempTheme . DIRECTORY_SEPARATOR . 'index.php', '<?php get_header(); wp_body_open(); ?>' . $visitLaterText);
326 file_put_contents($tempTheme . DIRECTORY_SEPARATOR . '.previous_theme', get_option('template', ''));
327 file_put_contents($tempTheme . DIRECTORY_SEPARATOR . '.previous_stylesheet', get_option('stylesheet', ''));
328 file_put_contents($tempTheme . DIRECTORY_SEPARATOR . '.earlier_active_plugins', serialize(get_option('active_plugins')));
329
330 update_option('active_plugins', ['backup-backup/backup-backup.php']);
331 update_option('template', 'backup_migration_restoration_in_progress');
332 update_option('stylesheet', 'backup_migration_restoration_in_progress');
333
334 $this->replacePath($this->tmp, DIRECTORY_SEPARATOR, $content);
335
336 }
337
338 public function cleanup() {
339
340 // Fix for automatic redirection module at TasteWP
341 if (strpos(site_url(), 'tastewp') !== false) {
342 if (function_exists('wp_load_alloptions')) wp_load_alloptions(true);
343 delete_option('__tastewp_redirection_performed', true);
344 delete_option('auto_smart_tastewp_redirect_performed', 1);
345 delete_option('tastewp_auto_activated', true);
346 delete_option('__tastewp_sub_requested', true);
347
348 if (function_exists('wp_load_alloptions')) wp_load_alloptions(true);
349 update_option('__tastewp_redirection_performed', true);
350 update_option('auto_smart_tastewp_redirect_performed', 1);
351 update_option('tastewp_auto_activated', true);
352 update_option('__tastewp_sub_requested', true);
353 }
354
355 $filesToBeRemoved = [];
356 $dir = $this->tmp;
357
358 $themedir = get_theme_root();
359 $tempTheme = $themedir . DIRECTORY_SEPARATOR . 'backup_migration_restoration_in_progress';
360
361 if (get_option('template') == 'backup_migration_restoration_in_progress' || get_option('stylesheet') == 'backup_migration_restoration_in_progress') {
362 if (file_exists($tempTheme . DIRECTORY_SEPARATOR . '.previous_theme')) {
363 update_option('template', file_get_contents($tempTheme . DIRECTORY_SEPARATOR . '.previous_theme'));
364 }
365 if (file_exists($tempTheme . DIRECTORY_SEPARATOR . '.previous_stylesheet')) {
366 update_option('stylesheet', file_get_contents($tempTheme . DIRECTORY_SEPARATOR . '.previous_stylesheet'));
367 }
368 if (file_exists($tempTheme . DIRECTORY_SEPARATOR . '.earlier_active_plugins')) {
369 update_option('active_plugins', unserialize(file_get_contents($tempTheme . DIRECTORY_SEPARATOR . '.earlier_active_plugins')));
370 }
371 }
372
373 $filesToBeRemoved[] = $tempTheme;
374
375 if (is_dir($dir) && file_exists($dir)) {
376
377 $it = new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS);
378 $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST);
379
380 $this->migration->log(__('Removing ', 'backup-backup') . iterator_count($files) . __(' files', 'backup-backup'), 'INFO');
381 foreach ($files as $file) {
382 $pathReal = $file->getRealPath();
383 if (!file_exists($pathReal)) continue;
384 if ($file->isDir()) {
385 @rmdir($pathReal);
386 } else {
387 gc_collect_cycles();
388 @unlink($pathReal);
389 }
390 }
391
392 @rmdir($dir);
393
394 }
395
396 if (file_exists($this->scanFile)) {
397 @unlink($this->scanFile);
398 }
399
400 $sc = BMI_TMP . DIRECTORY_SEPARATOR . '.restore_secret';
401 if (file_exists($sc)) {
402 @unlink($sc);
403 }
404
405 $tblmap = BMI_TMP . DIRECTORY_SEPARATOR . '.table_map';
406 if (file_exists($tblmap)) {
407 @unlink($tblmap);
408 }
409
410 $allowedFiles = ['wp-config.php', '.htaccess', '.litespeed', '.default.json', 'driveKeys.php', '.autologin.php', '.migrationFinished'];
411 foreach (glob(BMI_TMP . DIRECTORY_SEPARATOR . 'backup-migration_??????????') as $filename) {
412
413 $basename = basename($filename);
414
415 if (is_dir($filename) && !in_array($basename, ['.', '..'])) {
416 $filesToBeRemoved[] = $filename;
417 }
418
419 }
420
421 foreach (glob(BMI_TMP . DIRECTORY_SEPARATOR . '.*') as $filename) {
422
423 $basename = basename($filename);
424
425 if (in_array($basename, ['.', '..'])) continue;
426 if (is_file($filename) && !in_array($basename, $allowedFiles)) {
427 $filesToBeRemoved[] = $filename;
428 }
429
430 }
431
432 foreach (glob(BMI_TMP . DIRECTORY_SEPARATOR . 'restore_scan_*') as $filename) {
433
434 $basename = basename($filename);
435
436 if (in_array($basename, ['.', '..'])) continue;
437 if (is_file($filename) && !in_array($basename, $allowedFiles)) {
438 $filesToBeRemoved[] = $filename;
439 }
440
441 }
442
443 foreach (glob(untrailingslashit(ABSPATH) . DIRECTORY_SEPARATOR . 'wp-config.??????????.php') as $filename) {
444
445 $basename = basename($filename);
446
447 if (in_array($basename, ['.', '..'])) continue;
448 if (is_file($filename) && !in_array($filename, $allowedFiles)) {
449 $filesToBeRemoved[] = $filename;
450 }
451
452 }
453
454 if (is_array($filesToBeRemoved) || is_object($filesToBeRemoved)) {
455 foreach ((array) $filesToBeRemoved as $file) {
456 $this->rrmdir($file);
457 }
458 }
459
460 }
461
462 private function rrmdir($dir) {
463
464 if (is_dir($dir)) {
465
466 $objects = scandir($dir);
467 foreach ($objects as $object) {
468
469 if ($object != "." && $object != "..") {
470
471 if (is_dir($dir . DIRECTORY_SEPARATOR . $object) && !is_link($dir . DIRECTORY_SEPARATOR . $object)) {
472
473 $this->rrmdir($dir . DIRECTORY_SEPARATOR . $object);
474
475 } else {
476
477 @unlink($dir . DIRECTORY_SEPARATOR . $object);
478
479 }
480
481 }
482
483 }
484
485 @rmdir($dir);
486
487 } else {
488
489 if (file_exists($dir) && is_file($dir)) {
490
491 @unlink($dir);
492
493 }
494
495 }
496
497 }
498
499 public function fixDumbWindowsSlashes() {
500
501 // Extraction directory (no trailing slash)
502 $tmp = $this->tmp;
503
504 $files = scandir($tmp);
505 if (sizeof($files) > 10) {
506
507 $this->migration->log(__("Performing solution to Windows backslashes...", 'backup-backup'), 'STEP');
508
509 foreach ($files as $index => $file) {
510
511 if (strpos($file, '\\') !== false) {
512
513 $path = explode('\\', $file);
514 $filename = array_pop($path);
515 $dirname = $tmp . DIRECTORY_SEPARATOR . join(DIRECTORY_SEPARATOR, $path);
516
517 if (!(file_exists($dirname) && is_dir($dirname))) {
518 mkdir($dirname, 0755, true);
519 }
520
521 rename($tmp . DIRECTORY_SEPARATOR . $file, $dirname . DIRECTORY_SEPARATOR . $filename);
522
523 }
524
525 }
526
527 $this->migration->log(__("Windows file structure fixed...", 'backup-backup'), 'SUCCESS');
528
529 }
530
531 }
532
533 public function findTablePrefixByFiles($manifestPrefix) {
534
535 $tmp = $this->tmp . DIRECTORY_SEPARATOR . 'db_tables';
536 $manifestPrefixExist = false;
537
538 if (!(file_exists($tmp) && is_dir($tmp))) {
539 return $manifestPrefix;
540 }
541
542 $originalPrefix = [
543 file_exists($tmp . DIRECTORY_SEPARATOR . $manifestPrefix . 'options.sql'),
544 file_exists($tmp . DIRECTORY_SEPARATOR . $manifestPrefix . 'users.sql'),
545 file_exists($tmp . DIRECTORY_SEPARATOR . $manifestPrefix . 'usermeta.sql'),
546 file_exists($tmp . DIRECTORY_SEPARATOR . $manifestPrefix . 'posts.sql'),
547 file_exists($tmp . DIRECTORY_SEPARATOR . $manifestPrefix . 'postmeta.sql')
548 ];
549
550 $lowerPrefix = [
551 file_exists($tmp . DIRECTORY_SEPARATOR . strtolower($manifestPrefix) . 'options.sql'),
552 file_exists($tmp . DIRECTORY_SEPARATOR . strtolower($manifestPrefix) . 'users.sql'),
553 file_exists($tmp . DIRECTORY_SEPARATOR . strtolower($manifestPrefix) . 'usermeta.sql'),
554 file_exists($tmp . DIRECTORY_SEPARATOR . strtolower($manifestPrefix) . 'posts.sql'),
555 file_exists($tmp . DIRECTORY_SEPARATOR . strtolower($manifestPrefix) . 'postmeta.sql')
556 ];
557
558 if (count(array_filter($lowerPrefix)) == 5 || count(array_filter($originalPrefix)) == 5) {
559 return $manifestPrefix;
560 }
561
562 $files = scandir($tmp);
563 $prefixes = [];
564
565 foreach ($files as $index => $file) {
566
567 if ($file == '.' || $file == '..') continue;
568
569 if (substr($file, 0, strlen($manifestPrefix)) == $manifestPrefix) {
570 $manifestPrefixExist = true;
571 return $manifestPrefix;
572 }
573
574 foreach ($files as $index2 => $comparefile) {
575
576 if ($comparefile == $file) continue;
577 $currentTopPrefix = '';
578
579 for ($i = 0; $i < min(strlen($comparefile), strlen($file)); ++$i) {
580
581 if ($file[$i] == $comparefile[$i]) {
582 $currentTopPrefix .= $file[$i];
583 } else break;
584
585 }
586
587 if ($currentTopPrefix != '') {
588 if (isset($prefixes[$currentTopPrefix])) {
589 $prefixes[$currentTopPrefix]++;
590 } else {
591 $prefixes[$currentTopPrefix] = 1;
592 }
593 }
594
595 }
596
597 }
598
599 if (sizeof($prefixes) <= 0) return $manifestPrefix;
600 else return array_search(max($prefixes), $prefixes);
601
602 }
603
604 public function makeUnZIP() {
605
606 // Source
607 $src = $this->src;
608
609 // Extract
610 $this->zip = new Zip();
611
612 if ($this->isCLI) {
613
614 $isOk = $this->zip->unzip_file($src, $this->tmp, $this->migration);
615
616 } else {
617
618 $last_seek = $this->recent_export_seek;
619
620 $file = new \SplFileObject($this->scanFile);
621 $file->seek($file->getSize());
622 $total_lines = $file->key() + 1;
623 $files = [];
624 $seek_begin = 0;
625 $recent_seek = $last_seek;
626 $shouldRepeat = false;
627
628 $batch = 50;
629 if ($total_lines > 1000) $batch = 100;
630 if ($total_lines > 2000) $batch = 200;
631 if ($total_lines > 6000) $batch = 300;
632 if ($total_lines > 12000) $batch = 500;
633 if ($total_lines > 36000) $batch = 1000;
634 if ($total_lines > 50000) $batch = 2500;
635 if ($total_lines > 100000) $batch = 5000;
636 if ($total_lines > 150000) $batch = 10000;
637 if ($total_lines > 200000) $batch = 20000;
638
639 if (defined('BMI_MAX_FILE_EXTRACTION_LIMIT')) {
640 $definedSize = BMI_MAX_FILE_EXTRACTION_LIMIT;
641 if (is_numeric($definedSize) && $definedSize > 50 && $definedSize < 20000) {
642 $batch = intval($definedSize);
643 }
644 }
645
646 if ($this->firstExtract == true) {
647 $this->migration->log(__("Preparing batching technique for extraction...", 'backup-backup'), 'STEP');
648 $this->migration->log(__('Files exported per batch: ', 'backup-backup') . $batch, 'INFO');
649 }
650
651 for ($i = $last_seek; $i < $total_lines; ++$i) {
652
653 $file->seek($i);
654 $line = trim($file->current());
655
656 if ($line && strlen($line) > 0) {
657
658 $files[] = $line;
659
660 }
661
662 $seek_begin++;
663 $recent_seek = $i;
664 if ($seek_begin > $batch) {
665
666 $shouldRepeat = true;
667 break;
668
669 }
670
671 }
672
673 $isOk = $this->zip->extract_files($src, $files, $this->tmp, $this->migration, $this->firstExtract);
674
675 }
676
677
678 if (!$isOk) {
679
680 // Verbose
681 $this->migration->log(__('Failed to extract the files...', 'backup-backup'), 'WARN');
682 $this->cleanup();
683
684 return false;
685
686 } else {
687
688 if (!$this->isCLI) {
689
690 $i = $recent_seek + 1;
691 $milestone = intval((($i / $total_lines) * 100) / 4);
692 $this->migration->progress($milestone);
693
694 $plus = -1;
695 if ($shouldRepeat != true) $plus = 0;
696
697 $this->migration->log(__('Extraction milestone: ', 'backup-backup') . ($i + $plus) . '/' . $total_lines . ' (' . number_format(($i / $total_lines) * 100, 2) . '%)', 'INFO');
698
699 }
700
701 }
702
703 // Verbose
704 if (!$this->isCLI && $shouldRepeat === true) {
705
706 $this->recent_export_seek = $recent_seek;
707 return 'repeat';
708
709 } else {
710
711 $this->migration->log(__('Files extracted...', 'backup-backup'), 'SUCCESS');
712 return true;
713
714 }
715
716 }
717
718 public function fixWPLogin(&$manifest) {
719
720 try {
721
722 global $wpdb;
723
724 $loginslug = false;
725 $sql = $wpdb->prepare("SELECT option_value FROM " . $this->dbFoundPrefix . "options WHERE option_name = 'bwpl_slug';");
726 $results = $wpdb->get_results($sql);
727
728 if (sizeof($results) > 0) $loginslug = $results[0]->option_value;
729
730 if ($loginslug != false && is_string($loginslug) && strlen($loginslug) >= 1) {
731
732 $wploginfile = trailingslashit(ABSPATH) . 'wp-login.php';
733 $blockedloginfile = trailingslashit(ABSPATH) . $loginslug . '-wp-login.php';
734
735 if (file_exists($wploginfile) && !file_exists($blockedloginfile)) {
736 @copy($wploginfile, $blockedloginfile);
737 }
738
739 }
740
741 }
742 catch (\Exception $e) {}
743 catch (\Throwable $e) {}
744
745 }
746
747 public function randomString($length = 64) {
748
749 $chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
750 $str = "";
751
752 for ($i = 0; $i < $length; ++$i) {
753
754 $str .= $chars[mt_rand(0, strlen($chars) - 1)];
755
756 }
757
758 return $str;
759
760 }
761
762 public function makeWPConfigCopy() {
763
764 $this->migration->log(__('Saving wp-config file...', 'backup-backup'), 'STEP');
765 $configData = file_get_contents(ABSPATH . 'wp-config.php');
766 if ($configData && strlen($configData) > 0) {
767 file_put_contents(ABSPATH . 'wp-config.' . $this->tmptime . '.php', $configData);
768 $this->migration->log(__('File wp-config saved', 'backup-backup'), 'SUCCESS');
769 } else {
770 $this->migration->log(__('Could not backup/read wp-config file.', 'backup-backup'), 'WARN');
771 }
772
773 }
774
775 public function getCurrentManifest($first = false) {
776
777 if ($first == true) {
778 $this->migration->log(__('Getting backup manifest...', 'backup-backup'), 'STEP');
779 }
780
781 $manifest = json_decode(file_get_contents($this->tmp . DIRECTORY_SEPARATOR . 'bmi_backup_manifest.json'));
782
783 if ($first == true) {
784 $this->migration->log(__('Manifest loaded', 'backup-backup'), 'SUCCESS');
785 }
786
787 return $manifest;
788
789 }
790
791 public function restoreBackupFromFiles($manifest) {
792
793 $this->same_domain = untrailingslashit($manifest->dbdomain) == untrailingslashit($this->siteurl) ? true : false;
794 $this->migration->log(__('Restoring files (this process may take a while)...', 'backup-backup'), 'STEP');
795 $contentDirectory = $this->WP_CONTENT_DIR;
796 $pathtowp = DIRECTORY_SEPARATOR . 'wp-content';
797 if (isset($manifest->config->WP_CONTENT_DIR) && isset($manifest->config->ABSPATH)) {
798 $absi = $manifest->config->ABSPATH;
799 $cotsi = $manifest->config->WP_CONTENT_DIR;
800 if (strlen($absi) <= strlen($cotsi) && substr($cotsi, 0, strlen($absi)) == $absi) {
801 $inside = true;
802 $pathtowp = substr($cotsi, strlen($absi));
803 } else {
804 $inside = false;
805 $pathtowp = $cotsi;
806 }
807 }
808
809 $this->replaceAll($pathtowp);
810 $this->migration->log(__('All files restored successfully.', 'backup-backup'), 'SUCCESS');
811
812 }
813
814 public function restoreDatabaseV1(&$manifest) {
815
816 $this->migration->log(__('Older backup detected, using V1 engine to restore database...', 'backup-backup'), 'WARN');
817 $this->migration->log(__('Database size: ' . BMP::humanSize(filesize($this->tmp . DIRECTORY_SEPARATOR . 'bmi_database_backup.sql')), 'backup-backup'), 'INFO');
818 $old_domain = $manifest->dbdomain;
819 $new_domain = $this->siteurl; // parse_url(home_url())['host'];
820
821 $abs = BMP::fixSlashes($manifest->config->ABSPATH);
822 $newabs = BMP::fixSlashes(ABSPATH);
823 $file = $this->tmp . DIRECTORY_SEPARATOR . 'bmi_database_backup.sql';
824 $this->db->importDatabase($file, $old_domain, $new_domain, $abs, $newabs, $this->dbFoundPrefix, $this->siteurl, $this->home);
825 $this->migration->log(__('Database restored', 'backup-backup'), 'SUCCESS');
826
827 }
828
829 public function setDBProgress($xi, $init_start, $table_names_alter) {
830
831 $this->db_xi = $xi;
832 $this->ini_start = $init_start;
833 $this->table_names_alter = $table_names_alter;
834
835 }
836
837 public function alter_tables(&$manifest) {
838
839 $storage = $this->tmp . DIRECTORY_SEPARATOR . 'db_tables';
840
841 $queriesAll = $manifest->total_queries;
842 if (isset($this->conversionStats['total_queries'])) {
843 $queriesAll = $this->conversionStats['total_queries'];
844 }
845
846 // $manifest->total_queries # the other solution
847 $importer = new BetterDatabaseImport($storage, $queriesAll, $manifest->config->ABSPATH, $manifest->dbdomain, $this->siteurl, $this->migration, $this->isCLI, $this->conversionStats);
848
849 $importer->xi = $this->db_xi;
850 $importer->init_start = $this->ini_start;
851 $importer->table_names_alter = $this->table_names_alter;
852
853 $importer->alter_names();
854 $this->migration->log(__('Database restored', 'backup-backup'), 'SUCCESS');
855
856 }
857
858 public function search_replace_v3(&$manifest) {
859
860 $res = false;
861 if (!$this->isCLI || $this->v3Importer == null) {
862 $storage = $this->tmp . DIRECTORY_SEPARATOR . 'db_tables';
863 $importer = new EvenBetterDatabaseImport($storage, false, $manifest, $this->migration, $this->splitting, $this->isCLI);
864 $res = $importer->searchReplace($this->replaceStep, $this->tableIndex, $this->currentReplacePage, $this->totalReplacePage, $this->fieldAdjustments, $manifest->config->table_prefix);
865 } else {
866 $res = $this->v3Importer->searchReplace($this->replaceStep, $this->tableIndex, $this->currentReplacePage, $this->totalReplacePage, $this->fieldAdjustments, $manifest->config->table_prefix);
867 }
868
869 if ($res && is_array($res) && $res['finished'] == true) {
870 $this->migration->log(__('Database restored', 'backup-backup'), 'SUCCESS');
871 }
872
873 return $res;
874
875 }
876
877 public function alter_tables_v3(&$manifest) {
878
879 if (!$this->isCLI || $this->v3Importer == null) {
880 $storage = $this->tmp . DIRECTORY_SEPARATOR . 'db_tables';
881 $importer = new EvenBetterDatabaseImport($storage, false, $manifest, $this->migration, $this->splitting, $this->isCLI);
882 $importer->alter_tables();
883
884 // Modify the WP Config and replace
885 $this->replaceDbPrefixInWPConfig($manifest);
886
887 $importer->enablePlugins();
888 } else {
889 $this->v3Importer->alter_tables();
890
891 // Modify the WP Config and replace
892 $this->replaceDbPrefixInWPConfig($manifest);
893
894 $this->v3Importer->enablePlugins();
895 }
896
897 $this->migration->log(__('Database restored', 'backup-backup'), 'SUCCESS');
898
899 }
900
901 public function restoreDatabaseV3(&$manifest) {
902
903 $storage = $this->tmp . DIRECTORY_SEPARATOR . 'db_tables';
904 $this->v3Importer = new EvenBetterDatabaseImport($storage, $this->firstDB, $manifest, $this->migration, $this->splitting, $this->isCLI);
905 $finished = $this->v3Importer->start();
906
907 if ($finished === true) {
908
909 return true;
910
911 } else {
912
913 return ['status' => 'new_file'];
914
915 }
916
917 }
918
919 public function restoreDatabaseV2(&$manifest) {
920
921 $storage = $this->tmp . DIRECTORY_SEPARATOR . 'db_tables';
922
923 if ($this->firstDB == true) {
924 $this->migration->log(__('Successfully detected backup created with V2 engine, importing...', 'backup-backup'), 'INFO');
925 $this->migration->log(__('Restoring database...', 'backup-backup'), 'STEP');
926 }
927
928 $queriesAll = $manifest->total_queries;
929 if (isset($this->conversionStats['total_queries'])) {
930 $queriesAll = $this->conversionStats['total_queries'];
931 }
932 $importer = new BetterDatabaseImport($storage, $queriesAll, $manifest->config->ABSPATH, $manifest->dbdomain, $this->siteurl, $this->migration, $this->isCLI, $this->conversionStats);
933
934 if ($this->isCLI) {
935
936 $importer->showFirstLogs();
937 $importer->import();
938
939 } else {
940
941 if ($this->firstDB == true) {
942 $importer->showFirstLogs();
943 }
944
945 $sqlFiles = $importer->get_sql_files($this->firstDB);
946
947 if ($this->firstDB != true) {
948 $importer->xi = $this->db_xi;
949 $importer->init_start = $this->ini_start;
950 $importer->table_names_alter = $this->table_names_alter;
951 }
952
953 if ($this->continueFile != false && $this->continueFile != '' && $this->continueSeek != false && $this->continueSeek != '') {
954
955 $import = $importer->restore_by_file($this->continueFile, $this->continueSeek);
956 $importer->queries_ended();
957 $this->continueFile = $this->continueFile;
958 $this->setDBProgress($importer->xi, $importer->init_start, $importer->table_names_alter);
959
960 } else {
961
962 if (sizeof($sqlFiles) > 0) {
963
964 $import = $importer->restore_by_file($sqlFiles[0]);
965 $importer->queries_ended();
966 $this->continueFile = $sqlFiles[0];
967 $this->setDBProgress($importer->xi, $importer->init_start, $importer->table_names_alter);
968
969 } else {
970
971 return true;
972
973 }
974
975 }
976
977 if ($import !== true) {
978
979 return ['status' => 'repeat', 'file' => $this->continueFile, 'seek' => $import];
980
981 } else {
982
983 return ['status' => 'new_file'];
984
985 }
986
987 }
988
989 $this->migration->log(__('Database restored', 'backup-backup'), 'SUCCESS');
990
991 }
992
993 public function restoreDatabaseDynamic(&$manifest) {
994
995 if ($this->firstDB == true) {
996 $this->migration->log(__('Checking the database structure...', 'backup-backup'), 'STEP');
997 }
998
999 if (is_dir($this->tmp . DIRECTORY_SEPARATOR . 'db_tables')) {
1000
1001 $forcev3Engine = false;
1002 if (isset($manifest->db_backup_engine) && $manifest->db_backup_engine === 'v4') {
1003 if ($this->v3engine == false) {
1004 $forcev3Engine = true;
1005
1006 if ($this->firstDB == true) {
1007 $this->migration->log(__('New search replace is disabled, nevertheless your backup does not support it, forcing to use new S&R engine.', 'backup-backup'), 'WARN');
1008 }
1009 }
1010 }
1011
1012 if ($this->v3engine || $forcev3Engine) {
1013
1014 if (!$this->isCLI) {
1015
1016 $this->v3RestoreUsed = true;
1017 $import = $this->restoreDatabaseV3($manifest);
1018 return $import;
1019
1020 } else {
1021
1022 $this->v3RestoreUsed = true;
1023 $this->restoreDatabaseV3($manifest);
1024
1025 }
1026
1027 } else {
1028
1029 if (!$this->isCLI) {
1030
1031 $import = $this->restoreDatabaseV2($manifest);
1032 return $import;
1033
1034 } else {
1035
1036 $this->restoreDatabaseV2($manifest);
1037
1038 }
1039
1040 }
1041
1042 } elseif (file_exists($this->tmp . DIRECTORY_SEPARATOR . 'bmi_database_backup.sql')) {
1043
1044 $this->restoreDatabaseV1($manifest);
1045
1046 } else {
1047
1048 $this->migration->log(__('This backup does not contain database copy, omitting...', 'backup-backup'), 'INFO');
1049 return false;
1050
1051 }
1052
1053 return true;
1054
1055 }
1056
1057 public function cleanupCurrentThemesAndPlugins() {
1058
1059 if ($this->cleanupbefore == true) {
1060
1061 $this->migration->log(__('Moving current themes and plugins.', 'backup-backup'), 'STEP');
1062
1063 $plugins_path = BMP::fixSlashes(WP_PLUGIN_DIR);
1064 $themes_path = BMP::fixSlashes(dirname(get_template_directory()));
1065
1066 $plugins = [];
1067 if (file_exists($plugins_path)) {
1068 $plugins = array_values(array_diff(scandir($plugins_path), ['..', '.', 'backup-backup', 'backup-backup-pro']));
1069 }
1070
1071 $themes = [];
1072 if (file_exists($themes_path)) {
1073 $themes = array_values(array_diff(scandir($themes_path), ['..', '.', 'backup-backup', 'backup-backup-pro']));
1074 }
1075
1076 $destination = BMI_BACKUPS_DEFAULT . DIRECTORY_SEPARATOR . 'clean-ups';
1077 $destination_unique = $destination . DIRECTORY_SEPARATOR . 'restoration_' . intval($this->start);
1078
1079 $destination_plugins = $destination_unique . DIRECTORY_SEPARATOR . 'plugins';
1080 $destination_themes = $destination_unique . DIRECTORY_SEPARATOR . 'themes';
1081
1082 if (!file_exists($destination)) @mkdir($destination, 0775, true);
1083 if (!file_exists($destination_unique)) @mkdir($destination_unique, 0775, true);
1084 if (!file_exists($destination_plugins)) @mkdir($destination_plugins, 0775, true);
1085 if (!file_exists($destination_themes)) @mkdir($destination_themes, 0775, true);
1086
1087 for ($i = 0; $i < sizeof($plugins); ++$i) {
1088 $pluginPath = trailingslashit($plugins_path) . $plugins[$i];
1089 $destPath = trailingslashit($destination_plugins) . $plugins[$i];
1090 rename($pluginPath, $destPath);
1091 }
1092
1093 for ($i = 0; $i < sizeof($themes); ++$i) {
1094 $themePath = trailingslashit($themes_path) . $themes[$i];
1095 $destPath = trailingslashit($destination_themes) . $themes[$i];
1096 rename($themePath, $destPath);
1097 }
1098
1099 $this->migration->log(__('Themes and plugins moved to safe directory.', 'backup-backup'), 'SUCCESS');
1100
1101 }
1102
1103 return true;
1104
1105 }
1106
1107 public function rescueCleanedThemesAndPlugins() {
1108
1109 if ($this->cleanupbefore == true) {
1110
1111 $this->migration->log(__('Restoring moved themes and plugins.', 'backup-backup'), 'INFO');
1112
1113 $plugins_path = BMP::fixSlashes(WP_PLUGIN_DIR);
1114 $themes_path = BMP::fixSlashes(dirname(get_template_directory()));
1115
1116 $destination = BMI_BACKUPS_DEFAULT . DIRECTORY_SEPARATOR . 'clean-ups';
1117 $destination_unique = $destination . DIRECTORY_SEPARATOR . 'restoration_' . intval($this->start);
1118
1119 $destination_plugins = $destination_unique . DIRECTORY_SEPARATOR . 'plugins';
1120 $destination_themes = $destination_unique . DIRECTORY_SEPARATOR . 'themes';
1121
1122 $plugins = [];
1123 if (file_exists($destination_plugins)) {
1124 $plugins = array_values(array_diff(scandir($destination_plugins), ['..', '.']));
1125 }
1126
1127 $themes = [];
1128 if (file_exists($destination_themes)) {
1129 $themes = array_values(array_diff(scandir($destination_themes), ['..', '.']));
1130 }
1131
1132 if (!file_exists($plugins_path)) @mkdir($plugins_path, 0775, true);
1133 if (!file_exists($themes_path)) @mkdir($themes_path, 0775, true);
1134
1135 for ($i = 0; $i < sizeof($plugins); ++$i) {
1136 $pluginPath = trailingslashit($destination_plugins) . $plugins[$i];
1137 $destPath = trailingslashit($plugins_path) . $plugins[$i];
1138 rename($pluginPath, $destPath);
1139 }
1140
1141 for ($i = 0; $i < sizeof($themes); ++$i) {
1142 $themePath = trailingslashit($destination_themes) . $themes[$i];
1143 $destPath = trailingslashit($themes_path) . $themes[$i];
1144 rename($themePath, $destPath);
1145 }
1146
1147 }
1148
1149 return true;
1150
1151 }
1152
1153 public function removeCleanedThemesAndPlugins() {
1154
1155 if (defined('BMI_KEEP_CLEANUPS') && BMI_KEEP_CLEANUPS == true) {
1156
1157 return true;
1158
1159 } else {
1160
1161 if ($this->cleanupbefore == true) {
1162
1163 $this->migration->log(__('Removing old plugins and themes moved before restoration.', 'backup-backup'), 'INFO');
1164
1165 $destination = BMI_BACKUPS_DEFAULT . DIRECTORY_SEPARATOR . 'clean-ups';
1166 $destination_unique = $destination . DIRECTORY_SEPARATOR . 'restoration_' . intval($this->start);
1167 $this->rrmdir($destination_unique);
1168
1169 }
1170
1171 }
1172
1173 }
1174
1175 public function replaceDbPrefixInWPConfig(&$manifest) {
1176
1177 $abs = untrailingslashit(ABSPATH);
1178 $curr_prefix = $this->table_prefix;
1179 $new_prefix = $this->dbFoundPrefix;
1180
1181 $this->migration->log('Detected table prefix: ' . $new_prefix, 'VERBOSE');
1182 $this->migration->log('Forwarded table prefix: ' . $curr_prefix, 'VERBOSE');
1183 $this->migration->log('Manifest table prefix: ' . $manifest->config->table_prefix, 'VERBOSE');
1184
1185 // if (strtolower($manifest->config->table_prefix) == strtolower($new_prefix)) {
1186 // $new_prefix = $manifest->config->table_prefix;
1187 // }
1188
1189 // if (strlen(trim($manifest->config->table_prefix)) == 0) {
1190 // return;
1191 // }
1192
1193 // if (strlen(trim($new_prefix)) == 0) {
1194 // return;
1195 // }
1196
1197 $new_prefix = $manifest->config->table_prefix;
1198
1199 $this->migration->log(__('Restoring wp-config file...', 'backup-backup'), 'STEP');
1200 $wpconfigDir = $abs . DIRECTORY_SEPARATOR . 'wp-config.' . $this->tmptime . '.php';
1201 if (file_exists($wpconfigDir) && is_readable($wpconfigDir) && is_writable($wpconfigDir)) {
1202
1203 // rename($abs . DIRECTORY_SEPARATOR . 'wp-config.' . $this->tmptime . '.php', $abs . DIRECTORY_SEPARATOR . 'wp-config.php');
1204 $wpconfig = file_get_contents($abs . DIRECTORY_SEPARATOR . 'wp-config.php');
1205 if (strpos($wpconfig, '"' . $curr_prefix . '";') !== false) {
1206 $wpconfig = str_replace('"' . $curr_prefix . '";', '"' . $new_prefix . '";', $wpconfig);
1207 } elseif (strpos($wpconfig, "'" . $curr_prefix . "';") !== false) {
1208 $wpconfig = str_replace("'" . $curr_prefix . "';", "'" . $new_prefix . "';", $wpconfig);
1209 }
1210
1211 file_put_contents($abs . DIRECTORY_SEPARATOR . 'wp-config.php', $wpconfig);
1212
1213 $this->migration->log(__('WP-Config restored', 'backup-backup'), 'SUCCESS');
1214
1215 } else {
1216
1217 $this->migration->log(__('Cannot write to WP-Config, if you need to change database prefix, please do it manually.', 'backup-backup'), 'WARN');
1218
1219 }
1220
1221 }
1222
1223 public function restoreOriginalWPConfig($remove = true) {
1224
1225 // $abs = untrailingslashit(ABSPATH);
1226 // $tmp_file_f = $abs . DIRECTORY_SEPARATOR . 'wp-config.' . $this->tmptime . '.php';
1227 // if (file_exists($tmp_file_f)) {
1228 // copy($tmp_file_f, $abs . DIRECTORY_SEPARATOR . 'wp-config.php');
1229 // if ($remove === true) @unlink($tmp_file_f);
1230 // }
1231 //
1232 // wp_load_alloptions(true);
1233
1234 }
1235
1236 public function makeNewLoginSession(&$manifest) {
1237
1238 wp_load_alloptions(true);
1239
1240 $this->migration->log(__('Making new login session', 'backup-backup'), 'STEP');
1241
1242 if ($manifest->cron === true || $manifest->cron === 'true' || $manifest->uid === 0 || $manifest->uid === '0') {
1243 $manifest->uid = 1;
1244 }
1245
1246 if (is_numeric($manifest->uid)) {
1247 $existant = (bool) get_users(['include' => $manifest->uid, 'fields' => 'ID']);
1248 if ($existant) {
1249 $user = get_user_by('id', $manifest->uid);
1250 } else {
1251 $existant = (bool) get_users(['include' => 1, 'fields' => 'ID']);
1252 if ($existant) {
1253 $user = get_user_by('id', 1);
1254 }
1255 }
1256 }
1257
1258 if (isset($user) && is_object($user) && property_exists($user, 'ID')) {
1259 remove_all_actions('wp_login', -1000);
1260 clean_user_cache(get_current_user_id());
1261 clean_user_cache($user->ID);
1262 wp_clear_auth_cookie();
1263 wp_set_current_user($user->ID, $user->user_login);
1264 wp_set_auth_cookie($user->ID, 1, is_ssl());
1265 do_action('wp_login', $user->user_login, $user);
1266 update_user_caches($user);
1267 }
1268
1269 $this->migration->log(__('User should be logged in', 'backup-backup'), 'SUCCESS');
1270
1271 }
1272
1273 public function setOrUpdateXhria() {
1274
1275 // Update Original Local Storage Path
1276 if ($this->backupStorage && is_string($this->backupStorage)) {
1277 if (function_exists('wp_load_alloptions')) wp_load_alloptions(true);
1278 delete_option('BMI::STORAGE::LOCAL::PATH');
1279 if (function_exists('wp_load_alloptions')) wp_load_alloptions(true);
1280 update_option('BMI::STORAGE::LOCAL::PATH', $this->backupStorage);
1281 }
1282
1283 if ($this->code && is_string($this->code) && strlen($this->code) > 0) update_option('z__bmi_xhria', $this->code);
1284 else delete_option('z__bmi_xhria');
1285
1286 }
1287
1288 public function clearElementorCache() {
1289
1290 $file = trailingslashit(wp_upload_dir()['basedir']) . 'elementor';
1291 if (file_exists($file) && is_dir($file)) {
1292 $this->migration->log(__('Clearing elementor template cache...', 'backup-backup'), 'STEP');
1293 $path = $file . DIRECTORY_SEPARATOR . '*';
1294 foreach (glob($path) as $file_path) if (!is_dir($file_path)) @unlink($file_path);
1295 $this->migration->log(__('Elementor cache cleared!', 'backup-backup'), 'SUCCESS');
1296 }
1297
1298 }
1299
1300 public function finalCleanUP() {
1301
1302 $this->migration->log(__('Cleaning temporary files...', 'backup-backup'), 'STEP');
1303 $this->cleanup();
1304 $this->removeCleanedThemesAndPlugins();
1305 $this->migration->log(__('Temporary files cleaned', 'backup-backup'), 'SUCCESS');
1306
1307 }
1308
1309 public function handleError($e) {
1310
1311 // Restore moved themes and plugins
1312 $this->rescueCleanedThemesAndPlugins();
1313
1314 // On this tragedy at least remove tmp files
1315 $this->migration->log(__('Something bad happened...', 'backup-backup'), 'ERROR');
1316 if (method_exists($e, 'getMessage')) {
1317 $this->migration->log($e->getMessage(), 'ERROR');
1318 $this->migration->log($e->getLine() . ' @ ' . $e->getFile(), 'ERROR');
1319 }
1320 $this->cleanup();
1321
1322 }
1323
1324 public function makeTMPDirectory() {
1325
1326 // Make temp dir
1327 $this->migration->log(__('Making temporary directory', 'backup-backup'), 'INFO');
1328 if (!(is_dir($this->tmp) || file_exists($this->tmp))) {
1329 mkdir($this->tmp, 0755, true);
1330 }
1331
1332 // Deny read of this folder
1333 copy(BMI_INCLUDES . DIRECTORY_SEPARATOR . 'htaccess' . DIRECTORY_SEPARATOR . '.htaccess', $this->tmp . DIRECTORY_SEPARATOR . '.htaccess');
1334 touch($this->tmp . DIRECTORY_SEPARATOR . 'index.html');
1335 touch($this->tmp . DIRECTORY_SEPARATOR . 'index.php');
1336
1337 }
1338
1339 public function backupLocalOptions() {
1340
1341 $pro_gd_token = get_option('bmi_pro_gd_token', false);
1342 $pro_gd_client_id = get_option('bmi_pro_gd_client_id', false);
1343
1344 if ($pro_gd_token != false && $pro_gd_client_id != false) {
1345 $tempKeyDriveFile = BMI_TMP . DIRECTORY_SEPARATOR . 'driveKeys.php';
1346 $content = "<?php \n";
1347 $content .= "//" . $pro_gd_token . "\n";
1348 $content .= "//" . $pro_gd_client_id . "\n";
1349 file_put_contents($tempKeyDriveFile, $content);
1350 }
1351
1352 }
1353
1354 private function makeRestoreSecret() {
1355
1356 $this->migration->log(__('Making new secret key for current restore process.', 'backup-backup'), 'STEP');
1357 $secret = $this->randomString();
1358 file_put_contents(BMI_TMP . DIRECTORY_SEPARATOR . '.restore_secret', $secret);
1359 $this->migration->log(__('Secret key generated, it will be returned to you (ping).', 'backup-backup'), 'SUCCESS');
1360
1361 return $secret;
1362
1363 }
1364
1365 public function listBackupContents() {
1366
1367 $manager = new ZipManager();
1368
1369 $save = $this->scanFile;
1370 $amount = $manager->getZipContentList($this->src, $save);
1371
1372 $this->migration->log(__('Scan found ', 'backup-backup') . $amount . __(' files inside the backup.', 'backup-backup'), 'INFO');
1373
1374 return $amount;
1375
1376 }
1377
1378 public function extractTo($secret = null) {
1379
1380 try {
1381
1382 // Require Universal Zip Library
1383 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'zipper' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'zip.php';
1384
1385 // Make restore secret
1386 if (!$this->isCLI && $this->batchStep == 0) {
1387
1388 // Verbose
1389 Logger::log('Restoring site...');
1390
1391 if ((gettype($secret) != 'string' || strlen($secret) != 64)) {
1392
1393 $secret = $this->makeRestoreSecret();
1394 BMP::res(['status' => 'secret', 'tmp' => $this->tmptime, 'secret' => $secret, 'options' => [
1395 'code' => $this->code,
1396 'start' => $this->start,
1397 'step' => 0
1398 ]]);
1399 return;
1400
1401 } else {
1402
1403 // $this->migration->log(__('Secret key detected successfully (pong)!', 'backup-backup'), 'INFO');
1404
1405 }
1406
1407 }
1408
1409 // STEP: 1
1410 if ($this->isCLI || $this->batchStep == 1) {
1411
1412 if (!$this->isCLI) {
1413
1414 $this->migration->log(__('Secret key detected successfully (pong)!', 'backup-backup'), 'INFO');
1415
1416 }
1417
1418 // Make temporary directory
1419 $this->makeTMPDirectory();
1420
1421 // Migrate local options
1422 $this->backupLocalOptions();
1423
1424 // Time start
1425 $this->migration->log(__('Scanning archive...', 'backup-backup'), 'STEP');
1426
1427 if (!$this->isCLI) {
1428
1429 BMP::res(['status' => 'restore_ongoing', 'tmp' => $this->tmptime, 'secret' => $secret, 'options' => [
1430 'code' => $this->code,
1431 'start' => $this->start,
1432 'step' => 1
1433 ]]);
1434
1435 return;
1436
1437 }
1438
1439 }
1440
1441 // STEP: 2
1442 if ($this->isCLI || $this->batchStep == 2) {
1443
1444 // Get ZIP contents for batch unzipping
1445 $this->fileAmount = $this->listBackupContents();
1446 $this->cleanupCurrentThemesAndPlugins();
1447
1448 if (!$this->isCLI) {
1449
1450 BMP::res(['status' => 'restore_ongoing', 'tmp' => $this->tmptime, 'secret' => $secret, 'options' => [
1451 'code' => $this->code,
1452 'start' => $this->start,
1453 'amount' => $this->fileAmount,
1454 'step' => 2
1455 ]]);
1456
1457 return;
1458
1459 }
1460
1461 }
1462
1463 // STEP: 3
1464 if ($this->isCLI || $this->batchStep == 3) {
1465
1466 // UnZIP the backup
1467 try {
1468 $unzipped = $this->makeUnZIP();
1469 } catch (\Exception $e) {
1470 $this->handleError($e);
1471 return;
1472 } catch (\Throwable $t) {
1473 $this->handleError($t);
1474 return;
1475 }
1476
1477 if ($unzipped === false) {
1478
1479 $this->handleError(__('File extraction process failed.', 'backup-backup'));
1480 return;
1481
1482 }
1483
1484 if (!$this->isCLI) {
1485
1486 $shouldRepeat = false;
1487 if ($unzipped === 'repeat') {
1488
1489 $shouldRepeat = true;
1490
1491 } else {
1492
1493 $shouldRepeat = false;
1494
1495 }
1496
1497 BMP::res(['status' => 'restore_ongoing', 'tmp' => $this->tmptime, 'secret' => $secret, 'options' => [
1498 'code' => $this->code,
1499 'start' => $this->start,
1500 'amount' => $this->fileAmount,
1501 'recent_export_seek' => $this->recent_export_seek,
1502 'repeat_export' => $shouldRepeat,
1503 'firstExtract' => $this->firstExtract,
1504 'step' => 3
1505 ]]);
1506
1507 return;
1508
1509 }
1510
1511 }
1512
1513 // STEP: 4
1514 if ($this->isCLI || $this->batchStep == 4) {
1515
1516 // Check if extracted files are not in backslashed Windows version, otherwise fix it
1517 $this->fixDumbWindowsSlashes();
1518 $this->removeUnwantedFiles();
1519
1520 // WP Config backup
1521 $this->makeWPConfigCopy();
1522
1523 if (!$this->isCLI) {
1524
1525 BMP::res(['status' => 'restore_ongoing', 'tmp' => $this->tmptime, 'secret' => $secret, 'options' => [
1526 'code' => $this->code,
1527 'start' => $this->start,
1528 'amount' => $this->fileAmount,
1529 'storage' => get_option('BMI::STORAGE::LOCAL::PATH', false),
1530 'step' => 4
1531 ]]);
1532
1533 return;
1534
1535 }
1536
1537 }
1538
1539 // STEP: 5
1540 if ($this->isCLI || $this->batchStep == 5) {
1541
1542 // Get manifest
1543 $manifest = $this->getCurrentManifest(true);
1544
1545 try {
1546
1547 if (isset($manifest->version)) {
1548 $this->migration->log(__('Backup Migration version used for that backup: ', 'backup-backup') . $manifest->version, 'INFO');
1549 } else {
1550 $this->migration->log(__('Backup was made with unknown version of Backup Migration plugin.', 'backup-backup'), 'INFO');
1551 }
1552
1553 } catch (\Exception $e) {
1554
1555 $this->migration->log(__('Backup was made with unknown version of Backup Migration plugin.', 'backup-backup'), 'INFO');
1556
1557 } catch (\Throwable $e) {
1558
1559 $this->migration->log(__('Backup was made with unknown version of Backup Migration plugin.', 'backup-backup'), 'INFO');
1560
1561 }
1562
1563 // Even remove extracted WP-config if it's different site.
1564 if (untrailingslashit($manifest->dbdomain) != untrailingslashit($this->siteurl)) {
1565
1566 // Unlink wp-config inside extracted directory
1567 $extractedWpConfigPath = $this->tmp . DIRECTORY_SEPARATOR . 'wordpress' . DIRECTORY_SEPARATOR . 'wp-config.php';
1568 if (file_exists($extractedWpConfigPath)) @unlink($extractedWpConfigPath);
1569
1570 }
1571
1572 // Restore files
1573 $this->restoreBackupFromFiles($manifest);
1574
1575
1576 if (untrailingslashit($manifest->dbdomain) != untrailingslashit($this->siteurl)) {
1577
1578 // Restore WP Config if it's different domain
1579 $this->restoreOriginalWPConfig(false);
1580
1581 }
1582
1583 if (!$this->isCLI) {
1584
1585 BMP::res(['status' => 'restore_ongoing', 'tmp' => $this->tmptime, 'secret' => $secret, 'options' => [
1586 'code' => $this->code,
1587 'start' => $this->start,
1588 'amount' => $this->fileAmount,
1589 'storage' => $this->backupStorage,
1590 'step' => 5
1591 ]]);
1592
1593 return;
1594
1595 }
1596
1597 }
1598
1599 // STEP: 6
1600 if ($this->isCLI || $this->batchStep == 6) {
1601
1602 // This literally does nothing.
1603
1604 if (!$this->isCLI) {
1605
1606 BMP::res(['status' => 'restore_ongoing', 'tmp' => $this->tmptime, 'secret' => $secret, 'options' => [
1607 'code' => $this->code,
1608 'start' => $this->start,
1609 'amount' => $this->fileAmount,
1610 'storage' => $this->backupStorage,
1611 'step' => 6
1612 ]]);
1613
1614 return;
1615
1616 }
1617
1618 }
1619
1620 // STEP 7
1621 if ($this->isCLI || $this->batchStep == 7) {
1622
1623 // Get manifest
1624 if (!isset($manifest)) {
1625 $manifest = $this->getCurrentManifest();
1626 }
1627
1628 $this->migration->log(__('Validating table prefix...', 'backup-backup'), 'STEP');
1629 $dbPrefix = $this->findTablePrefixByFiles($manifest->config->table_prefix);
1630 $this->migration->log(__('Table prefix in manifest: ', 'backup-backup') . $manifest->config->table_prefix, 'INFO');
1631 $this->migration->log(__('Detected table prefix: ', 'backup-backup') . $dbPrefix, 'INFO');
1632
1633 $wasDisabled = 0;
1634 $dbFinishedConv = 'false';
1635 $newDataProcess = $this->processData;
1636
1637 $forcev3Engine = false;
1638 if (isset($manifest->db_backup_engine) && $manifest->db_backup_engine === 'v4') {
1639 if ($this->v3engine == false) {
1640 $forcev3Engine = true;
1641 }
1642 }
1643
1644 if ($this->v3engine || $forcev3Engine) {
1645
1646 if ($this->usingDbEngineV4) {
1647 $this->migration->log(__('Splitting process is disabled because v4 restore engine is enabled.', 'backup-backup'), 'INFO');
1648 } else {
1649 $this->migration->log(__('Splitting process is disabled because v3 restore engine is enabled.', 'backup-backup'), 'INFO');
1650 }
1651
1652 $wasDisabled = 1;
1653
1654 } else if (!$this->splitting) {
1655
1656 $this->migration->log(__('Splitting process is disabled in the settings, omitting.', 'backup-backup'), 'INFO');
1657 $wasDisabled = 1;
1658
1659 } else {
1660
1661 $db_tables = $this->tmp . DIRECTORY_SEPARATOR . 'db_tables';
1662
1663 if (is_dir($db_tables)) {
1664
1665 if (empty($this->processData)) {
1666 $this->migration->log(__('Converting database files into partial files.', 'backup-backup'), 'STEP');
1667 if (defined('BMI_DB_MAX_ROWS_PER_QUERY')) {
1668 $this->migration->log(__('Max rows per query (this site): ', 'backup-backup') . BMI_DB_MAX_ROWS_PER_QUERY, 'INFO');
1669 }
1670
1671 try {
1672
1673 if (isset($manifest->source_query_output)) {
1674 $this->migration->log(__('Max rows per query (source site): ', 'backup-backup') . $manifest->source_query_output, 'INFO');
1675 } else {
1676 $this->migration->log(__('Unknown query output value of backup file, maybe it was made before v1.1.7', 'backup-backup'), 'INFO');
1677 }
1678
1679 } catch (\Exception $e) {
1680
1681 $this->migration->log(__('Unknown query output value of backup file, maybe it was made before v1.1.7', 'backup-backup'), 'INFO');
1682
1683 } catch (\Throwable $e) {
1684
1685 $this->migration->log(__('Unknown query output value of backup file, maybe it was made before v1.1.7', 'backup-backup'), 'INFO');
1686
1687 }
1688
1689 }
1690
1691
1692 $dbsort = new SmartDatabaseSort($db_tables, $this->migration, $this->isCLI);
1693 $process = $dbsort->sortUnsorted($this->processData);
1694
1695 if (!is_null($process) && isset($process)) {
1696 $newDataProcess = $process;
1697 }
1698
1699 if ($this->isCLI || (isset($process['convertionFinished']) && $process['convertionFinished'] == 'yes')) {
1700 $this->migration->log(__('Database convertion finished successfully.', 'backup-backup'), 'SUCCESS');
1701
1702 $this->migration->log(__('Calculating new query size and counts.', 'backup-backup'), 'STEP');
1703 $stats = $dbsort->countAllFilesAndQueries();
1704 $this->migration->log(__('Calculaion completed, printing details.', 'backup-backup'), 'SUCCESS');
1705
1706 $this->migration->log(__('Total queries to insert after conversion: ', 'backup-backup') . $stats['total_queries'], 'INFO');
1707 $this->migration->log(__('Partial files count after conversion: ', 'backup-backup') . sizeof($stats['all_files']), 'INFO');
1708 $this->migration->log(__('Total size of the database: ', 'backup-backup') . BMP::humanSize($stats['total_size']), 'INFO');
1709 $this->migration->log(__('Table count to be imported: ', 'backup-backup') . sizeof($stats['all_tables']), 'INFO');
1710
1711 $total_qrs = $stats['total_queries'];
1712 $this->conversionStats = [];
1713 $this->conversionStats['total_queries'] = $total_qrs;
1714
1715 $dbFinishedConv = 'true';
1716 }
1717
1718 } else {
1719
1720 if (file_exists($this->tmp . DIRECTORY_SEPARATOR . 'bmi_database_backup.sql')) {
1721
1722 $this->migration->log(__('Ommiting database convert step as the database backup included was not made with V2 engine.', 'backup-backup'), 'WARN');
1723 $this->migration->log(__('The process may be less stable if the database is larger than usual.', 'backup-backup'), 'WARN');
1724 $dbFinishedConv = 'true';
1725
1726 } else {
1727
1728 $this->migration->log(__('Ommiting database convert step as there is no database backup included.', 'backup-backup'), 'INFO');
1729 $dbFinishedConv = 'true';
1730
1731 }
1732
1733 }
1734
1735 }
1736
1737 if (!$this->isCLI) {
1738
1739 BMP::res(['status' => 'restore_ongoing', 'tmp' => $this->tmptime, 'secret' => $secret, 'options' => [
1740 'code' => $this->code,
1741 'start' => $this->start,
1742 'amount' => $this->fileAmount,
1743 'dbConvertionFinished' => $dbFinishedConv,
1744 'processData' => $newDataProcess,
1745 'conversionStats' => $this->conversionStats,
1746 'storage' => $this->backupStorage,
1747 'dbFoundPrefix' => $dbPrefix,
1748 'step' => 7 + $wasDisabled
1749 ]]);
1750
1751 return;
1752
1753 }
1754
1755 }
1756
1757 // STEP: 8
1758 if ($this->isCLI || $this->batchStep == 8) {
1759
1760 // Get manifest
1761 if (!isset($manifest)) {
1762 $manifest = $this->getCurrentManifest();
1763 }
1764
1765 if (isset($manifest->db_backup_engine) && $manifest->db_backup_engine === 'v4') {
1766 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'even-better-restore-v4.php';
1767 $this->usingDbEngineV4 = true;
1768 } else {
1769 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'even-better-restore-v3.php';
1770 $this->usingDbEngineV4 = false;
1771 }
1772
1773 // Try to restore database
1774 if (!$this->isCLI) {
1775
1776 $dbFinished = false;
1777 $database_exist = $this->restoreDatabaseDynamic($manifest);
1778
1779 if ($database_exist === false || $database_exist === true) {
1780
1781 $dbFinished = true;
1782
1783 } else {
1784
1785 if ($database_exist['status'] == 'new_file') {
1786
1787 $this->continueFile = false;
1788 $this->continueSeek = false;
1789
1790 } else {
1791
1792 $this->continueFile = $database_exist['file'];
1793 $this->continueSeek = $database_exist['seek'];
1794
1795 }
1796
1797 }
1798
1799 } else {
1800
1801 $database_exist = $this->restoreDatabaseDynamic($manifest);
1802
1803 }
1804
1805 $this->databaseExist = $database_exist;
1806
1807 if (!$this->isCLI) {
1808
1809 BMP::res(['status' => 'restore_ongoing', 'tmp' => $this->tmptime, 'secret' => $secret, 'options' => [
1810 'code' => $this->code,
1811 'start' => $this->start,
1812 'amount' => $this->fileAmount,
1813 'databaseExist' => $database_exist === true ? 'true' : 'false',
1814 'continueFile' => $this->continueFile,
1815 'continueSeek' => $this->continueSeek,
1816 'dbFinished' => $dbFinished,
1817 'firstDB' => $this->firstDB,
1818 'db_xi' => $this->db_xi,
1819 'ini_start' => $this->ini_start,
1820 'table_names_alter' => $this->table_names_alter,
1821 'conversionStats' => $this->conversionStats,
1822 'v3RestoreUsed' => $this->v3RestoreUsed,
1823 'dbFoundPrefix' => $this->dbFoundPrefix,
1824 'storage' => $this->backupStorage,
1825 'step' => 8
1826 ]]);
1827
1828 return;
1829
1830 }
1831
1832 }
1833
1834 // STEP: 9
1835 if ($this->isCLI || $this->batchStep == 9) {
1836
1837 // Get manifest
1838 if (!isset($manifest)) {
1839 $manifest = $this->getCurrentManifest();
1840 }
1841
1842 if (isset($manifest->db_backup_engine) && $manifest->db_backup_engine === 'v4') {
1843 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'even-better-restore-v4.php';
1844 $this->usingDbEngineV4 = true;
1845 } else {
1846 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'even-better-restore-v3.php';
1847 $this->usingDbEngineV4 = false;
1848 }
1849
1850 $database_exist = $this->databaseExist;
1851 if ($database_exist === true || $database_exist === 'true') {
1852 $this->removePreviousSelectionsIfDatabaseIncluded();
1853 }
1854
1855 // Alter all tables
1856 $status = false;
1857 $tableIndex = $this->tableIndex;
1858 $replaceStep = $this->replaceStep;
1859 $replaceFinished = false;
1860 $currentReplacePage = 0;
1861 $totalReplacePage = 0;
1862 $fieldAdjustments = 0;
1863
1864 if ($this->isCLI) {
1865
1866 $srFinished = false;
1867 if ($database_exist && $this->v3RestoreUsed == true) {
1868 while (!$srFinished) {
1869
1870 $status = $this->search_replace_v3($manifest);
1871
1872 if ($status != false && is_array($status)) {
1873 $this->replaceStep = $status['step'];
1874 $this->tableIndex = $status['tableIndex'];
1875 $this->replaceFinished = $status['finished'];
1876 $this->currentReplacePage = $status['currentPage'];
1877 $this->totalReplacePage = $status['totalPages'];
1878 $this->fieldAdjustments = $status['fieldAdjustments'];
1879
1880 if ($this->replaceFinished == true) $srFinished = true;
1881 }
1882
1883 }
1884 } else {
1885 $this->replaceFinished = true;
1886 $this->migration->progress(98);
1887 }
1888
1889 } else {
1890
1891 if ($database_exist && $this->v3RestoreUsed == true) {
1892 $status = $this->search_replace_v3($manifest);
1893 } else {
1894 $this->replaceFinished = true;
1895 $this->migration->progress(98);
1896 }
1897
1898 if ($status != false && is_array($status)) {
1899 $this->replaceStep = $status['step'];
1900 $this->tableIndex = $status['tableIndex'];
1901 $this->replaceFinished = $status['finished'];
1902 $this->currentReplacePage = $status['currentPage'];
1903 $this->totalReplacePage = $status['totalPages'];
1904 $this->fieldAdjustments = $status['fieldAdjustments'];
1905 }
1906
1907 }
1908
1909 if (!$this->isCLI) {
1910
1911 BMP::res([
1912 'status' => 'restore_ongoing',
1913 'tmp' => $this->tmptime,
1914 'secret' => $secret,
1915 'options' => [
1916 'code' => $this->code,
1917 'start' => $this->start,
1918 'amount' => $this->fileAmount,
1919 'databaseExist' => $database_exist === true ? 'true' : 'false',
1920 'firstDB' => $this->firstDB,
1921 'db_xi' => $this->db_xi,
1922 'ini_start' => $this->ini_start,
1923 'table_names_alter' => $this->table_names_alter,
1924 'conversionStats' => $this->conversionStats,
1925 'v3RestoreUsed' => $this->v3RestoreUsed,
1926 'replaceStep' => $this->replaceStep,
1927 'tableIndex' => $this->tableIndex,
1928 'replaceFinished' => $this->replaceFinished,
1929 'currentReplacePage' => $this->currentReplacePage,
1930 'totalReplacePage' => $this->totalReplacePage,
1931 'fieldAdjustments' => $this->fieldAdjustments,
1932 'dbFoundPrefix' => $this->dbFoundPrefix,
1933 'storage' => $this->backupStorage,
1934 'step' => 9
1935 ]
1936 ]);
1937
1938 return;
1939
1940 }
1941
1942 }
1943
1944 // STEP: 10
1945 if ($this->isCLI || $this->batchStep == 10) {
1946
1947 // Rename database from temporary to destination
1948 // And do the rest
1949 // Step 10 runs only at the end of database import
1950 // Get manifest
1951 if (!isset($manifest)) {
1952 $manifest = $this->getCurrentManifest();
1953 }
1954
1955 if (isset($manifest->db_backup_engine) && $manifest->db_backup_engine === 'v4') {
1956 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'even-better-restore-v4.php';
1957 $this->usingDbEngineV4 = true;
1958 } else {
1959 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'even-better-restore-v3.php';
1960 $this->usingDbEngineV4 = false;
1961 }
1962
1963 $database_exist = $this->databaseExist;
1964
1965 // Restore WP Config ** It allows to recover session after restore no matter what
1966 if ($database_exist == true || $database_exist == 'true') {
1967
1968 // Alter all tables
1969 if ($this->v3RestoreUsed == true) {
1970
1971 $this->alter_tables_v3($manifest);
1972
1973 } else {
1974
1975 $this->alter_tables($manifest);
1976
1977 // Modify the WP Config and replace
1978 $this->replaceDbPrefixInWPConfig($manifest);
1979
1980 }
1981
1982 // User is logged off at this point, try to log in
1983 $this->makeNewLoginSession($manifest);
1984
1985 } else {
1986
1987 // Restore WP Config without modifications
1988 $this->restoreOriginalWPConfig();
1989
1990 }
1991
1992 // Make sure the Xhria was not modified
1993 $this->setOrUpdateXhria();
1994
1995 // Fix elementor templates
1996 $this->clearElementorCache();
1997
1998 // Make final cleanup
1999 $this->finalCleanUP();
2000
2001 // Final flush of rewrite rules
2002 flush_rewrite_rules();
2003
2004 // Dedicated fix for block-wp-login plugin
2005 $this->fixWPLogin($manifest);
2006
2007 // Touch autologin file
2008 $autologin_file = BMI_BACKUPS . DIRECTORY_SEPARATOR . '.autologin';
2009 touch($autologin_file);
2010
2011 // Final verbose
2012 if ((intval(microtime(true)) - intval($this->start)) > 0) {
2013 $this->migration->log(__('Restore process took: ', 'backup-backup') . (intval(microtime(true)) - intval($this->start)) . ' seconds.', 'INFO');
2014 } else {
2015 $this->migration->log(__('Restore process fully finished.', 'INFO'));
2016 }
2017 Logger::log('Site restored...');
2018
2019 // Return success
2020 return true;
2021
2022 }
2023
2024 } catch (\Exception $e) {
2025
2026 // On this tragedy at least remove tmp files
2027 $this->handleError($e);
2028 return false;
2029
2030 } catch (\Throwable $e) {
2031
2032 // On this tragedy at least remove tmp files
2033 $this->handleError($e);
2034 return false;
2035
2036 }
2037
2038 }
2039
2040 }
2041