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